2018-06-11 18:55:48 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
#include "QskInputPanelBox.h"
|
2018-06-11 18:55:48 +02:00
|
|
|
#include "QskVirtualKeyboard.h"
|
|
|
|
#include "QskInputPredictionBar.h"
|
|
|
|
#include "QskTextInput.h"
|
|
|
|
#include "QskTextLabel.h"
|
|
|
|
#include "QskLinearBox.h"
|
|
|
|
|
2018-07-19 14:10:48 +02:00
|
|
|
#include <qstring.h>
|
|
|
|
#include <qpointer.h>
|
2018-06-11 18:55:48 +02:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
class TextInputProxy final : public QskTextInput
|
|
|
|
{
|
|
|
|
public:
|
2018-06-12 08:20:48 +02:00
|
|
|
TextInputProxy( QskInputPanelBox* panelBox, QQuickItem* parentItem = nullptr ):
|
2018-06-11 18:55:48 +02:00
|
|
|
QskTextInput( parentItem ),
|
2018-06-12 08:20:48 +02:00
|
|
|
m_panelBox( panelBox )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
2018-06-12 08:20:48 +02:00
|
|
|
setObjectName( "InputBoxProxy" );
|
2018-06-11 18:55:48 +02:00
|
|
|
setFocusPolicy( Qt::NoFocus );
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual QskAspect::Subcontrol effectiveSubcontrol(
|
|
|
|
QskAspect::Subcontrol subControl ) const override
|
|
|
|
{
|
|
|
|
if ( subControl == QskTextInput::Panel )
|
2018-06-12 08:20:48 +02:00
|
|
|
return m_panelBox->effectiveSubcontrol( QskInputPanelBox::ProxyPanel );
|
2018-06-11 18:55:48 +02:00
|
|
|
|
|
|
|
if ( subControl == QskTextInput::Text )
|
2018-06-12 08:20:48 +02:00
|
|
|
return m_panelBox->effectiveSubcontrol( QskInputPanelBox::ProxyText );
|
2018-06-11 18:55:48 +02:00
|
|
|
|
|
|
|
return subControl;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void focusInEvent( QFocusEvent* ) override final
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void focusOutEvent( QFocusEvent* ) override final
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-06-12 08:20:48 +02:00
|
|
|
QskInputPanelBox* m_panelBox;
|
2018-06-11 18:55:48 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QSK_SUBCONTROL( QskInputPanelBox, Panel )
|
|
|
|
QSK_SUBCONTROL( QskInputPanelBox, ProxyPanel )
|
|
|
|
QSK_SUBCONTROL( QskInputPanelBox, ProxyText )
|
2018-06-11 18:55:48 +02:00
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
class QskInputPanelBox::PrivateData
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
QPointer< QQuickItem > inputItem;
|
|
|
|
|
|
|
|
QskLinearBox* layout;
|
|
|
|
QskTextLabel* prompt;
|
|
|
|
TextInputProxy* inputProxy;
|
|
|
|
QskInputPredictionBar* predictionBar;
|
|
|
|
QskVirtualKeyboard* keyboard;
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QskInputPanelBox::PanelHints panelHints = QskInputPanelBox::InputProxy;
|
2018-06-11 18:55:48 +02:00
|
|
|
};
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QskInputPanelBox::QskInputPanelBox( QQuickItem* parent ):
|
2018-06-11 18:55:48 +02:00
|
|
|
Inherited( parent ),
|
|
|
|
m_data( new PrivateData() )
|
|
|
|
{
|
|
|
|
setAutoLayoutChildren( true );
|
|
|
|
|
|
|
|
m_data->prompt = new QskTextLabel();
|
|
|
|
m_data->prompt->setVisible( false );
|
|
|
|
|
|
|
|
m_data->inputProxy = new TextInputProxy( this, nullptr );
|
|
|
|
m_data->inputProxy->setVisible(
|
2018-06-12 08:20:48 +02:00
|
|
|
m_data->panelHints & QskInputPanelBox::InputProxy );
|
2018-06-11 18:55:48 +02:00
|
|
|
|
|
|
|
m_data->predictionBar = new QskInputPredictionBar();
|
|
|
|
m_data->predictionBar->setVisible(
|
2018-06-12 08:20:48 +02:00
|
|
|
m_data->panelHints & QskInputPanelBox::Prediction );
|
2018-06-11 18:55:48 +02:00
|
|
|
|
|
|
|
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-12 08:20:48 +02:00
|
|
|
this, &QskInputPanelBox::predictiveTextSelected );
|
2018-06-11 18:55:48 +02:00
|
|
|
|
|
|
|
connect( m_data->keyboard, &QskVirtualKeyboard::keySelected,
|
2018-06-12 08:20:48 +02:00
|
|
|
this, &QskInputPanelBox::keySelected );
|
2018-06-11 18:55:48 +02:00
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QskInputPanelBox::~QskInputPanelBox()
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
void QskInputPanelBox::setPanelHint( PanelHint hint, bool on )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
if ( on )
|
|
|
|
setPanelHints( m_data->panelHints | hint );
|
|
|
|
else
|
|
|
|
setPanelHints( m_data->panelHints & ~hint );
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
void QskInputPanelBox::setPanelHints( PanelHints hints )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
if ( hints == m_data->panelHints )
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_data->panelHints = hints;
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
m_data->inputProxy->setVisible( hints & QskInputPanelBox::InputProxy );
|
|
|
|
m_data->predictionBar->setVisible( hints & QskInputPanelBox::Prediction );
|
2018-06-11 18:55:48 +02:00
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
const bool showPrompt = ( hints & QskInputPanelBox::InputProxy )
|
2018-06-11 18:55:48 +02:00
|
|
|
&& !m_data->prompt->text().isEmpty();
|
|
|
|
|
|
|
|
m_data->prompt->setVisible( showPrompt );
|
|
|
|
|
|
|
|
Q_EMIT panelHintsChanged();
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QskInputPanelBox::PanelHints QskInputPanelBox::panelHints() const
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
return m_data->panelHints;
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
void QskInputPanelBox::attachInputItem( QQuickItem* item )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
if ( item == m_data->inputItem )
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_data->inputItem = item;
|
|
|
|
|
|
|
|
if ( item )
|
|
|
|
{
|
2018-06-12 08:20:48 +02:00
|
|
|
if ( m_data->panelHints & QskInputPanelBox::InputProxy )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
m_data->inputProxy->setupFrom( item );
|
|
|
|
m_data->inputProxy->setEditing( true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QQuickItem* QskInputPanelBox::attachedInputItem() const
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
return m_data->inputItem;
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QQuickItem* QskInputPanelBox::inputProxy() const
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
2018-06-12 08:20:48 +02:00
|
|
|
if ( m_data->panelHints & QskInputPanelBox::InputProxy )
|
|
|
|
return m_data->inputProxy;
|
|
|
|
|
|
|
|
return nullptr;
|
2018-06-11 18:55:48 +02:00
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QskAspect::Subcontrol QskInputPanelBox::effectiveSubcontrol(
|
2018-06-11 18:55:48 +02:00
|
|
|
QskAspect::Subcontrol subControl ) const
|
|
|
|
{
|
|
|
|
if( subControl == QskBox::Panel )
|
2018-06-12 08:20:48 +02:00
|
|
|
return QskInputPanelBox::Panel;
|
2018-06-11 18:55:48 +02:00
|
|
|
|
|
|
|
#if 1
|
|
|
|
// TODO ...
|
2018-06-12 08:20:48 +02:00
|
|
|
if( subControl == QskInputPanelBox::ProxyPanel )
|
2018-06-11 18:55:48 +02:00
|
|
|
return QskTextInput::Panel;
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
if( subControl == QskInputPanelBox::ProxyText )
|
2018-06-11 18:55:48 +02:00
|
|
|
return QskTextInput::Text;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return subControl;
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
QString QskInputPanelBox::inputPrompt() const
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
return m_data->prompt->text();
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
void QskInputPanelBox::setInputPrompt( const QString& text )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
auto prompt = m_data->prompt;
|
|
|
|
|
|
|
|
if ( text != prompt->text() )
|
|
|
|
{
|
|
|
|
prompt->setText( text );
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
if ( m_data->panelHints & QskInputPanelBox::InputProxy )
|
2018-06-11 18:55:48 +02:00
|
|
|
prompt->setVisible( !text.isEmpty() );
|
|
|
|
|
|
|
|
Q_EMIT inputPromptChanged( text );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
void QskInputPanelBox::setPrediction( const QStringList& prediction )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
m_data->predictionBar->setPrediction( prediction );
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
void QskInputPanelBox::keyPressEvent( QKeyEvent* event )
|
2018-06-11 18:55:48 +02:00
|
|
|
{
|
|
|
|
int keyCode = -1;
|
|
|
|
|
|
|
|
switch( event->key() )
|
|
|
|
{
|
|
|
|
case Qt::Key_Return:
|
|
|
|
case Qt::Key_Escape:
|
|
|
|
{
|
|
|
|
keyCode = event->key();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
const auto text = event->text();
|
|
|
|
|
|
|
|
if ( !text.isEmpty() )
|
|
|
|
keyCode = text[0].unicode();
|
|
|
|
else
|
|
|
|
keyCode = event->key();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_data->keyboard->hasKey( keyCode ) )
|
|
|
|
{
|
|
|
|
// animating the corresponding key button ???
|
|
|
|
Q_EMIT keySelected( keyCode );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-12 08:20:48 +02:00
|
|
|
#include "moc_QskInputPanelBox.cpp"
|