text input: Add M3 outlined mode
This commit is contained in:
parent
0208573325
commit
59a42395b2
|
@ -451,12 +451,16 @@ void Editor::setupTextLabel()
|
||||||
void Editor::setupTextInput()
|
void Editor::setupTextInput()
|
||||||
{
|
{
|
||||||
using Q = QskTextInput;
|
using Q = QskTextInput;
|
||||||
|
using M3 = QskMaterial3Skin;
|
||||||
|
|
||||||
const QskStateCombination allStates( QskStateCombination::CombinationNoState, QskAspect::AllStates );
|
const QskStateCombination allStates( QskStateCombination::CombinationNoState, QskAspect::AllStates );
|
||||||
|
|
||||||
// Panel
|
// Panel
|
||||||
|
|
||||||
setStrutSize( Q::Panel, -1.0, 56_dp );
|
setStrutSize( Q::Panel, -1.0, 56_dp );
|
||||||
|
|
||||||
|
// Panel - Filled
|
||||||
|
|
||||||
setGradient( Q::Panel, m_pal.surfaceVariant );
|
setGradient( Q::Panel, m_pal.surfaceVariant );
|
||||||
|
|
||||||
setBoxShape( Q::Panel, m_pal.shapeExtraSmallTop );
|
setBoxShape( Q::Panel, m_pal.shapeExtraSmallTop );
|
||||||
|
@ -484,6 +488,16 @@ void Editor::setupTextInput()
|
||||||
setGradient( Q::Panel | Q::Disabled, disabledPanelColor, allStates );
|
setGradient( Q::Panel | Q::Disabled, disabledPanelColor, allStates );
|
||||||
setBoxBorderColors( Q::Panel | Q::Disabled, m_pal.onSurface38, allStates );
|
setBoxBorderColors( Q::Panel | Q::Disabled, m_pal.onSurface38, allStates );
|
||||||
|
|
||||||
|
// Panel - Outlined
|
||||||
|
|
||||||
|
setGradient( Q::Panel | M3::Outlined, Qt::transparent );
|
||||||
|
setBoxShape( Q::Panel | M3::Outlined, m_pal.shapeExtraSmall );
|
||||||
|
setBoxBorderMetrics( Q::Panel | M3::Outlined, 1_dp );
|
||||||
|
setBoxBorderColors( Q::Panel | M3::Outlined, m_pal.outline );
|
||||||
|
|
||||||
|
setBoxBorderMetrics( Q::Panel | M3::Outlined | Q::Focused, 2_dp, allStates );
|
||||||
|
setBoxBorderColors( Q::Panel | M3::Outlined | Q::Focused, m_pal.primary, allStates );
|
||||||
|
|
||||||
|
|
||||||
// LeadingIcon
|
// LeadingIcon
|
||||||
|
|
||||||
|
@ -492,18 +506,19 @@ void Editor::setupTextInput()
|
||||||
const auto leadingIcon = symbol( "text_field_search" );
|
const auto leadingIcon = symbol( "text_field_search" );
|
||||||
setSymbol( Q::LeadingIcon, leadingIcon );
|
setSymbol( Q::LeadingIcon, leadingIcon );
|
||||||
|
|
||||||
setGraphicRole( Q::LeadingIcon, QskMaterial3Skin::GraphicRoleOnSurface );
|
setGraphicRole( Q::LeadingIcon, M3::GraphicRoleOnSurface );
|
||||||
setGraphicRole( Q::LeadingIcon | Q::Error, QskMaterial3Skin::GraphicRoleOnSurfaceVariant, allStates );
|
setGraphicRole( Q::LeadingIcon | Q::Error, M3::GraphicRoleOnSurfaceVariant, allStates );
|
||||||
|
|
||||||
|
|
||||||
// LabelText
|
// LabelText
|
||||||
|
|
||||||
setAlignment( Q::LabelText, Qt::AlignLeft | Qt::AlignVCenter );
|
setAlignment( Q::LabelText, Qt::AlignLeft | Qt::AlignTop );
|
||||||
|
|
||||||
const QskStateCombination textEmptyStates( QskStateCombination::CombinationNoState,
|
const QskStateCombination textEmptyStates( QskStateCombination::CombinationNoState,
|
||||||
Q::Focused | Q::Hovered | Q::ReadOnly | Q::Disabled );
|
Q::Hovered | Q::ReadOnly | Q::Disabled | Q::Error );
|
||||||
|
|
||||||
setFontRole( Q::LabelText | Q::TextEmpty, BodyMedium, textEmptyStates );
|
setAlignment( Q::LabelText | Q::TextEmpty, Qt::AlignLeft | Qt::AlignVCenter, textEmptyStates );
|
||||||
|
setFontRole( Q::LabelText | Q::TextEmpty, BodyLarge, textEmptyStates );
|
||||||
setColor( Q::LabelText | Q::TextEmpty, m_pal.onSurfaceVariant, textEmptyStates );
|
setColor( Q::LabelText | Q::TextEmpty, m_pal.onSurfaceVariant, textEmptyStates );
|
||||||
|
|
||||||
const QskStateCombination editingHoveredFocused( QskStateCombination::CombinationNoState,
|
const QskStateCombination editingHoveredFocused( QskStateCombination::CombinationNoState,
|
||||||
|
@ -516,38 +531,47 @@ void Editor::setupTextInput()
|
||||||
setColor( Q::LabelText | Q::Error, m_pal.error, allStates );
|
setColor( Q::LabelText | Q::Error, m_pal.error, allStates );
|
||||||
setColor( Q::LabelText | Q::Error | Q::Hovered, m_pal.onErrorContainer, allStates );
|
setColor( Q::LabelText | Q::Error | Q::Hovered, m_pal.onErrorContainer, allStates );
|
||||||
|
|
||||||
|
// LabelText - Outlined
|
||||||
|
|
||||||
|
setMargin( Q::LabelText | M3::Outlined, { 4_dp, 0, 4_dp, 0 }, editingHoveredFocused );
|
||||||
|
|
||||||
|
|
||||||
// InputText
|
// InputText
|
||||||
|
|
||||||
setMargin( Q::InputText, { 16_dp, 8_dp, 16_dp, 8_dp } );
|
setMargin( Q::InputText, { 16_dp, 8_dp, 16_dp, 8_dp } );
|
||||||
setColor( Q::InputText, m_pal.onSurface );
|
setColor( Q::InputText, m_pal.onSurface );
|
||||||
setFontRole( Q::InputText, BodyMedium );
|
setFontRole( Q::InputText, BodyLarge );
|
||||||
setAlignment( Q::InputText, Qt::AlignLeft | Qt::AlignBottom );
|
setAlignment( Q::InputText, Qt::AlignLeft | Qt::AlignBottom );
|
||||||
|
|
||||||
setColor( Q::InputText | Q::Error, m_pal.onSurface, allStates ); // same as with Hovered and Focused
|
setColor( Q::InputText | Q::Error, m_pal.onSurface, allStates ); // same as with Hovered and Focused
|
||||||
|
|
||||||
setColor( Q::InputText | Q::Disabled, m_pal.onSurface38 );
|
setColor( Q::InputText | Q::Disabled, m_pal.onSurface38 );
|
||||||
|
|
||||||
|
// InputText - Outlined
|
||||||
|
|
||||||
|
setAlignment( Q::InputText | M3::Outlined, Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
|
|
||||||
|
|
||||||
// HintText
|
// HintText
|
||||||
|
|
||||||
setColor( Q::HintText, color( Q::InputText ) );
|
setColor( Q::HintText, color( Q::InputText ) );
|
||||||
setFontRole( Q::HintText, fontRole( Q::InputText ) );
|
setFontRole( Q::HintText, fontRole( Q::InputText ) );
|
||||||
setAlignment( Q::HintText, alignment( Q::InputText ) );
|
setAlignment( Q::HintText, alignment( Q::InputText ) );
|
||||||
|
setAlignment( Q::HintText | M3::Outlined, alignment( Q::InputText | M3::Outlined ) );
|
||||||
|
|
||||||
|
|
||||||
// TrailingIcon
|
// TrailingIcon
|
||||||
|
|
||||||
setStrutSize( Q::TrailingIcon, { 24_dp, 24_dp } );
|
setStrutSize( Q::TrailingIcon, { 24_dp, 24_dp } );
|
||||||
setMargin( Q::TrailingIcon, { 0, 0, 12_dp, 0 } );
|
setMargin( Q::TrailingIcon, { 0, 0, 12_dp, 0 } );
|
||||||
setGraphicRole( Q::TrailingIcon, QskMaterial3Skin::GraphicRoleOnSurface );
|
setGraphicRole( Q::TrailingIcon, M3::GraphicRoleOnSurfaceVariant );
|
||||||
const auto trailingIcon = symbol( "text_field_cancel" );
|
const auto trailingIcon = symbol( "text_field_cancel" );
|
||||||
setSymbol( Q::TrailingIcon, trailingIcon );
|
setSymbol( Q::TrailingIcon, trailingIcon );
|
||||||
|
|
||||||
const auto errorIcon = symbol( "text_field_error" );
|
const auto errorIcon = symbol( "text_field_error" );
|
||||||
setSymbol( Q::TrailingIcon | Q::Error, errorIcon, allStates );
|
setSymbol( Q::TrailingIcon | Q::Error, errorIcon, allStates );
|
||||||
setGraphicRole( Q::TrailingIcon | Q::Error, QskMaterial3Skin::GraphicRoleError, allStates );
|
setGraphicRole( Q::TrailingIcon | Q::Error, M3::GraphicRoleError, allStates );
|
||||||
setGraphicRole( Q::TrailingIcon | Q::Error | Q::Hovered, QskMaterial3Skin::GraphicRoleOnErrorContainer, allStates );
|
setGraphicRole( Q::TrailingIcon | Q::Error | Q::Hovered, M3::GraphicRoleOnErrorContainer, allStates );
|
||||||
|
|
||||||
|
|
||||||
// TrailingIconRipple
|
// TrailingIconRipple
|
||||||
|
@ -1654,6 +1678,7 @@ QskMaterial3Theme::QskMaterial3Theme( QskSkin::ColorScheme colorScheme,
|
||||||
elevation2 = QskShadowMetrics( -2, 8, { 0, 2 } );
|
elevation2 = QskShadowMetrics( -2, 8, { 0, 2 } );
|
||||||
elevation3 = QskShadowMetrics( -1, 11, { 0, 2 } );
|
elevation3 = QskShadowMetrics( -1, 11, { 0, 2 } );
|
||||||
|
|
||||||
|
shapeExtraSmall = QskBoxShapeMetrics( 4_dp, 4_dp, 4_dp, 4_dp );
|
||||||
shapeExtraSmallTop = QskBoxShapeMetrics( 4_dp, 4_dp, 0, 0 );
|
shapeExtraSmallTop = QskBoxShapeMetrics( 4_dp, 4_dp, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,7 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme
|
||||||
|
|
||||||
qreal stateOpacity( int state ) const;
|
qreal stateOpacity( int state ) const;
|
||||||
|
|
||||||
|
QskBoxShapeMetrics shapeExtraSmall;
|
||||||
QskBoxShapeMetrics shapeExtraSmallTop;
|
QskBoxShapeMetrics shapeExtraSmallTop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -61,57 +61,70 @@ namespace
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class InputBox : public QskLinearBox
|
class TextInputBox : public QskLinearBox
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputBox( QQuickItem* parent = nullptr )
|
TextInputBox( QQuickItem* parent = nullptr )
|
||||||
: QskLinearBox( Qt::Horizontal, parent )
|
: QskLinearBox( Qt::Horizontal, parent )
|
||||||
{
|
{
|
||||||
setSpacing( 40 );
|
setSpacing( 25 );
|
||||||
setDefaultAlignment( Qt::AlignHCenter | Qt::AlignTop );
|
setDefaultAlignment( Qt::AlignHCenter | Qt::AlignTop );
|
||||||
|
|
||||||
{
|
{
|
||||||
auto spinBox = new QskSpinBox( 0.0, 100.0, 1.0, this );
|
|
||||||
spinBox->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
|
|
||||||
spinBox->setPageSize( 5 );
|
|
||||||
spinBox->setValue( 35 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( const auto& emphasis : { QskTextInput::NoEmphasis, QskTextInput::LowEmphasis } )
|
||||||
{
|
{
|
||||||
auto input = new QskTextInput( this );
|
{
|
||||||
input->setLabelText( "filled" );
|
auto input = new QskTextInput( this );
|
||||||
input->setHintText( "hint text" );
|
input->setEmphasis( emphasis );
|
||||||
input->setSupportingText( "supporting text" );
|
const QString text = ( emphasis == QskTextInput::NoEmphasis ) ? "filled" : "outlined";
|
||||||
input->setMaxLength( 10 );
|
input->setLabelText( text );
|
||||||
}
|
input->setHintText( "hint text" );
|
||||||
|
input->setSupportingText( "supporting text" );
|
||||||
|
input->setMaxLength( 10 );
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto input = new QskTextInput( this );
|
auto input = new QskTextInput( this );
|
||||||
input->setLeadingIcon( {} );
|
input->setEmphasis( emphasis );
|
||||||
input->setLabelText( "no leading icon" );
|
input->setLeadingIcon( {} );
|
||||||
input->setHintText( "hint text" );
|
input->setLabelText( "no leading icon" );
|
||||||
input->setSupportingText( "supporting text" );
|
input->setHintText( "hint text" );
|
||||||
}
|
input->setSupportingText( "supporting text" );
|
||||||
auto input = new QskTextInput( this );
|
}
|
||||||
input->setSkinStateFlag( QskTextInput::Error );
|
{
|
||||||
input->setLabelText( "error" );
|
auto input = new QskTextInput( this );
|
||||||
input->setHintText( "hint text" );
|
input->setEmphasis( emphasis );
|
||||||
input->setSupportingText( "error text" );
|
input->setLeadingIcon( {} );
|
||||||
}
|
input->setLabelText( "no hint text" );
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto input = new QskTextInput( this );
|
auto input = new QskTextInput( this );
|
||||||
input->setReadOnly( true );
|
input->setEmphasis( emphasis );
|
||||||
input->setLabelText( "read only" );
|
input->setSkinStateFlag( QskTextInput::Error );
|
||||||
input->setSizePolicy( Qt::Horizontal, QskSizePolicy::MinimumExpanding );
|
input->setLabelText( "error" );
|
||||||
}
|
input->setHintText( "hint text" );
|
||||||
|
input->setSupportingText( "error text" );
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto input = new QskTextInput( this );
|
auto input = new QskTextInput( this );
|
||||||
input->setMaxLength( 15 );
|
input->setEmphasis( emphasis );
|
||||||
input->setLabelText( "password" );
|
input->setReadOnly( true );
|
||||||
input->setEchoMode( QskTextInput::Password );
|
input->setLabelText( "read only" );
|
||||||
input->setHintText( "better be strong" );
|
input->setSizePolicy( Qt::Horizontal, QskSizePolicy::MinimumExpanding );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto input = new QskTextInput( this );
|
||||||
|
input->setEmphasis( emphasis );
|
||||||
|
input->setMaxLength( 15 );
|
||||||
|
input->setLabelText( "password" );
|
||||||
|
input->setEchoMode( QskTextInput::Password );
|
||||||
|
input->setHintText( "better be strong" );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -136,12 +149,17 @@ InputPage::InputPage( QQuickItem* parent )
|
||||||
auto spinBox = new QskSpinBox( 0.0, 100.0, 1.0 );
|
auto spinBox = new QskSpinBox( 0.0, 100.0, 1.0 );
|
||||||
spinBox->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
|
spinBox->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
auto inputBox = new InputBox();
|
auto textInputBox = new TextInputBox();
|
||||||
inputBox->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
|
inputBox->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
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 );
|
||||||
|
|
||||||
|
auto spinBox = new QskSpinBox( 0.0, 100.0, 1.0 );
|
||||||
|
spinBox->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
|
||||||
|
spinBox->setPageSize( 5 );
|
||||||
|
spinBox->setValue( 35 );
|
||||||
|
|
||||||
vBox->addItem( sliders[0].continous );
|
vBox->addItem( sliders[0].continous );
|
||||||
vBox->addItem( sliders[0].discrete );
|
vBox->addItem( sliders[0].discrete );
|
||||||
|
|
|
@ -293,6 +293,11 @@ namespace
|
||||||
class QskTextInput::PrivateData
|
class QskTextInput::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
PrivateData()
|
||||||
|
: emphasis( NoEmphasis )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
TextInput* textInput;
|
TextInput* textInput;
|
||||||
QString labelText;
|
QString labelText;
|
||||||
QString hintText;
|
QString hintText;
|
||||||
|
@ -300,6 +305,7 @@ class QskTextInput::PrivateData
|
||||||
|
|
||||||
unsigned int activationModes : 3;
|
unsigned int activationModes : 3;
|
||||||
bool hasPanel : 1;
|
bool hasPanel : 1;
|
||||||
|
int emphasis : 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
QskTextInput::QskTextInput( QQuickItem* parent )
|
QskTextInput::QskTextInput( QQuickItem* parent )
|
||||||
|
@ -563,6 +569,12 @@ QSizeF QskTextInput::layoutSizeHint( Qt::SizeHint which, const QSizeF& ) const
|
||||||
hint = hint.expandedTo( strutSizeHint( Panel ) );
|
hint = hint.expandedTo( strutSizeHint( Panel ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( emphasis() == LowEmphasis )
|
||||||
|
{
|
||||||
|
const auto fontHeight = effectiveFontHeight( LabelText | TextEmpty );
|
||||||
|
hint.rheight() += fontHeight / 2;
|
||||||
|
}
|
||||||
|
|
||||||
if( !supportingText().isEmpty() || maxLength() != 32767 ) // magic number hardcoded in qquicktextinput.cpp
|
if( !supportingText().isEmpty() || maxLength() != 32767 ) // magic number hardcoded in qquicktextinput.cpp
|
||||||
{
|
{
|
||||||
const auto margins = marginHint( SupportingText );
|
const auto margins = marginHint( SupportingText );
|
||||||
|
@ -587,6 +599,24 @@ void QskTextInput::updateNode( QSGNode* node )
|
||||||
Inherited::updateNode( node );
|
Inherited::updateNode( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskTextInput::setEmphasis( Emphasis emphasis )
|
||||||
|
{
|
||||||
|
if ( emphasis != m_data->emphasis )
|
||||||
|
{
|
||||||
|
m_data->emphasis = emphasis;
|
||||||
|
|
||||||
|
resetImplicitSize();
|
||||||
|
update();
|
||||||
|
|
||||||
|
Q_EMIT emphasisChanged( emphasis );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QskTextInput::Emphasis QskTextInput::emphasis() const
|
||||||
|
{
|
||||||
|
return static_cast< Emphasis >( m_data->emphasis );
|
||||||
|
}
|
||||||
|
|
||||||
QString QskTextInput::inputText() const
|
QString QskTextInput::inputText() const
|
||||||
{
|
{
|
||||||
return m_data->textInput->text();
|
return m_data->textInput->text();
|
||||||
|
@ -798,6 +828,18 @@ void QskTextInput::ensureVisible( int position )
|
||||||
m_data->textInput->ensureVisible( position );
|
m_data->textInput->ensureVisible( position );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QskAspect::Variation QskTextInput::effectiveVariation() const
|
||||||
|
{
|
||||||
|
switch( m_data->emphasis )
|
||||||
|
{
|
||||||
|
case LowEmphasis:
|
||||||
|
return QskAspect::Small;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QskAspect::NoVariation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int QskTextInput::cursorPosition() const
|
int QskTextInput::cursorPosition() const
|
||||||
{
|
{
|
||||||
return m_data->textInput->cursorPosition();
|
return m_data->textInput->cursorPosition();
|
||||||
|
|
|
@ -58,6 +58,9 @@ class QSK_EXPORT QskTextInput : public QskControl
|
||||||
Q_PROPERTY( bool panel READ hasPanel
|
Q_PROPERTY( bool panel READ hasPanel
|
||||||
WRITE setPanel NOTIFY panelChanged )
|
WRITE setPanel NOTIFY panelChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( Emphasis emphasis READ emphasis
|
||||||
|
WRITE setEmphasis NOTIFY emphasisChanged )
|
||||||
|
|
||||||
using Inherited = QskControl;
|
using Inherited = QskControl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -67,6 +70,13 @@ class QSK_EXPORT QskTextInput : public QskControl
|
||||||
|
|
||||||
QSK_STATES( ReadOnly, Editing, Selected, Error, TextEmpty )
|
QSK_STATES( ReadOnly, Editing, Selected, Error, TextEmpty )
|
||||||
|
|
||||||
|
enum Emphasis
|
||||||
|
{
|
||||||
|
LowEmphasis = -1,
|
||||||
|
NoEmphasis = 0,
|
||||||
|
};
|
||||||
|
Q_ENUM( Emphasis )
|
||||||
|
|
||||||
enum ActivationMode
|
enum ActivationMode
|
||||||
{
|
{
|
||||||
NoActivation,
|
NoActivation,
|
||||||
|
@ -99,6 +109,9 @@ class QSK_EXPORT QskTextInput : public QskControl
|
||||||
|
|
||||||
void setupFrom( const QQuickItem* );
|
void setupFrom( const QQuickItem* );
|
||||||
|
|
||||||
|
void setEmphasis( Emphasis );
|
||||||
|
Emphasis emphasis() const;
|
||||||
|
|
||||||
QString inputText() const;
|
QString inputText() const;
|
||||||
|
|
||||||
QString labelText() const;
|
QString labelText() const;
|
||||||
|
@ -179,6 +192,8 @@ class QSK_EXPORT QskTextInput : public QskControl
|
||||||
|
|
||||||
void ensureVisible( int position );
|
void ensureVisible( int position );
|
||||||
|
|
||||||
|
QskAspect::Variation effectiveVariation() const override;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setInputText( const QString& );
|
void setInputText( const QString& );
|
||||||
void setLabelText( const QString& );
|
void setLabelText( const QString& );
|
||||||
|
@ -186,6 +201,8 @@ class QSK_EXPORT QskTextInput : public QskControl
|
||||||
void setEditing( bool );
|
void setEditing( bool );
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
void emphasisChanged( Emphasis );
|
||||||
|
|
||||||
void editingChanged( bool );
|
void editingChanged( bool );
|
||||||
|
|
||||||
void activationModesChanged();
|
void activationModesChanged();
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include "QskTextInputSkinlet.h"
|
#include "QskTextInputSkinlet.h"
|
||||||
#include "QskTextInput.h"
|
#include "QskTextInput.h"
|
||||||
|
|
||||||
|
#include "QskBoxBorderColors.h"
|
||||||
|
#include "QskBoxBorderMetrics.h"
|
||||||
|
#include "QskBoxShapeMetrics.h"
|
||||||
#include "QskFunctions.h"
|
#include "QskFunctions.h"
|
||||||
|
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
|
@ -20,6 +23,39 @@ namespace
|
||||||
+ " / " + QString::number( input->maxLength() );
|
+ " / " + QString::number( input->maxLength() );
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to "cut a hole" in the upper gradient for the label text:
|
||||||
|
QskBoxBorderColors outlineColors( const QskTextInput* input )
|
||||||
|
{
|
||||||
|
auto borderColors = input->boxBorderColorsHint( Q::Panel );
|
||||||
|
auto topGradient = borderColors.gradientAt( Qt::TopEdge );
|
||||||
|
|
||||||
|
const auto panelRect = input->subControlRect( Q::Panel );
|
||||||
|
|
||||||
|
const auto margins = input->marginHint( Q::LabelText );
|
||||||
|
const auto iconMargins = input->marginHint( Q::LeadingIcon );
|
||||||
|
|
||||||
|
const auto x1 = iconMargins.left() - margins.left();
|
||||||
|
const auto r1 = x1 / panelRect.width();
|
||||||
|
|
||||||
|
const auto w = qskHorizontalAdvance( input->effectiveFont( Q::LabelText ), input->labelText() );
|
||||||
|
|
||||||
|
const auto x2 = x1 + w + margins.right();
|
||||||
|
const auto r2 = x2 / panelRect.width();
|
||||||
|
|
||||||
|
topGradient.setStops( {
|
||||||
|
{ 0.0, topGradient.startColor() },
|
||||||
|
{ r1, topGradient.startColor() },
|
||||||
|
{ r1, Qt::transparent },
|
||||||
|
{ r2, Qt::transparent },
|
||||||
|
{ r2, topGradient.startColor() },
|
||||||
|
{ 1.0, topGradient.startColor() }
|
||||||
|
} );
|
||||||
|
|
||||||
|
borderColors.setGradientAt( Qt::TopEdge, topGradient );
|
||||||
|
|
||||||
|
return borderColors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QskTextInputSkinlet::QskTextInputSkinlet( QskSkin* skin )
|
QskTextInputSkinlet::QskTextInputSkinlet( QskSkin* skin )
|
||||||
|
@ -50,6 +86,13 @@ QRectF QskTextInputSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
{
|
{
|
||||||
auto rect = contentsRect;
|
auto rect = contentsRect;
|
||||||
|
|
||||||
|
if( input->emphasis() == Q::LowEmphasis )
|
||||||
|
{
|
||||||
|
const auto fontHeight = input->effectiveFontHeight( Q::LabelText | Q::Focused );
|
||||||
|
rect.setY( fontHeight / 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const auto h = input->strutSizeHint( subControl ).height();
|
const auto h = input->strutSizeHint( subControl ).height();
|
||||||
rect.setHeight( h );
|
rect.setHeight( h );
|
||||||
|
|
||||||
|
@ -78,13 +121,27 @@ QRectF QskTextInputSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
{
|
{
|
||||||
const auto inputRect = input->subControlRect( Q::InputText );
|
const auto inputRect = input->subControlRect( Q::InputText );
|
||||||
|
|
||||||
if( input->hasSkinState( Q::Focused ) || !input->inputText().isEmpty() )
|
if( !input->inputText().isEmpty()
|
||||||
|
|| input->hasSkinState( Q::Focused )
|
||||||
|
|| input->hasSkinState( Q::Editing ) )
|
||||||
{
|
{
|
||||||
const auto margins = input->marginHint( subControl );
|
const auto margins = input->marginHint( subControl );
|
||||||
auto rect = inputRect;
|
auto rect = inputRect;
|
||||||
rect.setY( contentsRect.y() + margins.top() );
|
const QFontMetricsF fm( input->effectiveFont( subControl ) );
|
||||||
const QFontMetricsF fm ( input->effectiveFont( subControl ) );
|
|
||||||
|
if( input->emphasis() == Q::LowEmphasis )
|
||||||
|
{
|
||||||
|
const auto iconMargins = input->marginHint( Q::LeadingIcon );
|
||||||
|
rect.setX( iconMargins.left() );
|
||||||
|
rect.setY( 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rect.setY( contentsRect.y() + margins.top() );
|
||||||
|
}
|
||||||
|
|
||||||
rect.setHeight( fm.height() );
|
rect.setHeight( fm.height() );
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -107,7 +164,8 @@ QRectF QskTextInputSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
}
|
}
|
||||||
else if ( subControl == Q::HintText )
|
else if ( subControl == Q::HintText )
|
||||||
{
|
{
|
||||||
if( input->hasSkinState( Q::Focused ) && input->inputText().isEmpty() ) // ### has TextEmpty state
|
if( input->hasSkinState( Q::TextEmpty )
|
||||||
|
&& ( input->hasSkinState( Q::Focused ) || input->hasSkinState( Q::Editing ) ) )
|
||||||
{
|
{
|
||||||
return input->subControlRect( Q::InputText );
|
return input->subControlRect( Q::InputText );
|
||||||
}
|
}
|
||||||
|
@ -213,7 +271,23 @@ QSGNode* QskTextInputSkinlet::updateSubNode(
|
||||||
if ( !input->hasPanel() )
|
if ( !input->hasPanel() )
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return updateBoxNode( skinnable, node, Q::Panel );
|
if( input->emphasis() == Q::LowEmphasis
|
||||||
|
&& ( !input->hasSkinState( Q::TextEmpty )
|
||||||
|
|| input->hasSkinState( Q::Focused )
|
||||||
|
|| input->hasSkinState( Q::Editing ) ) )
|
||||||
|
{
|
||||||
|
const auto shape = skinnable->boxShapeHint( Q::Panel );
|
||||||
|
const auto borderMetrics = skinnable->boxBorderMetricsHint( Q::Panel );
|
||||||
|
const auto borderColors = outlineColors( input );
|
||||||
|
const auto gradient = input->gradientHint( Q::Panel );
|
||||||
|
|
||||||
|
return updateBoxNode( skinnable, node, input->subControlRect( Q::Panel ),
|
||||||
|
shape, borderMetrics, borderColors, gradient );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return updateBoxNode( skinnable, node, Q::Panel );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case LeadingIconRole:
|
case LeadingIconRole:
|
||||||
|
|
Loading…
Reference in New Issue