11#include "QskPanGestureRecognizer.h"
12#include "QskGesture.h"
14#include <qguiapplication.h>
15#include <qstylehints.h>
18#include <private/qquickitem_p.h>
23static inline qreal qskDefaultDragMargin()
26 return QGuiApplication::styleHints()->startDragDistance();
29static inline void qskCatchMouseEvents( QQuickItem* item )
33 item->setAcceptedMouseButtons( Qt::LeftButton );
34 item->setFiltersChildMouseEvents(
true );
38static bool qskCheckDirection( Qt::Edge edge,
const QskPanGesture* gesture )
40 const auto degrees = gesture->angle();
45 return ( degrees < 90.0 ) || ( degrees ) > 270.0;
48 return ( degrees > 90.0 ) && ( degrees < 270.0 );
51 return degrees > 180.0;
54 return degrees < 180.0;
60static inline QRectF qskAlignedToEdge(
61 const QRectF& r,
const QSizeF& sz, Qt::Edge edge )
66 return QRectF( r.left(), r.top(), sz.width(), r.height() );
69 return QRectF( r.right() - sz.width(), r.top(), sz.width(), r.height() );
72 return QRectF( r.left(), r.top(), r.width(), sz.height() );
75 return QRectF( r.left(), r.bottom() - sz.height(), r.width(), sz.height() );
81static QPointF qskDrawerTranslation(
const QskDrawer* drawer,
const QSizeF& size )
83 const auto ratio = 1.0 - drawer->fadingFactor();
88 switch( drawer->edge() )
91 dx = -ratio * size.width();
95 dx = ratio * size.width();
99 dy = -ratio * size.height();
103 dy = ratio * size.height();
107 return QPointF( dx, dy );
120 setWatchedItem( drawer->parentItem() );
121 setTargetItem( drawer );
125 bool isAcceptedPos(
const QPointF& pos )
const override
127 auto drawer = qobject_cast< const QskDrawer* >( targetItem() );
128 if ( drawer->isFading() )
131 auto rect = qskItemRect( watchedItem() );
133 if ( !drawer->isOpen() )
135 const auto dragMargin = drawer->dragMargin();
136 if ( dragMargin <= 0.0 )
139 switch( drawer->edge() )
142 rect.setRight( rect.left() + dragMargin );
146 rect.setLeft( rect.right() - dragMargin );
150 rect.setBottom( rect.top() + dragMargin );
154 rect.setTop( rect.bottom() - dragMargin );
159 return rect.contains( pos );
164class QskDrawer::PrivateData
167 PrivateData( Qt::Edge edge )
172 GestureRecognizer* gestureRecognizer =
nullptr;
174 qreal dragMargin = qskDefaultDragMargin();
178QskDrawer::QskDrawer( QQuickItem* parentItem )
181 setPolishOnParentResize(
true );
184QskDrawer::QskDrawer( Qt::Edge edge, QQuickItem* parentItem )
185 : Inherited ( parentItem )
186 , m_data( new PrivateData( edge ) )
192 setPopupFlag( PopupFlag::CloseOnPressOutside,
true );
201 setAutoLayoutChildren(
true );
202 setInteractive(
true );
204 connect(
this, &QskPopup::fadingChanged,
this, &QQuickItem::setClip );
207QskDrawer::~QskDrawer()
211Qt::Edge QskDrawer::edge()
const
216void QskDrawer::setEdge( Qt::Edge edge )
218 if( m_data->edge == edge )
226void QskDrawer::setInteractive(
bool on )
228 if ( on == isInteractive() )
233 m_data->gestureRecognizer =
new GestureRecognizer(
this );
235 qskCatchMouseEvents( parentItem() );
240 delete m_data->gestureRecognizer;
241 m_data->gestureRecognizer =
nullptr;
244 Q_EMIT interactiveChanged( on );
247bool QskDrawer::isInteractive()
const
249 return m_data->gestureRecognizer !=
nullptr;
252void QskDrawer::setDragMargin( qreal margin )
254 margin = std::max( margin, 0.0 );
256 if ( margin != m_data->dragMargin )
258 m_data->dragMargin = margin;
259 Q_EMIT dragMarginChanged( margin );
263void QskDrawer::resetDragMargin()
265 setDragMargin( qskDefaultDragMargin() );
268qreal QskDrawer::dragMargin()
const
270 return m_data->dragMargin;
275 if ( event->gesture()->type() == QskGesture::Pan )
281 const auto gesture =
static_cast< const QskPanGesture*
>(
event->gesture().get() );
282 if ( gesture->state() == QskGesture::Finished )
284 const auto forwards = qskCheckDirection( m_data->edge, gesture );
285 if ( forwards != isOpen() )
292 Inherited::gestureEvent( event );
295void QskDrawer::itemChange( QQuickItem::ItemChange change,
296 const QQuickItem::ItemChangeData& value )
298 Inherited::itemChange( change, value );
300 switch(
static_cast< int >( change ) )
302 case QQuickItem::ItemParentHasChanged:
304 if ( parentItem() && isInteractive() )
305 qskCatchMouseEvents( parentItem() );
312void QskDrawer::updateResources()
314 Inherited::updateResources();
321 if (
const auto item = parentItem() )
323 auto r = qskItemRect( item );
324 r = qskAlignedToEdge( r,
sizeConstraint( Qt::PreferredSize ), edge() );
326 r.translate( qskDrawerTranslation(
this, r.size() ) );
333 if ( isFading() && clip() )
335 if (
auto clipNode = QQuickItemPrivate::get(
this )->clipNode() )
342 const auto r = clipRect();
343 if ( r != clipNode->rect() )
345 clipNode->setRect( r );
354QRectF QskDrawer::clipRect()
const
356 if ( isFading() && parentItem() )
365 constexpr qreal d = 1e6;
367 QRectF r( -d, -d, 2.0 * d, 2.0 * d );
376 r.setRight( parentItem()->width() - x() );
384 r.setBottom( parentItem()->height() - y() );
391 return Inherited::clipRect();
404#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 *)