QskTextInput inproved

This commit is contained in:
Uwe Rathmann 2018-04-09 10:05:59 +02:00
parent 546044f916
commit 1513d3716f
6 changed files with 143 additions and 47 deletions

View File

@ -8,6 +8,7 @@
#include "QskInputCompositionModel.h"
#include "QskPinyinCompositionModel.h"
#include "QskHunspellCompositionModel.h"
#include <QskDialog.h>
#include <QskWindow.h>
@ -78,7 +79,11 @@ QskInputContext::QskInputContext():
{
setObjectName( "InputContext" );
#if 1
m_data->compositionModel = new QskInputCompositionModel( this );
#else
m_data->compositionModel = new QskHunspellCompositionModel( this );
#endif
connect( m_data->compositionModel, &QskInputCompositionModel::candidatesChanged,
this, &QskInputContext::handleCandidatesChanged );

View File

@ -42,6 +42,7 @@ public:
auto* textInput = new QskTextInput( this );
textInput->setText( "I am a line edit. Press and edit Me." );
textInput->setSelectByMouse( true );
textInput->setSizePolicy( Qt::Horizontal, QskSizePolicy::Preferred );
#if LOCAL_PANEL
auto* inputPanel = new QskVirtualKeyboard( this );

View File

@ -4,11 +4,19 @@
*****************************************************************************/
#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
#define private public
#include <private/qquicktextinput_p.h>
#include <private/qquicktextinput_p_p.h>
#undef private
QSK_QT_PRIVATE_END
static inline void qskBindSignals( const QQuickTextInput* wrappedInput,
@ -69,12 +77,19 @@ namespace
class TextInput final : public QQuickTextInput
{
public:
TextInput( QQuickItem* parent ) :
TextInput( QQuickItem* parent ):
QQuickTextInput( parent )
{
classBegin();
setActiveFocusOnTab( false );
setFlag( ItemAcceptsInputMethod, false );
setFocusOnPress( false );
connect( this, &TextInput::contentSizeChanged,
this, &TextInput::updateClip );
componentComplete();
}
void setAlignment( Qt::Alignment alignment )
@ -85,23 +100,90 @@ namespace
inline bool handleEvent( QEvent* event )
{
switch( event->type() )
return QQuickTextInput::event( event );
}
virtual void focusInEvent( QFocusEvent* ) override
{
auto d = QQuickTextInputPrivate::get( this );
if ( d->m_readOnly )
return;
d->cursorVisible = true;
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
d->updateCursorBlinking();
d->setBlinkingCursorEnabled( true );
#endif
if ( d->determineHorizontalAlignment() )
{
case QEvent::FocusIn:
case QEvent::FocusOut:
{
auto d = QQuickTextInputPrivate::get( this );
d->updateLayout();
d->updateHorizontalScroll();
d->updateVerticalScroll();
d->focusOnPress = true;
d->handleFocusEvent( static_cast< QFocusEvent* >( event ) );
d->focusOnPress = false;
return true;
}
default:
return QQuickTextInput::event( event );
#if 0
updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorRectangle);
#endif
}
connect( QGuiApplication::inputMethod(),
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 )
{
if ( alignment != this->alignment() )
@ -325,6 +397,11 @@ void QskTextInput::setReadOnly( bool on )
qskUpdateInputMethod( this, Qt::ImEnabled );
}
void QskTextInput::ensureVisible( int position )
{
m_data->textInput->ensureVisible( position );
}
bool QskTextInput::isCursorVisible() const
{
return m_data->textInput->isCursorVisible();
@ -507,7 +584,9 @@ QVariant QskTextInput::inputMethodQuery(
return locale();
}
case Qt::ImCursorRectangle:
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
case Qt::ImInputItemClipRectangle:
#endif
{
QVariant v = m_data->textInput->inputMethodQuery( query, argument );
#if 1

View File

@ -8,7 +8,6 @@
#include "QskControl.h"
class QskTextOptions;
class QValidator;
class QSK_EXPORT QskTextInput : public QskControl
@ -20,9 +19,6 @@ class QSK_EXPORT QskTextInput : public QskControl
Q_PROPERTY( int fontRole READ fontRole
WRITE setFontRole NOTIFY fontRoleChanged )
Q_PROPERTY( QskTextOptions textOptions READ textOptions
WRITE setTextOptions NOTIFY textOptionsChanged )
Q_PROPERTY( Qt::Alignment alignment READ alignment
WRITE setAlignment NOTIFY alignmentChanged )
@ -57,9 +53,6 @@ public:
void setFontRole( int role );
int fontRole() const;
void setTextOptions( const QskTextOptions& );
QskTextOptions textOptions() const;
void setAlignment( Qt::Alignment );
Qt::Alignment alignment() const;
@ -124,6 +117,8 @@ public:
Qt::InputMethodHints inputMethodHints() const;
void setInputMethodHints( Qt::InputMethodHints );
void ensureVisible( int position );
public Q_SLOTS:
void setText( const QString& );

View File

@ -198,10 +198,22 @@ static bool qskIsAutorepeat( int key )
&& key != Qt::Key_Mode_switch );
}
static inline QPlatformInputContext* qskInputContext()
static inline QQuickItem* qskInputItem()
{
auto inputMethod = QGuiApplication::inputMethod();
return QInputMethodPrivate::get( inputMethod )->platformInputContext();
QPlatformInputContext* inputContext;
#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 )
@ -536,19 +548,12 @@ bool QskVirtualKeyboard::eventFilter( QObject* object, QEvent* event )
always has the focus. But this does not work, when a virtual
keyboard is used, where you can navigate and select inside.
So we have to fix the receiver.
Maybe QEvent::EnterEditFocus is good for something ??
*/
if ( const auto inputContext = qskInputContext() )
{
QQuickItem* item = nullptr;
if ( QMetaObject::invokeMethod( inputContext, "inputItem",
Qt::DirectConnection, Q_RETURN_ARG( QQuickItem*, item ) ) )
{
if ( item )
QGuiApplication::sendEvent( item, event );
}
}
if ( auto item = qskInputItem() )
QGuiApplication::sendEvent( item, event );
return true;
}
@ -556,4 +561,13 @@ bool QskVirtualKeyboard::eventFilter( QObject* object, QEvent* 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"

View File

@ -54,6 +54,8 @@ public Q_SLOTS:
protected:
virtual bool eventFilter( QObject*, QEvent* ) override;
virtual bool event( QEvent* ) override;
virtual void updateLayout() override;
private Q_SLOTS: