qskinny/playground/gradients/GradientView.cpp
2024-09-17 13:37:04 +02:00

195 lines
4.7 KiB
C++

/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "GradientView.h"
#ifdef SHAPE_GRADIENT
#include "GradientQuickShape.h"
#endif
#include <QskPaintedNode.h>
#include <QskBoxFillNode.h>
#include <QskBoxRectangleNode.h>
#include <QskGradient.h>
#include <QskGradientDirection.h>
#include <QskBoxRenderer.h>
#include <QskBoxShapeMetrics.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskTextLabel.h>
#include <QBrush>
#include <QPainter>
namespace
{
template< typename Node >
inline Node* gradientNode( QSGNode* node )
{
if ( node == nullptr )
node = new Node();
return static_cast< Node* >( node );
}
class PaintedNode final : public QskPaintedNode
{
public:
PaintedNode()
{
setRenderHint( QskPaintedNode::Raster );
}
void updateNode( QQuickWindow* window,
const QRectF& rect, const QskGradient& gradient )
{
update( window, rect, QSizeF(), &gradient );
}
QskHashValue hash( const void* nodeData ) const override
{
const auto gradient = reinterpret_cast< const QskGradient* >( nodeData );
return gradient->hash();
}
protected:
void paint( QPainter* painter, const QSize& size, const void* nodeData ) override
{
const auto gradient = reinterpret_cast< const QskGradient* >( nodeData );
const QRect rect( 0, 0, size.width(), size.height() );
painter->fillRect( rect, gradient->stretchedTo( rect ).toQGradient() );
}
};
class InfoLabel : public QskTextLabel
{
public:
InfoLabel( GradientView::NodeType nodeType, QQuickItem* parent )
: QskTextLabel( parent )
{
QString text;
switch( nodeType )
{
case GradientView::Painted:
text = "Raster PaintEngine";
break;
case GradientView::BoxRectangle:
text = "Colored Vertices";
break;
case GradientView::BoxFill:
text = "Qskinny Shader";
break;
#ifdef SHAPE_GRADIENT
case GradientView::Shape:
text = "Qt/Quick Shape Shader";
break;
#endif
default:
break;
}
if ( !text.isEmpty() )
{
QColor c( Qt::white );
c.setAlpha( 200 );
setBackgroundColor( c );
setText( text );
}
}
};
}
GradientView::GradientView( NodeType nodeType, QQuickItem* parent )
: QQuickItem( parent )
, m_nodeType( nodeType )
{
setFlag( QQuickItem::ItemHasContents, true );
auto label = new InfoLabel( nodeType, this );
label->setPosition( 10, 10 );
label->setSize( label->sizeHint() );
}
GradientView::NodeType GradientView::GradientView::nodeType() const
{
return m_nodeType;
}
void GradientView::setGradient( const QskGradient& gradient )
{
m_gradient = gradient;
update();
}
QskGradient GradientView::gradient() const
{
return m_gradient;
}
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
void GradientView::geometryChange( const QRectF&, const QRectF& )
#else
void GradientView::geometryChanged( const QRectF&, const QRectF& )
#endif
{
update();
}
QSGNode* GradientView::updatePaintNode(
QSGNode* oldNode, QQuickItem::UpdatePaintNodeData* )
{
const QRectF rect( 0, 0, width(), height() );
QskBoxShapeMetrics shape;
#if 0
shape.setRadius( 80 );
#endif
switch( m_nodeType )
{
case Painted:
{
auto node = gradientNode< PaintedNode >( oldNode );
node->updateNode( window(), rect, m_gradient );
return node;
}
case BoxFill:
{
auto node = gradientNode< QskBoxFillNode >( oldNode );
node->updateNode( rect, m_gradient );
return node;
}
case BoxRectangle:
{
auto node = gradientNode< QskBoxRectangleNode >( oldNode );
node->updateNode( rect, shape, m_gradient );
return node;
}
#ifdef SHAPE_GRADIENT
case Shape:
{
return GradientQuickShape::updateNode(
window(), rect, m_gradient, oldNode );
}
#endif
default:
break;
}
return nullptr;
}
#include "moc_GradientView.cpp"