started to remove QskSkinRenderer

This commit is contained in:
Uwe Rathmann 2017-10-20 13:09:30 +02:00
parent 958196db19
commit f21bed63c7
13 changed files with 198 additions and 250 deletions

View File

@ -5,7 +5,10 @@
#include "Frame.h" #include "Frame.h"
#include <QskBoxOptions.h> #include <QskBoxShapeMetrics.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskGradient.h>
#include <QskBoxNode.h> #include <QskBoxNode.h>
#include <QskSkinlet.h> #include <QskSkinlet.h>
@ -145,18 +148,10 @@ void Frame::updateFrameNode( const QRectF& rect, QskBoxNode* node )
} }
} }
QskBoxOptions options; const QskBoxBorderColors borderColors( c1, c1, c2, c2 );
const qreal radius = effectiveRadius( rect, m_radius );
options.border.setWidths( m_frameWidth );
options.borderColors.setColor( Qsk::Left, c1 );
options.borderColors.setColor( Qsk::Top, c1 );
options.borderColors.setColor( Qsk::Right, c2 );
options.borderColors.setColor( Qsk::Bottom, c2 );
options.fillGradient.setColor( m_color );
options.shape.setRadius( effectiveRadius( rect, m_radius ) );
node->setBoxData( rect, options ); node->setBoxData( rect, radius, m_frameWidth, borderColors, m_color );
} }
#include "moc_Frame.cpp" #include "moc_Frame.cpp"

View File

@ -109,15 +109,15 @@ bool QskTextOptions::operator==( const QskTextOptions& other ) const
&& ( m_maximumLineCount == other.m_maximumLineCount ); && ( m_maximumLineCount == other.m_maximumLineCount );
} }
bool QskTextOptions::isRichText( const QString& text ) const bool QskTextOptions::isPlainText( const QString& text ) const
{ {
if ( text.isEmpty() ) if ( text.isEmpty() )
return false; return true;
if ( m_format == QskTextOptions::AutoText ) if ( m_format == QskTextOptions::AutoText )
return Qt::mightBeRichText( text ); return !Qt::mightBeRichText( text );
return m_format == QskTextOptions::RichText; return m_format == QskTextOptions::PlainText;
} }
uint qHash( const QskTextOptions &options, uint seed ) noexcept uint qHash( const QskTextOptions &options, uint seed ) noexcept

View File

@ -70,7 +70,7 @@ public:
bool operator==( const QskTextOptions& other ) const; bool operator==( const QskTextOptions& other ) const;
bool operator!=( const QskTextOptions& other ) const; bool operator!=( const QskTextOptions& other ) const;
bool isRichText( const QString& text ) const; bool isPlainText( const QString& text ) const;
int textFlags() const; int textFlags() const;

View File

@ -6,7 +6,6 @@
#include "QskScrollViewSkinlet.h" #include "QskScrollViewSkinlet.h"
#include "QskScrollView.h" #include "QskScrollView.h"
#include "QskAspect.h" #include "QskAspect.h"
#include "QskSkinRenderer.h"
#include "QskFunctions.h" #include "QskFunctions.h"
#include <QTransform> #include <QTransform>

View File

@ -6,52 +6,13 @@
#include "QskSkinRenderer.h" #include "QskSkinRenderer.h"
#include "QskSkinnable.h" #include "QskSkinnable.h"
#include "QskControl.h" #include "QskControl.h"
#include "QskRgbValue.h"
#include "QskTextRenderer.h" #include "QskTextRenderer.h"
#include "QskPlainTextRenderer.h" #include "QskPlainTextRenderer.h"
#include "QskBoxOptions.h"
#include "QskTextNode.h" #include "QskTextNode.h"
#include <QMatrix4x4> #include <QMatrix4x4>
static inline qreal qskRadiusAt( const QskBoxShapeMetrics& shape, Qt::Edge edge )
{
switch( edge )
{
case Qt::LeftEdge:
{
return qMax(
shape.radius( Qt::TopLeftCorner ).width(),
shape.radius( Qt::BottomLeftCorner ).width()
);
}
case Qt::TopEdge:
{
return qMax(
shape.radius( Qt::TopLeftCorner ).height(),
shape.radius( Qt::TopRightCorner ).height()
);
}
case Qt::RightEdge:
{
return qMax(
shape.radius( Qt::TopRightCorner ).width(),
shape.radius( Qt::BottomRightCorner ).width()
);
}
case Qt::BottomEdge:
{
return qMax(
shape.radius( Qt::BottomLeftCorner ).height(),
shape.radius( Qt::BottomRightCorner ).height()
);
}
}
return 0.0;
}
QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable, QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable,
const QString& text, const QskTextOptions& options, const QString& text, const QskTextOptions& options,
QskAspect::Subcontrol subControl ) QskAspect::Subcontrol subControl )
@ -60,9 +21,9 @@ QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable,
auto font = skinnable->effectiveFont( subControl ); auto font = skinnable->effectiveFont( subControl );
if ( options.isRichText( text ) ) if ( options.isPlainText( text ) )
{ {
QskTextRenderer renderer; QskPlainTextRenderer renderer;
renderer.setFont( font ); renderer.setFont( font );
renderer.setOptions( options ); renderer.setOptions( options );
@ -70,7 +31,7 @@ QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable,
} }
else else
{ {
QskPlainTextRenderer renderer; QskTextRenderer renderer;
renderer.setFont( font ); renderer.setFont( font );
renderer.setOptions( options ); renderer.setOptions( options );
@ -84,15 +45,7 @@ QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable,
{ {
const auto font = skinnable->effectiveFont( subControl ); const auto font = skinnable->effectiveFont( subControl );
if ( options.isRichText( text ) ) if ( options.isPlainText( text ) )
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textRect( boundingSize, text ).size();
}
else
{ {
QskPlainTextRenderer renderer; QskPlainTextRenderer renderer;
renderer.setFont( font ); renderer.setFont( font );
@ -100,14 +53,14 @@ QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable,
return renderer.textRect( boundingSize, text ).size(); return renderer.textRect( boundingSize, text ).size();
} }
} else
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
void QskSkinRenderer::updateTextAt( const QskSkinnable* skinnable, return renderer.textRect( boundingSize, text ).size();
const QPointF& pos, const QString& text, const QskTextOptions& options, }
QskTextNode* textNode, QskAspect::Subcontrol subControl )
{
const QRectF r( pos.x(), pos.y(), 0.0, 0.0 );
updateText( skinnable, r, Qt::AlignLeft, text, options, textNode, subControl );
} }
void QskSkinRenderer::updateText( const QskSkinnable* skinnable, void QskSkinRenderer::updateText( const QskSkinnable* skinnable,
@ -137,13 +90,12 @@ void QskSkinRenderer::updateText( const QskSkinnable* skinnable,
subControl | Style, Qsk::Normal ); subControl | Style, Qsk::Normal );
} }
const auto isRichText = options.isRichText( text ) || const auto isPlainText = options.isPlainText( text );
options.format() == QskTextOptions::StyledText;
// doesn't work - we end up with a black rectangle TODO ... // doesn't work - we end up with a black rectangle TODO ...
#if 0 #if 0
// Optimization: only update the color if that is all that has changed // Optimization: only update the color if that is all that has changed
if ( !isRichText && ( ( skinnable->dirtyAspects() & TypeMask ) == Color ) ) if ( isPlainText && color_is_dirty )
{ {
QskPlainTextRenderer::updateNodeColor( parentNode, textRgb, QskPlainTextRenderer::updateNodeColor( parentNode, textRgb,
fontOptions.textStyle, styleRgb ); fontOptions.textStyle, styleRgb );
@ -155,35 +107,28 @@ void QskSkinRenderer::updateText( const QskSkinnable* skinnable,
{ {
case QskTextOptions::FixedSize: case QskTextOptions::FixedSize:
break; break;
case QskTextOptions::HorizontalFit: case QskTextOptions::HorizontalFit:
Q_UNIMPLEMENTED(); Q_UNIMPLEMENTED();
break; break;
case QskTextOptions::VerticalFit: case QskTextOptions::VerticalFit:
font.setPixelSize( bounds.height() * 0.5 ); font.setPixelSize( bounds.height() * 0.5 );
break; break;
case QskTextOptions::Fit: case QskTextOptions::Fit:
Q_UNIMPLEMENTED(); Q_UNIMPLEMENTED();
break; break;
} }
QColor linkColor; QColor linkColor;
if ( isRichText ) if ( !isPlainText )
linkColor = skinnable->color( subControl | LinkColor ); linkColor = skinnable->color( subControl | LinkColor );
if ( textNode->setTextData( text, bounds.size(), font, if ( textNode->setTextData( text, bounds.size(), font,
options, alignment, textStyle, textColor, styleColor, linkColor ) ) options, alignment, textStyle, textColor, styleColor, linkColor ) )
{ {
if ( isRichText ) if ( isPlainText )
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
renderer.setAlignment( alignment );
renderer.updateNode( skinnable->owningControl(), bounds.size(),
text, textNode, textColor, textStyle, styleColor, linkColor );
}
else
{ {
QskPlainTextRenderer renderer; QskPlainTextRenderer renderer;
renderer.setFont( font ); renderer.setFont( font );
@ -193,52 +138,15 @@ void QskSkinRenderer::updateText( const QskSkinnable* skinnable,
renderer.updateNode( skinnable->owningControl(), bounds.size(), renderer.updateNode( skinnable->owningControl(), bounds.size(),
text, textNode, textColor, textStyle, styleColor ); text, textNode, textColor, textStyle, styleColor );
} }
else
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
renderer.setAlignment( alignment );
renderer.updateNode( skinnable->owningControl(), bounds.size(),
text, textNode, textColor, textStyle, styleColor, linkColor );
}
} }
} }
QskBoxOptions QskSkinRenderer::boxOptions( const QskSkinnable* skinnable,
const QSizeF& size, QskAspect::Subcontrol subControl )
{
using namespace QskAspect;
QskBoxOptions options;
options.shape = skinnable->boxShapeHint( subControl ).toAbsolute( size );
options.border = skinnable->boxBorderMetricsHint( subControl ).toAbsolute( size );
options.borderColors = skinnable->boxBorderColorsHint( subControl );
options.fillGradient = skinnable->gradientHint( subControl );
return options;
}
QMarginsF QskSkinRenderer::paddingHint(
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& border,
const QSizeF& size, bool inner )
{
const auto shapeAbsolute = shape.toAbsolute( size );
const auto borderAbsolute = border.toAbsolute( size );
QMarginsF padding(
qskRadiusAt( shapeAbsolute, Qt::LeftEdge ),
qskRadiusAt( shapeAbsolute, Qt::TopEdge ),
qskRadiusAt( shapeAbsolute, Qt::RightEdge ),
qskRadiusAt( shapeAbsolute, Qt::BottomEdge )
);
// half of the border goes to the inner side
const QMarginsF b = borderAbsolute.widths() * 0.5;
/*
not correct for calculating the outer padding,
but to get things started. TODO ...
*/
if ( inner )
padding -= b;
else
padding += b;
// sin 45° ceiled : 0.70710678;
constexpr double f = 1.0 - 0.70710678;
return f * padding;
}

View File

@ -13,15 +13,11 @@
class QskSkinnable; class QskSkinnable;
class QskTextOptions; class QskTextOptions;
class QskBoxOptions;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskTextNode; class QskTextNode;
class QPointF; class QPointF;
class QRectF; class QRectF;
class QSizeF; class QSizeF;
class QMarginsF;
class QString; class QString;
namespace QskSkinRenderer namespace QskSkinRenderer
@ -34,22 +30,12 @@ namespace QskSkinRenderer
const QString&, const QskTextOptions&, const QString&, const QskTextOptions&,
QskTextNode*, QskAspect::Subcontrol ); QskTextNode*, QskAspect::Subcontrol );
QSK_EXPORT void updateTextAt( const QskSkinnable*,
const QPointF&, const QString&, const QskTextOptions&,
QskTextNode*, QskAspect::Subcontrol );
QSK_EXPORT QSizeF textSize( const QskSkinnable*, QSK_EXPORT QSizeF textSize( const QskSkinnable*,
const QString&, const QskTextOptions&, QskAspect::Subcontrol ); const QString&, const QskTextOptions&, QskAspect::Subcontrol );
QSK_EXPORT QSizeF textSize( const QskSkinnable*, QSK_EXPORT QSizeF textSize( const QskSkinnable*,
const QSizeF& boundingSize, const QString&, const QSizeF& boundingSize, const QString&,
const QskTextOptions&, QskAspect::Subcontrol ); const QskTextOptions&, QskAspect::Subcontrol );
QSK_EXPORT QskBoxOptions boxOptions( const QskSkinnable*,
const QSizeF&, QskAspect::Subcontrol );
QSK_EXPORT QMarginsF paddingHint(
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&, const QSizeF&, bool inner );
} }
#endif #endif

View File

@ -9,6 +9,9 @@
#include "QskSetup.h" #include "QskSetup.h"
#include "QskSkin.h" #include "QskSkin.h"
#include "QskControl.h" #include "QskControl.h"
#include "QskBoxShapeMetrics.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h"
#include "QskGradient.h" #include "QskGradient.h"
#include "QskSkinRenderer.h" #include "QskSkinRenderer.h"
#include "QskBoxNode.h" #include "QskBoxNode.h"
@ -16,7 +19,6 @@
#include "QskTextNode.h" #include "QskTextNode.h"
#include "QskGraphicNode.h" #include "QskGraphicNode.h"
#include "QskGraphicTextureFactory.h" #include "QskGraphicTextureFactory.h"
#include "QskBoxOptions.h"
#include "QskFunctions.h" #include "QskFunctions.h"
#include <QSGSimpleRectNode> #include <QSGSimpleRectNode>
@ -78,6 +80,15 @@ static inline QSGNode* qskUpdateGraphicNode(
return graphicNode; return graphicNode;
} }
static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics,
const QskBoxBorderColors& borderColors, const QskGradient& gradient )
{
if ( gradient.isVisible() )
return true;
return !borderMetrics.isNull() && borderColors.isVisible();
}
class QskSkinlet::PrivateData class QskSkinlet::PrivateData
{ {
public: public:
@ -188,10 +199,7 @@ QSGNode* QskSkinlet::updateBackgroundNode(
if ( boxNode == nullptr ) if ( boxNode == nullptr )
boxNode = new QskBoxNode(); boxNode = new QskBoxNode();
QskBoxOptions options; boxNode->setBoxData( rect, gradient );
options.fillGradient = gradient;
boxNode->setBoxData( rect, options );
return boxNode; return boxNode;
} }
@ -342,21 +350,29 @@ QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
{ {
using namespace QskAspect; using namespace QskAspect;
if ( rect.isEmpty() ) const QMarginsF margins = skinnable->marginsHint( subControl | Margin );
const QRectF boxRect = rect.marginsRemoved( margins );
if ( boxRect.isEmpty() )
return nullptr; return nullptr;
const auto options = QskSkinRenderer::boxOptions( skinnable, rect.size(), subControl ); auto borderMetrics = skinnable->boxBorderMetricsHint( subControl );
if ( !options.isVisible() ) borderMetrics = borderMetrics.toAbsolute( boxRect.size() );
const auto borderColors = skinnable->boxBorderColorsHint( subControl );
const auto fillGradient = skinnable->gradientHint( subControl );
if ( !qskIsBoxVisible( borderMetrics, borderColors, fillGradient ) )
return nullptr; return nullptr;
auto shape = skinnable->boxShapeHint( subControl );
shape = shape.toAbsolute( boxRect.size() );
auto boxNode = static_cast< QskBoxNode* >( node ); auto boxNode = static_cast< QskBoxNode* >( node );
if ( boxNode == nullptr ) if ( boxNode == nullptr )
boxNode = new QskBoxNode(); boxNode = new QskBoxNode();
const QMarginsF margins = skinnable->marginsHint( subControl | Margin ); boxNode->setBoxData( boxRect, shape, borderMetrics, borderColors, fillGradient );
const QRectF boxRect = rect.marginsRemoved( margins );
boxNode->setBoxData( boxRect, options );
return boxNode; return boxNode;
} }
@ -373,21 +389,28 @@ QSGNode* QskSkinlet::updateBoxClipNode( const QskSkinnable* skinnable,
{ {
using namespace QskAspect; using namespace QskAspect;
if ( rect.isEmpty() )
return nullptr;
const auto options = QskSkinRenderer::boxOptions( skinnable, rect.size(), subControl );
if ( !options.isVisible() )
return nullptr;
auto clipNode = static_cast< QskBoxClipNode* >( node ); auto clipNode = static_cast< QskBoxClipNode* >( node );
if ( clipNode == nullptr ) if ( clipNode == nullptr )
clipNode = new QskBoxClipNode(); clipNode = new QskBoxClipNode();
const QRectF clipRect = rect.marginsRemoved( const QMarginsF margins = skinnable->marginsHint( subControl | Margin );
skinnable->marginsHint( subControl | Margin ) );
clipNode->setBox( clipRect, options.shape, options.border ); const QRectF clipRect = rect.marginsRemoved( margins );
if ( clipRect.isEmpty() )
{
clipNode->setIsRectangular( true );
clipNode->setClipRect( clipRect );
}
else
{
auto borderMetrics = skinnable->boxBorderMetricsHint( subControl );
borderMetrics = borderMetrics.toAbsolute( clipRect.size() );
auto shape = skinnable->boxShapeHint( subControl );
shape = shape.toAbsolute( clipRect.size() );
clipNode->setBox( clipRect, shape, borderMetrics );
}
return clipNode; return clipNode;
} }

View File

@ -604,30 +604,60 @@ const char* QskSkinnable::skinStateAsPrintable( QskAspect::State state ) const
return bytes[counter].constData(); return bytes[counter].constData();
} }
static inline QMarginsF qskMargins( const QskSkinnable* skinnable, static inline QMarginsF qskEffectivePadding( const QskSkinnable* skinnable,
QskAspect::Aspect aspect, const QSizeF& size, bool inner ) QskAspect::Aspect aspect, const QSizeF& size, bool inner )
{ {
using namespace QskAspect; using namespace QskAspect;
using namespace Qt;
const QMarginsF padding1 = QskSkinRenderer::paddingHint( const auto shape = skinnable->boxShapeHint( aspect | Shape ).toAbsolute( size );
skinnable->boxShapeHint( aspect | Shape), const auto borderMetrics = skinnable->boxBorderMetricsHint( aspect | Border );
skinnable->boxBorderMetricsHint( aspect | Border ),
size, inner );
const QMarginsF padding2 = skinnable->marginsHint( aspect | Padding );
const qreal left = qMax( shape.radius( TopLeftCorner ).width(),
shape.radius( BottomLeftCorner ).width() );
const qreal top = qMax( shape.radius( TopLeftCorner ).height(),
shape.radius( TopRightCorner ).height() );
const qreal right = qMax( shape.radius( TopRightCorner ).width(),
shape.radius( BottomRightCorner ).width() );
const qreal bottom = qMax( shape.radius( Qt::BottomLeftCorner ).height(),
shape.radius( Qt::BottomRightCorner ).height() );
QMarginsF padding( left, top, right, bottom );
// half of the border goes to the inner side
const auto borderMargins = borderMetrics.toAbsolute( size ).widths() * 0.5;
if ( inner )
{
padding -= borderMargins;
}
else
{
// not correct, but to get things started. TODO ...
padding += borderMargins;
}
// sin 45° ceiled : 0.70710678;
padding *= 1.0 - 0.70710678;
const QMarginsF paddingHint = skinnable->marginsHint( aspect | Padding );
return QMarginsF( return QMarginsF(
qMax( padding1.left(), padding2.left() ), qMax( padding.left(), paddingHint.left() ),
qMax( padding1.top(), padding2.top() ), qMax( padding.top(), paddingHint.top() ),
qMax( padding1.right(), padding2.right() ), qMax( padding.right(), paddingHint.right() ),
qMax( padding1.bottom(), padding2.bottom() ) qMax( padding.bottom(), paddingHint.bottom() )
); );
} }
QSizeF QskSkinnable::innerBoxSize( QSizeF QskSkinnable::innerBoxSize(
QskAspect::Aspect aspect, const QSizeF& outerBoxSize ) const QskAspect::Aspect aspect, const QSizeF& outerBoxSize ) const
{ {
const QMarginsF m = qskMargins( this, aspect, outerBoxSize, true ); const QMarginsF m = qskEffectivePadding( this, aspect, outerBoxSize, true );
return QSizeF( outerBoxSize.width() - m.left() - m.right(), return QSizeF( outerBoxSize.width() - m.left() - m.right(),
outerBoxSize.height() - m.top() - m.bottom() ); outerBoxSize.height() - m.top() - m.bottom() );
@ -636,14 +666,14 @@ QSizeF QskSkinnable::innerBoxSize(
QRectF QskSkinnable::innerBox( QRectF QskSkinnable::innerBox(
QskAspect::Aspect aspect, const QRectF& outerBox ) const QskAspect::Aspect aspect, const QRectF& outerBox ) const
{ {
const QMarginsF m = qskMargins( this, aspect, outerBox.size(), true ); const QMarginsF m = qskEffectivePadding( this, aspect, outerBox.size(), true );
return outerBox.marginsRemoved( m ); return outerBox.marginsRemoved( m );
} }
QSizeF QskSkinnable::outerBoxSize( QSizeF QskSkinnable::outerBoxSize(
QskAspect::Aspect aspect, const QSizeF& innerBoxSize ) const QskAspect::Aspect aspect, const QSizeF& innerBoxSize ) const
{ {
const QMarginsF m = qskMargins( this, aspect, innerBoxSize, false ); const QMarginsF m = qskEffectivePadding( this, aspect, innerBoxSize, false );
return QSizeF( innerBoxSize.width() + m.left() + m.right(), return QSizeF( innerBoxSize.width() + m.left() + m.right(),
innerBoxSize.height() + m.top() + m.bottom() ); innerBoxSize.height() + m.top() + m.bottom() );
@ -652,7 +682,7 @@ QSizeF QskSkinnable::outerBoxSize(
QRectF QskSkinnable::outerBox( QRectF QskSkinnable::outerBox(
QskAspect::Aspect aspect, const QRectF& innerBox ) const QskAspect::Aspect aspect, const QRectF& innerBox ) const
{ {
const QMarginsF m = qskMargins( this, aspect, innerBox.size(), false ); const QMarginsF m = qskEffectivePadding( this, aspect, innerBox.size(), false );
return innerBox.marginsAdded( m ); return innerBox.marginsAdded( m );
} }

View File

@ -17,15 +17,32 @@ class QskTextLabel::PrivateData
{ {
public: public:
PrivateData( const QString& txt ): PrivateData( const QString& txt ):
effectiveTextFormat( QskTextOptions::AutoText ),
text( txt ) text( txt )
{ {
effectiveTextFormat = textOptions.format();
} }
QskTextOptions textOptions; QskTextOptions effectiveOptions() const
{
if ( textOptions.format() != QskTextOptions::AutoText )
return textOptions;
if ( effectiveTextFormat == QskTextOptions::AutoText )
{
effectiveTextFormat = textOptions.isPlainText( text )
? QskTextOptions::PlainText : QskTextOptions::RichText;
}
QskTextOptions options = textOptions;
options.setFormat( effectiveTextFormat );
return options;
}
QskTextOptions::TextFormat effectiveTextFormat;
QString text; QString text;
QskTextOptions textOptions;
mutable QskTextOptions::TextFormat effectiveTextFormat;
}; };
QskTextLabel::QskTextLabel( QQuickItem* parent ): QskTextLabel::QskTextLabel( QQuickItem* parent ):
@ -50,7 +67,7 @@ void QskTextLabel::setText( const QString& text )
return; return;
m_data->text = text; m_data->text = text;
m_data->effectiveTextFormat = QskTextOptions::AutoText; m_data->effectiveTextFormat = m_data->textOptions.format();
resetImplicitSize(); resetImplicitSize();
update(); update();
@ -68,9 +85,6 @@ void QskTextLabel::setTextOptions( const QskTextOptions& options )
if ( options == m_data->textOptions ) if ( options == m_data->textOptions )
return; return;
if ( options.format() != m_data->textOptions.format() )
m_data->effectiveTextFormat = QskTextOptions::AutoText;
#if 0 #if 0
// we are killing user settings of the policy this way ?? // we are killing user settings of the policy this way ??
@ -80,6 +94,7 @@ void QskTextLabel::setTextOptions( const QskTextOptions& options )
setSizePolicy( policy, sizePolicy().verticalPolicy() ); setSizePolicy( policy, sizePolicy().verticalPolicy() );
#endif #endif
m_data->effectiveTextFormat = options.format();
m_data->textOptions = options; m_data->textOptions = options;
resetImplicitSize(); resetImplicitSize();
@ -156,27 +171,12 @@ QFont QskTextLabel::font() const
return effectiveFont( QskTextLabel::Text ); return effectiveFont( QskTextLabel::Text );
} }
bool QskTextLabel::isRichText() const
{
if ( m_data->effectiveTextFormat == QskTextOptions::AutoText )
{
// caching the rich text evaluation
const bool isRichRext = m_data->textOptions.isRichText( m_data->text );
m_data->effectiveTextFormat = isRichRext ? QskTextOptions::RichText : QskTextOptions::PlainText;
}
return m_data->effectiveTextFormat;
}
QSizeF QskTextLabel::contentsSizeHint() const QSizeF QskTextLabel::contentsSizeHint() const
{ {
if ( !m_data->text.isEmpty() ) if ( !m_data->text.isEmpty() )
{ {
QskTextOptions options = textOptions(); return QskSkinRenderer::textSize( this, m_data->text,
options.setFormat( isRichText() ? QskTextOptions::RichText : QskTextOptions::PlainText ); m_data->effectiveOptions(), QskTextLabel::Text );
return QskSkinRenderer::textSize(
this, m_data->text, options, QskTextLabel::Text );
} }
return QSizeF( 0, 0 ); return QSizeF( 0, 0 );
@ -199,11 +199,9 @@ qreal QskTextLabel::heightForWidth( qreal width ) const
maxHeight = m_data->textOptions.maximumLineCount() * lineHeight; maxHeight = m_data->textOptions.maximumLineCount() * lineHeight;
} }
QskTextOptions options = textOptions();
options.setFormat( isRichText() ? QskTextOptions::RichText : QskTextOptions::PlainText );
const QSizeF size = QskSkinRenderer::textSize( this, const QSizeF size = QskSkinRenderer::textSize( this,
QSizeF( width, maxHeight ), m_data->text, options, QskTextLabel::Text ); QSizeF( width, maxHeight ), m_data->text,
m_data->effectiveOptions(), QskTextLabel::Text );
return qCeil( size.height() ); return qCeil( size.height() );
} }
@ -218,11 +216,9 @@ qreal QskTextLabel::widthForHeight( qreal height ) const
const qreal maxWidth = std::numeric_limits< qreal >::max(); const qreal maxWidth = std::numeric_limits< qreal >::max();
QskTextOptions options = textOptions();
options.setFormat( isRichText() ? QskTextOptions::RichText : QskTextOptions::PlainText );
const QSizeF size = QskSkinRenderer::textSize( this, const QSizeF size = QskSkinRenderer::textSize( this,
QSizeF( maxWidth, height ), m_data->text, options, QskTextLabel::Text ); QSizeF( maxWidth, height ), m_data->text,
m_data->effectiveOptions(), QskTextLabel::Text );
return qCeil( size.width() ); return qCeil( size.width() );
} }

View File

@ -57,8 +57,6 @@ public:
virtual qreal heightForWidth( qreal width ) const override; virtual qreal heightForWidth( qreal width ) const override;
virtual qreal widthForHeight( qreal height ) const override; virtual qreal widthForHeight( qreal height ) const override;
bool isRichText() const;
QFont font() const; QFont font() const;
Q_SIGNALS: Q_SIGNALS:

View File

@ -4,8 +4,12 @@
*****************************************************************************/ *****************************************************************************/
#include "QskBoxNode.h" #include "QskBoxNode.h"
#include "QskBoxOptions.h"
#include "QskBoxRenderer.h" #include "QskBoxRenderer.h"
#include "QskBoxShapeMetrics.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h"
#include "QskGradient.h"
#include <QSGVertexColorMaterial> #include <QSGVertexColorMaterial>
#include <QSGFlatColorMaterial> #include <QSGFlatColorMaterial>
@ -25,19 +29,21 @@ static inline bool qskIsMonochrome( const QRgb* rgbValues )
&& ( rgbValues[2] == rgbValues[3] ); && ( rgbValues[2] == rgbValues[3] );
} }
static inline uint qskMetricsHash( const QskBoxOptions& options ) static inline uint qskMetricsHash( const QskBoxShapeMetrics& shape,
const QskBoxBorderMetrics& borderMetrics )
{ {
uint hash = 13000; uint hash = 13000;
hash = options.shape.hash( hash ); hash = shape.hash( hash );
return options.border.hash( hash ); return borderMetrics.hash( hash );
} }
static inline uint qskColorsHash( const QskBoxOptions& options ) static inline uint qskColorsHash( const QskBoxBorderColors& borderColors,
const QskGradient& fillGradient )
{ {
uint hash = 13000; uint hash = 13000;
hash = options.borderColors.hash( hash ); hash = borderColors.hash( hash );
return options.fillGradient.hash( hash ); return fillGradient.hash( hash );
} }
QskBoxNode::QskBoxNode(): QskBoxNode::QskBoxNode():
@ -55,11 +61,19 @@ QskBoxNode::~QskBoxNode()
delete material(); delete material();
} }
void QskBoxNode::setBoxData( const QRectF& rect, const QskBoxOptions& options ) void QskBoxNode::setBoxData( const QRectF& rect, const QskGradient& fillGradient )
{
setBoxData( rect, QskBoxShapeMetrics(), QskBoxBorderMetrics(),
QskBoxBorderColors(), fillGradient );
}
void QskBoxNode::setBoxData( const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics,
const QskBoxBorderColors& borderColors, const QskGradient& fillGradient )
{ {
#if 1 #if 1
const uint metricsHash = qskMetricsHash( options ); const uint metricsHash = qskMetricsHash( shape, borderMetrics );
const uint colorsHash = qskColorsHash( options ); const uint colorsHash = qskColorsHash( borderColors, fillGradient );
if ( ( metricsHash == m_metricsHash ) && if ( ( metricsHash == m_metricsHash ) &&
( colorsHash == m_colorsHash ) && ( rect == m_rect ) ) ( colorsHash == m_colorsHash ) && ( rect == m_rect ) )
@ -81,11 +95,7 @@ void QskBoxNode::setBoxData( const QRectF& rect, const QskBoxOptions& options )
return; return;
} }
const auto& gradient = options.fillGradient; bool hasFill = fillGradient.isValid();
const auto& borderMetrics = options.border;
const auto& borderColors = options.borderColors;
bool hasFill = options.fillGradient.isValid();
bool hasBorder = !borderMetrics.isNull(); bool hasBorder = !borderMetrics.isNull();
if ( hasBorder ) if ( hasBorder )
@ -104,14 +114,14 @@ void QskBoxNode::setBoxData( const QRectF& rect, const QskBoxOptions& options )
return; return;
} }
const bool isFillMonochrome = hasFill ? gradient.isMonochrome() : true; const bool isFillMonochrome = hasFill ? fillGradient.isMonochrome() : true;
const bool isBorderMonochrome = hasBorder ? borderColors.isMonochrome() : true; const bool isBorderMonochrome = hasBorder ? borderColors.isMonochrome() : true;
if ( hasFill && hasBorder ) if ( hasFill && hasBorder )
{ {
if ( isFillMonochrome && isBorderMonochrome ) if ( isFillMonochrome && isBorderMonochrome )
{ {
if ( borderColors.color( Qsk::Left ) == gradient.startColor() ) if ( borderColors.color( Qsk::Left ) == fillGradient.startColor() )
{ {
// we can draw border and background in one // we can draw border and background in one
hasBorder = false; hasBorder = false;
@ -143,8 +153,8 @@ void QskBoxNode::setBoxData( const QRectF& rect, const QskBoxOptions& options )
{ {
setMonochrome( false ); setMonochrome( false );
renderer.renderBox( m_rect, options.shape, options.border, renderer.renderBox( m_rect, shape, borderMetrics,
options.borderColors, options.fillGradient, *geometry() ); borderColors, fillGradient, *geometry() );
} }
else else
{ {
@ -155,15 +165,13 @@ void QskBoxNode::setBoxData( const QRectF& rect, const QskBoxOptions& options )
if ( hasFill ) if ( hasFill )
{ {
flatMaterial->setColor( gradient.startColor() ); flatMaterial->setColor( fillGradient.startColor() );
renderer.renderFill( m_rect, options.shape, renderer.renderFill( m_rect, shape, QskBoxBorderMetrics(), *geometry() );
QskBoxBorderMetrics(), *geometry() );
} }
else else
{ {
flatMaterial->setColor( borderColors.color( Qsk::Left ).rgba() ); flatMaterial->setColor( borderColors.color( Qsk::Left ).rgba() );
renderer.renderBorder( m_rect, options.shape, renderer.renderBorder( m_rect, shape, borderMetrics, *geometry() );
options.border, *geometry() );
} }
} }
} }

View File

@ -8,7 +8,10 @@
#include "QskGlobal.h" #include "QskGlobal.h"
class QskBoxOptions; class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxBorderColors;
class QskGradient;
class QRectF; class QRectF;
#include <QSGNode> #include <QSGNode>
@ -19,7 +22,11 @@ public:
QskBoxNode(); QskBoxNode();
virtual ~QskBoxNode(); virtual ~QskBoxNode();
void setBoxData( const QRectF& rect, const QskBoxOptions& ); void setBoxData( const QRectF& rect,
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskBoxBorderColors&, const QskGradient& );
void setBoxData( const QRectF& rect, const QskGradient& );
private: private:
void setMonochrome( bool on ); void setMonochrome( bool on );

View File

@ -31,7 +31,6 @@ DEPENDPATH *= $${QSK_SUBDIRS}
HEADERS += \ HEADERS += \
common/QskAspect.h \ common/QskAspect.h \
common/QskBoxOptions.h \
common/QskBoxBorderColors.h \ common/QskBoxBorderColors.h \
common/QskBoxBorderMetrics.h \ common/QskBoxBorderMetrics.h \
common/QskBoxShapeMetrics.h \ common/QskBoxShapeMetrics.h \
@ -49,7 +48,6 @@ HEADERS += \
SOURCES += \ SOURCES += \
common/QskAspect.cpp \ common/QskAspect.cpp \
common/QskBoxOptions.cpp \
common/QskBoxBorderColors.cpp \ common/QskBoxBorderColors.cpp \
common/QskBoxBorderMetrics.cpp \ common/QskBoxBorderMetrics.cpp \
common/QskBoxShapeMetrics.cpp \ common/QskBoxShapeMetrics.cpp \