QskTextEdit/QskTextArea introduced
This commit is contained in:
parent
4e8c3e665c
commit
86b3c9f556
|
|
@ -49,6 +49,7 @@
|
||||||
#include "QskFluent2Theme.h"
|
#include "QskFluent2Theme.h"
|
||||||
#include "QskFluent2TextFieldSkinlet.h"
|
#include "QskFluent2TextFieldSkinlet.h"
|
||||||
|
|
||||||
|
#include <QskTextAreaSkinlet.h>
|
||||||
#include <QskSkinHintTableEditor.h>
|
#include <QskSkinHintTableEditor.h>
|
||||||
|
|
||||||
#include <QskBox.h>
|
#include <QskBox.h>
|
||||||
|
|
@ -80,6 +81,7 @@
|
||||||
#include <QskTabButton.h>
|
#include <QskTabButton.h>
|
||||||
#include <QskTabView.h>
|
#include <QskTabView.h>
|
||||||
#include <QskTextField.h>
|
#include <QskTextField.h>
|
||||||
|
#include <QskTextArea.h>
|
||||||
#include <QskTextLabel.h>
|
#include <QskTextLabel.h>
|
||||||
#include <QskVirtualKeyboard.h>
|
#include <QskVirtualKeyboard.h>
|
||||||
|
|
||||||
|
|
@ -297,6 +299,15 @@ namespace
|
||||||
void setupTabViewMetrics();
|
void setupTabViewMetrics();
|
||||||
void setupTabViewColors( QskAspect::Section, const QskFluent2Theme& );
|
void setupTabViewColors( QskAspect::Section, const QskFluent2Theme& );
|
||||||
|
|
||||||
|
template< typename Q >
|
||||||
|
void setupTextControlMetrics();
|
||||||
|
|
||||||
|
template< typename Q, typename SK >
|
||||||
|
void setupTextControlColors( QskAspect::Section section, const QskFluent2Theme& theme );
|
||||||
|
|
||||||
|
void setupTextAreaMetrics();
|
||||||
|
void setupTextAreaColors( QskAspect::Section, const QskFluent2Theme& );
|
||||||
|
|
||||||
void setupTextFieldMetrics();
|
void setupTextFieldMetrics();
|
||||||
void setupTextFieldColors( QskAspect::Section, const QskFluent2Theme& );
|
void setupTextFieldColors( QskAspect::Section, const QskFluent2Theme& );
|
||||||
|
|
||||||
|
|
@ -356,6 +367,7 @@ void Editor::setupMetrics()
|
||||||
setupTabButtonMetrics();
|
setupTabButtonMetrics();
|
||||||
setupTabBarMetrics();
|
setupTabBarMetrics();
|
||||||
setupTabViewMetrics();
|
setupTabViewMetrics();
|
||||||
|
setupTextAreaMetrics();
|
||||||
setupTextFieldMetrics();
|
setupTextFieldMetrics();
|
||||||
setupTextLabelMetrics();
|
setupTextLabelMetrics();
|
||||||
setupVirtualKeyboardMetrics();
|
setupVirtualKeyboardMetrics();
|
||||||
|
|
@ -395,6 +407,7 @@ void Editor::setupColors( QskAspect::Section section, const QskFluent2Theme& the
|
||||||
setupTabButtonColors( section, theme );
|
setupTabButtonColors( section, theme );
|
||||||
setupTabBarColors( section, theme );
|
setupTabBarColors( section, theme );
|
||||||
setupTabViewColors( section, theme );
|
setupTabViewColors( section, theme );
|
||||||
|
setupTextAreaColors( section, theme );
|
||||||
setupTextFieldColors( section, theme );
|
setupTextFieldColors( section, theme );
|
||||||
setupTextLabelColors( section, theme );
|
setupTextLabelColors( section, theme );
|
||||||
setupVirtualKeyboardColors( section, theme );
|
setupVirtualKeyboardColors( section, theme );
|
||||||
|
|
@ -1781,10 +1794,8 @@ void Editor::setupTextLabelColors(
|
||||||
setColor( Q::Text | section, pal.fillColor.text.primary );
|
setColor( Q::Text | section, pal.fillColor.text.primary );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupTextFieldMetrics()
|
template< typename Q > void Editor::setupTextControlMetrics()
|
||||||
{
|
{
|
||||||
using Q = QskTextField;
|
|
||||||
|
|
||||||
setStrutSize( Q::TextPanel, { -1, 30_px } );
|
setStrutSize( Q::TextPanel, { -1, 30_px } );
|
||||||
setPadding( Q::TextPanel, { 11_px, 0, 11_px, 0 } );
|
setPadding( Q::TextPanel, { 11_px, 0, 11_px, 0 } );
|
||||||
|
|
||||||
|
|
@ -1794,18 +1805,15 @@ void Editor::setupTextFieldMetrics()
|
||||||
|
|
||||||
setBoxShape( Q::TextPanel, 3_px );
|
setBoxShape( Q::TextPanel, 3_px );
|
||||||
|
|
||||||
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignVCenter );
|
|
||||||
setFontRole( Q::Text, Fluent2::Body );
|
setFontRole( Q::Text, Fluent2::Body );
|
||||||
|
|
||||||
setAlignment( Q::PlaceholderText, alignment( Q::Text ) );
|
setAlignment( Q::PlaceholderText, alignment( Q::Text ) );
|
||||||
setFontRole( Q::PlaceholderText, fontRole( Q::Text ) );
|
setFontRole( Q::PlaceholderText, fontRole( Q::Text ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupTextFieldColors(
|
template< typename Q, typename SK > void Editor::setupTextControlColors(
|
||||||
QskAspect::Section section, const QskFluent2Theme& theme)
|
QskAspect::Section section, const QskFluent2Theme& theme)
|
||||||
{
|
{
|
||||||
using Q = QskTextField;
|
|
||||||
using SK = QskTextFieldSkinlet;
|
|
||||||
using A = QskAspect;
|
using A = QskAspect;
|
||||||
|
|
||||||
const auto& pal = theme.palette;
|
const auto& pal = theme.palette;
|
||||||
|
|
@ -1858,6 +1866,36 @@ void Editor::setupTextFieldColors(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextAreaMetrics()
|
||||||
|
{
|
||||||
|
using Q = QskTextArea;
|
||||||
|
|
||||||
|
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignTop );
|
||||||
|
|
||||||
|
setupTextControlMetrics< Q >();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextAreaColors(
|
||||||
|
QskAspect::Section section, const QskFluent2Theme& theme )
|
||||||
|
{
|
||||||
|
setupTextControlColors< QskTextArea, QskTextAreaSkinlet >( section, theme );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextFieldMetrics()
|
||||||
|
{
|
||||||
|
using Q = QskTextField;
|
||||||
|
|
||||||
|
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
|
|
||||||
|
setupTextControlMetrics< Q >();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextFieldColors(
|
||||||
|
QskAspect::Section section, const QskFluent2Theme& theme )
|
||||||
|
{
|
||||||
|
setupTextControlColors< QskTextField, QskTextFieldSkinlet >( section, theme );
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::setupSwitchButtonMetrics()
|
void Editor::setupSwitchButtonMetrics()
|
||||||
{
|
{
|
||||||
using Q = QskSwitchButton;
|
using Q = QskSwitchButton;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@
|
||||||
#include <QskTabBar.h>
|
#include <QskTabBar.h>
|
||||||
#include <QskTabButton.h>
|
#include <QskTabButton.h>
|
||||||
#include <QskTabView.h>
|
#include <QskTabView.h>
|
||||||
|
#include <QskTextArea.h>
|
||||||
|
#include <QskTextAreaSkinlet.h>
|
||||||
#include <QskTextField.h>
|
#include <QskTextField.h>
|
||||||
#include <QskTextFieldSkinlet.h>
|
#include <QskTextFieldSkinlet.h>
|
||||||
#include <QskTextLabel.h>
|
#include <QskTextLabel.h>
|
||||||
|
|
@ -142,6 +144,10 @@ namespace
|
||||||
Q_INVOKABLE void setupTabButton();
|
Q_INVOKABLE void setupTabButton();
|
||||||
Q_INVOKABLE void setupTabBar();
|
Q_INVOKABLE void setupTabBar();
|
||||||
Q_INVOKABLE void setupTabView();
|
Q_INVOKABLE void setupTabView();
|
||||||
|
|
||||||
|
template< typename Q, typename SK >
|
||||||
|
void setupTextControl();
|
||||||
|
Q_INVOKABLE void setupTextArea();
|
||||||
Q_INVOKABLE void setupTextField();
|
Q_INVOKABLE void setupTextField();
|
||||||
Q_INVOKABLE void setupTextLabel();
|
Q_INVOKABLE void setupTextLabel();
|
||||||
|
|
||||||
|
|
@ -383,16 +389,12 @@ void Editor::setupTextLabel()
|
||||||
setBoxBorderColors( Q::Panel, QskRgb::lighter( m_pal.outline, 108 ) );
|
setBoxBorderColors( Q::Panel, QskRgb::lighter( m_pal.outline, 108 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupTextField()
|
template< typename Q, typename SK >
|
||||||
|
void Editor::setupTextControl()
|
||||||
{
|
{
|
||||||
using Q = QskTextField;
|
|
||||||
using SK = QskTextFieldSkinlet;
|
|
||||||
using A = QskAspect;
|
using A = QskAspect;
|
||||||
using P = QPalette;
|
using P = QPalette;
|
||||||
|
|
||||||
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignVCenter );
|
|
||||||
setAlignment( Q::PlaceholderText, Qt::AlignLeft | Qt::AlignVCenter );
|
|
||||||
|
|
||||||
for ( auto state : { A::NoState, Q::Disabled } )
|
for ( auto state : { A::NoState, Q::Disabled } )
|
||||||
{
|
{
|
||||||
const auto colorGroup = ( state == A::NoState ) ? P::Active : P::Disabled;
|
const auto colorGroup = ( state == A::NoState ) ? P::Active : P::Disabled;
|
||||||
|
|
@ -418,6 +420,28 @@ void Editor::setupTextField()
|
||||||
setPadding( Q::TextPanel, 4_px );
|
setPadding( Q::TextPanel, 4_px );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextArea()
|
||||||
|
{
|
||||||
|
using Q = QskTextArea;
|
||||||
|
using SK = QskTextAreaSkinlet;
|
||||||
|
|
||||||
|
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignTop );
|
||||||
|
setAlignment( Q::PlaceholderText, Qt::AlignLeft | Qt::AlignTop );
|
||||||
|
|
||||||
|
setupTextControl< Q, SK >();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextField()
|
||||||
|
{
|
||||||
|
using Q = QskTextField;
|
||||||
|
using SK = QskTextFieldSkinlet;
|
||||||
|
|
||||||
|
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
|
setAlignment( Q::PlaceholderText, Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
|
|
||||||
|
setupTextControl< Q, SK >();
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::setupProgressBar()
|
void Editor::setupProgressBar()
|
||||||
{
|
{
|
||||||
// indeterminate style is different: TODO ...
|
// indeterminate style is different: TODO ...
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include "QskMaterial3ProgressBarSkinlet.h"
|
#include "QskMaterial3ProgressBarSkinlet.h"
|
||||||
#include "QskMaterial3SliderSkinlet.h"
|
#include "QskMaterial3SliderSkinlet.h"
|
||||||
#include "QskMaterial3TextFieldSkinlet.h"
|
#include "QskMaterial3TextFieldSkinlet.h"
|
||||||
|
#include <QskTextEditSkinlet.h>
|
||||||
|
|
||||||
#include <QskSkinHintTableEditor.h>
|
#include <QskSkinHintTableEditor.h>
|
||||||
|
|
||||||
|
|
@ -46,6 +47,7 @@
|
||||||
#include <QskTabBar.h>
|
#include <QskTabBar.h>
|
||||||
#include <QskTabButton.h>
|
#include <QskTabButton.h>
|
||||||
#include <QskTabView.h>
|
#include <QskTabView.h>
|
||||||
|
#include <QskTextArea.h>
|
||||||
#include <QskTextField.h>
|
#include <QskTextField.h>
|
||||||
#include <QskTextLabel.h>
|
#include <QskTextLabel.h>
|
||||||
#include <QskVirtualKeyboard.h>
|
#include <QskVirtualKeyboard.h>
|
||||||
|
|
@ -185,6 +187,10 @@ namespace
|
||||||
Q_INVOKABLE void setupTabButton();
|
Q_INVOKABLE void setupTabButton();
|
||||||
Q_INVOKABLE void setupTabBar();
|
Q_INVOKABLE void setupTabBar();
|
||||||
Q_INVOKABLE void setupTabView();
|
Q_INVOKABLE void setupTabView();
|
||||||
|
|
||||||
|
template< typename Q, typename SK >
|
||||||
|
void setupTextControl();
|
||||||
|
Q_INVOKABLE void setupTextArea();
|
||||||
Q_INVOKABLE void setupTextField();
|
Q_INVOKABLE void setupTextField();
|
||||||
Q_INVOKABLE void setupTextLabel();
|
Q_INVOKABLE void setupTextLabel();
|
||||||
|
|
||||||
|
|
@ -431,11 +437,9 @@ void Editor::setupTextLabel()
|
||||||
setPadding( Q::Panel, 5_px );
|
setPadding( Q::Panel, 5_px );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupTextField()
|
template< typename Q, typename SK >
|
||||||
|
void Editor::setupTextControl()
|
||||||
{
|
{
|
||||||
using Q = QskTextField;
|
|
||||||
using SK = QskTextInputSkinlet;
|
|
||||||
|
|
||||||
setStrutSize( Q::Panel, -1.0, 56_px );
|
setStrutSize( Q::Panel, -1.0, 56_px );
|
||||||
setPadding( Q::Panel, { 12_px, 8_px, 12_px, 8_px } );
|
setPadding( Q::Panel, { 12_px, 8_px, 12_px, 8_px } );
|
||||||
setGradient( Q::Panel, m_pal.surfaceVariant );
|
setGradient( Q::Panel, m_pal.surfaceVariant );
|
||||||
|
|
@ -457,7 +461,6 @@ void Editor::setupTextField()
|
||||||
|
|
||||||
setColor( Q::Text, m_pal.onSurface );
|
setColor( Q::Text, m_pal.onSurface );
|
||||||
setFontRole( Q::Text, BodyLarge );
|
setFontRole( Q::Text, BodyLarge );
|
||||||
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignVCenter );
|
|
||||||
|
|
||||||
setAlignment( Q::PlaceholderText, Qt::AlignLeft | Qt::AlignVCenter );
|
setAlignment( Q::PlaceholderText, Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
|
|
||||||
|
|
@ -474,6 +477,26 @@ void Editor::setupTextField()
|
||||||
setAlignment( Q::PlaceholderText, alignment( Q::Text ) );
|
setAlignment( Q::PlaceholderText, alignment( Q::Text ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextArea()
|
||||||
|
{
|
||||||
|
using Q = QskTextArea;
|
||||||
|
using SK = QskTextEditSkinlet;
|
||||||
|
|
||||||
|
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignTop );
|
||||||
|
|
||||||
|
setupTextControl< Q, SK >();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::setupTextField()
|
||||||
|
{
|
||||||
|
using Q = QskTextField;
|
||||||
|
using SK = QskTextInputSkinlet;
|
||||||
|
|
||||||
|
setAlignment( Q::Text, Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
|
|
||||||
|
setupTextControl< Q, SK >();
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::setupProgressBar()
|
void Editor::setupProgressBar()
|
||||||
{
|
{
|
||||||
using A = QskAspect;
|
using A = QskAspect;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <QskGridBox.h>
|
#include <QskGridBox.h>
|
||||||
#include <QskSlider.h>
|
#include <QskSlider.h>
|
||||||
|
#include <QskTextArea.h>
|
||||||
#include <QskTextField.h>
|
#include <QskTextField.h>
|
||||||
#include <QskSpinBox.h>
|
#include <QskSpinBox.h>
|
||||||
|
|
||||||
|
|
@ -92,6 +93,22 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextAreaBox : public QskLinearBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextAreaBox( QQuickItem* parent = nullptr )
|
||||||
|
: QskLinearBox( Qt::Horizontal, parent )
|
||||||
|
{
|
||||||
|
setSpacing( 20 );
|
||||||
|
|
||||||
|
{
|
||||||
|
auto textArea = new QskTextArea( "here enter longer text", this );
|
||||||
|
textArea->setWrapMode( QskTextOptions::Wrap );
|
||||||
|
textArea->setPlaceholderText( "placeholder text" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
InputPage::InputPage( QQuickItem* parent )
|
InputPage::InputPage( QQuickItem* parent )
|
||||||
|
|
@ -123,6 +140,8 @@ InputPage::InputPage( QQuickItem* parent )
|
||||||
auto textInputBox = new TextInputBox();
|
auto textInputBox = new TextInputBox();
|
||||||
textInputBox->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
|
textInputBox->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
|
auto textAreaBox = new TextAreaBox();
|
||||||
|
|
||||||
auto vBox = new QskLinearBox( Qt::Vertical );
|
auto vBox = new QskLinearBox( Qt::Vertical );
|
||||||
vBox->setSpacing( 30 );
|
vBox->setSpacing( 30 );
|
||||||
vBox->setExtraSpacingAt( Qt::RightEdge | Qt::BottomEdge );
|
vBox->setExtraSpacingAt( Qt::RightEdge | Qt::BottomEdge );
|
||||||
|
|
@ -130,8 +149,9 @@ InputPage::InputPage( QQuickItem* parent )
|
||||||
vBox->addItem( sliders[0].continous );
|
vBox->addItem( sliders[0].continous );
|
||||||
vBox->addItem( sliders[0].discrete );
|
vBox->addItem( sliders[0].discrete );
|
||||||
vBox->addItem( sliders[0].centered );
|
vBox->addItem( sliders[0].centered );
|
||||||
vBox->addItem( textInputBox );
|
|
||||||
vBox->addItem( spinBox );
|
vBox->addItem( spinBox );
|
||||||
|
vBox->addItem( textInputBox );
|
||||||
|
vBox->addItem( textAreaBox );
|
||||||
|
|
||||||
auto mainBox = new QskLinearBox( Qt::Horizontal, this );
|
auto mainBox = new QskLinearBox( Qt::Horizontal, this );
|
||||||
mainBox->setSpacing( 30 );
|
mainBox->setSpacing( 30 );
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,10 @@ list(APPEND HEADERS
|
||||||
controls/QskTabButtonSkinlet.h
|
controls/QskTabButtonSkinlet.h
|
||||||
controls/QskTabView.h
|
controls/QskTabView.h
|
||||||
controls/QskTabViewSkinlet.h
|
controls/QskTabViewSkinlet.h
|
||||||
|
controls/QskTextArea.h
|
||||||
|
controls/QskTextAreaSkinlet.h
|
||||||
|
controls/QskTextEdit.h
|
||||||
|
controls/QskTextEditSkinlet.h
|
||||||
controls/QskTextField.h
|
controls/QskTextField.h
|
||||||
controls/QskTextFieldSkinlet.h
|
controls/QskTextFieldSkinlet.h
|
||||||
controls/QskTextInput.h
|
controls/QskTextInput.h
|
||||||
|
|
@ -391,6 +395,10 @@ list(APPEND SOURCES
|
||||||
controls/QskTabButtonSkinlet.cpp
|
controls/QskTabButtonSkinlet.cpp
|
||||||
controls/QskTabView.cpp
|
controls/QskTabView.cpp
|
||||||
controls/QskTabViewSkinlet.cpp
|
controls/QskTabViewSkinlet.cpp
|
||||||
|
controls/QskTextArea.cpp
|
||||||
|
controls/QskTextAreaSkinlet.cpp
|
||||||
|
controls/QskTextEdit.cpp
|
||||||
|
controls/QskTextEditSkinlet.cpp
|
||||||
controls/QskTextField.cpp
|
controls/QskTextField.cpp
|
||||||
controls/QskTextFieldSkinlet.cpp
|
controls/QskTextFieldSkinlet.cpp
|
||||||
controls/QskTextInput.cpp
|
controls/QskTextInput.cpp
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,12 @@
|
||||||
#include "QskTextLabel.h"
|
#include "QskTextLabel.h"
|
||||||
#include "QskTextLabelSkinlet.h"
|
#include "QskTextLabelSkinlet.h"
|
||||||
|
|
||||||
|
#include "QskTextArea.h"
|
||||||
|
#include "QskTextAreaSkinlet.h"
|
||||||
|
|
||||||
|
#include "QskTextEdit.h"
|
||||||
|
#include "QskTextEditSkinlet.h"
|
||||||
|
|
||||||
#include "QskTextField.h"
|
#include "QskTextField.h"
|
||||||
#include "QskTextFieldSkinlet.h"
|
#include "QskTextFieldSkinlet.h"
|
||||||
|
|
||||||
|
|
@ -211,6 +217,7 @@ QskSkin::QskSkin( QObject* parent )
|
||||||
declareSkinlet< QskTabButton, QskTabButtonSkinlet >();
|
declareSkinlet< QskTabButton, QskTabButtonSkinlet >();
|
||||||
declareSkinlet< QskTabView, QskTabViewSkinlet >();
|
declareSkinlet< QskTabView, QskTabViewSkinlet >();
|
||||||
declareSkinlet< QskTextLabel, QskTextLabelSkinlet >();
|
declareSkinlet< QskTextLabel, QskTextLabelSkinlet >();
|
||||||
|
declareSkinlet< QskTextArea, QskTextAreaSkinlet >();
|
||||||
declareSkinlet< QskTextField, QskTextFieldSkinlet >();
|
declareSkinlet< QskTextField, QskTextFieldSkinlet >();
|
||||||
declareSkinlet< QskProgressBar, QskProgressBarSkinlet >();
|
declareSkinlet< QskProgressBar, QskProgressBarSkinlet >();
|
||||||
declareSkinlet< QskProgressRing, QskProgressRingSkinlet >();
|
declareSkinlet< QskProgressRing, QskProgressRingSkinlet >();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskTextArea.h"
|
||||||
|
|
||||||
|
QSK_SUBCONTROL( QskTextArea, Panel )
|
||||||
|
QSK_SUBCONTROL( QskTextArea, PlaceholderText )
|
||||||
|
|
||||||
|
class QskTextArea::PrivateData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString placeholderText;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskTextArea::QskTextArea( QQuickItem* parent )
|
||||||
|
: Inherited( parent )
|
||||||
|
, m_data( new PrivateData() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextArea::QskTextArea( const QString& text, QQuickItem* parent )
|
||||||
|
: QskTextArea( parent )
|
||||||
|
{
|
||||||
|
setText( text );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextArea::~QskTextArea()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextArea::setPlaceholderText( const QString& text )
|
||||||
|
{
|
||||||
|
if ( m_data->placeholderText != text )
|
||||||
|
{
|
||||||
|
m_data->placeholderText = text;
|
||||||
|
Q_EMIT placeholderTextChanged( text );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QskTextArea::placeholderText() const
|
||||||
|
{
|
||||||
|
return m_data->placeholderText;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskTextArea.cpp"
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_TEXT_AREA_H
|
||||||
|
#define QSK_TEXT_AREA_H
|
||||||
|
|
||||||
|
#include "QskTextEdit.h"
|
||||||
|
|
||||||
|
class QSK_EXPORT QskTextArea : public QskTextEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY( QString placeholderText READ placeholderText
|
||||||
|
WRITE setPlaceholderText NOTIFY placeholderTextChanged )
|
||||||
|
|
||||||
|
using Inherited = QskTextEdit;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSK_SUBCONTROLS( Panel, PlaceholderText )
|
||||||
|
|
||||||
|
QskTextArea( QQuickItem* parent = nullptr );
|
||||||
|
QskTextArea( const QString& text, QQuickItem* parent = nullptr );
|
||||||
|
|
||||||
|
~QskTextArea() override;
|
||||||
|
|
||||||
|
void setPlaceholderText( const QString& );
|
||||||
|
QString placeholderText() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void placeholderTextChanged( const QString& );
|
||||||
|
|
||||||
|
private:
|
||||||
|
class PrivateData;
|
||||||
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskTextAreaSkinlet.h"
|
||||||
|
#include "QskTextArea.h"
|
||||||
|
|
||||||
|
using Q = QskTextArea;
|
||||||
|
|
||||||
|
QskTextAreaSkinlet::QskTextAreaSkinlet( QskSkin* skin )
|
||||||
|
: Inherited( skin )
|
||||||
|
{
|
||||||
|
setNodeRoles( { PanelRole, TextPanelRole, PlaceholderTextRole } );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextAreaSkinlet::~QskTextAreaSkinlet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskTextAreaSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
|
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
||||||
|
{
|
||||||
|
if ( subControl == Q::Panel )
|
||||||
|
return contentsRect;
|
||||||
|
|
||||||
|
if ( subControl == Q::TextPanel )
|
||||||
|
return skinnable->subControlContentsRect( contentsRect, Q::Panel );
|
||||||
|
|
||||||
|
if ( subControl == Q::PlaceholderText )
|
||||||
|
{
|
||||||
|
const auto textArea = static_cast< const QskTextArea* >( skinnable );
|
||||||
|
if( textArea->text().isEmpty() )
|
||||||
|
return subControlRect( skinnable, contentsRect, Q::Text );
|
||||||
|
|
||||||
|
return QRectF();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode* QskTextAreaSkinlet::updateSubNode(
|
||||||
|
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||||
|
{
|
||||||
|
const auto textArea = static_cast< const QskTextArea* >( skinnable );
|
||||||
|
|
||||||
|
switch ( nodeRole )
|
||||||
|
{
|
||||||
|
case PanelRole:
|
||||||
|
{
|
||||||
|
return updateBoxNode( skinnable, node, Q::Panel );
|
||||||
|
}
|
||||||
|
|
||||||
|
case PlaceholderTextRole:
|
||||||
|
{
|
||||||
|
const auto text = effectivePlaceholderText( textArea );
|
||||||
|
if ( text.isEmpty() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto subControl = Q::PlaceholderText;
|
||||||
|
|
||||||
|
QskSkinHintStatus status;
|
||||||
|
|
||||||
|
auto options = skinnable->textOptionsHint( subControl, &status );
|
||||||
|
if ( !status.isValid() )
|
||||||
|
options.setElideMode( Qt::ElideRight );
|
||||||
|
|
||||||
|
return updateTextNode( skinnable, node,
|
||||||
|
textArea->subControlRect( subControl ),
|
||||||
|
textArea->alignmentHint( subControl, Qt::AlignLeft ),
|
||||||
|
options, text, subControl );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF QskTextAreaSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||||
|
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||||
|
{
|
||||||
|
if ( which != Qt::PreferredSize )
|
||||||
|
return QSizeF();
|
||||||
|
|
||||||
|
auto hint = Inherited::sizeHint( skinnable, which, constraint );
|
||||||
|
hint = skinnable->outerBoxSize( Q::Panel, hint );
|
||||||
|
hint = hint.expandedTo( skinnable->strutSizeHint( Q::Panel ) );
|
||||||
|
|
||||||
|
return hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QskTextAreaSkinlet::effectivePlaceholderText(
|
||||||
|
const QskTextArea* textArea ) const
|
||||||
|
{
|
||||||
|
if ( textArea->text().isEmpty() &&
|
||||||
|
!( textArea->isReadOnly() || textArea->isEditing() ) )
|
||||||
|
{
|
||||||
|
return textArea->placeholderText();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskTextAreaSkinlet.cpp"
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_TEXT_AREA_SKINLET_H
|
||||||
|
#define QSK_TEXT_AREA_SKINLET_H
|
||||||
|
|
||||||
|
#include "QskTextEditSkinlet.h"
|
||||||
|
|
||||||
|
class QskTextArea;
|
||||||
|
|
||||||
|
class QSK_EXPORT QskTextAreaSkinlet : public QskTextEditSkinlet
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
using Inherited = QskTextEditSkinlet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum NodeRole : quint8
|
||||||
|
{
|
||||||
|
PanelRole = Inherited::RoleCount,
|
||||||
|
|
||||||
|
PlaceholderTextRole,
|
||||||
|
RoleCount
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_INVOKABLE QskTextAreaSkinlet( QskSkin* = nullptr );
|
||||||
|
~QskTextAreaSkinlet() override;
|
||||||
|
|
||||||
|
QRectF subControlRect( const QskSkinnable*,
|
||||||
|
const QRectF& rect, QskAspect::Subcontrol ) const override;
|
||||||
|
|
||||||
|
QSizeF sizeHint( const QskSkinnable*,
|
||||||
|
Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QSGNode* updateSubNode( const QskSkinnable*,
|
||||||
|
quint8 nodeRole, QSGNode* ) const override;
|
||||||
|
|
||||||
|
virtual QString effectivePlaceholderText( const QskTextArea* ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,758 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskTextEdit.h"
|
||||||
|
#include "QskTextEditSkinlet.h"
|
||||||
|
#include "QskFontRole.h"
|
||||||
|
#include "QskInternalMacros.h"
|
||||||
|
#include "QskQuick.h"
|
||||||
|
|
||||||
|
QSK_QT_PRIVATE_BEGIN
|
||||||
|
#include <private/qquicktextedit_p.h>
|
||||||
|
#include <private/qquicktextedit_p_p.h>
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
#include <private/qeventpoint_p.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
QSK_SUBCONTROL( QskTextEdit, TextPanel )
|
||||||
|
QSK_SUBCONTROL( QskTextEdit, Text )
|
||||||
|
|
||||||
|
QSK_SYSTEM_STATE( QskTextEdit, ReadOnly, QskAspect::FirstSystemState << 1 )
|
||||||
|
QSK_SYSTEM_STATE( QskTextEdit, Editing, QskAspect::FirstSystemState << 2 )
|
||||||
|
QSK_SYSTEM_STATE( QskTextEdit, Error, QskAspect::FirstSystemState << 4 )
|
||||||
|
|
||||||
|
static inline void qskPropagateReadOnly( QskTextEdit* edit )
|
||||||
|
{
|
||||||
|
Q_EMIT edit->readOnlyChanged( edit->isReadOnly() );
|
||||||
|
|
||||||
|
QEvent event( QEvent::ReadOnlyChange );
|
||||||
|
QCoreApplication::sendEvent( edit, &event );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void qskTranslateMouseEventPosition(
|
||||||
|
QMouseEvent* mouseEvent, const QPointF& offset )
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
auto& point = mouseEvent->point( 0 );
|
||||||
|
|
||||||
|
QMutableEventPoint::setPosition(
|
||||||
|
point, point.position() + offset );
|
||||||
|
#else
|
||||||
|
mouseEvent->setLocalPos( mouseEvent->localPos() + offset );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void qskBindSignals(
|
||||||
|
const QQuickTextEdit* wrappedEdit, QskTextEdit* edit )
|
||||||
|
{
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::textChanged,
|
||||||
|
edit, [ edit ] { Q_EMIT edit->textChanged( edit->text() ); } );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::preeditTextChanged,
|
||||||
|
edit, [ edit ] { Q_EMIT edit->preeditTextChanged( edit->preeditText() ); } );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::readOnlyChanged,
|
||||||
|
edit, [ edit ] { qskPropagateReadOnly( edit ); } );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::overwriteModeChanged,
|
||||||
|
edit, &QskTextEdit::overwriteModeChanged );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::wrapModeChanged,
|
||||||
|
edit, [ edit ] { Q_EMIT edit->wrapModeChanged( edit->wrapMode() ); } );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::lineCountChanged,
|
||||||
|
[ edit ] { Q_EMIT edit->lineCountChanged( edit->lineCount() ); } );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::textFormatChanged,
|
||||||
|
edit, [ edit ]( QQuickTextEdit::TextFormat format )
|
||||||
|
{
|
||||||
|
Q_EMIT edit->textFormatChanged( static_cast< QskTextOptions::TextFormat >( format ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::selectByMouseChanged,
|
||||||
|
edit, &QskTextEdit::selectByMouseChanged );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickTextEdit::tabStopDistanceChanged,
|
||||||
|
edit, &QskTextEdit::tabStopDistanceChanged );
|
||||||
|
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickItem::implicitWidthChanged,
|
||||||
|
edit, &QskControl::resetImplicitSize );
|
||||||
|
|
||||||
|
QObject::connect( wrappedEdit, &QQuickItem::implicitHeightChanged,
|
||||||
|
edit, &QskControl::resetImplicitSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class QuickTextEdit final : public QQuickTextEdit
|
||||||
|
{
|
||||||
|
using Inherited = QQuickTextEdit;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QuickTextEdit( QskTextEdit* );
|
||||||
|
|
||||||
|
void setEditing( bool on );
|
||||||
|
|
||||||
|
inline void setAlignment( Qt::Alignment alignment )
|
||||||
|
{
|
||||||
|
setHAlign( ( HAlignment ) ( int( alignment ) & 0x0f ) );
|
||||||
|
setVAlign( ( VAlignment ) ( int( alignment ) & 0xf0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateColors();
|
||||||
|
void updateMetrics();
|
||||||
|
|
||||||
|
inline bool handleEvent( QEvent* event )
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
switch( static_cast< int >( event->type() ) )
|
||||||
|
{
|
||||||
|
case QEvent::MouseButtonDblClick:
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
case QEvent::MouseMove:
|
||||||
|
{
|
||||||
|
auto mouseEvent = static_cast< QMouseEvent* >( event );
|
||||||
|
|
||||||
|
/*
|
||||||
|
As the event was sent for the parent item
|
||||||
|
we have to translate the position into
|
||||||
|
our coordinate system.
|
||||||
|
*/
|
||||||
|
qskTranslateMouseEventPosition( mouseEvent, -position() );
|
||||||
|
ok = this->event( mouseEvent );
|
||||||
|
qskTranslateMouseEventPosition( mouseEvent, position() );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ok = this->event( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool hasSelectedText() const
|
||||||
|
{
|
||||||
|
return !selectedText().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
void geometryChange(
|
||||||
|
const QRectF& newGeometry, const QRectF& oldGeometry ) override
|
||||||
|
{
|
||||||
|
Inherited::geometryChange( newGeometry, oldGeometry );
|
||||||
|
updateClip();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void geometryChanged(
|
||||||
|
const QRectF& newGeometry, const QRectF& oldGeometry ) override
|
||||||
|
{
|
||||||
|
Inherited::geometryChanged( newGeometry, oldGeometry );
|
||||||
|
updateClip();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void updateClip()
|
||||||
|
{
|
||||||
|
setClip( ( contentWidth() > width() ) ||
|
||||||
|
( contentHeight() > height() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode* updatePaintNode(
|
||||||
|
QSGNode* oldNode, UpdatePaintNodeData* data ) override
|
||||||
|
{
|
||||||
|
updateColors();
|
||||||
|
return Inherited::updatePaintNode( oldNode, data );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QuickTextEdit::QuickTextEdit( QskTextEdit* textField )
|
||||||
|
: QQuickTextEdit( textField )
|
||||||
|
{
|
||||||
|
classBegin();
|
||||||
|
|
||||||
|
setActiveFocusOnTab( false );
|
||||||
|
setFlag( ItemAcceptsInputMethod, false );
|
||||||
|
setFocusOnPress( false );
|
||||||
|
setSelectByMouse( true );
|
||||||
|
|
||||||
|
componentComplete();
|
||||||
|
|
||||||
|
connect( this, &QuickTextEdit::contentSizeChanged,
|
||||||
|
this, &QuickTextEdit::updateClip );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickTextEdit::setEditing( bool on )
|
||||||
|
{
|
||||||
|
auto d = QQuickTextEditPrivate::get( this );
|
||||||
|
|
||||||
|
if ( d->cursorVisible == on )
|
||||||
|
return;
|
||||||
|
|
||||||
|
setCursorVisible( on );
|
||||||
|
|
||||||
|
polish();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickTextEdit::updateMetrics()
|
||||||
|
{
|
||||||
|
auto textEdit = static_cast< const QskTextEdit* >( parentItem() );
|
||||||
|
|
||||||
|
setAlignment( textEdit->alignment() );
|
||||||
|
setFont( textEdit->font() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickTextEdit::updateColors()
|
||||||
|
{
|
||||||
|
using Q = QskTextEdit;
|
||||||
|
|
||||||
|
auto input = static_cast< const Q* >( parentItem() );
|
||||||
|
|
||||||
|
setColor( input->color( Q::Text ) );
|
||||||
|
|
||||||
|
const auto state = QskTextEditSkinlet::Selected;
|
||||||
|
|
||||||
|
setSelectionColor( input->color( Q::TextPanel | state ) );
|
||||||
|
setSelectedTextColor( input->color( Q::Text | state ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class QskTextEdit::PrivateData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QuickTextEdit* wrappedEdit;
|
||||||
|
|
||||||
|
ActivationModes activationModes;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskTextEdit::QskTextEdit( QQuickItem* parent )
|
||||||
|
: Inherited( parent )
|
||||||
|
, m_data( new PrivateData() )
|
||||||
|
{
|
||||||
|
m_data->activationModes = ActivationOnMouse | ActivationOnKey;
|
||||||
|
|
||||||
|
setPolishOnResize( true );
|
||||||
|
|
||||||
|
setAcceptHoverEvents( true );
|
||||||
|
setFocusPolicy( Qt::StrongFocus );
|
||||||
|
|
||||||
|
setFlag( QQuickItem::ItemAcceptsInputMethod );
|
||||||
|
|
||||||
|
/*
|
||||||
|
QQuickTextEdit is a beast of almost 3.5k lines of code, we don't
|
||||||
|
want to reimplement that - at least not now.
|
||||||
|
So this is more or less a simple wrapper making everything
|
||||||
|
conforming to qskinny.
|
||||||
|
*/
|
||||||
|
|
||||||
|
m_data->wrappedEdit = new QuickTextEdit( this );
|
||||||
|
qskBindSignals( m_data->wrappedEdit, this );
|
||||||
|
|
||||||
|
setAcceptedMouseButtons( m_data->wrappedEdit->acceptedMouseButtons() );
|
||||||
|
m_data->wrappedEdit->setAcceptedMouseButtons( Qt::NoButton );
|
||||||
|
|
||||||
|
initSizePolicy( QskSizePolicy::Expanding, QskSizePolicy::Expanding );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextEdit::~QskTextEdit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTextEdit::event( QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::ShortcutOverride )
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->handleEvent( event );
|
||||||
|
}
|
||||||
|
else if ( event->type() == QEvent::LocaleChange )
|
||||||
|
{
|
||||||
|
qskUpdateInputMethod( this, Qt::ImPreferredLanguage );
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::event( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::keyPressEvent( QKeyEvent* event )
|
||||||
|
{
|
||||||
|
if ( isEditing() )
|
||||||
|
{
|
||||||
|
switch ( event->key() )
|
||||||
|
{
|
||||||
|
case Qt::Key_Enter:
|
||||||
|
case Qt::Key_Return:
|
||||||
|
{
|
||||||
|
QGuiApplication::inputMethod()->commit();
|
||||||
|
|
||||||
|
if ( !( inputMethodHints() & Qt::ImhMultiLine ) )
|
||||||
|
{
|
||||||
|
setEditing( false );
|
||||||
|
|
||||||
|
// When returning from a virtual keyboard
|
||||||
|
qskForceActiveFocus( this, Qt::PopupFocusReason );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
case Qt::Key_Escape:
|
||||||
|
{
|
||||||
|
setEditing( false );
|
||||||
|
qskForceActiveFocus( this, Qt::PopupFocusReason );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->handleEvent( event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ( m_data->activationModes & ActivationOnKey ) && !event->isAutoRepeat() )
|
||||||
|
{
|
||||||
|
if ( event->key() == Qt::Key_Select || event->key() == Qt::Key_Space )
|
||||||
|
{
|
||||||
|
setEditing( true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Inherited::keyPressEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::keyReleaseEvent( QKeyEvent* event )
|
||||||
|
{
|
||||||
|
Inherited::keyReleaseEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::mousePressEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->handleEvent( event );
|
||||||
|
|
||||||
|
if ( !isReadOnly() && !qGuiApp->styleHints()->setFocusOnTouchRelease() )
|
||||||
|
setEditing( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::mouseMoveEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->handleEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::mouseReleaseEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->handleEvent( event );
|
||||||
|
|
||||||
|
if ( !isReadOnly() && qGuiApp->styleHints()->setFocusOnTouchRelease() )
|
||||||
|
setEditing( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::mouseDoubleClickEvent( QMouseEvent* event )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->handleEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::inputMethodEvent( QInputMethodEvent* event )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->handleEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::focusInEvent( QFocusEvent* event )
|
||||||
|
{
|
||||||
|
if ( m_data->activationModes & ActivationOnFocus )
|
||||||
|
{
|
||||||
|
switch ( event->reason() )
|
||||||
|
{
|
||||||
|
case Qt::ActiveWindowFocusReason:
|
||||||
|
case Qt::PopupFocusReason:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
#if 1
|
||||||
|
// auto selecting the complete text ???
|
||||||
|
#endif
|
||||||
|
setEditing( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Inherited::focusInEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::focusOutEvent( QFocusEvent* event )
|
||||||
|
{
|
||||||
|
switch ( event->reason() )
|
||||||
|
{
|
||||||
|
case Qt::ActiveWindowFocusReason:
|
||||||
|
case Qt::PopupFocusReason:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->deselect();
|
||||||
|
setEditing( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Inherited::focusOutEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::updateLayout()
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->updateMetrics();
|
||||||
|
qskSetItemGeometry( m_data->wrappedEdit, subControlRect( Text ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::updateNode( QSGNode* node )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->updateColors();
|
||||||
|
Inherited::updateNode( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QskTextEdit::text() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setText( const QString& text )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setText( text );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::clear()
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::selectAll()
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextEdit::ActivationModes QskTextEdit::activationModes() const
|
||||||
|
{
|
||||||
|
return static_cast< QskTextEdit::ActivationModes >( m_data->activationModes );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setActivationModes( ActivationModes modes )
|
||||||
|
{
|
||||||
|
if ( static_cast< ActivationModes >( m_data->activationModes ) != modes )
|
||||||
|
{
|
||||||
|
m_data->activationModes = modes;
|
||||||
|
Q_EMIT activationModesChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void qskUpdateInputMethodFont( const QskTextEdit* input )
|
||||||
|
{
|
||||||
|
const auto queries = Qt::ImCursorRectangle | Qt::ImFont | Qt::ImAnchorRectangle;
|
||||||
|
qskUpdateInputMethod( input, queries );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setFontRole( const QskFontRole& role )
|
||||||
|
{
|
||||||
|
if ( setFontRoleHint( Text, role ) )
|
||||||
|
{
|
||||||
|
qskUpdateInputMethodFont( this );
|
||||||
|
Q_EMIT fontRoleChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::resetFontRole()
|
||||||
|
{
|
||||||
|
if ( resetFontRoleHint( Text ) )
|
||||||
|
{
|
||||||
|
qskUpdateInputMethodFont( this );
|
||||||
|
Q_EMIT fontRoleChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QskFontRole QskTextEdit::fontRole() const
|
||||||
|
{
|
||||||
|
return fontRoleHint( Text );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setAlignment( Qt::Alignment alignment )
|
||||||
|
{
|
||||||
|
if ( setAlignmentHint( Text, alignment ) )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setAlignment( alignment );
|
||||||
|
Q_EMIT alignmentChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::resetAlignment()
|
||||||
|
{
|
||||||
|
if ( resetAlignmentHint( Text ) )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setAlignment( alignment() );
|
||||||
|
Q_EMIT alignmentChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::Alignment QskTextEdit::alignment() const
|
||||||
|
{
|
||||||
|
return alignmentHint( Text, Qt::AlignLeft | Qt::AlignTop );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setWrapMode( QskTextOptions::WrapMode wrapMode )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setWrapMode(
|
||||||
|
static_cast< QQuickTextEdit::WrapMode >( wrapMode ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextOptions::WrapMode QskTextEdit::wrapMode() const
|
||||||
|
{
|
||||||
|
return static_cast< QskTextOptions::WrapMode >(
|
||||||
|
m_data->wrappedEdit->wrapMode() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setSelectByMouse( bool on )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setSelectByMouse( on );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTextEdit::selectByMouse() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->selectByMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
QFont QskTextEdit::font() const
|
||||||
|
{
|
||||||
|
return effectiveFont( QskTextEdit::Text );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTextEdit::isReadOnly() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->isReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setReadOnly( bool on )
|
||||||
|
{
|
||||||
|
auto edit = m_data->wrappedEdit;
|
||||||
|
|
||||||
|
if ( edit->isReadOnly() == on )
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// do we want to be able to restore the previous policy ?
|
||||||
|
setFocusPolicy( Qt::NoFocus );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
edit->setReadOnly( on );
|
||||||
|
|
||||||
|
// we are killing user settings here ?
|
||||||
|
edit->setFlag( QQuickItem::ItemAcceptsInputMethod, !on );
|
||||||
|
qskUpdateInputMethod( this, Qt::ImEnabled );
|
||||||
|
|
||||||
|
setSkinStateFlag( ReadOnly, on );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setEditing( bool on )
|
||||||
|
{
|
||||||
|
if ( isReadOnly() || on == isEditing() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
setSkinStateFlag( Editing, on );
|
||||||
|
m_data->wrappedEdit->setEditing( on );
|
||||||
|
|
||||||
|
if ( on )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
updateInputMethod( Qt::ImCursorRectangle | Qt::ImAnchorRectangle );
|
||||||
|
QGuiApplication::inputMethod()->inputDirection
|
||||||
|
#endif
|
||||||
|
qskInputMethodSetVisible( this, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Q_EMIT m_data->wrappedEdit->editingFinished();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
inputMethod->reset();
|
||||||
|
#endif
|
||||||
|
qskInputMethodSetVisible( this, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT editingChanged( on );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTextEdit::isEditing() const
|
||||||
|
{
|
||||||
|
return hasSkinState( Editing );
|
||||||
|
}
|
||||||
|
|
||||||
|
int QskTextEdit::cursorPosition() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->cursorPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setCursorPosition( int pos )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setCursorPosition( pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QskTextEdit::preeditText() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->preeditText();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTextEdit::overwriteMode() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->overwriteMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setOverwriteMode( bool overwrite )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setOverwriteMode( overwrite );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setTextFormat( QskTextOptions::TextFormat textFormat )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setTextFormat(
|
||||||
|
static_cast< QQuickTextEdit::TextFormat >( textFormat ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextOptions::TextFormat QskTextEdit::textFormat() const
|
||||||
|
{
|
||||||
|
return static_cast< QskTextOptions::TextFormat >(
|
||||||
|
m_data->wrappedEdit->textFormat() );
|
||||||
|
}
|
||||||
|
|
||||||
|
int QskTextEdit::lineCount() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->lineCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QskTextEdit::inputMethodQuery(
|
||||||
|
Qt::InputMethodQuery property ) const
|
||||||
|
{
|
||||||
|
return inputMethodQuery( property, QVariant() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant QskTextEdit::inputMethodQuery(
|
||||||
|
Qt::InputMethodQuery query, const QVariant& argument ) const
|
||||||
|
{
|
||||||
|
switch ( query )
|
||||||
|
{
|
||||||
|
case Qt::ImEnabled:
|
||||||
|
{
|
||||||
|
return QVariant( ( bool ) ( flags() & ItemAcceptsInputMethod ) );
|
||||||
|
}
|
||||||
|
case Qt::ImFont:
|
||||||
|
{
|
||||||
|
return font();
|
||||||
|
}
|
||||||
|
case Qt::ImPreferredLanguage:
|
||||||
|
{
|
||||||
|
return locale();
|
||||||
|
}
|
||||||
|
case Qt::ImInputItemClipRectangle:
|
||||||
|
case Qt::ImCursorRectangle:
|
||||||
|
{
|
||||||
|
QVariant v = m_data->wrappedEdit->inputMethodQuery( query, argument );
|
||||||
|
#if 1
|
||||||
|
if ( v.canConvert< QRectF >() )
|
||||||
|
v.setValue( v.toRectF().translated( m_data->wrappedEdit->position() ) );
|
||||||
|
#endif
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->inputMethodQuery( query, argument );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTextEdit::canUndo() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->canUndo();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskTextEdit::canRedo() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->canRedo();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::InputMethodHints QskTextEdit::inputMethodHints() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->inputMethodHints();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setInputMethodHints( Qt::InputMethodHints hints )
|
||||||
|
{
|
||||||
|
if ( m_data->wrappedEdit->inputMethodHints() != hints )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setInputMethodHints( hints );
|
||||||
|
qskUpdateInputMethod( this, Qt::ImHints );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int QskTextEdit::tabStopDistance() const
|
||||||
|
{
|
||||||
|
return m_data->wrappedEdit->tabStopDistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setTabStopDistance( qreal distance )
|
||||||
|
{
|
||||||
|
m_data->wrappedEdit->setTabStopDistance( distance );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskTextEdit::setupFrom( const QQuickItem* item )
|
||||||
|
{
|
||||||
|
if ( item == nullptr )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// finding attributes from the input hints of item
|
||||||
|
|
||||||
|
int maxCharacters = 32767;
|
||||||
|
|
||||||
|
Qt::InputMethodQueries queries = Qt::ImQueryAll;
|
||||||
|
queries &= ~Qt::ImEnabled;
|
||||||
|
|
||||||
|
QInputMethodQueryEvent event( queries );
|
||||||
|
QCoreApplication::sendEvent( const_cast< QQuickItem* >( item ), &event );
|
||||||
|
|
||||||
|
if ( event.queries() & Qt::ImMaximumTextLength )
|
||||||
|
{
|
||||||
|
// needs to be handled before Qt::ImCursorPosition !
|
||||||
|
|
||||||
|
const auto max = event.value( Qt::ImMaximumTextLength ).toInt();
|
||||||
|
maxCharacters = qBound( 0, max, maxCharacters );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( event.queries() & Qt::ImSurroundingText )
|
||||||
|
{
|
||||||
|
const auto text = event.value( Qt::ImSurroundingText ).toString();
|
||||||
|
setText( text );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( event.queries() & Qt::ImCursorPosition )
|
||||||
|
{
|
||||||
|
const auto pos = event.value( Qt::ImCursorPosition ).toInt();
|
||||||
|
setCursorPosition( pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( event.queries() & Qt::ImCurrentSelection )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
const auto text = event.value( Qt::ImCurrentSelection ).toString();
|
||||||
|
if ( !text.isEmpty() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskTextEdit.cpp"
|
||||||
|
|
@ -0,0 +1,190 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_TEXT_EDIT_H
|
||||||
|
#define QSK_TEXT_EDIT_H
|
||||||
|
|
||||||
|
#include "QskControl.h"
|
||||||
|
#include "QskTextOptions.h"
|
||||||
|
|
||||||
|
class QValidator;
|
||||||
|
class QskFontRole;
|
||||||
|
|
||||||
|
class QSK_EXPORT QskTextEdit : public QskControl
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY( QString text READ text
|
||||||
|
WRITE setText NOTIFY textChanged USER true )
|
||||||
|
|
||||||
|
Q_PROPERTY( QskFontRole fontRole READ fontRole
|
||||||
|
WRITE setFontRole RESET resetFontRole NOTIFY fontRoleChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( QFont font READ font )
|
||||||
|
|
||||||
|
Q_PROPERTY( Qt::Alignment alignment READ alignment
|
||||||
|
WRITE setAlignment RESET resetAlignment NOTIFY alignmentChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( QskTextOptions::WrapMode wrapMode READ wrapMode
|
||||||
|
WRITE setWrapMode NOTIFY wrapModeChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( int lineCount READ lineCount NOTIFY lineCountChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( QskTextOptions::TextFormat textFormat READ textFormat
|
||||||
|
WRITE setTextFormat NOTIFY textFormatChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( ActivationModes activationModes READ activationModes
|
||||||
|
WRITE setActivationModes NOTIFY activationModesChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( bool selectByMouse READ selectByMouse
|
||||||
|
WRITE setSelectByMouse NOTIFY selectByMouseChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( bool editing READ isEditing
|
||||||
|
WRITE setEditing NOTIFY editingChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( qreal tabStopDistance READ tabStopDistance
|
||||||
|
WRITE setTabStopDistance NOTIFY tabStopDistanceChanged )
|
||||||
|
|
||||||
|
using Inherited = QskControl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSK_SUBCONTROLS( TextPanel, Text )
|
||||||
|
QSK_STATES( ReadOnly, Editing, Error )
|
||||||
|
|
||||||
|
enum ActivationMode
|
||||||
|
{
|
||||||
|
NoActivation,
|
||||||
|
|
||||||
|
ActivationOnFocus = 1 << 0,
|
||||||
|
ActivationOnMouse = 1 << 1,
|
||||||
|
ActivationOnKey = 1 << 2,
|
||||||
|
|
||||||
|
ActivationOnInput = ActivationOnMouse | ActivationOnKey,
|
||||||
|
ActivationOnAll = ActivationOnFocus | ActivationOnMouse | ActivationOnKey
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM( ActivationMode )
|
||||||
|
Q_DECLARE_FLAGS( ActivationModes, ActivationMode )
|
||||||
|
|
||||||
|
QskTextEdit( QQuickItem* parent = nullptr );
|
||||||
|
|
||||||
|
~QskTextEdit() override;
|
||||||
|
|
||||||
|
void setupFrom( const QQuickItem* );
|
||||||
|
|
||||||
|
QString text() const;
|
||||||
|
|
||||||
|
void setFontRole( const QskFontRole& role );
|
||||||
|
void resetFontRole();
|
||||||
|
QskFontRole fontRole() const;
|
||||||
|
|
||||||
|
void setAlignment( Qt::Alignment );
|
||||||
|
void resetAlignment();
|
||||||
|
Qt::Alignment alignment() const;
|
||||||
|
|
||||||
|
void setWrapMode( QskTextOptions::WrapMode );
|
||||||
|
QskTextOptions::WrapMode wrapMode() const;
|
||||||
|
|
||||||
|
void setTextFormat( QskTextOptions::TextFormat );
|
||||||
|
QskTextOptions::TextFormat textFormat() const;
|
||||||
|
|
||||||
|
int lineCount() const;
|
||||||
|
|
||||||
|
void setActivationModes( ActivationModes );
|
||||||
|
ActivationModes activationModes() const;
|
||||||
|
|
||||||
|
void setSelectByMouse( bool );
|
||||||
|
bool selectByMouse() const;
|
||||||
|
|
||||||
|
bool isEditing() const;
|
||||||
|
|
||||||
|
QFont font() const;
|
||||||
|
|
||||||
|
bool isReadOnly() const;
|
||||||
|
void setReadOnly( bool );
|
||||||
|
|
||||||
|
int cursorPosition() const;
|
||||||
|
void setCursorPosition( int );
|
||||||
|
|
||||||
|
QString preeditText() const;
|
||||||
|
|
||||||
|
bool overwriteMode() const;
|
||||||
|
void setOverwriteMode( bool );
|
||||||
|
|
||||||
|
QVariant inputMethodQuery( Qt::InputMethodQuery ) const override;
|
||||||
|
QVariant inputMethodQuery( Qt::InputMethodQuery, const QVariant& argument ) const;
|
||||||
|
|
||||||
|
bool canUndo() const;
|
||||||
|
bool canRedo() const;
|
||||||
|
|
||||||
|
Qt::InputMethodHints inputMethodHints() const;
|
||||||
|
void setInputMethodHints( Qt::InputMethodHints );
|
||||||
|
|
||||||
|
int tabStopDistance() const;
|
||||||
|
void setTabStopDistance( qreal );
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void clear();
|
||||||
|
void selectAll();
|
||||||
|
void setText( const QString& );
|
||||||
|
void setEditing( bool );
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void textChanged( const QString& );
|
||||||
|
void preeditTextChanged( const QString& );
|
||||||
|
|
||||||
|
void editingChanged( bool );
|
||||||
|
|
||||||
|
void activationModesChanged();
|
||||||
|
void readOnlyChanged( bool );
|
||||||
|
void panelChanged( bool );
|
||||||
|
|
||||||
|
void displayTextChanged( const QString& );
|
||||||
|
|
||||||
|
void textEdited( const QString& );
|
||||||
|
void placeholderTextChanged( const QString& );
|
||||||
|
|
||||||
|
void fontRoleChanged();
|
||||||
|
void alignmentChanged();
|
||||||
|
void wrapModeChanged( QskTextOptions::WrapMode );
|
||||||
|
|
||||||
|
void lineCountChanged( int );
|
||||||
|
|
||||||
|
void selectByMouseChanged( bool );
|
||||||
|
|
||||||
|
void textFormatChanged( QskTextOptions::TextFormat );
|
||||||
|
|
||||||
|
void overwriteModeChanged( bool );
|
||||||
|
|
||||||
|
void tabStopDistanceChanged( qreal );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool event( QEvent* ) override;
|
||||||
|
|
||||||
|
void inputMethodEvent( QInputMethodEvent* ) override;
|
||||||
|
|
||||||
|
void focusInEvent( QFocusEvent* ) override;
|
||||||
|
void focusOutEvent( QFocusEvent* ) override;
|
||||||
|
|
||||||
|
void mousePressEvent( QMouseEvent* ) override;
|
||||||
|
void mouseMoveEvent( QMouseEvent* ) override;
|
||||||
|
void mouseReleaseEvent( QMouseEvent* ) override;
|
||||||
|
void mouseDoubleClickEvent( QMouseEvent* ) override;
|
||||||
|
|
||||||
|
void keyPressEvent( QKeyEvent* ) override;
|
||||||
|
void keyReleaseEvent( QKeyEvent* ) override;
|
||||||
|
|
||||||
|
void updateLayout() override;
|
||||||
|
void updateNode( QSGNode* ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class PrivateData;
|
||||||
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS( QskTextEdit::ActivationModes )
|
||||||
|
Q_DECLARE_METATYPE( QskTextEdit::ActivationModes )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskTextEditSkinlet.h"
|
||||||
|
#include "QskTextEdit.h"
|
||||||
|
|
||||||
|
#include <qfontmetrics.h>
|
||||||
|
|
||||||
|
using Q = QskTextEdit;
|
||||||
|
|
||||||
|
QSK_SYSTEM_STATE( QskTextEditSkinlet, Selected, QskAspect::FirstSystemState << 3 )
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskTextEditSkinlet.cpp"
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) The authors
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_TEXT_EDIT_SKINLET_H
|
||||||
|
#define QSK_TEXT_EDIT_SKINLET_H
|
||||||
|
|
||||||
|
#include "QskSkinlet.h"
|
||||||
|
|
||||||
|
class QSK_EXPORT QskTextEditSkinlet : public QskSkinlet
|
||||||
|
{
|
||||||
|
using Inherited = QskSkinlet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSK_STATES( Selected )
|
||||||
|
|
||||||
|
enum NodeRole : quint8
|
||||||
|
{
|
||||||
|
TextPanelRole,
|
||||||
|
RoleCount
|
||||||
|
};
|
||||||
|
|
||||||
|
~QskTextEditSkinlet() override;
|
||||||
|
|
||||||
|
QRectF subControlRect( const QskSkinnable*,
|
||||||
|
const QRectF& rect, QskAspect::Subcontrol ) const override;
|
||||||
|
|
||||||
|
QSizeF sizeHint( const QskSkinnable*,
|
||||||
|
Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QskTextEditSkinlet( QskSkin* = nullptr );
|
||||||
|
|
||||||
|
QSGNode* updateSubNode( const QskSkinnable*,
|
||||||
|
quint8 nodeRole, QSGNode* ) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -236,7 +236,7 @@ namespace
|
||||||
const auto state = QskTextInputSkinlet::Selected;
|
const auto state = QskTextInputSkinlet::Selected;
|
||||||
|
|
||||||
setSelectionColor( input->color( Q::TextPanel | state ) );
|
setSelectionColor( input->color( Q::TextPanel | state ) );
|
||||||
setSelectedTextColor( input->color( QskTextInput::Text | state ) );
|
setSelectedTextColor( input->color( Q::Text | state ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue