11#include "QskPanGestureRecognizer.h"
12#include "QskGesture.h"
13#include "QskInternalMacros.h"
15#include <qguiapplication.h>
16#include <qstylehints.h>
19#include <private/qquickitem_p.h>
24static inline qreal qskDefaultDragMargin()
27 return QGuiApplication::styleHints()->startDragDistance();
30static inline void qskCatchMouseEvents( QQuickItem* item )
34 item->setAcceptedMouseButtons( Qt::LeftButton );
35 item->setFiltersChildMouseEvents(
true );
39static bool qskCheckDirection( Qt::Edge edge,
const QskPanGesture* gesture )
41 const auto degrees = gesture->angle();
46 return ( degrees < 90.0 ) || ( degrees ) > 270.0;
49 return ( degrees > 90.0 ) && ( degrees < 270.0 );
52 return degrees > 180.0;
55 return degrees < 180.0;
61static inline QRectF qskAlignedToEdge(
62 const QRectF& r,
const QSizeF& sz, Qt::Edge edge )
67 return QRectF( r.left(), r.top(), sz.width(), r.height() );
70 return QRectF( r.right() - sz.width(), r.top(), sz.width(), r.height() );
73 return QRectF( r.left(), r.top(), r.width(), sz.height() );
76 return QRectF( r.left(), r.bottom() - sz.height(), r.width(), sz.height() );
82static QPointF qskDrawerTranslation(
const QskDrawer* drawer,
const QSizeF& size )
84 const auto ratio = 1.0 - drawer->fadingFactor();
89 switch( drawer->edge() )
92 dx = -ratio * size.width();
96 dx = ratio * size.width();
100 dy = -ratio * size.height();
104 dy = ratio * size.height();
108 return QPointF( dx, dy );
121 setWatchedItem( drawer->parentItem() );
122 setTargetItem( drawer );
126 bool isAcceptedPos(
const QPointF& pos )
const override
128 auto drawer = qobject_cast< const QskDrawer* >( targetItem() );
129 if ( drawer->isFading() )
132 auto rect = qskItemRect( watchedItem() );
134 if ( !drawer->isOpen() )
136 const auto dragMargin = drawer->dragMargin();
137 if ( dragMargin <= 0.0 )
140 switch( drawer->edge() )
143 rect.setRight( rect.left() + dragMargin );
147 rect.setLeft( rect.right() - dragMargin );
151 rect.setBottom( rect.top() + dragMargin );
155 rect.setTop( rect.bottom() - dragMargin );
160 return rect.contains( pos );
165class QskDrawer::PrivateData
168 PrivateData( Qt::Edge edge )
173 GestureRecognizer* gestureRecognizer =
nullptr;
175 qreal dragMargin = qskDefaultDragMargin();
179QskDrawer::QskDrawer( QQuickItem* parentItem )
182 setPolishOnParentResize(
true );
185QskDrawer::QskDrawer( Qt::Edge edge, QQuickItem* parentItem )
186 : Inherited ( parentItem )
187 , m_data( new PrivateData( edge ) )
193 setPopupFlag( PopupFlag::CloseOnPressOutside,
true );
202 setAutoLayoutChildren(
true );
203 setInteractive(
true );
205 connect(
this, &QskPopup::fadingChanged,
this, &QQuickItem::setClip );
208QskDrawer::~QskDrawer()
212Qt::Edge QskDrawer::edge()
const
217void QskDrawer::setEdge( Qt::Edge edge )
219 if( m_data->edge == edge )
227void QskDrawer::setInteractive(
bool on )
229 if ( on == isInteractive() )
234 m_data->gestureRecognizer =
new GestureRecognizer(
this );
236 qskCatchMouseEvents( parentItem() );
241 delete m_data->gestureRecognizer;
242 m_data->gestureRecognizer =
nullptr;
245 Q_EMIT interactiveChanged( on );
248bool QskDrawer::isInteractive()
const
250 return m_data->gestureRecognizer !=
nullptr;
253void QskDrawer::setDragMargin( qreal margin )
255 margin = std::max( margin, 0.0 );
257 if ( margin != m_data->dragMargin )
259 m_data->dragMargin = margin;
260 Q_EMIT dragMarginChanged( margin );
264void QskDrawer::resetDragMargin()
266 setDragMargin( qskDefaultDragMargin() );
269qreal QskDrawer::dragMargin()
const
271 return m_data->dragMargin;
276 if ( event->gesture()->type() == QskGesture::Pan )
282 const auto gesture =
static_cast< const QskPanGesture*
>(
event->gesture().get() );
283 if ( gesture->state() == QskGesture::Finished )
285 const auto forwards = qskCheckDirection( m_data->edge, gesture );
286 if ( forwards != isOpen() )
293 Inherited::gestureEvent( event );
296void QskDrawer::itemChange( QQuickItem::ItemChange change,
297 const QQuickItem::ItemChangeData& value )
299 Inherited::itemChange( change, value );
301 switch(
static_cast< int >( change ) )
303 case QQuickItem::ItemParentHasChanged:
305 if ( parentItem() && isInteractive() )
306 qskCatchMouseEvents( parentItem() );
313void QskDrawer::updateResources()
315 Inherited::updateResources();
322 if (
const auto item = parentItem() )
324 auto r = qskItemRect( item );
325 r = qskAlignedToEdge( r,
sizeConstraint( Qt::PreferredSize ), edge() );
327 r.translate( qskDrawerTranslation(
this, r.size() ) );
334 if ( isFading() && clip() )
336 if (
auto clipNode = QQuickItemPrivate::get(
this )->clipNode() )
343 const auto r = clipRect();
344 if ( r != clipNode->rect() )
346 clipNode->setRect( r );
355QRectF QskDrawer::clipRect()
const
357 if ( isFading() && parentItem() )
366 constexpr qreal d = 1e6;
368 QRectF r( -d, -d, 2.0 * d, 2.0 * d );
377 r.setRight( parentItem()->width() - x() );
385 r.setBottom( parentItem()->height() - y() );
392 return Inherited::clipRect();
405#include "moc_QskDrawer.cpp"
Lookup key for a QskSkinHintTable.
QRectF subControlContentsRect(QskAspect::Subcontrol) const
QRectF layoutRectForSize(const QSizeF &) const override
void updateNode(QSGNode *) override
void setGeometry(qreal x, qreal y, qreal width, qreal height)
virtual void updateNode(QSGNode *)