virtual keyboard: Make layouts settable
This commit is contained in:
parent
e36f81b297
commit
f56cf19fd5
@ -14,98 +14,172 @@
|
|||||||
#include <QskTextInput.h>
|
#include <QskTextInput.h>
|
||||||
|
|
||||||
#include <QskAspect.h>
|
#include <QskAspect.h>
|
||||||
#include <QskWindow.h>
|
|
||||||
#include <QskFunctions.h>
|
#include <QskFunctions.h>
|
||||||
|
#include <QskInputPanelBox.h>
|
||||||
#include <QskObjectCounter.h>
|
#include <QskObjectCounter.h>
|
||||||
|
#include <QskVirtualKeyboard.h>
|
||||||
|
#include <QskWindow.h>
|
||||||
|
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
|
||||||
static inline QString nativeLocaleString( const QLocale& locale )
|
namespace
|
||||||
{
|
{
|
||||||
switch ( locale.language() )
|
class Keyboard final : public QskVirtualKeyboard
|
||||||
{
|
{
|
||||||
case QLocale::Bulgarian:
|
using Inherited = QskVirtualKeyboard;
|
||||||
return QStringLiteral( "български език" );
|
|
||||||
|
|
||||||
case QLocale::Czech:
|
public:
|
||||||
return QStringLiteral( "Čeština" );
|
Keyboard( QQuickItem* parentItem = nullptr ):
|
||||||
|
QskVirtualKeyboard( parentItem )
|
||||||
case QLocale::German:
|
|
||||||
return QStringLiteral( "Deutsch" );
|
|
||||||
|
|
||||||
case QLocale::Danish:
|
|
||||||
return QStringLiteral( "Dansk" );
|
|
||||||
|
|
||||||
case QLocale::Greek:
|
|
||||||
return QStringLiteral( "Eλληνικά" );
|
|
||||||
|
|
||||||
case QLocale::English:
|
|
||||||
{
|
|
||||||
switch ( locale.country() )
|
|
||||||
{
|
{
|
||||||
case QLocale::Canada:
|
// here rearrange keyboard layouts if necessary
|
||||||
case QLocale::UnitedStates:
|
|
||||||
case QLocale::UnitedStatesMinorOutlyingIslands:
|
|
||||||
case QLocale::UnitedStatesVirginIslands:
|
|
||||||
return QStringLiteral( "English (US)" );
|
|
||||||
|
|
||||||
default:
|
|
||||||
return QStringLiteral( "English (UK)" );
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Panel : public QskInputPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Panel( QQuickItem* parentItem = nullptr )
|
||||||
|
: QskInputPanel( parentItem )
|
||||||
|
{
|
||||||
|
setAutoLayoutChildren( true );
|
||||||
|
setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
|
||||||
|
|
||||||
|
m_box = new QskInputPanelBox( this );
|
||||||
|
m_box->setKeyboard( new Keyboard() );
|
||||||
|
|
||||||
|
connect( m_box, &QskInputPanelBox::keySelected,
|
||||||
|
this, &QskInputPanel::keySelected );
|
||||||
|
|
||||||
|
connect( m_box, &QskInputPanelBox::predictiveTextSelected,
|
||||||
|
this, &QskInputPanel::predictiveTextSelected );
|
||||||
}
|
}
|
||||||
|
|
||||||
case QLocale::Spanish:
|
void attachItem( QQuickItem* item ) override
|
||||||
return QStringLiteral( "Español" );
|
{
|
||||||
|
m_box->attachInputItem( item );
|
||||||
|
}
|
||||||
|
|
||||||
case QLocale::Finnish:
|
QQuickItem* inputProxy() const override
|
||||||
return QStringLiteral( "Suomi" );
|
{
|
||||||
|
return m_box->inputProxy();
|
||||||
|
}
|
||||||
|
|
||||||
case QLocale::French:
|
void setPrompt( const QString& prompt ) override
|
||||||
return QStringLiteral( "Français" );
|
{
|
||||||
|
m_box->setInputPrompt( prompt );
|
||||||
|
}
|
||||||
|
|
||||||
case QLocale::Hungarian:
|
void setPredictionEnabled( bool on ) override
|
||||||
return QStringLiteral( "Magyar" );
|
{
|
||||||
|
m_box->setPanelHint( QskInputPanelBox::Prediction, on );
|
||||||
|
}
|
||||||
|
|
||||||
case QLocale::Italian:
|
void setPrediction( const QStringList& prediction ) override
|
||||||
return QStringLiteral( "Italiano" );
|
{
|
||||||
|
QskInputPanel::setPrediction( prediction );
|
||||||
|
m_box->setPrediction( prediction );
|
||||||
|
}
|
||||||
|
|
||||||
case QLocale::Japanese:
|
|
||||||
return QStringLiteral( "日本語" );
|
|
||||||
|
|
||||||
case QLocale::Latvian:
|
private:
|
||||||
return QStringLiteral( "Latviešu" );
|
QskInputPanelBox* m_box;
|
||||||
|
};
|
||||||
|
|
||||||
case QLocale::Lithuanian:
|
class InputContextFactory : public QskInputContextFactory
|
||||||
return QStringLiteral( "Lietuvių" );
|
{
|
||||||
|
QskInputPanel* createPanel() const override
|
||||||
|
{
|
||||||
|
return new Panel;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
case QLocale::Dutch:
|
QString nativeLocaleString( const QLocale& locale )
|
||||||
return QStringLiteral( "Nederlands" );
|
{
|
||||||
|
switch ( locale.language() )
|
||||||
|
{
|
||||||
|
case QLocale::Bulgarian:
|
||||||
|
return QStringLiteral( "български език" );
|
||||||
|
|
||||||
case QLocale::Portuguese:
|
case QLocale::Czech:
|
||||||
return QStringLiteral( "Português" );
|
return QStringLiteral( "Čeština" );
|
||||||
|
|
||||||
case QLocale::Romanian:
|
case QLocale::German:
|
||||||
return QStringLiteral( "Română" );
|
return QStringLiteral( "Deutsch" );
|
||||||
|
|
||||||
case QLocale::Russian:
|
case QLocale::Danish:
|
||||||
return QStringLiteral( "Русский" );
|
return QStringLiteral( "Dansk" );
|
||||||
|
|
||||||
case QLocale::Slovenian:
|
case QLocale::Greek:
|
||||||
return QStringLiteral( "Slovenščina" );
|
return QStringLiteral( "Eλληνικά" );
|
||||||
|
|
||||||
case QLocale::Slovak:
|
case QLocale::English:
|
||||||
return QStringLiteral( "Slovenčina" );
|
{
|
||||||
|
switch ( locale.country() )
|
||||||
|
{
|
||||||
|
case QLocale::Canada:
|
||||||
|
case QLocale::UnitedStates:
|
||||||
|
case QLocale::UnitedStatesMinorOutlyingIslands:
|
||||||
|
case QLocale::UnitedStatesVirginIslands:
|
||||||
|
return QStringLiteral( "English (US)" );
|
||||||
|
|
||||||
case QLocale::Turkish:
|
default:
|
||||||
return QStringLiteral( "Türkçe" );
|
return QStringLiteral( "English (UK)" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case QLocale::Chinese:
|
case QLocale::Spanish:
|
||||||
return QStringLiteral( "中文" );
|
return QStringLiteral( "Español" );
|
||||||
|
|
||||||
default:
|
case QLocale::Finnish:
|
||||||
return QLocale::languageToString( locale.language() );
|
return QStringLiteral( "Suomi" );
|
||||||
|
|
||||||
|
case QLocale::French:
|
||||||
|
return QStringLiteral( "Français" );
|
||||||
|
|
||||||
|
case QLocale::Hungarian:
|
||||||
|
return QStringLiteral( "Magyar" );
|
||||||
|
|
||||||
|
case QLocale::Italian:
|
||||||
|
return QStringLiteral( "Italiano" );
|
||||||
|
|
||||||
|
case QLocale::Japanese:
|
||||||
|
return QStringLiteral( "日本語" );
|
||||||
|
|
||||||
|
case QLocale::Latvian:
|
||||||
|
return QStringLiteral( "Latviešu" );
|
||||||
|
|
||||||
|
case QLocale::Lithuanian:
|
||||||
|
return QStringLiteral( "Lietuvių" );
|
||||||
|
|
||||||
|
case QLocale::Dutch:
|
||||||
|
return QStringLiteral( "Nederlands" );
|
||||||
|
|
||||||
|
case QLocale::Portuguese:
|
||||||
|
return QStringLiteral( "Português" );
|
||||||
|
|
||||||
|
case QLocale::Romanian:
|
||||||
|
return QStringLiteral( "Română" );
|
||||||
|
|
||||||
|
case QLocale::Russian:
|
||||||
|
return QStringLiteral( "Русский" );
|
||||||
|
|
||||||
|
case QLocale::Slovenian:
|
||||||
|
return QStringLiteral( "Slovenščina" );
|
||||||
|
|
||||||
|
case QLocale::Slovak:
|
||||||
|
return QStringLiteral( "Slovenčina" );
|
||||||
|
|
||||||
|
case QLocale::Turkish:
|
||||||
|
return QStringLiteral( "Türkçe" );
|
||||||
|
|
||||||
|
case QLocale::Chinese:
|
||||||
|
return QStringLiteral( "中文" );
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QLocale::languageToString( locale.language() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,6 +380,7 @@ int main( int argc, char* argv[] )
|
|||||||
window2.show();
|
window2.show();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QskInputContext::instance()->setFactory( new InputContextFactory() );
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1103,9 +1103,23 @@ void Editor::setupVirtualKeyboard()
|
|||||||
|
|
||||||
// key panel
|
// key panel
|
||||||
setMargin( Q::ButtonPanel, 5_dp );
|
setMargin( Q::ButtonPanel, 5_dp );
|
||||||
setGradient( Q::ButtonPanel, m_pal.background );
|
setGradient( Q::ButtonPanel, m_pal.surface2 );
|
||||||
|
setGradient( Q::ButtonPanel | QskPushButton::Pressed, m_pal.surface );
|
||||||
|
setColor( Q::ButtonText | QskPushButton::Pressed, m_pal.outlineVariant );
|
||||||
setBoxShape( Q::ButtonPanel, 6_dp );
|
setBoxShape( Q::ButtonPanel, 6_dp );
|
||||||
|
|
||||||
|
setBoxShape( Q::ButtonPanel | A::Huge, 100, Qt::RelativeSize );
|
||||||
|
setGradient( Q::ButtonPanel | A::Huge, m_pal.primary );
|
||||||
|
setColor( Q::ButtonText | A::Huge, m_pal.onPrimary );
|
||||||
|
|
||||||
|
setGradient( Q::ButtonPanel | A::Large, m_pal.outlineVariant );
|
||||||
|
|
||||||
|
setBoxShape( Q::ButtonPanel | A::Small, 100, Qt::RelativeSize );
|
||||||
|
setGradient( Q::ButtonPanel | A::Small, m_pal.secondary );
|
||||||
|
setColor( Q::ButtonText | A::Small, m_pal.onSecondary );
|
||||||
|
|
||||||
|
setGradient( Q::ButtonPanel | A::Tiny, m_pal.outlineVariant );
|
||||||
|
|
||||||
for ( auto state : { A::NoState, Q::Focused } )
|
for ( auto state : { A::NoState, Q::Focused } )
|
||||||
setBoxBorderColors( Q::ButtonPanel | QskPushButton::Pressed | state,
|
setBoxBorderColors( Q::ButtonPanel | QskPushButton::Pressed | state,
|
||||||
m_pal.secondary );
|
m_pal.secondary );
|
||||||
@ -1117,7 +1131,7 @@ void Editor::setupVirtualKeyboard()
|
|||||||
setFontRole( Q::ButtonText, QskMaterial3Skin::M3HeadlineSmall );
|
setFontRole( Q::ButtonText, QskMaterial3Skin::M3HeadlineSmall );
|
||||||
|
|
||||||
// panel
|
// panel
|
||||||
setGradient( Q::Panel, m_pal.surfaceVariant );
|
setGradient( Q::Panel, m_pal.background );
|
||||||
setPadding( Q::Panel, { 3_dp, 25_dp, 3_dp, 5_dp } );
|
setPadding( Q::Panel, { 3_dp, 25_dp, 3_dp, 5_dp } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +218,20 @@ void QskInputPanelBox::setPrediction( const QStringList& prediction )
|
|||||||
m_data->predictionBar->setPrediction( prediction );
|
m_data->predictionBar->setPrediction( prediction );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskInputPanelBox::setKeyboard( QskVirtualKeyboard* keyboard )
|
||||||
|
{
|
||||||
|
if( m_data->keyboard )
|
||||||
|
{
|
||||||
|
m_data->keyboard->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data->keyboard = keyboard;
|
||||||
|
m_data->layout->addItem( m_data->keyboard );
|
||||||
|
|
||||||
|
connect( m_data->keyboard, &QskVirtualKeyboard::keySelected,
|
||||||
|
this, &QskInputPanelBox::keySelected );
|
||||||
|
}
|
||||||
|
|
||||||
void QskInputPanelBox::keyPressEvent( QKeyEvent* event )
|
void QskInputPanelBox::keyPressEvent( QKeyEvent* event )
|
||||||
{
|
{
|
||||||
int keyCode = -1;
|
int keyCode = -1;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "QskBox.h"
|
#include "QskBox.h"
|
||||||
|
|
||||||
class QskInputEngine;
|
class QskInputEngine;
|
||||||
|
class QskVirtualKeyboard;
|
||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
class QLocale;
|
class QLocale;
|
||||||
@ -52,6 +53,8 @@ class QSK_EXPORT QskInputPanelBox : public QskBox
|
|||||||
|
|
||||||
QString inputPrompt() const;
|
QString inputPrompt() const;
|
||||||
|
|
||||||
|
void setKeyboard( QskVirtualKeyboard* );
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void panelHintsChanged();
|
void panelHintsChanged();
|
||||||
void inputPromptChanged( const QString& );
|
void inputPromptChanged( const QString& );
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include "QskVirtualKeyboard.h"
|
#include "QskVirtualKeyboard.h"
|
||||||
#include "QskPushButton.h"
|
#include "QskPushButton.h"
|
||||||
#include "QskTextOptions.h"
|
|
||||||
|
|
||||||
#include <qguiapplication.h>
|
#include <qguiapplication.h>
|
||||||
#include <qset.h>
|
#include <qset.h>
|
||||||
@ -13,97 +12,138 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
enum
|
class Button : public QskPushButton
|
||||||
{
|
|
||||||
RowCount = 5,
|
|
||||||
ColumnCount = 12
|
|
||||||
};
|
|
||||||
|
|
||||||
using KeyRow = int[ ColumnCount ];
|
|
||||||
|
|
||||||
class Button final : public QskPushButton
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Button( int row, int column, QskVirtualKeyboard* parent )
|
Button( QskVirtualKeyboard* parent )
|
||||||
: QskPushButton( parent )
|
: QskPushButton( parent )
|
||||||
, m_row( row )
|
|
||||||
, m_column( column )
|
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
QskTextOptions options;
|
|
||||||
options.setFontSizeMode( QskTextOptions::VerticalFit );
|
|
||||||
setTextOptions( options );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setFocusPolicy( Qt::TabFocus );
|
setFocusPolicy( Qt::TabFocus );
|
||||||
|
|
||||||
|
setSubcontrolProxy( QskPushButton::Panel, QskVirtualKeyboard::ButtonPanel );
|
||||||
|
setSubcontrolProxy( QskPushButton::Text, QskVirtualKeyboard::ButtonText );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskAspect::Subcontrol substitutedSubcontrol(
|
int key() const
|
||||||
QskAspect::Subcontrol subControl ) const override
|
|
||||||
{
|
{
|
||||||
auto keyBoard = static_cast< const QskVirtualKeyboard* >( parent() );
|
return m_key;
|
||||||
|
|
||||||
if ( subControl == QskPushButton::Panel )
|
|
||||||
return keyBoard->effectiveSubcontrol( QskVirtualKeyboard::ButtonPanel );
|
|
||||||
|
|
||||||
if ( subControl == QskPushButton::Text )
|
|
||||||
return keyBoard->effectiveSubcontrol( QskVirtualKeyboard::ButtonText );
|
|
||||||
|
|
||||||
return QskPushButton::substitutedSubcontrol( subControl );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int row() const { return m_row; }
|
void setKey( int key )
|
||||||
int column() const { return m_column; }
|
{
|
||||||
|
m_key = key;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int m_row;
|
int m_key = 0;
|
||||||
const int m_column;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool qskIsAutorepeat( int key )
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
( key != Qt::Key_Return ) &&
|
||||||
|
( key != Qt::Key_Enter ) &&
|
||||||
|
( key != Qt::Key_Shift ) &&
|
||||||
|
( key != Qt::Key_CapsLock ) &&
|
||||||
|
( key != Qt::Key_Mode_switch ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QskVirtualKeyboardLayouts
|
|
||||||
|
QSK_SUBCONTROL( QskVirtualKeyboard, Panel )
|
||||||
|
QSK_SUBCONTROL( QskVirtualKeyboard, ButtonPanel )
|
||||||
|
QSK_SUBCONTROL( QskVirtualKeyboard, ButtonText )
|
||||||
|
|
||||||
|
class QskVirtualKeyboard::PrivateData
|
||||||
{
|
{
|
||||||
struct KeyCodes
|
public:
|
||||||
{
|
int rowCount = 5;
|
||||||
using Row = int[ ColumnCount ];
|
int columnCount = 12;
|
||||||
Row data[ RowCount ];
|
|
||||||
};
|
|
||||||
|
|
||||||
using Layout = KeyCodes[ QskVirtualKeyboard::ModeCount ];
|
QskVirtualKeyboardLayouts layouts;
|
||||||
|
const QskVirtualKeyboardLayouts::Layout* currentLayout = nullptr;
|
||||||
|
QskVirtualKeyboard::Mode mode = QskVirtualKeyboard::LowercaseMode;
|
||||||
|
|
||||||
Layout bg; // Bulgarian
|
QVector< Button* > keyButtons;
|
||||||
Layout cs; // Czech
|
QSet< int > keyCodes;
|
||||||
Layout de; // German
|
|
||||||
Layout da; // Danish
|
|
||||||
Layout el; // Greek
|
|
||||||
Layout en_GB; // English (GB)
|
|
||||||
Layout en_US; // English (US)
|
|
||||||
Layout es; // Spanish
|
|
||||||
Layout fi; // Finnish
|
|
||||||
Layout fr; // French
|
|
||||||
Layout hu; // Hungarian
|
|
||||||
Layout it; // Italian
|
|
||||||
Layout ja; // Japanese
|
|
||||||
Layout lv; // Latvian
|
|
||||||
Layout lt; // Lithuanian
|
|
||||||
Layout nl; // Dutch
|
|
||||||
Layout pt; // Portuguese
|
|
||||||
Layout ro; // Romanian
|
|
||||||
Layout ru; // Russian
|
|
||||||
Layout sl; // Slovene
|
|
||||||
Layout sk; // Slovak
|
|
||||||
Layout tr; // Turkish
|
|
||||||
Layout zh; // Chinese
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QskVirtualKeyboard::QskVirtualKeyboard( QQuickItem* parent )
|
||||||
|
: Inherited( parent )
|
||||||
|
, m_data( new PrivateData )
|
||||||
|
{
|
||||||
|
setPolishOnResize( true );
|
||||||
|
initSizePolicy( QskSizePolicy::Expanding, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
#define LOWER( x ) int( x + 32 ) // Convert an uppercase key to lowercase
|
#define LOWER( x ) int( x + 32 ) // Convert an uppercase key to lowercase
|
||||||
static constexpr const QskVirtualKeyboardLayouts qskKeyboardLayouts =
|
m_data->layouts =
|
||||||
{
|
{
|
||||||
#include "QskVirtualKeyboardLayouts.cpp"
|
#include "QskVirtualKeyboardLayouts.cpp"
|
||||||
};
|
};
|
||||||
#undef LOWER
|
#undef LOWER
|
||||||
|
|
||||||
static qreal qskKeyStretch( int key )
|
ensureButtons();
|
||||||
|
|
||||||
|
connect( this, &QskControl::localeChanged,
|
||||||
|
this, &QskVirtualKeyboard::updateLocale );
|
||||||
|
|
||||||
|
updateLocale( locale() );
|
||||||
|
|
||||||
|
setSubcontrolProxy( QskBox::Panel, Panel );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskVirtualKeyboard::~QskVirtualKeyboard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskVirtualKeyboard::setMode( QskVirtualKeyboard::Mode mode )
|
||||||
|
{
|
||||||
|
m_data->mode = mode;
|
||||||
|
polish();
|
||||||
|
|
||||||
|
Q_EMIT modeChanged( m_data->mode );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskVirtualKeyboard::Mode QskVirtualKeyboard::mode() const
|
||||||
|
{
|
||||||
|
return m_data->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF QskVirtualKeyboard::layoutSizeHint(
|
||||||
|
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||||
|
{
|
||||||
|
if ( which != Qt::PreferredSize )
|
||||||
|
return QSizeF();
|
||||||
|
|
||||||
|
const qreal ratio = qreal( rowCount() ) / columnCount();
|
||||||
|
|
||||||
|
qreal w = constraint.width();
|
||||||
|
qreal h = constraint.height();
|
||||||
|
|
||||||
|
if ( h >= 0 )
|
||||||
|
{
|
||||||
|
const auto padding = innerPadding( Panel, QSizeF( h, h ) );
|
||||||
|
const auto dw = padding.left() + padding.right();
|
||||||
|
const auto dh = padding.top() + padding.bottom();
|
||||||
|
|
||||||
|
w = ( h - dh ) / ratio + dw;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( w < 0 )
|
||||||
|
w = 600;
|
||||||
|
|
||||||
|
const auto padding = innerPadding( Panel, QSizeF( w, w ) );
|
||||||
|
const auto dw = padding.left() + padding.right();
|
||||||
|
const auto dh = padding.top() + padding.bottom();
|
||||||
|
|
||||||
|
h = ( w - dw ) * ratio + dh;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSizeF( w, h );
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QskVirtualKeyboard::keyStretch( int key ) const
|
||||||
{
|
{
|
||||||
switch ( key )
|
switch ( key )
|
||||||
{
|
{
|
||||||
@ -126,29 +166,12 @@ static qreal qskKeyStretch( int key )
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal qskRowStretch( const KeyRow& keyRow )
|
bool QskVirtualKeyboard::isKeyVisible( int key ) const
|
||||||
{
|
{
|
||||||
qreal stretch = 0;
|
return key != 0;
|
||||||
|
|
||||||
for ( const auto& key : keyRow )
|
|
||||||
{
|
|
||||||
if ( !key )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
stretch += qskKeyStretch( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( stretch == 0.0 )
|
|
||||||
{
|
|
||||||
stretch = ColumnCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stretch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString qskTextForKey( int key )
|
QString QskVirtualKeyboard::textForKey( int key ) const
|
||||||
{
|
{
|
||||||
// Special cases
|
// Special cases
|
||||||
switch ( key )
|
switch ( key )
|
||||||
@ -189,191 +212,96 @@ static QString qskTextForKey( int key )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool qskIsAutorepeat( int key )
|
QskVirtualKeyboard::KeyType QskVirtualKeyboard::typeForKey( int key ) const
|
||||||
{
|
{
|
||||||
return (
|
switch( key )
|
||||||
( key != Qt::Key_Return ) &&
|
|
||||||
( key != Qt::Key_Enter ) &&
|
|
||||||
( key != Qt::Key_Shift ) &&
|
|
||||||
( key != Qt::Key_CapsLock ) &&
|
|
||||||
( 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 ];
|
case Qt::Key_Return:
|
||||||
|
case Qt::Key_Enter:
|
||||||
|
return EnterType;
|
||||||
|
|
||||||
for ( int row = 0; row < RowCount; row++ )
|
case Qt::Key_Backspace:
|
||||||
{
|
return BackspaceType;
|
||||||
const auto& keys = keyCodes.data[ row ];
|
|
||||||
|
|
||||||
for ( int col = 0; col < ColumnCount; col++ )
|
case Qt::Key_Shift:
|
||||||
codes += keys[ col ];
|
case Qt::Key_CapsLock:
|
||||||
}
|
return CapsSwitchType;
|
||||||
|
|
||||||
|
case Qt::Key_Mode_switch:
|
||||||
|
return ModeSwitchType;
|
||||||
|
|
||||||
|
case Qt::Key_Comma:
|
||||||
|
case Qt::Key_Period:
|
||||||
|
return SpecialCharacterType;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NormalType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return codes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSK_SUBCONTROL( QskVirtualKeyboard, Panel )
|
void QskVirtualKeyboard::updateLayout() // ### fill keyCodes here
|
||||||
QSK_SUBCONTROL( QskVirtualKeyboard, ButtonPanel )
|
|
||||||
QSK_SUBCONTROL( QskVirtualKeyboard, ButtonText )
|
|
||||||
|
|
||||||
class QskVirtualKeyboard::PrivateData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const QskVirtualKeyboardLayouts::Layout* currentLayout = nullptr;
|
|
||||||
QskVirtualKeyboard::Mode mode = QskVirtualKeyboard::LowercaseMode;
|
|
||||||
|
|
||||||
QVector< Button* > keyButtons;
|
|
||||||
QSet< int > keyCodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
QskVirtualKeyboard::QskVirtualKeyboard( QQuickItem* parent )
|
|
||||||
: Inherited( parent )
|
|
||||||
, m_data( new PrivateData )
|
|
||||||
{
|
|
||||||
setPolishOnResize( true );
|
|
||||||
initSizePolicy( QskSizePolicy::Expanding, QskSizePolicy::Fixed );
|
|
||||||
|
|
||||||
m_data->keyButtons.reserve( RowCount * ColumnCount );
|
|
||||||
|
|
||||||
const auto autoRepeatInterval =
|
|
||||||
1000 / QGuiApplication::styleHints()->keyboardAutoRepeatRate();
|
|
||||||
|
|
||||||
for ( int row = 0; row < RowCount; row++ )
|
|
||||||
{
|
|
||||||
for ( int col = 0; col < ColumnCount; col++ )
|
|
||||||
{
|
|
||||||
auto button = new Button( row, col, this );
|
|
||||||
button->installEventFilter( this );
|
|
||||||
|
|
||||||
button->setAutoRepeat( false );
|
|
||||||
button->setAutoRepeatDelay( 500 );
|
|
||||||
button->setAutoRepeatInterval( autoRepeatInterval );
|
|
||||||
|
|
||||||
connect( button, &QskPushButton::pressed,
|
|
||||||
this, &QskVirtualKeyboard::buttonPressed );
|
|
||||||
|
|
||||||
m_data->keyButtons += button;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connect( this, &QskControl::localeChanged,
|
|
||||||
this, &QskVirtualKeyboard::updateLocale );
|
|
||||||
|
|
||||||
updateLocale( locale() );
|
|
||||||
}
|
|
||||||
|
|
||||||
QskVirtualKeyboard::~QskVirtualKeyboard()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QskAspect::Subcontrol QskVirtualKeyboard::substitutedSubcontrol(
|
|
||||||
QskAspect::Subcontrol subControl ) const
|
|
||||||
{
|
|
||||||
if ( subControl == QskBox::Panel )
|
|
||||||
return QskVirtualKeyboard::Panel;
|
|
||||||
|
|
||||||
return Inherited::substitutedSubcontrol( subControl );
|
|
||||||
}
|
|
||||||
|
|
||||||
QskVirtualKeyboard::Mode QskVirtualKeyboard::mode() const
|
|
||||||
{
|
|
||||||
return m_data->mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSizeF QskVirtualKeyboard::layoutSizeHint(
|
|
||||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
|
||||||
{
|
|
||||||
if ( which != Qt::PreferredSize )
|
|
||||||
return QSizeF();
|
|
||||||
|
|
||||||
constexpr qreal ratio = qreal( RowCount ) / ColumnCount;
|
|
||||||
|
|
||||||
qreal w = constraint.width();
|
|
||||||
qreal h = constraint.height();
|
|
||||||
|
|
||||||
if ( h >= 0 )
|
|
||||||
{
|
|
||||||
const auto padding = innerPadding( Panel, QSizeF( h, h ) );
|
|
||||||
const auto dw = padding.left() + padding.right();
|
|
||||||
const auto dh = padding.top() + padding.bottom();
|
|
||||||
|
|
||||||
w = ( h - dh ) / ratio + dw;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( w < 0 )
|
|
||||||
w = 600;
|
|
||||||
|
|
||||||
const auto padding = innerPadding( Panel, QSizeF( w, w ) );
|
|
||||||
const auto dw = padding.left() + padding.right();
|
|
||||||
const auto dh = padding.top() + padding.bottom();
|
|
||||||
|
|
||||||
h = ( w - dw ) * ratio + dh;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QSizeF( w, h );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskVirtualKeyboard::updateLayout()
|
|
||||||
{
|
{
|
||||||
const auto r = layoutRect();
|
const auto r = layoutRect();
|
||||||
if ( r.isEmpty() )
|
if ( r.isEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto spacing = spacingHint( Panel );
|
const auto spacing = spacingHint( Panel );
|
||||||
const auto totalVSpacing = ( RowCount - 1 ) * spacing;
|
const auto totalVSpacing = ( rowCount() - 1 ) * spacing;
|
||||||
|
|
||||||
const auto keyHeight = ( r.height() - totalVSpacing ) / RowCount;
|
const auto keyHeight = ( r.height() - totalVSpacing ) / rowCount();
|
||||||
|
|
||||||
const auto& keyCodes = ( *m_data->currentLayout )[ m_data->mode ];
|
|
||||||
|
|
||||||
qreal yPos = r.top();
|
qreal yPos = r.top();
|
||||||
|
|
||||||
for ( int row = 0; row < RowCount; row++ )
|
const auto& page = ( *m_data->currentLayout )[ mode() ];
|
||||||
{
|
|
||||||
const auto& keys = keyCodes.data[ row ];
|
|
||||||
|
|
||||||
|
for ( int i = 0; i < page.size(); i++ )
|
||||||
|
{
|
||||||
|
const QVector< int > row = page[ i ];
|
||||||
#if 1
|
#if 1
|
||||||
// there should be a better way
|
// there should be a better way
|
||||||
auto totalHSpacing = -spacing;
|
auto totalHSpacing = -spacing;
|
||||||
if ( spacing )
|
if ( spacing )
|
||||||
{
|
{
|
||||||
for ( int col = 0; col < ColumnCount; col++ )
|
for ( int j = 0; j < row.size(); j++ )
|
||||||
{
|
{
|
||||||
if ( keys[ col ] != 0 )
|
if ( row[ j ] != 0 )
|
||||||
totalHSpacing += spacing;
|
totalHSpacing += spacing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
const auto baseKeyWidth = ( r.width() - totalHSpacing ) / qskRowStretch( keys );
|
const auto baseKeyWidth = ( r.width() - totalHSpacing ) / rowStretch( row );
|
||||||
qreal xPos = r.left();
|
qreal xPos = r.left();
|
||||||
|
|
||||||
for ( int col = 0; col < ColumnCount; col++ )
|
for ( int j = 0; j < columnCount(); j++ )
|
||||||
{
|
{
|
||||||
const int key = keys[ col ];
|
auto button = m_data->keyButtons[ i * columnCount() + j ];
|
||||||
auto button = m_data->keyButtons[ row * ColumnCount + col ];
|
|
||||||
|
|
||||||
button->setVisible( key != 0 );
|
if( j < row.size() )
|
||||||
|
|
||||||
if ( button->isVisible() )
|
|
||||||
{
|
{
|
||||||
const qreal keyWidth = baseKeyWidth * qskKeyStretch( key );
|
const int key = row[ j ];
|
||||||
|
button->setVisible( isKeyVisible( key ) );
|
||||||
|
|
||||||
const QRectF rect( xPos, yPos, keyWidth, keyHeight );
|
if ( button->isVisible() )
|
||||||
|
{
|
||||||
|
const qreal keyWidth = baseKeyWidth * keyStretch( key );
|
||||||
|
|
||||||
button->setGeometry( rect );
|
const QRectF rect( xPos, yPos, keyWidth, keyHeight );
|
||||||
button->setAutoRepeat( qskIsAutorepeat( key ) );
|
|
||||||
button->setText( qskTextForKey( key ) );
|
|
||||||
|
|
||||||
xPos += keyWidth + spacing;
|
button->setGeometry( rect );
|
||||||
|
button->setAutoRepeat( qskIsAutorepeat( key ) );
|
||||||
|
button->setKey( key );
|
||||||
|
button->setText( textForKey( key ) );
|
||||||
|
|
||||||
|
const auto type = typeForKey( key );
|
||||||
|
const auto emphasis = emphasisForType( type );
|
||||||
|
button->setEmphasis( emphasis );
|
||||||
|
|
||||||
|
xPos += keyWidth + spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button->setVisible( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,14 +314,88 @@ bool QskVirtualKeyboard::hasKey( int keyCode ) const
|
|||||||
return m_data->keyCodes.contains( keyCode );
|
return m_data->keyCodes.contains( keyCode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QskVirtualKeyboard::rowCount() const
|
||||||
|
{
|
||||||
|
return m_data->rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskVirtualKeyboard::setRowCount( int rowCount )
|
||||||
|
{
|
||||||
|
m_data->rowCount = rowCount;
|
||||||
|
ensureButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
int QskVirtualKeyboard::columnCount() const
|
||||||
|
{
|
||||||
|
return m_data->columnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskVirtualKeyboard::setColumnCount( int columnCount )
|
||||||
|
{
|
||||||
|
m_data->columnCount = columnCount;
|
||||||
|
ensureButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
QskVirtualKeyboardLayouts QskVirtualKeyboard::layouts() const
|
||||||
|
{
|
||||||
|
return m_data->layouts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskVirtualKeyboard::setLayouts( const QskVirtualKeyboardLayouts& layouts )
|
||||||
|
{
|
||||||
|
m_data->layouts = layouts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskVirtualKeyboard::ensureButtons()
|
||||||
|
{
|
||||||
|
const int newButtonSize = rowCount() * columnCount();
|
||||||
|
const int oldButtonSize = m_data->keyButtons.size();
|
||||||
|
|
||||||
|
if( newButtonSize == oldButtonSize )
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto autoRepeatInterval =
|
||||||
|
1000 / QGuiApplication::styleHints()->keyboardAutoRepeatRate();
|
||||||
|
|
||||||
|
m_data->keyButtons.reserve( rowCount() * columnCount() );
|
||||||
|
|
||||||
|
for( int i = 0; i < rowCount(); i++ )
|
||||||
|
{
|
||||||
|
for( int j = 0; j < columnCount(); j++ )
|
||||||
|
{
|
||||||
|
const int index = i * columnCount() + j;
|
||||||
|
|
||||||
|
if( index >= m_data->keyButtons.size() )
|
||||||
|
{
|
||||||
|
auto button = new Button( this );
|
||||||
|
button->installEventFilter( this );
|
||||||
|
|
||||||
|
button->setAutoRepeat( false );
|
||||||
|
button->setAutoRepeatDelay( 500 );
|
||||||
|
button->setAutoRepeatInterval( autoRepeatInterval );
|
||||||
|
|
||||||
|
connect( button, &QskPushButton::pressed,
|
||||||
|
this, &QskVirtualKeyboard::buttonPressed );
|
||||||
|
|
||||||
|
m_data->keyButtons += button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while( m_data->keyButtons.size() > newButtonSize )
|
||||||
|
{
|
||||||
|
auto* button = m_data->keyButtons.takeLast();
|
||||||
|
button->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QskVirtualKeyboard::buttonPressed()
|
void QskVirtualKeyboard::buttonPressed()
|
||||||
{
|
{
|
||||||
const auto button = static_cast< const Button* >( sender() );
|
const auto button = static_cast< const Button* >( sender() );
|
||||||
if ( button == nullptr )
|
if ( button == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto& keyCodes = ( *m_data->currentLayout )[ m_data->mode ];
|
const int key = button->key();
|
||||||
const int key = keyCodes.data[ button->row() ][ button->column() ];
|
|
||||||
|
|
||||||
// Mode-switching keys
|
// Mode-switching keys
|
||||||
switch ( key )
|
switch ( key )
|
||||||
@ -427,6 +429,49 @@ void QskVirtualKeyboard::buttonPressed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskVirtualKeyboard::updateKeyCodes()
|
||||||
|
{
|
||||||
|
m_data->keyCodes = {};
|
||||||
|
m_data->keyCodes.reserve( rowCount() * columnCount() );
|
||||||
|
|
||||||
|
for ( int mode = 0; mode < ModeCount; mode++ )
|
||||||
|
{
|
||||||
|
const auto& page = ( *m_data->currentLayout )[ mode ];
|
||||||
|
|
||||||
|
for ( int i = 0; i < page.size(); i++ )
|
||||||
|
{
|
||||||
|
const auto& row = page[ i ];
|
||||||
|
|
||||||
|
for ( int j = 0; j < row.size(); j++ )
|
||||||
|
{
|
||||||
|
m_data->keyCodes += row[ j ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QskVirtualKeyboard::rowStretch( const QVector< int >& row )
|
||||||
|
{
|
||||||
|
qreal stretch = 0;
|
||||||
|
|
||||||
|
for ( const int& key : row )
|
||||||
|
{
|
||||||
|
if ( !key )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stretch += keyStretch( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stretch == 0.0 )
|
||||||
|
{
|
||||||
|
stretch = columnCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return stretch;
|
||||||
|
}
|
||||||
|
|
||||||
void QskVirtualKeyboard::updateLocale( const QLocale& locale )
|
void QskVirtualKeyboard::updateLocale( const QLocale& locale )
|
||||||
{
|
{
|
||||||
const QskVirtualKeyboardLayouts::Layout* newLayout = nullptr;
|
const QskVirtualKeyboardLayouts::Layout* newLayout = nullptr;
|
||||||
@ -434,23 +479,23 @@ void QskVirtualKeyboard::updateLocale( const QLocale& locale )
|
|||||||
switch ( locale.language() )
|
switch ( locale.language() )
|
||||||
{
|
{
|
||||||
case QLocale::Bulgarian:
|
case QLocale::Bulgarian:
|
||||||
newLayout = &qskKeyboardLayouts.bg;
|
newLayout = &m_data->layouts.bg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Czech:
|
case QLocale::Czech:
|
||||||
newLayout = &qskKeyboardLayouts.cs;
|
newLayout = &m_data->layouts.cs;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::German:
|
case QLocale::German:
|
||||||
newLayout = &qskKeyboardLayouts.de;
|
newLayout = &m_data->layouts.de;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Danish:
|
case QLocale::Danish:
|
||||||
newLayout = &qskKeyboardLayouts.da;
|
newLayout = &m_data->layouts.da;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Greek:
|
case QLocale::Greek:
|
||||||
newLayout = &qskKeyboardLayouts.el;
|
newLayout = &m_data->layouts.el;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::English:
|
case QLocale::English:
|
||||||
@ -461,11 +506,11 @@ void QskVirtualKeyboard::updateLocale( const QLocale& locale )
|
|||||||
case QLocale::UnitedStates:
|
case QLocale::UnitedStates:
|
||||||
case QLocale::UnitedStatesMinorOutlyingIslands:
|
case QLocale::UnitedStatesMinorOutlyingIslands:
|
||||||
case QLocale::UnitedStatesVirginIslands:
|
case QLocale::UnitedStatesVirginIslands:
|
||||||
newLayout = &qskKeyboardLayouts.en_US;
|
newLayout = &m_data->layouts.en_US;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
newLayout = &qskKeyboardLayouts.en_GB;
|
newLayout = &m_data->layouts.en_GB;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,94 +518,109 @@ void QskVirtualKeyboard::updateLocale( const QLocale& locale )
|
|||||||
}
|
}
|
||||||
|
|
||||||
case QLocale::Spanish:
|
case QLocale::Spanish:
|
||||||
newLayout = &qskKeyboardLayouts.es;
|
newLayout = &m_data->layouts.es;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Finnish:
|
case QLocale::Finnish:
|
||||||
newLayout = &qskKeyboardLayouts.fi;
|
newLayout = &m_data->layouts.fi;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::French:
|
case QLocale::French:
|
||||||
newLayout = &qskKeyboardLayouts.fr;
|
newLayout = &m_data->layouts.fr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Hungarian:
|
case QLocale::Hungarian:
|
||||||
newLayout = &qskKeyboardLayouts.hu;
|
newLayout = &m_data->layouts.hu;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Italian:
|
case QLocale::Italian:
|
||||||
newLayout = &qskKeyboardLayouts.it;
|
newLayout = &m_data->layouts.it;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Japanese:
|
case QLocale::Japanese:
|
||||||
newLayout = &qskKeyboardLayouts.ja;
|
newLayout = &m_data->layouts.ja;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Latvian:
|
case QLocale::Latvian:
|
||||||
newLayout = &qskKeyboardLayouts.lv;
|
newLayout = &m_data->layouts.lv;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Lithuanian:
|
case QLocale::Lithuanian:
|
||||||
newLayout = &qskKeyboardLayouts.lt;
|
newLayout = &m_data->layouts.lt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Dutch:
|
case QLocale::Dutch:
|
||||||
newLayout = &qskKeyboardLayouts.nl;
|
newLayout = &m_data->layouts.nl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Portuguese:
|
case QLocale::Portuguese:
|
||||||
newLayout = &qskKeyboardLayouts.pt;
|
newLayout = &m_data->layouts.pt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Romanian:
|
case QLocale::Romanian:
|
||||||
newLayout = &qskKeyboardLayouts.ro;
|
newLayout = &m_data->layouts.ro;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Russian:
|
case QLocale::Russian:
|
||||||
newLayout = &qskKeyboardLayouts.ru;
|
newLayout = &m_data->layouts.ru;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Slovenian:
|
case QLocale::Slovenian:
|
||||||
newLayout = &qskKeyboardLayouts.sl;
|
newLayout = &m_data->layouts.sl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Slovak:
|
case QLocale::Slovak:
|
||||||
newLayout = &qskKeyboardLayouts.sk;
|
newLayout = &m_data->layouts.sk;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Turkish:
|
case QLocale::Turkish:
|
||||||
newLayout = &qskKeyboardLayouts.tr;
|
newLayout = &m_data->layouts.tr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QLocale::Chinese:
|
case QLocale::Chinese:
|
||||||
newLayout = &qskKeyboardLayouts.zh;
|
newLayout = &m_data->layouts.zh;
|
||||||
break;
|
break;
|
||||||
#if 1
|
#if 1
|
||||||
case QLocale::C:
|
case QLocale::C:
|
||||||
newLayout = &qskKeyboardLayouts.en_US;
|
newLayout = &m_data->layouts.en_US;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
qWarning() << "QskVirtualKeyboard: unsupported locale:" << locale;
|
qWarning() << "QskVirtualKeyboard: unsupported locale:" << locale;
|
||||||
newLayout = &qskKeyboardLayouts.en_US;
|
newLayout = &m_data->layouts.en_US;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( newLayout != m_data->currentLayout )
|
if ( newLayout != m_data->currentLayout )
|
||||||
{
|
{
|
||||||
m_data->currentLayout = newLayout;
|
m_data->currentLayout = newLayout;
|
||||||
m_data->keyCodes = qskKeyCodes( *newLayout );
|
updateKeyCodes();
|
||||||
|
|
||||||
setMode( LowercaseMode );
|
setMode( LowercaseMode );
|
||||||
polish();
|
polish();
|
||||||
|
Q_EMIT keyboardLayoutChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskVirtualKeyboard::setMode( QskVirtualKeyboard::Mode mode )
|
QskPushButton::Emphasis QskVirtualKeyboard::emphasisForType( KeyType type )
|
||||||
{
|
{
|
||||||
m_data->mode = mode;
|
switch( type )
|
||||||
polish();
|
{
|
||||||
|
case EnterType:
|
||||||
|
return QskPushButton::VeryHighEmphasis;
|
||||||
|
|
||||||
Q_EMIT modeChanged( m_data->mode );
|
case BackspaceType:
|
||||||
|
case CapsSwitchType:
|
||||||
|
return QskPushButton::HighEmphasis;
|
||||||
|
|
||||||
|
case ModeSwitchType:
|
||||||
|
return QskPushButton::LowEmphasis;
|
||||||
|
|
||||||
|
case SpecialCharacterType:
|
||||||
|
return QskPushButton::VeryLowEmphasis;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QskPushButton::NoEmphasis;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_QskVirtualKeyboard.cpp"
|
#include "moc_QskVirtualKeyboard.cpp"
|
||||||
|
@ -7,6 +7,37 @@
|
|||||||
#define QSK_VIRTUAL_KEYBOARD_H
|
#define QSK_VIRTUAL_KEYBOARD_H
|
||||||
|
|
||||||
#include "QskBox.h"
|
#include "QskBox.h"
|
||||||
|
#include "QskPushButton.h"
|
||||||
|
|
||||||
|
class QSK_EXPORT QskVirtualKeyboardLayouts
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Layout = QVector< QVector< QVector< int > > >;
|
||||||
|
|
||||||
|
Layout bg; // Bulgarian
|
||||||
|
Layout cs; // Czech
|
||||||
|
Layout de; // German
|
||||||
|
Layout da; // Danish
|
||||||
|
Layout el; // Greek
|
||||||
|
Layout en_GB; // English (GB)
|
||||||
|
Layout en_US; // English (US)
|
||||||
|
Layout es; // Spanish
|
||||||
|
Layout fi; // Finnish
|
||||||
|
Layout fr; // French
|
||||||
|
Layout hu; // Hungarian
|
||||||
|
Layout it; // Italian
|
||||||
|
Layout ja; // Japanese
|
||||||
|
Layout lv; // Latvian
|
||||||
|
Layout lt; // Lithuanian
|
||||||
|
Layout nl; // Dutch
|
||||||
|
Layout pt; // Portuguese
|
||||||
|
Layout ro; // Romanian
|
||||||
|
Layout ru; // Russian
|
||||||
|
Layout sl; // Slovene
|
||||||
|
Layout sk; // Slovak
|
||||||
|
Layout tr; // Turkish
|
||||||
|
Layout zh; // Chinese
|
||||||
|
};
|
||||||
|
|
||||||
class QSK_EXPORT QskVirtualKeyboard : public QskBox
|
class QSK_EXPORT QskVirtualKeyboard : public QskBox
|
||||||
{
|
{
|
||||||
@ -27,6 +58,16 @@ class QSK_EXPORT QskVirtualKeyboard : public QskBox
|
|||||||
};
|
};
|
||||||
Q_ENUM( Mode )
|
Q_ENUM( Mode )
|
||||||
|
|
||||||
|
enum KeyType
|
||||||
|
{
|
||||||
|
NormalType,
|
||||||
|
EnterType,
|
||||||
|
BackspaceType,
|
||||||
|
CapsSwitchType,
|
||||||
|
ModeSwitchType,
|
||||||
|
SpecialCharacterType
|
||||||
|
};
|
||||||
|
|
||||||
QskVirtualKeyboard( QQuickItem* parent = nullptr );
|
QskVirtualKeyboard( QQuickItem* parent = nullptr );
|
||||||
~QskVirtualKeyboard() override;
|
~QskVirtualKeyboard() override;
|
||||||
|
|
||||||
@ -37,19 +78,36 @@ class QSK_EXPORT QskVirtualKeyboard : public QskBox
|
|||||||
|
|
||||||
bool hasKey( int keyCode ) const;
|
bool hasKey( int keyCode ) const;
|
||||||
|
|
||||||
|
int rowCount() const;
|
||||||
|
void setRowCount( int );
|
||||||
|
|
||||||
|
int columnCount() const;
|
||||||
|
void setColumnCount( int );
|
||||||
|
|
||||||
|
QskVirtualKeyboardLayouts layouts() const;
|
||||||
|
void setLayouts( const QskVirtualKeyboardLayouts& );
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void modeChanged( Mode );
|
void modeChanged( QskVirtualKeyboard::Mode );
|
||||||
|
void keyboardLayoutChanged();
|
||||||
void keySelected( int keyCode );
|
void keySelected( int keyCode );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual qreal keyStretch( int ) const;
|
||||||
|
virtual bool isKeyVisible( int ) const;
|
||||||
|
virtual QString textForKey( int ) const;
|
||||||
|
virtual KeyType typeForKey( int ) const;
|
||||||
|
|
||||||
void updateLayout() override;
|
void updateLayout() override;
|
||||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
||||||
QskAspect::Subcontrol substitutedSubcontrol(
|
|
||||||
QskAspect::Subcontrol ) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ensureButtons();
|
||||||
void buttonPressed();
|
void buttonPressed();
|
||||||
|
void updateKeyCodes();
|
||||||
|
QskPushButton::Emphasis emphasisForType( KeyType );
|
||||||
|
|
||||||
|
qreal rowStretch( const QVector< int >& );
|
||||||
|
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user