QskTextInput inproved
This commit is contained in:
parent
546044f916
commit
1513d3716f
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "QskInputCompositionModel.h"
|
#include "QskInputCompositionModel.h"
|
||||||
#include "QskPinyinCompositionModel.h"
|
#include "QskPinyinCompositionModel.h"
|
||||||
|
#include "QskHunspellCompositionModel.h"
|
||||||
|
|
||||||
#include <QskDialog.h>
|
#include <QskDialog.h>
|
||||||
#include <QskWindow.h>
|
#include <QskWindow.h>
|
||||||
|
@ -78,7 +79,11 @@ QskInputContext::QskInputContext():
|
||||||
{
|
{
|
||||||
setObjectName( "InputContext" );
|
setObjectName( "InputContext" );
|
||||||
|
|
||||||
|
#if 1
|
||||||
m_data->compositionModel = new QskInputCompositionModel( this );
|
m_data->compositionModel = new QskInputCompositionModel( this );
|
||||||
|
#else
|
||||||
|
m_data->compositionModel = new QskHunspellCompositionModel( this );
|
||||||
|
#endif
|
||||||
|
|
||||||
connect( m_data->compositionModel, &QskInputCompositionModel::candidatesChanged,
|
connect( m_data->compositionModel, &QskInputCompositionModel::candidatesChanged,
|
||||||
this, &QskInputContext::handleCandidatesChanged );
|
this, &QskInputContext::handleCandidatesChanged );
|
||||||
|
|
|
@ -42,6 +42,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 );
|
textInput->setSelectByMouse( true );
|
||||||
|
textInput->setSizePolicy( Qt::Horizontal, QskSizePolicy::Preferred );
|
||||||
|
|
||||||
#if LOCAL_PANEL
|
#if LOCAL_PANEL
|
||||||
auto* inputPanel = new QskVirtualKeyboard( this );
|
auto* inputPanel = new QskVirtualKeyboard( this );
|
||||||
|
|
|
@ -4,11 +4,19 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "QskTextInput.h"
|
#include "QskTextInput.h"
|
||||||
#include "QskTextOptions.h"
|
|
||||||
|
// VS2012+ disable keyword macroizing unless _ALLOW_KEYWORD_MACROS is set
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#if ( _MSC_VER >= 1700 ) && !defined( _ALLOW_KEYWORD_MACROS )
|
||||||
|
#define _ALLOW_KEYWORD_MACROS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
|
#define private public
|
||||||
#include <private/qquicktextinput_p.h>
|
#include <private/qquicktextinput_p.h>
|
||||||
#include <private/qquicktextinput_p_p.h>
|
#include <private/qquicktextinput_p_p.h>
|
||||||
|
#undef private
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
static inline void qskBindSignals( const QQuickTextInput* wrappedInput,
|
static inline void qskBindSignals( const QQuickTextInput* wrappedInput,
|
||||||
|
@ -69,12 +77,19 @@ namespace
|
||||||
class TextInput final : public QQuickTextInput
|
class TextInput final : public QQuickTextInput
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextInput( QQuickItem* parent ) :
|
TextInput( QQuickItem* parent ):
|
||||||
QQuickTextInput( parent )
|
QQuickTextInput( parent )
|
||||||
{
|
{
|
||||||
|
classBegin();
|
||||||
|
|
||||||
setActiveFocusOnTab( false );
|
setActiveFocusOnTab( false );
|
||||||
setFlag( ItemAcceptsInputMethod, false );
|
setFlag( ItemAcceptsInputMethod, false );
|
||||||
setFocusOnPress( false );
|
setFocusOnPress( false );
|
||||||
|
|
||||||
|
connect( this, &TextInput::contentSizeChanged,
|
||||||
|
this, &TextInput::updateClip );
|
||||||
|
|
||||||
|
componentComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAlignment( Qt::Alignment alignment )
|
void setAlignment( Qt::Alignment alignment )
|
||||||
|
@ -85,23 +100,90 @@ namespace
|
||||||
|
|
||||||
inline bool handleEvent( QEvent* event )
|
inline bool handleEvent( QEvent* event )
|
||||||
{
|
{
|
||||||
switch( event->type() )
|
return QQuickTextInput::event( event );
|
||||||
{
|
}
|
||||||
case QEvent::FocusIn:
|
|
||||||
case QEvent::FocusOut:
|
virtual void focusInEvent( QFocusEvent* ) override
|
||||||
{
|
{
|
||||||
auto d = QQuickTextInputPrivate::get( this );
|
auto d = QQuickTextInputPrivate::get( this );
|
||||||
|
|
||||||
d->focusOnPress = true;
|
if ( d->m_readOnly )
|
||||||
d->handleFocusEvent( static_cast< QFocusEvent* >( event ) );
|
return;
|
||||||
d->focusOnPress = false;
|
|
||||||
|
|
||||||
return true;
|
d->cursorVisible = true;
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||||
|
d->updateCursorBlinking();
|
||||||
|
d->setBlinkingCursorEnabled( true );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( d->determineHorizontalAlignment() )
|
||||||
|
{
|
||||||
|
d->updateLayout();
|
||||||
|
d->updateHorizontalScroll();
|
||||||
|
d->updateVerticalScroll();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorRectangle);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
connect( QGuiApplication::inputMethod(),
|
||||||
return QQuickTextInput::event( event );
|
SIGNAL(inputDirectionChanged(Qt::LayoutDirection)),
|
||||||
|
this, SLOT(q_updateAlignment()) );
|
||||||
|
|
||||||
|
qGuiApp->inputMethod()->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void focusOutEvent( QFocusEvent* event ) override
|
||||||
|
{
|
||||||
|
auto d = QQuickTextInputPrivate::get( this );
|
||||||
|
|
||||||
|
if (d->m_readOnly)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d->cursorVisible = false;
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||||
|
d->updateCursorBlinking();
|
||||||
|
d->setBlinkingCursorEnabled( false );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( d->m_passwordEchoEditing || d->m_passwordEchoTimer.isActive() )
|
||||||
|
{
|
||||||
|
d->updatePasswordEchoEditing( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( event->reason() != Qt::ActiveWindowFocusReason
|
||||||
|
&& event->reason() != Qt::PopupFocusReason )
|
||||||
|
{
|
||||||
|
if ( d->hasSelectedText() && !d->persistentSelection )
|
||||||
|
deselect();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto status = d->hasAcceptableInput( d->m_text );
|
||||||
|
if ( status == QQuickTextInputPrivate::AcceptableInput )
|
||||||
|
{
|
||||||
|
if ( d->fixup() )
|
||||||
|
Q_EMIT editingFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect( QGuiApplication::inputMethod(),
|
||||||
|
SIGNAL(inputDirectionChanged(Qt::LayoutDirection)),
|
||||||
|
this, SLOT(q_updateAlignment()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void geometryChanged(
|
||||||
|
const QRectF& newGeometry, const QRectF& oldGeometry ) override
|
||||||
|
{
|
||||||
|
QQuickTextInput::geometryChanged( newGeometry, oldGeometry );
|
||||||
|
updateClip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateClip()
|
||||||
|
{
|
||||||
|
setClip( ( contentWidth() > width() ) ||
|
||||||
|
( contentHeight() > height() ) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -276,16 +358,6 @@ void QskTextInput::setFontRole( int role )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QskTextOptions QskTextInput::textOptions() const
|
|
||||||
{
|
|
||||||
return QskTextOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskTextInput::setTextOptions( const QskTextOptions& options )
|
|
||||||
{
|
|
||||||
Q_UNUSED( options )
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskTextInput::setAlignment( Qt::Alignment alignment )
|
void QskTextInput::setAlignment( Qt::Alignment alignment )
|
||||||
{
|
{
|
||||||
if ( alignment != this->alignment() )
|
if ( alignment != this->alignment() )
|
||||||
|
@ -325,6 +397,11 @@ void QskTextInput::setReadOnly( bool on )
|
||||||
qskUpdateInputMethod( this, Qt::ImEnabled );
|
qskUpdateInputMethod( this, Qt::ImEnabled );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskTextInput::ensureVisible( int position )
|
||||||
|
{
|
||||||
|
m_data->textInput->ensureVisible( position );
|
||||||
|
}
|
||||||
|
|
||||||
bool QskTextInput::isCursorVisible() const
|
bool QskTextInput::isCursorVisible() const
|
||||||
{
|
{
|
||||||
return m_data->textInput->isCursorVisible();
|
return m_data->textInput->isCursorVisible();
|
||||||
|
@ -507,7 +584,9 @@ QVariant QskTextInput::inputMethodQuery(
|
||||||
return locale();
|
return locale();
|
||||||
}
|
}
|
||||||
case Qt::ImCursorRectangle:
|
case Qt::ImCursorRectangle:
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
||||||
case Qt::ImInputItemClipRectangle:
|
case Qt::ImInputItemClipRectangle:
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
QVariant v = m_data->textInput->inputMethodQuery( query, argument );
|
QVariant v = m_data->textInput->inputMethodQuery( query, argument );
|
||||||
#if 1
|
#if 1
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include "QskControl.h"
|
#include "QskControl.h"
|
||||||
|
|
||||||
class QskTextOptions;
|
|
||||||
class QValidator;
|
class QValidator;
|
||||||
|
|
||||||
class QSK_EXPORT QskTextInput : public QskControl
|
class QSK_EXPORT QskTextInput : public QskControl
|
||||||
|
@ -20,9 +19,6 @@ class QSK_EXPORT QskTextInput : public QskControl
|
||||||
Q_PROPERTY( int fontRole READ fontRole
|
Q_PROPERTY( int fontRole READ fontRole
|
||||||
WRITE setFontRole NOTIFY fontRoleChanged )
|
WRITE setFontRole NOTIFY fontRoleChanged )
|
||||||
|
|
||||||
Q_PROPERTY( QskTextOptions textOptions READ textOptions
|
|
||||||
WRITE setTextOptions NOTIFY textOptionsChanged )
|
|
||||||
|
|
||||||
Q_PROPERTY( Qt::Alignment alignment READ alignment
|
Q_PROPERTY( Qt::Alignment alignment READ alignment
|
||||||
WRITE setAlignment NOTIFY alignmentChanged )
|
WRITE setAlignment NOTIFY alignmentChanged )
|
||||||
|
|
||||||
|
@ -57,9 +53,6 @@ public:
|
||||||
void setFontRole( int role );
|
void setFontRole( int role );
|
||||||
int fontRole() const;
|
int fontRole() const;
|
||||||
|
|
||||||
void setTextOptions( const QskTextOptions& );
|
|
||||||
QskTextOptions textOptions() const;
|
|
||||||
|
|
||||||
void setAlignment( Qt::Alignment );
|
void setAlignment( Qt::Alignment );
|
||||||
Qt::Alignment alignment() const;
|
Qt::Alignment alignment() const;
|
||||||
|
|
||||||
|
@ -124,6 +117,8 @@ public:
|
||||||
Qt::InputMethodHints inputMethodHints() const;
|
Qt::InputMethodHints inputMethodHints() const;
|
||||||
void setInputMethodHints( Qt::InputMethodHints );
|
void setInputMethodHints( Qt::InputMethodHints );
|
||||||
|
|
||||||
|
void ensureVisible( int position );
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setText( const QString& );
|
void setText( const QString& );
|
||||||
|
|
||||||
|
|
|
@ -198,10 +198,22 @@ static bool qskIsAutorepeat( int key )
|
||||||
&& key != Qt::Key_Mode_switch );
|
&& key != Qt::Key_Mode_switch );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QPlatformInputContext* qskInputContext()
|
static inline QQuickItem* qskInputItem()
|
||||||
{
|
{
|
||||||
auto inputMethod = QGuiApplication::inputMethod();
|
QPlatformInputContext* inputContext;
|
||||||
return QInputMethodPrivate::get( inputMethod )->platformInputContext();
|
#if 1
|
||||||
|
inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
||||||
|
#else
|
||||||
|
// for some reason the gcc sanitizer does not like this one
|
||||||
|
inputContext = QInputMethodPrivate::get( inputMethod )->platformInputContext();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QQuickItem* item = nullptr;
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod( inputContext, "inputItem",
|
||||||
|
Qt::DirectConnection, Q_RETURN_ARG( QQuickItem*, item ) );
|
||||||
|
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSK_SUBCONTROL( QskVirtualKeyboard, Panel )
|
QSK_SUBCONTROL( QskVirtualKeyboard, Panel )
|
||||||
|
@ -536,19 +548,12 @@ bool QskVirtualKeyboard::eventFilter( QObject* object, QEvent* event )
|
||||||
always has the focus. But this does not work, when a virtual
|
always has the focus. But this does not work, when a virtual
|
||||||
keyboard is used, where you can navigate and select inside.
|
keyboard is used, where you can navigate and select inside.
|
||||||
So we have to fix the receiver.
|
So we have to fix the receiver.
|
||||||
|
|
||||||
|
Maybe QEvent::EnterEditFocus is good for something ??
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( const auto inputContext = qskInputContext() )
|
if ( auto item = qskInputItem() )
|
||||||
{
|
|
||||||
QQuickItem* item = nullptr;
|
|
||||||
|
|
||||||
if ( QMetaObject::invokeMethod( inputContext, "inputItem",
|
|
||||||
Qt::DirectConnection, Q_RETURN_ARG( QQuickItem*, item ) ) )
|
|
||||||
{
|
|
||||||
if ( item )
|
|
||||||
QGuiApplication::sendEvent( item, event );
|
QGuiApplication::sendEvent( item, event );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -556,4 +561,13 @@ bool QskVirtualKeyboard::eventFilter( QObject* object, QEvent* event )
|
||||||
return Inherited::eventFilter( object, event );
|
return Inherited::eventFilter( object, event );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QskVirtualKeyboard::event( QEvent* event )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Handling Qt::Key_Return/Qt::KeyEscape here
|
||||||
|
and forward everything else to the input item TODO ...
|
||||||
|
*/
|
||||||
|
return Inherited::event( event );
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_QskVirtualKeyboard.cpp"
|
#include "moc_QskVirtualKeyboard.cpp"
|
||||||
|
|
|
@ -54,6 +54,8 @@ public Q_SLOTS:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool eventFilter( QObject*, QEvent* ) override;
|
virtual bool eventFilter( QObject*, QEvent* ) override;
|
||||||
|
virtual bool event( QEvent* ) override;
|
||||||
|
|
||||||
virtual void updateLayout() override;
|
virtual void updateLayout() override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
|
Loading…
Reference in New Issue