using gestures to open the drawer
This commit is contained in:
parent
ef68c66b10
commit
bfff8c3fe1
|
@ -17,32 +17,6 @@
|
||||||
|
|
||||||
namespace
|
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
|
class Drawer : public QskDrawer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -50,7 +24,7 @@ namespace
|
||||||
: QskDrawer( parent )
|
: QskDrawer( parent )
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
setAnimationHint( Panel | QskAspect::Position, 2000 );
|
setAnimationHint( Panel | QskAspect::Position, 1000 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setEdge( edge );
|
setEdge( edge );
|
||||||
|
@ -101,51 +75,6 @@ namespace
|
||||||
const auto edge = static_cast< Qt::Edge >( 1 << i );
|
const auto edge = static_cast< Qt::Edge >( 1 << i );
|
||||||
m_drawers[i] = new Drawer( edge, this );
|
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:
|
private:
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
#include "QskAspect.h"
|
#include "QskAspect.h"
|
||||||
#include "QskAnimationHint.h"
|
#include "QskAnimationHint.h"
|
||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
|
#include "QskEvent.h"
|
||||||
|
|
||||||
|
#include "QskPanGestureRecognizer.h"
|
||||||
|
#include "QskGesture.h"
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquickitem_p.h>
|
#include <private/qquickitem_p.h>
|
||||||
|
@ -77,6 +81,49 @@ namespace
|
||||||
private:
|
private:
|
||||||
QskDrawer* m_drawer = nullptr;
|
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
|
class QskDrawer::PrivateData
|
||||||
|
@ -108,6 +155,11 @@ QskDrawer::QskDrawer( QQuickItem* parentItem )
|
||||||
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
||||||
if ( parentItem )
|
if ( parentItem )
|
||||||
m_data->listener = new GeometryListener( this );
|
m_data->listener = new GeometryListener( this );
|
||||||
|
|
||||||
|
(void) new GestureRecognizer( this );
|
||||||
|
#if 1
|
||||||
|
parentItem->setAcceptedMouseButtons( Qt::LeftButton );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QskDrawer::~QskDrawer()
|
QskDrawer::~QskDrawer()
|
||||||
|
@ -130,6 +182,20 @@ void QskDrawer::setEdge( Qt::Edge edge )
|
||||||
edgeChanged( 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
|
QRectF QskDrawer::layoutRectForSize( const QSizeF& size ) const
|
||||||
{
|
{
|
||||||
return Inherited::layoutRectForSize( size );
|
return Inherited::layoutRectForSize( size );
|
||||||
|
|
|
@ -36,6 +36,8 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
||||||
void aboutToShow() override;
|
void aboutToShow() override;
|
||||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||||
|
|
||||||
|
void gestureEvent( QskGestureEvent* ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startFading( bool );
|
void startFading( bool );
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,9 @@ class QskGestureRecognizer::PrivateData
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickItem* watchedItem = nullptr;
|
QQuickItem* watchedItem = nullptr;
|
||||||
|
#if 1
|
||||||
|
QQuickItem* targetItem = nullptr; // QPointer ???
|
||||||
|
#endif
|
||||||
|
|
||||||
QVector< QMouseEvent* > pendingEvents;
|
QVector< QMouseEvent* > pendingEvents;
|
||||||
|
|
||||||
|
@ -121,6 +124,16 @@ QQuickItem* QskGestureRecognizer::watchedItem() const
|
||||||
return m_data->watchedItem;
|
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 )
|
void QskGestureRecognizer::setAcceptedMouseButtons( Qt::MouseButtons buttons )
|
||||||
{
|
{
|
||||||
m_data->buttons = buttons;
|
m_data->buttons = buttons;
|
||||||
|
|
|
@ -43,11 +43,16 @@ class QSK_EXPORT QskGestureRecognizer : public QObject
|
||||||
QskGestureRecognizer( QObject* parent = nullptr );
|
QskGestureRecognizer( QObject* parent = nullptr );
|
||||||
~QskGestureRecognizer() override;
|
~QskGestureRecognizer() override;
|
||||||
|
|
||||||
bool eventFilter( QObject* object, QEvent* event) override;
|
bool eventFilter( QObject*, QEvent* ) override;
|
||||||
|
|
||||||
|
// the item where the gesture happens
|
||||||
void setWatchedItem( QQuickItem* );
|
void setWatchedItem( QQuickItem* );
|
||||||
QQuickItem* watchedItem() const;
|
QQuickItem* watchedItem() const;
|
||||||
|
|
||||||
|
// the item processing the gesture events
|
||||||
|
void setTargetItem( QQuickItem* );
|
||||||
|
QQuickItem* targetItem() const;
|
||||||
|
|
||||||
// Qt::NoButton means: all buttons accepted
|
// Qt::NoButton means: all buttons accepted
|
||||||
void setAcceptedMouseButtons( Qt::MouseButtons );
|
void setAcceptedMouseButtons( Qt::MouseButtons );
|
||||||
Qt::MouseButtons acceptedMouseButtons() const;
|
Qt::MouseButtons acceptedMouseButtons() const;
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
#include "QskEvent.h"
|
#include "QskEvent.h"
|
||||||
#include "QskGesture.h"
|
#include "QskGesture.h"
|
||||||
|
|
||||||
#include <qcoreapplication.h>
|
|
||||||
#include <qline.h>
|
#include <qline.h>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
#include <qquickitem.h>
|
#include <qquickitem.h>
|
||||||
|
#include <qguiapplication.h>
|
||||||
|
#include <qstylehints.h>
|
||||||
|
|
||||||
static inline bool qskIsInOrientation(
|
static inline bool qskIsInOrientation(
|
||||||
const QPointF& from, const QPointF& to, Qt::Orientations orientations )
|
const QPointF& from, const QPointF& to, Qt::Orientations orientations )
|
||||||
|
@ -60,9 +61,14 @@ static inline qreal qskAngle(
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskSendPanGestureEvent(
|
static void qskSendPanGestureEvent(
|
||||||
QQuickItem* item, QskGesture::State state, qreal velocity, qreal angle,
|
QskGestureRecognizer* recognizer, QskGesture::State state,
|
||||||
const QPointF& origin, const QPointF& lastPosition, const QPointF& position )
|
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 >();
|
auto gesture = std::make_shared< QskPanGesture >();
|
||||||
gesture->setState( state );
|
gesture->setState( state );
|
||||||
|
|
||||||
|
@ -146,7 +152,7 @@ class QskPanGestureRecognizer::PrivateData
|
||||||
public:
|
public:
|
||||||
Qt::Orientations orientations = Qt::Horizontal | Qt::Vertical;
|
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
|
quint64 timestampVelocity = 0.0; // timestamp of the last mouse event
|
||||||
qreal angle = 0.0;
|
qreal angle = 0.0;
|
||||||
|
@ -243,12 +249,12 @@ void QskPanGestureRecognizer::processMove( const QPointF& pos, quint64 timestamp
|
||||||
|
|
||||||
if ( started )
|
if ( started )
|
||||||
{
|
{
|
||||||
qskSendPanGestureEvent( watchedItem(), QskGesture::Started,
|
qskSendPanGestureEvent( this, QskGesture::Started,
|
||||||
velocity, m_data->angle, m_data->origin, m_data->origin, m_data->pos );
|
velocity, m_data->angle, m_data->origin, m_data->origin, m_data->pos );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qskSendPanGestureEvent( watchedItem(), QskGesture::Updated,
|
qskSendPanGestureEvent( this, QskGesture::Updated,
|
||||||
velocity, m_data->angle, m_data->origin, oldPos, m_data->pos );
|
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 ulong elapsedTotal = timestamp - timestampStarted();
|
||||||
const qreal velocity = m_data->velocityTracker.velocity( elapsedTotal );
|
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 );
|
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 );
|
void setOrientations( Qt::Orientations );
|
||||||
Qt::Orientations orientations() const;
|
Qt::Orientations orientations() const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void processPress( const QPointF&, quint64 timestamp, bool isFinal ) override;
|
void processPress( const QPointF&, quint64 timestamp, bool isFinal ) override;
|
||||||
void processMove( const QPointF&, quint64 timestamp ) override;
|
void processMove( const QPointF&, quint64 timestamp ) override;
|
||||||
void processRelease( const QPointF&, quint64 timestamp ) override;
|
void processRelease( const QPointF&, quint64 timestamp ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -121,7 +121,7 @@ namespace
|
||||||
scheme = Qt::ColorScheme::Unknown;
|
scheme = Qt::ColorScheme::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto systemScheme = qGuiApp->styleHints()->colorScheme();
|
const auto systemScheme = QGuiApplication::styleHints()->colorScheme();
|
||||||
|
|
||||||
if( scheme == systemScheme )
|
if( scheme == systemScheme )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue