qskinny/src/inputpanel/QskInputPanel.cpp

231 lines
5.6 KiB
C++
Raw Normal View History

2018-04-06 17:30:24 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskInputPanel.h"
#include "QskVirtualKeyboard.h"
#include "QskInputPredictionBar.h"
#include "QskTextInput.h"
#include "QskTextLabel.h"
#include "QskLinearBox.h"
2018-04-06 17:30:24 +02:00
#include <QString>
#include <QLocale>
#include <QPointer>
#include <QInputMethodQueryEvent>
namespace
{
2018-04-30 10:03:51 +02:00
class TextInputProxy final : public QskTextInput
{
public:
2018-04-30 10:03:51 +02:00
TextInputProxy( QQuickItem* parentItem = nullptr ):
QskTextInput( parentItem )
{
2018-04-27 13:48:51 +02:00
setObjectName( "InputPanelInputProxy" );
setFocusPolicy( Qt::NoFocus );
2018-06-01 17:26:22 +02:00
}
protected:
virtual void focusInEvent( QFocusEvent* ) override final
{
}
virtual void focusOutEvent( QFocusEvent* ) override final
{
}
};
}
QSK_SUBCONTROL( QskInputPanel, Panel )
class QskInputPanel::PrivateData
{
public:
QPointer< QQuickItem > inputItem;
2018-04-12 12:03:51 +02:00
QskLinearBox* layout;
QskTextLabel* prompt;
2018-04-30 10:03:51 +02:00
TextInputProxy* inputProxy;
QskInputPredictionBar* predictionBar;
QskVirtualKeyboard* keyboard;
2018-06-02 17:10:41 +02:00
int maxChars = -1;
2018-04-27 13:48:51 +02:00
2018-06-02 17:10:41 +02:00
QskInputPanel::PanelHints panelHints = QskInputPanel::InputProxy;
};
QskInputPanel::QskInputPanel( QQuickItem* parent ):
Inherited( parent ),
m_data( new PrivateData() )
{
setAutoLayoutChildren( true );
2018-04-12 12:03:51 +02:00
initSizePolicy( QskSizePolicy::Expanding, QskSizePolicy::Constrained );
m_data->prompt = new QskTextLabel();
m_data->prompt->setVisible( false );
2018-04-30 10:03:51 +02:00
m_data->inputProxy = new TextInputProxy();
2018-06-02 17:10:41 +02:00
m_data->inputProxy->setVisible(
m_data->panelHints & QskInputPanel::InputProxy );
m_data->predictionBar = new QskInputPredictionBar();
2018-06-02 17:10:41 +02:00
m_data->predictionBar->setVisible(
m_data->panelHints & QskInputPanel::Prediction );
m_data->keyboard = new QskVirtualKeyboard();
auto layout = new QskLinearBox( Qt::Vertical, this );
layout->addItem( m_data->prompt, Qt::AlignLeft | Qt::AlignHCenter );
layout->addItem( m_data->inputProxy, Qt::AlignLeft | Qt::AlignHCenter );
layout->addStretch( 10 );
layout->addItem( m_data->predictionBar );
layout->addItem( m_data->keyboard );
m_data->layout = layout;
connect( m_data->predictionBar, &QskInputPredictionBar::predictiveTextSelected,
2018-06-02 17:10:41 +02:00
this, &QskInputPanel::predictiveTextSelected );
connect( m_data->keyboard, &QskVirtualKeyboard::keySelected,
2018-06-02 17:10:41 +02:00
this, &QskInputPanel::keySelected );
}
QskInputPanel::~QskInputPanel()
{
}
2018-06-02 17:10:41 +02:00
void QskInputPanel::setPanelHint( PanelHint hint, bool on )
{
if ( on )
setPanelHints( m_data->panelHints | hint );
else
setPanelHints( m_data->panelHints & ~hint );
}
void QskInputPanel::setPanelHints( PanelHints hints )
2018-04-12 12:03:51 +02:00
{
2018-06-02 17:10:41 +02:00
if ( hints == m_data->panelHints )
return;
2018-06-02 17:10:41 +02:00
m_data->panelHints = hints;
2018-06-02 17:10:41 +02:00
m_data->inputProxy->setVisible( hints & QskInputPanel::InputProxy );
m_data->predictionBar->setVisible( hints & QskInputPanel::Prediction );
2018-04-12 12:03:51 +02:00
2018-06-02 17:10:41 +02:00
const bool showPrompt = ( hints & QskInputPanel::InputProxy )
&& !m_data->prompt->text().isEmpty();
2018-04-12 12:03:51 +02:00
2018-06-02 17:10:41 +02:00
m_data->prompt->setVisible( showPrompt );
Q_EMIT panelHintsChanged();
}
QskInputPanel::PanelHints QskInputPanel::panelHints() const
{
return m_data->panelHints;
2018-04-12 12:03:51 +02:00
}
void QskInputPanel::attachInputItem( QQuickItem* item )
2018-04-12 12:03:51 +02:00
{
if ( item == m_data->inputItem )
return;
2018-04-12 12:03:51 +02:00
m_data->inputItem = item;
2018-04-12 12:03:51 +02:00
if ( item )
2018-04-12 12:03:51 +02:00
{
2018-06-02 17:10:41 +02:00
if ( m_data->panelHints & QskInputPanel::InputProxy )
{
2018-06-02 17:10:41 +02:00
m_data->inputProxy->setupFrom( item );
2018-04-27 13:48:51 +02:00
m_data->inputProxy->setEditing( true );
2018-06-02 17:10:41 +02:00
// hiding the cursor in item
const QInputMethodEvent::Attribute attribute(
QInputMethodEvent::Cursor, 0, 0, QVariant() );
QInputMethodEvent event( QString(), { attribute } );
QCoreApplication::sendEvent( item, &event );
}
2018-04-12 12:03:51 +02:00
}
}
2018-04-12 12:03:51 +02:00
QQuickItem* QskInputPanel::attachedInputItem() const
{
return m_data->inputItem;
}
2018-06-01 17:26:22 +02:00
QQuickItem* QskInputPanel::inputProxy() const
{
return m_data->inputProxy;
}
QskAspect::Subcontrol QskInputPanel::effectiveSubcontrol(
QskAspect::Subcontrol subControl ) const
{
if( subControl == QskBox::Panel )
return QskInputPanel::Panel;
return subControl;
2018-04-12 12:03:51 +02:00
}
QString QskInputPanel::inputPrompt() const
{
return m_data->prompt->text();
}
void QskInputPanel::setInputPrompt( const QString& text )
{
auto prompt = m_data->prompt;
if ( text != prompt->text() )
{
prompt->setText( text );
2018-06-02 17:10:41 +02:00
if ( m_data->panelHints & QskInputPanel::InputProxy )
prompt->setVisible( !text.isEmpty() );
Q_EMIT inputPromptChanged( text );
}
}
2018-06-02 17:10:41 +02:00
void QskInputPanel::setPrediction( const QStringList& prediction )
{
2018-06-02 17:10:41 +02:00
m_data->predictionBar->setPrediction( prediction );
}
2018-04-13 16:32:48 +02:00
void QskInputPanel::keyPressEvent( QKeyEvent* event )
{
2018-06-03 11:01:22 +02:00
int keyCode = -1;
2018-04-13 16:32:48 +02:00
switch( event->key() )
{
case Qt::Key_Return:
case Qt::Key_Escape:
{
2018-06-03 11:01:22 +02:00
keyCode = event->key();
2018-04-30 10:03:51 +02:00
break;
}
2018-04-13 16:32:48 +02:00
default:
{
const auto text = event->text();
2018-06-02 17:10:41 +02:00
2018-04-13 16:32:48 +02:00
if ( !text.isEmpty() )
2018-06-03 11:01:22 +02:00
keyCode = text[0].unicode();
2018-04-13 16:32:48 +02:00
else
2018-06-03 11:01:22 +02:00
keyCode = event->key();
2018-04-13 16:32:48 +02:00
}
}
2018-06-03 11:01:22 +02:00
if ( m_data->keyboard->hasKey( keyCode ) )
{
// animating the corresponding key button ???
Q_EMIT keySelected( keyCode );
}
2018-04-13 16:32:48 +02:00
}
#include "moc_QskInputPanel.cpp"