From ce50d493122c29d68aa1171587548115ac024838 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sun, 3 Jun 2018 11:01:22 +0200 Subject: [PATCH] keyboard handling improved --- src/inputpanel/QskInputPanel.cpp | 26 +++---- src/inputpanel/QskVirtualKeyboard.cpp | 106 ++++++++++++++++---------- src/inputpanel/QskVirtualKeyboard.h | 2 + 3 files changed, 79 insertions(+), 55 deletions(-) diff --git a/src/inputpanel/QskInputPanel.cpp b/src/inputpanel/QskInputPanel.cpp index fc93c46d..6c70529e 100644 --- a/src/inputpanel/QskInputPanel.cpp +++ b/src/inputpanel/QskInputPanel.cpp @@ -198,26 +198,14 @@ void QskInputPanel::setPrediction( const QStringList& prediction ) void QskInputPanel::keyPressEvent( QKeyEvent* event ) { - // animate the corresponding key button TODO + int keyCode = -1; switch( event->key() ) { case Qt::Key_Return: case Qt::Key_Escape: { - Q_EMIT keySelected( event->key() ); - break; - } - - case Qt::Key_Shift: - case Qt::Key_Control: - case Qt::Key_Meta: - case Qt::Key_Alt: - case Qt::Key_AltGr: - case Qt::Key_CapsLock: - case Qt::Key_NumLock: - case Qt::Key_ScrollLock: - { + keyCode = event->key(); break; } @@ -226,11 +214,17 @@ void QskInputPanel::keyPressEvent( QKeyEvent* event ) const auto text = event->text(); if ( !text.isEmpty() ) - Q_EMIT keySelected( text[0].unicode() ); + keyCode = text[0].unicode(); else - Q_EMIT keySelected( event->key() ); + keyCode = event->key(); } } + + if ( m_data->keyboard->hasKey( keyCode ) ) + { + // animating the corresponding key button ??? + Q_EMIT keySelected( keyCode ); + } } #include "moc_QskInputPanel.cpp" diff --git a/src/inputpanel/QskVirtualKeyboard.cpp b/src/inputpanel/QskVirtualKeyboard.cpp index 1432f080..b379d625 100644 --- a/src/inputpanel/QskVirtualKeyboard.cpp +++ b/src/inputpanel/QskVirtualKeyboard.cpp @@ -9,6 +9,7 @@ #include #include +#include namespace { @@ -191,6 +192,27 @@ static bool qskIsAutorepeat( int key ) && key != Qt::Key_Mode_switch ); } +static QSet< int > qskKeyCodes( const QskVirtualKeyboardLayouts::Layout& layout ) +{ + QSet< int > codes; + codes.reserve( RowCount * ColumnCount ); + + for ( int mode = 0; mode <= QskVirtualKeyboard::ModeCount; mode++ ) + { + const auto& keyCodes = layout[ mode ]; + + for( int row = 0; row < RowCount; row++ ) + { + const auto& keys = keyCodes.data[ row ]; + + for ( int col = 0; col < ColumnCount; col++ ) + codes += keys[ col ]; + } + } + + return codes; +} + QSK_SUBCONTROL( QskVirtualKeyboard, Panel ) QSK_SUBCONTROL( QskVirtualKeyboard, ButtonPanel ) QSK_SUBCONTROL( QskVirtualKeyboard, ButtonText ) @@ -198,17 +220,11 @@ QSK_SUBCONTROL( QskVirtualKeyboard, ButtonText ) class QskVirtualKeyboard::PrivateData { public: - PrivateData(): - currentLayout( nullptr ), - mode( QskVirtualKeyboard::LowercaseMode ) - { - } - -public: - const QskVirtualKeyboardLayouts::Layout* currentLayout; - QskVirtualKeyboard::Mode mode; + const QskVirtualKeyboardLayouts::Layout* currentLayout = nullptr; + QskVirtualKeyboard::Mode mode = QskVirtualKeyboard::LowercaseMode; QVector< Button* > keyButtons; + QSet< int > keyCodes; }; QskVirtualKeyboard::QskVirtualKeyboard( QQuickItem* parent ): @@ -356,7 +372,7 @@ void QskVirtualKeyboard::updateLayout() const int key = keys[ col ]; auto button = m_data->keyButtons[ row * ColumnCount + col ]; - button->setVisible( key != Qt::Key( 0 ) ); + button->setVisible( key != 0 ); if ( button->isVisible() ) { @@ -376,6 +392,11 @@ void QskVirtualKeyboard::updateLayout() } } +bool QskVirtualKeyboard::hasKey( int keyCode ) const +{ + return m_data->keyCodes.contains( keyCode ); +} + void QskVirtualKeyboard::buttonPressed() { const auto button = static_cast< const Button* >( sender() ); @@ -419,26 +440,28 @@ void QskVirtualKeyboard::buttonPressed() void QskVirtualKeyboard::updateLocale( const QLocale& locale ) { + const QskVirtualKeyboardLayouts::Layout* newLayout = nullptr; + switch( locale.language() ) { case QLocale::Bulgarian: - m_data->currentLayout = &qskKeyboardLayouts.bg; + newLayout = &qskKeyboardLayouts.bg; break; case QLocale::Czech: - m_data->currentLayout = &qskKeyboardLayouts.cs; + newLayout = &qskKeyboardLayouts.cs; break; case QLocale::German: - m_data->currentLayout = &qskKeyboardLayouts.de; + newLayout = &qskKeyboardLayouts.de; break; case QLocale::Danish: - m_data->currentLayout = &qskKeyboardLayouts.da; + newLayout = &qskKeyboardLayouts.da; break; case QLocale::Greek: - m_data->currentLayout = &qskKeyboardLayouts.el; + newLayout = &qskKeyboardLayouts.el; break; case QLocale::English: @@ -449,11 +472,11 @@ void QskVirtualKeyboard::updateLocale( const QLocale& locale ) case QLocale::UnitedStates: case QLocale::UnitedStatesMinorOutlyingIslands: case QLocale::UnitedStatesVirginIslands: - m_data->currentLayout = &qskKeyboardLayouts.en_US; + newLayout = &qskKeyboardLayouts.en_US; break; default: - m_data->currentLayout = &qskKeyboardLayouts.en_GB; + newLayout = &qskKeyboardLayouts.en_GB; break; } @@ -461,81 +484,86 @@ void QskVirtualKeyboard::updateLocale( const QLocale& locale ) } case QLocale::Spanish: - m_data->currentLayout = &qskKeyboardLayouts.es; + newLayout = &qskKeyboardLayouts.es; break; case QLocale::Finnish: - m_data->currentLayout = &qskKeyboardLayouts.fi; + newLayout = &qskKeyboardLayouts.fi; break; case QLocale::French: - m_data->currentLayout = &qskKeyboardLayouts.fr; + newLayout = &qskKeyboardLayouts.fr; break; case QLocale::Hungarian: - m_data->currentLayout = &qskKeyboardLayouts.hu; + newLayout = &qskKeyboardLayouts.hu; break; case QLocale::Italian: - m_data->currentLayout = &qskKeyboardLayouts.it; + newLayout = &qskKeyboardLayouts.it; break; case QLocale::Japanese: - m_data->currentLayout = &qskKeyboardLayouts.ja; + newLayout = &qskKeyboardLayouts.ja; break; case QLocale::Latvian: - m_data->currentLayout = &qskKeyboardLayouts.lv; + newLayout = &qskKeyboardLayouts.lv; break; case QLocale::Lithuanian: - m_data->currentLayout = &qskKeyboardLayouts.lt; + newLayout = &qskKeyboardLayouts.lt; break; case QLocale::Dutch: - m_data->currentLayout = &qskKeyboardLayouts.nl; + newLayout = &qskKeyboardLayouts.nl; break; case QLocale::Portuguese: - m_data->currentLayout = &qskKeyboardLayouts.pt; + newLayout = &qskKeyboardLayouts.pt; break; case QLocale::Romanian: - m_data->currentLayout = &qskKeyboardLayouts.ro; + newLayout = &qskKeyboardLayouts.ro; break; case QLocale::Russia: - m_data->currentLayout = &qskKeyboardLayouts.ru; + newLayout = &qskKeyboardLayouts.ru; break; case QLocale::Slovenian: - m_data->currentLayout = &qskKeyboardLayouts.sl; + newLayout = &qskKeyboardLayouts.sl; break; case QLocale::Slovak: - m_data->currentLayout = &qskKeyboardLayouts.sk; + newLayout = &qskKeyboardLayouts.sk; break; case QLocale::Turkish: - m_data->currentLayout = &qskKeyboardLayouts.tr; + newLayout = &qskKeyboardLayouts.tr; break; case QLocale::Chinese: - m_data->currentLayout = &qskKeyboardLayouts.zh; + newLayout = &qskKeyboardLayouts.zh; break; #if 1 case QLocale::C: - m_data->currentLayout = &qskKeyboardLayouts.en_US; + newLayout = &qskKeyboardLayouts.en_US; break; #endif default: - qWarning() << "QskInputPanel: unsupported locale:" << locale; - m_data->currentLayout = &qskKeyboardLayouts.en_US; - + qWarning() << "QskVirtualKeyboard: unsupported locale:" << locale; + newLayout = &qskKeyboardLayouts.en_US; } - setMode( LowercaseMode ); - polish(); + if ( newLayout != m_data->currentLayout ) + { + m_data->currentLayout = newLayout; + m_data->keyCodes = qskKeyCodes( *newLayout ); + + setMode( LowercaseMode ); + polish(); + } } void QskVirtualKeyboard::setMode( QskVirtualKeyboard::Mode mode ) diff --git a/src/inputpanel/QskVirtualKeyboard.h b/src/inputpanel/QskVirtualKeyboard.h index c26dc054..07d3a9b9 100644 --- a/src/inputpanel/QskVirtualKeyboard.h +++ b/src/inputpanel/QskVirtualKeyboard.h @@ -43,6 +43,8 @@ public: virtual QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol ) const override; + bool hasKey( int keyCode ) const; + Q_SIGNALS: void modeChanged( Mode ); void keySelected( int keyCode );