QskAbstractTextInputSkinlet instead of QskTextInputSkinlet/QskTextEditSkinlet
This commit is contained in:
parent
5af007cf4a
commit
3fbd18456e
|
@ -76,8 +76,10 @@ namespace
|
|||
field->setText( "John Doe" );
|
||||
field->setPlaceholderText( "<Name>" );
|
||||
|
||||
#if 0
|
||||
connect( field, &QskTextField::textChanged,
|
||||
[field]() { qDebug() << "Text:" << field->text(); } );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -107,11 +109,11 @@ connect( field, &QskTextField::textChanged,
|
|||
setSpacing( 20 );
|
||||
|
||||
{
|
||||
auto textArea = new QskTextArea( "here enter longer text", this );
|
||||
auto textArea = new QskTextArea( "here enter longer text\nwith multiple lines", this );
|
||||
textArea->setWrapMode( QskTextOptions::Wrap );
|
||||
textArea->setPlaceholderText( "placeholder text" );
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
connect( textArea, &QskTextArea::textChanged,
|
||||
this, [textArea]() { qDebug() << "Text:" << textArea->text(); } );
|
||||
#endif
|
||||
|
@ -200,12 +202,6 @@ void InputPage::syncValues( qreal value )
|
|||
auto sliders = findChildren< QskSlider* >();
|
||||
for ( auto slider : sliders )
|
||||
slider->setValue( value );
|
||||
|
||||
#if 1
|
||||
auto textEdits = findChildren< QskTextEdit* >();
|
||||
for ( auto edit : textEdits )
|
||||
edit->setText( QString::number( value ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
blockUpdates = false;
|
||||
|
|
|
@ -198,6 +198,7 @@ endif()
|
|||
list(APPEND HEADERS
|
||||
controls/QskAbstractButton.h
|
||||
controls/QskAbstractTextInput.h
|
||||
controls/QskAbstractTextInputSkinlet.h
|
||||
controls/QskAnimationHint.h
|
||||
controls/QskAnimator.h
|
||||
controls/QskMainView.h
|
||||
|
@ -287,11 +288,9 @@ list(APPEND HEADERS
|
|||
controls/QskTextArea.h
|
||||
controls/QskTextAreaSkinlet.h
|
||||
controls/QskTextEdit.h
|
||||
controls/QskTextEditSkinlet.h
|
||||
controls/QskTextField.h
|
||||
controls/QskTextFieldSkinlet.h
|
||||
controls/QskTextInput.h
|
||||
controls/QskTextInputSkinlet.h
|
||||
controls/QskTextLabel.h
|
||||
controls/QskTextLabelSkinlet.h
|
||||
controls/QskVariantAnimator.h
|
||||
|
@ -308,6 +307,7 @@ list(APPEND PRIVATE_HEADERS
|
|||
list(APPEND SOURCES
|
||||
controls/QskAbstractButton.cpp
|
||||
controls/QskAbstractTextInput.cpp
|
||||
controls/QskAbstractTextInputSkinlet.cpp
|
||||
controls/QskAnimator.cpp
|
||||
controls/QskAnimationHint.cpp
|
||||
controls/QskMainView.cpp
|
||||
|
@ -400,11 +400,9 @@ list(APPEND SOURCES
|
|||
controls/QskTextArea.cpp
|
||||
controls/QskTextAreaSkinlet.cpp
|
||||
controls/QskTextEdit.cpp
|
||||
controls/QskTextEditSkinlet.cpp
|
||||
controls/QskTextField.cpp
|
||||
controls/QskTextFieldSkinlet.cpp
|
||||
controls/QskTextInput.cpp
|
||||
controls/QskTextInputSkinlet.cpp
|
||||
controls/QskTextLabel.cpp
|
||||
controls/QskTextLabelSkinlet.cpp
|
||||
controls/QskVariantAnimator.cpp
|
||||
|
|
|
@ -24,11 +24,24 @@ QSK_QT_PRIVATE_BEGIN
|
|||
QSK_QT_PRIVATE_END
|
||||
|
||||
QSK_SUBCONTROL( QskAbstractTextInput, Text )
|
||||
QSK_SUBCONTROL( QskAbstractTextInput, TextPanel )
|
||||
|
||||
QSK_SYSTEM_STATE( QskAbstractTextInput, ReadOnly, QskAspect::FirstSystemState << 1 )
|
||||
QSK_SYSTEM_STATE( QskAbstractTextInput, Editing, QskAspect::FirstSystemState << 2 )
|
||||
QSK_SYSTEM_STATE( QskAbstractTextInput, Selected, QskAspect::FirstSystemState << 3 )
|
||||
|
||||
/*
|
||||
QQuickText-Edit/Input are beasts of several thousands lines of code,
|
||||
we can't ( and don't want to ) reimplement them.
|
||||
Instead we implement wrappers with some extra functionality to
|
||||
have it in line with the QSkinny framework.
|
||||
|
||||
For some reason Qt development decided not to introduce a common
|
||||
base class for QQuickText-Edit/input and implemented large parts
|
||||
of the API twice. To avoid that we also have to copy those parts to our
|
||||
wrappers we need the ugly implementation you find in this file.
|
||||
*/
|
||||
|
||||
static inline QVariant qskInputMethodQuery(
|
||||
const QQuickItem* item, Qt::InputMethodQuery query, QVariant argument )
|
||||
{
|
||||
|
@ -109,12 +122,14 @@ class QskAbstractTextInput::PrivateData
|
|||
#define INPUT_INVOKE_ARG(func, arg) \
|
||||
( m_data->textInput ? m_data->textInput->func( arg ) : m_data->textEdit->func( arg ) )
|
||||
|
||||
#define INPUT_CONNECT( func ) \
|
||||
#define INPUT_CONNECT2( func1, func2 ) \
|
||||
m_data->textInput \
|
||||
? connect( m_data->textInput, &QQuickTextInput::func, this, &QskAbstractTextInput::func ) \
|
||||
: connect( m_data->textEdit, &QQuickTextEdit::func, this, &QskAbstractTextInput::func )
|
||||
? connect( m_data->textInput, &QQuickTextInput::func1, this, &QskAbstractTextInput::func2 ) \
|
||||
: connect( m_data->textEdit, &QQuickTextEdit::func1, this, &QskAbstractTextInput::func2 )
|
||||
|
||||
#define INPUT_CONNECT1( func, get ) \
|
||||
#define INPUT_CONNECT1( func ) INPUT_CONNECT2( func, func )
|
||||
|
||||
#define INPUT_CONNECT_ARG( func, get ) \
|
||||
do \
|
||||
{ \
|
||||
auto f = [this]() { Q_EMIT func( get() ); }; \
|
||||
|
@ -148,22 +163,24 @@ void QskAbstractTextInput::setup( QQuickItem* wrappedInput )
|
|||
m_data->textInput = qobject_cast< QQuickTextInput* >( wrappedInput );
|
||||
m_data->textEdit = qobject_cast< QQuickTextEdit* >( wrappedInput );
|
||||
|
||||
INPUT_CONNECT( textChanged );
|
||||
INPUT_CONNECT( preeditTextChanged );
|
||||
INPUT_CONNECT( readOnlyChanged );
|
||||
INPUT_CONNECT( overwriteModeChanged );
|
||||
INPUT_CONNECT( cursorVisibleChanged );
|
||||
INPUT_CONNECT1( cursorPositionChanged, cursorPosition );
|
||||
INPUT_CONNECT( selectByMouseChanged );
|
||||
INPUT_CONNECT1( persistentSelectionChanged, persistentSelection );
|
||||
INPUT_CONNECT1( wrapModeChanged, wrapMode );
|
||||
INPUT_CONNECT1( textChanged );
|
||||
INPUT_CONNECT1( preeditTextChanged );
|
||||
INPUT_CONNECT1( selectedTextChanged );
|
||||
INPUT_CONNECT1( readOnlyChanged );
|
||||
INPUT_CONNECT1( overwriteModeChanged );
|
||||
INPUT_CONNECT1( cursorVisibleChanged );
|
||||
INPUT_CONNECT_ARG( cursorPositionChanged, cursorPosition );
|
||||
INPUT_CONNECT1( selectByMouseChanged );
|
||||
INPUT_CONNECT_ARG( persistentSelectionChanged, persistentSelection );
|
||||
INPUT_CONNECT_ARG( wrapModeChanged, wrapMode );
|
||||
INPUT_CONNECT2( contentSizeChanged, resetImplicitSize );
|
||||
|
||||
INPUT_CONNECT1( canUndoChanged, canUndo );
|
||||
INPUT_CONNECT1( canRedoChanged, canRedo );
|
||||
INPUT_CONNECT1( canPasteChanged, canPaste );
|
||||
INPUT_CONNECT_ARG( canUndoChanged, canUndo );
|
||||
INPUT_CONNECT_ARG( canRedoChanged, canRedo );
|
||||
INPUT_CONNECT_ARG( canPasteChanged, canPaste );
|
||||
|
||||
INPUT_CONNECT1( inputMethodHintsChanged, inputMethodHints );
|
||||
INPUT_CONNECT1( inputMethodComposingChanged, isInputMethodComposing );
|
||||
INPUT_CONNECT_ARG( inputMethodHintsChanged, inputMethodHints );
|
||||
INPUT_CONNECT_ARG( inputMethodComposingChanged, isInputMethodComposing );
|
||||
|
||||
/*
|
||||
Other properties offered from QQuickTextInput/QQuickTextEdit:
|
||||
|
@ -196,9 +213,8 @@ void QskAbstractTextInput::setup( QQuickItem* wrappedInput )
|
|||
|
||||
- selectionStartChanged;
|
||||
- selectionEndChanged;
|
||||
- selectedTextChanged;
|
||||
|
||||
Maybe there is a better API for the selection TODO ...
|
||||
Do we need this ?
|
||||
|
||||
- mouseSelectionModeChanged
|
||||
|
||||
|
@ -208,7 +224,7 @@ void QskAbstractTextInput::setup( QQuickItem* wrappedInput )
|
|||
|
||||
This signal should never be emitted as it happens on
|
||||
events ( focusOut, commit keys ) that are handled in
|
||||
QskAbstractTextInput and indicated with editicgChanged( bool );
|
||||
QskAbstractTextInput and are indicated with editingChanged( bool );
|
||||
( Maybe having an assertion TODO ... )
|
||||
|
||||
- contentSizeChanged
|
||||
|
@ -239,46 +255,59 @@ void QskAbstractTextInput::setActivationModes( ActivationModes modes )
|
|||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
// stupid code forwarding calls 1:1 to the wrapped item
|
||||
|
||||
bool QskAbstractTextInput::selectByMouse() const
|
||||
{
|
||||
return INPUT_INVOKE( selectByMouse );
|
||||
}
|
||||
{ return INPUT_INVOKE( selectByMouse ); }
|
||||
|
||||
void QskAbstractTextInput::setSelectByMouse( bool on )
|
||||
{
|
||||
INPUT_INVOKE_ARG( setSelectByMouse, on );
|
||||
}
|
||||
{ INPUT_INVOKE_ARG( setSelectByMouse, on ); }
|
||||
|
||||
bool QskAbstractTextInput::persistentSelection() const
|
||||
{
|
||||
return INPUT_INVOKE( persistentSelection );
|
||||
}
|
||||
{ return INPUT_INVOKE( persistentSelection ); }
|
||||
|
||||
void QskAbstractTextInput::setPersistentSelection( bool on )
|
||||
{
|
||||
INPUT_INVOKE_ARG( setPersistentSelection, on );
|
||||
}
|
||||
{ INPUT_INVOKE_ARG( setPersistentSelection, on ); }
|
||||
|
||||
int QskAbstractTextInput::length() const
|
||||
{
|
||||
return INPUT_INVOKE( length );
|
||||
}
|
||||
{ return INPUT_INVOKE( length ); }
|
||||
|
||||
QString QskAbstractTextInput::text() const
|
||||
{
|
||||
return INPUT_INVOKE( text );
|
||||
}
|
||||
{ return INPUT_INVOKE( text ); }
|
||||
|
||||
void QskAbstractTextInput::setText( const QString& text )
|
||||
{
|
||||
INPUT_INVOKE_ARG( setText, text );
|
||||
}
|
||||
{ INPUT_INVOKE_ARG( setText, text ); }
|
||||
|
||||
QString QskAbstractTextInput::preeditText() const
|
||||
{
|
||||
return INPUT_INVOKE( preeditText );
|
||||
}
|
||||
{ return INPUT_INVOKE( preeditText ); }
|
||||
|
||||
QString QskAbstractTextInput::selectedText() const
|
||||
{ return INPUT_INVOKE( selectedText ); }
|
||||
|
||||
bool QskAbstractTextInput::isInputMethodComposing() const
|
||||
{ return INPUT_INVOKE( isInputMethodComposing ); }
|
||||
|
||||
bool QskAbstractTextInput::overwriteMode() const
|
||||
{ return INPUT_INVOKE( overwriteMode ); }
|
||||
|
||||
void QskAbstractTextInput::setOverwriteMode( bool on )
|
||||
{ INPUT_INVOKE_ARG( setOverwriteMode, on ); }
|
||||
|
||||
int QskAbstractTextInput::cursorPosition() const
|
||||
{ return INPUT_INVOKE( cursorPosition ); }
|
||||
|
||||
void QskAbstractTextInput::setCursorPosition( int pos )
|
||||
{ INPUT_INVOKE_ARG( setCursorPosition, pos ); }
|
||||
|
||||
bool QskAbstractTextInput::isCursorVisible() const
|
||||
{ return INPUT_INVOKE( isCursorVisible ); }
|
||||
|
||||
void QskAbstractTextInput::setCursorVisible( bool on )
|
||||
{ INPUT_INVOKE_ARG( setCursorVisible, on ); }
|
||||
|
||||
bool QskAbstractTextInput::isReadOnly() const { return INPUT_INVOKE( isReadOnly ); }
|
||||
bool QskAbstractTextInput::canUndo() const { return INPUT_INVOKE( canUndo ); }
|
||||
bool QskAbstractTextInput::canRedo() const { return INPUT_INVOKE( canRedo ); }
|
||||
bool QskAbstractTextInput::canPaste() const { return INPUT_INVOKE( canPaste ); }
|
||||
|
@ -292,6 +321,14 @@ void QskAbstractTextInput::paste() { INPUT_INVOKE( paste ); }
|
|||
void QskAbstractTextInput::undo() { INPUT_INVOKE( undo ); }
|
||||
void QskAbstractTextInput::redo() { INPUT_INVOKE( redo ); }
|
||||
|
||||
#endif
|
||||
|
||||
bool QskAbstractTextInput::hasSelectedText() const
|
||||
{
|
||||
return INPUT_INVOKE( selectionEnd ) > INPUT_INVOKE( selectionStart );
|
||||
}
|
||||
|
||||
|
||||
void QskAbstractTextInput::setFontRole( const QskFontRole& role )
|
||||
{
|
||||
if ( setFontRoleHint( Text, role ) )
|
||||
|
@ -546,11 +583,6 @@ void QskAbstractTextInput::inputMethodEvent( QInputMethodEvent* event )
|
|||
}
|
||||
}
|
||||
|
||||
bool QskAbstractTextInput::isReadOnly() const
|
||||
{
|
||||
return INPUT_INVOKE( isReadOnly );
|
||||
}
|
||||
|
||||
void QskAbstractTextInput::setReadOnly( bool on )
|
||||
{
|
||||
if ( on == isReadOnly() )
|
||||
|
@ -575,11 +607,6 @@ void QskAbstractTextInput::setReadOnly( bool on )
|
|||
setSkinStateFlag( ReadOnly, on );
|
||||
}
|
||||
|
||||
bool QskAbstractTextInput::isInputMethodComposing() const
|
||||
{
|
||||
return INPUT_INVOKE( isInputMethodComposing );
|
||||
}
|
||||
|
||||
bool QskAbstractTextInput::isEditing() const
|
||||
{
|
||||
return hasSkinState( Editing );
|
||||
|
@ -599,36 +626,6 @@ void QskAbstractTextInput::setEditing( bool on )
|
|||
Q_EMIT editingChanged( on );
|
||||
}
|
||||
|
||||
bool QskAbstractTextInput::overwriteMode() const
|
||||
{
|
||||
return INPUT_INVOKE( overwriteMode );
|
||||
}
|
||||
|
||||
void QskAbstractTextInput::setOverwriteMode( bool on )
|
||||
{
|
||||
INPUT_INVOKE_ARG( setOverwriteMode, on );
|
||||
}
|
||||
|
||||
int QskAbstractTextInput::cursorPosition() const
|
||||
{
|
||||
return INPUT_INVOKE( cursorPosition );
|
||||
}
|
||||
|
||||
void QskAbstractTextInput::setCursorPosition( int pos )
|
||||
{
|
||||
INPUT_INVOKE_ARG( setCursorPosition, pos );
|
||||
}
|
||||
|
||||
bool QskAbstractTextInput::isCursorVisible() const
|
||||
{
|
||||
return INPUT_INVOKE( isCursorVisible );
|
||||
}
|
||||
|
||||
void QskAbstractTextInput::setCursorVisible( bool on )
|
||||
{
|
||||
INPUT_INVOKE_ARG( setCursorVisible, on );
|
||||
}
|
||||
|
||||
void QskAbstractTextInput::setWrapMode( QskTextOptions::WrapMode wrapMode )
|
||||
{
|
||||
if ( m_data->textInput )
|
||||
|
|
|
@ -23,6 +23,9 @@ class QSK_EXPORT QskAbstractTextInput : public QskControl
|
|||
Q_PROPERTY( QString preeditText READ preeditText
|
||||
NOTIFY preeditTextChanged )
|
||||
|
||||
Q_PROPERTY( QString selectedText READ selectedText
|
||||
NOTIFY selectedTextChanged )
|
||||
|
||||
Q_PROPERTY( bool editing READ isEditing
|
||||
WRITE setEditing NOTIFY editingChanged )
|
||||
|
||||
|
@ -71,7 +74,7 @@ class QSK_EXPORT QskAbstractTextInput : public QskControl
|
|||
using Inherited = QskControl;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Text )
|
||||
QSK_SUBCONTROLS( Text, TextPanel )
|
||||
QSK_STATES( ReadOnly, Editing, Selected )
|
||||
|
||||
enum ActivationMode
|
||||
|
@ -93,6 +96,8 @@ class QSK_EXPORT QskAbstractTextInput : public QskControl
|
|||
|
||||
QString text() const;
|
||||
QString preeditText() const;
|
||||
QString selectedText() const;
|
||||
bool hasSelectedText() const;
|
||||
|
||||
int length() const;
|
||||
|
||||
|
@ -182,6 +187,7 @@ class QSK_EXPORT QskAbstractTextInput : public QskControl
|
|||
void inputMethodComposingChanged( bool );
|
||||
|
||||
void textChanged();
|
||||
void selectedTextChanged();
|
||||
void textEdited( const QString& );
|
||||
void preeditTextChanged();
|
||||
|
||||
|
|
|
@ -3,24 +3,22 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskTextInputSkinlet.h"
|
||||
#include "QskTextInput.h"
|
||||
#include "QskAbstractTextInputSkinlet.h"
|
||||
#include "QskAbstractTextInput.h"
|
||||
|
||||
#include <qfontmetrics.h>
|
||||
using Q = QskAbstractTextInput;
|
||||
|
||||
using Q = QskTextInput;
|
||||
|
||||
QskTextInputSkinlet::QskTextInputSkinlet( QskSkin* skin )
|
||||
QskAbstractTextInputSkinlet::QskAbstractTextInputSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
setNodeRoles( { TextPanelRole } );
|
||||
}
|
||||
|
||||
QskTextInputSkinlet::~QskTextInputSkinlet()
|
||||
QskAbstractTextInputSkinlet::~QskAbstractTextInputSkinlet()
|
||||
{
|
||||
}
|
||||
|
||||
QRectF QskTextInputSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||
QRectF QskAbstractTextInputSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
if ( subControl == Q::TextPanel )
|
||||
|
@ -29,10 +27,6 @@ QRectF QskTextInputSkinlet::subControlRect( const QskSkinnable* skinnable,
|
|||
if ( subControl == Q::Text )
|
||||
{
|
||||
auto rect = skinnable->subControlContentsRect( contentsRect, Q::TextPanel );
|
||||
|
||||
const auto h = skinnable->effectiveFontHeight( Q::Text );
|
||||
rect.setTop( rect.center().y() - 0.5 * h );
|
||||
rect.setHeight( h );
|
||||
rect = rect.marginsAdded( skinnable->marginHint( Q::Text ) );
|
||||
|
||||
return rect;
|
||||
|
@ -41,7 +35,7 @@ QRectF QskTextInputSkinlet::subControlRect( const QskSkinnable* skinnable,
|
|||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskTextInputSkinlet::updateSubNode(
|
||||
QSGNode* QskAbstractTextInputSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
switch ( nodeRole )
|
||||
|
@ -53,24 +47,21 @@ QSGNode* QskTextInputSkinlet::updateSubNode(
|
|||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QSizeF QskTextInputSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
QSizeF QskAbstractTextInputSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const auto textInput = static_cast< const QskTextInput* >( skinnable );
|
||||
Q_UNUSED( constraint ); // TODO ...
|
||||
|
||||
const QFontMetricsF fm( skinnable->effectiveFont( Q::Text ) );
|
||||
const auto input = static_cast< const QskAbstractTextInput* >( skinnable );
|
||||
|
||||
#if 0
|
||||
auto hint = QSizeF( textInput->unwrappedTextSize().width(), fm.height() );
|
||||
#else
|
||||
auto hint = fm.size( Qt::TextSingleLine | Qt::TextExpandTabs, textInput->text() );
|
||||
#endif
|
||||
|
||||
hint = skinnable->outerBoxSize( Q::TextPanel, hint );
|
||||
hint = hint.expandedTo( skinnable->strutSizeHint( Q::TextPanel ) );
|
||||
auto hint = input->unwrappedTextSize();
|
||||
hint = input->outerBoxSize( Q::TextPanel, hint );
|
||||
hint = hint.expandedTo( input->strutSizeHint( Q::TextPanel ) );
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
#include "moc_QskAbstractTextInputSkinlet.cpp"
|
|
@ -3,13 +3,15 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_TEXT_EDIT_SKINLET_H
|
||||
#define QSK_TEXT_EDIT_SKINLET_H
|
||||
#ifndef QSK_ABSTRACT_TEXT_INPUT_SKINLET_H
|
||||
#define QSK_ABSTRACT_TEXT_INPUT_SKINLET_H
|
||||
|
||||
#include "QskSkinlet.h"
|
||||
|
||||
class QSK_EXPORT QskTextEditSkinlet : public QskSkinlet
|
||||
class QSK_EXPORT QskAbstractTextInputSkinlet : public QskSkinlet
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
using Inherited = QskSkinlet;
|
||||
|
||||
public:
|
||||
|
@ -19,7 +21,8 @@ class QSK_EXPORT QskTextEditSkinlet : public QskSkinlet
|
|||
RoleCount
|
||||
};
|
||||
|
||||
~QskTextEditSkinlet() override;
|
||||
Q_INVOKABLE QskAbstractTextInputSkinlet( QskSkin* = nullptr );
|
||||
~QskAbstractTextInputSkinlet() override;
|
||||
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF& rect, QskAspect::Subcontrol ) const override;
|
||||
|
@ -28,8 +31,6 @@ class QSK_EXPORT QskTextEditSkinlet : public QskSkinlet
|
|||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
protected:
|
||||
QskTextEditSkinlet( QskSkin* = nullptr );
|
||||
|
||||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
};
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
#include "QskAbstractTextInput.h"
|
||||
#include "QskAbstractTextInputSkinlet.h"
|
||||
|
||||
#include "QskBox.h"
|
||||
#include "QskBoxSkinlet.h"
|
||||
|
||||
|
@ -103,9 +106,6 @@
|
|||
#include "QskTextArea.h"
|
||||
#include "QskTextAreaSkinlet.h"
|
||||
|
||||
#include "QskTextEdit.h"
|
||||
#include "QskTextEditSkinlet.h"
|
||||
|
||||
#include "QskTextField.h"
|
||||
#include "QskTextFieldSkinlet.h"
|
||||
|
||||
|
@ -194,6 +194,7 @@ QskSkin::QskSkin( QObject* parent )
|
|||
{
|
||||
declareSkinlet< QskControl, QskSkinlet >();
|
||||
|
||||
declareSkinlet< QskAbstractTextInput, QskAbstractTextInputSkinlet >();
|
||||
declareSkinlet< QskBox, QskBoxSkinlet >();
|
||||
declareSkinlet< QskCheckBox, QskCheckBoxSkinlet >();
|
||||
declareSkinlet< QskComboBox, QskComboBoxSkinlet >();
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
#ifndef QSK_TEXT_AREA_SKINLET_H
|
||||
#define QSK_TEXT_AREA_SKINLET_H
|
||||
|
||||
#include "QskTextEditSkinlet.h"
|
||||
#include "QskAbstractTextInputSkinlet.h"
|
||||
|
||||
class QskTextArea;
|
||||
|
||||
class QSK_EXPORT QskTextAreaSkinlet : public QskTextEditSkinlet
|
||||
class QSK_EXPORT QskTextAreaSkinlet : public QskAbstractTextInputSkinlet
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
using Inherited = QskTextEditSkinlet;
|
||||
using Inherited = QskAbstractTextInputSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole : quint8
|
||||
|
|
|
@ -12,6 +12,7 @@ QSK_QT_PRIVATE_BEGIN
|
|||
#include <private/qquicktextedit_p_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
|
||||
QSK_SUBCONTROL( QskTextEdit, Text )
|
||||
QSK_SUBCONTROL( QskTextEdit, TextPanel )
|
||||
|
||||
/*
|
||||
|
@ -139,24 +140,25 @@ QskTextEdit::QskTextEdit( QQuickItem* parent )
|
|||
, m_data( new PrivateData() )
|
||||
{
|
||||
m_data->wrappedEdit = new QuickTextEdit( this );
|
||||
auto wrappedEdit = m_data->wrappedEdit;
|
||||
|
||||
setAcceptedMouseButtons( m_data->wrappedEdit->acceptedMouseButtons() );
|
||||
m_data->wrappedEdit->setAcceptedMouseButtons( Qt::NoButton );
|
||||
setAcceptedMouseButtons( wrappedEdit->acceptedMouseButtons() );
|
||||
wrappedEdit->setAcceptedMouseButtons( Qt::NoButton );
|
||||
|
||||
initSizePolicy( QskSizePolicy::Expanding, QskSizePolicy::Expanding );
|
||||
|
||||
setup( m_data->wrappedEdit );
|
||||
setup( wrappedEdit );
|
||||
|
||||
connect( m_data->wrappedEdit, &QQuickTextEdit::lineCountChanged,
|
||||
connect( wrappedEdit, &QQuickTextEdit::lineCountChanged,
|
||||
this, [this]() { Q_EMIT lineCountChanged( lineCount() ); } );
|
||||
|
||||
connect( m_data->wrappedEdit, &QQuickTextEdit::linkActivated,
|
||||
connect( wrappedEdit, &QQuickTextEdit::linkActivated,
|
||||
this, &QskTextEdit::linkActivated );
|
||||
|
||||
connect( m_data->wrappedEdit, &QQuickTextEdit::linkHovered,
|
||||
connect( wrappedEdit, &QQuickTextEdit::linkHovered,
|
||||
this, &QskTextEdit::linkHovered );
|
||||
|
||||
connect( m_data->wrappedEdit, &QQuickTextEdit::linkActivated,
|
||||
connect( wrappedEdit, &QQuickTextEdit::linkActivated,
|
||||
this, &QskTextEdit::linkActivated );
|
||||
}
|
||||
|
||||
|
@ -164,6 +166,18 @@ QskTextEdit::~QskTextEdit()
|
|||
{
|
||||
}
|
||||
|
||||
QskAspect::Subcontrol QskTextEdit::substitutedSubcontrol(
|
||||
QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
if ( subControl == Inherited::Text )
|
||||
return Text;
|
||||
|
||||
if ( subControl == Inherited::TextPanel )
|
||||
return TextPanel;
|
||||
|
||||
return Inherited::substitutedSubcontrol( subControl );
|
||||
}
|
||||
|
||||
QUrl QskTextEdit::baseUrl() const
|
||||
{
|
||||
return m_data->wrappedEdit->baseUrl();
|
||||
|
|
|
@ -27,7 +27,7 @@ class QSK_EXPORT QskTextEdit : public QskAbstractTextInput
|
|||
using Inherited = QskAbstractTextInput;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( TextPanel )
|
||||
QSK_SUBCONTROLS( Text, TextPanel )
|
||||
|
||||
QskTextEdit( QQuickItem* parent = nullptr );
|
||||
~QskTextEdit() override;
|
||||
|
@ -54,6 +54,10 @@ class QSK_EXPORT QskTextEdit : public QskAbstractTextInput
|
|||
void linkHovered( const QString& );
|
||||
void linkActivated( const QString& );
|
||||
|
||||
protected:
|
||||
QskAspect::Subcontrol substitutedSubcontrol(
|
||||
QskAspect::Subcontrol ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskTextEditSkinlet.h"
|
||||
#include "QskTextEdit.h"
|
||||
|
||||
#include <qfontmetrics.h>
|
||||
|
||||
using Q = QskTextEdit;
|
||||
|
||||
QskTextEditSkinlet::QskTextEditSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
setNodeRoles( { TextPanelRole } );
|
||||
}
|
||||
|
||||
QskTextEditSkinlet::~QskTextEditSkinlet()
|
||||
{
|
||||
}
|
||||
|
||||
QRectF QskTextEditSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
if ( subControl == Q::TextPanel )
|
||||
{
|
||||
return contentsRect;
|
||||
}
|
||||
else if ( subControl == Q::Text )
|
||||
{
|
||||
auto rect = skinnable->subControlContentsRect( contentsRect, Q::TextPanel );
|
||||
rect = rect.marginsAdded( skinnable->marginHint( Q::Text ) );
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskTextEditSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
switch ( nodeRole )
|
||||
{
|
||||
case TextPanelRole:
|
||||
{
|
||||
return updateBoxNode( skinnable, node, Q::TextPanel );
|
||||
}
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QSizeF QskTextEditSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const auto textEdit = static_cast< const QskTextEdit* >( skinnable );
|
||||
|
||||
const QFontMetricsF fm( textEdit->effectiveFont( Q::Text ) );
|
||||
|
||||
int flags = Qt::TextExpandTabs;
|
||||
|
||||
const auto wm = textEdit->wrapMode();
|
||||
|
||||
if( wm & QskTextOptions::WordWrap )
|
||||
{
|
||||
flags |= Qt::TextWordWrap;
|
||||
}
|
||||
else if( wm & QskTextOptions::WrapAnywhere )
|
||||
{
|
||||
flags |= Qt::TextWrapAnywhere;
|
||||
}
|
||||
else if( wm & QskTextOptions::Wrap )
|
||||
{
|
||||
flags |= Qt::TextWordWrap | Qt::TextWrapAnywhere;
|
||||
}
|
||||
|
||||
auto hint = fm.boundingRect( textEdit->subControlRect( Q::Text ), flags, textEdit->text() ).size();
|
||||
|
||||
hint = textEdit->outerBoxSize( Q::TextPanel, hint );
|
||||
hint = hint.expandedTo( textEdit->strutSizeHint( Q::TextPanel ) );
|
||||
|
||||
return hint;
|
||||
}
|
|
@ -6,20 +6,20 @@
|
|||
#ifndef QSK_TEXT_FIELD_SKINLET_H
|
||||
#define QSK_TEXT_FIELD_SKINLET_H
|
||||
|
||||
#include "QskTextInputSkinlet.h"
|
||||
#include "QskAbstractTextInputSkinlet.h"
|
||||
|
||||
class QskTextField;
|
||||
|
||||
class QSK_EXPORT QskTextFieldSkinlet : public QskTextInputSkinlet
|
||||
class QSK_EXPORT QskTextFieldSkinlet : public QskAbstractTextInputSkinlet
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
using Inherited = QskTextInputSkinlet;
|
||||
using Inherited = QskAbstractTextInputSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole : quint8
|
||||
{
|
||||
PanelRole = QskTextInputSkinlet::RoleCount,
|
||||
PanelRole = QskAbstractTextInputSkinlet::RoleCount,
|
||||
|
||||
PlaceholderTextRole,
|
||||
RoleCount
|
||||
|
|
|
@ -12,6 +12,7 @@ QSK_QT_PRIVATE_BEGIN
|
|||
#include <private/qquicktextinput_p_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
|
||||
QSK_SUBCONTROL( QskTextInput, Text )
|
||||
QSK_SUBCONTROL( QskTextInput, TextPanel )
|
||||
QSK_SYSTEM_STATE( QskTextInput, Error, QskAspect::FirstSystemState << 4 )
|
||||
|
||||
|
@ -154,13 +155,6 @@ QskTextInput::QskTextInput( QQuickItem* parent )
|
|||
: Inherited( parent )
|
||||
, m_data( new PrivateData() )
|
||||
{
|
||||
/*
|
||||
QQuickTextInput is a beast of almost 5k lines of code, we don't
|
||||
want to reimplement that - at least not now.
|
||||
So QskTextInput is more or less a simple wrapper making everything
|
||||
conforming to qskinny.
|
||||
*/
|
||||
|
||||
m_data->wrappedInput = new QuickTextInput( this );
|
||||
auto wrappedInput = m_data->wrappedInput;
|
||||
|
||||
|
@ -171,7 +165,6 @@ QskTextInput::QskTextInput( QQuickItem* parent )
|
|||
|
||||
setup( wrappedInput );
|
||||
|
||||
#if 1
|
||||
connect( wrappedInput, &QQuickTextInput::maximumLengthChanged,
|
||||
this, &QskTextInput::maximumLengthChanged );
|
||||
|
||||
|
@ -183,14 +176,24 @@ QskTextInput::QskTextInput( QQuickItem* parent )
|
|||
|
||||
connect( wrappedInput, &QQuickTextInput::acceptableInputChanged,
|
||||
this, [this]() { Q_EMIT acceptableInputChanged( hasAcceptableInput() ); } );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
QskTextInput::~QskTextInput()
|
||||
{
|
||||
}
|
||||
|
||||
QskAspect::Subcontrol QskTextInput::substitutedSubcontrol(
|
||||
QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
if ( subControl == Inherited::Text )
|
||||
return Text;
|
||||
|
||||
if ( subControl == Inherited::TextPanel )
|
||||
return TextPanel;
|
||||
|
||||
return Inherited::substitutedSubcontrol( subControl );
|
||||
}
|
||||
|
||||
void QskTextInput::ensureVisible( int position )
|
||||
{
|
||||
m_data->wrappedInput->ensureVisible( position );
|
||||
|
|
|
@ -46,8 +46,7 @@ class QSK_EXPORT QskTextInput : public QskAbstractTextInput
|
|||
using Inherited = QskAbstractTextInput;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( TextPanel )
|
||||
|
||||
QSK_SUBCONTROLS( Text, TextPanel )
|
||||
QSK_STATES( Error )
|
||||
|
||||
enum EchoMode : quint8
|
||||
|
@ -108,6 +107,10 @@ class QSK_EXPORT QskTextInput : public QskAbstractTextInput
|
|||
|
||||
void displayTextChanged();
|
||||
|
||||
protected:
|
||||
QskAspect::Subcontrol substitutedSubcontrol(
|
||||
QskAspect::Subcontrol ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_TEXT_INPUT_SKINLET_H
|
||||
#define QSK_TEXT_INPUT_SKINLET_H
|
||||
|
||||
#include "QskSkinlet.h"
|
||||
|
||||
class QSK_EXPORT QskTextInputSkinlet : public QskSkinlet
|
||||
{
|
||||
using Inherited = QskSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole : quint8
|
||||
{
|
||||
TextPanelRole,
|
||||
RoleCount
|
||||
};
|
||||
|
||||
~QskTextInputSkinlet() override;
|
||||
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF& rect, QskAspect::Subcontrol ) const override;
|
||||
|
||||
QSizeF sizeHint( const QskSkinnable*,
|
||||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
protected:
|
||||
QskTextInputSkinlet( QskSkin* = nullptr );
|
||||
|
||||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue