2017-07-21 16:21:34 +00:00
|
|
|
/******************************************************************************
|
2024-01-17 13:31:45 +00:00
|
|
|
* QSkinny - Copyright (C) The authors
|
2023-04-06 07:23:37 +00:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
2017-07-21 16:21:34 +00:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskBoxNode.h"
|
2022-12-05 11:34:08 +00:00
|
|
|
#include "QskBoxShadowNode.h"
|
|
|
|
#include "QskBoxRectangleNode.h"
|
|
|
|
#include "QskSGNode.h"
|
|
|
|
|
2017-10-20 11:09:30 +00:00
|
|
|
#include "QskGradient.h"
|
2022-11-13 16:22:09 +00:00
|
|
|
#include "QskGradientDirection.h"
|
2022-12-05 11:34:08 +00:00
|
|
|
#include "QskShadowMetrics.h"
|
|
|
|
#include "QskBoxBorderMetrics.h"
|
|
|
|
#include "QskBoxBorderColors.h"
|
2024-10-24 08:16:51 +00:00
|
|
|
#include "QskBoxShapeMetrics.h"
|
2024-09-24 08:14:26 +00:00
|
|
|
#include "QskRgbValue.h"
|
2017-10-20 11:09:30 +00:00
|
|
|
|
2022-12-05 11:34:08 +00:00
|
|
|
namespace
|
|
|
|
{
|
2024-12-09 13:53:59 +00:00
|
|
|
enum NodeRole : quint8
|
2022-12-05 11:34:08 +00:00
|
|
|
{
|
|
|
|
ShadowRole,
|
2024-10-23 13:20:42 +00:00
|
|
|
ShadowFillRole,
|
2022-12-05 11:34:08 +00:00
|
|
|
BoxRole,
|
|
|
|
FillRole
|
|
|
|
};
|
|
|
|
}
|
2017-08-28 15:42:11 +00:00
|
|
|
|
2023-04-04 06:49:11 +00:00
|
|
|
static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
|
2017-10-17 15:34:00 +00:00
|
|
|
{
|
2024-10-23 13:20:42 +00:00
|
|
|
static const QVector< quint8 > roles =
|
|
|
|
{ ShadowRole, ShadowFillRole, BoxRole, FillRole };
|
2017-09-03 12:55:21 +00:00
|
|
|
|
2022-12-05 11:34:08 +00:00
|
|
|
auto oldNode = QskSGNode::findChildNode( parentNode, role );
|
|
|
|
QskSGNode::replaceChildNode( roles, role, parentNode, oldNode, node );
|
2017-08-28 15:42:11 +00:00
|
|
|
}
|
2017-07-21 16:21:34 +00:00
|
|
|
|
2022-12-05 11:34:08 +00:00
|
|
|
template< typename Node >
|
2024-10-23 13:20:42 +00:00
|
|
|
static inline Node* qskNode( QSGNode* parentNode, quint8 role )
|
2017-08-28 15:42:11 +00:00
|
|
|
{
|
2022-12-05 11:34:08 +00:00
|
|
|
using namespace QskSGNode;
|
2017-07-21 16:21:34 +00:00
|
|
|
|
2022-12-05 11:34:08 +00:00
|
|
|
auto node = static_cast< Node* > ( findChildNode( parentNode, role ) );
|
2022-10-31 13:42:08 +00:00
|
|
|
|
2022-12-05 11:34:08 +00:00
|
|
|
if ( node == nullptr )
|
|
|
|
{
|
|
|
|
node = new Node();
|
|
|
|
setNodeRole( node, role );
|
|
|
|
}
|
|
|
|
|
|
|
|
return node;
|
|
|
|
}
|
2022-10-31 13:42:08 +00:00
|
|
|
|
2018-08-03 06:15:28 +00:00
|
|
|
QskBoxNode::QskBoxNode()
|
2017-07-21 16:21:34 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QskBoxNode::~QskBoxNode()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2024-11-07 10:21:45 +00:00
|
|
|
void QskBoxNode::updateNode( const QQuickWindow* window, const QRectF& rect,
|
2024-10-24 08:16:51 +00:00
|
|
|
const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics,
|
2022-12-05 11:34:08 +00:00
|
|
|
const QskBoxBorderColors& borderColors, const QskGradient& gradient,
|
|
|
|
const QskShadowMetrics& shadowMetrics, const QColor& shadowColor )
|
2017-07-21 16:21:34 +00:00
|
|
|
{
|
2022-12-05 11:34:08 +00:00
|
|
|
using namespace QskSGNode;
|
2017-07-21 16:21:34 +00:00
|
|
|
|
2022-12-05 11:34:08 +00:00
|
|
|
QskBoxShadowNode* shadowNode = nullptr;
|
2024-10-23 13:20:42 +00:00
|
|
|
QskBoxRectangleNode* shadowFillNode = nullptr;
|
2022-12-05 11:34:08 +00:00
|
|
|
QskBoxRectangleNode* rectNode = nullptr;
|
2024-09-17 11:57:10 +00:00
|
|
|
QskBoxRectangleNode* fillNode = nullptr;
|
2017-10-17 15:34:00 +00:00
|
|
|
|
2024-09-23 13:55:00 +00:00
|
|
|
if ( !rect.isEmpty() )
|
2017-07-21 16:21:34 +00:00
|
|
|
{
|
2024-09-24 08:17:10 +00:00
|
|
|
const auto hasFilling = gradient.isVisible();
|
|
|
|
const auto hasBorder = !borderMetrics.isNull() && borderColors.isVisible();
|
2024-10-24 08:16:51 +00:00
|
|
|
const auto hasShadow = !shadowMetrics.isNull() && QskRgb::isVisible( shadowColor );
|
2024-09-24 08:14:26 +00:00
|
|
|
|
|
|
|
if ( hasShadow )
|
2024-09-23 13:55:00 +00:00
|
|
|
{
|
2024-10-24 08:16:51 +00:00
|
|
|
const auto shadow = shadowMetrics.toAbsolute( rect.size() );
|
|
|
|
const auto shadowRect = shadow.shadowRect( rect );
|
2024-10-23 13:20:42 +00:00
|
|
|
|
2024-10-25 16:54:04 +00:00
|
|
|
auto shadowShape = shapeMetrics;
|
|
|
|
|
|
|
|
switch( static_cast< int >( shadow.shapeMode() ) )
|
|
|
|
{
|
|
|
|
case QskShadowMetrics::Ellipse:
|
|
|
|
shadowShape.setRadius( 100.0, Qt::RelativeSize );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QskShadowMetrics::Rectangle:
|
|
|
|
shadowShape.setRadius( 0.0, Qt::AbsoluteSize );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-10-24 08:16:51 +00:00
|
|
|
if ( shadow.blurRadius() <= 0.0 )
|
2024-10-23 13:20:42 +00:00
|
|
|
{
|
|
|
|
// QskBoxRectangleNode allows scene graph batching
|
|
|
|
shadowFillNode = qskNode< QskBoxRectangleNode >( this, ShadowFillRole );
|
2024-11-07 10:21:45 +00:00
|
|
|
shadowFillNode->updateFilling( window,
|
|
|
|
shadowRect, shadowShape, shadowColor );
|
2024-10-23 13:20:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
shadowNode = qskNode< QskBoxShadowNode >( this, ShadowRole );
|
2024-10-24 08:16:51 +00:00
|
|
|
shadowNode->setShadowData( shadowRect,
|
2024-10-25 16:54:04 +00:00
|
|
|
shadowShape, shadow.blurRadius(), shadowColor );
|
2024-10-23 13:20:42 +00:00
|
|
|
}
|
2024-09-23 13:55:00 +00:00
|
|
|
}
|
2017-08-28 15:42:11 +00:00
|
|
|
|
2024-09-24 08:17:10 +00:00
|
|
|
if ( hasBorder || hasFilling )
|
2017-10-17 15:34:00 +00:00
|
|
|
{
|
2022-12-05 11:34:08 +00:00
|
|
|
rectNode = qskNode< QskBoxRectangleNode >( this, BoxRole );
|
2024-09-24 08:17:10 +00:00
|
|
|
|
|
|
|
if ( hasBorder && hasFilling )
|
2024-09-23 13:55:00 +00:00
|
|
|
{
|
2024-09-24 08:17:10 +00:00
|
|
|
const bool doCombine = rectNode->hasHint( QskFillNode::PreferColoredGeometry )
|
|
|
|
&& QskBoxRectangleNode::isCombinedGeometrySupported( gradient );
|
2024-09-23 13:55:00 +00:00
|
|
|
|
2024-09-24 08:17:10 +00:00
|
|
|
if ( !doCombine )
|
|
|
|
fillNode = qskNode< QskBoxRectangleNode >( this, FillRole );
|
|
|
|
}
|
2024-10-23 13:20:42 +00:00
|
|
|
|
2024-09-24 08:17:10 +00:00
|
|
|
if ( fillNode )
|
2024-09-23 13:55:00 +00:00
|
|
|
{
|
2024-11-07 10:21:45 +00:00
|
|
|
rectNode->updateBorder( window, rect,
|
|
|
|
shapeMetrics, borderMetrics, borderColors );
|
|
|
|
|
|
|
|
fillNode->updateFilling( window, rect,
|
|
|
|
shapeMetrics, borderMetrics, gradient );
|
2024-09-23 13:55:00 +00:00
|
|
|
}
|
2024-09-24 08:17:10 +00:00
|
|
|
else
|
|
|
|
{
|
2024-11-07 10:21:45 +00:00
|
|
|
rectNode->updateBox( window, rect,
|
|
|
|
shapeMetrics, borderMetrics, borderColors, gradient );
|
2024-09-24 08:17:10 +00:00
|
|
|
}
|
2017-10-17 15:34:00 +00:00
|
|
|
}
|
2017-07-21 16:21:34 +00:00
|
|
|
}
|
2017-10-17 15:34:00 +00:00
|
|
|
|
2022-12-05 11:34:08 +00:00
|
|
|
qskUpdateChildren( this, ShadowRole, shadowNode );
|
2024-10-23 13:20:42 +00:00
|
|
|
qskUpdateChildren( this, ShadowFillRole, shadowFillNode );
|
2022-12-05 11:34:08 +00:00
|
|
|
qskUpdateChildren( this, BoxRole, rectNode );
|
|
|
|
qskUpdateChildren( this, FillRole, fillNode );
|
2017-07-21 16:21:34 +00:00
|
|
|
}
|