112 lines
3.1 KiB
C++
112 lines
3.1 KiB
C++
/******************************************************************************
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*****************************************************************************/
|
|
|
|
#include "QskBoxNode.h"
|
|
#include "QskBoxFillNode.h"
|
|
#include "QskBoxShadowNode.h"
|
|
#include "QskBoxRectangleNode.h"
|
|
#include "QskBoxRenderer.h"
|
|
#include "QskSGNode.h"
|
|
|
|
#include "QskGradient.h"
|
|
#include "QskGradientDirection.h"
|
|
#include "QskShadowMetrics.h"
|
|
#include "QskBoxBorderMetrics.h"
|
|
#include "QskBoxBorderColors.h"
|
|
|
|
namespace
|
|
{
|
|
enum Role
|
|
{
|
|
ShadowRole,
|
|
BoxRole,
|
|
FillRole
|
|
};
|
|
}
|
|
|
|
static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
|
|
{
|
|
static const QVector< quint8 > roles = { ShadowRole, BoxRole, FillRole };
|
|
|
|
auto oldNode = QskSGNode::findChildNode( parentNode, role );
|
|
QskSGNode::replaceChildNode( roles, role, parentNode, oldNode, node );
|
|
}
|
|
|
|
template< typename Node >
|
|
inline Node* qskNode( QSGNode* parentNode, quint8 role )
|
|
{
|
|
using namespace QskSGNode;
|
|
|
|
auto node = static_cast< Node* > ( findChildNode( parentNode, role ) );
|
|
|
|
if ( node == nullptr )
|
|
{
|
|
node = new Node();
|
|
setNodeRole( node, role );
|
|
}
|
|
|
|
return node;
|
|
}
|
|
|
|
QskBoxNode::QskBoxNode()
|
|
{
|
|
}
|
|
|
|
QskBoxNode::~QskBoxNode()
|
|
{
|
|
}
|
|
|
|
void QskBoxNode::updateNode( const QRectF& rect,
|
|
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics,
|
|
const QskBoxBorderColors& borderColors, const QskGradient& gradient,
|
|
const QskShadowMetrics& shadowMetrics, const QColor& shadowColor )
|
|
{
|
|
using namespace QskSGNode;
|
|
|
|
QskBoxShadowNode* shadowNode = nullptr;
|
|
QskBoxRectangleNode* rectNode = nullptr;
|
|
QskBoxFillNode* fillNode = nullptr;
|
|
|
|
if ( !shadowMetrics.isNull()
|
|
&& shadowColor.isValid() && shadowColor.alpha() != 0 )
|
|
{
|
|
shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole );
|
|
shadowNode->setShadowData( shadowMetrics.shadowRect( rect ),
|
|
shape, shadowMetrics.blurRadius(), shadowColor );
|
|
}
|
|
|
|
/*
|
|
QskBoxRectangleNode supports vertical/horizontal and many tilted
|
|
linear gradients. If our gradient doesn't fall into this category
|
|
we use a QskBoxFillNode.
|
|
|
|
However the border is always done with a QskBoxRectangleNode
|
|
*/
|
|
|
|
if ( QskBox::isGradientSupported( shape, gradient ) )
|
|
{
|
|
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
|
|
rectNode->updateNode( rect, shape, borderMetrics, borderColors, gradient );
|
|
}
|
|
else
|
|
{
|
|
if ( !borderMetrics.isNull() && borderColors.isVisible() )
|
|
{
|
|
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
|
|
rectNode->updateNode( rect, shape, borderMetrics, borderColors, QskGradient() );
|
|
}
|
|
|
|
if ( gradient.isVisible() )
|
|
{
|
|
fillNode = qskNode< QskBoxFillNode >( this, FillRole );
|
|
fillNode->updateNode( rect, shape, borderMetrics, gradient );
|
|
}
|
|
}
|
|
|
|
qskUpdateChildren( this, ShadowRole, shadowNode );
|
|
qskUpdateChildren( this, BoxRole, rectNode );
|
|
qskUpdateChildren( this, FillRole, fillNode );
|
|
}
|