2023-12-07 10:24:47 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2023-12-08 14:47:32 +00:00
|
|
|
#include "Overlay.h"
|
2023-12-18 08:39:17 +00:00
|
|
|
#include "TextureFilterNode.h"
|
2023-12-19 17:37:34 +00:00
|
|
|
#include "TextureFilterMaterial.h"
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
#include <QskSkinlet.h>
|
|
|
|
#include <QskQuick.h>
|
|
|
|
#include <QskBoxShapeMetrics.h>
|
|
|
|
#include <QskBoxBorderMetrics.h>
|
|
|
|
#include <QskBoxBorderColors.h>
|
|
|
|
#include <QskGradient.h>
|
2023-12-19 11:45:40 +00:00
|
|
|
#include <QskSceneTexture.h>
|
2023-12-18 08:02:45 +00:00
|
|
|
#include <QskSGNode.h>
|
|
|
|
#include <QskRgbValue.h>
|
2023-12-15 11:54:13 +00:00
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
namespace
|
2023-12-07 10:24:47 +00:00
|
|
|
{
|
2023-12-19 17:37:34 +00:00
|
|
|
class Material : public TextureFilterMaterial
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using TextureFilterMaterial::TextureFilterMaterial;
|
|
|
|
|
|
|
|
QSGMaterialType* type() const override
|
|
|
|
{
|
|
|
|
static QSGMaterialType staticType;
|
|
|
|
return &staticType;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class FilterNode : public TextureFilterNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
FilterNode( QSGTexture* texture )
|
|
|
|
{
|
|
|
|
QString shaders[] = { ":/shaders/blur.vert", ":/shaders/blur.frag" };
|
|
|
|
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
|
|
|
shaders[0] += ".qsb";
|
|
|
|
shaders[1] += ".qsb";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
setFlag( QSGNode::OwnsMaterial, true );
|
|
|
|
setTextureMaterial( new Material( shaders[0], shaders[1] ) );
|
|
|
|
|
|
|
|
setOwnsTexture( true );
|
|
|
|
setTexture( texture );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
class Skinlet : public QskSkinlet
|
2023-12-07 10:24:47 +00:00
|
|
|
{
|
2023-12-17 11:33:23 +00:00
|
|
|
using Inherited = QskSkinlet;
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
public:
|
2023-12-18 08:39:17 +00:00
|
|
|
enum NodeRole { FillRole, BorderRole };
|
2023-12-17 11:33:23 +00:00
|
|
|
|
|
|
|
Skinlet()
|
2023-12-07 10:24:47 +00:00
|
|
|
{
|
2023-12-18 08:39:17 +00:00
|
|
|
setNodeRoles( { FillRole, BorderRole } );
|
2023-12-17 11:33:23 +00:00
|
|
|
}
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-18 08:02:45 +00:00
|
|
|
QRectF subControlRect( const QskSkinnable*,
|
|
|
|
const QRectF& contentsRect, QskAspect::Subcontrol ) const override
|
|
|
|
{
|
|
|
|
return contentsRect;
|
|
|
|
}
|
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
QSGNode* updateSubNode(
|
|
|
|
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
|
|
|
{
|
|
|
|
const auto overlay = static_cast< const Overlay* >( skinnable );
|
|
|
|
|
|
|
|
switch ( nodeRole )
|
2023-12-07 10:24:47 +00:00
|
|
|
{
|
2023-12-18 08:39:17 +00:00
|
|
|
case FillRole:
|
|
|
|
return updateFillNode( overlay, node );
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
case BorderRole:
|
2023-12-18 08:02:45 +00:00
|
|
|
return updateBoxNode( skinnable, node, Overlay::Panel );
|
2023-12-17 11:33:23 +00:00
|
|
|
break;
|
|
|
|
};
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
return nullptr;
|
2023-12-12 09:55:30 +00:00
|
|
|
}
|
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
private:
|
2023-12-18 08:39:17 +00:00
|
|
|
QSGNode* updateFillNode( const Overlay* overlay, QSGNode* node ) const
|
2023-12-18 08:02:45 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
There should be a way to avoid the clip node by passing the
|
2023-12-18 08:39:17 +00:00
|
|
|
vertex list directly to the texture node. TODO ...
|
2023-12-18 08:02:45 +00:00
|
|
|
*/
|
|
|
|
using Q = Overlay;
|
|
|
|
|
|
|
|
QSGNode* clipNode = nullptr;
|
2023-12-18 08:39:17 +00:00
|
|
|
QSGNode* textureNode = nullptr;
|
2023-12-18 08:02:45 +00:00
|
|
|
|
|
|
|
if ( node )
|
|
|
|
{
|
|
|
|
if ( node->firstChild() )
|
|
|
|
{
|
|
|
|
clipNode = node;
|
2023-12-18 08:39:17 +00:00
|
|
|
textureNode = node->firstChild();
|
2023-12-18 08:02:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-12-18 08:39:17 +00:00
|
|
|
textureNode = node;
|
2023-12-18 08:02:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-18 08:39:17 +00:00
|
|
|
textureNode = updateTextureNode( overlay, textureNode );
|
2023-12-18 08:02:45 +00:00
|
|
|
|
|
|
|
if ( overlay->boxShapeHint( Q::Panel ).isRectangle() )
|
|
|
|
{
|
|
|
|
delete clipNode;
|
|
|
|
clipNode = nullptr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clipNode = updateBoxClipNode( overlay, clipNode, Q::Panel );
|
|
|
|
}
|
|
|
|
|
2023-12-18 08:39:17 +00:00
|
|
|
QskSGNode::setParentNode( textureNode, clipNode );
|
2023-12-18 08:02:45 +00:00
|
|
|
|
2023-12-18 08:39:17 +00:00
|
|
|
return clipNode ? clipNode : textureNode;
|
2023-12-18 08:02:45 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 08:39:17 +00:00
|
|
|
QSGNode* updateTextureNode( const Overlay* overlay, QSGNode* node ) const
|
2023-12-17 11:33:23 +00:00
|
|
|
{
|
|
|
|
const auto window = overlay->window();
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
if ( overlay->size().isEmpty() )
|
|
|
|
return nullptr;
|
2023-12-15 11:54:13 +00:00
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
auto rootNode = qskScenegraphAnchorNode( window );
|
|
|
|
if ( rootNode == nullptr )
|
|
|
|
return nullptr;
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-19 17:37:34 +00:00
|
|
|
auto textureNode = static_cast< FilterNode* >( node );
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-18 08:39:17 +00:00
|
|
|
if ( textureNode == nullptr )
|
2023-12-17 11:33:23 +00:00
|
|
|
{
|
|
|
|
auto texture = new QskSceneTexture( window );
|
|
|
|
QObject::connect( texture, &QskSceneTexture::updateRequested,
|
|
|
|
overlay, &QQuickItem::update );
|
2023-12-07 10:24:47 +00:00
|
|
|
|
2023-12-19 17:37:34 +00:00
|
|
|
textureNode = new FilterNode( texture );
|
2023-12-17 11:33:23 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 08:02:45 +00:00
|
|
|
{
|
2023-12-18 08:39:17 +00:00
|
|
|
auto texture = qobject_cast< QskSceneTexture* >( textureNode->texture() );
|
2023-12-18 08:02:45 +00:00
|
|
|
Q_ASSERT( texture );
|
2023-12-17 11:33:23 +00:00
|
|
|
|
2023-12-18 08:02:45 +00:00
|
|
|
texture->setFiltering(
|
|
|
|
overlay->smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
|
2023-12-17 11:33:23 +00:00
|
|
|
|
2023-12-18 08:02:45 +00:00
|
|
|
auto finalNode = const_cast< QSGTransformNode* >( qskItemNode( overlay ) );
|
|
|
|
texture->render( rootNode, finalNode, overlay->geometry() );
|
|
|
|
}
|
2023-12-17 11:33:23 +00:00
|
|
|
|
2023-12-18 08:02:45 +00:00
|
|
|
{
|
|
|
|
const auto rect = overlay->subControlRect( Overlay::Panel );
|
2023-12-18 08:39:17 +00:00
|
|
|
textureNode->setRect( rect );
|
2023-12-18 08:02:45 +00:00
|
|
|
}
|
2023-12-17 11:33:23 +00:00
|
|
|
|
2023-12-18 08:39:17 +00:00
|
|
|
return textureNode;
|
2023-12-17 11:33:23 +00:00
|
|
|
}
|
|
|
|
};
|
2023-12-07 10:24:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-18 08:02:45 +00:00
|
|
|
QSK_SUBCONTROL( Overlay, Panel )
|
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
Overlay::Overlay( QQuickItem* parent )
|
|
|
|
: Inherited( parent )
|
2023-12-07 10:24:47 +00:00
|
|
|
{
|
2023-12-17 11:33:23 +00:00
|
|
|
setSkinlet( new Skinlet() );
|
2023-12-18 08:02:45 +00:00
|
|
|
|
|
|
|
setBoxBorderMetricsHint( Panel, 1 );
|
|
|
|
setBoxBorderColorsHint( Panel, QskRgb::toTransparent( QskRgb::DarkGrey, 100 ) );
|
|
|
|
setBoxShapeHint( Panel, QskBoxShapeMetrics( 25, Qt::RelativeSize ) );
|
2023-12-07 10:24:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-17 11:33:23 +00:00
|
|
|
Overlay::~Overlay()
|
2023-12-07 10:24:47 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-12-18 08:02:45 +00:00
|
|
|
QRectF Overlay::layoutRectForSize( const QSizeF& size ) const
|
|
|
|
{
|
|
|
|
return subControlContentsRect( size, Panel );
|
|
|
|
}
|
|
|
|
|
2023-12-08 14:47:32 +00:00
|
|
|
void Overlay::geometryChange(
|
2023-12-07 10:24:47 +00:00
|
|
|
const QRectF& newGeometry, const QRectF& oldGeometry )
|
|
|
|
{
|
|
|
|
Inherited::geometryChange( newGeometry, oldGeometry );
|
2023-12-12 09:55:30 +00:00
|
|
|
update();
|
2023-12-07 10:24:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-08 14:47:32 +00:00
|
|
|
#include "moc_Overlay.cpp"
|