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 <QskRgbValue.h>
#include <QskBoxShapeMetrics.h>
#include <QskGradient.h>
#include <QskAnimationHint.h>
QSK_SUBCONTROL( Slider, Scale )
@ -15,7 +17,15 @@ Slider::Slider( QQuickItem* parentItem ):
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( QskSlider::Handle, QskRgbValue::Grey800 );

View File

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

View File

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

View File

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

View File

@ -6,7 +6,6 @@
#include "QskListViewSkinlet.h"
#include "QskListView.h"
#include "QskAspect.h"
#include "QskSkinRenderer.h"
#include "QskTextOptions.h"
#include "QskTextNode.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 "QskBoxBorderColors.h"
#include "QskGradient.h"
#include "QskSkinRenderer.h"
#include "QskBoxNode.h"
#include "QskBoxClipNode.h"
#include "QskTextNode.h"
#include "QskTextColors.h"
#include "QskTextOptions.h"
#include "QskGraphicNode.h"
#include "QskGraphicTextureFactory.h"
#include "QskFunctions.h"
@ -89,6 +90,31 @@ static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics,
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
{
public:
@ -428,8 +454,37 @@ QSGNode* QskSkinlet::updateTextNode(
if ( textNode == nullptr )
textNode = new QskTextNode();
QskSkinRenderer::updateText( skinnable, rect, alignment,
text, textOptions, textNode, subControl );
auto colors = qskTextColors( skinnable, 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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,11 +5,32 @@
#include "QskTextNode.h"
#include "QskTextOptions.h"
#include "QskTextColors.h"
#include "QskTextRenderer.h"
#include "QskPlainTextRenderer.h"
#include <QFont>
#include <QColor>
#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():
m_hash( 0 )
{
@ -19,26 +40,99 @@ QskTextNode::~QskTextNode()
{
}
bool QskTextNode::setTextData(
const QString& text, const QSizeF& size, const QFont& font,
const QskTextOptions& options, Qt::Alignment alignment, Qsk::TextStyle textStyle,
const QColor& textColor, const QColor& styleColor, const QColor& linkColor )
void QskTextNode::setTextData( const QQuickItem* item,
const QString& text, const QRectF& rect, const QFont& font,
const QskTextOptions& options, const QskTextColors& colors,
Qt::Alignment alignment, Qsk::TextStyle textStyle )
{
uint hash;
if ( m_rect != rect )
{
QMatrix4x4 matrix;
matrix.translate( rect.left(), rect.top() );
hash = qHash( text, 0 );
hash = qHash( font, hash );
hash = qHash( options, hash );
hash = qHash( alignment, hash );
hash = qHash( textStyle, hash );
hash = qHash( textColor.rgba(), hash );
hash = qHash( styleColor.rgba(), hash );
hash = qHash( linkColor.rgba(), hash );
hash = qHashBits( &size, sizeof( QSizeF ), hash );
if ( matrix != this->matrix() ) // avoid setting DirtyMatrix accidently
setMatrix( matrix );
}
const uint hash = qskHash( text, rect.size(), font,
options, colors, alignment, textStyle );
if ( hash == m_hash )
return false;
return;
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 <QSGTransformNode>
#include <Qt>
#include <QRectF>
class QskTextOptions;
class QskTextColors;
class QString;
class QFont;
class QQuickItem;
class QSK_EXPORT QskTextNode : public QSGTransformNode
{
@ -21,10 +24,22 @@ public:
QskTextNode();
virtual ~QskTextNode();
bool setTextData( const QString& text, const QSizeF&, const QFont&,
const QskTextOptions&, Qt::Alignment, Qsk::TextStyle,
const QColor& textColor, const QColor& styleColor, const QColor& linkColor );
void setTextData( const QQuickItem* item,
const QString& text, const QRectF&, const QFont&,
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:
QRectF m_rect;
uint m_hash;
};

View File

@ -4,6 +4,8 @@
*****************************************************************************/
#include "QskTextRenderer.h"
#include "QskTextColors.h"
#include <QQuickWindow>
QSK_QT_PRIVATE_BEGIN
@ -16,63 +18,40 @@ QSK_QT_PRIVATE_END
class QskTextHelperItem final : public QQuickText
{
public:
QskTextHelperItem();
void refWindow( QQuickWindow* window );
void derefWindow();
void begin();
void end();
void begin() { classBegin(); }
void end() { componentComplete(); }
QRectF layedOutTextRect() const;
void updateTextNode( QQuickWindow*, QSGNode* );
QRectF layedOutTextRect() const
{
auto that = const_cast< QskTextHelperItem* >( this );
return QQuickTextPrivate::get( that )->layedOutTextRect;
}
void updateTextNode( QQuickWindow* window, QSGNode* parentNode )
{
QQuickItemPrivate::get( this )->refWindow( window );
while ( parentNode->firstChild() )
delete parentNode->firstChild();
auto node = QQuickText::updatePaintNode( nullptr, nullptr );
node->reparentChildNodesTo( parentNode );
delete node;
QQuickItemPrivate::get( this )->derefWindow();
}
protected:
virtual QSGNode* updatePaintNode(
QSGNode*, UpdatePaintNodeData* ) override final;
QSGNode*, UpdatePaintNodeData* ) override final
{
// should never be called
return nullptr;
}
};
QskTextHelperItem::QskTextHelperItem():
QQuickText( nullptr )
{
}
QRectF QskTextHelperItem::layedOutTextRect() const
{
auto that = const_cast< QskTextHelperItem* >( this );
return QQuickTextPrivate::get( that )->layedOutTextRect;
}
void QskTextHelperItem::updateTextNode( QQuickWindow* window, QSGNode* parentNode )
{
QQuickItemPrivate::get( this )->refWindow( window );
while ( parentNode->firstChild() )
delete parentNode->firstChild(); // This is done in QQuickText::updatePaintNode anyway
auto node = QQuickText::updatePaintNode( nullptr, nullptr );
node->reparentChildNodesTo( parentNode );
delete node;
QQuickItemPrivate::get( this )->derefWindow();
}
void QskTextHelperItem::begin()
{
classBegin();
}
void QskTextHelperItem::end()
{
componentComplete();
}
QSGNode* QskTextHelperItem::updatePaintNode( QSGNode*, UpdatePaintNodeData* )
{
// should never be called
return nullptr;
}
/*
size requests and rendering might be from different threads and we
better use different items as we might end up in events internally
@ -171,13 +150,12 @@ void QskTextRenderer::setupItem( QskTextHelperItem* textItem ) const
#endif
}
void QskTextRenderer::updateNode( const QQuickItem* item,
const QRectF& rect, const QString& text, QSGTransformNode* parentNode,
const QColor& textColor, Qsk::TextStyle style, const QColor& styleColor,
const QColor& linkColor )
void QskTextRenderer::updateNode( const QString& text,
const QRectF& rect, Qsk::TextStyle style, const QskTextColors& colors,
const QQuickItem* item, QSGTransformNode* node )
{
// 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 )
qskRenderHelper = new QskTextHelperItem();
@ -204,16 +182,23 @@ void QskTextRenderer::updateNode( const QQuickItem* item,
textItem.doLayout();
}
textItem.setColor( textColor );
textItem.setColor( colors.textColor );
textItem.setStyle( static_cast< QQuickText::TextStyle >( style ) );
textItem.setStyleColor( styleColor );
textItem.setLinkColor( linkColor );
textItem.setStyleColor( colors.styleColor );
textItem.setLinkColor( colors.linkColor );
textItem.setText( text );
textItem.end();
textItem.updateTextNode( item->window(), parentNode );
textItem.updateTextNode( item->window(), node );
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>
class QskTextHelperItem;
class QskTextColors;
class QQuickItem;
class QQuickWindow;
@ -31,13 +32,13 @@ public:
void setOptions( const QskTextOptions& );
void setAlignment( Qt::Alignment );
void updateNode( const QQuickItem*, const QSizeF&, const QString&,
QSGTransformNode*, const QColor& textColor,
Qsk::TextStyle, const QColor& styleColor, const QColor& linkColor );
void updateNode( const QString&, const QSizeF&,
Qsk::TextStyle, const QskTextColors&,
const QQuickItem*, QSGTransformNode* );
void updateNode( const QQuickItem*, const QRectF&, const QString&,
QSGTransformNode*, const QColor& textColor, Qsk::TextStyle,
const QColor& styleColor, const QColor& linkColor );
void updateNode( const QString&, const QRectF&,
Qsk::TextStyle, const QskTextColors&,
const QQuickItem*, QSGTransformNode* );
QSizeF textSize( const QString& ) const;
QRectF textRect( const QSizeF&, const QString& ) const;
@ -50,12 +51,4 @@ private:
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

View File

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