QskPopup improvements
This commit is contained in:
parent
af8df9f4be
commit
8d2ff3c3fe
|
@ -15,6 +15,7 @@
|
|||
#include <QskInputPredictionBar.h>
|
||||
#include <QskListView.h>
|
||||
#include <QskPageIndicator.h>
|
||||
#include <QskPopup.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskScrollView.h>
|
||||
|
|
|
@ -5,11 +5,109 @@
|
|||
|
||||
#include "QskPopupSkinlet.h"
|
||||
#include "QskPopup.h"
|
||||
#include "QskSGNode.h"
|
||||
|
||||
#include <qtransform.h>
|
||||
#include <qsgnode.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
class RootNode : public QSGNode
|
||||
{
|
||||
public:
|
||||
~RootNode()
|
||||
{
|
||||
delete m_clipNode;
|
||||
delete m_transformNode;
|
||||
delete m_contentsNode;
|
||||
}
|
||||
|
||||
void setClipRect( const QRectF& rect )
|
||||
{
|
||||
if ( rect.isValid() )
|
||||
{
|
||||
if ( m_clipNode == nullptr )
|
||||
{
|
||||
m_clipNode = new QSGClipNode();
|
||||
m_clipNode->setFlag( QSGNode::OwnedByParent, false );
|
||||
m_clipNode->setIsRectangular( true );
|
||||
}
|
||||
|
||||
m_clipNode->setClipRect( rect );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_clipNode;
|
||||
m_clipNode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void setTranslation( qreal dx, qreal dy )
|
||||
{
|
||||
if ( dx != 0.0 || dy != 0.0 )
|
||||
{
|
||||
if ( m_transformNode == nullptr )
|
||||
{
|
||||
m_transformNode = new QSGTransformNode();
|
||||
m_transformNode->setFlag( QSGNode::OwnedByParent, false );
|
||||
}
|
||||
|
||||
QTransform transform;
|
||||
transform.translate( dx, dy );
|
||||
|
||||
m_transformNode->setMatrix( transform );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete m_transformNode;
|
||||
m_transformNode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void setContentsNode( QSGNode* contentsNode )
|
||||
{
|
||||
if ( m_contentsNode != contentsNode )
|
||||
{
|
||||
if ( contentsNode )
|
||||
contentsNode->setFlag( QSGNode::OwnedByParent, false );
|
||||
|
||||
delete m_contentsNode;
|
||||
m_contentsNode = contentsNode;
|
||||
}
|
||||
}
|
||||
|
||||
void rearrangeNodes()
|
||||
{
|
||||
const std::initializer_list< QSGNode* > nodes =
|
||||
{ m_clipNode, m_transformNode, m_contentsNode };
|
||||
|
||||
QSGNode* parentNode = this;
|
||||
for ( auto node : nodes )
|
||||
{
|
||||
if ( node )
|
||||
{
|
||||
QskSGNode::setParentNode( node, parentNode );
|
||||
parentNode = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline QSGNode* contentsNode()
|
||||
{
|
||||
return m_contentsNode;
|
||||
}
|
||||
|
||||
private:
|
||||
QSGClipNode* m_clipNode = nullptr;
|
||||
QSGTransformNode* m_transformNode = nullptr;
|
||||
QSGNode* m_contentsNode = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
QskPopupSkinlet::QskPopupSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
appendNodeRoles( { OverlayRole } );
|
||||
appendNodeRoles( { OverlayRole, ContentsRole } );
|
||||
}
|
||||
|
||||
QskPopupSkinlet::~QskPopupSkinlet() = default;
|
||||
|
@ -28,13 +126,45 @@ QRectF QskPopupSkinlet::subControlRect( const QskSkinnable* skinnable,
|
|||
QSGNode* QskPopupSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
const auto popup = static_cast< const QskPopup* >( skinnable );
|
||||
|
||||
switch ( nodeRole )
|
||||
{
|
||||
case OverlayRole:
|
||||
return updateBoxNode( skinnable, node, QskPopup::Overlay );
|
||||
|
||||
case ContentsRole:
|
||||
return updateExtraNode( popup, node );
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QSGNode* QskPopupSkinlet::updateExtraNode( const QskPopup* popup, QSGNode* node ) const
|
||||
{
|
||||
auto cr = popup->contentsRect();
|
||||
if ( cr.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto rootNode = QskSGNode::ensureNode< RootNode >( node );
|
||||
|
||||
const auto faderProgress = popup->metric( popup->faderAspect() );
|
||||
if ( faderProgress > 0.0 && faderProgress < 1.0 )
|
||||
rootNode->setClipRect( cr );
|
||||
|
||||
rootNode->setTranslation( 0.0, -faderProgress * cr.height() );
|
||||
|
||||
auto contentsNode = updateContentsNode( popup, rootNode->contentsNode() );
|
||||
rootNode->setContentsNode( contentsNode );
|
||||
|
||||
rootNode->rearrangeNodes();
|
||||
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
QSGNode* QskPopupSkinlet::updateContentsNode( const QskPopup*, QSGNode* ) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#include "moc_QskPopupSkinlet.cpp"
|
||||
|
|
|
@ -20,6 +20,8 @@ class QSK_EXPORT QskPopupSkinlet : public QskSkinlet
|
|||
enum NodeRole
|
||||
{
|
||||
OverlayRole,
|
||||
ContentsRole,
|
||||
|
||||
RoleCount
|
||||
};
|
||||
|
||||
|
@ -33,7 +35,10 @@ class QSK_EXPORT QskPopupSkinlet : public QskSkinlet
|
|||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
|
||||
virtual QSGNode* updateContentsNode( const QskPopup*, QSGNode* ) const;
|
||||
|
||||
private:
|
||||
QSGNode* updateExtraNode( const QskPopup*, QSGNode* ) const;
|
||||
QSGNode* updateOverlayNode( const QskPopup*, QSGNode* ) const;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue