diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index b2b03bca..fc25f8cf 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -49,8 +49,6 @@ static inline bool qskMaybeGesture( QQuickItem* item, QskControl::QskControl( QQuickItem* parent ) : QskQuickItem( *( new QskControlPrivate() ), parent ) { - Inherited::setActiveFocusOnTab( false ); - if ( parent ) { // inheriting attributes from parent @@ -91,55 +89,6 @@ bool QskControl::autoLayoutChildren() const return d_func()->autoLayoutChildren; } -void QskControl::setWheelEnabled( bool on ) -{ - Q_D( QskControl ); - if ( on != d->isWheelEnabled ) - { - d->isWheelEnabled = on; - Q_EMIT wheelEnabledChanged(); - } -} - -bool QskControl::isWheelEnabled() const -{ - return d_func()->isWheelEnabled; -} - -void QskControl::setFocusPolicy( Qt::FocusPolicy policy ) -{ - Q_D( QskControl ); - if ( policy != d->focusPolicy ) - { - d->focusPolicy = ( policy & ~Qt::TabFocus ); - - const bool tabFocus = policy & Qt::TabFocus; - - if ( !tabFocus && window() ) - { - // Removing the activeFocusItem from the focus tab chain is not possible - if ( window()->activeFocusItem() == this ) - { - if ( auto focusItem = nextItemInFocusChain( true ) ) - focusItem->setFocus( true ); - } - } - - Inherited::setActiveFocusOnTab( tabFocus ); - - Q_EMIT focusPolicyChanged(); - } -} - -Qt::FocusPolicy QskControl::focusPolicy() const -{ - uint policy = d_func()->focusPolicy; - if ( Inherited::activeFocusOnTab() ) - policy |= Qt::TabFocus; - - return static_cast< Qt::FocusPolicy >( policy ); -} - void QskControl::setBackgroundColor( const QColor& color ) { setBackground( QskGradient( color ) ); @@ -857,7 +806,7 @@ bool QskControl::childMouseEventFilter( QQuickItem* child, QEvent* event ) { /* The strategy implemented in many classes of the Qt development is - to analyze the events without blocking the handling of the child. + to analyze the events without blocking the handling of the child. Once a gesture is detected the gesture handling trys to steal the mouse grab hoping for the child to abort its operation. diff --git a/src/controls/QskControl.h b/src/controls/QskControl.h index 41793c87..906d915d 100644 --- a/src/controls/QskControl.h +++ b/src/controls/QskControl.h @@ -32,12 +32,6 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable Q_PROPERTY( bool autoLayoutChildren READ autoLayoutChildren WRITE setAutoLayoutChildren ) - Q_PROPERTY( Qt::FocusPolicy focusPolicy READ focusPolicy - WRITE setFocusPolicy NOTIFY focusPolicyChanged ) - - Q_PROPERTY( bool wheelEnabled READ isWheelEnabled - WRITE setWheelEnabled NOTIFY wheelEnabledChanged ) - Q_PROPERTY( bool visibleToLayout READ isVisibleToLayout ) Q_PROPERTY( QskMargins margins READ margins @@ -95,12 +89,6 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable void setAutoLayoutChildren( bool ); bool autoLayoutChildren() const; - void setWheelEnabled( bool ); - bool isWheelEnabled() const; - - void setFocusPolicy( Qt::FocusPolicy ); - Qt::FocusPolicy focusPolicy() const; - void setSection( QskAspect::Section ); void resetSection(); QskAspect::Section section() const override final; @@ -180,8 +168,6 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable void marginsChanged( const QMarginsF& ); void focusIndicatorRectChanged(); void localeChanged( const QLocale& ); - void focusPolicyChanged(); - void wheelEnabledChanged(); public Q_SLOTS: void setLocale( const QLocale& ); @@ -209,7 +195,6 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable virtual QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const; private: - void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy void updateInputMethod( Qt::InputMethodQueries ) = delete; // use qskUpdateInputMethod QSGNode* updateItemPaintNode( QSGNode* ) override final; diff --git a/src/controls/QskControlPrivate.cpp b/src/controls/QskControlPrivate.cpp index c8608dc4..d8f402ba 100644 --- a/src/controls/QskControlPrivate.cpp +++ b/src/controls/QskControlPrivate.cpp @@ -150,8 +150,6 @@ QskControlPrivate::QskControlPrivate() , explicitLocale( false ) , explicitSection( false ) , autoLayoutChildren( false ) - , focusPolicy( Qt::NoFocus ) - , isWheelEnabled( false ) , blockLayoutRequestEvents( true ) { } diff --git a/src/controls/QskControlPrivate.h b/src/controls/QskControlPrivate.h index 239201a5..9e39d8ad 100644 --- a/src/controls/QskControlPrivate.h +++ b/src/controls/QskControlPrivate.h @@ -59,9 +59,6 @@ class QskControlPrivate : public QskQuickItemPrivate bool autoLayoutChildren : 1; - uint focusPolicy : 4; - bool isWheelEnabled : 1; - mutable bool blockLayoutRequestEvents : 1; }; diff --git a/src/controls/QskQuickItem.cpp b/src/controls/QskQuickItem.cpp index 36c71d77..0ca67380 100644 --- a/src/controls/QskQuickItem.cpp +++ b/src/controls/QskQuickItem.cpp @@ -171,6 +171,7 @@ QskQuickItem::QskQuickItem( QskQuickItemPrivate& dd, QQuickItem* parent ) : QQuickItem( dd, parent ) { setFlag( QQuickItem::ItemHasContents, true ); + Inherited::setActiveFocusOnTab( false ); if ( dd.updateFlags & QskQuickItem::DeferredUpdate ) qskFilterWindow( window() ); @@ -349,6 +350,55 @@ bool QskQuickItem::isTabFence() const return d_func()->isTabFence; } +void QskQuickItem::setFocusPolicy( Qt::FocusPolicy policy ) +{ + Q_D( QskQuickItem ); + if ( policy != d->focusPolicy ) + { + d->focusPolicy = ( policy & ~Qt::TabFocus ); + + const bool tabFocus = policy & Qt::TabFocus; + + if ( !tabFocus && window() ) + { + // Removing the activeFocusItem from the focus tab chain is not possible + if ( window()->activeFocusItem() == this ) + { + if ( auto focusItem = nextItemInFocusChain( true ) ) + focusItem->setFocus( true ); + } + } + + Inherited::setActiveFocusOnTab( tabFocus ); + + Q_EMIT focusPolicyChanged( focusPolicy() ); + } +} + +Qt::FocusPolicy QskQuickItem::focusPolicy() const +{ + uint policy = d_func()->focusPolicy; + if ( Inherited::activeFocusOnTab() ) + policy |= Qt::TabFocus; + + return static_cast< Qt::FocusPolicy >( policy ); +} + +void QskQuickItem::setWheelEnabled( bool on ) +{ + Q_D( QskQuickItem ); + if ( on != d->wheelEnabled ) + { + d->wheelEnabled = on; + Q_EMIT wheelEnabledChanged( on ); + } +} + +bool QskQuickItem::isWheelEnabled() const +{ + return d_func()->wheelEnabled; +} + void QskQuickItem::setPolishOnResize( bool on ) { Q_D( QskQuickItem ); @@ -937,7 +987,7 @@ QSGNode* QskQuickItem::updatePaintNode( QSGNode* node, UpdatePaintNodeData* data it has already been allocated. When deleting it we have a dangling pointer. instead of the new one. - To avoid creashes for the second situation we manually clear d->paintNode. + To avoid creashes for the second situation we manually clear d->paintNode. */ d->paintNode = nullptr; #endif diff --git a/src/controls/QskQuickItem.h b/src/controls/QskQuickItem.h index 02f1807f..5fdfe10c 100644 --- a/src/controls/QskQuickItem.h +++ b/src/controls/QskQuickItem.h @@ -26,6 +26,12 @@ class QSK_EXPORT QskQuickItem : public QQuickItem Q_PROPERTY( bool polishOnResize READ polishOnResize WRITE setPolishOnResize NOTIFY itemFlagsChanged FINAL ) + Q_PROPERTY( Qt::FocusPolicy focusPolicy READ focusPolicy + WRITE setFocusPolicy NOTIFY focusPolicyChanged ) + + Q_PROPERTY( bool wheelEnabled READ isWheelEnabled + WRITE setWheelEnabled NOTIFY wheelEnabledChanged ) + Q_PROPERTY( bool visibleToParent READ isVisibleToParent ) Q_PROPERTY( bool hasChildItems READ hasChildItems ) Q_PROPERTY( bool initiallyPainted READ isInitiallyPainted ) @@ -75,9 +81,15 @@ class QSK_EXPORT QskQuickItem : public QQuickItem void setPolishOnResize( bool ); bool polishOnResize() const; + void setFocusPolicy( Qt::FocusPolicy ); + Qt::FocusPolicy focusPolicy() const; + void setTabFence( bool ); bool isTabFence() const; + void setWheelEnabled( bool ); + bool isWheelEnabled() const; + void setLayoutMirroring( bool on, bool childrenInherit = false ); void resetLayoutMirroring(); bool layoutMirroring() const; @@ -85,9 +97,9 @@ class QSK_EXPORT QskQuickItem : public QQuickItem void resetUpdateFlags(); UpdateFlags updateFlags() const; - Q_INVOKABLE void setUpdateFlag( UpdateFlag, bool on = true ); - Q_INVOKABLE void resetUpdateFlag( UpdateFlag ); - Q_INVOKABLE bool testUpdateFlag( UpdateFlag ) const; + void setUpdateFlag( UpdateFlag, bool on = true ); + void resetUpdateFlag( UpdateFlag ); + bool testUpdateFlag( UpdateFlag ) const; void classBegin() override; void componentComplete() override; @@ -100,6 +112,9 @@ class QSK_EXPORT QskQuickItem : public QQuickItem bool maybeUnresized() const; Q_SIGNALS: + void wheelEnabledChanged( bool ); + void focusPolicyChanged( Qt::FocusPolicy ); + void itemFlagsChanged(); void updateFlagsChanged( UpdateFlags ); @@ -158,6 +173,7 @@ class QSK_EXPORT QskQuickItem : public QQuickItem */ void childrenRect() = delete; + void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy void applyUpdateFlag( UpdateFlag, bool on ); QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override final; diff --git a/src/controls/QskQuickItemPrivate.cpp b/src/controls/QskQuickItemPrivate.cpp index bdfcb19e..2310f359 100644 --- a/src/controls/QskQuickItemPrivate.cpp +++ b/src/controls/QskQuickItemPrivate.cpp @@ -21,6 +21,8 @@ QskQuickItemPrivate::QskQuickItemPrivate() , blockedImplicitSize( true ) , clearPreviousNodes( false ) , initiallyPainted( false ) + , wheelEnabled( false ) + , focusPolicy( Qt::NoFocus ) { if ( updateFlags & QskQuickItem::DeferredLayout ) { diff --git a/src/controls/QskQuickItemPrivate.h b/src/controls/QskQuickItemPrivate.h index 615b3df3..8fff90c9 100644 --- a/src/controls/QskQuickItemPrivate.h +++ b/src/controls/QskQuickItemPrivate.h @@ -57,6 +57,9 @@ class QskQuickItemPrivate : public QQuickItemPrivate bool clearPreviousNodes : 1; bool initiallyPainted : 1; + bool wheelEnabled : 1; + + uint focusPolicy : 4; }; #endif diff --git a/src/controls/QskSetup.cpp b/src/controls/QskSetup.cpp index 4df5ae3d..b910cf81 100644 --- a/src/controls/QskSetup.cpp +++ b/src/controls/QskSetup.cpp @@ -4,7 +4,7 @@ *****************************************************************************/ #include "QskSetup.h" -#include "QskControl.h" +#include "QskQuickItem.h" #include "QskGraphicProviderMap.h" #include "QskSkinManager.h" #include "QskSkin.h" @@ -164,7 +164,7 @@ QskGraphicProvider* QskSetup::graphicProvider( const QString& providerId ) const bool QskSetup::eventFilter( QObject* object, QEvent* event ) { - if ( auto control = qskControlCast( object ) ) + if ( auto qskItem = qobject_cast< QskQuickItem* >( object ) ) { /* Qt::FocusPolicy has always been there with widgets, got lost with @@ -186,7 +186,7 @@ bool QskSetup::eventFilter( QObject* object, QEvent* event ) case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: { - if ( ( control->focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus ) + if ( ( qskItem->focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus ) { const bool focusOnRelease = QGuiApplication::styleHints()->setFocusOnTouchRelease(); @@ -194,19 +194,19 @@ bool QskSetup::eventFilter( QObject* object, QEvent* event ) if ( focusOnRelease ) { if ( event->type() == QEvent::MouseButtonRelease ) - control->forceActiveFocus( Qt::MouseFocusReason ); + qskItem->forceActiveFocus( Qt::MouseFocusReason ); } else { if ( event->type() == QEvent::MouseButtonPress ) - control->forceActiveFocus( Qt::MouseFocusReason ); + qskItem->forceActiveFocus( Qt::MouseFocusReason ); } } break; } case QEvent::Wheel: { - if ( !control->isWheelEnabled() ) + if ( !qskItem->isWheelEnabled() ) { /* We block further processing of the event. This is in line @@ -218,8 +218,8 @@ bool QskSetup::eventFilter( QObject* object, QEvent* event ) return true; } - if ( ( control->focusPolicy() & Qt::WheelFocus ) == Qt::WheelFocus ) - control->forceActiveFocus( Qt::MouseFocusReason ); + if ( ( qskItem->focusPolicy() & Qt::WheelFocus ) == Qt::WheelFocus ) + qskItem->forceActiveFocus( Qt::MouseFocusReason ); break; }