FocusIndicator, that becomes temporarily visible when using the

keyboard. Will become part of QskFocusIndicator later
This commit is contained in:
Uwe Rathmann 2023-11-30 08:42:51 +01:00
parent e67ee71224
commit c3c9405b65
4 changed files with 227 additions and 2 deletions

View File

@ -12,6 +12,7 @@ set(SOURCES
dialog/DialogPage.h dialog/DialogPage.cpp
listbox/ListBoxPage.h listbox/ListBoxPage.cpp
Page.h Page.cpp
FocusIndicator.h FocusIndicator.cpp
main.cpp
)
qt_add_resources(SOURCES icons.qrc)

View File

@ -0,0 +1,182 @@
#include "FocusIndicator.h"
#include <QskEvent.h>
#include <QskAnimationHint.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxShapeMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskRgbValue.h>
#include <QQuickWindow>
QSK_STATE( FocusIndicator, Concealed, QskAspect::FirstUserState )
class FocusIndicator::PrivateData
{
public:
void restartTimer( FocusIndicator* indicator, int ms )
{
if( timerId > 0 )
{
indicator->killTimer( timerId );
timerId = 0;
}
if ( ms > 0 )
timerId = indicator->startTimer( ms );
}
const int timeout = 4500;
int timerId = 0;
bool blockAutoRepeatKeyEvents = false;
};
FocusIndicator::FocusIndicator( QQuickItem* parent )
: Inherited( parent )
, m_data( new PrivateData() )
{
if( window() )
window()->installEventFilter( this );
#if 1
auto colors = boxBorderColorsHint( Panel );
setBoxBorderColorsHint( Panel | Concealed, QskRgb::Transparent );
setAnimationHint( Panel | QskAspect::Color, 200 );
setAnimationHint( Panel | QskAspect::Color | Concealed, 500 );
#endif
m_data->restartTimer( this, m_data->timeout );
}
FocusIndicator::~FocusIndicator()
{
}
void FocusIndicator::setConcealed( bool on )
{
if ( on == isConcealed() )
return;
setSkinStateFlag( Concealed, on );
int timeout = 0;
if ( !on )
timeout = m_data->timeout + animationHint( Panel | QskAspect::Color ).duration;
m_data->restartTimer( this, timeout );
Q_EMIT concealedChanged( on );
}
bool FocusIndicator::eventFilter( QObject* object, QEvent* event )
{
if( object != window() )
return Inherited::eventFilter( object, event );
switch( static_cast< int >( event->type() ) )
{
case QEvent::KeyPress:
{
const auto keyEvent = static_cast< QKeyEvent* >( event );
if( keyEvent->isAutoRepeat() && m_data->blockAutoRepeatKeyEvents )
return true;
if ( qskIsButtonPressKey( keyEvent ) )
{
if ( isConcealed() )
{
setConcealed( false );
return true;
}
return false;
}
if( qskFocusChainIncrement( keyEvent ) != 0 )
{
if ( isConcealed() )
{
setConcealed( false );
m_data->blockAutoRepeatKeyEvents = true;
return true;
}
else
{
// extending the timer
m_data->restartTimer( this, m_data->timeout );
return false;
}
}
m_data->blockAutoRepeatKeyEvents = false;
break;
}
case QEvent::KeyRelease:
{
if( m_data->blockAutoRepeatKeyEvents )
{
if( !static_cast< QKeyEvent* >( event )->isAutoRepeat() )
m_data->blockAutoRepeatKeyEvents = false;
return true;
}
break;
}
case QEvent::FocusOut:
{
setConcealed( true );
break;
}
case QEvent::FocusIn:
{
setConcealed( false );
break;
}
}
return Inherited::eventFilter( object, event );
}
void FocusIndicator::windowChangeEvent( QskWindowChangeEvent* event )
{
Inherited::windowChangeEvent( event );
if( event->oldWindow() )
event->oldWindow()->removeEventFilter( this );
if( event->window() )
event->window()->installEventFilter( this );
}
void FocusIndicator::timerEvent( QTimerEvent* event )
{
if( event->timerId() == m_data->timerId )
{
m_data->restartTimer( this, 0 );
if ( !isConcealed() )
{
setSkinStateFlag( Concealed, true );
Q_EMIT concealedChanged( true );
}
return;
}
Inherited::timerEvent( event );
}
bool FocusIndicator::isConcealed() const
{
return hasSkinState( Concealed );
}
#include "moc_FocusIndicator.cpp"

View File

@ -0,0 +1,41 @@
#pragma once
#include <QskFocusIndicator.h>
/*
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 concealed READ isConcealed
WRITE setConcealed NOTIFY concealedChanged )
using Inherited = QskFocusIndicator;
public:
QSK_STATES( Concealed )
FocusIndicator( QQuickItem* parent = nullptr );
~FocusIndicator() override;
bool isConcealed() const;
bool eventFilter( QObject*, QEvent* ) override;
public Q_SLOTS:
void setConcealed( bool );
Q_SIGNALS:
void concealedChanged( bool );
protected:
void windowChangeEvent( QskWindowChangeEvent* ) override;
void timerEvent( QTimerEvent* ) override;
private:
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskLinearBox.h"
#include "FocusIndicator.h"
#include "label/LabelPage.h"
#include "progressbar/ProgressBarPage.h"
#include "inputs/InputPage.h"
@ -16,6 +16,7 @@
#include <SkinnyShapeProvider.h>
#include <SkinnyNamespace.h>
#include "QskLinearBox.h"
#include <QskMainView.h>
#include <QskFocusIndicator.h>
#include <QskObjectCounter.h>
@ -296,7 +297,7 @@ int main( int argc, char* argv[] )
QskWindow window;
window.addItem( mainView );
window.addItem( new QskFocusIndicator() );
window.addItem( new FocusIndicator() );
window.resize( 800, 600 );
window.show();