much easier implementation used - the only hack is about updating the
clip node manually for each updatePaintNode
This commit is contained in:
parent
a9621f19ed
commit
4afe56990b
|
@ -9,6 +9,7 @@
|
||||||
#include <QskControl.h>
|
#include <QskControl.h>
|
||||||
#include <QskDrawer.h>
|
#include <QskDrawer.h>
|
||||||
#include <QskPushButton.h>
|
#include <QskPushButton.h>
|
||||||
|
#include <QskFocusIndicator.h>
|
||||||
#include <QskWindow.h>
|
#include <QskWindow.h>
|
||||||
#include <QskEvent.h>
|
#include <QskEvent.h>
|
||||||
#include <QskAnimationHint.h>
|
#include <QskAnimationHint.h>
|
||||||
|
@ -30,31 +31,32 @@ namespace
|
||||||
content->setAutoLayoutChildren( true );
|
content->setAutoLayoutChildren( true );
|
||||||
content->setMargins( 20 );
|
content->setMargins( 20 );
|
||||||
|
|
||||||
|
auto button = new QskPushButton( "Push Me", content );
|
||||||
|
button->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||||
|
button->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||||
|
|
||||||
|
const auto size = content->sizeHint();
|
||||||
|
|
||||||
switch( edge )
|
switch( edge )
|
||||||
{
|
{
|
||||||
case Qt::LeftEdge:
|
case Qt::LeftEdge:
|
||||||
content->setBackgroundColor( QskRgb::Tomato );
|
content->setBackgroundColor( QskRgb::Tomato );
|
||||||
content->setFixedWidth( 100 );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::RightEdge:
|
case Qt::RightEdge:
|
||||||
content->setFixedWidth( 200 );
|
content->setFixedWidth( 1.5 * size.width() );
|
||||||
content->setBackgroundColor( QskRgb::Orchid );
|
content->setBackgroundColor( QskRgb::Orchid );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::TopEdge:
|
case Qt::TopEdge:
|
||||||
content->setFixedHeight( 100 );
|
|
||||||
content->setBackgroundColor( QskRgb::Chartreuse );
|
content->setBackgroundColor( QskRgb::Chartreuse );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
case Qt::BottomEdge:
|
||||||
content->setFixedHeight( 200 );
|
content->setFixedHeight( 2 * size.height() );
|
||||||
content->setBackgroundColor( QskRgb::Wheat );
|
content->setBackgroundColor( QskRgb::Wheat );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto button = new QskPushButton( "Push Me", content );
|
|
||||||
button->setPreferredHeight( 100 );
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,6 +129,7 @@ int main( int argc, char* argv[] )
|
||||||
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
||||||
|
|
||||||
QskWindow window;
|
QskWindow window;
|
||||||
|
window.addItem( new QskFocusIndicator() );
|
||||||
window.addItem( new MainBox() );
|
window.addItem( new MainBox() );
|
||||||
window.resize( 600, 600 );
|
window.resize( 600, 600 );
|
||||||
window.show();
|
window.show();
|
||||||
|
|
|
@ -51,44 +51,6 @@ static bool qskCheckDirection( Qt::Edge edge, const QskPanGesture* gesture )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QRectF qskAlignedToEdge(
|
|
||||||
const QRectF& rect, const QSizeF& size, Qt::Edge edge )
|
|
||||||
{
|
|
||||||
QRectF r( 0.0, 0.0, size.width(), size.height() );
|
|
||||||
|
|
||||||
switch( 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class GestureRecognizer : public QskPanGestureRecognizer
|
class GestureRecognizer : public QskPanGestureRecognizer
|
||||||
|
@ -231,24 +193,6 @@ qreal QskDrawer::dragMargin() const
|
||||||
return m_data->dragMargin;
|
return m_data->dragMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QskDrawer::event( QEvent* event )
|
|
||||||
{
|
|
||||||
if ( event->type() == QEvent::PolishRequest )
|
|
||||||
{
|
|
||||||
if ( const auto item = parentItem() )
|
|
||||||
{
|
|
||||||
auto r = qskItemRect( item );
|
|
||||||
r = qskAlignedToEdge( r, sizeConstraint( Qt::PreferredSize ), edge() );
|
|
||||||
|
|
||||||
setGeometry( r );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Inherited::event( event );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskDrawer::gestureEvent( QskGestureEvent* event )
|
void QskDrawer::gestureEvent( QskGestureEvent* event )
|
||||||
{
|
{
|
||||||
if ( event->gesture()->type() == QskGesture::Pan )
|
if ( event->gesture()->type() == QskGesture::Pan )
|
||||||
|
|
|
@ -42,8 +42,6 @@ class QSK_EXPORT QskDrawer : public QskSlideIn
|
||||||
void interactiveChanged( bool );
|
void interactiveChanged( bool );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool event( QEvent* ) override;
|
|
||||||
|
|
||||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||||
void gestureEvent( QskGestureEvent* ) override;
|
void gestureEvent( QskGestureEvent* ) override;
|
||||||
|
|
||||||
|
|
|
@ -76,20 +76,28 @@ static inline QVariant qskAligned05( const QVariant& value )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline bool qskCheckReceiverThread( const QObject* receiver )
|
static inline void qskSendAnimatorEvent(
|
||||||
|
const QskAspect aspect, int index, bool on, QObject* receiver )
|
||||||
{
|
{
|
||||||
/*
|
const auto state = on ? QskAnimatorEvent::Started : QskAnimatorEvent::Terminated;
|
||||||
QskInputPanelSkinlet changes the skin state, what leads to
|
|
||||||
sending events from the wrong thread. Until we have fixed it
|
|
||||||
let's block sending the event to avoid running into assertions
|
|
||||||
in QCoreApplication::sendEvent
|
|
||||||
*/
|
|
||||||
|
|
||||||
const QThread* thread = receiver->thread();
|
const auto thread = receiver->thread();
|
||||||
if ( thread == nullptr )
|
if ( thread && ( thread != QThread::currentThread() ) )
|
||||||
return true;
|
{
|
||||||
|
/*
|
||||||
return ( thread == QThread::currentThread() );
|
QskInputPanelSkinlet changes the skin state, what leads to
|
||||||
|
sending events from the wrong thread. We can't use
|
||||||
|
QCoreApplication::sendEvent then, TODO ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
auto event = new QskAnimatorEvent( aspect, index, state );
|
||||||
|
QCoreApplication::postEvent( receiver, event );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QskAnimatorEvent event( aspect, index, state );
|
||||||
|
QCoreApplication::sendEvent( receiver, &event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QskHintAnimator::QskHintAnimator() noexcept
|
QskHintAnimator::QskHintAnimator() noexcept
|
||||||
|
@ -338,11 +346,7 @@ void QskHintAnimatorTable::start( QskControl* control,
|
||||||
|
|
||||||
animator->start();
|
animator->start();
|
||||||
|
|
||||||
if ( qskCheckReceiverThread( control ) )
|
qskSendAnimatorEvent( aspect, index, true, control );
|
||||||
{
|
|
||||||
QskAnimatorEvent event( aspect, index, QskAnimatorEvent::Started );
|
|
||||||
QCoreApplication::sendEvent( control, &event );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QskHintAnimator* QskHintAnimatorTable::animator( QskAspect aspect, int index ) const
|
const QskHintAnimator* QskHintAnimatorTable::animator( QskAspect aspect, int index ) const
|
||||||
|
@ -390,15 +394,7 @@ bool QskHintAnimatorTable::cleanup()
|
||||||
it = animators.erase( it );
|
it = animators.erase( it );
|
||||||
|
|
||||||
if ( control )
|
if ( control )
|
||||||
{
|
qskSendAnimatorEvent( aspect, index, false, control );
|
||||||
if ( qskCheckReceiverThread( control ) )
|
|
||||||
{
|
|
||||||
auto event = new QskAnimatorEvent(
|
|
||||||
aspect, index, QskAnimatorEvent::Terminated );
|
|
||||||
|
|
||||||
QCoreApplication::postEvent( control, event );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "QskSlideIn.h"
|
#include "QskSlideIn.h"
|
||||||
#include "QskAnimationHint.h"
|
#include "QskQuick.h"
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquickitem_p.h>
|
#include <private/qquickitem_p.h>
|
||||||
#include <private/qquickitemchangelistener_p.h>
|
#include <private/qquickitemchangelistener_p.h>
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
static QPointF qskSlideInTranslation( const QskSlideIn* slideIn )
|
static QPointF qskSlideInTranslation( const QskSlideIn* slideIn, const QSizeF& size )
|
||||||
{
|
{
|
||||||
const auto ratio = 1.0 - slideIn->transitioningFactor();
|
const auto ratio = 1.0 - slideIn->transitioningFactor();
|
||||||
|
|
||||||
|
@ -21,59 +21,44 @@ static QPointF qskSlideInTranslation( const QskSlideIn* slideIn )
|
||||||
switch( slideIn->edge() )
|
switch( slideIn->edge() )
|
||||||
{
|
{
|
||||||
case Qt::LeftEdge:
|
case Qt::LeftEdge:
|
||||||
dx = -ratio * slideIn->width();
|
dx = -ratio * size.width();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::RightEdge:
|
case Qt::RightEdge:
|
||||||
dx = ratio * slideIn->width();
|
dx = ratio * size.width();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::TopEdge:
|
case Qt::TopEdge:
|
||||||
dy = -ratio * slideIn->height();
|
dy = -ratio * size.height();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
case Qt::BottomEdge:
|
||||||
dy = ratio * slideIn->height();
|
dy = ratio * size.height();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QPointF( dx, dy );
|
return QPointF( dx, dy );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QRectF qskUnboundedClipRect( const QRectF& rect, Qt::Edge edge )
|
static inline QRectF qskAlignedToEdge(
|
||||||
|
const QRectF& r, const QSizeF& sz, Qt::Edge edge )
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
When sliding we want to clip against the edge, where the drawer
|
|
||||||
slides in/out. However the size of the slidein 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.
|
|
||||||
*/
|
|
||||||
constexpr qreal d = 1e6;
|
|
||||||
|
|
||||||
QRectF r( -d, -d, 2.0 * d, 2.0 * d );
|
|
||||||
|
|
||||||
switch( edge )
|
switch( edge )
|
||||||
{
|
{
|
||||||
case Qt::LeftEdge:
|
case Qt::LeftEdge:
|
||||||
r.setLeft( rect.left() );
|
return QRectF( r.left(), r.top(), sz.width(), r.height() );
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::RightEdge:
|
case Qt::RightEdge:
|
||||||
r.setRight( rect.right() );
|
return QRectF( r.right() - sz.width(), r.top(), sz.width(), r.height() );
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::TopEdge:
|
case Qt::TopEdge:
|
||||||
r.setTop( rect.top() );
|
return QRectF( r.left(), r.top(), r.width(), sz.height() );
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
case Qt::BottomEdge:
|
||||||
r.setBottom( rect.bottom() );
|
return QRectF( r.left(), r.bottom() - sz.height(), r.width(), sz.height() );
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return QRectF();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -106,8 +91,7 @@ namespace
|
||||||
private:
|
private:
|
||||||
void adjust()
|
void adjust()
|
||||||
{
|
{
|
||||||
QEvent event( QEvent::PolishRequest );
|
m_adjustedItem->polish();
|
||||||
QCoreApplication::sendEvent( m_adjustedItem, &event );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEnabled( bool on )
|
void setEnabled( bool on )
|
||||||
|
@ -159,7 +143,7 @@ QskSlideIn::QskSlideIn( QQuickItem* parentItem )
|
||||||
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
||||||
|
|
||||||
connect( this, &QskPopup::transitioningChanged,
|
connect( this, &QskPopup::transitioningChanged,
|
||||||
this, &QskSlideIn::setClip );
|
this, &QQuickItem::setClip );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskSlideIn::~QskSlideIn()
|
QskSlideIn::~QskSlideIn()
|
||||||
|
@ -197,17 +181,89 @@ void QskSlideIn::itemChange( QQuickItem::ItemChange change,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskSlideIn::clipRect() const
|
void QskSlideIn::updateResources()
|
||||||
{
|
{
|
||||||
if ( !isTransitioning() )
|
Inherited::updateResources();
|
||||||
return Inherited::clipRect();
|
|
||||||
|
/*
|
||||||
|
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() );
|
||||||
|
|
||||||
return qskUnboundedClipRect( rect(), edge() );
|
r.translate( qskSlideInTranslation( this, r.size() ) );
|
||||||
|
setGeometry( r );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskSlideIn::layoutRectForSize( const QSizeF& size ) const
|
QRectF QskSlideIn::clipRect() const
|
||||||
{
|
{
|
||||||
return QRectF( qskSlideInTranslation( this ), size );
|
if ( isTransitioning() && parentItem() )
|
||||||
|
{
|
||||||
|
// parent rectangle translated into the coordinate system of the slideIn
|
||||||
|
const QRectF rect( -position(), parentItem()->size() );
|
||||||
|
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
|
||||||
|
QRectF r( -d, -d, 2.0 * d, 2.0 * d );
|
||||||
|
|
||||||
|
switch( edge() )
|
||||||
|
{
|
||||||
|
case Qt::LeftEdge:
|
||||||
|
r.setLeft( rect.left() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::RightEdge:
|
||||||
|
r.setRight( rect.right() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::TopEdge:
|
||||||
|
r.setTop( rect.top() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::BottomEdge:
|
||||||
|
r.setBottom( rect.bottom() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::clipRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSlideIn::updateNode( QSGNode* node )
|
||||||
|
{
|
||||||
|
if ( isTransitioning() && clip() )
|
||||||
|
{
|
||||||
|
if ( auto clipNode = QQuickItemPrivate::get( this )->clipNode() )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The clipRect is changing while transitioning. 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_QskSlideIn.cpp"
|
#include "moc_QskSlideIn.cpp"
|
||||||
|
|
|
@ -25,12 +25,12 @@ class QSK_EXPORT QskSlideIn : public QskPopup
|
||||||
void setAdjustingToParentGeometry( bool on );
|
void setAdjustingToParentGeometry( bool on );
|
||||||
bool isAdjustingToParentGeometry() const;
|
bool isAdjustingToParentGeometry() const;
|
||||||
|
|
||||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QskSlideIn( QQuickItem* = nullptr );
|
QskSlideIn( QQuickItem* = nullptr );
|
||||||
|
|
||||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||||
|
void updateResources() override;
|
||||||
|
void updateNode( QSGNode* ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
|
|
Loading…
Reference in New Issue