396 lines
11 KiB
C++
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
2023-04-06 09:23:37 +02:00
* SPDX-License-Identifier: BSD-3-Clause
2017-07-21 18:21:34 +02:00
*****************************************************************************/
#include <SkinnyShortcut.h>
2017-07-28 14:47:11 +02:00
#include <QskDialog.h>
#include <QskFocusIndicator.h>
2018-08-03 08:15:28 +02:00
#include <QskInputContext.h>
#include <QskInputPanel.h>
2017-07-28 14:47:11 +02:00
#include <QskLinearBox.h>
#include <QskListView.h>
#include <QskTextInput.h>
2017-07-28 14:47:11 +02:00
#include <QskAspect.h>
2020-03-13 13:32:22 +01:00
#include <QskFunctions.h>
#include <QskInputPanelBox.h>
2017-07-21 18:21:34 +02:00
#include <QskObjectCounter.h>
#include <QskVirtualKeyboard.h>
#include <QskWindow.h>
2017-07-21 18:21:34 +02:00
#include <QFontMetricsF>
2018-08-03 08:15:28 +02:00
#include <QGuiApplication>
2017-07-21 18:21:34 +02:00
namespace
{
class Keyboard final : public QskVirtualKeyboard
{
using Inherited = QskVirtualKeyboard;
public:
Keyboard( QQuickItem* parentItem = nullptr ):
QskVirtualKeyboard( parentItem )
{
// here rearrange keyboard layouts if necessary
}
};
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 );
}
void attachItem( QQuickItem* item ) override
{
m_box->attachInputItem( item );
}
QQuickItem* inputProxy() const override
{
return m_box->inputProxy();
}
void setPrompt( const QString& prompt ) override
{
m_box->setInputPrompt( prompt );
}
void setPredictionEnabled( bool on ) override
{
m_box->setPanelHint( QskInputPanelBox::Prediction, on );
}
void setPrediction( const QStringList& prediction ) override
{
QskInputPanel::setPrediction( prediction );
m_box->setPrediction( prediction );
}
private:
QskInputPanelBox* m_box;
};
class InputContextFactory : public QskInputContextFactory
{
QskInputPanel* createPanel() const override
{
return new Panel;
}
};
QString nativeLocaleString( const QLocale& locale )
{
switch ( locale.language() )
{
case QLocale::Bulgarian:
return QStringLiteral( "български език" );
case QLocale::Czech:
return QStringLiteral( "Čeština" );
case QLocale::German:
return QStringLiteral( "Deutsch" );
case QLocale::Danish:
return QStringLiteral( "Dansk" );
case QLocale::Greek:
return QStringLiteral( "Eλληνικά" );
case QLocale::English:
{
2023-11-15 11:52:07 +01:00
const auto territory =
#if QT_VERSION >= QT_VERSION_CHECK( 6, 2, 0 )
locale.territory();
#else
locale.country();
#endif
switch ( territory )
{
case QLocale::Canada:
case QLocale::UnitedStates:
case QLocale::UnitedStatesMinorOutlyingIslands:
case QLocale::UnitedStatesVirginIslands:
return QStringLiteral( "English (US)" );
default:
return QStringLiteral( "English (UK)" );
}
}
case QLocale::Spanish:
return QStringLiteral( "Español" );
case QLocale::Finnish:
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() );
}
}
}
2017-07-28 14:47:11 +02:00
class InputBox : public QskLinearBox
{
2018-08-03 08:15:28 +02:00
public:
InputBox( QQuickItem* parentItem = nullptr )
: QskLinearBox( Qt::Vertical, parentItem )
2017-07-28 14:47:11 +02:00
{
2018-04-11 17:33:43 +02:00
setExtraSpacingAt( Qt::BottomEdge | Qt::RightEdge );
2017-07-28 14:47:11 +02:00
setMargins( 10 );
setSpacing( 10 );
2018-04-11 17:33:43 +02:00
auto* textInput1 = new QskTextInput( this );
2018-04-13 16:24:08 +02:00
textInput1->setText( "Press and edit Me." );
2018-04-11 17:33:43 +02:00
textInput1->setSizePolicy( Qt::Horizontal, QskSizePolicy::Preferred );
auto* textInput2 = new QskTextInput( this );
2018-04-13 16:24:08 +02:00
textInput2->setText( "Press and edit Me." );
2018-04-11 17:33:43 +02:00
textInput2->setSizePolicy( Qt::Horizontal, QskSizePolicy::Preferred );
2018-04-18 10:46:11 +02:00
textInput2->setActivationModes( QskTextInput::ActivationOnAll );
2018-04-13 16:24:08 +02:00
auto* textInput3 = new QskTextInput( this );
textInput3->setReadOnly( true );
textInput3->setText( "Read Only information." );
textInput3->setSizePolicy( Qt::Horizontal, QskSizePolicy::Preferred );
auto* textInput4 = new QskTextInput( this );
textInput4->setEchoMode( QskTextInput::Password );
textInput4->setPasswordMaskDelay( 1000 );
2018-04-13 16:24:08 +02:00
textInput4->setMaxLength( 8 );
textInput4->setText( "12345678" );
textInput4->setSizePolicy( Qt::Horizontal, QskSizePolicy::Preferred );
2017-07-28 14:47:11 +02:00
}
};
2018-07-31 17:32:25 +02:00
class LocaleListView final : public QskListView
{
2018-06-08 12:54:00 +02:00
Q_OBJECT
2018-08-03 08:15:28 +02:00
public:
LocaleListView( QQuickItem* parentItem = nullptr )
: QskListView( parentItem )
, m_maxWidth( 0.0 )
{
2018-04-06 17:30:24 +02:00
for ( auto language :
{
QLocale::Bulgarian, QLocale::Czech, QLocale::German,
QLocale::Danish, QLocale::English, QLocale::Spanish,
QLocale::Finnish, QLocale::French, QLocale::Hungarian,
QLocale::Italian, QLocale::Japanese, QLocale::Latvian,
QLocale::Lithuanian, QLocale::Dutch, QLocale::Portuguese,
QLocale::Romanian, QLocale::Russian, QLocale::Slovenian,
QLocale::Slovak, QLocale::Turkish, QLocale::Chinese
} )
{
if ( language == QLocale::English )
{
append( QLocale( QLocale::English, QLocale::UnitedStates ) );
append( QLocale( QLocale::English, QLocale::UnitedKingdom ) );
}
else
{
append( QLocale( language ) );
}
}
setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
setPreferredWidth( columnWidth( 0 ) + 20 );
setScrollableSize( QSizeF( columnWidth( 0 ), rowCount() * rowHeight() ) );
2018-06-08 12:54:00 +02:00
connect( this, &QskListView::selectedRowChanged,
[ this ]( int row ) { Q_EMIT selected( localeAt( row ) ); } );
}
2018-07-31 17:32:25 +02:00
int rowCount() const override
{
return m_values.count();
}
2018-07-31 17:32:25 +02:00
int columnCount() const override
{
return 1;
}
2018-07-31 17:32:25 +02:00
qreal columnWidth( int ) const override
{
if ( m_maxWidth == 0.0 )
{
const QFontMetricsF fm( effectiveFont( Text ) );
2017-10-30 12:06:19 +01:00
for ( const auto& entry : m_values )
2020-03-13 13:32:22 +01:00
m_maxWidth = qMax( m_maxWidth, qskHorizontalAdvance( fm, entry.first ) );
const auto padding = paddingHint( Cell );
m_maxWidth += padding.left() + padding.right();
}
return m_maxWidth;
}
2018-07-31 17:32:25 +02:00
qreal rowHeight() const override
{
const QFontMetricsF fm( effectiveFont( Text ) );
const auto padding = paddingHint( Cell );
return fm.height() + padding.top() + padding.bottom();
}
2018-07-31 17:32:25 +02:00
QVariant valueAt( int row, int ) const override
{
2018-08-03 08:15:28 +02:00
return m_values[ row ].first;
}
2018-04-04 20:19:47 +02:00
QLocale localeAt( int row ) const
{
if ( row >= 0 && row < m_values.size() )
2018-08-03 08:15:28 +02:00
return m_values[ row ].second;
2018-04-04 20:19:47 +02:00
return QLocale();
}
2018-08-03 08:15:28 +02:00
Q_SIGNALS:
2018-06-08 12:54:00 +02:00
void selected( const QLocale& );
2018-08-03 08:15:28 +02:00
private:
2018-04-06 17:30:24 +02:00
inline void append( const QLocale& locale )
{
m_values += qMakePair( nativeLocaleString( locale ), locale );
}
QVector< QPair< QString, QLocale > > m_values;
mutable qreal m_maxWidth;
};
2018-06-08 12:54:00 +02:00
class Window : public QskWindow
{
2018-08-03 08:15:28 +02:00
public:
2018-06-08 12:54:00 +02:00
Window()
{
populate();
}
void populate()
{
auto box = new QskLinearBox( Qt::Horizontal );
box->setSpacing( 10 );
box->setPadding( 10 );
box->setPanel( true );
2018-06-08 12:54:00 +02:00
auto listView = new LocaleListView( box );
2018-08-03 08:15:28 +02:00
auto inputBox = new InputBox( box );
2018-06-08 12:54:00 +02:00
/*
Disable Qt::ClickFocus, so that the input panel stays open
when selecting a different locale
*/
listView->setFocusPolicy( Qt::TabFocus );
connect( listView, &LocaleListView::selected,
inputBox, &InputBox::setLocale );
addItem( box );
addItem( new QskFocusIndicator() );
}
};
2017-07-21 18:21:34 +02:00
int main( int argc, char* argv[] )
{
#ifdef ITEM_STATISTICS
QskObjectCounter counter( true );
#endif
qputenv( "QT_IM_MODULE", "skinny" );
2017-07-21 18:21:34 +02:00
QGuiApplication app( argc, argv );
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
2017-07-21 18:21:34 +02:00
2018-04-12 12:03:51 +02:00
#if 1
2018-04-27 13:48:51 +02:00
// We don't want to have the input panel in a top level window.
2017-07-28 14:47:11 +02:00
qskDialog->setPolicy( QskDialog::EmbeddedBox );
#endif
2018-06-12 08:20:48 +02:00
Window window1;
window1.setObjectName( "Window 1" );
window1.setTitle( "Window 1" );
2018-06-12 08:20:48 +02:00
window1.resize( 600, 600 );
window1.show();
2017-07-21 18:21:34 +02:00
#if 1
2018-06-08 12:54:00 +02:00
Window window2;
2018-06-12 08:20:48 +02:00
window2.setObjectName( "Window 2" );
window2.setTitle( "Window 2" );
2018-06-12 08:20:48 +02:00
window2.setX( window1.x() + 100 );
2018-06-08 12:54:00 +02:00
window2.resize( 600, 600 );
window2.show();
#endif
QskInputContext::instance()->setFactory( new InputContextFactory() );
2017-07-21 18:21:34 +02:00
return app.exec();
}
2018-06-08 12:54:00 +02:00
#include "main.moc"