using gestures to open the drawer
This commit is contained in:
parent
ef68c66b10
commit
bfff8c3fe1
|
@ -17,32 +17,6 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
inline qreal distanceToEdge(
|
||||
const QRectF& rect, const QPointF& pos, int edge )
|
||||
{
|
||||
qreal dt = 10e6;
|
||||
switch( edge )
|
||||
{
|
||||
case Qt::TopEdge:
|
||||
dt = pos.y() - rect.top();
|
||||
break;
|
||||
|
||||
case Qt::BottomEdge:
|
||||
dt = rect.bottom() - pos.y();
|
||||
break;
|
||||
|
||||
case Qt::LeftEdge:
|
||||
dt = pos.x() - rect.left();
|
||||
break;
|
||||
|
||||
case Qt::RightEdge:
|
||||
dt = rect.right() - pos.x();
|
||||
break;
|
||||
}
|
||||
|
||||
return std::abs( dt );
|
||||
}
|
||||
|
||||
class Drawer : public QskDrawer
|
||||
{
|
||||
public:
|
||||
|
@ -50,7 +24,7 @@ namespace
|
|||
: QskDrawer( parent )
|
||||
{
|
||||
#if 1
|
||||
setAnimationHint( Panel | QskAspect::Position, 2000 );
|
||||
setAnimationHint( Panel | QskAspect::Position, 1000 );
|
||||
#endif
|
||||
|
||||
setEdge( edge );
|
||||
|
@ -101,51 +75,6 @@ namespace
|
|||
const auto edge = static_cast< Qt::Edge >( 1 << i );
|
||||
m_drawers[i] = new Drawer( edge, this );
|
||||
}
|
||||
|
||||
setAcceptedMouseButtons( Qt::LeftButton );
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool contains( const QPointF& pos ) const
|
||||
{
|
||||
if ( auto control = qskControlCast( parentItem() ) )
|
||||
{
|
||||
// we want to catch clicks on the margins of the parent
|
||||
|
||||
auto r = rect();
|
||||
if ( !r.contains( pos ) )
|
||||
{
|
||||
r = r.marginsAdded( control->margins() );
|
||||
return r.contains( pos );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return QskControl::contains( pos );
|
||||
}
|
||||
|
||||
void mousePressEvent( QMouseEvent* event ) override
|
||||
{
|
||||
const auto pos = qskMousePosition( event );
|
||||
|
||||
int drawerIndex = -1;
|
||||
qreal minDist = 10e6;
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
const auto edge = static_cast< Qt::Edge >( 1 << i );
|
||||
const auto dist = distanceToEdge( rect(), pos, edge );
|
||||
|
||||
if ( dist < minDist )
|
||||
{
|
||||
minDist = dist;
|
||||
drawerIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( drawerIndex >= 0 )
|
||||
m_drawers[drawerIndex]->open();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#include "QskAspect.h"
|
||||
#include "QskAnimationHint.h"
|
||||
#include "QskQuick.h"
|
||||
#include "QskEvent.h"
|
||||
|
||||
#include "QskPanGestureRecognizer.h"
|
||||
#include "QskGesture.h"
|
||||
|
||||
QSK_QT_PRIVATE_BEGIN
|
||||
#include <private/qquickitem_p.h>
|
||||
|
@ -77,6 +81,49 @@ namespace
|
|||
private:
|
||||
QskDrawer* m_drawer = nullptr;
|
||||
};
|
||||
|
||||
class GestureRecognizer : public QskPanGestureRecognizer
|
||||
{
|
||||
using Inherited = QskPanGestureRecognizer;
|
||||
|
||||
public:
|
||||
GestureRecognizer( QskDrawer* drawer )
|
||||
: QskPanGestureRecognizer( drawer )
|
||||
{
|
||||
setWatchedItem( drawer->parentItem() );
|
||||
setTargetItem( drawer );
|
||||
}
|
||||
|
||||
protected:
|
||||
QRectF gestureRect() const override
|
||||
{
|
||||
auto drawer = qobject_cast< QskDrawer* >( parent() );
|
||||
|
||||
const auto dist = 50;
|
||||
auto rect = qskItemRect( watchedItem() );
|
||||
|
||||
switch( drawer->edge() )
|
||||
{
|
||||
case Qt::LeftEdge:
|
||||
rect.setRight( rect.left() + dist );
|
||||
break;
|
||||
|
||||
case Qt::RightEdge:
|
||||
rect.setLeft( rect.right() - dist );
|
||||
break;
|
||||
|
||||
case Qt::TopEdge:
|
||||
rect.setBottom( rect.top() + dist );
|
||||
break;
|
||||
|
||||
case Qt::BottomEdge:
|
||||
rect.setTop( rect.bottom() - dist );
|
||||
break;
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class QskDrawer::PrivateData
|
||||
|
@ -108,6 +155,11 @@ QskDrawer::QskDrawer( QQuickItem* parentItem )
|
|||
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
||||
if ( parentItem )
|
||||
m_data->listener = new GeometryListener( this );
|
||||
|
||||
(void) new GestureRecognizer( this );
|
||||
#if 1
|
||||
parentItem->setAcceptedMouseButtons( Qt::LeftButton );
|
||||
#endif
|
||||
}
|
||||
|
||||
QskDrawer::~QskDrawer()
|
||||
|
@ -130,6 +182,20 @@ void QskDrawer::setEdge( Qt::Edge edge )
|
|||
edgeChanged( edge );
|
||||
}
|
||||
|
||||
void QskDrawer::gestureEvent( QskGestureEvent* event )
|
||||
{
|
||||
if ( event->gesture()->type() == QskGesture::Pan )
|
||||
{
|
||||
const auto gesture = static_cast< const QskPanGesture* >( event->gesture().get() );
|
||||
if ( gesture->state() == QskGesture::Finished )
|
||||
open();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Inherited::gestureEvent( event );
|
||||
}
|
||||
|
||||
QRectF QskDrawer::layoutRectForSize( const QSizeF& size ) const
|
||||
{
|
||||
return Inherited::layoutRectForSize( size );
|
||||
|
|
|
@ -36,6 +36,8 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
|||
void aboutToShow() override;
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
|
||||
void gestureEvent( QskGestureEvent* ) override;
|
||||
|
||||
private:
|
||||
void startFading( bool );
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ class QskGestureRecognizer::PrivateData
|
|||
}
|
||||
|
||||
QQuickItem* watchedItem = nullptr;
|
||||
#if 1
|
||||
QQuickItem* targetItem = nullptr; // QPointer ???
|
||||
#endif
|
||||
|
||||
QVector< QMouseEvent* > pendingEvents;
|
||||
|
||||
|
@ -121,6 +124,16 @@ QQuickItem* QskGestureRecognizer::watchedItem() const
|
|||
return m_data->watchedItem;
|
||||
}
|
||||
|
||||
void QskGestureRecognizer::setTargetItem( QQuickItem* item )
|
||||
{
|
||||
m_data->targetItem = item;
|
||||
}
|
||||
|
||||
QQuickItem* QskGestureRecognizer::targetItem() const
|
||||
{
|
||||
return m_data->targetItem;
|
||||
}
|
||||
|
||||
void QskGestureRecognizer::setAcceptedMouseButtons( Qt::MouseButtons buttons )
|
||||
{
|
||||
m_data->buttons = buttons;
|
||||
|
|
|
@ -43,11 +43,16 @@ class QSK_EXPORT QskGestureRecognizer : public QObject
|
|||
QskGestureRecognizer( QObject* parent = nullptr );
|
||||
~QskGestureRecognizer() override;
|
||||
|
||||
bool eventFilter( QObject* object, QEvent* event) override;
|
||||
bool eventFilter( QObject*, QEvent* ) override;
|
||||
|
||||
// the item where the gesture happens
|
||||
void setWatchedItem( QQuickItem* );
|
||||
QQuickItem* watchedItem() const;
|
||||
|
||||
// the item processing the gesture events
|
||||
void setTargetItem( QQuickItem* );
|
||||
QQuickItem* targetItem() const;
|
||||
|
||||
// Qt::NoButton means: all buttons accepted
|
||||
void setAcceptedMouseButtons( Qt::MouseButtons );
|
||||
Qt::MouseButtons acceptedMouseButtons() const;
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#include "QskEvent.h"
|
||||
#include "QskGesture.h"
|
||||
|
||||
#include <qcoreapplication.h>
|
||||
#include <qline.h>
|
||||
#include <qmath.h>
|
||||
#include <qquickitem.h>
|
||||
#include <qguiapplication.h>
|
||||
#include <qstylehints.h>
|
||||
|
||||
static inline bool qskIsInOrientation(
|
||||
const QPointF& from, const QPointF& to, Qt::Orientations orientations )
|
||||
|
@ -60,9 +61,14 @@ static inline qreal qskAngle(
|
|||
}
|
||||
|
||||
static void qskSendPanGestureEvent(
|
||||
QQuickItem* item, QskGesture::State state, qreal velocity, qreal angle,
|
||||
const QPointF& origin, const QPointF& lastPosition, const QPointF& position )
|
||||
QskGestureRecognizer* recognizer, QskGesture::State state,
|
||||
qreal velocity, qreal angle, const QPointF& origin,
|
||||
const QPointF& lastPosition, const QPointF& position )
|
||||
{
|
||||
auto item = recognizer->targetItem();
|
||||
if ( item == nullptr )
|
||||
item = recognizer->watchedItem();
|
||||
|
||||
auto gesture = std::make_shared< QskPanGesture >();
|
||||
gesture->setState( state );
|
||||
|
||||
|
@ -146,7 +152,7 @@ class QskPanGestureRecognizer::PrivateData
|
|||
public:
|
||||
Qt::Orientations orientations = Qt::Horizontal | Qt::Vertical;
|
||||
|
||||
int minDistance = 15;
|
||||
int minDistance = QGuiApplication::styleHints()->startDragDistance() + 5;
|
||||
|
||||
quint64 timestampVelocity = 0.0; // timestamp of the last mouse event
|
||||
qreal angle = 0.0;
|
||||
|
@ -243,12 +249,12 @@ void QskPanGestureRecognizer::processMove( const QPointF& pos, quint64 timestamp
|
|||
|
||||
if ( started )
|
||||
{
|
||||
qskSendPanGestureEvent( watchedItem(), QskGesture::Started,
|
||||
qskSendPanGestureEvent( this, QskGesture::Started,
|
||||
velocity, m_data->angle, m_data->origin, m_data->origin, m_data->pos );
|
||||
}
|
||||
else
|
||||
{
|
||||
qskSendPanGestureEvent( watchedItem(), QskGesture::Updated,
|
||||
qskSendPanGestureEvent( this, QskGesture::Updated,
|
||||
velocity, m_data->angle, m_data->origin, oldPos, m_data->pos );
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +267,7 @@ void QskPanGestureRecognizer::processRelease( const QPointF&, quint64 timestamp
|
|||
const ulong elapsedTotal = timestamp - timestampStarted();
|
||||
const qreal velocity = m_data->velocityTracker.velocity( elapsedTotal );
|
||||
|
||||
qskSendPanGestureEvent( watchedItem(), QskGesture::Finished,
|
||||
qskSendPanGestureEvent( this, QskGesture::Finished,
|
||||
velocity, m_data->angle, m_data->origin, m_data->pos, m_data->pos );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,12 @@ class QSK_EXPORT QskPanGestureRecognizer : public QskGestureRecognizer
|
|||
void setOrientations( Qt::Orientations );
|
||||
Qt::Orientations orientations() const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
void processPress( const QPointF&, quint64 timestamp, bool isFinal ) override;
|
||||
void processMove( const QPointF&, quint64 timestamp ) override;
|
||||
void processRelease( const QPointF&, quint64 timestamp ) override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace
|
|||
scheme = Qt::ColorScheme::Unknown;
|
||||
}
|
||||
|
||||
const auto systemScheme = qGuiApp->styleHints()->colorScheme();
|
||||
const auto systemScheme = QGuiApplication::styleHints()->colorScheme();
|
||||
|
||||
if( scheme == systemScheme )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue