keyboard: Fix focusing / tab key
This commit is contained in:
parent
412267cf9a
commit
ddea04445c
|
@ -208,9 +208,6 @@ QLocale QskInputContext::locale() const
|
||||||
|
|
||||||
void QskInputContext::setFocusObject( QObject* focusObject )
|
void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
{
|
{
|
||||||
if ( m_focusObject )
|
|
||||||
m_focusObject->removeEventFilter( this );
|
|
||||||
|
|
||||||
m_focusObject = focusObject;
|
m_focusObject = focusObject;
|
||||||
if ( !m_focusObject )
|
if ( !m_focusObject )
|
||||||
{
|
{
|
||||||
|
@ -229,8 +226,15 @@ void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
{
|
{
|
||||||
m_inputItem = focusQuickItem;
|
m_inputItem = focusQuickItem;
|
||||||
m_inputCompositionModel->setInputItem( m_inputItem ); // ### use a signal/slot connection
|
m_inputCompositionModel->setInputItem( m_inputItem ); // ### use a signal/slot connection
|
||||||
|
if( m_inputPanel )
|
||||||
|
m_inputPanel->setTabFence( false );
|
||||||
inputItemChanged = true;
|
inputItemChanged = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( m_inputPanel )
|
||||||
|
m_inputPanel->setTabFence( true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( inputItemChanged )
|
if( inputItemChanged )
|
||||||
|
@ -246,58 +250,9 @@ void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_focusObject->installEventFilter( this );
|
|
||||||
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
|
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskInputContext::eventFilter( QObject* object, QEvent* event )
|
|
||||||
{
|
|
||||||
if ( m_inputPanel && event->type() == QEvent::KeyPress )
|
|
||||||
{
|
|
||||||
auto keyEvent = static_cast< QKeyEvent* >( event );
|
|
||||||
const auto key = keyEvent->key();
|
|
||||||
switch ( key )
|
|
||||||
{
|
|
||||||
case Qt::Key_Tab:
|
|
||||||
case Qt::Key_Backtab:
|
|
||||||
if ( m_inputPanel->advanceFocus( key == Qt::Key_Tab ) )
|
|
||||||
{
|
|
||||||
keyEvent->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_Select:
|
|
||||||
case Qt::Key_Space:
|
|
||||||
// if there is a focused key, treat the key like a push button
|
|
||||||
if ( m_inputPanel->activateFocusKey() )
|
|
||||||
{
|
|
||||||
keyEvent->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_inputPanel && event->type() == QEvent::KeyRelease )
|
|
||||||
{
|
|
||||||
auto keyEvent = static_cast< QKeyEvent* >( event );
|
|
||||||
const auto key = keyEvent->key();
|
|
||||||
switch ( key )
|
|
||||||
{
|
|
||||||
case Qt::Key_Select:
|
|
||||||
case Qt::Key_Space:
|
|
||||||
if ( m_inputPanel->deactivateFocusKey() )
|
|
||||||
{
|
|
||||||
keyEvent->accept();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Inherited::eventFilter( object, event );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputContext::invokeAction( QInputMethod::Action action, int cursorPosition )
|
void QskInputContext::invokeAction( QInputMethod::Action action, int cursorPosition )
|
||||||
{
|
{
|
||||||
Q_UNUSED(cursorPosition);
|
Q_UNUSED(cursorPosition);
|
||||||
|
|
|
@ -36,9 +36,6 @@ public:
|
||||||
QLocale locale() const override;
|
QLocale locale() const override;
|
||||||
void setFocusObject( QObject* ) override;
|
void setFocusObject( QObject* ) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
bool eventFilter( QObject*, QEvent* ) override;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void emitAnimatingChanged();
|
void emitAnimatingChanged();
|
||||||
void handleCandidatesChanged();
|
void handleCandidatesChanged();
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <QskPushButton.h>
|
#include <QskPushButton.h>
|
||||||
#include <QskTextLabel.h>
|
#include <QskTextLabel.h>
|
||||||
#include <QskDialog.h>
|
#include <QskDialog.h>
|
||||||
#include <QFocusEvent>
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QStyleHints>
|
#include <QStyleHints>
|
||||||
#include <QskLinearBox.h>
|
#include <QskLinearBox.h>
|
||||||
|
@ -81,9 +80,7 @@ static constexpr const QskInputPanelLayouts qskInputPanelLayouts =
|
||||||
|
|
||||||
QSK_DECLARE_OPERATORS_FOR_FLAGS( Qt::Key ) // Must appear after the LOWER macro
|
QSK_DECLARE_OPERATORS_FOR_FLAGS( Qt::Key ) // Must appear after the LOWER macro
|
||||||
|
|
||||||
static const Qt::Key KeyPressed = static_cast< Qt::Key >( Qt::ShiftModifier );
|
|
||||||
static const Qt::Key KeyLocked = static_cast< Qt::Key >( Qt::ControlModifier );
|
static const Qt::Key KeyLocked = static_cast< Qt::Key >( Qt::ControlModifier );
|
||||||
static const Qt::Key KeyFocused = static_cast< Qt::Key >( Qt::MetaModifier );
|
|
||||||
static const Qt::Key KeyStates = static_cast< Qt::Key >( Qt::KeyboardModifierMask );
|
static const Qt::Key KeyStates = static_cast< Qt::Key >( Qt::KeyboardModifierMask );
|
||||||
|
|
||||||
static qreal qskKeyStretch( Qt::Key key )
|
static qreal qskKeyStretch( Qt::Key key )
|
||||||
|
@ -231,7 +228,6 @@ class QskInputPanel::PrivateData
|
||||||
PrivateData():
|
PrivateData():
|
||||||
currentLayout( nullptr ),
|
currentLayout( nullptr ),
|
||||||
mode( QskInputPanel::LowercaseMode ),
|
mode( QskInputPanel::LowercaseMode ),
|
||||||
focusKeyIndex( -1 ),
|
|
||||||
selectedGroup( -1 ),
|
selectedGroup( -1 ),
|
||||||
candidateOffset( 0 ),
|
candidateOffset( 0 ),
|
||||||
buttonsBox( nullptr ),
|
buttonsBox( nullptr ),
|
||||||
|
@ -243,7 +239,6 @@ class QskInputPanel::PrivateData
|
||||||
const QskInputPanelLayouts::Layout* currentLayout;
|
const QskInputPanelLayouts::Layout* currentLayout;
|
||||||
QskInputPanel::Mode mode;
|
QskInputPanel::Mode mode;
|
||||||
|
|
||||||
qint16 focusKeyIndex;
|
|
||||||
qint16 selectedGroup;
|
qint16 selectedGroup;
|
||||||
qint32 candidateOffset;
|
qint32 candidateOffset;
|
||||||
|
|
||||||
|
@ -282,7 +277,9 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
|
||||||
this, &QskInputPanel::updateLocale );
|
this, &QskInputPanel::updateLocale );
|
||||||
|
|
||||||
setFlag( ItemIsFocusScope, true );
|
setFlag( ItemIsFocusScope, true );
|
||||||
setTabFence( true );
|
|
||||||
|
// ### for some reason we never get focus when this is a tab fence:
|
||||||
|
// setTabFence( true );
|
||||||
|
|
||||||
setAutoLayoutChildren( true );
|
setAutoLayoutChildren( true );
|
||||||
|
|
||||||
|
@ -306,8 +303,6 @@ QskInputPanel::QskInputPanel( QQuickItem* parent ):
|
||||||
int keyIndex = m_data->keyTable[ m_data->mode ].indexOf( &keyData );
|
int keyIndex = m_data->keyTable[ m_data->mode ].indexOf( &keyData );
|
||||||
QskKeyButton* button = new QskKeyButton( keyIndex, this, rowBox );
|
QskKeyButton* button = new QskKeyButton( keyIndex, this, rowBox );
|
||||||
|
|
||||||
button->installEventFilter( this );
|
|
||||||
|
|
||||||
m_data->keyButtons.append( button );
|
m_data->keyButtons.append( button );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,94 +507,6 @@ void QskInputPanel::setPreeditCandidates( const QVector< Qt::Key >& candidates )
|
||||||
setCandidateOffset( 0 );
|
setCandidateOffset( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskInputPanel::advanceFocus( bool forward )
|
|
||||||
{
|
|
||||||
deactivateFocusKey();
|
|
||||||
auto offset = forward ? 1 : -1;
|
|
||||||
|
|
||||||
auto focusKeyIndex = m_data->focusKeyIndex;
|
|
||||||
|
|
||||||
Q_FOREVER
|
|
||||||
{
|
|
||||||
focusKeyIndex += offset;
|
|
||||||
|
|
||||||
if( focusKeyIndex < 0 || focusKeyIndex >= RowCount * KeyCount )
|
|
||||||
{
|
|
||||||
clearFocusKey();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto key = keyDataAt( focusKeyIndex ).key;
|
|
||||||
|
|
||||||
if( key && key != Qt::Key_unknown )
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_data->focusKeyIndex >= 0 )
|
|
||||||
{
|
|
||||||
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_data->focusKeyIndex = focusKeyIndex;
|
|
||||||
keyDataAt( m_data->focusKeyIndex ).key |= KeyFocused;
|
|
||||||
update();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QskInputPanel::activateFocusKey()
|
|
||||||
{
|
|
||||||
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
|
||||||
{
|
|
||||||
auto& keyData = keyDataAt( m_data->focusKeyIndex );
|
|
||||||
|
|
||||||
if( keyData.key & KeyPressed )
|
|
||||||
{
|
|
||||||
handleKey( m_data->focusKeyIndex );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
keyData.key |= KeyPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
update();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QskInputPanel::deactivateFocusKey()
|
|
||||||
{
|
|
||||||
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
|
||||||
{
|
|
||||||
auto& keyData = keyDataAt( m_data->focusKeyIndex );
|
|
||||||
|
|
||||||
if( keyData.key & KeyPressed )
|
|
||||||
{
|
|
||||||
keyData.key &= ~KeyPressed;
|
|
||||||
handleKey( m_data->focusKeyIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
update();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputPanel::clearFocusKey()
|
|
||||||
{
|
|
||||||
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
|
||||||
{
|
|
||||||
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_data->focusKeyIndex = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputPanel::setCandidateOffset( int candidateOffset )
|
void QskInputPanel::setCandidateOffset( int candidateOffset )
|
||||||
{
|
{
|
||||||
m_data->candidateOffset = candidateOffset;
|
m_data->candidateOffset = candidateOffset;
|
||||||
|
@ -665,27 +572,6 @@ void QskInputPanel::geometryChanged(
|
||||||
Q_EMIT keyboardRectChanged();
|
Q_EMIT keyboardRectChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskInputPanel::eventFilter( QObject* object, QEvent* event )
|
|
||||||
{
|
|
||||||
if( event->type() == QEvent::InputMethod )
|
|
||||||
{
|
|
||||||
QInputMethodEvent* inputMethodEvent = static_cast< QInputMethodEvent* >( event );
|
|
||||||
Q_EMIT inputMethodEventReceived( inputMethodEvent );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if( event->type() == QEvent::KeyPress )
|
|
||||||
{
|
|
||||||
// Return, Backspace and others are covered here (maybe because they don't carry a 'commit string'):
|
|
||||||
QKeyEvent* keyEvent = static_cast< QKeyEvent* >( event );
|
|
||||||
Q_EMIT keyEventReceived( keyEvent );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Inherited::eventFilter( object, event );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputPanel::updateLayout()
|
void QskInputPanel::updateLayout()
|
||||||
{
|
{
|
||||||
if( geometry().isNull() )
|
if( geometry().isNull() )
|
||||||
|
|
|
@ -112,10 +112,6 @@ public:
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setPreeditGroups( const QVector< Qt::Key >& );
|
void setPreeditGroups( const QVector< Qt::Key >& );
|
||||||
void setPreeditCandidates( const QVector< Qt::Key >& );
|
void setPreeditCandidates( const QVector< Qt::Key >& );
|
||||||
bool advanceFocus( bool = true );
|
|
||||||
bool activateFocusKey();
|
|
||||||
bool deactivateFocusKey();
|
|
||||||
void clearFocusKey();
|
|
||||||
|
|
||||||
void handleKey( int keyIndex );
|
void handleKey( int keyIndex );
|
||||||
KeyData& keyDataAt( int ) const;
|
KeyData& keyDataAt( int ) const;
|
||||||
|
@ -123,7 +119,6 @@ public Q_SLOTS:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void geometryChanged( const QRectF&, const QRectF& ) override;
|
virtual void geometryChanged( const QRectF&, const QRectF& ) override;
|
||||||
virtual bool eventFilter( QObject* object, QEvent* event ) override;
|
|
||||||
virtual void updateLayout() override;
|
virtual void updateLayout() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue