virtual keyboard related stuff improved
This commit is contained in:
parent
7b2e63c7e5
commit
f4060f2e75
|
|
@ -58,11 +58,19 @@ QskVirtualKeyboard* qskVirtualKeyboard( QQuickItem* inputPanel )
|
||||||
class QskInputContext::PrivateData
|
class QskInputContext::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
PrivateData():
|
||||||
|
ownsInputPanelWindow( false )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
QPointer< QQuickItem > inputItem;
|
QPointer< QQuickItem > inputItem;
|
||||||
QPointer< QQuickItem > inputPanel;
|
QPointer< QQuickItem > inputPanel;
|
||||||
|
|
||||||
QskInputCompositionModel* compositionModel;
|
QskInputCompositionModel* compositionModel;
|
||||||
QHash< QLocale, QskInputCompositionModel* > compositionModels;
|
QHash< QLocale, QskInputCompositionModel* > compositionModels;
|
||||||
|
|
||||||
|
// the input panel is embedded in a window
|
||||||
|
bool ownsInputPanelWindow : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
QskInputContext::QskInputContext():
|
QskInputContext::QskInputContext():
|
||||||
|
|
@ -104,54 +112,79 @@ bool QskInputContext::hasCapability( Capability ) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQuickItem* QskInputContext::inputItem()
|
||||||
|
{
|
||||||
|
return m_data->inputItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskInputContext::setInputItem( QQuickItem* item )
|
||||||
|
{
|
||||||
|
if ( m_data->inputItem == item )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data->inputItem = item;
|
||||||
|
|
||||||
|
if ( m_data->inputItem == nullptr )
|
||||||
|
{
|
||||||
|
hideInputPanel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
update( Qt::ImQueryAll );
|
||||||
|
}
|
||||||
|
|
||||||
void QskInputContext::update( Qt::InputMethodQueries queries )
|
void QskInputContext::update( Qt::InputMethodQueries queries )
|
||||||
{
|
{
|
||||||
if ( m_data->inputItem == nullptr )
|
if ( m_data->inputItem == nullptr || m_data->inputPanel == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto queryEvent = queryInputMethod( queries );
|
const auto queryEvent = queryInputMethod( queries );
|
||||||
|
|
||||||
// Qt::ImCursorRectangle
|
if ( queryEvent.queries() & Qt::ImEnabled )
|
||||||
// Qt::ImFont
|
|
||||||
// Qt::ImCursorPosition
|
|
||||||
// Qt::ImSurroundingText // important for chinese input
|
|
||||||
// Qt::ImCurrentSelection // important for prediction
|
|
||||||
// Qt::ImMaximumTextLength // should be monitored
|
|
||||||
// Qt::ImAnchorPosition
|
|
||||||
|
|
||||||
if ( queries & Qt::ImHints )
|
|
||||||
{
|
{
|
||||||
|
if ( !queryEvent.value( Qt::ImEnabled ).toBool() )
|
||||||
|
{
|
||||||
|
hideInputPanel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( queryEvent.queries() & Qt::ImHints )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
ImhHiddenText = 0x1, // might need to disable certain checks
|
||||||
|
ImhSensitiveData = 0x2, // shouldn't change anything
|
||||||
|
ImhNoAutoUppercase = 0x4, // if we support auto uppercase, disable it
|
||||||
|
ImhPreferNumbers = 0x8, // default to number keyboard
|
||||||
|
ImhPreferUppercase = 0x10, // start with shift on
|
||||||
|
ImhPreferLowercase = 0x20, // start with shift off
|
||||||
|
ImhNoPredictiveText = 0x40, // ignored for now
|
||||||
|
|
||||||
|
ImhDate = 0x80, // ignored for now (no date keyboard)
|
||||||
|
ImhTime = 0x100, // ignored for know (no time keyboard)
|
||||||
|
|
||||||
|
ImhPreferLatin = 0x200, // can be used to launch chinese kb in english mode
|
||||||
|
|
||||||
|
ImhMultiLine = 0x400, // not useful?
|
||||||
|
|
||||||
|
ImhDigitsOnly // default to number keyboard, disable other keys
|
||||||
|
ImhFormattedNumbersOnly // hard to say
|
||||||
|
ImhUppercaseOnly // caps-lock, disable shift
|
||||||
|
ImhLowercaseOnly // disable shift
|
||||||
|
ImhDialableCharactersOnly // dial pad (calculator?)
|
||||||
|
ImhEmailCharactersOnly // disable certain symbols (email-only kb?)
|
||||||
|
ImhUrlCharactersOnly // disable certain symbols (url-only kb?)
|
||||||
|
ImhLatinOnly // disable chinese input
|
||||||
|
*/
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
const auto hints = static_cast< Qt::InputMethodHints >(
|
const auto hints = static_cast< Qt::InputMethodHints >(
|
||||||
queryEvent.value( Qt::ImHints ).toInt() );
|
queryEvent.value( Qt::ImHints ).toInt() );
|
||||||
|
|
||||||
//ImhHiddenText = 0x1, // might need to disable certain checks
|
|
||||||
//ImhSensitiveData = 0x2, // shouldn't change anything
|
|
||||||
//ImhNoAutoUppercase = 0x4, // if we support auto uppercase, disable it
|
|
||||||
//ImhPreferNumbers = 0x8, // default to number keyboard
|
|
||||||
//ImhPreferUppercase = 0x10, // start with shift on
|
|
||||||
//ImhPreferLowercase = 0x20, // start with shift off
|
|
||||||
//ImhNoPredictiveText = 0x40, // ignored for now
|
|
||||||
|
|
||||||
//ImhDate = 0x80, // ignored for now (no date keyboard)
|
|
||||||
//ImhTime = 0x100, // ignored for know (no time keyboard)
|
|
||||||
|
|
||||||
//ImhPreferLatin = 0x200, // can be used to launch chinese kb in english mode
|
|
||||||
|
|
||||||
//ImhMultiLine = 0x400, // not useful?
|
|
||||||
|
|
||||||
//ImhDigitsOnly // default to number keyboard, disable other keys
|
|
||||||
//ImhFormattedNumbersOnly // hard to say
|
|
||||||
//ImhUppercaseOnly // caps-lock, disable shift
|
|
||||||
//ImhLowercaseOnly // disable shift
|
|
||||||
//ImhDialableCharactersOnly // dial pad (calculator?)
|
|
||||||
//ImhEmailCharactersOnly // disable certain symbols (email-only kb?)
|
|
||||||
//ImhUrlCharactersOnly // disable certain symbols (url-only kb?)
|
|
||||||
//ImhLatinOnly // disable chinese input
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( queries & Qt::ImPreferredLanguage )
|
if ( queryEvent.queries() & Qt::ImPreferredLanguage )
|
||||||
{
|
{
|
||||||
const auto locale = queryEvent.value( Qt::ImPreferredLanguage ).toLocale();
|
const auto locale = queryEvent.value( Qt::ImPreferredLanguage ).toLocale();
|
||||||
|
|
||||||
|
|
@ -172,20 +205,24 @@ void QskInputContext::update( Qt::InputMethodQueries queries )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Qt::ImAbsolutePosition
|
/*
|
||||||
// Qt::ImTextBeforeCursor // important for chinese
|
Qt::ImMicroFocus
|
||||||
// Qt::ImTextAfterCursor // important for chinese
|
Qt::ImCursorRectangle
|
||||||
// Qt::ImPlatformData // hard to say...
|
Qt::ImFont
|
||||||
}
|
Qt::ImCursorPosition
|
||||||
|
Qt::ImSurroundingText // important for chinese input
|
||||||
|
Qt::ImCurrentSelection // important for prediction
|
||||||
|
Qt::ImMaximumTextLength // should be monitored
|
||||||
|
Qt::ImAnchorPosition
|
||||||
|
|
||||||
QQuickItem* QskInputContext::inputItem()
|
Qt::ImAbsolutePosition
|
||||||
{
|
Qt::ImTextBeforeCursor // important for chinese
|
||||||
return m_data->inputItem;
|
Qt::ImTextAfterCursor // important for chinese
|
||||||
}
|
Qt::ImPlatformData // hard to say...
|
||||||
|
Qt::ImEnterKeyType
|
||||||
void QskInputContext::setInputItem( QQuickItem* item )
|
Qt::ImAnchorRectangle
|
||||||
{
|
Qt::ImInputItemClipRectangle // could be used for the geometry of the panel
|
||||||
m_data->inputItem = item;
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskInputContext::keyboardRect() const
|
QRectF QskInputContext::keyboardRect() const
|
||||||
|
|
@ -212,9 +249,12 @@ void QskInputContext::showInputPanel()
|
||||||
|
|
||||||
if ( QskDialog::instance()->policy() == QskDialog::TopLevelWindow )
|
if ( QskDialog::instance()->policy() == QskDialog::TopLevelWindow )
|
||||||
{
|
{
|
||||||
|
m_data->ownsInputPanelWindow = true;
|
||||||
|
|
||||||
auto window = new QskWindow;
|
auto window = new QskWindow;
|
||||||
window->setFlags( Qt::Tool | Qt::WindowDoesNotAcceptFocus );
|
window->setFlags( Qt::Tool | Qt::WindowDoesNotAcceptFocus );
|
||||||
window->resize( 800, 240 ); // ### what size?
|
window->resize( 800, 240 ); // ### what size?
|
||||||
|
|
||||||
m_data->inputPanel->setParentItem( window->contentItem() );
|
m_data->inputPanel->setParentItem( window->contentItem() );
|
||||||
connect( window, &QskWindow::visibleChanged,
|
connect( window, &QskWindow::visibleChanged,
|
||||||
this, &QskInputContext::emitInputPanelVisibleChanged );
|
this, &QskInputContext::emitInputPanelVisibleChanged );
|
||||||
|
|
@ -230,24 +270,32 @@ void QskInputContext::showInputPanel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto window = m_data->inputPanel->window();
|
if ( m_data->ownsInputPanelWindow )
|
||||||
if ( window && window != QGuiApplication::focusWindow() )
|
{
|
||||||
window->show();
|
if ( m_data->inputPanel->window() )
|
||||||
|
m_data->inputPanel->window()->show();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_data->inputPanel->setVisible( true );
|
m_data->inputPanel->setVisible( true );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QskInputContext::hideInputPanel()
|
void QskInputContext::hideInputPanel()
|
||||||
{
|
{
|
||||||
if ( m_data->inputPanel == nullptr )
|
if ( m_data->inputPanel == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto window = m_data->inputPanel->window();
|
if ( m_data->ownsInputPanelWindow )
|
||||||
if ( window && window != QGuiApplication::focusWindow() )
|
{
|
||||||
|
if ( auto window = m_data->inputPanel->window() )
|
||||||
window->hide();
|
window->hide();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_data->inputPanel->setVisible( false );
|
m_data->inputPanel->setVisible( false );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool QskInputContext::isInputPanelVisible() const
|
bool QskInputContext::isInputPanelVisible() const
|
||||||
{
|
{
|
||||||
|
|
@ -269,38 +317,28 @@ Qt::LayoutDirection QskInputContext::inputDirection() const
|
||||||
|
|
||||||
void QskInputContext::setFocusObject( QObject* focusObject )
|
void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
{
|
{
|
||||||
if ( focusObject == nullptr )
|
|
||||||
{
|
|
||||||
setInputItem( nullptr );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool inputItemChanged = false;
|
|
||||||
|
|
||||||
auto focusItem = qobject_cast< QQuickItem* >( focusObject );
|
auto focusItem = qobject_cast< QQuickItem* >( focusObject );
|
||||||
if( focusItem )
|
|
||||||
|
if ( focusItem == nullptr )
|
||||||
{
|
{
|
||||||
// Do not change the input item when panel buttons get the focus:
|
if ( m_data->inputItem )
|
||||||
|
{
|
||||||
|
if ( m_data->inputItem->window() == QGuiApplication::focusWindow() )
|
||||||
|
setInputItem( nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Do not change the input item when
|
||||||
|
navigating on or into the panel
|
||||||
|
*/
|
||||||
|
|
||||||
if( qskNearestFocusScope( focusItem ) != m_data->inputPanel )
|
if( qskNearestFocusScope( focusItem ) != m_data->inputPanel )
|
||||||
{
|
|
||||||
setInputItem( focusItem );
|
setInputItem( focusItem );
|
||||||
inputItemChanged = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( inputItemChanged )
|
|
||||||
{
|
|
||||||
const auto queryEvent = queryInputMethod( Qt::ImEnabled );
|
|
||||||
if ( !queryEvent.value( Qt::ImEnabled ).toBool() )
|
|
||||||
{
|
|
||||||
hideInputPanel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update( Qt::InputMethodQuery( Qt::ImQueryAll & ~Qt::ImEnabled ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputContext::setCompositionModel(
|
void QskInputContext::setCompositionModel(
|
||||||
const QLocale& locale, QskInputCompositionModel* model )
|
const QLocale& locale, QskInputCompositionModel* model )
|
||||||
{
|
{
|
||||||
|
|
@ -355,10 +393,6 @@ void QskInputContext::invokeAction( QInputMethod::Action action, int value )
|
||||||
case QskVirtualKeyboard::SelectCandidate:
|
case QskVirtualKeyboard::SelectCandidate:
|
||||||
{
|
{
|
||||||
model->commitCandidate( value );
|
model->commitCandidate( value );
|
||||||
|
|
||||||
if ( auto keyboard = qskVirtualKeyboard( m_data->inputPanel ) )
|
|
||||||
keyboard->setPreeditCandidates( QVector< QString >() );
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QInputMethod::Click:
|
case QInputMethod::Click:
|
||||||
|
|
@ -403,6 +437,7 @@ void QskInputContext::setInputPanel( QQuickItem* inputPanel )
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data->inputPanel = inputPanel;
|
m_data->inputPanel = inputPanel;
|
||||||
|
m_data->ownsInputPanelWindow = false;
|
||||||
|
|
||||||
if ( inputPanel )
|
if ( inputPanel )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ public:
|
||||||
|
|
||||||
auto* textInput = new QskTextInput( this );
|
auto* textInput = new QskTextInput( this );
|
||||||
textInput->setText( "I am a line edit. Press and edit Me." );
|
textInput->setText( "I am a line edit. Press and edit Me." );
|
||||||
|
textInput->setSelectByMouse( true );
|
||||||
|
|
||||||
#if LOCAL_PANEL
|
#if LOCAL_PANEL
|
||||||
auto* inputPanel = new QskVirtualKeyboard( this );
|
auto* inputPanel = new QskVirtualKeyboard( this );
|
||||||
|
|
@ -179,6 +180,12 @@ int main( int argc, char* argv[] )
|
||||||
auto listView = new LocaleListView( box );
|
auto listView = new LocaleListView( box );
|
||||||
auto inputBox = new InputBox( box );
|
auto inputBox = new InputBox( box );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Disable Qt::ClickFocus, so that the input panel stays open
|
||||||
|
when selecting a different locale
|
||||||
|
*/
|
||||||
|
listView->setFocusPolicy( Qt::TabFocus );
|
||||||
|
|
||||||
QObject::connect( listView, &QskListView::selectedRowChanged,
|
QObject::connect( listView, &QskListView::selectedRowChanged,
|
||||||
inputBox, [ = ]( int row ) { inputBox->setLocale( listView->localeAt( row ) ); } );
|
inputBox, [ = ]( int row ) { inputBox->setLocale( listView->localeAt( row ) ); } );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquickitem_p.h>
|
#include <private/qquickitem_p.h>
|
||||||
|
#include <private/qinputmethod_p.h>
|
||||||
#if defined( QT_DEBUG )
|
#if defined( QT_DEBUG )
|
||||||
#include <private/qquickpositioners_p.h>
|
#include <private/qquickpositioners_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -144,6 +145,38 @@ QQuickItem* qskNearestFocusScope( const QQuickItem* item )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qskUpdateInputMethod( const QQuickItem* item, Qt::InputMethodQueries queries )
|
||||||
|
{
|
||||||
|
auto inputMethod = QGuiApplication::inputMethod();
|
||||||
|
|
||||||
|
bool doUpdate = item->hasActiveFocus();
|
||||||
|
|
||||||
|
if ( !doUpdate )
|
||||||
|
{
|
||||||
|
const auto inputContext =
|
||||||
|
QInputMethodPrivate::get( inputMethod )->platformInputContext();
|
||||||
|
|
||||||
|
if ( inputContext && inputContext->isInputPanelVisible() )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
QskInputContext allows to navigate inside the input panel
|
||||||
|
without losing the connected input item
|
||||||
|
*/
|
||||||
|
|
||||||
|
QQuickItem* inputItem = nullptr;
|
||||||
|
|
||||||
|
if ( QMetaObject::invokeMethod( inputContext, "inputItem",
|
||||||
|
Qt::DirectConnection, Q_RETURN_ARG( QQuickItem*, inputItem ) ) )
|
||||||
|
{
|
||||||
|
doUpdate = ( item == inputItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( doUpdate )
|
||||||
|
inputMethod->update( queries );
|
||||||
|
}
|
||||||
|
|
||||||
QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* item )
|
QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* item )
|
||||||
{
|
{
|
||||||
if ( item )
|
if ( item )
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,8 @@ private:
|
||||||
// don't use boundingRect - it seems to be deprecated
|
// don't use boundingRect - it seems to be deprecated
|
||||||
virtual QRectF boundingRect() const override final { return rect(); }
|
virtual QRectF boundingRect() const override final { return rect(); }
|
||||||
|
|
||||||
void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy instead
|
void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy
|
||||||
|
void updateInputMethod( Qt::InputMethodQueries ) = delete; // use qskUpdateInputMethod
|
||||||
|
|
||||||
virtual QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override final;
|
virtual QSGNode* updatePaintNode( QSGNode*, UpdatePaintNodeData* ) override final;
|
||||||
virtual void updatePolish() override final;
|
virtual void updatePolish() override final;
|
||||||
|
|
@ -261,6 +262,8 @@ QSK_EXPORT void qskSetItemGeometry( QQuickItem*, const QRectF& );
|
||||||
QSK_EXPORT QQuickItem* qskNearestFocusScope( const QQuickItem* );
|
QSK_EXPORT QQuickItem* qskNearestFocusScope( const QQuickItem* );
|
||||||
QSK_EXPORT QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* );
|
QSK_EXPORT QList< QQuickItem* > qskPaintOrderChildItems( const QQuickItem* );
|
||||||
|
|
||||||
|
QSK_EXPORT void qskUpdateInputMethod( const QQuickItem*, Qt::InputMethodQueries );
|
||||||
|
|
||||||
QSK_EXPORT const QSGNode* qskItemNode( const QQuickItem* );
|
QSK_EXPORT const QSGNode* qskItemNode( const QQuickItem* );
|
||||||
QSK_EXPORT const QSGNode* qskPaintNode( const QQuickItem* );
|
QSK_EXPORT const QSGNode* qskPaintNode( const QQuickItem* );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,6 @@ QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquicktextinput_p_p.h>
|
#include <private/qquicktextinput_p_p.h>
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
static inline void qskUpdateInputMethod(
|
|
||||||
const QskTextInput*, Qt::InputMethodQueries queries )
|
|
||||||
{
|
|
||||||
auto inputMethod = QGuiApplication::inputMethod();
|
|
||||||
inputMethod->update( queries );
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void qskBindSignals( const QQuickTextInput* wrappedInput,
|
static inline void qskBindSignals( const QQuickTextInput* wrappedInput,
|
||||||
QskTextInput* input )
|
QskTextInput* input )
|
||||||
{
|
{
|
||||||
|
|
@ -81,6 +74,7 @@ namespace
|
||||||
{
|
{
|
||||||
setActiveFocusOnTab( false );
|
setActiveFocusOnTab( false );
|
||||||
setFlag( ItemAcceptsInputMethod, false );
|
setFlag( ItemAcceptsInputMethod, false );
|
||||||
|
setFocusOnPress( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAlignment( Qt::Alignment alignment )
|
void setAlignment( Qt::Alignment alignment )
|
||||||
|
|
@ -96,9 +90,8 @@ namespace
|
||||||
case QEvent::FocusIn:
|
case QEvent::FocusIn:
|
||||||
case QEvent::FocusOut:
|
case QEvent::FocusOut:
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
auto d = QQuickTextInputPrivate::get( this );
|
auto d = QQuickTextInputPrivate::get( this );
|
||||||
|
|
||||||
d->focusOnPress = true;
|
d->focusOnPress = true;
|
||||||
d->handleFocusEvent( static_cast< QFocusEvent* >( event ) );
|
d->handleFocusEvent( static_cast< QFocusEvent* >( event ) );
|
||||||
d->focusOnPress = false;
|
d->focusOnPress = false;
|
||||||
|
|
@ -131,6 +124,13 @@ QskTextInput::QskTextInput( QQuickItem* parent ):
|
||||||
|
|
||||||
setFlag( QQuickItem::ItemAcceptsInputMethod );
|
setFlag( QQuickItem::ItemAcceptsInputMethod );
|
||||||
|
|
||||||
|
/*
|
||||||
|
QQuickTextInput is a beast of almost 5k lines of code, we don't
|
||||||
|
want to reimplement that - at least not now.
|
||||||
|
So this is more or less a simple wrapper making everything
|
||||||
|
conforming to qskinny.
|
||||||
|
*/
|
||||||
|
|
||||||
m_data->textInput = new TextInput( this );
|
m_data->textInput = new TextInput( this );
|
||||||
qskBindSignals( m_data->textInput, this );
|
qskBindSignals( m_data->textInput, this );
|
||||||
|
|
||||||
|
|
@ -156,6 +156,10 @@ bool QskTextInput::event( QEvent* event )
|
||||||
{
|
{
|
||||||
return m_data->textInput->handleEvent( event );
|
return m_data->textInput->handleEvent( event );
|
||||||
}
|
}
|
||||||
|
else if ( event->type() == QEvent::LocaleChange )
|
||||||
|
{
|
||||||
|
qskUpdateInputMethod( this, Qt::ImPreferredLanguage );
|
||||||
|
}
|
||||||
|
|
||||||
return Inherited::event( event );
|
return Inherited::event( event );
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +174,32 @@ void QskTextInput::keyReleaseEvent( QKeyEvent* event )
|
||||||
Inherited::keyReleaseEvent( event );
|
Inherited::keyReleaseEvent( event );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskTextInput::mousePressEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->textInput->handleEvent( event );
|
||||||
|
|
||||||
|
if ( !isReadOnly() && !qGuiApp->styleHints()->setFocusOnTouchRelease() )
|
||||||
|
qGuiApp->inputMethod()->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextInput::mouseMoveEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->textInput->handleEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextInput::mouseReleaseEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->textInput->handleEvent( event );
|
||||||
|
|
||||||
|
if ( !isReadOnly() && qGuiApp->styleHints()->setFocusOnTouchRelease() )
|
||||||
|
qGuiApp->inputMethod()->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextInput::mouseDoubleClickEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->textInput->handleEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
void QskTextInput::inputMethodEvent( QInputMethodEvent* event )
|
void QskTextInput::inputMethodEvent( QInputMethodEvent* event )
|
||||||
{
|
{
|
||||||
m_data->textInput->handleEvent( event );
|
m_data->textInput->handleEvent( event );
|
||||||
|
|
@ -472,12 +502,17 @@ QVariant QskTextInput::inputMethodQuery(
|
||||||
{
|
{
|
||||||
return font();
|
return font();
|
||||||
}
|
}
|
||||||
case Qt::ImCursorPosition:
|
case Qt::ImPreferredLanguage:
|
||||||
|
{
|
||||||
|
return locale();
|
||||||
|
}
|
||||||
|
case Qt::ImCursorRectangle:
|
||||||
|
case Qt::ImInputItemClipRectangle:
|
||||||
{
|
{
|
||||||
QVariant v = m_data->textInput->inputMethodQuery( query, argument );
|
QVariant v = m_data->textInput->inputMethodQuery( query, argument );
|
||||||
#if 1
|
#if 1
|
||||||
if ( v.canConvert< QPointF >() )
|
if ( v.canConvert< QRectF >() )
|
||||||
v.setValue( v.toPointF() + m_data->textInput->position() );
|
v.setValue( v.toRectF().translated( m_data->textInput->position() ) );
|
||||||
#endif
|
#endif
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,12 +154,20 @@ Q_SIGNALS:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool event( QEvent* ) override;
|
virtual bool event( QEvent* ) override;
|
||||||
virtual void keyPressEvent( QKeyEvent* ) override;
|
|
||||||
virtual void keyReleaseEvent( QKeyEvent* ) override;
|
|
||||||
virtual void inputMethodEvent( QInputMethodEvent* ) override;
|
virtual void inputMethodEvent( QInputMethodEvent* ) override;
|
||||||
|
|
||||||
virtual void focusInEvent( QFocusEvent* ) override;
|
virtual void focusInEvent( QFocusEvent* ) override;
|
||||||
virtual void focusOutEvent( QFocusEvent* ) override;
|
virtual void focusOutEvent( QFocusEvent* ) override;
|
||||||
|
|
||||||
|
virtual void mousePressEvent( QMouseEvent* ) override;
|
||||||
|
virtual void mouseMoveEvent( QMouseEvent* ) override;
|
||||||
|
virtual void mouseReleaseEvent( QMouseEvent* ) override;
|
||||||
|
virtual void mouseDoubleClickEvent( QMouseEvent* ) override;
|
||||||
|
|
||||||
|
virtual void keyPressEvent( QKeyEvent* ) override;
|
||||||
|
virtual void keyReleaseEvent( QKeyEvent* ) override;
|
||||||
|
|
||||||
virtual void updateLayout() override;
|
virtual void updateLayout() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
#include <QStyleHints>
|
#include <QStyleHints>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qguiapplication_p.h>
|
#include <private/qinputmethod_p.h>
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
#include <qpa/qplatformintegration.h>
|
#include <qpa/qplatformintegration.h>
|
||||||
|
|
@ -134,7 +134,8 @@ static bool qskIsAutorepeat( int key )
|
||||||
|
|
||||||
static inline QPlatformInputContext* qskInputContext()
|
static inline QPlatformInputContext* qskInputContext()
|
||||||
{
|
{
|
||||||
return QGuiApplicationPrivate::platformIntegration()->inputContext();
|
auto inputMethod = QGuiApplication::inputMethod();
|
||||||
|
return QInputMethodPrivate::get( inputMethod )->platformInputContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSK_SUBCONTROL( QskVirtualKeyboardCandidateButton, Panel )
|
QSK_SUBCONTROL( QskVirtualKeyboardCandidateButton, Panel )
|
||||||
|
|
@ -505,14 +506,12 @@ QString QskVirtualKeyboard::displayLanguageName() const
|
||||||
|
|
||||||
void QskVirtualKeyboard::setPreeditCandidates( const QVector< QString >& candidates )
|
void QskVirtualKeyboard::setPreeditCandidates( const QVector< QString >& candidates )
|
||||||
{
|
{
|
||||||
if( m_data->candidates == candidates )
|
if( m_data->candidates != candidates )
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_data->candidates = candidates;
|
m_data->candidates = candidates;
|
||||||
setCandidateOffset( 0 );
|
setCandidateOffset( 0 );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QskVirtualKeyboard::setCandidateOffset( int candidateOffset )
|
void QskVirtualKeyboard::setCandidateOffset( int candidateOffset )
|
||||||
{
|
{
|
||||||
|
|
@ -548,13 +547,6 @@ void QskVirtualKeyboard::setCandidateOffset( int candidateOffset )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskVirtualKeyboard::geometryChanged(
|
|
||||||
const QRectF& newGeometry, const QRectF& oldGeometry )
|
|
||||||
{
|
|
||||||
Inherited::geometryChanged( newGeometry, oldGeometry );
|
|
||||||
Q_EMIT keyboardRectChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskVirtualKeyboard::updateLayout()
|
void QskVirtualKeyboard::updateLayout()
|
||||||
{
|
{
|
||||||
if( geometry().isNull() )
|
if( geometry().isNull() )
|
||||||
|
|
@ -680,6 +672,7 @@ void QskVirtualKeyboard::handleCandidateKey( int index, const QString& text )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
selectCandidate( index );
|
selectCandidate( index );
|
||||||
|
setPreeditCandidates( QVector< QString >() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -879,9 +872,9 @@ bool QskVirtualKeyboard::eventFilter( QObject* object, QEvent* event )
|
||||||
if ( event->type() == QEvent::InputMethodQuery )
|
if ( event->type() == QEvent::InputMethodQuery )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Qt/Quick expects that the item associated with the virtual keyboard
|
Qt/Quick expects that the item associated with the input context
|
||||||
always has the focus. But you also find systems, where you have to
|
always has the focus. But this does not work, when a virtual
|
||||||
navigate and select inside the virtual keyboard.
|
keyboard is used, where you can navigate and select inside.
|
||||||
So we have to fix the receiver.
|
So we have to fix the receiver.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,6 @@ public Q_SLOTS:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool eventFilter( QObject*, QEvent* ) override;
|
virtual bool eventFilter( QObject*, QEvent* ) override;
|
||||||
virtual void geometryChanged( const QRectF&, const QRectF& ) override;
|
|
||||||
virtual void updateLayout() override;
|
virtual void updateLayout() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -151,7 +150,6 @@ private:
|
||||||
void updateKeyData();
|
void updateKeyData();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void keyboardRectChanged();
|
|
||||||
void displayLanguageNameChanged();
|
void displayLanguageNameChanged();
|
||||||
void modeChanged( QskVirtualKeyboard::Mode );
|
void modeChanged( QskVirtualKeyboard::Mode );
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue