From 3f8616c08462e09a331fc3fc43eb18872ceffefa Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 18 Apr 2018 10:46:11 +0200 Subject: [PATCH] QskTextInput improved --- inputcontext/QskInputCompositionModel.cpp | 5 + playground/inputpanel/main.cpp | 1 + skins/material/QskMaterialSkin.cpp | 2 + skins/squiek/QskSquiekSkin.cpp | 2 + src/controls/QskTextInput.cpp | 138 +++++++++++++++++++--- src/controls/QskTextInput.h | 8 +- 6 files changed, 135 insertions(+), 21 deletions(-) diff --git a/inputcontext/QskInputCompositionModel.cpp b/inputcontext/QskInputCompositionModel.cpp index 999dddf3..32a09b3a 100644 --- a/inputcontext/QskInputCompositionModel.cpp +++ b/inputcontext/QskInputCompositionModel.cpp @@ -146,6 +146,11 @@ void QskInputCompositionModel::composeKey( int key ) return; } + case Qt::Key_Escape: + { + sendKeyEvents( Qt::Key_Escape ); + return; + } default: { if ( !spaceLeft ) diff --git a/playground/inputpanel/main.cpp b/playground/inputpanel/main.cpp index 96a6766d..cdbe0922 100644 --- a/playground/inputpanel/main.cpp +++ b/playground/inputpanel/main.cpp @@ -44,6 +44,7 @@ public: auto* textInput2 = new QskTextInput( this ); textInput2->setText( "Press and edit Me." ); textInput2->setSizePolicy( Qt::Horizontal, QskSizePolicy::Preferred ); + textInput2->setActivationModes( QskTextInput::ActivationOnAll ); auto* textInput3 = new QskTextInput( this ); textInput3->setReadOnly( true ); diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 70c110ce..6350a165 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -202,6 +202,8 @@ void QskMaterialSkin::initTextInputHints() const ColorPalette& pal = m_data->palette; setColor( Q::Text, pal.textColor ); + setColor( Q::PanelSelected, pal.accentColor ); + setColor( Q::TextSelected, pal.contrastColor ); setMargins( Q::Panel | Padding, 5 ); setBoxShape( Q::Panel, 4 ); diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 4836d36c..441552f3 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -308,6 +308,8 @@ void QskSquiekSkin::initTextInputHints() static_cast( Qt::AlignLeft | Qt::AlignTop ) ); setColor( Q::Text, pal.themeForeground ); + setColor( Q::PanelSelected, pal.highlighted ); + setColor( Q::TextSelected, pal.highlightedText ); setMargins( Q::Panel | Padding, 5 ); setBoxBorderMetrics( Q::Panel, 2 ); diff --git a/src/controls/QskTextInput.cpp b/src/controls/QskTextInput.cpp index accd7359..04fc5cea 100644 --- a/src/controls/QskTextInput.cpp +++ b/src/controls/QskTextInput.cpp @@ -21,6 +21,8 @@ QSK_QT_PRIVATE_END QSK_SUBCONTROL( QskTextInput, Panel ) QSK_SUBCONTROL( QskTextInput, Text ) +QSK_SUBCONTROL( QskTextInput, PanelSelected ) +QSK_SUBCONTROL( QskTextInput, TextSelected ) QSK_STATE( QskTextInput, ReadOnly, QskAspect::FirstSystemState << 1 ) QSK_STATE( QskTextInput, Editing, QskAspect::FirstSystemState << 2 ) @@ -70,6 +72,8 @@ namespace { class TextInput final : public QQuickTextInput { + using Inherited = QQuickTextInput; + public: TextInput( QskTextInput* ); @@ -94,13 +98,19 @@ namespace return isAcceptable; } - inline bool handleEvent( QEvent* event ) { return this->event( event ); } + void updateColors(); + void updateMetrics(); + + inline bool handleEvent( QEvent* event ) + { + return this->event( event ); + } protected: virtual void geometryChanged( const QRectF& newGeometry, const QRectF& oldGeometry ) override { - QQuickTextInput::geometryChanged( newGeometry, oldGeometry ); + Inherited::geometryChanged( newGeometry, oldGeometry ); updateClip(); } @@ -109,6 +119,13 @@ namespace setClip( ( contentWidth() > width() ) || ( contentHeight() > height() ) ); } + + virtual QSGNode* updatePaintNode( + QSGNode *oldNode, UpdatePaintNodeData* data ) override + { + updateColors(); + return Inherited::updatePaintNode( oldNode, data ); + } }; TextInput::TextInput( QskTextInput* textInput ): @@ -134,6 +151,7 @@ namespace return; setCursorVisible( on ); + d->setBlinkingCursorEnabled( on ); if ( !on ) { @@ -151,6 +169,55 @@ namespace polish(); update(); } + + void TextInput::updateMetrics() + { + auto input = static_cast< const QskTextInput* >( parentItem() ); + + setAlignment( input->alignment() ); + setFont( input->font() ); + } + + void TextInput::updateColors() + { + auto input = static_cast< const QskTextInput* >( parentItem() ); + auto d = QQuickTextInputPrivate::get( this ); + + bool isDirty = false; + + QColor color; + + color = input->color( QskTextInput::Text ); + if ( d->color != color ) + { + d->color = color; + isDirty = true; + } + + if ( d->hasSelectedText() ) + { + color = input->color( QskTextInput::PanelSelected ); + if ( d->selectionColor != color ) + { + d->selectionColor = color; + isDirty = true; + } + + color = input->color( QskTextInput::TextSelected ); + if ( d->selectedTextColor != color ) + { + d->selectedTextColor = color; + isDirty = true; + } + } + + if ( isDirty ) + { + d->textLayoutDirty = true; + d->updateType = QQuickTextInputPrivate::UpdatePaintNode; + update(); + } + } } class QskTextInput::PrivateData @@ -216,20 +283,32 @@ void QskTextInput::keyPressEvent( QKeyEvent* event ) { if ( isEditing() ) { - if ( event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return ) + switch( event->key() ) { - if ( m_data->textInput->fixup() ) + case Qt::Key_Enter: + case Qt::Key_Return: { - auto inputMethod = QGuiApplication::inputMethod(); - inputMethod->commit(); - - if ( !( inputMethodHints() & Qt::ImhMultiLine) ) - setEditing( false ); - } - } - else - { - m_data->textInput->handleEvent( event ); + if ( m_data->textInput->fixup() ) + { + QGuiApplication::inputMethod()->commit(); + + if ( !( inputMethodHints() & Qt::ImhMultiLine) ) + setEditing( false ); + } + break; + } +#if 1 + case Qt::Key_Escape: + { + QGuiApplication::inputMethod()->hide(); + setEditing( false ); + break; + } +#endif + default: + { + m_data->textInput->handleEvent( event ); + } } return; @@ -285,6 +364,19 @@ void QskTextInput::inputMethodEvent( QInputMethodEvent* event ) void QskTextInput::focusInEvent( QFocusEvent* event ) { + if ( m_data->activationModes & ActivationOnFocus ) + { + switch( event->reason() ) + { + case Qt::ActiveWindowFocusReason: + case Qt::PopupFocusReason: + break; + + default: + setEditing( true ); + } + } + Inherited::focusInEvent( event ); } @@ -315,8 +407,12 @@ QSizeF QskTextInput::contentsSizeHint() const { using namespace QskAspect; - const qreal w = m_data->textInput->implicitWidth(); - const qreal h = m_data->textInput->implicitHeight(); + auto input = m_data->textInput; + + input->updateMetrics(); + + const qreal w = input->implicitWidth(); + const qreal h = input->implicitHeight(); const QSizeF minSize( metric( Panel | MinimumWidth ), metric( Panel | MinimumHeight ) ); @@ -328,12 +424,16 @@ void QskTextInput::updateLayout() { auto input = m_data->textInput; - input->setAlignment( alignment() ); - input->setFont( font() ); - + input->updateMetrics(); qskSetItemGeometry( input, subControlRect( Text ) ); } +void QskTextInput::updateNode( QSGNode* node ) +{ + m_data->textInput->updateColors(); + Inherited::updateNode( node ); +} + QString QskTextInput::text() const { return m_data->textInput->text(); diff --git a/src/controls/QskTextInput.h b/src/controls/QskTextInput.h index 9155df68..25995ae9 100644 --- a/src/controls/QskTextInput.h +++ b/src/controls/QskTextInput.h @@ -31,7 +31,7 @@ class QSK_EXPORT QskTextInput : public QskControl using Inherited = QskControl; public: - QSK_SUBCONTROLS( Panel, Text ) + QSK_SUBCONTROLS( Panel, Text, PanelSelected, TextSelected ) QSK_STATES( ReadOnly, Editing ) enum ActivationMode @@ -40,7 +40,10 @@ public: ActivationOnFocus = 1 << 0 , ActivationOnMouse = 1 << 1, - ActivationOnKey = 1 << 2 + ActivationOnKey = 1 << 2, + + ActivationOnInput = ActivationOnMouse | ActivationOnKey, + ActivationOnAll = ActivationOnFocus | ActivationOnMouse | ActivationOnKey }; Q_ENUM( ActivationMode ) @@ -156,6 +159,7 @@ protected: virtual void keyReleaseEvent( QKeyEvent* ) override; virtual void updateLayout() override; + virtual void updateNode( QSGNode*) override; private: class PrivateData;