QskInputContext is no platform input context anymore to avoid forwarding
private APIs to applicaton code
This commit is contained in:
parent
b29f688df2
commit
e5d6fe0dc3
|
@ -4,12 +4,244 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <qpa/qplatforminputcontextplugin_p.h>
|
#include <qpa/qplatforminputcontextplugin_p.h>
|
||||||
|
#include <qpa/qplatforminputcontext.h>
|
||||||
|
|
||||||
#include "QskInputContext.h"
|
#include "QskInputContext.h"
|
||||||
#include "QskPinyinTextPredictor.h"
|
#include "QskPinyinTextPredictor.h"
|
||||||
#include "QskHunspellTextPredictor.h"
|
#include "QskHunspellTextPredictor.h"
|
||||||
|
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
|
#include <QRectF>
|
||||||
|
#include <QEvent>
|
||||||
|
|
||||||
|
/*
|
||||||
|
QPlatformInputContext is no stable public API.
|
||||||
|
So we forward everything to QskInputContext
|
||||||
|
*/
|
||||||
|
class QskPlatformInputContext final : public QPlatformInputContext
|
||||||
|
{
|
||||||
|
using Inherited = QPlatformInputContext;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QskPlatformInputContext();
|
||||||
|
virtual ~QskPlatformInputContext() = default;
|
||||||
|
|
||||||
|
virtual bool isValid() const override;
|
||||||
|
virtual bool hasCapability( Capability ) const override;
|
||||||
|
|
||||||
|
virtual void update( Qt::InputMethodQueries ) override;
|
||||||
|
virtual void invokeAction( QInputMethod::Action, int ) override;
|
||||||
|
|
||||||
|
virtual QRectF keyboardRect() const override;
|
||||||
|
virtual bool isAnimating() const override;
|
||||||
|
|
||||||
|
virtual void showInputPanel() override;
|
||||||
|
virtual void hideInputPanel() override;
|
||||||
|
virtual bool isInputPanelVisible() const override;
|
||||||
|
|
||||||
|
virtual void reset() override;
|
||||||
|
virtual void commit() override;
|
||||||
|
|
||||||
|
virtual void setFocusObject( QObject* ) override;
|
||||||
|
|
||||||
|
virtual QLocale locale() const override;
|
||||||
|
virtual Qt::LayoutDirection inputDirection() const override;
|
||||||
|
|
||||||
|
virtual bool filterEvent( const QEvent* ) override;
|
||||||
|
|
||||||
|
Q_INVOKABLE QQuickItem* inputItem();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool event( QEvent* ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateContext();
|
||||||
|
void updateLocale();
|
||||||
|
|
||||||
|
QLocale m_locale;
|
||||||
|
QPointer< QskInputContext > m_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskPlatformInputContext::QskPlatformInputContext()
|
||||||
|
{
|
||||||
|
auto context = QskInputContext::instance();
|
||||||
|
if ( context == nullptr )
|
||||||
|
{
|
||||||
|
context = new QskInputContext();
|
||||||
|
QskInputContext::setInstance( context );
|
||||||
|
}
|
||||||
|
|
||||||
|
updateContext();
|
||||||
|
updateLocale();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::updateContext()
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
m_context->disconnect( this );
|
||||||
|
|
||||||
|
m_context = QskInputContext::instance();
|
||||||
|
|
||||||
|
if ( m_context )
|
||||||
|
{
|
||||||
|
connect( m_context, &QskInputContext::activeChanged,
|
||||||
|
this, &QPlatformInputContext::emitInputPanelVisibleChanged );
|
||||||
|
|
||||||
|
connect( m_context, &QskInputContext::panelRectChanged,
|
||||||
|
this, &QPlatformInputContext::emitKeyboardRectChanged );
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
m_context->registerPredictor( QLocale(),
|
||||||
|
new QskHunspellTextPredictor() );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
m_context->registerPredictor(
|
||||||
|
QLocale::Chinese, new QskPinyinTextPredictor() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::updateLocale()
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
{
|
||||||
|
const auto oldLocale = m_locale;
|
||||||
|
m_locale = m_context->locale();
|
||||||
|
|
||||||
|
if ( oldLocale != m_locale )
|
||||||
|
emitLocaleChanged();
|
||||||
|
|
||||||
|
if ( m_locale.textDirection() != oldLocale.textDirection() )
|
||||||
|
emitInputDirectionChanged( m_locale.textDirection() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskPlatformInputContext::isValid() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskPlatformInputContext::hasCapability( Capability ) const
|
||||||
|
{
|
||||||
|
// what is QPlatformInputContext::HiddenTextCapability ???
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::update( Qt::InputMethodQueries queries )
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
m_context->update( queries );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::invokeAction(
|
||||||
|
QInputMethod::Action action, int cursorPosition )
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
{
|
||||||
|
if ( action == QInputMethod::Click )
|
||||||
|
m_context->processClickAt( cursorPosition );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskPlatformInputContext::keyboardRect() const
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
return m_context->panelRect();
|
||||||
|
|
||||||
|
return QRectF();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskPlatformInputContext::isAnimating() const
|
||||||
|
{
|
||||||
|
// who is interested in this ?
|
||||||
|
// also: emitAnimatingChanged
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::showInputPanel()
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
m_context->setActive( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::hideInputPanel()
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
m_context->setActive( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskPlatformInputContext::isInputPanelVisible() const
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
return m_context->isActive();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::reset()
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
m_context->commitPrediction( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::commit()
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
m_context->commitPrediction( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskPlatformInputContext::setFocusObject( QObject* object )
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
m_context->setFocusObject( object );
|
||||||
|
}
|
||||||
|
|
||||||
|
QLocale QskPlatformInputContext::locale() const
|
||||||
|
{
|
||||||
|
return m_locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::LayoutDirection QskPlatformInputContext::inputDirection() const
|
||||||
|
{
|
||||||
|
return m_locale.textDirection();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskPlatformInputContext::filterEvent( const QEvent* )
|
||||||
|
{
|
||||||
|
// called from QXcbKeyboard, but what about other platforms
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickItem* QskPlatformInputContext::inputItem()
|
||||||
|
{
|
||||||
|
if ( m_context )
|
||||||
|
return m_context->inputItem();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskPlatformInputContext::event( QEvent* event )
|
||||||
|
{
|
||||||
|
switch( event->type() )
|
||||||
|
{
|
||||||
|
case QEvent::LocaleChange:
|
||||||
|
{
|
||||||
|
updateLocale();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::PlatformPanel:
|
||||||
|
{
|
||||||
|
updateContext();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::event( event );
|
||||||
|
}
|
||||||
|
|
||||||
class QskInputContextPlugin final : public QPlatformInputContextPlugin
|
class QskInputContextPlugin final : public QPlatformInputContextPlugin
|
||||||
{
|
{
|
||||||
|
@ -22,18 +254,7 @@ public:
|
||||||
{
|
{
|
||||||
if ( system.compare( QStringLiteral( "skinny" ), Qt::CaseInsensitive ) == 0 )
|
if ( system.compare( QStringLiteral( "skinny" ), Qt::CaseInsensitive ) == 0 )
|
||||||
{
|
{
|
||||||
auto context = new QskInputContext();
|
auto context = new QskPlatformInputContext();
|
||||||
|
|
||||||
#if 0
|
|
||||||
context->registerPredictor( QLocale(),
|
|
||||||
new QskHunspellTextPredictor( this ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
context->registerPredictor(
|
|
||||||
QLocale::Chinese, new QskPinyinTextPredictor( this ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,47 +24,46 @@ QSK_QT_PRIVATE_BEGIN
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
#include <qpa/qplatformintegration.h>
|
#include <qpa/qplatformintegration.h>
|
||||||
|
#include <qpa/qplatforminputcontext.h>
|
||||||
|
|
||||||
static QPointer< QskInputPanel > qskInputPanel = nullptr;
|
static QPointer< QskInputContext > qskInputContext = nullptr;
|
||||||
|
|
||||||
static void qskDeletePanel()
|
static void qskSendToPlatformContext( QEvent::Type type )
|
||||||
{
|
{
|
||||||
delete qskInputPanel;
|
const auto platformInputContext =
|
||||||
}
|
|
||||||
|
|
||||||
static void qskInputPanelHook()
|
|
||||||
{
|
|
||||||
qAddPostRoutine( qskDeletePanel );
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_COREAPP_STARTUP_FUNCTION( qskInputPanelHook )
|
|
||||||
|
|
||||||
static void qskSetInputPanel( QskInputPanel* inputPanel )
|
|
||||||
{
|
|
||||||
if ( inputPanel == qskInputPanel )
|
|
||||||
return;
|
|
||||||
|
|
||||||
delete qskInputPanel;
|
|
||||||
qskInputPanel = inputPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputContext::setInputPanel( QskInputPanel* inputPanel )
|
|
||||||
{
|
|
||||||
if ( inputPanel == qskInputPanel )
|
|
||||||
return;
|
|
||||||
|
|
||||||
qskSetInputPanel( inputPanel );
|
|
||||||
|
|
||||||
const auto inputContext =
|
|
||||||
QGuiApplicationPrivate::platformIntegration()->inputContext();
|
QGuiApplicationPrivate::platformIntegration()->inputContext();
|
||||||
|
|
||||||
if ( auto context = qobject_cast< QskInputContext* >( inputContext ) )
|
if ( platformInputContext )
|
||||||
context->hideInputPanel();
|
{
|
||||||
|
QEvent event( type );
|
||||||
|
QCoreApplication::sendEvent( platformInputContext, &event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QskInputPanel* QskInputContext::inputPanel()
|
static void qskInputContextHook()
|
||||||
{
|
{
|
||||||
return qskInputPanel;
|
qAddPostRoutine( []{ delete qskInputContext; } );
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_COREAPP_STARTUP_FUNCTION( qskInputContextHook )
|
||||||
|
|
||||||
|
void QskInputContext::setInstance( QskInputContext* inputContext )
|
||||||
|
{
|
||||||
|
if ( inputContext != qskInputContext )
|
||||||
|
{
|
||||||
|
const auto oldContext = qskInputContext;
|
||||||
|
qskInputContext = inputContext;
|
||||||
|
|
||||||
|
if ( oldContext && oldContext->parent() == nullptr )
|
||||||
|
delete oldContext;
|
||||||
|
|
||||||
|
qskSendToPlatformContext( QEvent::PlatformPanel );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QskInputContext* QskInputContext::instance()
|
||||||
|
{
|
||||||
|
return qskInputContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint qskHashLocale( const QLocale& locale )
|
static inline uint qskHashLocale( const QLocale& locale )
|
||||||
|
@ -124,8 +123,9 @@ class QskInputContext::PrivateData
|
||||||
public:
|
public:
|
||||||
// item receiving the input
|
// item receiving the input
|
||||||
QPointer< QQuickItem > inputItem;
|
QPointer< QQuickItem > inputItem;
|
||||||
|
QPointer< QskInputPanel > inputPanel;
|
||||||
|
|
||||||
// popup or window embedding qskInputPanel
|
// popup or window embedding the panel
|
||||||
QskPopup* inputPopup = nullptr;
|
QskPopup* inputPopup = nullptr;
|
||||||
QskWindow* inputWindow = nullptr;
|
QskWindow* inputWindow = nullptr;
|
||||||
|
|
||||||
|
@ -145,22 +145,32 @@ QskInputContext::~QskInputContext()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskInputContext::isValid() const
|
QQuickItem* QskInputContext::inputItem() const
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QskInputContext::hasCapability( Capability ) const
|
|
||||||
{
|
|
||||||
// what is QPlatformInputContext::HiddenTextCapability ???
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QQuickItem* QskInputContext::inputItem()
|
|
||||||
{
|
{
|
||||||
return m_data->inputItem;
|
return m_data->inputItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QskInputPanel* QskInputContext::inputPanel() const
|
||||||
|
{
|
||||||
|
if ( m_data->inputPanel == nullptr )
|
||||||
|
{
|
||||||
|
auto that = const_cast< QskInputContext* >( this );
|
||||||
|
|
||||||
|
auto panel = new QskInputPanel();
|
||||||
|
panel->setParent( that );
|
||||||
|
|
||||||
|
connect( panel, &QQuickItem::visibleChanged,
|
||||||
|
this, &QskInputContext::activeChanged );
|
||||||
|
|
||||||
|
connect( panel, &QskControl::localeChanged,
|
||||||
|
this, []{ qskSendToPlatformContext( QEvent::LocaleChange ); } );
|
||||||
|
|
||||||
|
m_data->inputPanel = panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_data->inputPanel;
|
||||||
|
}
|
||||||
|
|
||||||
void QskInputContext::update( Qt::InputMethodQueries queries )
|
void QskInputContext::update( Qt::InputMethodQueries queries )
|
||||||
{
|
{
|
||||||
if ( queries & Qt::ImEnabled )
|
if ( queries & Qt::ImEnabled )
|
||||||
|
@ -170,28 +180,21 @@ void QskInputContext::update( Qt::InputMethodQueries queries )
|
||||||
|
|
||||||
if ( !event.value( Qt::ImEnabled ).toBool() )
|
if ( !event.value( Qt::ImEnabled ).toBool() )
|
||||||
{
|
{
|
||||||
hideInputPanel();
|
hidePanel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( qskInputPanel )
|
if ( auto panel = inputPanel() )
|
||||||
qskInputPanel->processInputMethodQueries( queries );
|
panel->processInputMethodQueries( queries );
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskInputContext::keyboardRect() const
|
QRectF QskInputContext::panelRect() const
|
||||||
{
|
{
|
||||||
// is this correct and what is this good for ?
|
|
||||||
if ( m_data->inputPopup )
|
if ( m_data->inputPopup )
|
||||||
return m_data->inputPopup->geometry();
|
return m_data->inputPopup->geometry();
|
||||||
|
|
||||||
return Inherited::keyboardRect();
|
return QRectF();
|
||||||
}
|
|
||||||
|
|
||||||
bool QskInputContext::isAnimating() const
|
|
||||||
{
|
|
||||||
// can be implemented once we have some sliding/fading effects
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QskPopup* QskInputContext::createEmbeddingPopup( QskInputPanel* panel )
|
QskPopup* QskInputContext::createEmbeddingPopup( QskInputPanel* panel )
|
||||||
|
@ -238,15 +241,18 @@ QskWindow* QskInputContext::createEmbeddingWindow( QskInputPanel* panel )
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputContext::showInputPanel()
|
void QskInputContext::showPanel()
|
||||||
{
|
{
|
||||||
auto focusItem = qobject_cast< QQuickItem* >( qGuiApp->focusObject() );
|
auto focusItem = qobject_cast< QQuickItem* >( qGuiApp->focusObject() );
|
||||||
|
|
||||||
if ( focusItem == nullptr )
|
if ( focusItem == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( ( focusItem == qskInputPanel )
|
auto panel = inputPanel();
|
||||||
|| qskIsAncestorOf( qskInputPanel, focusItem ) )
|
if ( panel == nullptr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ( focusItem == panel )
|
||||||
|
|| qskIsAncestorOf( panel, focusItem ) )
|
||||||
{
|
{
|
||||||
// ignore: usually the input proxy of the panel
|
// ignore: usually the input proxy of the panel
|
||||||
return;
|
return;
|
||||||
|
@ -254,26 +260,6 @@ void QskInputContext::showInputPanel()
|
||||||
|
|
||||||
m_data->inputItem = focusItem;
|
m_data->inputItem = focusItem;
|
||||||
|
|
||||||
if ( qskInputPanel == nullptr )
|
|
||||||
qskSetInputPanel( new QskInputPanel() );
|
|
||||||
|
|
||||||
connect( qskInputPanel, &QQuickItem::visibleChanged,
|
|
||||||
this, &QPlatformInputContext::emitInputPanelVisibleChanged,
|
|
||||||
Qt::UniqueConnection );
|
|
||||||
|
|
||||||
connect( qskInputPanel, &QskControl::localeChanged,
|
|
||||||
this, &QPlatformInputContext::emitLocaleChanged,
|
|
||||||
Qt::UniqueConnection );
|
|
||||||
|
|
||||||
if ( qskInputPanel->parent() == nullptr )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Take ownership to avoid, that the panel gets
|
|
||||||
destroyed together with the popup/window
|
|
||||||
*/
|
|
||||||
qskInputPanel->setParent( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( QskDialog::instance()->policy() == QskDialog::TopLevelWindow )
|
if ( QskDialog::instance()->policy() == QskDialog::TopLevelWindow )
|
||||||
{
|
{
|
||||||
// The input panel is embedded in a top level window
|
// The input panel is embedded in a top level window
|
||||||
|
@ -282,7 +268,7 @@ void QskInputContext::showInputPanel()
|
||||||
|
|
||||||
if ( m_data->inputWindow == nullptr )
|
if ( m_data->inputWindow == nullptr )
|
||||||
{
|
{
|
||||||
auto window = createEmbeddingWindow( qskInputPanel );
|
auto window = createEmbeddingWindow( panel );
|
||||||
|
|
||||||
if ( window )
|
if ( window )
|
||||||
{
|
{
|
||||||
|
@ -311,7 +297,7 @@ void QskInputContext::showInputPanel()
|
||||||
|
|
||||||
if ( m_data->inputPopup == nullptr )
|
if ( m_data->inputPopup == nullptr )
|
||||||
{
|
{
|
||||||
auto popup = createEmbeddingPopup( qskInputPanel );
|
auto popup = createEmbeddingPopup( panel );
|
||||||
|
|
||||||
if ( popup )
|
if ( popup )
|
||||||
{
|
{
|
||||||
|
@ -330,12 +316,12 @@ void QskInputContext::showInputPanel()
|
||||||
m_data->engine->setPredictor(
|
m_data->engine->setPredictor(
|
||||||
m_data->predictorTable.find( locale() ) );
|
m_data->predictorTable.find( locale() ) );
|
||||||
|
|
||||||
qskInputPanel->setLocale( locale() );
|
panel->setLocale( locale() );
|
||||||
qskInputPanel->attachInputItem( m_data->inputItem );
|
panel->attachInputItem( m_data->inputItem );
|
||||||
qskInputPanel->setEngine( m_data->engine );
|
panel->setEngine( m_data->engine );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputContext::hideInputPanel()
|
void QskInputContext::hidePanel()
|
||||||
{
|
{
|
||||||
if ( m_data->inputPopup )
|
if ( m_data->inputPopup )
|
||||||
{
|
{
|
||||||
|
@ -354,11 +340,11 @@ void QskInputContext::hideInputPanel()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( qskInputPanel )
|
if ( auto panel = inputPanel() )
|
||||||
{
|
{
|
||||||
qskInputPanel->setParentItem( nullptr );
|
panel->setParentItem( nullptr );
|
||||||
qskInputPanel->attachInputItem( nullptr );
|
panel->attachInputItem( nullptr );
|
||||||
qskInputPanel->setEngine( nullptr );
|
panel->setEngine( nullptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_data->inputPopup )
|
if ( m_data->inputPopup )
|
||||||
|
@ -378,10 +364,23 @@ void QskInputContext::hideInputPanel()
|
||||||
m_data->inputItem = nullptr;
|
m_data->inputItem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskInputContext::isInputPanelVisible() const
|
void QskInputContext::setActive( bool on )
|
||||||
{
|
{
|
||||||
return qskInputPanel && qskInputPanel->isVisible()
|
if ( on )
|
||||||
&& qskInputPanel->window() && qskInputPanel->window()->isVisible();
|
showPanel();
|
||||||
|
else
|
||||||
|
hidePanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskInputContext::isActive() const
|
||||||
|
{
|
||||||
|
if ( auto panel = inputPanel() )
|
||||||
|
{
|
||||||
|
return panel && panel->isVisible()
|
||||||
|
&& panel->window() && panel->window()->isVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QLocale QskInputContext::locale() const
|
QLocale QskInputContext::locale() const
|
||||||
|
@ -397,11 +396,6 @@ QLocale QskInputContext::locale() const
|
||||||
return QLocale();
|
return QLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::LayoutDirection QskInputContext::inputDirection() const
|
|
||||||
{
|
|
||||||
return Inherited::inputDirection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputContext::setFocusObject( QObject* focusObject )
|
void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
{
|
{
|
||||||
if ( m_data->inputItem == nullptr || m_data->inputItem == focusObject )
|
if ( m_data->inputItem == nullptr || m_data->inputItem == focusObject )
|
||||||
|
@ -421,7 +415,7 @@ void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
if ( m_data->inputItem->hasFocus() )
|
if ( m_data->inputItem->hasFocus() )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
As long as the focus is noewhere and
|
As long as the focus is nowhere and
|
||||||
the local focus stay on the input item
|
the local focus stay on the input item
|
||||||
we don't care
|
we don't care
|
||||||
*/
|
*/
|
||||||
|
@ -448,7 +442,7 @@ void QskInputContext::setFocusObject( QObject* focusObject )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hideInputPanel();
|
hidePanel();
|
||||||
m_data->inputItem = nullptr;
|
m_data->inputItem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,20 +470,17 @@ QskTextPredictor* QskInputContext::registeredPredictor( const QLocale& locale )
|
||||||
return m_data->predictorTable.find( locale );
|
return m_data->predictorTable.find( locale );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputContext::invokeAction( QInputMethod::Action, int )
|
void QskInputContext::processClickAt( int cursorPosition )
|
||||||
{
|
{
|
||||||
|
Q_UNUSED( cursorPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskInputContext::reset()
|
void QskInputContext::commitPrediction( bool )
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskInputContext::commit()
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
commit is called, when the input item loses the focus.
|
called, when the input item loses the focus.
|
||||||
As it it should be possible to navigate inside of the
|
As it it should be possible to navigate inside of the
|
||||||
inputPanel this is no valid reason to hide the panel.
|
inputPanel what should we do here ?
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,15 +492,13 @@ bool QskInputContext::eventFilter( QObject* object, QEvent* event )
|
||||||
{
|
{
|
||||||
case QEvent::Move:
|
case QEvent::Move:
|
||||||
{
|
{
|
||||||
if ( qskInputPanel )
|
Q_EMIT panelRectChanged();
|
||||||
emitKeyboardRectChanged();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QEvent::Resize:
|
case QEvent::Resize:
|
||||||
{
|
{
|
||||||
if ( qskInputPanel )
|
if ( auto panel = inputPanel() )
|
||||||
qskInputPanel->setSize( m_data->inputWindow->size() );
|
panel->setSize( m_data->inputWindow->size() );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +517,7 @@ bool QskInputContext::eventFilter( QObject* object, QEvent* event )
|
||||||
{
|
{
|
||||||
case QskEvent::GeometryChange:
|
case QskEvent::GeometryChange:
|
||||||
{
|
{
|
||||||
emitKeyboardRectChanged();
|
Q_EMIT panelRectChanged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QEvent::DeferredDelete:
|
case QEvent::DeferredDelete:
|
||||||
|
@ -542,10 +531,4 @@ bool QskInputContext::eventFilter( QObject* object, QEvent* event )
|
||||||
return Inherited::eventFilter( object, event );
|
return Inherited::eventFilter( object, event );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskInputContext::filterEvent( const QEvent* )
|
|
||||||
{
|
|
||||||
// called from QXcbKeyboard, but what about other platforms
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_QskInputContext.cpp"
|
#include "moc_QskInputContext.cpp"
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
#define QSK_INPUT_CONTEXT_H
|
#define QSK_INPUT_CONTEXT_H
|
||||||
|
|
||||||
#include "QskGlobal.h"
|
#include "QskGlobal.h"
|
||||||
#include <qpa/qplatforminputcontext.h>
|
#include <QObject>
|
||||||
|
#include <Qt>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class QskTextPredictor;
|
class QskTextPredictor;
|
||||||
|
@ -16,46 +17,35 @@ class QskPopup;
|
||||||
class QskWindow;
|
class QskWindow;
|
||||||
class QQuickItem;
|
class QQuickItem;
|
||||||
|
|
||||||
class QSK_EXPORT QskInputContext : public QPlatformInputContext
|
class QSK_EXPORT QskInputContext : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
using Inherited = QPlatformInputContext;
|
using Inherited = QObject;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QskInputContext();
|
QskInputContext();
|
||||||
virtual ~QskInputContext();
|
virtual ~QskInputContext();
|
||||||
|
|
||||||
virtual bool isValid() const override;
|
virtual QRectF panelRect() const;
|
||||||
virtual bool hasCapability( Capability ) const override;
|
|
||||||
|
|
||||||
virtual void update( Qt::InputMethodQueries ) override;
|
virtual void setActive( bool );
|
||||||
virtual void invokeAction( QInputMethod::Action, int ) override;
|
virtual bool isActive() const;
|
||||||
|
|
||||||
virtual QRectF keyboardRect() const override;
|
virtual QLocale locale() const;
|
||||||
virtual bool isAnimating() const override;
|
|
||||||
|
|
||||||
virtual void showInputPanel() override;
|
|
||||||
virtual void hideInputPanel() override;
|
|
||||||
virtual bool isInputPanelVisible() const override;
|
|
||||||
|
|
||||||
virtual void reset() override;
|
|
||||||
virtual void commit() override;
|
|
||||||
|
|
||||||
virtual void setFocusObject( QObject* ) override;
|
|
||||||
|
|
||||||
virtual QLocale locale() const override;
|
|
||||||
virtual Qt::LayoutDirection inputDirection() const override;
|
|
||||||
|
|
||||||
void registerPredictor( const QLocale&, QskTextPredictor* );
|
void registerPredictor( const QLocale&, QskTextPredictor* );
|
||||||
QskTextPredictor* registeredPredictor( const QLocale& );
|
QskTextPredictor* registeredPredictor( const QLocale& );
|
||||||
|
|
||||||
Q_INVOKABLE QQuickItem* inputItem();
|
virtual QQuickItem* inputItem() const;
|
||||||
|
virtual QskInputPanel* inputPanel() const;
|
||||||
|
|
||||||
virtual bool filterEvent( const QEvent* ) override;
|
static QskInputContext* instance();
|
||||||
|
static void setInstance( QskInputContext* );
|
||||||
|
|
||||||
static void setInputPanel( QskInputPanel* );
|
Q_SIGNALS:
|
||||||
static QskInputPanel* inputPanel();
|
void activeChanged();
|
||||||
|
void panelRectChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool eventFilter( QObject*, QEvent* ) override;
|
virtual bool eventFilter( QObject*, QEvent* ) override;
|
||||||
|
@ -63,7 +53,18 @@ protected:
|
||||||
virtual QskPopup* createEmbeddingPopup( QskInputPanel* );
|
virtual QskPopup* createEmbeddingPopup( QskInputPanel* );
|
||||||
virtual QskWindow* createEmbeddingWindow( QskInputPanel* );
|
virtual QskWindow* createEmbeddingWindow( QskInputPanel* );
|
||||||
|
|
||||||
|
virtual void showPanel();
|
||||||
|
virtual void hidePanel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class QskPlatformInputContext;
|
||||||
|
|
||||||
|
// called from QskPlatformInputContext
|
||||||
|
virtual void setFocusObject( QObject* );
|
||||||
|
virtual void update( Qt::InputMethodQueries );
|
||||||
|
virtual void processClickAt( int cursorPosition );
|
||||||
|
virtual void commitPrediction( bool );
|
||||||
|
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue