From e365592457907df7c9d660c402a75a5cbb5994d1 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 14 Mar 2018 17:30:37 +0100 Subject: [PATCH] new input panel code --- skins/material/QskMaterialSkin.cpp | 2 + skins/squiek/QskSquiekSkin.cpp | 2 + src/controls/QskInputPanel.cpp | 409 ++++++++++++-------------- src/controls/QskInputPanel.h | 53 +++- src/controls/QskInputPanelSkinlet.cpp | 222 -------------- src/controls/QskInputPanelSkinlet.h | 43 --- src/controls/QskSkin.cpp | 4 - src/src.pro | 2 - 8 files changed, 229 insertions(+), 508 deletions(-) delete mode 100644 src/controls/QskInputPanelSkinlet.cpp delete mode 100644 src/controls/QskInputPanelSkinlet.h diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 37a4b8b0..f4987bf6 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -525,6 +525,7 @@ void QskMaterialSkin::initInputPanelHints() const ColorPalette& pal = m_data->palette; +/* // key panel setMargins( Q::KeyPanel | Margin, 2 ); @@ -552,6 +553,7 @@ void QskMaterialSkin::initInputPanelHints() setBoxBorderMetrics( Q::Panel, 0 ); setGradient( Q::Panel, pal.darker150 ); setBoxBorderColors( Q::Panel, pal.baseColor ); +*/ } void QskMaterialSkin::initScrollViewHints() diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 4d199662..5b1d3ba9 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -558,6 +558,7 @@ void QskSquiekSkin::initInputPanelHints() const ColorPalette& pal = m_data->palette; +/* // key panel setMargins( Q::KeyPanel | Margin, 2 ); // should be Panel | Spacing @@ -584,6 +585,7 @@ void QskSquiekSkin::initInputPanelHints() setMargins( Q::Panel | Padding, 5 ); setMargins( Q::Panel | Spacing, 5 ); setPanel( Q::Panel, Raised ); +*/ } void QskSquiekSkin::initScrollViewHints() diff --git a/src/controls/QskInputPanel.cpp b/src/controls/QskInputPanel.cpp index bbc78c4f..967e1e34 100644 --- a/src/controls/QskInputPanel.cpp +++ b/src/controls/QskInputPanel.cpp @@ -7,21 +7,19 @@ #include "QskAspect.h" +#include +#include #include #include #include #include +#include + +#include #include #include -QSK_SUBCONTROL( QskInputPanel, Panel ) -QSK_SUBCONTROL( QskInputPanel, KeyPanel ) -QSK_SUBCONTROL( QskInputPanel, KeyGlyph ) - -QSK_STATE( QskInputPanel, Checked, QskAspect::LastSystemState >> 3 ) -QSK_STATE( QskInputPanel, Pressed, QskAspect::LastSystemState >> 2 ) - namespace { struct KeyTable @@ -34,73 +32,6 @@ namespace return int( intptr_t( value - data[0] ) ); } }; - - QskInputPanel::KeyData* qskKeyDataAt( KeyTable& table, qreal x, qreal y ) - { - if( x < 0 || x > 1 || y < 0 || y > 1 ) - { - return nullptr; - } - - auto rowIndex = size_t( std::floor( y * QskInputPanel::RowCount ) ); - auto columnIndex = size_t( std::floor( x * QskInputPanel::KeyCount ) ); - - Q_FOREVER - { - const auto rect = table.data[ rowIndex ][ columnIndex ].rect; - - if( rect.contains( x, y ) ) - { - return &table.data[ rowIndex ][ columnIndex ]; - } - - // Look up/down - if( y < rect.top() ) - { - if( rowIndex == 0 ) - { - break; - } - - rowIndex -= 1; - continue; - } - else if( y > rect.bottom() ) - { - if( rowIndex == QskInputPanel::RowCount - 1 ) - { - break; - } - - rowIndex += 1; - continue; - } - - // Look left/right - if( x < rect.left() ) - { - if( columnIndex == 0 ) - { - break; - } - - columnIndex -= 1; - continue; - } - else if( x > rect.right() ) - { - if( columnIndex == QskInputPanel::KeyCount - 1 ) - { - break; - } - - columnIndex += 1; - continue; - } - } - - return nullptr; - } } struct QskInputPanelLayouts @@ -208,6 +139,64 @@ namespace }; } +QSK_SUBCONTROL( QskKeyButton, Panel ) +QSK_SUBCONTROL( QskKeyButton, Text ) +QSK_SUBCONTROL( QskKeyButton, TextCancelButton ) + +QskKeyButton::QskKeyButton( int keyIndex, QskInputPanel* inputPanel, QQuickItem* parent ) : + Inherited( parent ), + m_keyIndex( keyIndex ), + m_inputPanel( inputPanel ) +{ + setFlag( QQuickItem::ItemAcceptsInputMethod ); + + updateText(); + + connect( this, &QskKeyButton::pressed, this, [ this ]() + { + m_inputPanel->handleKey( m_keyIndex ); + } ); + + connect( m_inputPanel, &QskInputPanel::modeChanged, this, &QskKeyButton::updateText ); +} + +QskAspect::Subcontrol QskKeyButton::effectiveSubcontrol( QskAspect::Subcontrol subControl ) const +{ + if( subControl == QskPushButton::Panel ) + { + return QskKeyButton::Panel; + } + + if( subControl == QskPushButton::Text ) + { + // ### we could also introduce a state to not always query the button + return isCancelButton() ? QskKeyButton::TextCancelButton : QskKeyButton::Text; + } + + return subControl; +} + +void QskKeyButton::updateText() +{ + QString text = m_inputPanel->currentTextForKeyIndex( m_keyIndex ); + + if( text.count() == 1 && text.at( 0 ) == Qt::Key_unknown ) + { + setText( QStringLiteral( "" ) ); + } + else + { + setText( text ); + } +} + +bool QskKeyButton::isCancelButton() const +{ + auto keyData = m_inputPanel->keyDataAt( m_keyIndex ); + bool isCancel = ( keyData.key == 0x2716 ); + return isCancel; +} + class QskInputPanel::PrivateData { public: @@ -217,7 +206,8 @@ class QskInputPanel::PrivateData focusKeyIndex( -1 ), selectedGroup( -1 ), candidateOffset( 0 ), - repeatKeyTimerId( -1 ) + repeatKeyTimerId( -1 ), + isUIInitialized( false ) { } @@ -238,12 +228,17 @@ class QskInputPanel::PrivateData std::unordered_map< int, KeyCounter > activeKeys; KeyTable keyTable[ ModeCount ]; + + QList< QskKeyButton* > keyButtons; + bool isUIInitialized; }; QskInputPanel::QskInputPanel( QQuickItem* parent ): QskControl( parent ), m_data( new PrivateData ) { + qRegisterMetaType< Qt::Key >(); + setFlag( ItemHasContents ); setAcceptedMouseButtons( Qt::LeftButton ); @@ -353,6 +348,8 @@ QString QskInputPanel::displayLanguageName() const default: return QStringLiteral( "English (UK)" ); } + + break; } case QLocale::Spanish: @@ -554,6 +551,7 @@ void QskInputPanel::setCandidateOffset( int candidateOffset ) } else { + keyData.isSuggestionKey = true; // ### reset when switching layouts etc.! keyData.key = m_data->candidates.at( i + m_data->candidateOffset ); } } @@ -566,166 +564,38 @@ void QskInputPanel::setCandidateOffset( int candidateOffset ) if( m_data->mode == LowercaseMode ) { - update(); + updateUI(); } } QRectF QskInputPanel::keyboardRect() const { auto keyboardRect = rect(); // ### margins? would eliminate this thing below - - if( QskDialog::instance()->policy() != QskDialog::TopLevelWindow ) - { - keyboardRect.adjust( 0, keyboardRect.height() * 0.5, 0, 0 ); - } - + // if ( QskDialog::instance()->policy() != QskDialog::TopLevelWindow ) + // keyboardRect.adjust( 0, keyboardRect.height() * 0.5, 0, 0 ); return keyboardRect; } +void QskInputPanel::registerCompositionModelForLocale( const QLocale& locale, + QskInputCompositionModel* model ) +{ + Q_EMIT inputMethodRegistered( locale, model ); +} + void QskInputPanel::geometryChanged( const QRectF& newGeometry, const QRectF& oldGeometry ) { Inherited::geometryChanged( newGeometry, oldGeometry ); + + if( newGeometry != oldGeometry && !newGeometry.size().isNull() && !m_data->isUIInitialized ) + { + createUI(); + m_data->isUIInitialized = true; + } + Q_EMIT keyboardRectChanged(); } -void QskInputPanel::mousePressEvent( QMouseEvent* e ) -{ - if( !keyboardRect().contains( e->pos() ) ) - { - e->ignore(); - return; - } - - QTouchEvent::TouchPoint touchPoint( 0 ); - touchPoint.setPos( e->pos() ); - touchPoint.setState( Qt::TouchPointPressed ); - - QTouchEvent touchEvent( QTouchEvent::TouchBegin, nullptr, - e->modifiers(), Qt::TouchPointPressed, { touchPoint } ); - QCoreApplication::sendEvent( this, &touchEvent ); - - e->setAccepted( touchEvent.isAccepted() ); -} - -void QskInputPanel::mouseMoveEvent( QMouseEvent* e ) -{ - QTouchEvent::TouchPoint touchPoint( 0 ); - touchPoint.setPos( e->pos() ); - touchPoint.setState( Qt::TouchPointMoved ); - - QTouchEvent touchEvent( QTouchEvent::TouchUpdate, nullptr, - e->modifiers(), Qt::TouchPointMoved, { touchPoint } ); - QCoreApplication::sendEvent( this, &touchEvent ); - - e->setAccepted( touchEvent.isAccepted() ); -} - -void QskInputPanel::mouseReleaseEvent( QMouseEvent* e ) -{ - QTouchEvent::TouchPoint touchPoint( 0 ); - touchPoint.setPos( e->pos() ); - touchPoint.setState( Qt::TouchPointReleased ); - - QTouchEvent touchEvent( QTouchEvent::TouchEnd, nullptr, - e->modifiers(), Qt::TouchPointReleased, { touchPoint } ); - QCoreApplication::sendEvent( this, &touchEvent ); - - e->setAccepted( touchEvent.isAccepted() ); -} - -// Try to handle touch-specific details here; once touch is resolved, send to handleKey() -void QskInputPanel::touchEvent( QTouchEvent* e ) -{ - if( e->type() == QEvent::TouchCancel ) - { - for( auto& it : m_data->activeKeys ) - { - keyDataAt( it.second.keyIndex ).key &= ~KeyPressed; - } - - m_data->activeKeys.clear(); - return; - } - - const auto rect = keyboardRect(); - - for( const auto& tp : e->touchPoints() ) - { - const auto pos = tp.pos(); - - const auto x = ( pos.x() - rect.x() ) / rect.width(); - const auto y = ( pos.y() - rect.y() ) / rect.height(); - - auto keyData = qskKeyDataAt( m_data->keyTable[ m_data->mode ], x, y ); - - if( !keyData || ( !keyData->key || keyData->key == Qt::Key_unknown ) ) - { - auto it = m_data->activeKeys.find( tp.id() ); - - if( it == m_data->activeKeys.cend() ) - { - continue; - } - - keyDataAt( it->second.keyIndex ).key &= ~KeyPressed; - m_data->activeKeys.erase( it ); - continue; - } - - const auto keyIndex = m_data->keyTable[ m_data->mode ].indexOf( keyData ); - auto it = m_data->activeKeys.find( tp.id() ); - - if( tp.state() == Qt::TouchPointReleased ) - { - const int repeatCount = it->second.count; - - auto it = m_data->activeKeys.find( tp.id() ); - keyDataAt( it->second.keyIndex ).key &= ~KeyPressed; - m_data->activeKeys.erase( it ); - - if( repeatCount < 0 ) - { - continue; // Don't compose an accepted held key - } - - handleKey( keyIndex ); - continue; - } - - if( it == m_data->activeKeys.end() ) - { - m_data->activeKeys.emplace( tp.id(), KeyCounter { keyIndex, 0 } ); - } - else - { - if( it->second.keyIndex != keyIndex ) - { - keyDataAt( it->second.keyIndex ).key &= ~KeyPressed; - it->second.count = 0; - } - - it->second.keyIndex = keyIndex; - } - - keyDataAt( keyIndex ).key |= KeyPressed; - } - - // Now start an update timer based on active keys - if( m_data->activeKeys.empty() && m_data->repeatKeyTimerId >= 0 ) - { - killTimer( m_data->repeatKeyTimerId ); - m_data->repeatKeyTimerId = -1; - } - else if( m_data->repeatKeyTimerId < 0 ) - { - m_data->repeatKeyTimerId = startTimer( 1000 - / QGuiApplication::styleHints()->keyboardAutoRepeatRate() ); - } /* else timer is already running as it should be */ - - update(); -} - void QskInputPanel::timerEvent( QTimerEvent* e ) { if( e->timerId() == m_data->repeatKeyTimerId ) @@ -759,6 +629,76 @@ void QskInputPanel::timerEvent( QTimerEvent* e ) } } +bool QskInputPanel::eventFilter( QObject* object, QEvent* event ) +{ + if( event->type() == QEvent::InputMethod ) + { + QInputMethodEvent* inputMethodEvent = static_cast< QInputMethodEvent* >( event ); + Q_EMIT inputMethodEventReceived( inputMethodEvent ); + return true; + } + else if( event->type() == QEvent::KeyPress ) + { + // Return, Backspace and others are covered here (maybe because they don't carry a 'commit string'): + QKeyEvent* keyEvent = static_cast< QKeyEvent* >( event ); + Q_EMIT keyEventReceived( keyEvent ); + return true; + } + else + { + return Inherited::eventFilter( object, event ); + } +} + +void QskInputPanel::createUI() +{ + // deferring the UI creation until we are visible so that the contentsRect() returns the proper value + + setAutoLayoutChildren( true ); + + auto& panelKeyData = keyData(); + + const auto contentsRect = keyboardRect(); + const qreal sx = contentsRect.size().width(); + const qreal sy = contentsRect.size().height(); + + QskLinearBox* outterBox = new QskLinearBox( Qt::Vertical, this ); + outterBox->setAutoAddChildren( true ); + + for( const auto& keyRow : panelKeyData ) + { + QskLinearBox* rowBox = new QskLinearBox( Qt::Horizontal, outterBox ); + rowBox->setAutoAddChildren( true ); + + for( const auto& keyData : keyRow ) + { + if( !keyData.key ) + { + continue; + } + + const QSizeF buttonSize( keyData.rect.width() * sx, keyData.rect.height() * sy ); + + int keyIndex = m_data->keyTable[ m_data->mode ].indexOf( &keyData ); + QskKeyButton* button = new QskKeyButton( keyIndex, this, rowBox ); + + button->installEventFilter( this ); + + button->setMaximumWidth( buttonSize.width() ); // ### set min width as well? + button->setFixedHeight( buttonSize.height() ); + m_data->keyButtons.append( button ); + } + } +} + +void QskInputPanel::updateUI() +{ + for( QskKeyButton* button : m_data->keyButtons ) + { + button->updateText(); + } +} + QskInputPanel::KeyData& QskInputPanel::keyDataAt( int keyIndex ) const { const auto row = keyIndex / KeyCount; @@ -768,7 +708,8 @@ QskInputPanel::KeyData& QskInputPanel::keyDataAt( int keyIndex ) const void QskInputPanel::handleKey( int keyIndex ) { - const auto key = keyDataAt( keyIndex ).key & ~KeyStates; + KeyData keyData = keyDataAt( keyIndex ); + const auto key = keyData.key & ~KeyStates; // Preedit keys const auto row = keyIndex / KeyCount; @@ -821,12 +762,30 @@ void QskInputPanel::handleKey( int keyIndex ) : SpecialCharacterMode ) ); return; + // This is (one of) the cancel symbol, not Qt::Key_Cancel: + case Qt::Key( 10006 ): + Q_EMIT cancelPressed(); + return; + default: break; } - // Normal keys - compose( key ); + if( keyData.isSuggestionKey ) + { + selectCandidate( keyIndex ); + } + else + { + compose( key ); + } +} + +QString QskInputPanel::currentTextForKeyIndex( int keyIndex ) const +{ + auto keyData = keyDataAt( keyIndex ); + QString text = textForKey( keyData.key ); + return text; } void QskInputPanel::compose( Qt::Key key ) @@ -974,10 +933,6 @@ void QskInputPanel::updateLocale( const QLocale& locale ) m_data->currentLayout = &qskInputPanelLayouts.zh; break; - case QLocale::C: - m_data->currentLayout = &qskInputPanelLayouts.en_US; - break; - default: qWarning() << "QskInputPanel: unsupported locale:" << locale; m_data->currentLayout = &qskInputPanelLayouts.en_US; @@ -1027,7 +982,7 @@ void QskInputPanel::updateKeyData() void QskInputPanel::setMode( QskInputPanel::Mode mode ) { m_data->mode = mode; - update(); + Q_EMIT modeChanged( m_data->mode ); } #include "QskInputPanel.moc" diff --git a/src/controls/QskInputPanel.h b/src/controls/QskInputPanel.h index b5a4da29..fa316770 100644 --- a/src/controls/QskInputPanel.h +++ b/src/controls/QskInputPanel.h @@ -7,9 +7,35 @@ #define QSK_INPUT_PANEL_H #include "QskControl.h" +#include "QskPushButton.h" #include +class QskInputCompositionModel; +class QskInputPanel; + +class QskKeyButton : public QskPushButton +{ + Q_OBJECT + + using Inherited = QskPushButton; + + public: + QSK_SUBCONTROLS( Panel, Text, TextCancelButton ) + QskKeyButton( int keyIndex, QskInputPanel* inputPanel, QQuickItem* parent = nullptr ); + + virtual QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol subControl ) const override; + + public Q_SLOTS: + void updateText(); + + private: + bool isCancelButton() const; + + const int m_keyIndex; + QskInputPanel* m_inputPanel; +}; + class QSK_EXPORT QskInputPanel : public QskControl { Q_OBJECT @@ -22,12 +48,10 @@ class QSK_EXPORT QskInputPanel : public QskControl using Inherited = QskControl; public: - QSK_SUBCONTROLS( Panel, KeyPanel, KeyGlyph ) - QSK_STATES( Checked, Pressed ) - struct KeyData { Qt::Key key = Qt::Key( 0 ); + bool isSuggestionKey = false; QRectF rect; }; @@ -74,6 +98,10 @@ public: QRectF keyboardRect() const; + // takes ownership: + void registerCompositionModelForLocale( const QLocale& locale, + QskInputCompositionModel* model ); + public Q_SLOTS: void setPreeditGroups( const QVector< Qt::Key >& ); void setPreeditCandidates( const QVector< Qt::Key >& ); @@ -82,19 +110,19 @@ public Q_SLOTS: bool deactivateFocusKey(); void clearFocusKey(); + void handleKey( int keyIndex ); + KeyData& keyDataAt( int ) const; + QString currentTextForKeyIndex( int keyIndex ) const; + protected: virtual void geometryChanged( const QRectF&, const QRectF& ) override; - - virtual void mousePressEvent( QMouseEvent* ) override; - virtual void mouseMoveEvent( QMouseEvent* ) override; - virtual void mouseReleaseEvent( QMouseEvent* ) override; - virtual void touchEvent( QTouchEvent* ) override; virtual void timerEvent( QTimerEvent* ) override; + virtual bool eventFilter( QObject* object, QEvent* event ) override; private: - KeyData& keyDataAt( int ) const; + void createUI(); + void updateUI(); // e.g. called when updating Pinyin suggestions - void handleKey( int ); void compose( Qt::Key ); void selectGroup( int ); void selectCandidate( int ); @@ -105,6 +133,11 @@ private: Q_SIGNALS: void keyboardRectChanged(); void displayLanguageNameChanged(); + void inputMethodRegistered( const QLocale& locale, QskInputCompositionModel* model ); + void inputMethodEventReceived( QInputMethodEvent* inputMethodEvent ); + void keyEventReceived( QKeyEvent* keyEvent ); + void modeChanged( QskInputPanel::Mode mode ); + void cancelPressed(); public: class PrivateData; diff --git a/src/controls/QskInputPanelSkinlet.cpp b/src/controls/QskInputPanelSkinlet.cpp deleted file mode 100644 index 56acd7a4..00000000 --- a/src/controls/QskInputPanelSkinlet.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/****************************************************************************** - * QSkinny - Copyright (C) 2016 Uwe Rathmann - * This file may be used under the terms of the QSkinny License, Version 1.0 - *****************************************************************************/ - -#include "QskInputPanelSkinlet.h" -#include "QskInputPanel.h" - -#include "QskAspect.h" -#include "QskSkin.h" -#include "QskTextOptions.h" -#include "QskTextNode.h" -#include "QskBoxNode.h" - -static constexpr const QSGNode::Flag IsSubtreeBlocked = - static_cast< QSGNode::Flag >( 0x100000 ); -static constexpr const QSGNode::Flag KeyFrameNode = - static_cast< QSGNode::Flag >( 0x200000 ); -static constexpr const QSGNode::Flag KeyGlyphNode = - static_cast< QSGNode::Flag >( 0x400000 ); - -namespace -{ - class KeySkinnable: public QskSkinnable - { - public: - KeySkinnable( QskInputPanel* panel ): - m_panel( panel ) - { - } - - void setKey( Qt::Key key ) - { - setSkinStateFlag( QskInputPanel::Pressed, key & Qt::ShiftModifier ); - setSkinStateFlag( QskInputPanel::Checked, key & Qt::ControlModifier ); - setSkinStateFlag( QskInputPanel::Focused, key & Qt::MetaModifier ); - } - - const QMetaObject* metaObject() const override final - { - // Use the parent skinlet - return &QskInputPanelSkinlet::staticMetaObject; - } - - protected: - virtual const QskSkinlet* effectiveSkinlet() const override final - { - return m_panel->effectiveSkinlet(); - } - - private: - virtual QskControl* owningControl() const override final - { - return const_cast< QskInputPanel* >( m_panel ); - } - - private: - QskInputPanel* m_panel; - }; - - class FrameNode final : public QskBoxNode, public KeySkinnable - { - public: - FrameNode( QskInputPanel* panel ): - KeySkinnable( panel ) - { - setFlag( KeyFrameNode ); - } - }; - - class TextNode final : public QskTextNode, public KeySkinnable - { - public: - TextNode( QskInputPanel* panel ): - KeySkinnable( panel ) - { - setFlag( KeyGlyphNode ); - } - }; - - class InputPanelNode final : public QskBoxNode - { - public: - InputPanelNode() - { - } - - virtual bool isSubtreeBlocked() const override final - { - return flags() & IsSubtreeBlocked; - } - - using Row = QSGNode*[ QskInputPanel::KeyCount ]; - Row frames[ QskInputPanel::RowCount ] = {}; - Row glyphs[ QskInputPanel::RowCount ] = {}; - }; -} - -static_assert( QskInputPanel::RowCount * QskInputPanel::KeyCount < 255, - "The number of keys must fit into an unsigned byte." ); - -QskInputPanelSkinlet::QskInputPanelSkinlet( QskSkin* skin ): - Inherited( skin ) -{ - setNodeRoles( { Panel0, Panel1, Panel2 } ); -} - -QskInputPanelSkinlet::~QskInputPanelSkinlet() -{ -} - -QSGNode* QskInputPanelSkinlet::updateSubNode( - const QskSkinnable* control, quint8 nodeRole, QSGNode* node ) const -{ - auto inputPanel = static_cast< const QskInputPanel* >( control ); - const bool blockSubtree = inputPanel->mode() != nodeRole; - - auto panelNode = static_cast< InputPanelNode* >( node ); - if ( panelNode && panelNode->isSubtreeBlocked() != blockSubtree ) - { - panelNode->setFlag( IsSubtreeBlocked, blockSubtree ); - panelNode->markDirty( QSGNode::DirtySubtreeBlocked ); - } - - if ( !blockSubtree ) - node = updatePanelNode( inputPanel, panelNode ); - - return node; -} - -QSGNode* QskInputPanelSkinlet::updatePanelNode( - const QskInputPanel* panel, QSGNode* node ) const -{ - auto panelNode = static_cast< InputPanelNode* >( node ); - if ( panelNode == nullptr ) - panelNode = new InputPanelNode; - - const auto contentsRect = panel->keyboardRect(); - - auto& panelKeyData = panel->keyData(); - for ( const auto& keyRow : panelKeyData ) - { - const auto rowIndex = &keyRow - panelKeyData; - auto& frames = panelNode->frames[ rowIndex ]; - auto& glyphs = panelNode->glyphs[ rowIndex ]; - - for ( const auto& keyData : keyRow ) - { - const auto colIndex = &keyData - keyRow; - auto& frame = frames[ colIndex ]; - auto& glyph = glyphs[ colIndex ]; - - if ( !keyData.key || keyData.key == Qt::Key_unknown ) - { - delete frame; - frame = nullptr; - - delete glyph; - glyph = nullptr; - - continue; - } - - const qreal sx = contentsRect.size().width(); - const qreal sy = contentsRect.size().height(); - - const QRectF keyRect( - contentsRect.x() + keyData.rect.x() * sx, - contentsRect.y() + keyData.rect.y() * sy, - keyData.rect.width() * sx, - keyData.rect.height() * sy ); - - frame = updateKeyFrameNode( panel, frame, keyRect, keyData.key ); - if ( frame->parent() != panelNode ) - panelNode->appendChildNode( frame ); - - glyph = updateKeyGlyphNode( panel, glyph, keyRect, keyData.key ); - if ( glyph->parent() != panelNode ) - panelNode->appendChildNode( glyph ); - } - } - - updateBoxNode( panel, panelNode, contentsRect, QskInputPanel::Panel ); - - return panelNode; -} - -QSGNode* QskInputPanelSkinlet::updateKeyFrameNode( - const QskInputPanel* panel, QSGNode* node, - const QRectF& rect, Qt::Key key ) const -{ - auto frameNode = static_cast< FrameNode* >( node ); - if ( frameNode == nullptr ) - frameNode = new FrameNode( const_cast< QskInputPanel* >( panel ) ); - - frameNode->setKey( key ); - updateBoxNode( frameNode, frameNode, rect, QskInputPanel::KeyPanel ); - - return frameNode; -} - -QSGNode* QskInputPanelSkinlet::updateKeyGlyphNode( - const QskInputPanel* panel, QSGNode* node, - const QRectF& rect, Qt::Key key ) const -{ - auto textNode = static_cast< TextNode* >( node ); - if ( textNode == nullptr ) - textNode = new TextNode( const_cast< QskInputPanel* >( panel ) ); - - textNode->setKey( key ); - - QskTextOptions options; - options.setFontSizeMode( QskTextOptions::VerticalFit ); - - const auto alignment = textNode->flagHint< Qt::Alignment >( - QskInputPanel::KeyGlyph | QskAspect::Alignment, Qt::AlignCenter ); - - return updateTextNode( panel, textNode, rect, alignment, - panel->textForKey( key ), options, QskInputPanel::KeyGlyph ); -} - -#include "moc_QskInputPanelSkinlet.cpp" diff --git a/src/controls/QskInputPanelSkinlet.h b/src/controls/QskInputPanelSkinlet.h deleted file mode 100644 index 02202069..00000000 --- a/src/controls/QskInputPanelSkinlet.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * QSkinny - Copyright (C) 2016 Uwe Rathmann - * This file may be used under the terms of the QSkinny License, Version 1.0 - *****************************************************************************/ - -#ifndef QSK_INPUT_PANEL_SKINLET_H -#define QSK_INPUT_PANEL_SKINLET_H - -#include "QskSkinlet.h" - -class QskInputPanel; - -class QSK_EXPORT QskInputPanelSkinlet : public QskSkinlet -{ - Q_GADGET - - using Inherited = QskSkinlet; - - enum NodeRole - { - Panel0, - Panel1, - Panel2 - }; - -public: - Q_INVOKABLE QskInputPanelSkinlet( QskSkin* = nullptr ); - virtual ~QskInputPanelSkinlet(); - -protected: - virtual QSGNode* updateSubNode( const QskSkinnable*, - quint8, QSGNode* ) const override; - - virtual QSGNode* updatePanelNode( const QskInputPanel*, QSGNode* ) const; - - virtual QSGNode* updateKeyFrameNode( const QskInputPanel*, - QSGNode*, const QRectF&, Qt::Key ) const; - - virtual QSGNode* updateKeyGlyphNode( const QskInputPanel*, - QSGNode*, const QRectF&, Qt::Key ) const; -}; - -#endif diff --git a/src/controls/QskSkin.cpp b/src/controls/QskSkin.cpp index 8b262531..427878ea 100644 --- a/src/controls/QskSkin.cpp +++ b/src/controls/QskSkin.cpp @@ -39,9 +39,6 @@ QSK_QT_PRIVATE_END #include "QskGraphicLabel.h" #include "QskGraphicLabelSkinlet.h" -#include "QskInputPanel.h" -#include "QskInputPanelSkinlet.h" - #include "QskListView.h" #include "QskListViewSkinlet.h" @@ -130,7 +127,6 @@ QskSkin::QskSkin( QObject* parent ): declareSkinlet< QskBox, QskBoxSkinlet >(); declareSkinlet< QskFocusIndicator, QskFocusIndicatorSkinlet >(); declareSkinlet< QskGraphicLabel, QskGraphicLabelSkinlet >(); - declareSkinlet< QskInputPanel, QskInputPanelSkinlet >(); declareSkinlet< QskListView, QskListViewSkinlet >(); declareSkinlet< QskPageIndicator, QskPageIndicatorSkinlet >(); declareSkinlet< QskPopup, QskPopupSkinlet >(); diff --git a/src/src.pro b/src/src.pro index 828b7a41..c92375ce 100644 --- a/src/src.pro +++ b/src/src.pro @@ -136,7 +136,6 @@ HEADERS += \ controls/QskGraphicLabelSkinlet.h \ controls/QskHintAnimator.h \ controls/QskInputPanel.h \ - controls/QskInputPanelSkinlet.h \ controls/QskListView.h \ controls/QskListViewSkinlet.h \ controls/QskObjectTree.h \ @@ -201,7 +200,6 @@ SOURCES += \ controls/QskGraphicLabelSkinlet.cpp \ controls/QskHintAnimator.cpp \ controls/QskInputPanel.cpp \ - controls/QskInputPanelSkinlet.cpp \ controls/QskListView.cpp \ controls/QskListViewSkinlet.cpp \ controls/QskObjectTree.cpp \