QskSkinRenderer removed

This commit is contained in:
Uwe Rathmann 2017-10-20 20:26:39 +02:00
parent a7a5d53821
commit d7d3047141
18 changed files with 320 additions and 402 deletions

View File

@ -3,6 +3,8 @@
#include <QskAspect.h> #include <QskAspect.h>
#include <QskRgbValue.h> #include <QskRgbValue.h>
#include <QskBoxShapeMetrics.h>
#include <QskGradient.h>
#include <QskAnimationHint.h> #include <QskAnimationHint.h>
QSK_SUBCONTROL( Slider, Scale ) QSK_SUBCONTROL( Slider, Scale )
@ -15,7 +17,15 @@ Slider::Slider( QQuickItem* parentItem ):
setMetric( QskSlider::Handle | Size, 80 ); setMetric( QskSlider::Handle | Size, 80 );
setColor( Fill, QskRgbValue::Grey700 ); #if 0
const QskGradient fillGradient( QskGradient::Horizontal,
QskRgbValue::Grey700, QskRgbValue::Grey500 );
#else
const QskGradient fillGradient( QskRgbValue::Grey700 );
#endif
setBoxShapeHint( Fill, 0 );
setGradientHint( Fill, fillGradient );
setColor( Scale, qRgb( 178, 178, 178 ) ); // for the ticks setColor( Scale, qRgb( 178, 178, 178 ) ); // for the ticks
setColor( QskSlider::Handle, QskRgbValue::Grey800 ); setColor( QskSlider::Handle, QskRgbValue::Grey800 );

View File

@ -8,12 +8,12 @@
#include <QskAspect.h> #include <QskAspect.h>
#include <QskSlider.h> #include <QskSlider.h>
#include <QskPlainTextRenderer.h>
#include <QskRgbValue.h> #include <QskRgbValue.h>
#include <QskTextNode.h>
#include <QskTextOptions.h>
#include <QskTextColors.h>
#include <QSGTransformNode>
#include <QSGFlatColorMaterial> #include <QSGFlatColorMaterial>
#include <QSGSimpleRectNode>
#include <QFontMetricsF> #include <QFontMetricsF>
#include <cmath> #include <cmath>
@ -58,7 +58,7 @@ public:
setMaterial( &m_material ); setMaterial( &m_material );
} }
void update( const QRectF& rect, qreal peak, const QColor& color ) void update( const QRectF& rect, qreal peakPos, const QColor& color )
{ {
if ( color != m_color ) if ( color != m_color )
{ {
@ -68,15 +68,15 @@ public:
markDirty( QSGNode::DirtyMaterial ); markDirty( QSGNode::DirtyMaterial );
} }
if ( rect != m_rect || peak != m_peak ) if ( rect != m_rect || peakPos != m_peakPos )
{ {
QSGGeometry::Point2D* p = QSGGeometry::Point2D* p =
reinterpret_cast< QSGGeometry::Point2D* >( m_geometry.vertexData() ); reinterpret_cast< QSGGeometry::Point2D* >( m_geometry.vertexData() );
const qreal y0 = rect.y() + qskPeak; const qreal y0 = rect.y() + qskPeak;
setLine( p, peak, peak, rect.y() ); setLine( p, peakPos, peakPos, rect.y() );
setLine( p + 2, peak - 5, peak + 5, y0 ); setLine( p + 2, peakPos - 5, peakPos + 5, y0 );
// corners manually "rounded" by 3 pixels // corners manually "rounded" by 3 pixels
@ -88,7 +88,7 @@ public:
setLine( p + 14, rect.left() + 2, rect.right() - 2, rect.bottom() ); setLine( p + 14, rect.left() + 2, rect.right() - 2, rect.bottom() );
m_rect = rect; m_rect = rect;
m_peak = peak; m_peakPos = peakPos;
markDirty( QSGNode::DirtyGeometry ); markDirty( QSGNode::DirtyGeometry );
} }
} }
@ -104,7 +104,7 @@ private:
} }
QRectF m_rect; QRectF m_rect;
qreal m_peak; qreal m_peakPos;
QColor m_color; QColor m_color;
QSGFlatColorMaterial m_material; QSGFlatColorMaterial m_material;
@ -164,7 +164,7 @@ QSGNode* SliderSkinlet::updateSubNode(
return updateDecorationNode( slider, node ); return updateDecorationNode( slider, node );
case FillRole: case FillRole:
return updateFillNode( slider, node ); return Inherited::updateSubNode( skinnable, nodeRole, node );
case HandleRole: case HandleRole:
return updateHandleNode( slider, node ); return updateHandleNode( slider, node );
@ -224,12 +224,6 @@ QRectF SliderSkinlet::handleRect( const QskSlider* slider ) const
return handleRect; return handleRect;
} }
QSGNode* SliderSkinlet::updateGrooveNode( const QskSlider*, QSGNode* ) const
{
// we don't have a groove
return nullptr;
}
QSGNode* SliderSkinlet::updateScaleNode( QSGNode* SliderSkinlet::updateScaleNode(
const QskSlider* slider, QSGNode* node ) const const QskSlider* slider, QSGNode* node ) const
{ {
@ -284,7 +278,7 @@ QSGNode* SliderSkinlet::updateDecorationNode(
const int tickCount = std::floor( slider->range() / slider->stepSize() ) + 1; const int tickCount = std::floor( slider->range() / slider->stepSize() ) + 1;
auto labelNode = static_cast< QSGTransformNode* >( decorationNode->firstChild() ); auto labelNode = static_cast< QskTextNode* >( decorationNode->firstChild() );
auto stepStride = slider->stepSize() / slider->range() * decorationRect.width(); auto stepStride = slider->stepSize() / slider->range() * decorationRect.width();
@ -295,24 +289,17 @@ QSGNode* SliderSkinlet::updateDecorationNode(
{ {
if ( labelNode == nullptr ) if ( labelNode == nullptr )
{ {
labelNode = new QSGTransformNode; labelNode = new QskTextNode;
decorationNode->appendChildNode( labelNode ); decorationNode->appendChildNode( labelNode );
} }
auto labelText = QString::number( slider->minimum() + slider->stepSize() * i, 'f', 0 ); auto labelText = QString::number( slider->minimum() + slider->stepSize() * i, 'f', 0 );
QskPlainTextRenderer renderer; labelNode->setTextData( slider, labelText, QRectF( x, y, 0, 0 ),
renderer.setFont( qskLabelFont ); qskLabelFont, QskTextOptions(), QskTextColors( QskRgbValue::Grey700 ),
renderer.setAlignment( Qt::AlignHCenter ); Qt::AlignHCenter, Qsk::Normal );
renderer.updateNode( slider, QRectF(), labelText, labelNode,
QskRgbValue::Grey700, Qsk::Normal, Qt::transparent );
QMatrix4x4 matrix;
matrix.translate( x, y );
labelNode->setMatrix( matrix );
labelNode = static_cast< decltype( labelNode ) >( labelNode->nextSibling() ); labelNode = static_cast< decltype( labelNode ) >( labelNode->nextSibling() );
x += 100 * stepStride; x += 100 * stepStride;
} }
@ -328,28 +315,6 @@ QSGNode* SliderSkinlet::updateDecorationNode(
return decorationNode; return decorationNode;
} }
QSGNode* SliderSkinlet::updateFillNode(
const QskSlider* slider, QSGNode* node ) const
{
const QRectF fillRect = subControlRect( slider, QskSlider::Fill );
if ( fillRect.isEmpty() )
return nullptr;
QSGSimpleRectNode* fillNode = static_cast< QSGSimpleRectNode* >( node );
if ( fillNode == nullptr )
{
fillNode = new QSGSimpleRectNode;
fillNode->setFlags( QSGNode::OwnedByParent );
fillNode->setColor( slider->color( QskSlider::Fill ) );
}
fillNode->setRect( fillRect );
fillNode->markDirty( QSGNode::DirtyForceUpdate );
return fillNode;
}
QSGNode* SliderSkinlet::updateHandleNode( QSGNode* SliderSkinlet::updateHandleNode(
const QskSlider* slider, QSGNode* node ) const const QskSlider* slider, QSGNode* node ) const
{ {
@ -367,31 +332,26 @@ QSGNode* SliderSkinlet::updateHandleNode(
slider->color( QskSlider::Handle ) ); slider->color( QskSlider::Handle ) );
// finally the value label // finally the value label
auto labelNode = static_cast< QSGTransformNode* >( handleNode->firstChild() ); auto labelNode = static_cast< QskTextNode* >( handleNode->firstChild() );
if ( labelNode == nullptr ) if ( labelNode == nullptr )
{ {
labelNode = new QSGTransformNode; labelNode = new QskTextNode;
handleNode->appendChildNode( labelNode ); handleNode->appendChildNode( labelNode );
} }
QFont font( QStringLiteral( "Roboto" ) ); QFont font( QStringLiteral( "Roboto" ) );
font.setPixelSize( 26 ); font.setPixelSize( 26 );
QskPlainTextRenderer renderer;
renderer.setFont( font );
renderer.setAlignment( Qt::AlignHCenter );
renderer.updateNode( slider, handleRect.size(),
QString::number( slider->value(), 'f', 0 ),
labelNode, Qt::white, Qsk::Normal, Qt::transparent );
#if 1
const qreal h = QFontMetrics( font ).height(); const qreal h = QFontMetrics( font ).height();
qreal y = handleRect.bottom() - 0.5 * ( handleRect.height() - qskPeak + h );
QMatrix4x4 matrix; auto textRect = handleRect;
matrix.translate( handleRect.x(), y ); textRect.setTop( textRect.bottom() - 0.5 * ( textRect.height() - qskPeak + h ) );
labelNode->setMatrix( matrix );
#endif const QString text = QString::number( slider->value(), 'f', 0 );
labelNode->setTextData( slider, text, textRect,
font, QskTextOptions(), QskTextColors( Qt::white ),
Qt::AlignHCenter, Qsk::Normal );
return handleNode; return handleNode;
} }

View File

@ -17,7 +17,7 @@ class SliderSkinlet : public QskSliderSkinlet
public: public:
enum NodeRole enum NodeRole
{ {
// we have a scale instead of the groove // we have a scale instead of a groove
ScaleRole = QskSliderSkinlet::HandleRole + 1, ScaleRole = QskSliderSkinlet::HandleRole + 1,
DecorationRole DecorationRole
}; };
@ -32,20 +32,15 @@ protected:
virtual QSGNode* updateSubNode( virtual QSGNode* updateSubNode(
const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override; const QskSkinnable*, quint8 nodeRole, QSGNode* ) const override;
virtual QSGNode* updateScaleNode( const QskSlider*, QSGNode* ) const;
virtual QSGNode* updateDecorationNode( const QskSlider*, QSGNode* ) const;
QSGNode* updateFillNode( const QskSlider*, QSGNode* ) const;
QSGNode* updateHandleNode( const QskSlider*, QSGNode* ) const;
QSGNode* updateGrooveNode( const QskSlider*, QSGNode* ) const;
private: private:
QSGNode* updateScaleNode( const QskSlider*, QSGNode* ) const;
QSGNode* updateDecorationNode( const QskSlider*, QSGNode* ) const;
QSGNode* updateHandleNode( const QskSlider*, QSGNode* ) const;
QRectF fillRect( const QskSlider* ) const; QRectF fillRect( const QskSlider* ) const;
QRectF scaleRect( const QskSlider* ) const; QRectF scaleRect( const QskSlider* ) const;
QRectF decorationRect( const QskSlider* ) const; QRectF decorationRect( const QskSlider* ) const;
QRectF handleRect( const QskSlider* ) const; QRectF handleRect( const QskSlider* ) const;
void updateHandleLabel( const QskSlider*, QSGTransformNode* ) const;
}; };
#endif #endif

View File

@ -10,7 +10,6 @@
#include "QskAspect.h" #include "QskAspect.h"
#include "QskSkin.h" #include "QskSkin.h"
#include "QskSkinRenderer.h"
#include "QskTextOptions.h" #include "QskTextOptions.h"
#include "QskTextNode.h" #include "QskTextNode.h"
#include "QskBoxNode.h" #include "QskBoxNode.h"
@ -146,6 +145,7 @@ QSGNode* QskInputPanelSkinlet::updatePanelNode(
const auto rowIndex = &keyRow - panelKeyData; const auto rowIndex = &keyRow - panelKeyData;
auto& frames = panelNode->frames[ rowIndex ]; auto& frames = panelNode->frames[ rowIndex ];
auto& glyphs = panelNode->glyphs[ rowIndex ]; auto& glyphs = panelNode->glyphs[ rowIndex ];
for ( const auto& keyData : keyRow ) for ( const auto& keyData : keyRow )
{ {
const auto colIndex = &keyData - keyRow; const auto colIndex = &keyData - keyRow;
@ -217,10 +217,8 @@ QSGNode* QskInputPanelSkinlet::updateKeyGlyphNode(
const auto alignment = textNode->flagHint< Qt::Alignment >( const auto alignment = textNode->flagHint< Qt::Alignment >(
QskInputPanel::KeyGlyph | QskAspect::Alignment, Qt::AlignCenter ); QskInputPanel::KeyGlyph | QskAspect::Alignment, Qt::AlignCenter );
QskSkinRenderer::updateText( textNode, rect, alignment, return updateTextNode( panel, textNode, rect, alignment,
panel->textForKey( key ), options, textNode, QskInputPanel::KeyGlyph ); panel->textForKey( key ), options, QskInputPanel::KeyGlyph );
return textNode;
} }
#include "moc_QskInputPanelSkinlet.cpp" #include "moc_QskInputPanelSkinlet.cpp"

View File

@ -6,7 +6,6 @@
#include "QskListViewSkinlet.h" #include "QskListViewSkinlet.h"
#include "QskListView.h" #include "QskListView.h"
#include "QskAspect.h" #include "QskAspect.h"
#include "QskSkinRenderer.h"
#include "QskTextOptions.h" #include "QskTextOptions.h"
#include "QskTextNode.h" #include "QskTextNode.h"
#include "QskGraphic.h" #include "QskGraphic.h"

View File

@ -1,152 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskSkinRenderer.h"
#include "QskSkinnable.h"
#include "QskControl.h"
#include "QskTextRenderer.h"
#include "QskPlainTextRenderer.h"
#include "QskTextNode.h"
#include <QMatrix4x4>
QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable,
const QString& text, const QskTextOptions& options,
QskAspect::Subcontrol subControl )
{
using namespace QskAspect;
auto font = skinnable->effectiveFont( subControl );
if ( options.effectiveFormat( text ) == QskTextOptions::PlainText )
{
QskPlainTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textSize( text );
}
else
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textSize( text );
}
}
QSizeF QskSkinRenderer::textSize( const QskSkinnable* skinnable,
const QSizeF& boundingSize, const QString& text,
const QskTextOptions& options, QskAspect::Subcontrol subControl )
{
const auto font = skinnable->effectiveFont( subControl );
if ( options.effectiveFormat( text ) == QskTextOptions::PlainText )
{
QskPlainTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textRect( boundingSize, text ).size();
}
else
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textRect( boundingSize, text ).size();
}
}
void QskSkinRenderer::updateText( const QskSkinnable* skinnable,
const QRectF& bounds, Qt::Alignment alignment,
const QString& text, const QskTextOptions& options,
QskTextNode* textNode, QskAspect::Subcontrol subControl )
{
using namespace QskAspect;
QMatrix4x4 matrix;
matrix.translate( bounds.left(), bounds.top() );
textNode->setMatrix( matrix );
QskSkinHintStatus status;
auto textColor = skinnable->color( subControl, &status );
if ( !status.isValid() )
textColor = skinnable->color( subControl | QskAspect::TextColor );
auto font = skinnable->effectiveFont( subControl );
auto styleColor = skinnable->color( subControl | StyleColor );
auto textStyle = Qsk::Normal;
if ( styleColor.alpha() == 0 )
{
textStyle = skinnable->flagHint< Qsk::TextStyle >(
subControl | Style, Qsk::Normal );
}
const auto isPlainText = options.effectiveFormat( text ) == QskTextOptions::PlainText;
// doesn't work - we end up with a black rectangle TODO ...
#if 0
// Optimization: only update the color if that is all that has changed
if ( isPlainText && color_is_dirty )
{
QskPlainTextRenderer::updateNodeColor( parentNode, textRgb,
fontOptions.textStyle, styleRgb );
return;
}
#endif
switch ( options.fontSizeMode() )
{
case QskTextOptions::FixedSize:
break;
case QskTextOptions::HorizontalFit:
Q_UNIMPLEMENTED();
break;
case QskTextOptions::VerticalFit:
font.setPixelSize( bounds.height() * 0.5 );
break;
case QskTextOptions::Fit:
Q_UNIMPLEMENTED();
break;
}
QColor linkColor;
if ( !isPlainText )
linkColor = skinnable->color( subControl | LinkColor );
if ( textNode->setTextData( text, bounds.size(), font,
options, alignment, textStyle, textColor, styleColor, linkColor ) )
{
if ( isPlainText )
{
QskPlainTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
renderer.setAlignment( alignment );
renderer.updateNode( skinnable->owningControl(), bounds.size(),
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 );
}
}
}

View File

@ -1,41 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_SKIN_RENDERER_H
#define QSK_SKIN_RENDERER_H
#include "QskGlobal.h"
#include "QskAspect.h"
#include <Qt>
class QskSkinnable;
class QskTextOptions;
class QskTextNode;
class QPointF;
class QRectF;
class QSizeF;
class QString;
namespace QskSkinRenderer
{
// a loose collection of functions, waiting to be
// organized somehow. TODO ...
QSK_EXPORT void updateText( const QskSkinnable*,
const QRectF&, Qt::Alignment,
const QString&, const QskTextOptions&,
QskTextNode*, QskAspect::Subcontrol );
QSK_EXPORT QSizeF textSize( const QskSkinnable*,
const QString&, const QskTextOptions&, QskAspect::Subcontrol );
QSK_EXPORT QSizeF textSize( const QskSkinnable*,
const QSizeF& boundingSize, const QString&,
const QskTextOptions&, QskAspect::Subcontrol );
}
#endif

View File

@ -13,10 +13,11 @@
#include "QskBoxBorderMetrics.h" #include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h" #include "QskBoxBorderColors.h"
#include "QskGradient.h" #include "QskGradient.h"
#include "QskSkinRenderer.h"
#include "QskBoxNode.h" #include "QskBoxNode.h"
#include "QskBoxClipNode.h" #include "QskBoxClipNode.h"
#include "QskTextNode.h" #include "QskTextNode.h"
#include "QskTextColors.h"
#include "QskTextOptions.h"
#include "QskGraphicNode.h" #include "QskGraphicNode.h"
#include "QskGraphicTextureFactory.h" #include "QskGraphicTextureFactory.h"
#include "QskFunctions.h" #include "QskFunctions.h"
@ -89,6 +90,31 @@ static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics,
return !borderMetrics.isNull() && borderColors.isVisible(); return !borderMetrics.isNull() && borderColors.isVisible();
} }
static inline QskTextColors qskTextColors(
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl )
{
using namespace QskAspect;
/*
Would be more efficient to have QskTextColors hints instead of
storing the colors as seperated hints. TODO ...
*/
QskSkinHintStatus status;
QskTextColors c;
c.textColor = skinnable->color( subControl, &status );
#if 1
if ( !status.isValid() )
c.textColor = skinnable->color( subControl | QskAspect::TextColor );
#endif
c.styleColor = skinnable->color( subControl | StyleColor );
c.linkColor = skinnable->color( subControl | LinkColor );
return c;
}
class QskSkinlet::PrivateData class QskSkinlet::PrivateData
{ {
public: public:
@ -428,8 +454,37 @@ QSGNode* QskSkinlet::updateTextNode(
if ( textNode == nullptr ) if ( textNode == nullptr )
textNode = new QskTextNode(); textNode = new QskTextNode();
QskSkinRenderer::updateText( skinnable, rect, alignment, auto colors = qskTextColors( skinnable, subControl );
text, textOptions, textNode, subControl );
auto textStyle = Qsk::Normal;
if ( colors.styleColor.alpha() == 0 )
{
textStyle = skinnable->flagHint< Qsk::TextStyle >(
subControl | QskAspect::Style, Qsk::Normal );
}
auto font = skinnable->effectiveFont( subControl );
switch ( textOptions.fontSizeMode() )
{
case QskTextOptions::FixedSize:
break;
case QskTextOptions::HorizontalFit:
Q_UNIMPLEMENTED();
break;
case QskTextOptions::VerticalFit:
font.setPixelSize( rect.height() * 0.5 );
break;
case QskTextOptions::Fit:
Q_UNIMPLEMENTED();
break;
}
textNode->setTextData( skinnable->owningControl(),
text, rect, font, textOptions, colors, alignment, textStyle );
return textNode; return textNode;
} }

View File

@ -16,7 +16,6 @@
#include "QskControl.h" #include "QskControl.h"
#include "QskColorFilter.h" #include "QskColorFilter.h"
#include "QskSkinTransition.h" #include "QskSkinTransition.h"
#include "QskSkinRenderer.h"
#include <QFont> #include <QFont>
#include <QElapsedTimer> #include <QElapsedTimer>

View File

@ -6,7 +6,7 @@
#include "QskTextLabel.h" #include "QskTextLabel.h"
#include "QskAspect.h" #include "QskAspect.h"
#include "QskTextOptions.h" #include "QskTextOptions.h"
#include "QskSkinRenderer.h" #include "QskTextNode.h"
#include <QFontMetricsF> #include <QFontMetricsF>
#include <QtMath> #include <QtMath>
@ -172,8 +172,9 @@ QSizeF QskTextLabel::contentsSizeHint() const
{ {
if ( !m_data->text.isEmpty() ) if ( !m_data->text.isEmpty() )
{ {
return QskSkinRenderer::textSize( this, m_data->text, const auto font = effectiveFont( Text );
m_data->effectiveOptions(), QskTextLabel::Text ); return QskTextNode::textSize(
m_data->text, font, m_data->effectiveOptions() );
} }
return QSizeF( 0, 0 ); return QSizeF( 0, 0 );
@ -181,7 +182,8 @@ QSizeF QskTextLabel::contentsSizeHint() const
qreal QskTextLabel::heightForWidth( qreal width ) const qreal QskTextLabel::heightForWidth( qreal width ) const
{ {
const qreal lineHeight = QFontMetricsF( effectiveFont( Text ) ).height(); const auto font = effectiveFont( Text );
const qreal lineHeight = QFontMetricsF( font ).height();
if ( m_data->text.isEmpty() || if ( m_data->text.isEmpty() ||
( m_data->textOptions.wrapMode() == QskTextOptions::NoWrap ) ) ( m_data->textOptions.wrapMode() == QskTextOptions::NoWrap ) )
@ -196,9 +198,8 @@ qreal QskTextLabel::heightForWidth( qreal width ) const
maxHeight = m_data->textOptions.maximumLineCount() * lineHeight; maxHeight = m_data->textOptions.maximumLineCount() * lineHeight;
} }
const QSizeF size = QskSkinRenderer::textSize( this, QSizeF size( width, maxHeight );
QSizeF( width, maxHeight ), m_data->text, size = QskTextNode::textSize( m_data->text, font, size, m_data->effectiveOptions() );
m_data->effectiveOptions(), QskTextLabel::Text );
return qCeil( size.height() ); return qCeil( size.height() );
} }
@ -211,11 +212,11 @@ qreal QskTextLabel::widthForHeight( qreal height ) const
return Inherited::widthForHeight( height ); return Inherited::widthForHeight( height );
} }
const auto font = effectiveFont( Text );
const qreal maxWidth = std::numeric_limits< qreal >::max(); const qreal maxWidth = std::numeric_limits< qreal >::max();
const QSizeF size = QskSkinRenderer::textSize( this, QSizeF size( maxWidth, height );
QSizeF( maxWidth, height ), m_data->text, size = QskTextNode::textSize( m_data->text, font, size, m_data->effectiveOptions() );
m_data->effectiveOptions(), QskTextLabel::Text );
return qCeil( size.width() ); return qCeil( size.width() );
} }

View File

@ -10,6 +10,7 @@
#include "QskBoxBorderMetrics.h" #include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h" #include "QskBoxBorderColors.h"
#include "QskGradient.h" #include "QskGradient.h"
#include "QskTextColors.h"
// Even if we don't use the standard Qt animation system we // Even if we don't use the standard Qt animation system we
// use its registry of interpolators: why adding our own ... // use its registry of interpolators: why adding our own ...
@ -26,6 +27,7 @@ static void qskRegisterInterpolator()
qRegisterAnimationInterpolator<QskBoxShapeMetrics>( QskBoxShapeMetrics::interpolate ); qRegisterAnimationInterpolator<QskBoxShapeMetrics>( QskBoxShapeMetrics::interpolate );
qRegisterAnimationInterpolator<QskBoxBorderMetrics>( QskBoxBorderMetrics::interpolate ); qRegisterAnimationInterpolator<QskBoxBorderMetrics>( QskBoxBorderMetrics::interpolate );
qRegisterAnimationInterpolator<QskBoxBorderColors>( QskBoxBorderColors::interpolate ); qRegisterAnimationInterpolator<QskBoxBorderColors>( QskBoxBorderColors::interpolate );
qRegisterAnimationInterpolator<QskTextColors>( QskTextColors::interpolate );
} }
Q_CONSTRUCTOR_FUNCTION( qskRegisterInterpolator ) Q_CONSTRUCTOR_FUNCTION( qskRegisterInterpolator )

View File

@ -5,6 +5,7 @@
#include "QskPlainTextRenderer.h" #include "QskPlainTextRenderer.h"
#include "QskSkinlet.h" #include "QskSkinlet.h"
#include "QskTextColors.h"
#include <QFontMetrics> #include <QFontMetrics>
#include <QGuiApplication> #include <QGuiApplication>
@ -175,9 +176,9 @@ static void qskRenderText(
} }
} }
void QskPlainTextRenderer::updateNode( void QskPlainTextRenderer::updateNode( const QString& text,
const QQuickItem* item, const QRectF& rect, const QString& text, QSGNode* parentNode, const QRectF& rect, Qsk::TextStyle style, const QskTextColors& colors,
const QColor& textColor, Qsk::TextStyle style, const QColor& styleColor ) const QQuickItem* item, QSGTransformNode* node )
{ {
QTextOption textOption( m_alignment ); QTextOption textOption( m_alignment );
textOption.setWrapMode( static_cast< QTextOption::WrapMode >( m_options.wrapMode() ) ); textOption.setWrapMode( static_cast< QTextOption::WrapMode >( m_options.wrapMode() ) );
@ -197,8 +198,16 @@ void QskPlainTextRenderer::updateNode(
+ ( m_alignment & Qt::AlignVCenter + ( m_alignment & Qt::AlignVCenter
? ( rect.height() - position.y() ) * 0.5 : 0 ) ); ? ( rect.height() - position.y() ) * 0.5 : 0 ) );
qskRenderText( const_cast< QQuickItem* >( item ), parentNode, &layout, position, qskRenderText( const_cast< QQuickItem* >( item ), node, &layout, position,
textColor, static_cast< QQuickText::TextStyle >( style ), styleColor ); colors.textColor, static_cast< QQuickText::TextStyle >( style ), colors.styleColor );
}
void QskPlainTextRenderer::updateNode( const QString& text,
const QSizeF& size, Qsk::TextStyle style, const QskTextColors& colors,
const QQuickItem* item, QSGTransformNode* node )
{
const QRectF textRect( 0, 0, size.width(), size.height() );
updateNode( text, textRect, style, colors, item, node );
} }
void QskPlainTextRenderer::updateNodeColor( QSGNode* parentNode, const QColor& textColor, void QskPlainTextRenderer::updateNodeColor( QSGNode* parentNode, const QColor& textColor,

View File

@ -13,9 +13,13 @@
#include <QFont> #include <QFont>
#include <QFontMetricsF> #include <QFontMetricsF>
class QskTextColors;
class QSGNode; class QSGNode;
class QQuickItem; class QQuickItem;
class QColor; class QColor;
class QSGTransformNode;
class QQuickItem;
class QSK_EXPORT QskPlainTextRenderer class QSK_EXPORT QskPlainTextRenderer
{ {
@ -27,13 +31,13 @@ public:
void setOptions( const QskTextOptions& ); void setOptions( const QskTextOptions& );
void setAlignment( Qt::Alignment ); void setAlignment( Qt::Alignment );
void updateNode( void updateNode( const QString&, const QSizeF&,
const QQuickItem*, const QRectF&, const QString&, QSGNode* parentNode, Qsk::TextStyle, const QskTextColors&,
const QColor& textColor, Qsk::TextStyle, const QColor& styleColor ); const QQuickItem*, QSGTransformNode* );
void updateNode( void updateNode( const QString&, const QRectF&,
const QQuickItem*, const QSizeF& size, const QString&, QSGNode* parentNode, Qsk::TextStyle, const QskTextColors&,
const QColor& textColor, Qsk::TextStyle, const QColor& styleColor ); const QQuickItem*, QSGTransformNode* );
static void updateNodeColor( QSGNode* parentNode, static void updateNodeColor( QSGNode* parentNode,
const QColor& textColor, Qsk::TextStyle, const QColor& styleColor ); const QColor& textColor, Qsk::TextStyle, const QColor& styleColor );
@ -50,12 +54,4 @@ private:
Qt::Alignment m_alignment; Qt::Alignment m_alignment;
}; };
inline void QskPlainTextRenderer::updateNode(
const QQuickItem* item, const QSizeF& size, const QString& text, QSGNode* parentNode,
const QColor& textColor, Qsk::TextStyle style, const QColor& styleColor )
{
updateNode( item, QRectF( QPointF(), size ),
text, parentNode, textColor, style, styleColor );
}
#endif #endif

View File

@ -5,11 +5,32 @@
#include "QskTextNode.h" #include "QskTextNode.h"
#include "QskTextOptions.h" #include "QskTextOptions.h"
#include "QskTextColors.h"
#include "QskTextRenderer.h"
#include "QskPlainTextRenderer.h"
#include <QFont> #include <QFont>
#include <QColor> #include <QColor>
#include <QString> #include <QString>
static inline uint qskHash(
const QString& text, const QSizeF& size, const QFont& font,
const QskTextOptions& options, const QskTextColors& colors,
Qt::Alignment alignment, Qsk::TextStyle textStyle )
{
uint hash = 11000;
hash = qHash( text, hash );
hash = qHash( font, hash );
hash = qHash( options, hash );
hash = qHash( alignment, hash );
hash = qHash( textStyle, hash );
hash = colors.hash( hash );
hash = qHashBits( &size, sizeof( QSizeF ), hash );
return hash;
}
QskTextNode::QskTextNode(): QskTextNode::QskTextNode():
m_hash( 0 ) m_hash( 0 )
{ {
@ -19,26 +40,99 @@ QskTextNode::~QskTextNode()
{ {
} }
bool QskTextNode::setTextData( void QskTextNode::setTextData( const QQuickItem* item,
const QString& text, const QSizeF& size, const QFont& font, const QString& text, const QRectF& rect, const QFont& font,
const QskTextOptions& options, Qt::Alignment alignment, Qsk::TextStyle textStyle, const QskTextOptions& options, const QskTextColors& colors,
const QColor& textColor, const QColor& styleColor, const QColor& linkColor ) Qt::Alignment alignment, Qsk::TextStyle textStyle )
{ {
uint hash; if ( m_rect != rect )
{
QMatrix4x4 matrix;
matrix.translate( rect.left(), rect.top() );
hash = qHash( text, 0 ); if ( matrix != this->matrix() ) // avoid setting DirtyMatrix accidently
hash = qHash( font, hash ); setMatrix( matrix );
hash = qHash( options, hash ); }
hash = qHash( alignment, hash );
hash = qHash( textStyle, hash ); const uint hash = qskHash( text, rect.size(), font,
hash = qHash( textColor.rgba(), hash ); options, colors, alignment, textStyle );
hash = qHash( styleColor.rgba(), hash );
hash = qHash( linkColor.rgba(), hash );
hash = qHashBits( &size, sizeof( QSizeF ), hash );
if ( hash == m_hash ) if ( hash == m_hash )
return false; return;
m_hash = hash; m_hash = hash;
return true;
const QRectF textRect( 0, 0, rect.width(), rect.height() );
if ( options.format() == QskTextOptions::PlainText )
{
#if 0
if ( colors_only )
{
// doesn't work - we end up with a black rectangle TODO ...
QskPlainTextRenderer::updateNodeColor( parentNode, textRgb,
fontOptions.textStyle, styleRgb );
return;
} }
#endif
QskPlainTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
renderer.setAlignment( alignment );
renderer.updateNode( text, textRect, textStyle, colors, item, this );
}
else
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
renderer.setAlignment( alignment );
renderer.updateNode( text, textRect, textStyle, colors, item, this );
}
}
QSizeF QskTextNode::textSize( const QString& text,
const QFont& font, const QskTextOptions& options )
{
if ( options.effectiveFormat( text ) == QskTextOptions::PlainText )
{
QskPlainTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textSize( text );
}
else
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textSize( text );
}
}
QSizeF QskTextNode::textSize( const QString& text, const QFont& font,
const QSizeF& boundingSize, const QskTextOptions& options )
{
if ( options.effectiveFormat( text ) == QskTextOptions::PlainText )
{
QskPlainTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textRect( boundingSize, text ).size();
}
else
{
QskTextRenderer renderer;
renderer.setFont( font );
renderer.setOptions( options );
return renderer.textRect( boundingSize, text ).size();
}
}

View File

@ -10,10 +10,13 @@
#include "QskNamespace.h" #include "QskNamespace.h"
#include <QSGTransformNode> #include <QSGTransformNode>
#include <Qt> #include <QRectF>
class QskTextOptions; class QskTextOptions;
class QskTextColors;
class QString; class QString;
class QFont;
class QQuickItem;
class QSK_EXPORT QskTextNode : public QSGTransformNode class QSK_EXPORT QskTextNode : public QSGTransformNode
{ {
@ -21,10 +24,22 @@ public:
QskTextNode(); QskTextNode();
virtual ~QskTextNode(); virtual ~QskTextNode();
bool setTextData( const QString& text, const QSizeF&, const QFont&, void setTextData( const QQuickItem* item,
const QskTextOptions&, Qt::Alignment, Qsk::TextStyle, const QString& text, const QRectF&, const QFont&,
const QColor& textColor, const QColor& styleColor, const QColor& linkColor ); const QskTextOptions&, const QskTextColors&,
Qt::Alignment, Qsk::TextStyle );
#if 1
// for the moment here TODO ...
static QSizeF textSize( const QString&,
const QFont&, const QskTextOptions& );
static QSizeF textSize( const QString&, const QFont&,
const QSizeF&, const QskTextOptions& );
#endif
private: private:
QRectF m_rect;
uint m_hash; uint m_hash;
}; };

View File

@ -4,6 +4,8 @@
*****************************************************************************/ *****************************************************************************/
#include "QskTextRenderer.h" #include "QskTextRenderer.h"
#include "QskTextColors.h"
#include <QQuickWindow> #include <QQuickWindow>
QSK_QT_PRIVATE_BEGIN QSK_QT_PRIVATE_BEGIN
@ -16,39 +18,24 @@ QSK_QT_PRIVATE_END
class QskTextHelperItem final : public QQuickText class QskTextHelperItem final : public QQuickText
{ {
public: public:
QskTextHelperItem();
void refWindow( QQuickWindow* window ); void refWindow( QQuickWindow* window );
void derefWindow(); void derefWindow();
void begin(); void begin() { classBegin(); }
void end(); void end() { componentComplete(); }
QRectF layedOutTextRect() const; QRectF layedOutTextRect() const
void updateTextNode( QQuickWindow*, QSGNode* );
protected:
virtual QSGNode* updatePaintNode(
QSGNode*, UpdatePaintNodeData* ) override final;
};
QskTextHelperItem::QskTextHelperItem():
QQuickText( nullptr )
{
}
QRectF QskTextHelperItem::layedOutTextRect() const
{ {
auto that = const_cast< QskTextHelperItem* >( this ); auto that = const_cast< QskTextHelperItem* >( this );
return QQuickTextPrivate::get( that )->layedOutTextRect; return QQuickTextPrivate::get( that )->layedOutTextRect;
} }
void QskTextHelperItem::updateTextNode( QQuickWindow* window, QSGNode* parentNode ) void updateTextNode( QQuickWindow* window, QSGNode* parentNode )
{ {
QQuickItemPrivate::get( this )->refWindow( window ); QQuickItemPrivate::get( this )->refWindow( window );
while ( parentNode->firstChild() ) while ( parentNode->firstChild() )
delete parentNode->firstChild(); // This is done in QQuickText::updatePaintNode anyway delete parentNode->firstChild();
auto node = QQuickText::updatePaintNode( nullptr, nullptr ); auto node = QQuickText::updatePaintNode( nullptr, nullptr );
node->reparentChildNodesTo( parentNode ); node->reparentChildNodesTo( parentNode );
@ -56,22 +43,14 @@ void QskTextHelperItem::updateTextNode( QQuickWindow* window, QSGNode* parentNod
QQuickItemPrivate::get( this )->derefWindow(); QQuickItemPrivate::get( this )->derefWindow();
} }
protected:
void QskTextHelperItem::begin() virtual QSGNode* updatePaintNode(
{ QSGNode*, UpdatePaintNodeData* ) override final
classBegin();
}
void QskTextHelperItem::end()
{
componentComplete();
}
QSGNode* QskTextHelperItem::updatePaintNode( QSGNode*, UpdatePaintNodeData* )
{ {
// should never be called // should never be called
return nullptr; return nullptr;
} }
};
/* /*
size requests and rendering might be from different threads and we size requests and rendering might be from different threads and we
@ -171,13 +150,12 @@ void QskTextRenderer::setupItem( QskTextHelperItem* textItem ) const
#endif #endif
} }
void QskTextRenderer::updateNode( const QQuickItem* item, void QskTextRenderer::updateNode( const QString& text,
const QRectF& rect, const QString& text, QSGTransformNode* parentNode, const QRectF& rect, Qsk::TextStyle style, const QskTextColors& colors,
const QColor& textColor, Qsk::TextStyle style, const QColor& styleColor, const QQuickItem* item, QSGTransformNode* node )
const QColor& linkColor )
{ {
// are we killing internal caches of QQuickText, when always using // are we killing internal caches of QQuickText, when always using
// the same item for the creation the text nodes ??? // the same item for the creation the text nodes. TODO ...
if ( qskRenderHelper == NULL ) if ( qskRenderHelper == NULL )
qskRenderHelper = new QskTextHelperItem(); qskRenderHelper = new QskTextHelperItem();
@ -204,16 +182,23 @@ void QskTextRenderer::updateNode( const QQuickItem* item,
textItem.doLayout(); textItem.doLayout();
} }
textItem.setColor( textColor ); textItem.setColor( colors.textColor );
textItem.setStyle( static_cast< QQuickText::TextStyle >( style ) ); textItem.setStyle( static_cast< QQuickText::TextStyle >( style ) );
textItem.setStyleColor( styleColor ); textItem.setStyleColor( colors.styleColor );
textItem.setLinkColor( linkColor ); textItem.setLinkColor( colors.linkColor );
textItem.setText( text ); textItem.setText( text );
textItem.end(); textItem.end();
textItem.updateTextNode( item->window(), parentNode ); textItem.updateTextNode( item->window(), node );
textItem.setText( QString::null ); textItem.setText( QString::null );
} }
void QskTextRenderer::updateNode( const QString& text,
const QSizeF& size, Qsk::TextStyle style, const QskTextColors& colors,
const QQuickItem* item, QSGTransformNode* node )
{
const QRectF textRect( 0, 0, size.width(), size.height() );
updateNode( text, textRect, style, colors, item, node );
}

View File

@ -14,6 +14,7 @@
#include <QRectF> #include <QRectF>
class QskTextHelperItem; class QskTextHelperItem;
class QskTextColors;
class QQuickItem; class QQuickItem;
class QQuickWindow; class QQuickWindow;
@ -31,13 +32,13 @@ public:
void setOptions( const QskTextOptions& ); void setOptions( const QskTextOptions& );
void setAlignment( Qt::Alignment ); void setAlignment( Qt::Alignment );
void updateNode( const QQuickItem*, const QSizeF&, const QString&, void updateNode( const QString&, const QSizeF&,
QSGTransformNode*, const QColor& textColor, Qsk::TextStyle, const QskTextColors&,
Qsk::TextStyle, const QColor& styleColor, const QColor& linkColor ); const QQuickItem*, QSGTransformNode* );
void updateNode( const QQuickItem*, const QRectF&, const QString&, void updateNode( const QString&, const QRectF&,
QSGTransformNode*, const QColor& textColor, Qsk::TextStyle, Qsk::TextStyle, const QskTextColors&,
const QColor& styleColor, const QColor& linkColor ); const QQuickItem*, QSGTransformNode* );
QSizeF textSize( const QString& ) const; QSizeF textSize( const QString& ) const;
QRectF textRect( const QSizeF&, const QString& ) const; QRectF textRect( const QSizeF&, const QString& ) const;
@ -50,12 +51,4 @@ private:
Qt::Alignment m_alignment; Qt::Alignment m_alignment;
}; };
inline void QskTextRenderer::updateNode( const QQuickItem* item, const QSizeF& size,
const QString& text, QSGTransformNode* node, const QColor& textColor,
Qsk::TextStyle style, const QColor& styleColor, const QColor& linkColor )
{
updateNode( item, QRectF( 0, 0, size.width(), size.height() ), text, node,
textColor, style, styleColor, linkColor );
}
#endif #endif

View File

@ -44,6 +44,7 @@ HEADERS += \
common/QskNamespace.h \ common/QskNamespace.h \
common/QskObjectCounter.h \ common/QskObjectCounter.h \
common/QskSizePolicy.h \ common/QskSizePolicy.h \
common/QskTextColors.h \
common/QskTextOptions.h common/QskTextOptions.h
SOURCES += \ SOURCES += \
@ -58,6 +59,7 @@ SOURCES += \
common/QskModule.cpp \ common/QskModule.cpp \
common/QskObjectCounter.cpp \ common/QskObjectCounter.cpp \
common/QskSizePolicy.cpp \ common/QskSizePolicy.cpp \
common/QskTextColors.cpp \
common/QskTextOptions.cpp common/QskTextOptions.cpp
HEADERS += \ HEADERS += \
@ -154,7 +156,6 @@ HEADERS += \
controls/QskSkinHintTable.h \ controls/QskSkinHintTable.h \
controls/QskSkinlet.h \ controls/QskSkinlet.h \
controls/QskSkinnable.h \ controls/QskSkinnable.h \
controls/QskSkinRenderer.h \
controls/QskSkinTransition.h \ controls/QskSkinTransition.h \
controls/QskSlider.h \ controls/QskSlider.h \
controls/QskSliderSkinlet.h \ controls/QskSliderSkinlet.h \
@ -218,7 +219,6 @@ SOURCES += \
controls/QskSkinFactory.cpp \ controls/QskSkinFactory.cpp \
controls/QskSkinlet.cpp \ controls/QskSkinlet.cpp \
controls/QskSkinnable.cpp \ controls/QskSkinnable.cpp \
controls/QskSkinRenderer.cpp \
controls/QskSkinTransition.cpp \ controls/QskSkinTransition.cpp \
controls/QskSlider.cpp \ controls/QskSlider.cpp \
controls/QskSliderSkinlet.cpp \ controls/QskSliderSkinlet.cpp \