From 247c0a4044d20943f843fb1409fd94b3b664f78a Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 6 Apr 2022 10:56:29 +0200 Subject: [PATCH 01/27] alignment fixed --- examples/buttons/TestButton.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/buttons/TestButton.qml b/examples/buttons/TestButton.qml index cbb76ae5..65550e1c 100644 --- a/examples/buttons/TestButton.qml +++ b/examples/buttons/TestButton.qml @@ -5,16 +5,16 @@ Qsk.PushButton { sizePolicy { - // long texts, should not have an effect + // long texts, should not have an effect horizontalPolicy: Qsk.SizePolicy.Ignored verticalPolicy: Qsk.SizePolicy.Ignored } - minimumSize - { - width: 80 - height: 60 - } + minimumSize + { + width: 80 + height: 60 + } shape { From c44c30fa4145cf8656a67a098894a27acf26d93c Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 6 Apr 2022 10:56:48 +0200 Subject: [PATCH 02/27] forgotten debug statement removed --- src/controls/QskWindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controls/QskWindow.cpp b/src/controls/QskWindow.cpp index 42f7640c..7061dbb9 100644 --- a/src/controls/QskWindow.cpp +++ b/src/controls/QskWindow.cpp @@ -492,7 +492,6 @@ QSize QskWindow::sizeConstraint() const if ( !qskIsTransparentForPositioner( child ) ) { const auto size = qskSizeConstraint( child, Qt::PreferredSize ); -qDebug() << child << size; if ( doWidth ) constraint.setWidth( qMax( constraint.width(), size.width() ) ); From c17e3defd3d79865f396faf9e04bcf932a34925c Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 7 Apr 2022 15:43:45 +0200 Subject: [PATCH 03/27] qskItemSize() removed, QQuickItem::size() is available since Qt 5.10 --- examples/thumbnails/main.cpp | 2 +- src/controls/QskQuick.cpp | 15 ++++----------- src/controls/QskQuick.h | 1 - src/controls/QskScrollArea.cpp | 2 +- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/examples/thumbnails/main.cpp b/examples/thumbnails/main.cpp index e267cd32..9944871d 100644 --- a/examples/thumbnails/main.cpp +++ b/examples/thumbnails/main.cpp @@ -158,7 +158,7 @@ class IconGrid : public QskLinearBox const int dim = dimension(); // we know, that all items have the same size - const auto itemSize = qskItemSize( itemAtIndex( 0 ) ); + const auto itemSize = itemAtIndex( 0 )->size(); const int rowMin = rect.top() / ( itemSize.height() + spacing() ); const int rowMax = rect.bottom() / ( itemSize.height() + spacing() ); diff --git a/src/controls/QskQuick.cpp b/src/controls/QskQuick.cpp index 6f71bca4..b44eef1b 100644 --- a/src/controls/QskQuick.cpp +++ b/src/controls/QskQuick.cpp @@ -16,13 +16,6 @@ QSK_QT_PRIVATE_END #include #include -QSizeF qskItemSize( const QQuickItem* item ) -{ - // obsolete for Qt >= 5.10 - auto d = QQuickItemPrivate::get( item ); - return QSizeF( d->width, d->height ); -} - QRectF qskItemRect( const QQuickItem* item ) { auto d = QQuickItemPrivate::get( item ); @@ -41,7 +34,7 @@ void qskSetItemGeometry( QQuickItem* item, const QRectF& rect ) { control->setGeometry( rect ); } - else + else if ( item ) { item->setPosition( rect.topLeft() ); item->setSize( rect.size() ); @@ -63,10 +56,10 @@ bool qskIsAncestorOf( const QQuickItem* item, const QQuickItem* child ) bool qskIsVisibleToParent( const QQuickItem* item ) { - if ( item ) - return QQuickItemPrivate::get( item )->explicitVisible; + if ( item == nullptr ) + return false; - return false; + return QQuickItemPrivate::get( item )->explicitVisible; } bool qskIsVisibleTo( const QQuickItem* item, const QQuickItem* ancestor ) diff --git a/src/controls/QskQuick.h b/src/controls/QskQuick.h index 74d29b6b..bf35eb93 100644 --- a/src/controls/QskQuick.h +++ b/src/controls/QskQuick.h @@ -48,7 +48,6 @@ QSK_EXPORT QskSizePolicy qskSizePolicy( const QQuickItem* ); QSK_EXPORT Qt::Alignment qskLayoutAlignmentHint( const QQuickItem* ); QSK_EXPORT bool qskRetainSizeWhenHidden( const QQuickItem* ); -QSK_EXPORT QSizeF qskItemSize( const QQuickItem* ); QSK_EXPORT QRectF qskItemRect( const QQuickItem* ); QSK_EXPORT QRectF qskItemGeometry( const QQuickItem* ); diff --git a/src/controls/QskScrollArea.cpp b/src/controls/QskScrollArea.cpp index e2078c2b..7f0ba937 100644 --- a/src/controls/QskScrollArea.cpp +++ b/src/controls/QskScrollArea.cpp @@ -500,7 +500,7 @@ QSizeF QskScrollArea::layoutSizeHint( Qt::SizeHint which, const QSizeF& constrai } else { - hint = qskItemSize( contentItem ); + hint = contentItem->size(); } if ( verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff ) From 741af6a8a6f2bbca260e4a949c72443a24e15031 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 7 Apr 2022 17:19:59 +0200 Subject: [PATCH 04/27] hiding isTransparentForPositioner --- src/controls/QskControl.cpp | 10 ++-------- src/controls/QskQuick.cpp | 23 ++++++++++++++++++----- src/controls/QskQuick.h | 2 ++ src/controls/QskSubWindow.cpp | 2 +- src/controls/QskWindow.cpp | 4 ++-- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index a0aff322..276d78e9 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -804,7 +804,7 @@ void QskControl::itemChange( QQuickItem::ItemChange change, } case QQuickItem::ItemChildAddedChange: { - if ( autoLayoutChildren() && !qskIsTransparentForPositioner( value.item ) ) + if ( autoLayoutChildren() && qskIsAdjustableByLayout( value.item ) ) polish(); break; @@ -844,13 +844,7 @@ void QskControl::updateItemPolish() const auto children = childItems(); for ( auto child : children ) { - /* - We don't want to resize invisible children, but then - we would need to set up connections to know when a child - becomes visible. So we don't use qskIsVisibleToLayout here. - And what about using QskControl::LayoutOutWhenHidden ? - */ - if ( !qskIsTransparentForPositioner( child ) ) + if ( qskIsAdjustableByLayout( child ) ) { const auto r = qskConstrainedItemRect( child, rect ); qskSetItemGeometry( child, r ); diff --git a/src/controls/QskQuick.cpp b/src/controls/QskQuick.cpp index b44eef1b..3522c49d 100644 --- a/src/controls/QskQuick.cpp +++ b/src/controls/QskQuick.cpp @@ -133,14 +133,27 @@ bool qskIsTransparentForPositioner( const QQuickItem* item ) bool qskIsVisibleToLayout( const QQuickItem* item ) { - if ( item ) + if ( item == nullptr ) + return false; + + const auto d = QQuickItemPrivate::get( item ); + return !d->isTransparentForPositioner() + && ( d->explicitVisible || qskRetainSizeWhenHidden( item ) ); +} + +bool qskIsAdjustableByLayout( const QQuickItem* item ) +{ + if ( qskIsTransparentForPositioner( item ) ) + return false; + + bool adjustable = qskIsVisibleToParent( item ); + if ( !adjustable ) { - const auto d = QQuickItemPrivate::get( item ); - return !d->isTransparentForPositioner() - && ( d->explicitVisible || qskRetainSizeWhenHidden( item ) ); + if ( auto control = qskControlCast( item ) ) + adjustable = control->testLayoutHint( QskControl::LayoutWhenHidden ); } - return false; + return adjustable; } QskSizePolicy qskSizePolicy( const QQuickItem* item ) diff --git a/src/controls/QskQuick.h b/src/controls/QskQuick.h index bf35eb93..2883a798 100644 --- a/src/controls/QskQuick.h +++ b/src/controls/QskQuick.h @@ -32,7 +32,9 @@ 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* ); QSK_EXPORT QSizeF qskEffectiveSizeHint( const QQuickItem*, Qt::SizeHint, const QSizeF& constraint = QSizeF() ); diff --git a/src/controls/QskSubWindow.cpp b/src/controls/QskSubWindow.cpp index b6acca87..4a4c72a2 100644 --- a/src/controls/QskSubWindow.cpp +++ b/src/controls/QskSubWindow.cpp @@ -248,7 +248,7 @@ void QskSubWindow::itemChange( QQuickItem::ItemChange change, case QQuickItem::ItemChildAddedChange: case QQuickItem::ItemChildRemovedChange: { - if ( !qskIsTransparentForPositioner( value.item ) ) + if ( qskIsVisibleToLayout( value.item ) ) { resetImplicitSize(); polish(); diff --git a/src/controls/QskWindow.cpp b/src/controls/QskWindow.cpp index 7061dbb9..a49f5c48 100644 --- a/src/controls/QskWindow.cpp +++ b/src/controls/QskWindow.cpp @@ -489,7 +489,7 @@ QSize QskWindow::sizeConstraint() const const auto children = contentItem()->childItems(); for ( auto child : children ) { - if ( !qskIsTransparentForPositioner( child ) ) + if ( qskIsVisibleToLayout( child ) ) { const auto size = qskSizeConstraint( child, Qt::PreferredSize ); @@ -527,7 +527,7 @@ void QskWindow::layoutItems() const auto children = contentItem()->childItems(); for ( auto child : children ) { - if ( !qskIsTransparentForPositioner( child ) ) + if ( qskIsAdjustableByLayout( child ) ) { const auto r = qskConstrainedItemRect( child, rect ); qskSetItemGeometry( child, r ); From eaf57ef1f0a0e46d08a0e690180a5613ed289734 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 7 Apr 2022 17:45:38 +0200 Subject: [PATCH 05/27] project file fixed --- src/src.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src.pro b/src/src.pro index 2f51cb2b..5a4089d9 100644 --- a/src/src.pro +++ b/src/src.pro @@ -299,7 +299,7 @@ HEADERS += \ layouts/QskGridLayoutEngine.h \ layouts/QskIndexedLayoutBox.h \ layouts/QskLayoutChain.h \ - layouts/QskLayoutEngine2D.cpp \ + layouts/QskLayoutEngine2D.h \ layouts/QskLayoutMetrics.h \ layouts/QskLinearBox.h \ layouts/QskLinearLayoutEngine.h \ From 21ad84e29104652f24bfd28db9b004fa5527d3fe Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 8 Apr 2022 15:37:32 +0200 Subject: [PATCH 06/27] Qsk::Visibility added --- src/common/QskNamespace.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/common/QskNamespace.h b/src/common/QskNamespace.h index 0e1872e3..fcb5abb1 100644 --- a/src/common/QskNamespace.h +++ b/src/common/QskNamespace.h @@ -39,6 +39,16 @@ namespace Qsk Sunken }; Q_ENUM_NS( TextStyle ) + + enum Visibility + { + Visible = 1 << 0, + Hidden = 1 << 1 + }; + Q_ENUM_NS( Visibility ) + + Q_DECLARE_FLAGS( Visibilities, Visibility ) + Q_DECLARE_OPERATORS_FOR_FLAGS( Visibilities ) } #endif From 449f08bf98a6f6629c4b353daba387881b298a5b Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 8 Apr 2022 15:37:55 +0200 Subject: [PATCH 07/27] beautified --- src/common/QskRgbValue.cpp | 4 ++-- src/controls/QskSkin.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/QskRgbValue.cpp b/src/common/QskRgbValue.cpp index 7b4c0b8c..bd6ac812 100644 --- a/src/common/QskRgbValue.cpp +++ b/src/common/QskRgbValue.cpp @@ -188,8 +188,8 @@ void QskRgb::debugColor( QDebug debug, QRgb rgb ) debug << '['; - debug << qRed( rgb ) << "r," << qGreen( rgb ) << "g," - << qBlue( rgb ) << 'b'; + debug << qRed( rgb ) << "r," + << qGreen( rgb ) << "g," << qBlue( rgb ) << 'b'; if ( qAlpha( rgb ) != 255 ) debug << ',' << qAlpha( rgb ) << 'a'; diff --git a/src/controls/QskSkin.cpp b/src/controls/QskSkin.cpp index 4a8e20e5..b7ad051a 100644 --- a/src/controls/QskSkin.cpp +++ b/src/controls/QskSkin.cpp @@ -229,7 +229,7 @@ void QskSkin::setupFonts( const QString& family, int weight, bool italic ) for ( int i = TinyFont; i <= HugeFont; i++ ) { - font.setPixelSize( qskDpiScaled( sizes[i-1] ) ); + font.setPixelSize( qskDpiScaled( sizes[i - 1] ) ); m_data->fonts[ i ] = font; } From 69e4152b4ccf1eb7d64e96fe42dc7c5607ea2a3c Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 8 Apr 2022 16:46:20 +0200 Subject: [PATCH 08/27] 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 \ From 4919bce00b3a42e3f82d6e4a902fe70ae78db7aa Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 8 Apr 2022 18:00:10 +0200 Subject: [PATCH 09/27] QskPlacementPolicy.dox added --- doc/classes/QskPlacementPolicy.dox | 176 +++++++++++++++++++++++++++++ doc/qskmodules.dox | 2 +- 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 doc/classes/QskPlacementPolicy.dox diff --git a/doc/classes/QskPlacementPolicy.dox b/doc/classes/QskPlacementPolicy.dox new file mode 100644 index 00000000..62aefe76 --- /dev/null +++ b/doc/classes/QskPlacementPolicy.dox @@ -0,0 +1,176 @@ +/*! + \class QskPlacementPolicy QskPlacementPolicy.h + + \ingroup Framework + + QskPlacementPolicy is a hint for layout code how to deal with + the geometry of an item when being visible or hidden. + + \sa QskControl::placementPolicy(), qskPlacementPolicy() +*/ + +/*! + \enum QskPlacementPolicy::Policy + + Hint for the layout code how to deal with the geometry of an + item. QskPlacementPolicy has two values one for the visible, + the other for the hidden state. + + \var QskPlacementPolicy::Ignore + + Ignore the item for all type of layout calculations. + + \var QskPlacementPolicy::Reserve + + Reseve space without giving the item its geometry. + + \var QskPlacementPolicy::Adjust + + Reserve space and adjust the geometry of the item + + \note QskPlacementPolicy::Reserve as hiddenPolicy() is equivalent + to what is offered by QSizePolicy::retainSizeWhenHidden(). +*/ + +/*! + \property QskPlacementPolicy::Policy QskPlacementPolicy::visiblePolicy + + \brief Policy for the item, when being visible ( to its parent ) + + - QskPlacementPolicy::Ignore + + For situations where a parent takes care of the geometry for its children, + but exceptions need to be defined. F.e a focus indicator. + + - QskPlacementPolicy::Reserve: + + There are not many relevant scenarios for this value. An + example might be when an item is inside of a grid layout, where all the + size hints should have an effect, but the final alignment of the item + inside of the cell has to be done manually. + + - QskPlacementPolicy::Adjust: + + The default value + + \accessors visiblePolicy(), setVisiblePolicy() + \sa hiddenPolicy, qskIsVisibleToParent() + + \note QskPlacementPolicy::Ignore is stored in the transparentForPositioner + bit in QQuickItem and might have an impact on Qt/Quick layout code. +*/ + +/*! + \property QskPlacementPolicy::Policy QskPlacementPolicy::hiddenPolicy + + \brief Policy for the item, when being hidden ( to its parent ) + + - QskPlacementPolicy::Ignore + + The default value + + - QskPlacementPolicy::Reserve: + + In combination with a visiblePolicy != QskPlacementPolicy::Ignore + the layout of the parent does not change, when the item is shown/hidden. + + - QskPlacementPolicy::Adjust: + + Sometimes an item wants to have its proper size even when being hidden. + + \accessors visiblePolicy(), setVisiblePolicy() + \sa qskIsVisibleToParent() + + \note QskPlacementPolicy::Ignore is stored in the transparentForPositioner + bit in QQuickItem and might have an impact on Qt/Quick layout code. +*/ + +/*! + \fn QskPlacementPolicy::QskPlacementPolicy() + + visiblePolicy is set to QskPlacementPolicy::Adjust, + hiddenPolicy to QskPlacementPolicy::Ignore. +*/ + +/*! + \fn QskPlacementPolicy::QskPlacementPolicy( Policy policy ) + + visiblePolicy and hiddenPolicy are set to policy +*/ + +/*! + \fn QskPlacementPolicy::QskPlacementPolicy( Policy visiblePolicy, Policy hiddenPolicy ) + + Initialization from visiblePolicy and hiddenPolicy +*/ + +/*! + \fn QskPlacementPolicy::QskPlacementPolicy( Qsk::Visibilities visiblities, Policy policy ) + + Initialize visiblePolicy and hiddenPolicy depending on visiblities +*/ + +/* + \fn QskPlacementPolicy::operator==( const QskPlacementPolicy& ) + + "Equal to" operator + \sa operator!=(), operator<() +*/ + +/* + \fn QskPlacementPolicy::operator!=( const QskPlacementPolicy& ) + + "Not equal to" operator + \sa operator==(), operator<() +*/ + +/* + \fn QskPlacementPolicy::setPolicy( Qsk::Visibilities, Policy ) +*/ + +*/ + \fn QskPlacementPolicy::policy( Qsk::Visibility ) +*/ + +/* + \fn QskPlacementPolicy::isEffective() + + \return true, when visiblePolicy or hiddenPolicy is not QskPlacementPolicy::Ignore + \sa isIgnoring() +*/ + +/* + \fn QskPlacementPolicy::isIgnoring( Qsk::Visibility ) + \return true, when visiblePolicy and hiddenPolicy is QskPlacementPolicy::Ignore + \sa isEffective() +*/ + +/* + \fn QskPlacementPolicy::isAdjusting( Qsk::Visibility ) + + \return true, when QskPlacementPolicy::Adjust is set for the visibility +*/ + +/* + \fn QskPlacementPolicy::setVisiblePolicy( Policy ) + + \sa visiblePolicy(), setHiddenPolicy() +*/ + +/* + \fn QskPlacementPolicy::visiblePolicy() + + \sa setVisiblePolicy(), hiddenPolicy() +*/ + +/* + \fn QskPlacementPolicy::setHiddenPolicy( Policy ) + + \sa hiddenPolicy(), setVisiblePolicy() +*/ + +/* + \fn QskPlacementPolicy::hiddenPolicy() + + \sa setHiddenPolicy(), visiblePolicy() +*/ diff --git a/doc/qskmodules.dox b/doc/qskmodules.dox index 7f2777bb..5017cf8a 100644 --- a/doc/qskmodules.dox +++ b/doc/qskmodules.dox @@ -5,7 +5,7 @@ \defgroup Animation Animation \defgroup Themeing Themeing \defgroup Controls Controls - \defgroup container Container + \defgroup Container Container \defgroup Layouts Layouts \defgroup Dialogs Dialogs \defgroup Skinlets Skinlets From f075f44c3dd0880cbed3204e65ef6e80decaf8ae Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sun, 10 Apr 2022 14:04:02 +0200 Subject: [PATCH 10/27] forgotten file added --- tests/checkboxes/target_wrapper.sh | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 tests/checkboxes/target_wrapper.sh diff --git a/tests/checkboxes/target_wrapper.sh b/tests/checkboxes/target_wrapper.sh new file mode 100755 index 00000000..88cc3928 --- /dev/null +++ b/tests/checkboxes/target_wrapper.sh @@ -0,0 +1,6 @@ +#!/bin/sh +LD_LIBRARY_PATH=/home/uwe/qskinny/config/qsk1/Qt/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} +export LD_LIBRARY_PATH +QT_PLUGIN_PATH=/home/uwe/qskinny/config/qsk1/Qt/plugins${QT_PLUGIN_PATH:+:$QT_PLUGIN_PATH} +export QT_PLUGIN_PATH +exec "$@" From a73ee6baba45f6426c58c66ff1e94ffbc43f0761 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Mon, 11 Apr 2022 10:01:24 +0200 Subject: [PATCH 11/27] Squashed commit of the following: commit e2887cdc9d7cbf69445c325fe074578e2f38da6c Author: Uwe Rathmann Date: Mon Apr 11 09:58:03 2022 +0200 wip commit 63efe9f3ad95fdf3d9fb15c929a45b0dc7cc681c Author: Uwe Rathmann Date: Mon Apr 11 09:39:18 2022 +0200 wip commit a2f3621fb6fea787f32c53428eee26f30c69510c Author: Uwe Rathmann Date: Mon Apr 11 08:04:11 2022 +0200 wip --- src/nodes/QskTextureRenderer.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/nodes/QskTextureRenderer.cpp b/src/nodes/QskTextureRenderer.cpp index d501d6f3..f180c119 100644 --- a/src/nodes/QskTextureRenderer.cpp +++ b/src/nodes/QskTextureRenderer.cpp @@ -180,12 +180,20 @@ uint QskTextureRenderer::createTexture( // Qt6.0.0 is buggy when using FBOs. So let's disable it for the moment TODO ... renderMode = Raster; #endif - if ( renderMode == AutoDetect ) + + if ( window && window->rendererInterface()->graphicsApi() != OpenGL ) { - if ( qskSetup->testItemUpdateFlag( QskQuickItem::PreferRasterForTextures ) ) - renderMode = Raster; - else - renderMode = OpenGL; + renderMode = Raster; + } + else + { + if ( renderMode == AutoDetect ) + { + if ( qskSetup->testItemUpdateFlag( QskQuickItem::PreferRasterForTextures ) ) + renderMode = Raster; + else + renderMode = OpenGL; + } } if ( renderMode == Raster ) From dc14dda5ea4992ab166ca336c2f3ec3798809040 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Mon, 11 Apr 2022 10:11:57 +0200 Subject: [PATCH 12/27] respecting the graphicsApi --- src/nodes/QskTextureRenderer.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/nodes/QskTextureRenderer.cpp b/src/nodes/QskTextureRenderer.cpp index f180c119..137226ab 100644 --- a/src/nodes/QskTextureRenderer.cpp +++ b/src/nodes/QskTextureRenderer.cpp @@ -25,6 +25,15 @@ #include #endif +static inline bool qskHasOpenGLRenderer( const QQuickWindow* window ) +{ + if ( window == nullptr ) + return false; + + const auto renderer = window->rendererInterface(); + return renderer->graphicsApi() == QSGRendererInterface::OpenGL; +} + static uint qskCreateTextureOpenGL( QQuickWindow* window, const QSize& size, QskTextureRenderer::PaintHelper* helper ) { @@ -181,19 +190,18 @@ uint QskTextureRenderer::createTexture( renderMode = Raster; #endif - if ( window && window->rendererInterface()->graphicsApi() != OpenGL ) + if ( renderMode != Raster ) { - renderMode = Raster; + if ( !qskHasOpenGLRenderer( window ) ) + renderMode = Raster; } - else + + if ( renderMode == AutoDetect ) { - if ( renderMode == AutoDetect ) - { - if ( qskSetup->testItemUpdateFlag( QskQuickItem::PreferRasterForTextures ) ) - renderMode = Raster; - else - renderMode = OpenGL; - } + if ( qskSetup->testItemUpdateFlag( QskQuickItem::PreferRasterForTextures ) ) + renderMode = Raster; + else + renderMode = OpenGL; } if ( renderMode == Raster ) From 4e8ede813094913d7e0a610e9b23214110da7e50 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Mon, 11 Apr 2022 10:12:33 +0200 Subject: [PATCH 13/27] QQuickImagePrivate can be used now --- playground/images/Image.cpp | 78 ++++++++++++++++++++----------------- playground/images/Image.h | 10 +++-- 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/playground/images/Image.cpp b/playground/images/Image.cpp index 39834688..e77be209 100644 --- a/playground/images/Image.cpp +++ b/playground/images/Image.cpp @@ -5,13 +5,14 @@ #include "Image.h" -// QQuickImagePrivate is not exported, so we -// we can't derive here +QSK_QT_PRIVATE_BEGIN +#include +QSK_QT_PRIVATE_END -class Image::PrivateData +class ImagePrivate : public QQuickImagePrivate { public: - PrivateData() + ImagePrivate() : sourceSizeAdjustment( false ) , deferredUpdates( true ) , dirtyPolish( false ) @@ -27,8 +28,7 @@ class Image::PrivateData }; Image::Image( QQuickItem* parent ) - : Inherited( parent ) - , m_data( new PrivateData() ) + : QQuickImage( *( new ImagePrivate() ), parent ) { } @@ -36,50 +36,48 @@ Image::~Image() { } -void Image::setVisible( bool on ) -{ - // QQuickItem::setVisible is no slot - Inherited::setVisible( on ); -} - void Image::show() { - Inherited::setVisible( true ); + setVisible( true ); } void Image::hide() { - Inherited::setVisible( false ); + setVisible( false ); } void Image::setSourceSizeAdjustment( bool on ) { - if ( on != m_data->sourceSizeAdjustment ) + Q_D( Image ); + + if ( on != d->sourceSizeAdjustment ) { - m_data->sourceSizeAdjustment = on; + d->sourceSizeAdjustment = on; Q_EMIT sourceSizeAdjustmentChanged(); } } bool Image::sourceSizeAdjustment() const { - return m_data->sourceSizeAdjustment; + return d_func()->sourceSizeAdjustment; } void Image::setDeferredUpdates( bool on ) { - if ( on != m_data->deferredUpdates ) + Q_D( Image ); + + if ( on != d->deferredUpdates ) { - m_data->deferredUpdates = on; + d->deferredUpdates = on; if ( !on ) { // when having blocked updates we reschedule them - if ( m_data->dirtyPolish ) + if ( d->dirtyPolish ) polish(); - if ( m_data->dirtyUpdate ) + if ( d->dirtyUpdate ) update(); } } @@ -87,18 +85,20 @@ void Image::setDeferredUpdates( bool on ) bool Image::deferredUpdates() const { - return m_data->deferredUpdates; + return d_func()->deferredUpdates; } void Image::setSourceSize( const QSize& size ) { if ( !( size.isEmpty() && sourceSize().isEmpty() ) ) - QQuickImage::setSourceSize( size ); + Inherited::setSourceSize( size ); } void Image::componentComplete() { - if ( m_data->deferredUpdates && m_data->sourceSizeAdjustment ) + Q_D( const Image ); + + if ( d->deferredUpdates && d->sourceSizeAdjustment ) { // QQuickImage::componentComplete() calls load // long before we have the final geometry @@ -119,12 +119,14 @@ void Image::itemChange( QQuickItem::ItemChange change, if ( change == ItemVisibleHasChanged ) { + Q_D( const Image ); + if ( value.boolValue ) { - if ( m_data->dirtyPolish ) + if ( d->dirtyPolish ) polish(); - if ( m_data->dirtyUpdate ) + if ( d->dirtyUpdate ) update(); } } @@ -156,9 +158,11 @@ void Image::geometryChanged( void Image::adjustSourceSize( const QSizeF& size ) { - if ( m_data->sourceSizeAdjustment ) + Q_D( const Image ); + + if ( d->sourceSizeAdjustment ) { - if ( m_data->deferredUpdates ) + if ( d->deferredUpdates ) { setImplicitSize( size.width(), size.height() ); polish(); @@ -172,35 +176,39 @@ void Image::adjustSourceSize( const QSizeF& size ) void Image::updatePolish() { - if ( m_data->deferredUpdates ) + Q_D( Image ); + + if ( d->deferredUpdates ) { if ( !isVisible() ) { - m_data->dirtyPolish = true; + d->dirtyPolish = true; return; } - if ( m_data->sourceSizeAdjustment ) + if ( d->sourceSizeAdjustment ) setSourceSize( QSize( int( width() ), int( height() ) ) ); } - m_data->dirtyPolish = false; + d->dirtyPolish = false; Inherited::updatePolish(); } QSGNode* Image::updatePaintNode( QSGNode* oldNode, UpdatePaintNodeData* data ) { - if ( m_data->deferredUpdates ) + Q_D( Image ); + + if ( d->deferredUpdates ) { if ( !isVisible() ) { - m_data->dirtyUpdate = true; + d->dirtyUpdate = true; return oldNode; } } - m_data->dirtyUpdate = false; + d->dirtyUpdate = false; return Inherited::updatePaintNode( oldNode, data ); } diff --git a/playground/images/Image.h b/playground/images/Image.h index 3eaabe49..fab9e720 100644 --- a/playground/images/Image.h +++ b/playground/images/Image.h @@ -19,7 +19,7 @@ QSK_QT_PRIVATE_BEGIN QSK_QT_PRIVATE_END -#include +class ImagePrivate; class Image : public QQuickImage { @@ -54,7 +54,12 @@ class Image : public QQuickImage public Q_SLOTS: void show(); void hide(); + +#ifdef Q_MOC_RUN + // methods from QQuickItem, we want to be available as string based slots void setVisible( bool ); + void setEnabled( bool ); +#endif Q_SIGNALS: void sourceSizeAdjustmentChanged(); @@ -75,6 +80,5 @@ class Image : public QQuickImage private: void adjustSourceSize( const QSizeF& ); - class PrivateData; - std::unique_ptr< PrivateData > m_data; + Q_DECLARE_PRIVATE( Image ) }; From d42e27af5daee0f9869ee81fd29512577282c945 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Mon, 11 Apr 2022 11:13:47 +0200 Subject: [PATCH 14/27] some adjustments for the software renderer --- playground/images/main.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/playground/images/main.cpp b/playground/images/main.cpp index d14d8a56..a50c1102 100644 --- a/playground/images/main.cpp +++ b/playground/images/main.cpp @@ -14,6 +14,26 @@ #include #include +#include + +namespace +{ + class ImageProvider : public QskGraphicImageProvider + { + public: + ImageProvider( const QString& id ) + : QskGraphicImageProvider( id, type() ) + { + } + + private: + static ImageType type() + { + const auto backend = QQuickWindow::sceneGraphBackend(); + return ( backend == "software" ) ? Image : Texture; + } + }; +} int main( int argc, char* argv[] ) { @@ -33,12 +53,10 @@ int main( int argc, char* argv[] ) SkinnyShortcut::enable( SkinnyShortcut::Quit | SkinnyShortcut::DebugShortcuts ); - // image provider that falls back to the graphic provider - QskGraphicImageProvider* imageProvider = - new QskGraphicImageProvider( providerId, QQuickImageProvider::Texture ); - QQmlApplicationEngine engine( QUrl( "qrc:/qml/images.qml" ) ); - engine.addImageProvider( imageProvider->graphicProviderId(), imageProvider ); + + // image provider that falls back to the graphic provider above + engine.addImageProvider( providerId, new ImageProvider( providerId ) ); return app.exec(); } From a1d60803f23a34d8eef40d1b3d1d0757e30f87d1 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Mon, 11 Apr 2022 12:05:00 +0200 Subject: [PATCH 15/27] avoid crash with vnc plugin --- src/inputpanel/QskInputContext.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/inputpanel/QskInputContext.cpp b/src/inputpanel/QskInputContext.cpp index 236c191f..ba99590b 100644 --- a/src/inputpanel/QskInputContext.cpp +++ b/src/inputpanel/QskInputContext.cpp @@ -183,13 +183,12 @@ static QPointer< QskInputContext > qskInputContext; static void qskSendToPlatformContext( QEvent::Type type ) { - const auto platformInputContext = - QGuiApplicationPrivate::platformIntegration()->inputContext(); + const auto integration = QGuiApplicationPrivate::platformIntegration(); - if ( platformInputContext ) + if ( const auto inputContext = integration->inputContext() ) { QEvent event( type ); - QCoreApplication::sendEvent( platformInputContext, &event ); + QCoreApplication::sendEvent( inputContext, &event ); } } @@ -208,9 +207,12 @@ void QskInputContext::setInstance( QskInputContext* inputContext ) qskInputContext = inputContext; if ( oldContext && oldContext->parent() == nullptr ) + { delete oldContext; - qskSendToPlatformContext( QEvent::PlatformPanel ); + // still needed with > Qt 5.15 ? + qskSendToPlatformContext( QEvent::PlatformPanel ); + } } } From 3a88045f8079cc5bb1f534ceebc89476f22b6b3b Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Tue, 12 Apr 2022 14:13:59 +0200 Subject: [PATCH 16/27] Skinny::init added --- playground/grids/main.cpp | 3 +++ support/SkinnyNamespace.cpp | 8 ++++++++ support/SkinnyNamespace.h | 1 + 3 files changed, 12 insertions(+) diff --git a/playground/grids/main.cpp b/playground/grids/main.cpp index ea81b96a..62a666b5 100644 --- a/playground/grids/main.cpp +++ b/playground/grids/main.cpp @@ -5,6 +5,8 @@ #include "TestBox.h" +#include + #include #include @@ -386,6 +388,7 @@ class MainWidget : public QWidget int main( int argc, char** argv ) { QApplication app( argc, argv ); + Skinny::init(); int testcase = 0; if ( argc == 2 ) diff --git a/support/SkinnyNamespace.cpp b/support/SkinnyNamespace.cpp index baf2d6a6..86066f2c 100644 --- a/support/SkinnyNamespace.cpp +++ b/support/SkinnyNamespace.cpp @@ -138,3 +138,11 @@ void Skinny::changeFonts( int increment ) Q_EMIT qskSetup->skinChanged( skin ); } + +void Skinny::init() +{ + /* + a dummy call - has no reason beside, that applications can load + the lib and all initializaion take place + */ +} diff --git a/support/SkinnyNamespace.h b/support/SkinnyNamespace.h index 072e60b2..ef47ddb1 100644 --- a/support/SkinnyNamespace.h +++ b/support/SkinnyNamespace.h @@ -12,4 +12,5 @@ namespace Skinny { SKINNY_EXPORT void changeSkin( QskAnimationHint hint = 500 ); SKINNY_EXPORT void changeFonts( int increment ); + SKINNY_EXPORT void init(); } From b8a9264c4fe789213cb0fe2473b15a974f45f79b Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 13 Apr 2022 07:23:36 +0200 Subject: [PATCH 17/27] github build action for Linux and Windows (#175) * initial github build action * Github actions: Install Qt 5.15 ... We use a specific Github Action for this, since the current Qt version shipping with Ubuntu is too old. * Github Action: Cache Qt installation * Github Action: Build on Linux and Windows Co-authored-by: Richard Spindler --- .github/workflows/qmake.yml | 85 +++++++++++++++++++++++++++++++++++++ README.md | 2 + 2 files changed, 87 insertions(+) create mode 100644 .github/workflows/qmake.yml diff --git a/.github/workflows/qmake.yml b/.github/workflows/qmake.yml new file mode 100644 index 00000000..ffc91214 --- /dev/null +++ b/.github/workflows/qmake.yml @@ -0,0 +1,85 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build-linux: + name: Linux build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Qt + id: cache-qt + uses: actions/cache@v1 # not v2! + with: + path: ../Qt + key: ${{ runner.os }}-QtCache + + - name: Install Qt + uses: jurplel/install-qt-action@v2 + with: + version: '5.15.2' + host: 'linux' + target: 'desktop' + install-deps: 'true' + modules: 'qtwebengine' + cached: ${{ steps.cache-qt.outputs.cache-hit }} + setup-python: 'true' + tools: '' + set-env: 'true' + tools-only: 'false' + + - name: Ubuntu and Qt version + run: | + cat /etc/issue + echo number of processors: $(nproc) + qmake -v + - name: qmake + run: qmake qskinny.pro + - name: make + run: make -j$(nproc) + + build-windows: + name: Windows build + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Qt + id: cache-qt + uses: actions/cache@v1 # not v2! + with: + path: ../Qt + key: ${{ runner.os }}-QtCache + + - name: Install Qt + uses: jurplel/install-qt-action@v2 + with: + version: '5.15.2' + host: 'windows' + target: 'desktop' + arch: 'win64_msvc2019_64' + install-deps: 'true' + modules: 'qtwebengine' + cached: ${{ steps.cache-qt.outputs.cache-hit }} + setup-python: 'true' + tools: '' + set-env: 'true' + tools-only: 'false' + + - uses: ilammy/msvc-dev-cmd@v1 + + - name: Qt version + run: qmake -v + shell: cmd + + - name: qmake + run: qmake qskinny.pro + shell: cmd + + - name: nmake + run: nmake + shell: cmd diff --git a/README.md b/README.md index 25e19754..dcdc8065 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # QSkinny +![](https://github.com/uwerat/qskinny/workflows/CI/badge.svg) + The (Q)Skinny library is a framework built on top of the Qt scene graph and very few core classes from Qt/Quick. It offers a set of lightweight controls, that can be used from C++ and/or QML. From 7693c8d91132e3ccd93290d503ee76c24bd644d7 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 13 Apr 2022 11:24:18 +0200 Subject: [PATCH 18/27] fix build on Windows (#176) * fix build on Windows fixes the following error from CI: common\QskAspect.cpp(199): error C2666: 'QFlags::operator &': 3 overloads have similar conversions D:\a\qskinny\Qt\5.15.2\msvc2019_64\include\QtCore/qflags.h(146): note: could be 'QFlags QFlags::operator &(Enum) noexcept const' with [ Enum=QskAspect::State ] D:\a\qskinny\Qt\5.15.2\msvc2019_64\include\QtCore/qflags.h(145): note: or 'QFlags QFlags::operator &(uint) noexcept const' D:\a\qskinny\Qt\5.15.2\msvc2019_64\include\QtCore/qflags.h(144): note: or 'QFlags QFlags::operator &(int) noexcept const' common\QskAspect.cpp(199): note: or 'built-in C++ operator&(QFlags::Int, quint16)' common\QskAspect.cpp(199): note: while trying to match the argument list '(QskAspect::States, const quint16)' * fix build on Windows fixes the following error from CI: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\include\memory(3124): error C2027: use of undefined type 'QskMenuSkinlet::PrivateData' D:\a\qskinny\qskinny\src\controls\QskMenuSkinlet.h(54): note: see declaration of 'QskMenuSkinlet::PrivateData' C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\include\memory(3123): note: while compiling class template member function 'void std::default_delete::operator ()(_Ty *) noexcept const' with [ _Ty=QskMenuSkinlet::PrivateData ] C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\include\memory(3233): note: see reference to function template instantiation 'void std::default_delete::operator ()(_Ty *) noexcept const' being compiled with [ _Ty=QskMenuSkinlet::PrivateData ] C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\include\memory(3160): note: see reference to class template instantiation 'std::default_delete' being compiled D:\a\qskinny\qskinny\src\controls\QskMenuSkinlet.h(55): note: see reference to class template instantiation 'std::unique_ptr>' being compiled C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\include\memory(3124): error C2338: can't delete an incomplete type C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\include\memory(3125): warning C4150: deletion of pointer to incomplete type 'QskMenuSkinlet::PrivateData'; no destructor called D:\a\qskinny\qskinny\src\controls\QskMenuSkinlet.h(54): note: see declaration of 'QskMenuSkinlet::PrivateData --- src/common/QskAspect.cpp | 2 +- src/controls/QskMenuSkinlet.cpp | 2 ++ src/controls/QskMenuSkinlet.h | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/QskAspect.cpp b/src/common/QskAspect.cpp index 6162df0e..80738393 100644 --- a/src/common/QskAspect.cpp +++ b/src/common/QskAspect.cpp @@ -194,7 +194,7 @@ static QByteArray qskStatesToString( for ( int i = 0; i < 16; i++ ) { - const quint16 mask = 1 << i; + const uint mask = 1 << i; if ( states & mask ) { diff --git a/src/controls/QskMenuSkinlet.cpp b/src/controls/QskMenuSkinlet.cpp index 6438b2b3..356fde4c 100644 --- a/src/controls/QskMenuSkinlet.cpp +++ b/src/controls/QskMenuSkinlet.cpp @@ -229,6 +229,8 @@ QskMenuSkinlet::QskMenuSkinlet( QskSkin* skin ) appendNodeRoles( { PanelRole } ); } +QskMenuSkinlet::~QskMenuSkinlet() = default; + QRectF QskMenuSkinlet::cursorRect( const QskSkinnable* skinnable, const QRectF& contentsRect, int index ) const { diff --git a/src/controls/QskMenuSkinlet.h b/src/controls/QskMenuSkinlet.h index 2738654a..bf90b604 100644 --- a/src/controls/QskMenuSkinlet.h +++ b/src/controls/QskMenuSkinlet.h @@ -19,7 +19,7 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet }; Q_INVOKABLE QskMenuSkinlet( QskSkin* = nullptr ); - ~QskMenuSkinlet() = default; + ~QskMenuSkinlet(); QRectF subControlRect( const QskSkinnable*, const QRectF&, QskAspect::Subcontrol ) const override; From 6d9dcbcf9101cd314eeefb62379fea40e3246b4e Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 13 Apr 2022 12:40:19 +0200 Subject: [PATCH 19/27] CI: Use jom to parallelize the build (#177) ... and use powershell after all --- .github/workflows/qmake.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/qmake.yml b/.github/workflows/qmake.yml index ffc91214..f2e05689 100644 --- a/.github/workflows/qmake.yml +++ b/.github/workflows/qmake.yml @@ -74,12 +74,12 @@ jobs: - name: Qt version run: qmake -v - shell: cmd - name: qmake run: qmake qskinny.pro - shell: cmd - - name: nmake - run: nmake - shell: cmd + - name: jom + run: | + Invoke-WebRequest -Uri "https://download.qt.io/official_releases/jom/jom.zip" -OutFile jom.zip + unzip jom.zip + .\jom From 6a84d4197f01ecf0e1ed7eaba2c9455e428d2fe1 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 13 Apr 2022 21:06:24 +0200 Subject: [PATCH 20/27] website: Add README on how to recreate the website (#179) Resolves #171 --- doc/generate-website.md | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 doc/generate-website.md diff --git a/doc/generate-website.md b/doc/generate-website.md new file mode 100644 index 00000000..121afe27 --- /dev/null +++ b/doc/generate-website.md @@ -0,0 +1,69 @@ +# Generating the website + +## Prerequisites + +You will need: + +1. The `documentation-xml-website` branch of the Edelhirsch QSkinny repository + at https://github.com/edelhirsch/qskinny/tree/documentation-xml-website . +1. A recent version of doxygen; The currently used version is 1.9.1 built from + github sources. The `doxygen` binary needs to be in the $PATH. +1. A recent version of doxybook2 with some custom patches. The script + `generate-website.sh` should download and build the right version, however + the script might need some adaptation of paths. + For reference, the required version can be found at + https://github.com/edelhirsch/doxybook2/tree/jekyll . +1. A recent version of Jekyll (see https://jekyllrb.com/), which will generate + the static html pages. This and other required packages can be installed via + ``` + gem install jekyll:3.9.0 + gem install bundler:2.1.4 + ``` + There might be some packages missing from the list above; in this case the + Gemfile in the qskinny-website repository might help. +1. Checkout the current website repository via + `git clone git@github.com:qskinny/qskinny.github.io.git` + +## Generating the website + +Generating the static HTML sites is done with the `generate-website.sh` script +in the `qskinny/doc` directory. The script has some hardcoded paths and probably +needs some adaptation to run correctly. + +It will do the following: + +1. Generate HTML from doxygen. This step is needed because for some reason when + generating XML from doxygen there are no images with dependency graphs. + *Note*: This step is only executed if the `html` folder doesn't exist, + because otherwise it would take too long. +1. Generate XML from doxygen. The generated XML is used with doxybook2 in the + next step. + *Note*: This step is only executed if the `xml` folder doesn't exist, + because otherwise it would take too long. +1. Generate markdown from XML with doxybook2. This markdown will be used by + Jekyll to either server the website content locally or generate static + HTML from it, see below. + +### Generating the website locally + +When the command line switch `-local` is used with the `generate-website.sh` +script, it will generate the content to a local folder `doxybook-out`. This is +meant to be able to copy selected files to the website directory at +`~/dev/qskinny-website`. +Otherwise, the script will copy the content to the website repository for +uploading (again, paths are hardcoded as of now). So when generating content +for the first time, just run the script without any switches, which should +generate the website to `~/dev/qskinny-website`. + +### Testing the website locally + +After having generated the website as described above, go to +`~/dev/qskinny-website` and run `jekyll serve --livereload`. This should start +a browser at http://127.0.0.1:4000/, which will display the website. + +### Generating the website publicly + +When the command line switch `-publish` is used, the script will automatically +generate a new version of the homepage and publish it at +https://qskinny.github.io . This wil only work with the proper user rights of +course. From eb771f83284ce97aad2de7640a75c1470a411b75 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 13 Apr 2022 21:07:00 +0200 Subject: [PATCH 21/27] CI: Add MacOS build (#178) --- .github/workflows/qmake.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.github/workflows/qmake.yml b/.github/workflows/qmake.yml index f2e05689..a53d68af 100644 --- a/.github/workflows/qmake.yml +++ b/.github/workflows/qmake.yml @@ -83,3 +83,39 @@ jobs: Invoke-WebRequest -Uri "https://download.qt.io/official_releases/jom/jom.zip" -OutFile jom.zip unzip jom.zip .\jom + + build-mac: + name: MacOS build + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Qt + id: cache-qt + uses: actions/cache@v1 # not v2! + with: + path: ../Qt + key: ${{ runner.os }}-QtCache + + - name: Install Qt + uses: jurplel/install-qt-action@v2 + with: + version: '5.15.2' + host: 'mac' + target: 'desktop' + install-deps: 'true' + modules: 'qtwebengine' + cached: ${{ steps.cache-qt.outputs.cache-hit }} + setup-python: 'true' + tools: '' + set-env: 'true' + tools-only: 'false' + + - name: MacOS and Qt version + run: | + sw_vers + echo number of processors: $(sysctl -n hw.ncpu) + qmake -v + - name: qmake + run: qmake qskinny.pro + - name: make + run: make -j$(sysctl -n hw.ncpu) From bf37fe000c6e1dcc6222405eb3a6c5f87764c163 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 14 Apr 2022 08:26:49 +0200 Subject: [PATCH 22/27] using QMetaObject instead of QTimer for delayed calls --- src/controls/QskSubWindowArea.cpp | 4 ++-- src/inputpanel/QskHunspellTextPredictor.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/controls/QskSubWindowArea.cpp b/src/controls/QskSubWindowArea.cpp index 66648eb5..90320f81 100644 --- a/src/controls/QskSubWindowArea.cpp +++ b/src/controls/QskSubWindowArea.cpp @@ -126,8 +126,8 @@ void QskSubWindowArea::itemChange( { // the child is not fully constructed // and we have to delay checking for sub windows - QTimer::singleShot( 0, this, - [ this ] { qskUpdateEventFilter( this ); } ); + QMetaObject::invokeMethod( this, + [ this ] { qskUpdateEventFilter( this ); }, Qt::QueuedConnection ); break; } diff --git a/src/inputpanel/QskHunspellTextPredictor.cpp b/src/inputpanel/QskHunspellTextPredictor.cpp index 77099176..0136380c 100644 --- a/src/inputpanel/QskHunspellTextPredictor.cpp +++ b/src/inputpanel/QskHunspellTextPredictor.cpp @@ -103,7 +103,8 @@ QskHunspellTextPredictor::QskHunspellTextPredictor( m_data->locale = locale; // make sure we call virtual functions: - QTimer::singleShot( 0, this, &QskHunspellTextPredictor::loadDictionaries ); + QMetaObject::invokeMethod( this, + &QskHunspellTextPredictor::loadDictionaries, Qt::QueuedConnection ); } QskHunspellTextPredictor::~QskHunspellTextPredictor() From 26c30373c47f6f90c775a8336a5d46f9592f7b55 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 15 Apr 2022 13:13:58 +0200 Subject: [PATCH 23/27] updated from Doxygen 1.9.3 ( using doxygen -u ) --- doc/Doxyfile | 313 +++++++++++++++++++++++++-------------------------- 1 file changed, 156 insertions(+), 157 deletions(-) diff --git a/doc/Doxyfile b/doc/Doxyfile index a68333bd..7ccbbb04 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.9.1 +# Doxyfile 1.9.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -93,14 +93,6 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. @@ -248,16 +240,16 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = "accessors=\par Access functions:^^" \ "subcontrols=\par Subcontrols:^^" \ @@ -307,8 +299,8 @@ OPTIMIZE_OUTPUT_SLICE = NO # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the # default for Fortran type files). For instance to make doxygen treat .inc files @@ -461,7 +453,7 @@ LOOKUP_CACHE_SIZE = 0 # than 0 to get more control over the balance between CPU load and processing # speed. At this moment only the input processing can be done using multiple # threads. Since this is still an experimental feature the default is set to 1, -# which efficively disables parallel processing. Please report any issues you +# which effectively disables parallel processing. Please report any issues you # encounter. Generating dot graphs in parallel is controlled by the # DOT_NUM_THREADS setting. # Minimum value: 0, maximum value: 32, default value: 1. @@ -605,6 +597,12 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -762,7 +760,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -808,18 +807,26 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = NO # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO @@ -845,7 +852,10 @@ WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = Doxygen.log @@ -885,10 +895,10 @@ INPUT_ENCODING = UTF-8 # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), -# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl, -# *.ucf, *.qsf and *.ice. +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = @@ -927,7 +937,7 @@ EXCLUDE_PATTERNS = *Private.* moc*.cpp *.moc # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test +# ANamespace::AClass, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* @@ -1104,44 +1114,6 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: -# http://clang.llvm.org/) for more accurate parsing at the cost of reduced -# performance. This can be particularly helpful with template rich C++ code for -# which doxygen's built-in parser lacks the necessary type information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = YES - -# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to -# YES then doxygen will add the directory of each input to the include path. -# The default value is: YES. - -CLANG_ADD_INC_PATHS = YES - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -# If clang assisted parsing is enabled you can provide the clang parser with the -# path to the directory containing a file called compile_commands.json. This -# file is the compilation database (see: -# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the -# options used when the source files were built. This is equivalent to -# specifying the -p option to a clang tool, such as clang-check. These options -# will then be passed to the parser. Any options specified with CLANG_OPTIONS -# will be added as well. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse_libclang=ON option for CMake. - -CLANG_DATABASE_PATH = - #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1253,7 +1225,7 @@ HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see +# this color. Hue is specified as an angle on a color-wheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. @@ -1263,7 +1235,7 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 30 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1345,6 +1317,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1370,8 +1349,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: -# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1530,16 +1513,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = YES + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1564,6 +1559,13 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + # If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg # tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see # https://inkscape.org) to generate formulas as SVG images instead of PNGs for @@ -1612,11 +1614,29 @@ FORMULA_MACROFILE = USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1629,15 +1649,21 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = @@ -1817,29 +1843,31 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1884,8 +1912,7 @@ USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode # command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# if errors occur, instead of asking the user for help. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1898,16 +1925,6 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # https://en.wikipedia.org/wiki/BibTeX and \cite for more info. @@ -1988,16 +2005,6 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -2094,15 +2101,6 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -2249,7 +2247,7 @@ SKIP_FUNCTION_MACROS = YES # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = # TODO: see https://www.qt.io/blog/2014/08/13/qt-weekly-17-linking-qt-classes-in-documentation-generated-with-doxygen +TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to @@ -2282,15 +2280,6 @@ EXTERNAL_PAGES = YES # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. @@ -2309,7 +2298,7 @@ HIDE_UNDOC_RELATIONS = YES # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO -# The default value is: YES. +# The default value is: NO. HAVE_DOT = YES @@ -2347,11 +2336,14 @@ DOT_FONTSIZE = 10 DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a +# graph for each documented class showing the direct and indirect inheritance +# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, +# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set +# to TEXT the direct and indirect inheritance relations will be shown as texts / +# links. +# Possible values are: NO, YES, TEXT and GRAPH. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES @@ -2480,6 +2472,13 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: @@ -2487,9 +2486,7 @@ DIRECTORY_GRAPH = YES # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, -# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, -# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, # png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and # png:gdiplus:gdiplus. # The default value is: png. @@ -2535,10 +2532,10 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = @@ -2600,6 +2597,8 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2608,8 +2607,8 @@ GENERATE_LEGEND = NO # If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. # -# Note: This setting is not only used for dot files but also for msc and -# plantuml temporary files. +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. DOT_CLEANUP = YES From 6dd3b44f52efec84fcee7891da1bb79e11470cf5 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 15 Apr 2022 13:19:52 +0200 Subject: [PATCH 24/27] placementPolicy as property --- doc/classes/QskControl.dox | 83 +++++++++++++++++++------------------- src/controls/QskControl.h | 1 + 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/doc/classes/QskControl.dox b/doc/classes/QskControl.dox index ee72dbc7..0a578f59 100644 --- a/doc/classes/QskControl.dox +++ b/doc/classes/QskControl.dox @@ -43,27 +43,6 @@ QQuickItem::focusOutEvent() */ -/*! - \enum QskControl::LayoutHint - - Hints, that can be used by the layout code - - \sa setLayoutHint(), testLayoutHint(), setLayoutHints(), layoutHints() - setAutoLayoutChildren(), QskLinearBox, QskGridBox, QskStackBox - - \var QskControl::RetainSizeWhenHidden - - When being enabled the layout code should retain the necessary space - for the control even when it is hidden. - - \saqt QSizePolicy::retainSizeWhenHidden() - - \var QskControl::LayoutWhenHidden - - When being enabled the layout code should set the geometry - to the control - even if it is not visible. -*/ - /*! \property QLocale QskControl::locale @@ -168,6 +147,14 @@ \property QskSizePolicy QskControl::sizePolicy \accessors sizePolicy(), setSizePolicy() + \sa placementPolicy +*/ + +/*! + \property QskPlacementPolicy QskControl::placementPolicy + + \accessors placementPolicy(), setPlacementPolicy() + \sa sizePolicy, effectivePlacementPolicy() */ /*! @@ -553,6 +540,40 @@ \return Height or width related part of the \ref sizePolicy property */ +/*! + \fn QskControl::setPlacementPolicy( QskPlacementPolicy ) + + \sa placementPolicy, effectivePlacementPolicy +*/ + +/*! + QskControl::setPlacementPolicy( QskPlacementPolicy::Policy, QskPlacementPolicy::Policy ) + + \sa placementPolicy, effectivePlacementPolicy + +/*! + void QskControl::setPlacementPolicy( Qsk::Visibilities, QskPlacementPolicy::Policy ); + + \sa placementPolicy, effectivePlacementPolicy() +*/ + +/*! + QskControl::placementPolicy() const; + + \sa placementPolicy, effectivePlacementPolicy() +*/ + +/*! + QskControl::placementPolicy( Qsk::Visibility ) const; + + \sa placementPolicy, effectivePlacementPolicy() +*/ + +/*! + QskControl::effectivePlacementPolicy() const; + +*/ + /*! \fn QskControl::setLayoutAlignmentHint @@ -563,26 +584,6 @@ */ -/*! - \fn QskControl::setLayoutHint - -*/ - -/*! - \fn QskControl::testLayoutHint - -*/ - -/*! - \fn QskControl::setLayoutHints - -*/ - -/*! - \fn QskControl::layoutHints - -*/ - /*! \fn QskControl::isVisibleToLayout diff --git a/src/controls/QskControl.h b/src/controls/QskControl.h index f59e541d..871343b9 100644 --- a/src/controls/QskControl.h +++ b/src/controls/QskControl.h @@ -47,6 +47,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable WRITE setBackground RESET resetBackground NOTIFY backgroundChanged ) Q_PROPERTY( QskSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy ) + Q_PROPERTY( QskSizePolicy placementPolicy READ placementPolicy WRITE setPlacementPolicy ) Q_PROPERTY( QSizeF minimumSize READ minimumSize WRITE setMinimumSize ) Q_PROPERTY( QSizeF maximumSize READ maximumSize WRITE setMaximumSize ) From 0b32b7887a5994b8b2cc56686acf8744eb3d2cd1 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 15 Apr 2022 13:22:58 +0200 Subject: [PATCH 25/27] doxygen texts --- doc/classes/QskNamespace.dox | 37 +++++++++++ doc/classes/QskPlacementPolicy.dox | 101 +++++++++++++++-------------- doc/classes/QskQuickItem.dox | 12 ++-- 3 files changed, 98 insertions(+), 52 deletions(-) create mode 100644 doc/classes/QskNamespace.dox diff --git a/doc/classes/QskNamespace.dox b/doc/classes/QskNamespace.dox new file mode 100644 index 00000000..f860a352 --- /dev/null +++ b/doc/classes/QskNamespace.dox @@ -0,0 +1,37 @@ +/*! + \namespace Qsk + + \ingroup Framework + + \brief Global definitions +*/ + +/*! + \enum Qsk::Direction + + \brief This enum type specifies a horizontal ot vertical direction + + \var Qsk::LeftToRight + Horizontally from left to right + + \var Qsk::RightToLeft + Horizontally from right to left + + \var Qsk::TopToBottom + Vertically from top to bottom + + \var Qsk::BottomToTop + Vertically from bottom to top +*/ + +/*! + \enum Qsk::Visibility + + \brief Visibility of an object + + \var Qsk::Visible + The object is visible + + \var Qsk::Hidden + The object is not visible +*/ diff --git a/doc/classes/QskPlacementPolicy.dox b/doc/classes/QskPlacementPolicy.dox index 62aefe76..e618d4ec 100644 --- a/doc/classes/QskPlacementPolicy.dox +++ b/doc/classes/QskPlacementPolicy.dox @@ -3,8 +3,8 @@ \ingroup Framework - QskPlacementPolicy is a hint for layout code how to deal with - the geometry of an item when being visible or hidden. + QskPlacementPolicy is a hint for layout code how to deal with + the geometry of an item depending on its visibility. \sa QskControl::placementPolicy(), qskPlacementPolicy() */ @@ -12,24 +12,23 @@ /*! \enum QskPlacementPolicy::Policy - Hint for the layout code how to deal with the geometry of an - item. QskPlacementPolicy has two values one for the visible, - the other for the hidden state. + Hint for the layout code how to deal with the geometry of an + item. QskPlacementPolicy has two values: one for the visible, + the other for the hidden state. \var QskPlacementPolicy::Ignore - Ignore the item for all type of layout calculations. + Ignore the item for all type of layout calculations \var QskPlacementPolicy::Reserve - Reseve space without giving the item its geometry. + Reseve space without giving the item its geometry \var QskPlacementPolicy::Adjust Reserve space and adjust the geometry of the item - \note QskPlacementPolicy::Reserve as hiddenPolicy() is equivalent - to what is offered by QSizePolicy::retainSizeWhenHidden(). + \sa visiblePolicy, hiddenPolicy */ /*! @@ -37,27 +36,27 @@ \brief Policy for the item, when being visible ( to its parent ) - - QskPlacementPolicy::Ignore + - QskPlacementPolicy::Ignore For situations where a parent takes care of the geometry for its children, - but exceptions need to be defined. F.e a focus indicator. + but the specific item should be omitted. F.e a focus indicator. - - QskPlacementPolicy::Reserve: + - QskPlacementPolicy::Reserve - There are not many relevant scenarios for this value. An - example might be when an item is inside of a grid layout, where all the - size hints should have an effect, but the final alignment of the item - inside of the cell has to be done manually. + There are not many relevant scenarios for reserving space for visible items + without adjusting them. An example might be when an item is inside of a + grid box, where all the size hints should have an effect, but the final + alignment of the item inside of the cell has to be done manually. - - QskPlacementPolicy::Adjust: + - QskPlacementPolicy::Adjust: The default value \accessors visiblePolicy(), setVisiblePolicy() - \sa hiddenPolicy, qskIsVisibleToParent() + \sa hiddenPolicy, QskQuickItem::isVisibleToParent(), qskIsVisibleToParent() \note QskPlacementPolicy::Ignore is stored in the transparentForPositioner - bit in QQuickItem and might have an impact on Qt/Quick layout code. + bit in QQuickItem and might have an impact on Qt/Quick layout code. */ /*! @@ -78,99 +77,107 @@ Sometimes an item wants to have its proper size even when being hidden. - \accessors visiblePolicy(), setVisiblePolicy() - \sa qskIsVisibleToParent() + \accessors hiddenPolicy(), setHiddenPolicy() + \sa visiblePolicy, QskQuickItem::isVisibleToParent(), qskIsVisibleToParent() \note QskPlacementPolicy::Ignore is stored in the transparentForPositioner bit in QQuickItem and might have an impact on Qt/Quick layout code. + + \note QskPlacementPolicy::Reserve is equivalent to what is offered by + \saqt QSizePolicy::retainSizeWhenHidden(). */ /*! \fn QskPlacementPolicy::QskPlacementPolicy() - visiblePolicy is set to QskPlacementPolicy::Adjust, - hiddenPolicy to QskPlacementPolicy::Ignore. + \brief Default constructor + + QskPlacementPolicy::Adjust is set for Qsk::Visible, while + QskPlacementPolicy::Ignore is used for Qsk::Hidden. + + \sa visiblePolicy, hiddenPolicy */ /*! \fn QskPlacementPolicy::QskPlacementPolicy( Policy policy ) - visiblePolicy and hiddenPolicy are set to policy + visiblePolicy and hiddenPolicy are set to policy */ /*! \fn QskPlacementPolicy::QskPlacementPolicy( Policy visiblePolicy, Policy hiddenPolicy ) - Initialization from visiblePolicy and hiddenPolicy + Initialization from visiblePolicy and hiddenPolicy */ /*! \fn QskPlacementPolicy::QskPlacementPolicy( Qsk::Visibilities visiblities, Policy policy ) - Initialize visiblePolicy and hiddenPolicy depending on visiblities + Initialize visiblePolicy and hiddenPolicy depending on visiblities */ -/* +/*! \fn QskPlacementPolicy::operator==( const QskPlacementPolicy& ) "Equal to" operator \sa operator!=(), operator<() */ -/* +/*! \fn QskPlacementPolicy::operator!=( const QskPlacementPolicy& ) - "Not equal to" operator + "Not equal to" operator \sa operator==(), operator<() */ -/* +/*! \fn QskPlacementPolicy::setPolicy( Qsk::Visibilities, Policy ) */ -*/ +/*! \fn QskPlacementPolicy::policy( Qsk::Visibility ) */ -/* +/*! \fn QskPlacementPolicy::isEffective() - \return true, when visiblePolicy or hiddenPolicy is not QskPlacementPolicy::Ignore - \sa isIgnoring() + \return true, when visiblePolicy or hiddenPolicy is not QskPlacementPolicy::Ignore + \sa isIgnoring() */ -/* +/*! \fn QskPlacementPolicy::isIgnoring( Qsk::Visibility ) - \return true, when visiblePolicy and hiddenPolicy is QskPlacementPolicy::Ignore - \sa isEffective() + + \return true, when visiblePolicy and hiddenPolicy are set to QskPlacementPolicy::Ignore + \sa isEffective() */ -/* +/*! \fn QskPlacementPolicy::isAdjusting( Qsk::Visibility ) - \return true, when QskPlacementPolicy::Adjust is set for the visibility + \return true, when QskPlacementPolicy::Adjust is set for the visibility */ -/* +/*! \fn QskPlacementPolicy::setVisiblePolicy( Policy ) - \sa visiblePolicy(), setHiddenPolicy() + \sa visiblePolicy(), setHiddenPolicy() */ -/* +/*! \fn QskPlacementPolicy::visiblePolicy() - \sa setVisiblePolicy(), hiddenPolicy() + \sa setVisiblePolicy(), hiddenPolicy() */ -/* +/*! \fn QskPlacementPolicy::setHiddenPolicy( Policy ) - \sa hiddenPolicy(), setVisiblePolicy() + \sa hiddenPolicy(), setVisiblePolicy() */ -/* +/*! \fn QskPlacementPolicy::hiddenPolicy() - \sa setHiddenPolicy(), visiblePolicy() + \sa setHiddenPolicy(), visiblePolicy() */ diff --git a/doc/classes/QskQuickItem.dox b/doc/classes/QskQuickItem.dox index b4c4750e..a7fcbf82 100644 --- a/doc/classes/QskQuickItem.dox +++ b/doc/classes/QskQuickItem.dox @@ -137,7 +137,7 @@ it is necessary to know which children would stay hidden when the container becomes visible. - \sa isVisibleToParent() + \sa setHidden(), show(), hide(), isVisibleToParent(), qskIsVisibleToParent() \saqt QQuickItem::setVisible() */ @@ -226,7 +226,7 @@ \return true once setVisible( false ) has been called - \sa visibleToParent + \sa visibleToParent(), qskIsVisibleToParent() \saqt QQuickItem::setVisible() */ @@ -562,7 +562,7 @@ An alternative way to call setVisible( true ). Useful for signal/slot connections - \sa hide() + \sa hide(), setHidden() \saqt QQuickItem::setVisible() */ @@ -579,8 +579,10 @@ /*! \fn QskQuickItem::setHidden - Convenience function, equivalent to setVisible( !on ). - \saqt QQuickItem::setVisible() + Convenience function, equivalent to setVisible( !on ). + + \sa show(), hide() + \saqt QQuickItem::setVisible() */ /*! From c4f5a4bc93954f98b49de6b401a9ca25743b68ee Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sat, 16 Apr 2022 11:32:51 +0200 Subject: [PATCH 26/27] compiler error fixed --- src/controls/QskControl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controls/QskControl.h b/src/controls/QskControl.h index 871343b9..418aab02 100644 --- a/src/controls/QskControl.h +++ b/src/controls/QskControl.h @@ -47,7 +47,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable WRITE setBackground RESET resetBackground NOTIFY backgroundChanged ) Q_PROPERTY( QskSizePolicy sizePolicy READ sizePolicy WRITE setSizePolicy ) - Q_PROPERTY( QskSizePolicy placementPolicy READ placementPolicy WRITE setPlacementPolicy ) + Q_PROPERTY( QskPlacementPolicy placementPolicy READ placementPolicy WRITE setPlacementPolicy ) Q_PROPERTY( QSizeF minimumSize READ minimumSize WRITE setMinimumSize ) Q_PROPERTY( QSizeF maximumSize READ maximumSize WRITE setMaximumSize ) From d52453311f0407bf564bd3f38ea230d3b5078692 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sat, 16 Apr 2022 12:25:39 +0200 Subject: [PATCH 27/27] heuristic for initializing the cascading property moved from skin to QskMenu --- skins/material/QskMaterialSkin.cpp | 3 +-- src/common/QskPlatform.cpp | 10 ++-------- src/controls/QskMenu.cpp | 3 ++- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 03b170ba..e496a556 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -237,8 +237,7 @@ void Editor::setupMenu() setGradient( Q::Panel, m_pal.baseColor ); - const bool isCascading = qskMaybeDesktopPlatform(); - setFlagHint( Q::Panel | A::Style, isCascading ); + setFlagHint( Q::Panel | A::Style, false ); // not cascading #if 0 setPadding( Q::Separator, QMarginsF( 10, 0, 10, 0 ) ); diff --git a/src/common/QskPlatform.cpp b/src/common/QskPlatform.cpp index 67fbfdf1..e94f9b57 100644 --- a/src/common/QskPlatform.cpp +++ b/src/common/QskPlatform.cpp @@ -42,16 +42,10 @@ const QPlatformIntegration* qskPlatformIntegration() bool qskMaybeDesktopPlatform() { - // this is what QC2 is doing for menus ? - -#if QT_VERSION >= QT_VERSION_CHECK( 5, 15, 0 ) -#if !QT_CONFIG(cursor) - return false; -#endif -#endif - +#if QT_CONFIG(cursor) if ( const auto platform = QGuiApplicationPrivate::platformIntegration() ) return platform->hasCapability( QPlatformIntegration::MultipleWindows ); +#endif return false; } diff --git a/src/controls/QskMenu.cpp b/src/controls/QskMenu.cpp index 9c1389f9..249765e4 100644 --- a/src/controls/QskMenu.cpp +++ b/src/controls/QskMenu.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,7 @@ QskMenu::~QskMenu() // has no effect as we do not offer submenus yet. TODO ... bool QskMenu::isCascading() const { - return flagHint( QskMenu::Panel | QskAspect::Style ); + return flagHint( QskMenu::Panel | QskAspect::Style, qskMaybeDesktopPlatform() ); } void QskMenu::setCascading( bool on )