diff --git a/examples/tlabels/main.cpp b/examples/tlabels/main.cpp index 3e065c5a..0ce3103a 100644 --- a/examples/tlabels/main.cpp +++ b/examples/tlabels/main.cpp @@ -19,12 +19,17 @@ class TextBox : public QskLinearBox TextBox( QQuickItem* parent = nullptr ) : QskLinearBox( Qt::Vertical, 3, parent ) { + setMargins( 10 ); + setDefaultAlignment( Qt::AlignTop ); + setExtraSpacingAt( Qt::BottomEdge ); + const QStringList texts = { "Default", "Tiny", "Small", "Medium", "Large", "Huge" }; for ( int i = 0; i < texts.size(); i++ ) { auto label = new QskTextLabel( texts[ i ] + " Font", this ); + label->setPanel( true ); label->setFontRole( i ); } } @@ -39,12 +44,12 @@ int main( int argc, char* argv[] ) QGuiApplication app( argc, argv ); SkinnyFont::init( &app ); - SkinnyShortcut::enable( SkinnyShortcut::Quit | - SkinnyShortcut::DebugShortcuts ); + SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts ); auto box = new TextBox(); QskWindow window; + window.setColor( Qt::lightGray ); window.addItem( box ); window.resize( box->sizeHint().toSize() ); diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 167d07bc..8400a5af 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -5,6 +5,7 @@ #include "QskMaterialSkin.h" +#include #include #include #include @@ -124,6 +125,7 @@ void QskMaterialSkin::initHints() { initCommonHints(); + initBoxHints(); initDialogButtonBoxHints(); initDialogButtonHints(); initFocusIndicatorHints(); @@ -167,6 +169,18 @@ void QskMaterialSkin::initCommonHints() qskShadedColor( m_data->palette.textColor, 0.6 ) ); } +void QskMaterialSkin::initBoxHints() +{ + using namespace QskAspect; + using Q = QskBox; + + const ColorPalette& pal = m_data->palette; + + setGradient( Q::Panel, pal.baseColor ); + setBoxShape( Q::Panel, 4 ); + setBoxBorderMetrics( Q::Panel, 0 ); +} + void QskMaterialSkin::initPopupHints() { using namespace QskAspect; @@ -191,6 +205,12 @@ void QskMaterialSkin::initTextLabelHints() setSkinHint( Q::Text | Alignment, Qt::AlignCenter ); setColor( Q::Text, pal.textColor ); + + setMargins( Q::Panel | Padding, 5 ); + setBoxShape( Q::Panel, 4 ); + setBoxBorderMetrics( Q::Panel, 2 ); + setBoxBorderColors( Q::Panel, pal.darker125 ); + setGradient( Q::Panel, pal.baseColor ); } void QskMaterialSkin::initTextInputHints() diff --git a/skins/material/QskMaterialSkin.h b/skins/material/QskMaterialSkin.h index 09fedcca..19b5f4cf 100644 --- a/skins/material/QskMaterialSkin.h +++ b/skins/material/QskMaterialSkin.h @@ -27,6 +27,7 @@ class QSK_MATERIAL_EXPORT QskMaterialSkin : public QskSkin void initCommonHints(); + void initBoxHints(); void initDialogButtonBoxHints(); void initDialogButtonHints(); void initFocusIndicatorHints(); diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index dbb3312c..8c88680a 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -5,6 +5,7 @@ #include "QskSquiekSkin.h" +#include #include #include #include @@ -251,6 +252,7 @@ void QskSquiekSkin::initHints() { initCommonHints(); + initBoxHints(); initDialogButtonBoxHints(); initDialogButtonHints(); initFocusIndicatorHints(); @@ -292,6 +294,11 @@ void QskSquiekSkin::initCommonHints() setColor( Control | StyleColor | Q::Disabled, pal.theme ); } +void QskSquiekSkin::initBoxHints() +{ + setPanel( QskBox::Panel, Plain ); +} + void QskSquiekSkin::initPopupHints() { using namespace QskAspect; @@ -310,6 +317,19 @@ void QskSquiekSkin::initTextLabelHints() setSkinHint( Q::Text | Alignment, Qt::AlignCenter ); setColor( Q::Text, pal.themeForeground ); + + setMargins( Q::Panel | Padding, 5 ); + setBoxBorderMetrics( Q::Panel, 2 ); + setBoxShape( Q::Panel, 4 ); + + const QColor c = pal.base; + + const QskBoxBorderColors borderColors( + c.darker( 170 ), c.darker( 170 ), + c.darker( 105 ), c.darker( 105 ) ); + + setBoxBorderColors( Q::Panel, borderColors ); + setGradient( Q::Panel, c ); } void QskSquiekSkin::initTextInputHints() diff --git a/skins/squiek/QskSquiekSkin.h b/skins/squiek/QskSquiekSkin.h index 483a0fd6..63747bbf 100644 --- a/skins/squiek/QskSquiekSkin.h +++ b/skins/squiek/QskSquiekSkin.h @@ -27,6 +27,7 @@ class QSK_SQUIEK_EXPORT QskSquiekSkin : public QskSkin void initCommonHints(); + void initBoxHints(); void initDialogButtonHints(); void initDialogButtonBoxHints(); void initFocusIndicatorHints(); diff --git a/src/controls/QskTextLabel.cpp b/src/controls/QskTextLabel.cpp index 6d3d82e1..84b49f8d 100644 --- a/src/controls/QskTextLabel.cpp +++ b/src/controls/QskTextLabel.cpp @@ -11,6 +11,7 @@ #include #include +QSK_SUBCONTROL( QskTextLabel, Panel ) QSK_SUBCONTROL( QskTextLabel, Text ) class QskTextLabel::PrivateData @@ -18,6 +19,7 @@ class QskTextLabel::PrivateData public: PrivateData( const QString& txt ) : text( txt ) + , hasPanel( false ) { effectiveTextFormat = textOptions.format(); } @@ -40,6 +42,8 @@ class QskTextLabel::PrivateData QskTextOptions textOptions; mutable QskTextOptions::TextFormat effectiveTextFormat; + + bool hasPanel : 1; }; QskTextLabel::QskTextLabel( QQuickItem* parent ) @@ -58,6 +62,24 @@ QskTextLabel::~QskTextLabel() { } +void QskTextLabel::setPanel( bool on ) +{ + if ( on == m_data->hasPanel ) + return; + + m_data->hasPanel = on; + + resetImplicitSize(); + update(); + + Q_EMIT panelChanged( on ); +} + +bool QskTextLabel::hasPanel() const +{ + return m_data->hasPanel; +} + void QskTextLabel::setText( const QString& text ) { if ( text == m_data->text ) @@ -246,9 +268,13 @@ QSizeF QskTextLabel::contentsSizeHint( } QSizeF size( constraint.width(), maxHeight ); + size = QskTextRenderer::textSize( m_data->text, font, m_data->effectiveOptions(), size ); + if ( m_data->hasPanel ) + size = outerBoxSize( Panel, size ); + hint.setHeight( qCeil( size.height() ) ); } } @@ -257,15 +283,22 @@ QSizeF QskTextLabel::contentsSizeHint( const qreal maxWidth = std::numeric_limits< qreal >::max(); QSizeF size( maxWidth, constraint.height() ); + size = QskTextRenderer::textSize( m_data->text, font, m_data->effectiveOptions(), size ); + if ( m_data->hasPanel ) + size = outerBoxSize( Panel, size ); + hint.setWidth( qCeil( size.width() ) ); } else { hint = QskTextRenderer::textSize( m_data->text, font, m_data->effectiveOptions() ); + + if ( m_data->hasPanel ) + hint = outerBoxSize( Panel, hint ); } return hint; diff --git a/src/controls/QskTextLabel.h b/src/controls/QskTextLabel.h index ab1ffb32..129aa7f3 100644 --- a/src/controls/QskTextLabel.h +++ b/src/controls/QskTextLabel.h @@ -27,10 +27,13 @@ class QSK_EXPORT QskTextLabel : public QskControl Q_PROPERTY( Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged ) + Q_PROPERTY( bool panel READ hasPanel + WRITE setPanel NOTIFY panelChanged FINAL ) + using Inherited = QskControl; public: - QSK_SUBCONTROLS( Text ) + QSK_SUBCONTROLS( Panel, Text ) QskTextLabel( QQuickItem* parent = nullptr ); QskTextLabel( const QString& text, QQuickItem* parent = nullptr ); @@ -62,19 +65,25 @@ class QSK_EXPORT QskTextLabel : public QskControl QFont font() const; + void setPanel( bool ); + bool hasPanel() const; + Q_SIGNALS: void textChanged( const QString& ); void textColorChanged( const QColor& ); void textOptionsChanged( const QskTextOptions& ); void fontRoleChanged(); void alignmentChanged(); + void panelChanged( bool ); public Q_SLOTS: void setText( const QString& ); protected: void changeEvent( QEvent* ) override; - QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override; + + QSizeF contentsSizeHint( + Qt::SizeHint, const QSizeF& ) const override; private: class PrivateData; diff --git a/src/controls/QskTextLabelSkinlet.cpp b/src/controls/QskTextLabelSkinlet.cpp index f0f4763e..a06f446b 100644 --- a/src/controls/QskTextLabelSkinlet.cpp +++ b/src/controls/QskTextLabelSkinlet.cpp @@ -11,7 +11,7 @@ QskTextLabelSkinlet::QskTextLabelSkinlet( QskSkin* skin ) : Inherited( skin ) { - setNodeRoles( { TextRole } ); + setNodeRoles( { PanelRole, TextRole } ); } QskTextLabelSkinlet::~QskTextLabelSkinlet() = default; @@ -19,10 +19,22 @@ QskTextLabelSkinlet::~QskTextLabelSkinlet() = default; QRectF QskTextLabelSkinlet::subControlRect( const QskSkinnable* skinnable, const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const { - if ( subControl == QskTextLabel::Text ) + const auto label = static_cast< const QskTextLabel* >( skinnable ); + + if ( subControl == QskTextLabel::Panel ) { return contentsRect; } + else if ( subControl == QskTextLabel::Text ) + { + if ( label->hasPanel() ) + { + auto r = subControlRect( label, contentsRect, QskTextLabel::Panel ); + return label->innerBox( QskTextLabel::Panel, r ); + } + + return contentsRect; + } return Inherited::subControlRect( skinnable, contentsRect, subControl ); } @@ -34,6 +46,13 @@ QSGNode* QskTextLabelSkinlet::updateSubNode( switch ( nodeRole ) { + case PanelRole: + { + if ( !label->hasPanel() ) + return nullptr; + + return updateBoxNode( label, node, QskTextLabel::Panel ); + } case TextRole: { return updateTextNode( label, node, diff --git a/src/controls/QskTextLabelSkinlet.h b/src/controls/QskTextLabelSkinlet.h index 5544983d..3bcd6f36 100644 --- a/src/controls/QskTextLabelSkinlet.h +++ b/src/controls/QskTextLabelSkinlet.h @@ -17,7 +17,7 @@ class QSK_EXPORT QskTextLabelSkinlet : public QskSkinlet public: enum NodeRole { - TextRole + PanelRole, TextRole }; Q_INVOKABLE QskTextLabelSkinlet( QskSkin* = nullptr );