input panel formatting
This commit is contained in:
parent
2f2d5cf122
commit
2e3834acf9
|
@ -37,8 +37,10 @@ namespace
|
||||||
|
|
||||||
QskInputPanel::KeyData* qskKeyDataAt( KeyTable& table, qreal x, qreal y )
|
QskInputPanel::KeyData* qskKeyDataAt( KeyTable& table, qreal x, qreal y )
|
||||||
{
|
{
|
||||||
if ( x < 0 || x > 1 || y < 0 || y > 1 )
|
if( x < 0 || x > 1 || y < 0 || y > 1 )
|
||||||
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
auto rowIndex = size_t( std::floor( y * QskInputPanel::RowCount ) );
|
auto rowIndex = size_t( std::floor( y * QskInputPanel::RowCount ) );
|
||||||
auto columnIndex = size_t( std::floor( x * QskInputPanel::KeyCount ) );
|
auto columnIndex = size_t( std::floor( x * QskInputPanel::KeyCount ) );
|
||||||
|
@ -46,40 +48,51 @@ namespace
|
||||||
Q_FOREVER
|
Q_FOREVER
|
||||||
{
|
{
|
||||||
const auto rect = table.data[ rowIndex ][ columnIndex ].rect;
|
const auto rect = table.data[ rowIndex ][ columnIndex ].rect;
|
||||||
if ( rect.contains( x, y ) )
|
|
||||||
|
if( rect.contains( x, y ) )
|
||||||
|
{
|
||||||
return &table.data[ rowIndex ][ columnIndex ];
|
return &table.data[ rowIndex ][ columnIndex ];
|
||||||
|
}
|
||||||
|
|
||||||
// Look up/down
|
// Look up/down
|
||||||
if ( y < rect.top() )
|
if( y < rect.top() )
|
||||||
|
{
|
||||||
|
if( rowIndex == 0 )
|
||||||
{
|
{
|
||||||
if ( rowIndex == 0 )
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rowIndex -= 1;
|
rowIndex -= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ( y > rect.bottom() )
|
else if( y > rect.bottom() )
|
||||||
|
{
|
||||||
|
if( rowIndex == QskInputPanel::RowCount - 1 )
|
||||||
{
|
{
|
||||||
if ( rowIndex == QskInputPanel::RowCount - 1 )
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rowIndex += 1;
|
rowIndex += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look left/right
|
// Look left/right
|
||||||
if ( x < rect.left() )
|
if( x < rect.left() )
|
||||||
|
{
|
||||||
|
if( columnIndex == 0 )
|
||||||
{
|
{
|
||||||
if ( columnIndex == 0 )
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
columnIndex -= 1;
|
columnIndex -= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ( x > rect.right() )
|
else if( x > rect.right() )
|
||||||
|
{
|
||||||
|
if( columnIndex == QskInputPanel::KeyCount - 1 )
|
||||||
{
|
{
|
||||||
if ( columnIndex == QskInputPanel::KeyCount - 1 )
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
columnIndex += 1;
|
columnIndex += 1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -130,7 +143,7 @@ struct QskInputPanelLayouts
|
||||||
#define LOWER(x) Qt::Key(x + 32) // Convert an uppercase key to lowercase
|
#define LOWER(x) Qt::Key(x + 32) // Convert an uppercase key to lowercase
|
||||||
static constexpr const QskInputPanelLayouts qskInputPanelLayouts =
|
static constexpr const QskInputPanelLayouts qskInputPanelLayouts =
|
||||||
{
|
{
|
||||||
#include "QskInputPanelLayouts.cpp"
|
#include "QskInputPanelLayouts.cpp"
|
||||||
};
|
};
|
||||||
#undef LOWER
|
#undef LOWER
|
||||||
|
|
||||||
|
@ -143,7 +156,7 @@ static const Qt::Key KeyStates = static_cast< Qt::Key >( Qt::KeyboardModifierMa
|
||||||
|
|
||||||
static qreal qskKeyStretch( Qt::Key key )
|
static qreal qskKeyStretch( Qt::Key key )
|
||||||
{
|
{
|
||||||
switch ( key )
|
switch( key )
|
||||||
{
|
{
|
||||||
case Qt::Key_Backspace:
|
case Qt::Key_Backspace:
|
||||||
case Qt::Key_Shift:
|
case Qt::Key_Shift:
|
||||||
|
@ -168,16 +181,20 @@ static qreal qskRowStretch( const QskInputPanel::KeyRow& keyRow )
|
||||||
{
|
{
|
||||||
qreal stretch = 0;
|
qreal stretch = 0;
|
||||||
|
|
||||||
for ( const auto& key : keyRow )
|
for( const auto& key : keyRow )
|
||||||
|
{
|
||||||
|
if( !key )
|
||||||
{
|
{
|
||||||
if ( !key )
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
stretch += qskKeyStretch( key );
|
stretch += qskKeyStretch( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( stretch == 0.0 )
|
if( stretch == 0.0 )
|
||||||
|
{
|
||||||
stretch = QskInputPanel::KeyCount;
|
stretch = QskInputPanel::KeyCount;
|
||||||
|
}
|
||||||
|
|
||||||
return stretch;
|
return stretch;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +210,7 @@ namespace
|
||||||
|
|
||||||
class QskInputPanel::PrivateData
|
class QskInputPanel::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrivateData():
|
PrivateData():
|
||||||
currentLayout( nullptr ),
|
currentLayout( nullptr ),
|
||||||
mode( QskInputPanel::LowercaseMode ),
|
mode( QskInputPanel::LowercaseMode ),
|
||||||
|
@ -204,7 +221,7 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const QskInputPanelLayouts::Layout* currentLayout;
|
const QskInputPanelLayouts::Layout* currentLayout;
|
||||||
QskInputPanel::Mode mode;
|
QskInputPanel::Mode mode;
|
||||||
|
|
||||||
|
@ -259,7 +276,7 @@ QString QskInputPanel::textForKey( Qt::Key key ) const
|
||||||
key &= ~KeyStates;
|
key &= ~KeyStates;
|
||||||
|
|
||||||
// Special cases
|
// Special cases
|
||||||
switch ( key )
|
switch( key )
|
||||||
{
|
{
|
||||||
case Qt::Key_Backspace:
|
case Qt::Key_Backspace:
|
||||||
case Qt::Key_Muhenkan:
|
case Qt::Key_Muhenkan:
|
||||||
|
@ -306,7 +323,7 @@ QString QskInputPanel::displayLanguageName() const
|
||||||
{
|
{
|
||||||
const auto locale = this->locale();
|
const auto locale = this->locale();
|
||||||
|
|
||||||
switch ( locale.language() )
|
switch( locale.language() )
|
||||||
{
|
{
|
||||||
case QLocale::Bulgarian:
|
case QLocale::Bulgarian:
|
||||||
return QStringLiteral( "български език" );
|
return QStringLiteral( "български език" );
|
||||||
|
@ -325,7 +342,7 @@ QString QskInputPanel::displayLanguageName() const
|
||||||
|
|
||||||
case QLocale::English:
|
case QLocale::English:
|
||||||
{
|
{
|
||||||
switch ( locale.country() )
|
switch( locale.country() )
|
||||||
{
|
{
|
||||||
case QLocale::Canada:
|
case QLocale::Canada:
|
||||||
case QLocale::UnitedStates:
|
case QLocale::UnitedStates:
|
||||||
|
@ -397,7 +414,7 @@ void QskInputPanel::setPreeditGroups( const QVector< Qt::Key >& groups )
|
||||||
{
|
{
|
||||||
auto& topRow = m_data->keyTable[ LowercaseMode ].data[ 0 ];
|
auto& topRow = m_data->keyTable[ LowercaseMode ].data[ 0 ];
|
||||||
|
|
||||||
for ( const auto& group : groups )
|
for( const auto& group : groups )
|
||||||
{
|
{
|
||||||
auto& keyData = topRow[ &group - groups.data() ];
|
auto& keyData = topRow[ &group - groups.data() ];
|
||||||
keyData.key = group;
|
keyData.key = group;
|
||||||
|
@ -406,14 +423,18 @@ void QskInputPanel::setPreeditGroups( const QVector< Qt::Key >& groups )
|
||||||
m_data->groups = groups;
|
m_data->groups = groups;
|
||||||
selectGroup( -1 );
|
selectGroup( -1 );
|
||||||
|
|
||||||
if ( m_data->mode == LowercaseMode )
|
if( m_data->mode == LowercaseMode )
|
||||||
|
{
|
||||||
update();
|
update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputPanel::setPreeditCandidates( const QVector< Qt::Key >& candidates )
|
void QskInputPanel::setPreeditCandidates( const QVector< Qt::Key >& candidates )
|
||||||
{
|
{
|
||||||
if ( m_data->candidates == candidates )
|
if( m_data->candidates == candidates )
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_data->candidates = candidates;
|
m_data->candidates = candidates;
|
||||||
setCandidateOffset( 0 );
|
setCandidateOffset( 0 );
|
||||||
|
@ -429,19 +450,25 @@ bool QskInputPanel::advanceFocus( bool forward )
|
||||||
Q_FOREVER
|
Q_FOREVER
|
||||||
{
|
{
|
||||||
focusKeyIndex += offset;
|
focusKeyIndex += offset;
|
||||||
if ( focusKeyIndex < 0 || focusKeyIndex >= RowCount * KeyCount )
|
|
||||||
|
if( focusKeyIndex < 0 || focusKeyIndex >= RowCount * KeyCount )
|
||||||
{
|
{
|
||||||
clearFocusKey();
|
clearFocusKey();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto key = keyDataAt( focusKeyIndex ).key;
|
const auto key = keyDataAt( focusKeyIndex ).key;
|
||||||
if ( key && key != Qt::Key_unknown )
|
|
||||||
|
if( key && key != Qt::Key_unknown )
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( m_data->focusKeyIndex >= 0 )
|
if( m_data->focusKeyIndex >= 0 )
|
||||||
|
{
|
||||||
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
|
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
|
||||||
|
}
|
||||||
|
|
||||||
m_data->focusKeyIndex = focusKeyIndex;
|
m_data->focusKeyIndex = focusKeyIndex;
|
||||||
keyDataAt( m_data->focusKeyIndex ).key |= KeyFocused;
|
keyDataAt( m_data->focusKeyIndex ).key |= KeyFocused;
|
||||||
|
@ -451,14 +478,18 @@ bool QskInputPanel::advanceFocus( bool forward )
|
||||||
|
|
||||||
bool QskInputPanel::activateFocusKey()
|
bool QskInputPanel::activateFocusKey()
|
||||||
{
|
{
|
||||||
if ( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
||||||
{
|
{
|
||||||
auto& keyData = keyDataAt( m_data->focusKeyIndex );
|
auto& keyData = keyDataAt( m_data->focusKeyIndex );
|
||||||
|
|
||||||
if ( keyData.key & KeyPressed )
|
if( keyData.key & KeyPressed )
|
||||||
|
{
|
||||||
handleKey( m_data->focusKeyIndex );
|
handleKey( m_data->focusKeyIndex );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
keyData.key |= KeyPressed;
|
keyData.key |= KeyPressed;
|
||||||
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
return true;
|
return true;
|
||||||
|
@ -469,10 +500,11 @@ bool QskInputPanel::activateFocusKey()
|
||||||
|
|
||||||
bool QskInputPanel::deactivateFocusKey()
|
bool QskInputPanel::deactivateFocusKey()
|
||||||
{
|
{
|
||||||
if ( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
||||||
{
|
{
|
||||||
auto& keyData = keyDataAt( m_data->focusKeyIndex );
|
auto& keyData = keyDataAt( m_data->focusKeyIndex );
|
||||||
if ( keyData.key & KeyPressed )
|
|
||||||
|
if( keyData.key & KeyPressed )
|
||||||
{
|
{
|
||||||
keyData.key &= ~KeyPressed;
|
keyData.key &= ~KeyPressed;
|
||||||
handleKey( m_data->focusKeyIndex );
|
handleKey( m_data->focusKeyIndex );
|
||||||
|
@ -487,7 +519,7 @@ bool QskInputPanel::deactivateFocusKey()
|
||||||
|
|
||||||
void QskInputPanel::clearFocusKey()
|
void QskInputPanel::clearFocusKey()
|
||||||
{
|
{
|
||||||
if ( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
if( m_data->focusKeyIndex > 0 && m_data->focusKeyIndex < RowCount * KeyCount )
|
||||||
{
|
{
|
||||||
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
|
keyDataAt( m_data->focusKeyIndex ).key &= ~KeyFocused;
|
||||||
update();
|
update();
|
||||||
|
@ -508,34 +540,44 @@ void QskInputPanel::setCandidateOffset( int candidateOffset )
|
||||||
const bool continueLeft = m_data->candidateOffset > 0;
|
const bool continueLeft = m_data->candidateOffset > 0;
|
||||||
const bool continueRight = ( candidateCount - m_data->candidateOffset ) > count;
|
const bool continueRight = ( candidateCount - m_data->candidateOffset ) > count;
|
||||||
|
|
||||||
for ( int i = 0; i < count; ++i )
|
for( int i = 0; i < count; ++i )
|
||||||
{
|
{
|
||||||
auto& keyData = topRow[ i + groupCount ];
|
auto& keyData = topRow[ i + groupCount ];
|
||||||
|
|
||||||
if ( continueLeft && i == 0 )
|
if( continueLeft && i == 0 )
|
||||||
|
{
|
||||||
keyData.key = Qt::Key_ApplicationLeft;
|
keyData.key = Qt::Key_ApplicationLeft;
|
||||||
else if ( continueRight && ( i == KeyCount - groupCount - 1 ) )
|
}
|
||||||
|
else if( continueRight && ( i == KeyCount - groupCount - 1 ) )
|
||||||
|
{
|
||||||
keyData.key = Qt::Key_ApplicationRight;
|
keyData.key = Qt::Key_ApplicationRight;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
keyData.key = m_data->candidates.at( i + m_data->candidateOffset );
|
keyData.key = m_data->candidates.at( i + m_data->candidateOffset );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( int i = count; i < KeyCount - groupCount; ++i )
|
for( int i = count; i < KeyCount - groupCount; ++i )
|
||||||
{
|
{
|
||||||
auto& keyData = topRow[ i + groupCount ];
|
auto& keyData = topRow[ i + groupCount ];
|
||||||
keyData.key = Qt::Key_unknown;
|
keyData.key = Qt::Key_unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_data->mode == LowercaseMode )
|
if( m_data->mode == LowercaseMode )
|
||||||
|
{
|
||||||
update();
|
update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskInputPanel::keyboardRect() const
|
QRectF QskInputPanel::keyboardRect() const
|
||||||
{
|
{
|
||||||
auto keyboardRect = rect(); // ### margins? would eliminate this thing below
|
auto keyboardRect = rect(); // ### margins? would eliminate this thing below
|
||||||
|
|
||||||
if ( QskDialog::instance()->policy() != QskDialog::TopLevelWindow )
|
if( QskDialog::instance()->policy() != QskDialog::TopLevelWindow )
|
||||||
|
{
|
||||||
keyboardRect.adjust( 0, keyboardRect.height() * 0.5, 0, 0 );
|
keyboardRect.adjust( 0, keyboardRect.height() * 0.5, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
return keyboardRect;
|
return keyboardRect;
|
||||||
}
|
}
|
||||||
|
@ -549,7 +591,7 @@ void QskInputPanel::geometryChanged(
|
||||||
|
|
||||||
void QskInputPanel::mousePressEvent( QMouseEvent* e )
|
void QskInputPanel::mousePressEvent( QMouseEvent* e )
|
||||||
{
|
{
|
||||||
if ( !keyboardRect().contains( e->pos() ) )
|
if( !keyboardRect().contains( e->pos() ) )
|
||||||
{
|
{
|
||||||
e->ignore();
|
e->ignore();
|
||||||
return;
|
return;
|
||||||
|
@ -595,17 +637,20 @@ void QskInputPanel::mouseReleaseEvent( QMouseEvent* e )
|
||||||
// Try to handle touch-specific details here; once touch is resolved, send to handleKey()
|
// Try to handle touch-specific details here; once touch is resolved, send to handleKey()
|
||||||
void QskInputPanel::touchEvent( QTouchEvent* e )
|
void QskInputPanel::touchEvent( QTouchEvent* e )
|
||||||
{
|
{
|
||||||
if ( e->type() == QEvent::TouchCancel )
|
if( e->type() == QEvent::TouchCancel )
|
||||||
|
{
|
||||||
|
for( auto& it : m_data->activeKeys )
|
||||||
{
|
{
|
||||||
for ( auto& it : m_data->activeKeys )
|
|
||||||
keyDataAt( it.second.keyIndex ).key &= ~KeyPressed;
|
keyDataAt( it.second.keyIndex ).key &= ~KeyPressed;
|
||||||
|
}
|
||||||
|
|
||||||
m_data->activeKeys.clear();
|
m_data->activeKeys.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto rect = keyboardRect();
|
const auto rect = keyboardRect();
|
||||||
for ( const auto& tp : e->touchPoints() )
|
|
||||||
|
for( const auto& tp : e->touchPoints() )
|
||||||
{
|
{
|
||||||
const auto pos = tp.pos();
|
const auto pos = tp.pos();
|
||||||
|
|
||||||
|
@ -613,11 +658,15 @@ void QskInputPanel::touchEvent( QTouchEvent* e )
|
||||||
const auto y = ( pos.y() - rect.y() ) / rect.height();
|
const auto y = ( pos.y() - rect.y() ) / rect.height();
|
||||||
|
|
||||||
auto keyData = qskKeyDataAt( m_data->keyTable[ m_data->mode ], x, y );
|
auto keyData = qskKeyDataAt( m_data->keyTable[ m_data->mode ], x, y );
|
||||||
if ( !keyData || ( !keyData->key || keyData->key == Qt::Key_unknown ) )
|
|
||||||
|
if( !keyData || ( !keyData->key || keyData->key == Qt::Key_unknown ) )
|
||||||
{
|
{
|
||||||
auto it = m_data->activeKeys.find( tp.id() );
|
auto it = m_data->activeKeys.find( tp.id() );
|
||||||
if ( it == m_data->activeKeys.cend() )
|
|
||||||
|
if( it == m_data->activeKeys.cend() )
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
keyDataAt( it->second.keyIndex ).key &= ~KeyPressed;
|
keyDataAt( it->second.keyIndex ).key &= ~KeyPressed;
|
||||||
m_data->activeKeys.erase( it );
|
m_data->activeKeys.erase( it );
|
||||||
|
@ -627,7 +676,7 @@ void QskInputPanel::touchEvent( QTouchEvent* e )
|
||||||
const auto keyIndex = m_data->keyTable[ m_data->mode ].indexOf( keyData );
|
const auto keyIndex = m_data->keyTable[ m_data->mode ].indexOf( keyData );
|
||||||
auto it = m_data->activeKeys.find( tp.id() );
|
auto it = m_data->activeKeys.find( tp.id() );
|
||||||
|
|
||||||
if ( tp.state() == Qt::TouchPointReleased )
|
if( tp.state() == Qt::TouchPointReleased )
|
||||||
{
|
{
|
||||||
const int repeatCount = it->second.count;
|
const int repeatCount = it->second.count;
|
||||||
|
|
||||||
|
@ -635,20 +684,22 @@ void QskInputPanel::touchEvent( QTouchEvent* e )
|
||||||
keyDataAt( it->second.keyIndex ).key &= ~KeyPressed;
|
keyDataAt( it->second.keyIndex ).key &= ~KeyPressed;
|
||||||
m_data->activeKeys.erase( it );
|
m_data->activeKeys.erase( it );
|
||||||
|
|
||||||
if ( repeatCount < 0 )
|
if( repeatCount < 0 )
|
||||||
|
{
|
||||||
continue; // Don't compose an accepted held key
|
continue; // Don't compose an accepted held key
|
||||||
|
}
|
||||||
|
|
||||||
handleKey( keyIndex );
|
handleKey( keyIndex );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( it == m_data->activeKeys.end() )
|
if( it == m_data->activeKeys.end() )
|
||||||
{
|
{
|
||||||
m_data->activeKeys.emplace( tp.id(), KeyCounter { keyIndex, 0 } );
|
m_data->activeKeys.emplace( tp.id(), KeyCounter { keyIndex, 0 } );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( it->second.keyIndex != keyIndex )
|
if( it->second.keyIndex != keyIndex )
|
||||||
{
|
{
|
||||||
keyDataAt( it->second.keyIndex ).key &= ~KeyPressed;
|
keyDataAt( it->second.keyIndex ).key &= ~KeyPressed;
|
||||||
it->second.count = 0;
|
it->second.count = 0;
|
||||||
|
@ -661,12 +712,12 @@ void QskInputPanel::touchEvent( QTouchEvent* e )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now start an update timer based on active keys
|
// Now start an update timer based on active keys
|
||||||
if ( m_data->activeKeys.empty() && m_data->repeatKeyTimerId >= 0 )
|
if( m_data->activeKeys.empty() && m_data->repeatKeyTimerId >= 0 )
|
||||||
{
|
{
|
||||||
killTimer( m_data->repeatKeyTimerId );
|
killTimer( m_data->repeatKeyTimerId );
|
||||||
m_data->repeatKeyTimerId = -1;
|
m_data->repeatKeyTimerId = -1;
|
||||||
}
|
}
|
||||||
else if ( m_data->repeatKeyTimerId < 0 )
|
else if( m_data->repeatKeyTimerId < 0 )
|
||||||
{
|
{
|
||||||
m_data->repeatKeyTimerId = startTimer( 1000
|
m_data->repeatKeyTimerId = startTimer( 1000
|
||||||
/ QGuiApplication::styleHints()->keyboardAutoRepeatRate() );
|
/ QGuiApplication::styleHints()->keyboardAutoRepeatRate() );
|
||||||
|
@ -677,31 +728,32 @@ void QskInputPanel::touchEvent( QTouchEvent* e )
|
||||||
|
|
||||||
void QskInputPanel::timerEvent( QTimerEvent* e )
|
void QskInputPanel::timerEvent( QTimerEvent* e )
|
||||||
{
|
{
|
||||||
if ( e->timerId() == m_data->repeatKeyTimerId )
|
if( e->timerId() == m_data->repeatKeyTimerId )
|
||||||
{
|
{
|
||||||
for ( auto it = m_data->activeKeys.begin(); it != m_data->activeKeys.end(); )
|
for( auto it = m_data->activeKeys.begin(); it != m_data->activeKeys.end(); )
|
||||||
{
|
{
|
||||||
if ( it->second.count >= 0 && it->second.count++ > 20 ) // ### use platform long-press hint
|
if( it->second.count >= 0 && it->second.count++ > 20 ) // ### use platform long-press hint
|
||||||
{
|
{
|
||||||
const auto key = keyDataAt( it->second.keyIndex ).key & ~KeyStates;
|
const auto key = keyDataAt( it->second.keyIndex ).key & ~KeyStates;
|
||||||
|
|
||||||
if ( !key || key == Qt::Key_unknown )
|
if( !key || key == Qt::Key_unknown )
|
||||||
{
|
{
|
||||||
it = m_data->activeKeys.erase( it );
|
it = m_data->activeKeys.erase( it );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( key == Qt::Key_ApplicationLeft || key == Qt::Key_ApplicationRight )
|
if( key == Qt::Key_ApplicationLeft || key == Qt::Key_ApplicationRight )
|
||||||
{
|
{
|
||||||
setCandidateOffset( m_data->candidateOffset
|
setCandidateOffset( m_data->candidateOffset
|
||||||
+ ( key == Qt::Key_ApplicationLeft ? -1 : 1 ) );
|
+ ( key == Qt::Key_ApplicationLeft ? -1 : 1 ) );
|
||||||
}
|
}
|
||||||
else if ( !( key & KeyLocked ) ) // do not repeat locked keys
|
else if( !( key & KeyLocked ) ) // do not repeat locked keys
|
||||||
{
|
{
|
||||||
// long press events could be emitted from here
|
// long press events could be emitted from here
|
||||||
compose( key & ~KeyStates );
|
compose( key & ~KeyStates );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -722,9 +774,9 @@ void QskInputPanel::handleKey( int keyIndex )
|
||||||
const auto row = keyIndex / KeyCount;
|
const auto row = keyIndex / KeyCount;
|
||||||
const auto column = keyIndex % KeyCount;
|
const auto column = keyIndex % KeyCount;
|
||||||
|
|
||||||
if ( m_data->mode == LowercaseMode && !m_data->groups.isEmpty() && row == 0 )
|
if( m_data->mode == LowercaseMode && !m_data->groups.isEmpty() && row == 0 )
|
||||||
{
|
{
|
||||||
if ( key == Qt::Key_ApplicationLeft
|
if( key == Qt::Key_ApplicationLeft
|
||||||
|| key == Qt::Key_ApplicationRight )
|
|| key == Qt::Key_ApplicationRight )
|
||||||
{
|
{
|
||||||
setCandidateOffset( m_data->candidateOffset
|
setCandidateOffset( m_data->candidateOffset
|
||||||
|
@ -733,18 +785,25 @@ void QskInputPanel::handleKey( int keyIndex )
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto groupCount = m_data->groups.length();
|
const auto groupCount = m_data->groups.length();
|
||||||
if ( column < groupCount )
|
|
||||||
|
if( column < groupCount )
|
||||||
|
{
|
||||||
selectGroup( column );
|
selectGroup( column );
|
||||||
else if ( column < KeyCount )
|
}
|
||||||
|
else if( column < KeyCount )
|
||||||
|
{
|
||||||
selectCandidate( column - groupCount + m_data->candidateOffset );
|
selectCandidate( column - groupCount + m_data->candidateOffset );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Q_UNREACHABLE(); // Handle the final key...
|
Q_UNREACHABLE(); // Handle the final key...
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mode-switching keys
|
// Mode-switching keys
|
||||||
switch ( key )
|
switch( key )
|
||||||
{
|
{
|
||||||
case Qt::Key_CapsLock:
|
case Qt::Key_CapsLock:
|
||||||
case Qt::Key_Kana_Lock:
|
case Qt::Key_Kana_Lock:
|
||||||
|
@ -779,18 +838,25 @@ void QskInputPanel::compose( Qt::Key key )
|
||||||
void QskInputPanel::selectGroup( int index )
|
void QskInputPanel::selectGroup( int index )
|
||||||
{
|
{
|
||||||
auto& topRow = m_data->keyTable[ m_data->mode ].data[ 0 ];
|
auto& topRow = m_data->keyTable[ m_data->mode ].data[ 0 ];
|
||||||
if ( m_data->selectedGroup >= 0 )
|
|
||||||
topRow[ m_data->selectedGroup ].key &= ~KeyLocked;
|
|
||||||
|
|
||||||
if ( m_data->selectedGroup == index )
|
if( m_data->selectedGroup >= 0 )
|
||||||
|
{
|
||||||
|
topRow[ m_data->selectedGroup ].key &= ~KeyLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_data->selectedGroup == index )
|
||||||
|
{
|
||||||
index = -1; // clear selection
|
index = -1; // clear selection
|
||||||
|
}
|
||||||
|
|
||||||
m_data->selectedGroup = index;
|
m_data->selectedGroup = index;
|
||||||
QGuiApplication::inputMethod()->invokeAction(
|
QGuiApplication::inputMethod()->invokeAction(
|
||||||
static_cast< QInputMethod::Action >( SelectGroup ), m_data->selectedGroup + 1 );
|
static_cast< QInputMethod::Action >( SelectGroup ), m_data->selectedGroup + 1 );
|
||||||
|
|
||||||
if ( m_data->selectedGroup < 0 )
|
if( m_data->selectedGroup < 0 )
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
topRow[ m_data->selectedGroup ].key |= KeyLocked;
|
topRow[ m_data->selectedGroup ].key |= KeyLocked;
|
||||||
}
|
}
|
||||||
|
@ -803,7 +869,7 @@ void QskInputPanel::selectCandidate( int index )
|
||||||
|
|
||||||
void QskInputPanel::updateLocale( const QLocale& locale )
|
void QskInputPanel::updateLocale( const QLocale& locale )
|
||||||
{
|
{
|
||||||
switch ( locale.language() )
|
switch( locale.language() )
|
||||||
{
|
{
|
||||||
case QLocale::Bulgarian:
|
case QLocale::Bulgarian:
|
||||||
m_data->currentLayout = &qskInputPanelLayouts.bg;
|
m_data->currentLayout = &qskInputPanelLayouts.bg;
|
||||||
|
@ -827,7 +893,7 @@ void QskInputPanel::updateLocale( const QLocale& locale )
|
||||||
|
|
||||||
case QLocale::English:
|
case QLocale::English:
|
||||||
{
|
{
|
||||||
switch ( locale.country() )
|
switch( locale.country() )
|
||||||
{
|
{
|
||||||
case QLocale::Canada:
|
case QLocale::Canada:
|
||||||
case QLocale::UnitedStates:
|
case QLocale::UnitedStates:
|
||||||
|
@ -835,12 +901,15 @@ void QskInputPanel::updateLocale( const QLocale& locale )
|
||||||
case QLocale::UnitedStatesVirginIslands:
|
case QLocale::UnitedStatesVirginIslands:
|
||||||
m_data->currentLayout = &qskInputPanelLayouts.en_US;
|
m_data->currentLayout = &qskInputPanelLayouts.en_US;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
m_data->currentLayout = &qskInputPanelLayouts.en_GB;
|
m_data->currentLayout = &qskInputPanelLayouts.en_GB;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case QLocale::Spanish:
|
case QLocale::Spanish:
|
||||||
m_data->currentLayout = &qskInputPanelLayouts.es;
|
m_data->currentLayout = &qskInputPanelLayouts.es;
|
||||||
break;
|
break;
|
||||||
|
@ -925,12 +994,12 @@ void QskInputPanel::updateKeyData()
|
||||||
// Key data is in normalized coordinates
|
// Key data is in normalized coordinates
|
||||||
const auto keyHeight = 1.0f / RowCount;
|
const auto keyHeight = 1.0f / RowCount;
|
||||||
|
|
||||||
for ( const auto& keyLayout : *m_data->currentLayout )
|
for( const auto& keyLayout : *m_data->currentLayout )
|
||||||
{
|
{
|
||||||
auto& keyDataLayout = m_data->keyTable[ &keyLayout - *m_data->currentLayout ];
|
auto& keyDataLayout = m_data->keyTable[ &keyLayout - *m_data->currentLayout ];
|
||||||
qreal yPos = 0;
|
qreal yPos = 0;
|
||||||
|
|
||||||
for ( int i = 0; i < RowCount; i++ )
|
for( int i = 0; i < RowCount; i++ )
|
||||||
{
|
{
|
||||||
auto& row = keyLayout.data[i];
|
auto& row = keyLayout.data[i];
|
||||||
auto& keyDataRow = keyDataLayout.data[ i ];
|
auto& keyDataRow = keyDataLayout.data[ i ];
|
||||||
|
@ -940,7 +1009,7 @@ void QskInputPanel::updateKeyData()
|
||||||
qreal xPos = 0;
|
qreal xPos = 0;
|
||||||
qreal keyWidth = baseKeyWidth;
|
qreal keyWidth = baseKeyWidth;
|
||||||
|
|
||||||
for ( const auto& key : row )
|
for( const auto& key : row )
|
||||||
{
|
{
|
||||||
auto& keyData = keyDataRow[ &key - row ];
|
auto& keyData = keyDataRow[ &key - row ];
|
||||||
keyData.key = key;
|
keyData.key = key;
|
||||||
|
|
Loading…
Reference in New Issue