Qt5 type of connection for QskShortcut
This commit is contained in:
parent
6644be15bd
commit
81acf6b610
@ -36,10 +36,10 @@ int main( int argc, char** argv )
|
|||||||
cout << "CTRL-T to change the color scheme, when the \"Default\" skin is active." << endl;
|
cout << "CTRL-T to change the color scheme, when the \"Default\" skin is active." << endl;
|
||||||
|
|
||||||
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_T ),
|
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_T ),
|
||||||
&skinFactory, SLOT(toggleScheme()), false );
|
false, &skinFactory, SLOT(toggleScheme()) );
|
||||||
|
|
||||||
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_S ),
|
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_S ),
|
||||||
&skinFactory, SLOT(rotateSkin()), false );
|
false, &skinFactory, SLOT(rotateSkin()) );
|
||||||
|
|
||||||
// With CTRL-B you can rotate a couple of visual debug modes
|
// With CTRL-B you can rotate a couple of visual debug modes
|
||||||
SkinnyShortcut::enable( SkinnyShortcut::DebugBackground |
|
SkinnyShortcut::enable( SkinnyShortcut::DebugBackground |
|
||||||
|
@ -8,16 +8,18 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
#include <QtGui/private/qguiapplication_p.h>
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QGlobalStatic>
|
||||||
|
#include <QtGui/private/qguiapplication_p.h>
|
||||||
|
|
||||||
class QskShortcutHandler final : public QObject
|
class QskShortcutHandler final : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static QskShortcutHandler* instance();
|
int addShortcut( QQuickWindow*, const QKeySequence&,
|
||||||
|
const QObject* receiver, const QMetaMethod& );
|
||||||
|
|
||||||
int addShortcut( QQuickWindow*, const QKeySequence&,
|
int addShortcut( QQuickWindow*, const QKeySequence&,
|
||||||
QObject* receiver, const QMetaMethod&, Qt::ConnectionType type );
|
const QObject* receiver, QtPrivate::QSlotObjectBase* );
|
||||||
|
|
||||||
void setEnabled( int id, bool );
|
void setEnabled( int id, bool );
|
||||||
void setAutoRepeat( int id, bool repeat );
|
void setAutoRepeat( int id, bool repeat );
|
||||||
@ -26,34 +28,36 @@ protected:
|
|||||||
virtual bool event( QEvent* event ) override final;
|
virtual bool event( QEvent* event ) override final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QskShortcutHandler() = default;
|
void cleanUp( QObject* );
|
||||||
|
|
||||||
static bool contextMatcher( QObject*, Qt::ShortcutContext );
|
static bool contextMatcher( QObject*, Qt::ShortcutContext );
|
||||||
static QShortcutMap& map();
|
static QShortcutMap& map();
|
||||||
|
|
||||||
struct InvokeData
|
class InvokeData
|
||||||
{
|
{
|
||||||
QObject* receiver;
|
public:
|
||||||
|
~InvokeData()
|
||||||
|
{
|
||||||
|
if ( slotObj )
|
||||||
|
slotObj->destroyIfLastRef();
|
||||||
|
}
|
||||||
|
|
||||||
QMetaMethod method;
|
QMetaMethod method;
|
||||||
Qt::ConnectionType connectionType;
|
QtPrivate::QSlotObjectBase* slotObj;
|
||||||
|
const QObject* receiver;
|
||||||
};
|
};
|
||||||
|
|
||||||
QMap< int, InvokeData > m_invokeDataMap;
|
QMap< int, InvokeData > m_invokeDataMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
QskShortcutHandler* QskShortcutHandler::instance()
|
|
||||||
{
|
|
||||||
static QskShortcutHandler handler;
|
|
||||||
return &handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QShortcutMap& QskShortcutHandler::map()
|
inline QShortcutMap& QskShortcutHandler::map()
|
||||||
{
|
{
|
||||||
return QGuiApplicationPrivate::instance()->shortcutMap;
|
return QGuiApplicationPrivate::instance()->shortcutMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskShortcutHandler::addShortcut( QQuickWindow* window, const QKeySequence& key,
|
int QskShortcutHandler::addShortcut(
|
||||||
QObject* receiver, const QMetaMethod& method, Qt::ConnectionType connectionType )
|
QQuickWindow* window, const QKeySequence& key,
|
||||||
|
const QObject* receiver, const QMetaMethod& method )
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@ -65,11 +69,48 @@ int QskShortcutHandler::addShortcut( QQuickWindow* window, const QKeySequence& k
|
|||||||
InvokeData& data = m_invokeDataMap[ id ];
|
InvokeData& data = m_invokeDataMap[ id ];
|
||||||
data.receiver = receiver;
|
data.receiver = receiver;
|
||||||
data.method = method;
|
data.method = method;
|
||||||
data.connectionType = connectionType;
|
data.slotObj = nullptr;
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QskShortcutHandler::addShortcut(
|
||||||
|
QQuickWindow* window, const QKeySequence& key,
|
||||||
|
const QObject* receiver, QtPrivate::QSlotObjectBase* slotObj )
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
|
||||||
|
if ( window )
|
||||||
|
id = map().addShortcut( window, key, Qt::WindowShortcut, contextMatcher );
|
||||||
|
else
|
||||||
|
id = map().addShortcut( this, key, Qt::ApplicationShortcut, contextMatcher );
|
||||||
|
|
||||||
|
InvokeData& data = m_invokeDataMap[ id ];
|
||||||
|
data.receiver = receiver;
|
||||||
|
data.slotObj = slotObj;
|
||||||
|
|
||||||
|
if ( receiver )
|
||||||
|
connect( receiver, &QObject::destroyed, this, &QskShortcutHandler::cleanUp );
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskShortcutHandler::cleanUp( QObject* receiver )
|
||||||
|
{
|
||||||
|
map().removeShortcut( 0, receiver );
|
||||||
|
|
||||||
|
for ( auto it = m_invokeDataMap.begin(); it != m_invokeDataMap.end(); )
|
||||||
|
{
|
||||||
|
if ( it->receiver == receiver )
|
||||||
|
{
|
||||||
|
it = m_invokeDataMap.erase( it );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool QskShortcutHandler::contextMatcher( QObject* obj, Qt::ShortcutContext context )
|
bool QskShortcutHandler::contextMatcher( QObject* obj, Qt::ShortcutContext context )
|
||||||
{
|
{
|
||||||
switch ( context )
|
switch ( context )
|
||||||
@ -107,7 +148,17 @@ bool QskShortcutHandler::event( QEvent* event )
|
|||||||
if ( it != m_invokeDataMap.constEnd() )
|
if ( it != m_invokeDataMap.constEnd() )
|
||||||
{
|
{
|
||||||
const InvokeData& data = ( *it );
|
const InvokeData& data = ( *it );
|
||||||
data.method.invoke( data.receiver, data.connectionType );
|
auto receiver = const_cast< QObject* >( data.receiver );
|
||||||
|
|
||||||
|
if ( data.slotObj )
|
||||||
|
{
|
||||||
|
void* args[] = { 0 };
|
||||||
|
data.slotObj->call( receiver, args );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.method.invoke( receiver, Qt::AutoConnection );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -116,16 +167,16 @@ bool QskShortcutHandler::event( QEvent* event )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC( QskShortcutHandler, qskShortcutHandler )
|
||||||
|
|
||||||
int QskShortcut::addShortcut( const QKeySequence& key,
|
int QskShortcut::addShortcut( const QKeySequence& key,
|
||||||
QObject* receiver, const char* method,
|
bool autoRepeat, const QObject* receiver, const char* method )
|
||||||
bool autoRepeat, Qt::ConnectionType connectionType )
|
|
||||||
{
|
{
|
||||||
return addShortcut( nullptr, key, receiver, method, autoRepeat, connectionType );
|
return addShortcut( nullptr, key, autoRepeat, receiver, method );
|
||||||
}
|
}
|
||||||
|
|
||||||
int QskShortcut::addShortcut( QQuickWindow* window, const QKeySequence& key,
|
int QskShortcut::addShortcut( QQuickWindow* window, const QKeySequence& key,
|
||||||
QObject* receiver, const char* method,
|
bool autoRepeat, const QObject* receiver, const char* method )
|
||||||
bool autoRepeat, Qt::ConnectionType connectionType )
|
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
|
|
||||||
@ -139,17 +190,42 @@ int QskShortcut::addShortcut( QQuickWindow* window, const QKeySequence& key,
|
|||||||
|
|
||||||
if ( methodIndex >= 0 )
|
if ( methodIndex >= 0 )
|
||||||
{
|
{
|
||||||
id = QskShortcutHandler::instance()->addShortcut( window, key,
|
id = qskShortcutHandler->addShortcut(
|
||||||
receiver, metaObject->method( methodIndex ), connectionType );
|
window, key, receiver, metaObject->method( methodIndex ) );
|
||||||
|
|
||||||
if ( !autoRepeat )
|
if ( !autoRepeat )
|
||||||
QskShortcutHandler::instance()->setAutoRepeat( id, false );
|
qskShortcutHandler->setAutoRepeat( id, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QskShortcut::addShortcutImpl( const QKeySequence& key,
|
||||||
|
bool autoRepeat, const QObject* receiver, QtPrivate::QSlotObjectBase* slotObj )
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
if ( receiver )
|
||||||
|
{
|
||||||
|
// how to call the slot in the receiver context, TODO ...
|
||||||
|
Q_ASSERT( qskShortcutHandler->thread() == receiver->thread() );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QQuickWindow* window = nullptr;
|
||||||
|
int id = qskShortcutHandler->addShortcut( window, key, receiver, slotObj );
|
||||||
|
|
||||||
|
if ( !autoRepeat )
|
||||||
|
qskShortcutHandler->setAutoRepeat( id, false );
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
void QskShortcut::setAutoRepeat( int id, bool on )
|
void QskShortcut::setAutoRepeat( int id, bool on )
|
||||||
{
|
{
|
||||||
QskShortcutHandler::instance()->setAutoRepeat( id, on );
|
qskShortcutHandler->setAutoRepeat( id, on );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskShortcut::setEnabled( int id, bool on )
|
||||||
|
{
|
||||||
|
qskShortcutHandler->setEnabled( id, on );
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
#define QSK_SHORTCUT_H
|
#define QSK_SHORTCUT_H
|
||||||
|
|
||||||
#include "QskGlobal.h"
|
#include "QskGlobal.h"
|
||||||
#include <Qt>
|
|
||||||
|
#include <QArgument>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
class QQuickWindow;
|
class QQuickWindow;
|
||||||
class QKeySequence;
|
class QKeySequence;
|
||||||
@ -15,15 +17,61 @@ class QObject;
|
|||||||
|
|
||||||
namespace QskShortcut
|
namespace QskShortcut
|
||||||
{
|
{
|
||||||
QSK_EXPORT int addShortcut( const QKeySequence&,
|
|
||||||
QObject* receiver, const char* method, bool autoRepeat = true,
|
|
||||||
Qt::ConnectionType type = Qt::AutoConnection );
|
|
||||||
|
|
||||||
QSK_EXPORT int addShortcut( QQuickWindow*, const QKeySequence&,
|
|
||||||
QObject* receiver, const char* method, bool autoRepeat = true,
|
|
||||||
Qt::ConnectionType type = Qt::AutoConnection );
|
|
||||||
|
|
||||||
QSK_EXPORT void setAutoRepeat( int, bool on );
|
QSK_EXPORT void setAutoRepeat( int, bool on );
|
||||||
|
QSK_EXPORT void setEnabled( int, bool on );
|
||||||
|
|
||||||
|
QSK_EXPORT int addShortcut( const QKeySequence&, bool autoRepeat,
|
||||||
|
const QObject* receiver, const char* method );
|
||||||
|
|
||||||
|
QSK_EXPORT int addShortcut( QQuickWindow*, const QKeySequence&, bool autoRepeat,
|
||||||
|
const QObject* receiver, const char* method );
|
||||||
|
|
||||||
|
QSK_EXPORT int addShortcutImpl( const QKeySequence&, bool autoRepeat,
|
||||||
|
const QObject* receiver, QtPrivate::QSlotObjectBase* );
|
||||||
|
|
||||||
|
// shortcut calling a QObject method
|
||||||
|
template< typename Func1 >
|
||||||
|
inline int addShortcut( const QKeySequence& key, bool autoRepeat,
|
||||||
|
const typename QtPrivate::FunctionPointer< Func1 >::Object* receiver, Func1 slot )
|
||||||
|
{
|
||||||
|
typedef QtPrivate::FunctionPointer< Func1 > SlotType;
|
||||||
|
|
||||||
|
Q_STATIC_ASSERT_X( int( SlotType::ArgumentCount ) == 0,
|
||||||
|
"The slot must not have any arguments.");
|
||||||
|
|
||||||
|
auto slotObj = new QtPrivate::QSlotObject< Func1,
|
||||||
|
typename SlotType::Arguments, void >(slot);
|
||||||
|
|
||||||
|
return addShortcutImpl( key, autoRepeat, receiver, slotObj );
|
||||||
|
}
|
||||||
|
|
||||||
|
// shortcut calling a functor or function pointer
|
||||||
|
template< typename Func1 >
|
||||||
|
int addShortcut( const QKeySequence& key, bool autoRepeat,
|
||||||
|
const QObject* context, Func1 slot )
|
||||||
|
{
|
||||||
|
using namespace QtPrivate;
|
||||||
|
|
||||||
|
typedef FunctionPointer< Func1 > SlotType;
|
||||||
|
|
||||||
|
Q_STATIC_ASSERT_X( int( SlotType::ArgumentCount ) <= 0,
|
||||||
|
"The slot must not have any arguments.");
|
||||||
|
|
||||||
|
Q_STATIC_ASSERT_X( !SlotType::IsPointerToMemberFunction,
|
||||||
|
"The slot must be no member function." );
|
||||||
|
|
||||||
|
auto slotObj = new QFunctorSlotObject< Func1, 0,
|
||||||
|
typename List_Left< void, 0 >::Value, void >( std::move( slot ) );
|
||||||
|
|
||||||
|
return addShortcutImpl( key, autoRepeat, context, slotObj );
|
||||||
|
}
|
||||||
|
|
||||||
|
// shortcut calling a functor or function pointer
|
||||||
|
template< typename Func1 >
|
||||||
|
int addShortcut( const QKeySequence& key, bool autoRepeat, Func1 slot )
|
||||||
|
{
|
||||||
|
return addShortcut( key, autoRepeat, nullptr, slot );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,21 +32,21 @@ void SkinnyShortcut::enable( Types types )
|
|||||||
if ( types & RotateSkin )
|
if ( types & RotateSkin )
|
||||||
{
|
{
|
||||||
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_S ),
|
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_S ),
|
||||||
&s_shortcut, SLOT( rotateSkin() ) );
|
false, &s_shortcut, SLOT( rotateSkin() ) );
|
||||||
cout << "CTRL-S to change the skin." << endl;
|
cout << "CTRL-S to change the skin." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( types & DebugBackground )
|
if ( types & DebugBackground )
|
||||||
{
|
{
|
||||||
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_B ),
|
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_B ),
|
||||||
&s_shortcut, SLOT( showBackground() ) );
|
false, &s_shortcut, SLOT( showBackground() ) );
|
||||||
cout << "CTRL-B to enable visual debugging modes." << endl;
|
cout << "CTRL-B to enable visual debugging modes." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( types & DebugStatistics )
|
if ( types & DebugStatistics )
|
||||||
{
|
{
|
||||||
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_K ),
|
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_K ),
|
||||||
&s_shortcut, SLOT( debugStatistics() ) );
|
false, &s_shortcut, SLOT( debugStatistics() ) );
|
||||||
cout << "CTRL-K to dump statistics about the items/nodes being currently used." << endl;
|
cout << "CTRL-K to dump statistics about the items/nodes being currently used." << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ void SkinnyShortcut::enable( Types types )
|
|||||||
// when not being implemented by the platform !!
|
// when not being implemented by the platform !!
|
||||||
|
|
||||||
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_Q ),
|
QskShortcut::addShortcut( QKeySequence( Qt::CTRL + Qt::Key_Q ),
|
||||||
QGuiApplication::instance(), SLOT( quit() ) );
|
false, QGuiApplication::instance(), SLOT( quit() ) );
|
||||||
cout << "CTRL-Q to terminate the application." << endl;
|
cout << "CTRL-Q to terminate the application." << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user