diff --git a/examples/gallery/FocusIndicator.cpp b/examples/gallery/FocusIndicator.cpp index 1f24b798..16c6565c 100644 --- a/examples/gallery/FocusIndicator.cpp +++ b/examples/gallery/FocusIndicator.cpp @@ -2,51 +2,24 @@ #include #include -#include -#include -#include -#include #include #include - -QSK_STATE( FocusIndicator, Concealed, QskAspect::FirstUserState ) - -static inline bool qskIsExposingKeyPress( const QKeyEvent* event ) +static inline bool qskIsEnablingKey( const QKeyEvent* event ) { // what keys do we want have here ??? return qskIsButtonPressKey( event ) || qskFocusChainIncrement( event ); } -static void qskMaybeExpose( FocusIndicator* indicator, bool on ) -{ - Q_UNUSED( indicator ); - Q_UNUSED( on ); - -#if 0 - if ( on ) - { - if ( auto w = indicator->window() ) - { - if ( w->isExposed() && w->isActive() ) - indicator->setExposed( true ); - } - } - else - { - indicator->setExposed( false ); - } -#endif -} - class FocusIndicator::PrivateData { public: - inline bool isAutoConcealing() const { return timeout > 0; } + inline bool isAutoDisabling() const { return duration > 0; } + inline bool isAutoEnabling() const { return false; } - int timeout = 0; - QBasicTimer concealTimer; + int duration = 0; + QBasicTimer timer; bool blockAutoRepeatKeyEvents = false; }; @@ -55,85 +28,94 @@ FocusIndicator::FocusIndicator( QQuickItem* parent ) : Inherited( parent ) , m_data( new PrivateData() ) { -#if 1 - auto colors = boxBorderColorsHint( Panel ); - - setBoxBorderColorsHint( Panel | Concealed, QskRgb::Transparent ); - - setAnimationHint( Panel | QskAspect::Color, 200 ); - setAnimationHint( Panel | QskAspect::Color | Concealed, 500 ); -#endif - - setExposedTimeout( 4500 ); + setDuration( 4500 ); } FocusIndicator::~FocusIndicator() { } -void FocusIndicator::setExposedTimeout( int ms ) +void FocusIndicator::setDuration( int ms ) { ms = std::max( ms, 0 ); - if ( ms == m_data->timeout ) + if ( ms == m_data->duration ) return; - m_data->timeout = ms; + m_data->duration = ms; - if ( m_data->isAutoConcealing() ) + if ( m_data->isAutoDisabling() ) { if ( auto w = window() ) w->installEventFilter( this ); - if ( isExposed() ) + if ( isEnabled() ) { if ( isInitiallyPainted() ) - m_data->concealTimer.start( m_data->timeout, this ); + m_data->timer.start( m_data->duration, this ); else - setExposed( false ); + setEnabled( false ); } + + connect( this, &QQuickItem::enabledChanged, + this, &FocusIndicator::resetTimer ); } else { if ( auto w = window() ) w->removeEventFilter( this ); - setExposed( true ); + setEnabled( true ); + + disconnect( this, &QQuickItem::enabledChanged, + this, &FocusIndicator::resetTimer ); } - Q_EMIT exposedTimeoutChanged( ms ); + Q_EMIT durationChanged( ms ); } -int FocusIndicator::exposedTimeout() const +int FocusIndicator::duration() const { - return m_data->timeout; + return m_data->duration; } -void FocusIndicator::setExposed( bool on ) +void FocusIndicator::maybeEnable( bool on ) { - if ( on == isExposed() ) + if ( !m_data->isAutoEnabling() ) return; - setSkinStateFlag( Concealed, !on ); - - if ( m_data->isAutoConcealing() ) + if ( on ) { - if ( on ) + if ( auto w = window() ) + { + if ( w->isExposed() && w->isActive() ) + setEnabled( true ); + } + } + else + { + setEnabled( false ); + } +} + +void FocusIndicator::resetTimer() +{ + if ( m_data->isAutoDisabling() ) + { + if ( isEnabled() ) { const auto hint = animationHint( Panel | QskAspect::Color ); - m_data->concealTimer.start( m_data->timeout + hint.duration, this ); + m_data->timer.start( m_data->duration + hint.duration, this ); } else { - m_data->concealTimer.stop(); + m_data->timer.stop(); } } - - Q_EMIT exposedChanged( on ); } bool FocusIndicator::eventFilter( QObject* object, QEvent* event ) { - if( ( object != window() ) || !m_data->isAutoConcealing() ) + if( ( object != window() ) || !m_data->isAutoDisabling() ) return Inherited::eventFilter( object, event ); switch( static_cast< int >( event->type() ) ) @@ -141,12 +123,14 @@ bool FocusIndicator::eventFilter( QObject* object, QEvent* event ) case QEvent::KeyPress: case QEvent::KeyRelease: case QEvent::ShortcutOverride: - if ( m_data->concealTimer.isActive() ) + { + if ( m_data->timer.isActive() ) { // renew the exposed period - m_data->concealTimer.start( m_data->timeout, this ); + m_data->timer.start( m_data->duration, this ); } break; + } } switch( static_cast< int >( event->type() ) ) @@ -164,9 +148,9 @@ bool FocusIndicator::eventFilter( QObject* object, QEvent* event ) return true; } - if ( !isExposed() && qskIsExposingKeyPress( keyEvent ) ) + if ( !isEnabled() && qskIsEnablingKey( keyEvent ) ) { - setExposed( true ); + setEnabled( true ); m_data->blockAutoRepeatKeyEvents = true; return true; } @@ -192,7 +176,7 @@ bool FocusIndicator::eventFilter( QObject* object, QEvent* event ) case QEvent::FocusIn: case QEvent::FocusOut: { - qskMaybeExpose( this, event->type() != QEvent::FocusOut ); + maybeEnable( event->type() != QEvent::FocusOut ); break; } } @@ -204,7 +188,7 @@ void FocusIndicator::windowChangeEvent( QskWindowChangeEvent* event ) { Inherited::windowChangeEvent( event ); - if ( m_data->isAutoConcealing() ) + if ( m_data->isAutoDisabling() ) { if ( auto w = event->oldWindow() ) w->removeEventFilter( this ); @@ -212,18 +196,18 @@ void FocusIndicator::windowChangeEvent( QskWindowChangeEvent* event ) if( auto w = event->window() ) { w->installEventFilter( this ); - qskMaybeExpose( this, true ); + maybeEnable( true ); } } } void FocusIndicator::timerEvent( QTimerEvent* event ) { - if ( m_data->isAutoConcealing() ) + if ( m_data->isAutoDisabling() ) { - if( event->timerId() == m_data->concealTimer.timerId() ) + if( event->timerId() == m_data->timer.timerId() ) { - setExposed( false ); + setEnabled( false ); return; } } @@ -231,9 +215,4 @@ void FocusIndicator::timerEvent( QTimerEvent* event ) Inherited::timerEvent( event ); } -bool FocusIndicator::isExposed() const -{ - return !hasSkinState( Concealed ); -} - #include "moc_FocusIndicator.cpp" diff --git a/examples/gallery/FocusIndicator.h b/examples/gallery/FocusIndicator.h index 718845bb..6a0238f8 100644 --- a/examples/gallery/FocusIndicator.h +++ b/examples/gallery/FocusIndicator.h @@ -2,59 +2,35 @@ #include -/* - A focus indicator, that becomes temporarily visible when using the keyboard - It is intended to move the code to QskFocusIndicator later. - */ class FocusIndicator : public QskFocusIndicator { Q_OBJECT - Q_PROPERTY( bool exposed READ isExposed - WRITE setExposed NOTIFY exposedChanged ) - - Q_PROPERTY( int exposedTimeout READ exposedTimeout - WRITE setExposedTimeout NOTIFY exposedTimeoutChanged ) + Q_PROPERTY( int duration READ duration + WRITE setDuration NOTIFY durationChanged ) using Inherited = QskFocusIndicator; public: - QSK_STATES( Concealed ) - FocusIndicator( QQuickItem* parent = nullptr ); ~FocusIndicator() override; - bool isExposed() const; - bool isConcealed() const; - bool eventFilter( QObject*, QEvent* ) override; - void setExposedTimeout( int ms ); - int exposedTimeout() const; - - public Q_SLOTS: - void setExposed( bool = true ); - void setConcealed( bool = true ); + void setDuration( int ms ); + int duration() const; Q_SIGNALS: - void exposedChanged( bool ); - void exposedTimeoutChanged( int ); + void durationChanged( int ); protected: void windowChangeEvent( QskWindowChangeEvent* ) override; void timerEvent( QTimerEvent* ) override; private: + void resetTimer(); + void maybeEnable( bool ); + class PrivateData; std::unique_ptr< PrivateData > m_data; }; - -inline void FocusIndicator::setConcealed( bool on ) -{ - setExposed( !on ); -} - -inline bool FocusIndicator::isConcealed() const -{ - return !isExposed(); -} diff --git a/skins/fluent2/QskFluent2Skin.cpp b/skins/fluent2/QskFluent2Skin.cpp index 4f5de05d..0e42ef5f 100644 --- a/skins/fluent2/QskFluent2Skin.cpp +++ b/skins/fluent2/QskFluent2Skin.cpp @@ -646,9 +646,18 @@ void Editor::setupFocusIndicatorColors( QskAspect::Section section, const QskFluent2Theme& theme ) { using Q = QskFocusIndicator; + using A = QskAspect; + const auto& pal = theme.palette; - setBoxBorderColors( Q::Panel | section, pal.strokeColor.focus.outer ); + const auto aspect = Q::Panel | section; + const auto color = pal.strokeColor.focus.outer; + + setBoxBorderColors( aspect, color ); + setBoxBorderColors( aspect | Q::Disabled, QskRgb::toTransparent( color, 0 ) ); + + setAnimation( Q::Panel | A::Color, 200 ); + setAnimation( Q::Panel | A::Color | Q::Disabled, 500 ); } void Editor::setupListViewMetrics() diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 19530b32..abcdac21 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -555,12 +555,19 @@ void Editor::setupProgressRing() void Editor::setupFocusIndicator() { using Q = QskFocusIndicator; + using A = QskAspect; setPadding( Q::Panel, 5 ); setBoxBorderMetrics( Q::Panel, 2 ); setBoxShape( Q::Panel, 4 ); setGradient( Q::Panel, Qt::transparent ); + setBoxBorderColors( Q::Panel, m_pal.highlighted ); + setBoxBorderColors( Q::Panel | Q::Disabled, + QskRgb::toTransparent( m_pal.highlighted, 0 ) ); + + setAnimation( Q::Panel | A::Color, 200 ); + setAnimation( Q::Panel | A::Color | Q::Disabled, 500 ); } void Editor::setupSeparator()