better fading support for popups, being used in QskDrawer/QskMenu/QskSubWindow
This commit is contained in:
parent
3b4f167709
commit
1ab236de9f
|
@ -623,13 +623,14 @@ void Editor::setupDrawerMetrics()
|
|||
using Q = QskDrawer;
|
||||
using A = QskAspect;
|
||||
|
||||
#if 1
|
||||
setAnimation( Q::Panel | A::Metric | A::Position, 200 );
|
||||
#endif
|
||||
setAnimation( Q::Panel | A::Position, 300, QEasingCurve::OutCubic );
|
||||
}
|
||||
|
||||
void Editor::setupDrawerColors( QskAspect::Section, const QskFluent2Theme& )
|
||||
void Editor::setupDrawerColors(
|
||||
QskAspect::Section section, const QskFluent2Theme& theme )
|
||||
{
|
||||
setGradient( QskDrawer::Panel | section,
|
||||
theme.palette.background.solid.base );
|
||||
}
|
||||
|
||||
void Editor::setupFocusIndicatorMetrics()
|
||||
|
@ -759,13 +760,7 @@ void Editor::setupMenuMetrics()
|
|||
setStrutSize( Q::Icon, 12, 12 );
|
||||
setPadding( Q::Icon, { 8, 8, 0, 8 } );
|
||||
|
||||
#if 1
|
||||
setPosition( Q::Panel, 1 );
|
||||
setPosition( Q::Panel | QskPopup::Closed, 0 );
|
||||
|
||||
// copied from Mat3 - what are the correct values for Fluent2 ???
|
||||
setAnimation( Q::Panel | A::Metric, 150 );
|
||||
#endif
|
||||
setAnimation( Q::Panel | A::Position, 100 );
|
||||
}
|
||||
|
||||
void Editor::setupMenuColors(
|
||||
|
@ -876,9 +871,11 @@ void Editor::setupPageIndicatorColors(
|
|||
void Editor::setupPopup( const QskFluent2Theme& theme )
|
||||
{
|
||||
using Q = QskPopup;
|
||||
using A = QskAspect;
|
||||
|
||||
const auto& pal = theme.palette;
|
||||
|
||||
setHint( Q::Overlay | A::Style, true );
|
||||
setGradient( Q::Overlay, pal.background.overlay.defaultColor );
|
||||
}
|
||||
|
||||
|
@ -1885,6 +1882,8 @@ void Editor::setupSwitchButtonColors(
|
|||
void Editor::setupSubWindow( const QskFluent2Theme& theme )
|
||||
{
|
||||
using Q = QskSubWindow;
|
||||
using A = QskAspect;
|
||||
|
||||
const auto& pal = theme.palette;
|
||||
|
||||
setPadding( Q::Panel, { 0, 31, 0, 0 } );
|
||||
|
@ -1902,6 +1901,8 @@ void Editor::setupSubWindow( const QskFluent2Theme& theme )
|
|||
setColor( Q::TitleBarText, pal.fillColor.text.primary );
|
||||
setAlignment( Q::TitleBarText, Qt::AlignLeft );
|
||||
setTextOptions( Q::TitleBarText, Qt::ElideRight, QskTextOptions::NoWrap );
|
||||
|
||||
setAnimation( Q::Panel | A::Position, 300, QEasingCurve::OutCubic );
|
||||
}
|
||||
|
||||
void Editor::setupVirtualKeyboardMetrics()
|
||||
|
|
|
@ -378,11 +378,9 @@ void Editor::setupMenu()
|
|||
setColor( Q::Text, m_pal.onSurface );
|
||||
setFontRole( Q::Text, QskMaterial3Skin::M3BodyMedium );
|
||||
|
||||
setPosition( Q::Panel, 1 );
|
||||
setPosition( Q::Panel | QskPopup::Closed, 0 );
|
||||
|
||||
setAnimation( Q::Panel | A::Metric, 150 );
|
||||
setAnimation( Q::Cursor | A::Position | A::Metric, 75, QEasingCurve::OutCubic );
|
||||
|
||||
setAnimation( Q::Panel | A::Position, 75 );
|
||||
}
|
||||
|
||||
void Editor::setupTextLabel()
|
||||
|
@ -811,7 +809,8 @@ void Editor::setupDrawer()
|
|||
using Q = QskDrawer;
|
||||
using A = QskAspect;
|
||||
|
||||
setAnimation( Q::Panel | A::Metric | A::Position, qskDuration );
|
||||
setGradient( Q::Panel, m_pal.background );
|
||||
setAnimation( Q::Panel | A::Position, 300, QEasingCurve::OutCubic );
|
||||
}
|
||||
|
||||
void Editor::setupSlider()
|
||||
|
@ -1261,6 +1260,7 @@ void Editor::setupSubWindow()
|
|||
for ( auto subControl : { Q::Panel, Q::TitleBarPanel, Q::TitleBarText } )
|
||||
setAnimation( subControl | A::Color, qskDuration );
|
||||
|
||||
setAnimation( Q::Panel | A::Position, qskDuration, QEasingCurve::OutCubic );
|
||||
}
|
||||
|
||||
QskMaterial3Theme::QskMaterial3Theme( QskSkin::ColorScheme colorScheme )
|
||||
|
|
|
@ -409,7 +409,7 @@ void Editor::setupPopup()
|
|||
using Q = QskPopup;
|
||||
|
||||
setHint( Q::Overlay | A::Style, true );
|
||||
setGradient( Q::Overlay, QColor( 220, 220, 220, 150 ) );
|
||||
setGradient( Q::Overlay, qRgba( 220, 220, 220, 150 ) );
|
||||
}
|
||||
|
||||
void Editor::setupMenu()
|
||||
|
@ -446,11 +446,8 @@ void Editor::setupMenu()
|
|||
setGraphicRole( Q::Icon | Q::Disabled, DisabledSymbol );
|
||||
setGraphicRole( Q::Icon | Q::Selected, CursorSymbol );
|
||||
|
||||
setPosition( Q::Panel, 1 );
|
||||
setPosition( Q::Panel | QskPopup::Closed, 0 );
|
||||
|
||||
setAnimation( Q::Panel | A::Metric, 150 );
|
||||
setAnimation( Q::Cursor | A::Position | A::Metric, 75, QEasingCurve::OutCubic );
|
||||
setAnimation( Q::Panel | A::Position, 100 );
|
||||
}
|
||||
|
||||
void Editor::setupTextLabel()
|
||||
|
@ -761,10 +758,11 @@ void Editor::setupDialogButtonBox()
|
|||
|
||||
void Editor::setupDrawer()
|
||||
{
|
||||
using A = QskAspect;
|
||||
using Q = QskDrawer;
|
||||
using A = QskAspect;
|
||||
|
||||
setAnimation( Q::Panel | A::Metric | A::Position, qskDuration );
|
||||
setPanel( Q::Panel, Plain );
|
||||
setAnimation( Q::Panel | A::Position, 300, QEasingCurve::OutCubic );
|
||||
}
|
||||
|
||||
void Editor::setupTabButton()
|
||||
|
@ -1126,8 +1124,12 @@ void Editor::setupSubWindow()
|
|||
|
||||
setAlignment( Q::TitleBarText, Qt::AlignLeft | Qt::AlignVCenter );
|
||||
|
||||
#if 1
|
||||
for ( auto subControl : { Q::Panel, Q::TitleBarPanel, Q::TitleBarText } )
|
||||
setAnimation( subControl | A::Color, qskDuration );
|
||||
#endif
|
||||
|
||||
setAnimation( Q::Panel | A::Position, qskDuration, QEasingCurve::OutCubic );
|
||||
}
|
||||
|
||||
void Editor::setupSpinBox()
|
||||
|
|
|
@ -115,7 +115,6 @@ list(APPEND HEADERS
|
|||
nodes/QskRichTextRenderer.h
|
||||
nodes/QskScaleRenderer.h
|
||||
nodes/QskSGNode.h
|
||||
nodes/QskSlideInNode.h
|
||||
nodes/QskStrokeNode.h
|
||||
nodes/QskStippledLineRenderer.h
|
||||
nodes/QskShapeNode.h
|
||||
|
@ -147,7 +146,6 @@ list(APPEND SOURCES
|
|||
nodes/QskRichTextRenderer.cpp
|
||||
nodes/QskScaleRenderer.cpp
|
||||
nodes/QskSGNode.cpp
|
||||
nodes/QskSlideInNode.cpp
|
||||
nodes/QskStrokeNode.cpp
|
||||
nodes/QskStippledLineRenderer.cpp
|
||||
nodes/QskShapeNode.cpp
|
||||
|
@ -178,6 +176,7 @@ list(APPEND HEADERS
|
|||
controls/QskComboBoxSkinlet.h
|
||||
controls/QskControl.h
|
||||
controls/QskDrawer.h
|
||||
controls/QskDrawerSkinlet.h
|
||||
controls/QskEvent.h
|
||||
controls/QskFlickAnimator.h
|
||||
controls/QskFocusIndicator.h
|
||||
|
@ -281,6 +280,7 @@ list(APPEND SOURCES
|
|||
controls/QskControlPrivate.cpp
|
||||
controls/QskDirtyItemFilter.cpp
|
||||
controls/QskDrawer.cpp
|
||||
controls/QskDrawerSkinlet.cpp
|
||||
controls/QskEvent.cpp
|
||||
controls/QskFlickAnimator.cpp
|
||||
controls/QskFocusIndicator.cpp
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "QskDrawer.h"
|
||||
#include "QskAspect.h"
|
||||
#include "QskAnimationHint.h"
|
||||
#include "QskQuick.h"
|
||||
#include "QskEvent.h"
|
||||
|
||||
|
@ -20,10 +19,6 @@ QSK_QT_PRIVATE_BEGIN
|
|||
#include <private/qquickitemchangelistener_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
|
||||
/*
|
||||
Only used for the sliding in animation. Do we want to
|
||||
introduce a specific panel as background ???
|
||||
*/
|
||||
QSK_SUBCONTROL( QskDrawer, Panel )
|
||||
|
||||
static inline qreal qskDefaultDragMargin()
|
||||
|
@ -63,77 +58,60 @@ static bool qskCheckDirection( Qt::Edge edge, const QskPanGesture* gesture )
|
|||
return false;
|
||||
}
|
||||
|
||||
static void qskLayoutDrawer( const QRectF& rect, QskDrawer* drawer )
|
||||
static inline QRectF qskAlignedToEdge(
|
||||
const QRectF& r, const QSizeF& sz, Qt::Edge edge )
|
||||
{
|
||||
const auto size = qskSizeConstraint( drawer, Qt::PreferredSize );
|
||||
switch( edge )
|
||||
{
|
||||
case Qt::LeftEdge:
|
||||
return QRectF( r.left(), r.top(), sz.width(), r.height() );
|
||||
|
||||
QRectF r( 0.0, 0.0, size.width(), size.height() );
|
||||
case Qt::RightEdge:
|
||||
return QRectF( r.right() - sz.width(), r.top(), sz.width(), r.height() );
|
||||
|
||||
case Qt::TopEdge:
|
||||
return QRectF( r.left(), r.top(), r.width(), sz.height() );
|
||||
|
||||
case Qt::BottomEdge:
|
||||
return QRectF( r.left(), r.bottom() - sz.height(), r.width(), sz.height() );
|
||||
}
|
||||
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
static QPointF qskDrawerTranslation( const QskDrawer* drawer, const QSizeF& size )
|
||||
{
|
||||
const auto ratio = 1.0 - drawer->fadingFactor();
|
||||
|
||||
auto dx = 0.0;
|
||||
auto dy = 0.0;
|
||||
|
||||
switch( drawer->edge() )
|
||||
{
|
||||
case Qt::LeftEdge:
|
||||
{
|
||||
r.setHeight( rect.height() );
|
||||
r.moveRight( rect.left() + size.width() );
|
||||
break;
|
||||
}
|
||||
case Qt::RightEdge:
|
||||
{
|
||||
r.setHeight( rect.height() );
|
||||
r.moveLeft( rect.right() - size.width() );
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::TopEdge:
|
||||
{
|
||||
r.setWidth( rect.width() );
|
||||
r.moveBottom( rect.top() + size.height() );
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::BottomEdge:
|
||||
{
|
||||
r.setWidth( rect.width() );
|
||||
r.moveTop( rect.bottom() - size.height() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drawer->setGeometry( r );
|
||||
}
|
||||
|
||||
static inline QRectF qskSlidingRect(
|
||||
const QSizeF& size, Qt::Edge edge, qreal ratio )
|
||||
{
|
||||
auto x = 0.0;
|
||||
auto y = 0.0;
|
||||
|
||||
ratio = 1.0 - ratio;
|
||||
|
||||
switch( edge )
|
||||
{
|
||||
case Qt::LeftEdge:
|
||||
x = -ratio * size.width();
|
||||
dx = -ratio * size.width();
|
||||
break;
|
||||
|
||||
case Qt::RightEdge:
|
||||
x = ratio * size.width();
|
||||
dx = ratio * size.width();
|
||||
break;
|
||||
|
||||
case Qt::TopEdge:
|
||||
y = -ratio * size.height();
|
||||
dy = -ratio * size.height();
|
||||
break;
|
||||
|
||||
case Qt::BottomEdge:
|
||||
y = ratio * size.height();
|
||||
dy = ratio * size.height();
|
||||
break;
|
||||
}
|
||||
|
||||
return QRectF( x, y, size.width(), size.height() );
|
||||
return QPointF( dx, dy );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// Using an eventFilter for QskEvent::GeometryChange instead ???
|
||||
|
||||
class GeometryListener final : public QQuickItemChangeListener
|
||||
{
|
||||
public:
|
||||
|
@ -160,14 +138,7 @@ namespace
|
|||
private:
|
||||
void adjust()
|
||||
{
|
||||
#if 0
|
||||
const auto pos = m_adjustedItem->mapFromItem( m_item, QPointF() );
|
||||
qskSetItemGeometry( m_adjustedItem,
|
||||
pos.x(), pos.y(), m_item->width(), m_item->height() );
|
||||
#else
|
||||
qskLayoutDrawer( QRectF( QPointF(), m_item->size() ),
|
||||
qobject_cast< QskDrawer* >( m_adjustedItem ) );
|
||||
#endif
|
||||
m_adjustedItem->polish();
|
||||
}
|
||||
|
||||
void setEnabled( bool on )
|
||||
|
@ -184,10 +155,7 @@ namespace
|
|||
QQuickItem* m_item;
|
||||
QQuickItem* m_adjustedItem;
|
||||
};
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class GestureRecognizer : public QskPanGestureRecognizer
|
||||
{
|
||||
using Inherited = QskPanGestureRecognizer;
|
||||
|
@ -204,7 +172,7 @@ namespace
|
|||
bool isAcceptedPos( const QPointF& pos ) const override
|
||||
{
|
||||
auto drawer = qobject_cast< const QskDrawer* >( targetItem() );
|
||||
if ( drawer->isTransitioning() )
|
||||
if ( drawer->isFading() )
|
||||
return false;
|
||||
|
||||
auto rect = qskItemRect( watchedItem() );
|
||||
|
@ -243,6 +211,11 @@ namespace
|
|||
class QskDrawer::PrivateData
|
||||
{
|
||||
public:
|
||||
PrivateData( Qt::Edge edge )
|
||||
: edge( edge )
|
||||
{
|
||||
}
|
||||
|
||||
inline void resetListener( QskDrawer* drawer )
|
||||
{
|
||||
delete listener;
|
||||
|
@ -252,37 +225,39 @@ class QskDrawer::PrivateData
|
|||
listener = new GeometryListener( drawer->parentItem(), drawer );
|
||||
}
|
||||
|
||||
Qt::Edge edge = Qt::LeftEdge;
|
||||
GestureRecognizer* gestureRecognizer = nullptr;
|
||||
GeometryListener* listener = nullptr;
|
||||
GestureRecognizer* gestureRecognizer = nullptr;
|
||||
|
||||
qreal dragMargin = qskDefaultDragMargin();
|
||||
Qt::Edge edge;
|
||||
};
|
||||
|
||||
QskDrawer::QskDrawer( QQuickItem* parentItem )
|
||||
: QskDrawer( Qt::LeftEdge, parentItem )
|
||||
{
|
||||
}
|
||||
|
||||
QskDrawer::QskDrawer( Qt::Edge edge, QQuickItem* parentItem )
|
||||
: Inherited ( parentItem )
|
||||
, m_data( new PrivateData )
|
||||
, m_data( new PrivateData( edge ) )
|
||||
{
|
||||
#if 1
|
||||
setZ( 1 );
|
||||
#endif
|
||||
|
||||
setAutoLayoutChildren( true );
|
||||
setInteractive( true );
|
||||
|
||||
setPopupFlag( PopupFlag::CloseOnPressOutside, true );
|
||||
setTransitionAspect( Panel | QskAspect::Position | QskAspect::Metric );
|
||||
|
||||
/*
|
||||
The drawer wants to be on top of the parent - not being
|
||||
A drawer wants to be on top of its parent - not being
|
||||
layouted into its layoutRect(). So we opt out and do
|
||||
the layout updates manually.
|
||||
*/
|
||||
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
||||
m_data->resetListener( this );
|
||||
|
||||
connect( this, &QskPopup::openChanged, this, &QskDrawer::setSliding );
|
||||
connect( this, &QskPopup::transitioningChanged, this, &QskDrawer::setIntermediate );
|
||||
setAutoLayoutChildren( true );
|
||||
setInteractive( true );
|
||||
|
||||
connect( this, &QskPopup::fadingChanged, this, &QQuickItem::setClip );
|
||||
}
|
||||
|
||||
QskDrawer::~QskDrawer()
|
||||
|
@ -374,18 +349,6 @@ void QskDrawer::gestureEvent( QskGestureEvent* event )
|
|||
Inherited::gestureEvent( event );
|
||||
}
|
||||
|
||||
QRectF QskDrawer::layoutRectForSize( const QSizeF& size ) const
|
||||
{
|
||||
qreal ratio;
|
||||
|
||||
if ( isTransitioning() )
|
||||
ratio = metric( transitionAspect() );
|
||||
else
|
||||
ratio = isOpen() ? 1.0 : 0.0;
|
||||
|
||||
return qskSlidingRect( size, m_data->edge, ratio );
|
||||
}
|
||||
|
||||
void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
||||
const QQuickItem::ItemChangeData& value )
|
||||
{
|
||||
|
@ -409,74 +372,96 @@ void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
|||
}
|
||||
}
|
||||
|
||||
void QskDrawer::setSliding( bool on )
|
||||
void QskDrawer::updateResources()
|
||||
{
|
||||
const qreal from = on ? 0.0 : 1.0;
|
||||
const qreal to = on ? 1.0 : 0.0;
|
||||
Inherited::updateResources();
|
||||
|
||||
const auto aspect = transitionAspect();
|
||||
/*
|
||||
Adjusting the geometry to the parent needs to be done before
|
||||
the layouting of the children ( -> autoLayoutChildren ) is done.
|
||||
So we are using this hook even if it is not about resources: TODO ...
|
||||
*/
|
||||
if ( const auto item = parentItem() )
|
||||
{
|
||||
auto r = qskItemRect( item );
|
||||
r = qskAlignedToEdge( r, sizeConstraint( Qt::PreferredSize ), edge() );
|
||||
|
||||
auto hint = animationHint( aspect );
|
||||
hint.updateFlags = QskAnimationHint::UpdatePolish;
|
||||
r.translate( qskDrawerTranslation( this, r.size() ) );
|
||||
setGeometry( r );
|
||||
}
|
||||
}
|
||||
|
||||
startTransition( aspect, hint, from, to );
|
||||
void QskDrawer::updateNode( QSGNode* node )
|
||||
{
|
||||
if ( isFading() && clip() )
|
||||
{
|
||||
if ( auto clipNode = QQuickItemPrivate::get( this )->clipNode() )
|
||||
{
|
||||
/*
|
||||
The clipRect is changing while fading. Couldn't
|
||||
find a way how to trigger updates - maybe be enabling/disabling
|
||||
the clip. So we do the updates manually. TODO ...
|
||||
*/
|
||||
const auto r = clipRect();
|
||||
if ( r != clipNode->rect() )
|
||||
{
|
||||
clipNode->setRect( r );
|
||||
clipNode->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Inherited::updateNode( node );
|
||||
}
|
||||
|
||||
QRectF QskDrawer::clipRect() const
|
||||
{
|
||||
if ( !isTransitioning() )
|
||||
return Inherited::clipRect();
|
||||
|
||||
/*
|
||||
When fading we want to clip against the edge, where the drawer
|
||||
slides in/out. However the size of the drawer is often smaller than the
|
||||
one of the parent and we would clip the overlay node
|
||||
and all content, that is located outside the drawer geometry.
|
||||
|
||||
So we expand the clip rectangle to "unbounded" at the other edges.
|
||||
|
||||
Note, that clipping against "rounded" rectangles can't be done
|
||||
properly by overloading clipRect. We would have to manipulate the clip node
|
||||
manually - like it is done in QskScrollArea. TODO ..
|
||||
*/
|
||||
constexpr qreal d = std::numeric_limits< short >::max();
|
||||
|
||||
QRectF r( -d, -d, 2.0 * d, 2.0 * d );
|
||||
|
||||
switch( m_data->edge )
|
||||
if ( isFading() && parentItem() )
|
||||
{
|
||||
case Qt::LeftEdge:
|
||||
r.setLeft( 0.0 );
|
||||
break;
|
||||
/*
|
||||
We might not fit into our parent and our children not
|
||||
into our rect. So we want to have a clip against the
|
||||
edge, where the drawer slides in/out only.
|
||||
Otherwise we would have unwanted effects, when clipping gets
|
||||
disabled once the transition is over.
|
||||
*/
|
||||
constexpr qreal d = 1e6;
|
||||
|
||||
case Qt::RightEdge:
|
||||
r.setRight( width() );
|
||||
break;
|
||||
QRectF r( -d, -d, 2.0 * d, 2.0 * d );
|
||||
|
||||
case Qt::TopEdge:
|
||||
r.setTop( 0.0 );
|
||||
break;
|
||||
switch( edge() )
|
||||
{
|
||||
case Qt::LeftEdge:
|
||||
r.setLeft( -x() );
|
||||
break;
|
||||
|
||||
case Qt::BottomEdge:
|
||||
r.setBottom( height() );
|
||||
break;
|
||||
case Qt::RightEdge:
|
||||
r.setRight( parentItem()->width() - x() );
|
||||
break;
|
||||
|
||||
case Qt::TopEdge:
|
||||
r.setTop( -y() );
|
||||
break;
|
||||
|
||||
case Qt::BottomEdge:
|
||||
r.setBottom( parentItem()->height() - y() );
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
return r;
|
||||
return Inherited::clipRect();
|
||||
}
|
||||
|
||||
void QskDrawer::setIntermediate( bool on )
|
||||
QskAspect QskDrawer::fadingAspect() const
|
||||
{
|
||||
setClip( on );
|
||||
Q_EMIT focusIndicatorRectChanged();
|
||||
return QskDrawer::Panel | QskAspect::Position;
|
||||
}
|
||||
|
||||
QRectF QskDrawer::focusIndicatorRect() const
|
||||
QRectF QskDrawer::layoutRectForSize( const QSizeF& size ) const
|
||||
{
|
||||
if ( isTransitioning() )
|
||||
return QRectF();
|
||||
|
||||
return Inherited::focusIndicatorRect();
|
||||
return subControlContentsRect( size, Panel );
|
||||
}
|
||||
|
||||
#include "moc_QskDrawer.cpp"
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#define QSK_DRAWER_H
|
||||
|
||||
#include "QskPopup.h"
|
||||
#include <qnamespace.h>
|
||||
|
||||
class QSK_EXPORT QskDrawer : public QskPopup
|
||||
{
|
||||
|
@ -27,6 +26,8 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
|||
QSK_SUBCONTROLS( Panel )
|
||||
|
||||
QskDrawer( QQuickItem* = nullptr );
|
||||
QskDrawer( Qt::Edge, QQuickItem* = nullptr );
|
||||
|
||||
~QskDrawer() override;
|
||||
|
||||
void setEdge( Qt::Edge );
|
||||
|
@ -39,10 +40,10 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
|||
void resetDragMargin();
|
||||
qreal dragMargin() const;
|
||||
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
|
||||
QRectF clipRect() const override;
|
||||
QRectF focusIndicatorRect() const override;
|
||||
QskAspect fadingAspect() const override;
|
||||
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void edgeChanged( Qt::Edge );
|
||||
|
@ -50,14 +51,13 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
|||
void interactiveChanged( bool );
|
||||
|
||||
protected:
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
void gestureEvent( QskGestureEvent* ) override;
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
|
||||
void updateResources() override;
|
||||
void updateNode( QSGNode* ) override;
|
||||
|
||||
private:
|
||||
void setSliding( bool );
|
||||
|
||||
void setIntermediate( bool );
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskDrawerSkinlet.h"
|
||||
#include "QskDrawer.h"
|
||||
|
||||
QskDrawerSkinlet::QskDrawerSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
appendNodeRoles( { PanelRole } );
|
||||
}
|
||||
|
||||
QskDrawerSkinlet::~QskDrawerSkinlet() = default;
|
||||
|
||||
QRectF QskDrawerSkinlet::subControlRect(
|
||||
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||
QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
if ( subControl == QskDrawer::Panel )
|
||||
return contentsRect;
|
||||
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskDrawerSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
if ( nodeRole == PanelRole )
|
||||
return updateBoxNode( skinnable, node, QskDrawer::Panel );
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QSizeF QskDrawerSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( which == Qt::PreferredSize )
|
||||
return skinnable->strutSizeHint( QskDrawer::Panel );
|
||||
|
||||
return Inherited::sizeHint( skinnable, which, constraint );
|
||||
}
|
||||
|
||||
#include "moc_QskDrawerSkinlet.cpp"
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_DRAWER_SKINLET_H
|
||||
#define QSK_DRAWER_SKINLET_H
|
||||
|
||||
#include "QskPopupSkinlet.h"
|
||||
|
||||
class QSK_EXPORT QskDrawerSkinlet : public QskPopupSkinlet
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
using Inherited = QskPopupSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole
|
||||
{
|
||||
ContentsRole = Inherited::RoleCount,
|
||||
PanelRole,
|
||||
|
||||
RoleCount
|
||||
};
|
||||
|
||||
Q_INVOKABLE QskDrawerSkinlet( QskSkin* = nullptr );
|
||||
~QskDrawerSkinlet() override;
|
||||
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||
|
||||
QSizeF sizeHint( const QskSkinnable*,
|
||||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
protected:
|
||||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -18,7 +18,10 @@
|
|||
#include <qvariant.h>
|
||||
#include <qeventloop.h>
|
||||
|
||||
QSK_SUBCONTROL( QskMenu, Overlay )
|
||||
QSK_QT_PRIVATE_BEGIN
|
||||
#include <private/qquickitem_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
|
||||
QSK_SUBCONTROL( QskMenu, Panel )
|
||||
QSK_SUBCONTROL( QskMenu, Segment )
|
||||
QSK_SUBCONTROL( QskMenu, Cursor )
|
||||
|
@ -58,20 +61,23 @@ QskMenu::QskMenu( QQuickItem* parent )
|
|||
, m_data( new PrivateData )
|
||||
{
|
||||
setModal( true );
|
||||
setTransitionAspect( QskMenu::Panel | QskAspect::Position | QskAspect::Metric );
|
||||
|
||||
setPopupFlag( QskPopup::CloseOnPressOutside, true );
|
||||
setPopupFlag( QskPopup::DeleteOnClose, true );
|
||||
|
||||
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
||||
setSubcontrolProxy( Inherited::Overlay, Overlay );
|
||||
|
||||
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
|
||||
// we hide the focus indicator while sliding
|
||||
connect( this, &QskMenu::transitioningChanged, this,
|
||||
&QskControl::focusIndicatorRectChanged );
|
||||
connect( this, &QskPopup::fadingChanged,
|
||||
this, &QskControl::focusIndicatorRectChanged );
|
||||
|
||||
connect( this, &QskMenu::opened, this,
|
||||
connect( this, &QskPopup::fadingChanged,
|
||||
this, &QQuickItem::setClip );
|
||||
|
||||
connect( this, &QskPopup::opened, this,
|
||||
[this]() { m_data->triggeredIndex = -1; } );
|
||||
|
||||
setAcceptHoverEvents( true );
|
||||
|
@ -81,6 +87,17 @@ QskMenu::~QskMenu()
|
|||
{
|
||||
}
|
||||
|
||||
QRectF QskMenu::clipRect() const
|
||||
{
|
||||
if ( isFading() )
|
||||
{
|
||||
constexpr qreal d = 1e6;
|
||||
return QRectF( -d, m_data->origin.y() - y(), 2.0 * d, d );
|
||||
}
|
||||
|
||||
return Inherited::clipRect();
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
// has no effect as we do not offer submenus yet. TODO ...
|
||||
|
@ -263,6 +280,40 @@ QString QskMenu::triggeredText() const
|
|||
return optionAt( m_data->triggeredIndex ).text();
|
||||
}
|
||||
|
||||
void QskMenu::updateResources()
|
||||
{
|
||||
qreal dy = 0.0;
|
||||
if ( isFading() )
|
||||
dy = ( 1.0 - fadingFactor() ) * height();
|
||||
|
||||
setPosition( m_data->origin.x(), m_data->origin.y() - dy );
|
||||
|
||||
Inherited::updateResources();
|
||||
}
|
||||
|
||||
void QskMenu::updateNode( QSGNode* node )
|
||||
{
|
||||
if ( isFading() && clip() )
|
||||
{
|
||||
if ( auto clipNode = QQuickItemPrivate::get( this )->clipNode() )
|
||||
{
|
||||
/*
|
||||
The clipRect is changing while fading. Couldn't
|
||||
find a way how to trigger updates - maybe be enabling/disabling
|
||||
the clip. So we do the updates manually. TODO ...
|
||||
*/
|
||||
const auto r = clipRect();
|
||||
if ( r != clipNode->rect() )
|
||||
{
|
||||
clipNode->setRect( r );
|
||||
clipNode->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Inherited::updateNode( node );
|
||||
}
|
||||
|
||||
void QskMenu::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
if( m_data->currentIndex < 0 )
|
||||
|
@ -435,7 +486,7 @@ void QskMenu::mouseReleaseEvent( QMouseEvent* event )
|
|||
|
||||
void QskMenu::aboutToShow()
|
||||
{
|
||||
setGeometry( QRectF( m_data->origin, sizeConstraint() ) );
|
||||
setSize( sizeConstraint() );
|
||||
|
||||
if ( m_data->currentIndex < 0 )
|
||||
{
|
||||
|
@ -448,7 +499,7 @@ void QskMenu::aboutToShow()
|
|||
|
||||
QRectF QskMenu::focusIndicatorRect() const
|
||||
{
|
||||
if ( isTransitioning() )
|
||||
if ( isFading() )
|
||||
return QRectF();
|
||||
|
||||
if( currentIndex() >= 0 )
|
||||
|
@ -492,6 +543,11 @@ void QskMenu::trigger( int index )
|
|||
}
|
||||
}
|
||||
|
||||
QskAspect QskMenu::fadingAspect() const
|
||||
{
|
||||
return QskMenu::Panel | QskAspect::Position;
|
||||
}
|
||||
|
||||
int QskMenu::exec()
|
||||
{
|
||||
(void) execPopup();
|
||||
|
|
|
@ -37,7 +37,7 @@ class QSK_EXPORT QskMenu : public QskPopup
|
|||
using Inherited = QskPopup;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Overlay, Panel, Segment, Cursor, Text, Icon, Separator )
|
||||
QSK_SUBCONTROLS( Panel, Segment, Cursor, Text, Icon, Separator )
|
||||
QSK_STATES( Selected, Pressed )
|
||||
|
||||
QskMenu( QQuickItem* parentItem = nullptr );
|
||||
|
@ -81,6 +81,9 @@ class QSK_EXPORT QskMenu : public QskPopup
|
|||
|
||||
bool isPressed() const;
|
||||
|
||||
QRectF clipRect() const override;
|
||||
QskAspect fadingAspect() const override;
|
||||
|
||||
Q_INVOKABLE int exec();
|
||||
|
||||
Q_SIGNALS:
|
||||
|
@ -115,6 +118,9 @@ class QSK_EXPORT QskMenu : public QskPopup
|
|||
void aboutToShow() override;
|
||||
void trigger( int );
|
||||
|
||||
void updateResources() override;
|
||||
void updateNode( QSGNode* ) override;
|
||||
|
||||
private:
|
||||
void traverse( int steps );
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "QskLabelData.h"
|
||||
|
||||
#include "QskSGNode.h"
|
||||
#include "QskSlideInNode.h"
|
||||
|
||||
#include <qfontmetrics.h>
|
||||
#include <qmath.h>
|
||||
|
@ -223,26 +222,13 @@ QSGNode* QskMenuSkinlet::updateSubNode(
|
|||
{
|
||||
case ContentsRole:
|
||||
{
|
||||
/*
|
||||
QskSlideInNode works for controls made of nodes - not for
|
||||
containers of other quick items. TODO ...
|
||||
*/
|
||||
|
||||
const auto popup = static_cast< const QskPopup* >( skinnable );
|
||||
|
||||
auto rect = popup->contentsRect();
|
||||
if ( rect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto slideInNode = QskSGNode::ensureNode< QskSlideInNode >( node );
|
||||
|
||||
const auto progress = popup->metric( popup->transitionAspect() );
|
||||
slideInNode->updateTranslation( rect, Qt::TopEdge, progress );
|
||||
|
||||
auto contentsNode = updateContentsNode( popup, slideInNode->contentsNode() );
|
||||
slideInNode->setContentsNode( contentsNode );
|
||||
|
||||
return slideInNode;
|
||||
return updateContentsNode( popup, node );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,23 @@ static bool qskReplayMousePress()
|
|||
return false;
|
||||
}
|
||||
|
||||
static void qskStartFading( QskPopup* popup, bool on )
|
||||
{
|
||||
const auto aspect = popup->fadingAspect();
|
||||
|
||||
auto hint = popup->animationHint( aspect );
|
||||
|
||||
if ( hint.isValid() )
|
||||
{
|
||||
hint.updateFlags = QskAnimationHint::UpdatePolish | QskAnimationHint::UpdateNode;
|
||||
|
||||
const qreal from = on ? 0.0 : 1.0;
|
||||
const qreal to = on ? 1.0 : 0.0;
|
||||
|
||||
popup->startTransition( aspect, hint, from, to );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class InputGrabber final : public QskInputGrabber
|
||||
|
@ -139,7 +156,6 @@ class QskPopup::PrivateData
|
|||
InputGrabber* inputGrabber = nullptr;
|
||||
|
||||
uint priority = 0;
|
||||
QskAspect transitionAspect;
|
||||
|
||||
int flags : 4;
|
||||
bool isModal : 1;
|
||||
|
@ -217,9 +233,11 @@ void QskPopup::setOpen( bool on )
|
|||
else
|
||||
Q_EMIT closed();
|
||||
|
||||
if ( isTransitioning() )
|
||||
qskStartFading( this, on );
|
||||
|
||||
if ( isFading() )
|
||||
{
|
||||
Q_EMIT transitioningChanged( true );
|
||||
Q_EMIT fadingChanged( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -238,9 +256,22 @@ bool QskPopup::isOpen() const
|
|||
return !hasSkinState( QskPopup::Closed );
|
||||
}
|
||||
|
||||
bool QskPopup::isTransitioning() const
|
||||
QskAspect QskPopup::fadingAspect() const
|
||||
{
|
||||
return runningHintAnimator( m_data->transitionAspect ) != nullptr;
|
||||
return QskAspect();
|
||||
}
|
||||
|
||||
bool QskPopup::isFading() const
|
||||
{
|
||||
return runningHintAnimator( fadingAspect() ) != nullptr;
|
||||
}
|
||||
|
||||
qreal QskPopup::fadingFactor() const
|
||||
{
|
||||
if ( auto animator = runningHintAnimator( fadingAspect() ) )
|
||||
return animator->currentValue().value< qreal >();
|
||||
|
||||
return isOpen() ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
QRectF QskPopup::overlayRect() const
|
||||
|
@ -291,44 +322,23 @@ void QskPopup::updateInputGrabber()
|
|||
}
|
||||
}
|
||||
|
||||
QskAspect QskPopup::transitionAspect() const
|
||||
{
|
||||
return m_data->transitionAspect;
|
||||
}
|
||||
|
||||
void QskPopup::setTransitionAspect( QskAspect aspect )
|
||||
{
|
||||
auto transitionAspect = aspect;
|
||||
transitionAspect.clearStates(); // animated values are always stateless
|
||||
|
||||
if ( transitionAspect == m_data->transitionAspect )
|
||||
return;
|
||||
|
||||
if ( isTransitioning() )
|
||||
{
|
||||
// stop the running animation TODO ...
|
||||
}
|
||||
|
||||
m_data->transitionAspect = transitionAspect;
|
||||
}
|
||||
|
||||
bool QskPopup::isTransitionAccepted( QskAspect aspect ) const
|
||||
{
|
||||
if ( isVisible() )
|
||||
if ( isVisible() && !isInitiallyPainted() )
|
||||
{
|
||||
/*
|
||||
Usually we suppress transitions, when a control has never been
|
||||
painted before as there is no valid starting point. Popups are
|
||||
different as we want to have smooth fade/slide appearances.
|
||||
*/
|
||||
if ( ( aspect.value() == 0 ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( aspect == m_data->transitionAspect )
|
||||
return true;
|
||||
|
||||
if ( aspect.isColor() )
|
||||
{
|
||||
if ( aspect.subControl() == effectiveSubcontrol( QskPopup::Overlay ) )
|
||||
return true;
|
||||
}
|
||||
if ( aspect.subControl() == effectiveSubcontrol( fadingAspect().subControl() ) )
|
||||
return true;
|
||||
|
||||
if ( aspect.subControl() == effectiveSubcontrol( QskPopup::Overlay ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return Inherited::isTransitionAccepted( aspect );
|
||||
|
@ -475,7 +485,7 @@ bool QskPopup::event( QEvent* event )
|
|||
const auto animatorEvent = static_cast< QskAnimatorEvent* >( event );
|
||||
|
||||
if ( ( animatorEvent->state() == QskAnimatorEvent::Terminated )
|
||||
&& ( animatorEvent->aspect() == m_data->transitionAspect ) )
|
||||
&& ( animatorEvent->aspect() == fadingAspect() ) )
|
||||
{
|
||||
if ( !isOpen() )
|
||||
{
|
||||
|
@ -485,7 +495,7 @@ bool QskPopup::event( QEvent* event )
|
|||
deleteLater();
|
||||
}
|
||||
|
||||
Q_EMIT transitioningChanged( false );
|
||||
Q_EMIT fadingChanged( false );
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -633,7 +643,7 @@ int QskPopup::execPopup()
|
|||
*/
|
||||
|
||||
connect( popup, &QObject::destroyed, this, &EventLoop::reject );
|
||||
connect( popup, &QskPopup::transitioningChanged, this, &EventLoop::maybeQuit );
|
||||
connect( popup, &QskPopup::fadingChanged, this, &EventLoop::maybeQuit );
|
||||
connect( popup, &QskPopup::openChanged, this, &EventLoop::maybeQuit );
|
||||
}
|
||||
|
||||
|
@ -648,7 +658,7 @@ int QskPopup::execPopup()
|
|||
{
|
||||
if ( auto popup = qobject_cast< const QskPopup* >( parent() ) )
|
||||
{
|
||||
if ( popup->isOpen() || popup->isTransitioning() )
|
||||
if ( popup->isOpen() || popup->isFading() )
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -656,7 +666,7 @@ int QskPopup::execPopup()
|
|||
}
|
||||
};
|
||||
|
||||
if ( isOpen() || isTransitioning() )
|
||||
if ( isOpen() || isFading() )
|
||||
{
|
||||
qWarning() << "QskPopup::exec: popup is already opened";
|
||||
return -1;
|
||||
|
|
|
@ -14,7 +14,7 @@ class QSK_EXPORT QskPopup : public QskControl
|
|||
|
||||
Q_PROPERTY( bool open READ isOpen WRITE setOpen NOTIFY openChanged )
|
||||
Q_PROPERTY( bool modal READ isModal WRITE setModal NOTIFY modalChanged )
|
||||
Q_PROPERTY( bool transitioning READ isTransitioning NOTIFY transitioningChanged )
|
||||
Q_PROPERTY( bool fading READ isFading NOTIFY fadingChanged )
|
||||
|
||||
Q_PROPERTY( bool overlay READ hasOverlay
|
||||
WRITE setOverlay RESET resetOverlay NOTIFY overlayChanged )
|
||||
|
@ -56,15 +56,13 @@ class QSK_EXPORT QskPopup : public QskControl
|
|||
void setPriority( uint );
|
||||
uint priority() const;
|
||||
|
||||
// transitions between open/closed states
|
||||
QskAspect transitionAspect() const;
|
||||
void setTransitionAspect( QskAspect );
|
||||
|
||||
bool isTransitioning() const;
|
||||
|
||||
bool isOpen() const;
|
||||
bool isClosed() const;
|
||||
|
||||
bool isFading() const;
|
||||
qreal fadingFactor() const;
|
||||
virtual QskAspect fadingAspect() const;
|
||||
|
||||
virtual QRectF overlayRect() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
|
@ -78,7 +76,7 @@ class QSK_EXPORT QskPopup : public QskControl
|
|||
void opened();
|
||||
void closed();
|
||||
void openChanged( bool );
|
||||
void transitioningChanged( bool );
|
||||
void fadingChanged( bool );
|
||||
|
||||
void modalChanged( bool );
|
||||
void overlayChanged( bool );
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
|
||||
#include "QskPopupSkinlet.h"
|
||||
#include "QskPopup.h"
|
||||
#include "QskRgbValue.h"
|
||||
|
||||
static inline QRgb qskInterpolatedRgb( QRgb rgb, qreal factor )
|
||||
{
|
||||
return QskRgb::toTransparent( rgb, qRound( factor * qAlpha( rgb ) ) );
|
||||
}
|
||||
|
||||
QskPopupSkinlet::QskPopupSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
|
@ -28,13 +34,43 @@ 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 );
|
||||
return updateOverlayNode( popup, node );
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QSGNode* QskPopupSkinlet::updateOverlayNode(
|
||||
const QskPopup* popup, QSGNode* node ) const
|
||||
{
|
||||
using Q = QskPopup;
|
||||
|
||||
const auto factor = popup->fadingFactor();
|
||||
if ( factor <= 0.0 )
|
||||
return nullptr;
|
||||
|
||||
const auto rect = popup->subControlRect( Q::Overlay );
|
||||
if ( rect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto gradient = popup->gradientHint( Q::Overlay );
|
||||
|
||||
if ( gradient.isVisible() && factor != 1.0 )
|
||||
{
|
||||
auto stops = gradient.stops();
|
||||
|
||||
for ( auto& stop : stops )
|
||||
stop.setRgb( qskInterpolatedRgb( stop.rgb(), factor ) );
|
||||
|
||||
gradient.setStops( stops );
|
||||
}
|
||||
|
||||
return updateBoxNode( popup, node, rect, gradient, QskPopup::Overlay );
|
||||
}
|
||||
|
||||
#include "moc_QskPopupSkinlet.cpp"
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
#include "QskComboBox.h"
|
||||
#include "QskComboBoxSkinlet.h"
|
||||
|
||||
#include "QskDrawer.h"
|
||||
#include "QskDrawerSkinlet.h"
|
||||
|
||||
#include "QskFocusIndicator.h"
|
||||
#include "QskFocusIndicatorSkinlet.h"
|
||||
|
||||
|
@ -160,6 +163,7 @@ QskSkin::QskSkin( QObject* parent )
|
|||
declareSkinlet< QskBox, QskBoxSkinlet >();
|
||||
declareSkinlet< QskCheckBox, QskCheckBoxSkinlet >();
|
||||
declareSkinlet< QskComboBox, QskComboBoxSkinlet >();
|
||||
declareSkinlet< QskDrawer, QskDrawerSkinlet >();
|
||||
declareSkinlet< QskFocusIndicator, QskFocusIndicatorSkinlet >();
|
||||
declareSkinlet< QskGraphicLabel, QskGraphicLabelSkinlet >();
|
||||
declareSkinlet< QskListView, QskListViewSkinlet >();
|
||||
|
|
|
@ -253,4 +253,15 @@ void QskSubWindow::itemChange( QQuickItem::ItemChange change,
|
|||
}
|
||||
}
|
||||
|
||||
void QskSubWindow::updateResources()
|
||||
{
|
||||
setOpacity( fadingFactor() );
|
||||
Inherited::updateResources();
|
||||
}
|
||||
|
||||
QskAspect QskSubWindow::fadingAspect() const
|
||||
{
|
||||
return QskSubWindow::Panel | QskAspect::Position;
|
||||
}
|
||||
|
||||
#include "moc_QskSubWindow.cpp"
|
||||
|
|
|
@ -83,6 +83,7 @@ class QSK_EXPORT QskSubWindow : public QskPopup
|
|||
QRectF titleBarRect() const;
|
||||
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
QskAspect fadingAspect() const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void decorationsChanged( Decorations );
|
||||
|
@ -95,6 +96,8 @@ class QSK_EXPORT QskSubWindow : public QskPopup
|
|||
bool event( QEvent* ) override;
|
||||
|
||||
void updateLayout() override;
|
||||
void updateResources() override;
|
||||
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
void itemChange( QQuickItem::ItemChange,
|
||||
|
|
|
@ -94,6 +94,18 @@ QSGNode* QskSubWindowSkinlet::updateSubNode(
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
case OverlayRole:
|
||||
{
|
||||
/*
|
||||
Overloading QskPopupSkinlet: as the opacity of the subwindow already
|
||||
depends on the fadingFactor we do not want the additional opacity
|
||||
adjustments for the overlay node.
|
||||
Maybe we should have a flag that indicates if the popup does
|
||||
opacity or geometry transitions, when fading TODO ...
|
||||
*/
|
||||
updateBoxNode( subWindow, node, Q::Overlay );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
|
|
|
@ -77,6 +77,7 @@ static void qskSetupSubWindow(
|
|||
const QString& title, QskDialog::Actions actions,
|
||||
QskDialog::Action defaultAction, QskDialogSubWindow* subWindow )
|
||||
{
|
||||
subWindow->setPopupFlag( QskPopup::DeleteOnClose );
|
||||
subWindow->setModal( true );
|
||||
subWindow->setWindowTitle( title );
|
||||
subWindow->setDialogActions( actions );
|
||||
|
@ -128,14 +129,14 @@ static QskDialog::Action qskMessageSubWindow(
|
|||
const QString& text, int symbolType, QskDialog::Actions actions,
|
||||
QskDialog::Action defaultAction )
|
||||
{
|
||||
QskMessageSubWindow subWindow( window->contentItem() );
|
||||
subWindow.setSymbolType( symbolType );
|
||||
subWindow.setText( text );
|
||||
auto subWindow = new QskMessageSubWindow( window->contentItem() );
|
||||
subWindow->setSymbolType( symbolType );
|
||||
subWindow->setText( text );
|
||||
|
||||
qskSetupSubWindow( title, actions, defaultAction, &subWindow );
|
||||
( void ) subWindow.exec();
|
||||
qskSetupSubWindow( title, actions, defaultAction, subWindow );
|
||||
( void ) subWindow->exec();
|
||||
|
||||
auto clickedAction = subWindow.clickedAction();
|
||||
auto clickedAction = subWindow->clickedAction();
|
||||
if ( clickedAction == QskDialog::NoAction )
|
||||
{
|
||||
// dialog might have been closed by the window menu
|
||||
|
@ -172,16 +173,16 @@ static QString qskSelectSubWindow(
|
|||
QskDialog::Actions actions, QskDialog::Action defaultAction,
|
||||
const QStringList& entries, int selectedRow )
|
||||
{
|
||||
QskSelectionSubWindow subWindow( window->contentItem() );
|
||||
subWindow.setInfoText( text );
|
||||
subWindow.setEntries( entries );
|
||||
subWindow.setSelectedRow( selectedRow );
|
||||
auto subWindow = new QskSelectionSubWindow( window->contentItem() );
|
||||
subWindow->setInfoText( text );
|
||||
subWindow->setEntries( entries );
|
||||
subWindow->setSelectedRow( selectedRow );
|
||||
|
||||
QString selectedEntry;
|
||||
|
||||
qskSetupSubWindow( title, actions, defaultAction, &subWindow );
|
||||
if ( subWindow.exec() == QskDialog::Accepted )
|
||||
selectedEntry = subWindow.selectedEntry();
|
||||
qskSetupSubWindow( title, actions, defaultAction, subWindow );
|
||||
if ( subWindow->exec() == QskDialog::Accepted )
|
||||
selectedEntry = subWindow->selectedEntry();
|
||||
|
||||
return selectedEntry;
|
||||
}
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskSlideInNode.h"
|
||||
#include "QskSGNode.h"
|
||||
#include <qtransform.h>
|
||||
|
||||
QSK_QT_PRIVATE_BEGIN
|
||||
#include <private/qsgnode_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
|
||||
class QskSlideInNodePrivate final : public QSGNodePrivate
|
||||
{
|
||||
public:
|
||||
~QskSlideInNodePrivate()
|
||||
{
|
||||
delete clipNode;
|
||||
delete transformNode;
|
||||
delete contentsNode;
|
||||
}
|
||||
|
||||
void reparentContentNode( QskSlideInNode* node )
|
||||
{
|
||||
if ( contentsNode )
|
||||
{
|
||||
QSGNode* parentNode = transformNode;
|
||||
|
||||
if ( parentNode == nullptr )
|
||||
parentNode = clipNode;
|
||||
|
||||
if ( parentNode == nullptr )
|
||||
parentNode = node;
|
||||
|
||||
QskSGNode::setParentNode( contentsNode, parentNode );
|
||||
}
|
||||
}
|
||||
|
||||
QSGClipNode* clipNode = nullptr;
|
||||
QSGTransformNode* transformNode = nullptr;
|
||||
QSGNode* contentsNode = nullptr;
|
||||
};
|
||||
|
||||
QskSlideInNode::QskSlideInNode()
|
||||
: QSGNode( *new QskSlideInNodePrivate, QSGNode::BasicNodeType )
|
||||
{
|
||||
}
|
||||
|
||||
QskSlideInNode::~QskSlideInNode() = default;
|
||||
|
||||
void QskSlideInNode::updateTranslation( const QRectF& rect,
|
||||
Qt::Edge edge, qreal progress )
|
||||
{
|
||||
Q_UNUSED( edge ); // TODO ...
|
||||
|
||||
Q_D( QskSlideInNode );
|
||||
|
||||
{
|
||||
// clipping
|
||||
|
||||
if ( progress >= 0.0 && progress < 1.0 )
|
||||
{
|
||||
if ( d->clipNode == nullptr )
|
||||
{
|
||||
d->clipNode = new QSGClipNode();
|
||||
d->clipNode->setFlag( QSGNode::OwnedByParent, false );
|
||||
d->clipNode->setIsRectangular( true );
|
||||
}
|
||||
|
||||
d->clipNode->setClipRect( rect );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
delete d->clipNode;
|
||||
d->clipNode = nullptr;
|
||||
}
|
||||
|
||||
if ( d->clipNode )
|
||||
QskSGNode::setParentNode( d->clipNode, this );
|
||||
}
|
||||
|
||||
{
|
||||
// translation
|
||||
|
||||
qreal dx = 0.0;
|
||||
qreal dy = ( progress - 1.0 ) * rect.height();
|
||||
|
||||
if ( dx != 0.0 || dy != 0.0 )
|
||||
{
|
||||
if ( d->transformNode == nullptr )
|
||||
{
|
||||
d->transformNode = new QSGTransformNode();
|
||||
d->transformNode->setFlag( QSGNode::OwnedByParent, false );
|
||||
}
|
||||
|
||||
QTransform transform;
|
||||
transform.translate( dx, dy );
|
||||
|
||||
d->transformNode->setMatrix( transform );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete d->transformNode;
|
||||
d->transformNode = nullptr;
|
||||
}
|
||||
|
||||
if ( d->transformNode )
|
||||
{
|
||||
QSGNode* parentNode = d->clipNode;
|
||||
if ( parentNode == nullptr )
|
||||
parentNode = this;
|
||||
|
||||
QskSGNode::setParentNode( d->transformNode, parentNode );
|
||||
}
|
||||
}
|
||||
|
||||
d->reparentContentNode( this );
|
||||
}
|
||||
|
||||
void QskSlideInNode::setContentsNode( QSGNode* node )
|
||||
{
|
||||
Q_D( QskSlideInNode );
|
||||
|
||||
if ( d->contentsNode == node )
|
||||
return;
|
||||
|
||||
if ( node )
|
||||
node->setFlag( QSGNode::OwnedByParent, false );
|
||||
|
||||
delete d->contentsNode;
|
||||
d->contentsNode = node;
|
||||
|
||||
d->reparentContentNode( this );
|
||||
}
|
||||
|
||||
QSGNode* QskSlideInNode::contentsNode()
|
||||
{
|
||||
return d_func()->contentsNode;
|
||||
}
|
||||
|
||||
const QSGNode* QskSlideInNode::contentsNode() const
|
||||
{
|
||||
return d_func()->contentsNode;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_SLIDE_IN_NODE_H
|
||||
#define QSK_SLIDE_IN_NODE_H
|
||||
|
||||
#include "QskGlobal.h"
|
||||
|
||||
#include <qsgnode.h>
|
||||
#include <qnamespace.h>
|
||||
|
||||
class QskSlideInNodePrivate;
|
||||
|
||||
class QSK_EXPORT QskSlideInNode : public QSGNode
|
||||
{
|
||||
public:
|
||||
QskSlideInNode();
|
||||
~QskSlideInNode() override;
|
||||
|
||||
void updateTranslation( const QRectF&, Qt::Edge, qreal progress );
|
||||
|
||||
void setContentsNode( QSGNode* );
|
||||
|
||||
QSGNode* contentsNode();
|
||||
const QSGNode* contentsNode() const;
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE( QskSlideInNode )
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue