questionable shadow class removed, using QQmlPrivate::RegisterType
again. Qt5 is using public APIs only - too many #ifdefs otherwise
This commit is contained in:
parent
5ecb85c725
commit
2b629123f9
@ -3,16 +3,25 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
############################################################################
|
||||
|
||||
set(HEADERS
|
||||
list(APPEND HEADERS
|
||||
QskQmlGlobal.h
|
||||
QskShortcutQml.h
|
||||
QskLayoutQml.h
|
||||
QskQml.h)
|
||||
QskQmlModule.h
|
||||
QskQmlRegister.h
|
||||
QskQml.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
list(APPEND SOURCES
|
||||
QskShortcutQml.cpp
|
||||
QskLayoutQml.cpp
|
||||
QskQml.cpp)
|
||||
QskQml.cpp
|
||||
)
|
||||
|
||||
if (QT_VERSION_MAJOR GREATER_EQUAL 6)
|
||||
list(APPEND HEADERS QskQmlClassInfo.h)
|
||||
list(APPEND SOURCES QskQmlClassInfo.cpp)
|
||||
endif()
|
||||
|
||||
set(target qskqmlexport)
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskQml.h"
|
||||
#include "QskQml.hpp"
|
||||
|
||||
#include "QskQmlRegister.h"
|
||||
#include "QskLayoutQml.h"
|
||||
#include "QskShortcutQml.h"
|
||||
|
||||
@ -44,8 +44,6 @@
|
||||
#include <QskSeparator.h>
|
||||
#include <QskShadowMetrics.h>
|
||||
#include <QskSimpleListBox.h>
|
||||
#include <QskSkin.h>
|
||||
#include <QskSkinManager.h>
|
||||
#include <QskSlider.h>
|
||||
#include <QskSpinBox.h>
|
||||
#include <QskStandardSymbol.h>
|
||||
@ -61,9 +59,9 @@
|
||||
#include <QskWindow.h>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 2, 0 )
|
||||
QSK_QT_PRIVATE_BEGIN
|
||||
QSK_QT_PRIVATE_BEGIN
|
||||
#include <private/qqmlmetatype_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
QSK_QT_PRIVATE_END
|
||||
#endif
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 )
|
||||
@ -191,9 +189,6 @@ namespace
|
||||
|
||||
void QskQml::registerTypes()
|
||||
{
|
||||
qmlRegisterUncreatableType< QskSkin >( QSK_MODULE_NAME, 1, 0, "Skin", QString() );
|
||||
qRegisterMetaType< QskSkin* >();
|
||||
|
||||
registerObject< QskShortcutQml >( "Shortcut" );
|
||||
|
||||
registerObject< QskWindow >();
|
||||
|
@ -1,288 +0,0 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_QML_HPP
|
||||
#define QSK_QML_HPP
|
||||
|
||||
#include <qqml.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define QSK_MODULE_NAME "Skinny"
|
||||
#define QSK_VERSION_MAJOR 1
|
||||
#define QSK_VERSION_MINOR 0
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 3, 0 )
|
||||
#define QSK_STRUCT_VERSION 0
|
||||
#elif QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 )
|
||||
#define QSK_STRUCT_VERSION 1
|
||||
#else
|
||||
#define QSK_STRUCT_VERSION 2
|
||||
#endif
|
||||
|
||||
// Required for QFlags to be constructed from an enum value
|
||||
#define QSK_REGISTER_FLAGS( Type ) \
|
||||
QMetaType::registerConverter< int, Type >( []( int value ) { return Type( value ); } )
|
||||
|
||||
namespace QskQml
|
||||
{
|
||||
inline const char* classNameQml( const QMetaObject& metaObject )
|
||||
{
|
||||
// without the "Qsk" prefix
|
||||
return metaObject.className() + 3;
|
||||
}
|
||||
|
||||
/*
|
||||
ClassInfo corresponds to the most reecent QQmlPrivate::RegisterType
|
||||
( structVersion: 2 introduced with Qt 6.5 )
|
||||
*/
|
||||
class ClassInfo
|
||||
{
|
||||
public:
|
||||
|
||||
template< typename T >
|
||||
void setTypeInfo()
|
||||
{
|
||||
using namespace QQmlPrivate;
|
||||
|
||||
constexpr bool isObject = std::is_base_of_v< QObject, T >;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
typeId = qMetaTypeId< T* >( );
|
||||
#else
|
||||
if ( isObject )
|
||||
typeId = QMetaType::fromType< T* >();
|
||||
else
|
||||
typeId = QMetaType::fromType< T >();
|
||||
|
||||
createValueType = ValueType< T, void >::create;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
For the moment we do not export lists - QMetaType::fromType< QList< T > >()
|
||||
creates so many symbols, that we would have to enable -mbig-obj for mingw
|
||||
TODO ...
|
||||
*/
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
const char* className = T::staticMetaObject.className(); \
|
||||
|
||||
const int nameLen = int(strlen(className) ); \
|
||||
const int listLen = int(strlen("QQmlListProperty<") ); \
|
||||
|
||||
QVarLengthArray< char, 64 > listName( listLen + nameLen + 2 );
|
||||
memcpy( listName.data(), "QQmlListProperty<", size_t( listLen ) );
|
||||
memcpy(listName.data() + listLen, className, size_t( nameLen ) );
|
||||
listName[listLen + nameLen] = '>';
|
||||
listName[listLen + nameLen + 1] = '\0';
|
||||
|
||||
listId = qRegisterNormalizedMetaType< QQmlListProperty< T > >( listName.constData() );
|
||||
#else
|
||||
if ( isObject );
|
||||
listId = QMetaType::fromType< QQmlListProperty< T > >( );
|
||||
else
|
||||
listId = QMetaType::fromType< QList< T > >( );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
parserStatusCast = StaticCastSelector< T,QQmlParserStatus >::cast();
|
||||
valueSourceCast = StaticCastSelector< T,QQmlPropertyValueSource >::cast();
|
||||
valueInterceptorCast = StaticCastSelector< T,QQmlPropertyValueInterceptor >::cast();
|
||||
#if QSK_STRUCT_VERSION >= 1
|
||||
finalizerCast = StaticCastSelector< T,QQmlFinalizerHook >::cast();
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
const int structVersion = QSK_STRUCT_VERSION;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QMetaType typeId;
|
||||
QMetaType listId;
|
||||
#else
|
||||
int typeId = 0;
|
||||
int listId = 0;
|
||||
#endif
|
||||
|
||||
int objectSize = 0;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
void ( *create )( void* ) = nullptr;
|
||||
#else
|
||||
void ( *create )( void*, void* ) = nullptr;
|
||||
void* const userdata = nullptr; // unused
|
||||
#endif
|
||||
|
||||
const QString noCreationReason; // unused
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
/*
|
||||
This one was introdued with Qt 6.x, but never worked
|
||||
as expected. With Qt 6.5 it has been replaced by adding
|
||||
the creationMethod that is triggering to look for
|
||||
invokable constructors.
|
||||
Let's check if it makes any sense to initialize it below
|
||||
at all. TODO ...
|
||||
*/
|
||||
QVariant ( *createValueType )( const QJSValue& ) = nullptr;
|
||||
#endif
|
||||
|
||||
const char* const uri = QSK_MODULE_NAME;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
const QTypeRevision version =
|
||||
QTypeRevision::fromVersion( QSK_VERSION_MAJOR, QSK_VERSION_MINOR );
|
||||
#else
|
||||
const int versionMajor = QSK_VERSION_MAJOR;
|
||||
const int versionMinor = QSK_VERSION_MINOR;
|
||||
#endif
|
||||
const char* elementName = nullptr;
|
||||
const QMetaObject* metaObject = nullptr;
|
||||
|
||||
/*
|
||||
We do not use attached properties as it always comes with
|
||||
creating extra QObjects.
|
||||
*/
|
||||
QObject* (* const attachedPropertiesFunction)( QObject* ) = nullptr;
|
||||
const QMetaObject* const attachedPropertiesMetaObject = nullptr;
|
||||
|
||||
int parserStatusCast = -1;
|
||||
int valueSourceCast = -1;
|
||||
int valueInterceptorCast = -1;
|
||||
|
||||
/*
|
||||
We do not use extensions as it always comes with
|
||||
creating extra QObjects.
|
||||
*/
|
||||
QObject* (* const extensionObjectCreate )( QObject* ) = nullptr;
|
||||
const QMetaObject* const extensionMetaObject = nullptr;
|
||||
|
||||
void* const customParser = nullptr; // QQmlCustomParser, unused
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
const QTypeRevision revision = QTypeRevision::zero();
|
||||
#else
|
||||
const int revision = 0;
|
||||
#endif
|
||||
int finalizerCast = -1;
|
||||
|
||||
const int creationMethod = 2; // ValueTypeCreationMethod::Structured
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
inline int registerType( const char* qmlName )
|
||||
{
|
||||
using namespace QQmlPrivate;
|
||||
|
||||
ClassInfo type;
|
||||
|
||||
type.setTypeInfo< T >();
|
||||
|
||||
type.objectSize = sizeof( T );
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
type.create = Constructors< T >::createInto;
|
||||
#else
|
||||
type.create = createInto< T >;
|
||||
#endif
|
||||
|
||||
type.elementName = qmlName;
|
||||
type.metaObject = &T::staticMetaObject;
|
||||
|
||||
return qmlregister( TypeRegistration, &type );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline int registerUncreatableType( const char* qmlName )
|
||||
{
|
||||
using namespace QQmlPrivate;
|
||||
|
||||
ClassInfo type;
|
||||
|
||||
type.setTypeInfo< T >();
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
type.objectSize = sizeof( T );
|
||||
type.create = Constructors< T >::createInto;
|
||||
#endif
|
||||
|
||||
type.elementName = qmlName;
|
||||
type.metaObject = &T::staticMetaObject;
|
||||
|
||||
return qmlregister( TypeRegistration, &type );
|
||||
}
|
||||
|
||||
inline int registerUncreatableMetaObject(
|
||||
const QMetaObject& staticMetaObject, const char* qmlName )
|
||||
{
|
||||
using namespace QQmlPrivate;
|
||||
|
||||
ClassInfo type;
|
||||
|
||||
type.elementName = qmlName;
|
||||
type.metaObject = &staticMetaObject;
|
||||
|
||||
return qmlregister( TypeRegistration, &type );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline void registerObject( const char* qmlName = nullptr )
|
||||
{
|
||||
// the class name without the "Qsk" prefix
|
||||
if ( qmlName == nullptr )
|
||||
qmlName = classNameQml( T::staticMetaObject );
|
||||
|
||||
( void ) registerType< T >( qmlName );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline void registerGadget()
|
||||
{
|
||||
auto className = classNameQml( T::staticMetaObject );
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
registerUncreatableType< T >( className );
|
||||
#else
|
||||
/*
|
||||
According to the QML naming rules uncreatables have to
|
||||
start with a lowercase letter ( since Qt6 ), while namespaces
|
||||
and creatable items usually start with a upper letter.
|
||||
This results in an odd naming scheme for the enums defined inside of gadgets.
|
||||
|
||||
To work around this we register the gadget twice - starting with
|
||||
upper or lower letter.
|
||||
|
||||
Maybe it would make sense to only pass stripped metaObjects, where all
|
||||
enums are removed from the first and everything else than the enums from
|
||||
the second. TODO ...
|
||||
*/
|
||||
|
||||
if ( T::staticMetaObject.enumeratorCount() > 0 )
|
||||
{
|
||||
registerUncreatableMetaObject( T::staticMetaObject, className );
|
||||
}
|
||||
|
||||
QByteArray name = className;
|
||||
name.data()[0] = std::tolower( name.data()[0] );
|
||||
registerUncreatableType< T >( name.constData() );
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int registerNamespace( const QMetaObject& metaObject )
|
||||
{
|
||||
return registerUncreatableMetaObject( metaObject, classNameQml( metaObject ) );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline int registerSingleton( QObject* singleton )
|
||||
{
|
||||
const auto name = classNameQml( T::staticMetaObject );
|
||||
|
||||
return qmlRegisterSingletonInstance( QSK_MODULE_NAME,
|
||||
QSK_VERSION_MAJOR, QSK_VERSION_MINOR, name, singleton );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
85
qmlexport/QskQmlClassInfo.cpp
Normal file
85
qmlexport/QskQmlClassInfo.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskQmlClassInfo.h"
|
||||
#include "QskQmlModule.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace QskQml;
|
||||
|
||||
ClassInfo::ClassInfo( const char* qmlName, const QMetaObject* metaObject )
|
||||
{
|
||||
m_info.structVersion = QSK_STRUCT_VERSION;
|
||||
|
||||
m_info.objectSize = 0;
|
||||
m_info.create = nullptr;
|
||||
m_info.userdata = nullptr; // unused
|
||||
|
||||
/*
|
||||
This one was introdued with Qt 6.x, but never worked
|
||||
as expected. With Qt 6.5 it has been replaced by adding
|
||||
the creationMethod that is triggering to look for
|
||||
invokable constructors.
|
||||
Let's check if it makes any sense to initialize it below
|
||||
at all. TODO ...
|
||||
*/
|
||||
m_info.createValueType = nullptr;
|
||||
|
||||
m_info.uri = QskQmlModule::name;
|
||||
m_info.version = QTypeRevision::fromVersion( QskQmlModule::name[0], QskQmlModule::name[1] );
|
||||
|
||||
m_info.elementName = qmlName;
|
||||
m_info.metaObject = metaObject;
|
||||
|
||||
/*
|
||||
We do not use attached properties as it always comes with
|
||||
creating extra QObjects.
|
||||
*/
|
||||
m_info.attachedPropertiesFunction = nullptr;
|
||||
m_info.attachedPropertiesMetaObject = nullptr;
|
||||
|
||||
m_info.parserStatusCast = m_info.valueSourceCast = m_info.valueInterceptorCast = -1;
|
||||
|
||||
/*
|
||||
We do not use extensions as it always comes with
|
||||
creating extra QObjects.
|
||||
*/
|
||||
m_info.extensionObjectCreate = nullptr;
|
||||
m_info.extensionMetaObject = nullptr;
|
||||
|
||||
m_info.customParser = nullptr; // QQmlCustomParser, unused
|
||||
|
||||
m_info.revision = QTypeRevision::zero();
|
||||
m_info.finalizerCast = -1;
|
||||
|
||||
m_info.creationMethod = QQmlPrivate::ValueTypeCreationMethod::Structured;
|
||||
}
|
||||
|
||||
QByteArray ClassInfo::normalizedListName(
|
||||
const char* containerName, const QMetaObject& metaObject )
|
||||
{
|
||||
static QByteArray name;
|
||||
name.reserve( 256 );
|
||||
|
||||
const int length1 = strlen( containerName );
|
||||
const int length2 = strlen( metaObject.className() );
|
||||
|
||||
name.resize( length1 + length2 + 3 );
|
||||
|
||||
auto p = name.data();
|
||||
|
||||
memcpy( p, containerName, size_t( length1 ) );
|
||||
p += length1;
|
||||
|
||||
*p++ = '<';
|
||||
|
||||
memcpy( p, metaObject.className(), size_t( length2 ) );
|
||||
p += length2;
|
||||
|
||||
*p++ = '>';
|
||||
*p++ = '\0';
|
||||
|
||||
return name;
|
||||
}
|
84
qmlexport/QskQmlClassInfo.h
Normal file
84
qmlexport/QskQmlClassInfo.h
Normal file
@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_QML_CLASSINFO_H
|
||||
#define QSK_QML_CLASSINFO_H
|
||||
|
||||
#include <qqml.h>
|
||||
|
||||
class QByteArray;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 3, 0 )
|
||||
#define QSK_STRUCT_VERSION 0
|
||||
#elif QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 )
|
||||
#define QSK_STRUCT_VERSION 1
|
||||
#else
|
||||
#define QSK_STRUCT_VERSION 2
|
||||
#endif
|
||||
|
||||
namespace QskQml
|
||||
{
|
||||
class ClassInfo
|
||||
{
|
||||
public:
|
||||
ClassInfo( const char* qmlName, const QMetaObject* );
|
||||
template< typename T > void setTypeInfo();
|
||||
|
||||
int registerType();
|
||||
|
||||
private:
|
||||
static QByteArray normalizedListName(
|
||||
const char* containerName, const QMetaObject& );
|
||||
|
||||
QQmlPrivate::RegisterType m_info;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
inline void ClassInfo::setTypeInfo()
|
||||
{
|
||||
using namespace QQmlPrivate;
|
||||
|
||||
constexpr bool isObject = std::is_base_of_v< QObject, T >;
|
||||
|
||||
if ( isObject )
|
||||
m_info.typeId = QMetaType::fromType< T* >();
|
||||
else
|
||||
m_info.typeId = QMetaType::fromType< T >();
|
||||
|
||||
m_info.objectSize = sizeof( T );
|
||||
m_info.create = Constructors< T >::createInto;
|
||||
|
||||
m_info.createValueType = ValueType< T, void >::create;
|
||||
|
||||
const auto name = normalizedListName(
|
||||
isObject ? "QQmlListProperty" : "QList", T::staticMetaObject );
|
||||
|
||||
/*
|
||||
QMetaType::fromType< QList< T >() creates a lot of symbols
|
||||
that end up in QskQml.o for all gadgets. So we export only
|
||||
registered lists. Registration might be done in the qskinny library
|
||||
itself - or in QskQml.cpp.
|
||||
|
||||
As we do not design plain data being a QObject I'm not sure
|
||||
if we need to have QQmlListProperty< T > at all ...
|
||||
*/
|
||||
m_info.listId = QMetaType::fromName( name.constData() );
|
||||
|
||||
m_info.parserStatusCast = StaticCastSelector< T, QQmlParserStatus >::cast();
|
||||
m_info.valueSourceCast = StaticCastSelector< T, QQmlPropertyValueSource >::cast();
|
||||
m_info.valueInterceptorCast = StaticCastSelector< T, QQmlPropertyValueInterceptor >::cast();
|
||||
|
||||
#if QSK_STRUCT_VERSION >= 1
|
||||
m_info.finalizerCast = StaticCastSelector< T, QQmlFinalizerHook >::cast();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int ClassInfo::registerType()
|
||||
{
|
||||
return qmlregister( QQmlPrivate::TypeRegistration, &m_info );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
17
qmlexport/QskQmlModule.h
Normal file
17
qmlexport/QskQmlModule.h
Normal file
@ -0,0 +1,17 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_QML_MODULE_H
|
||||
#define QSK_QML_MODULE_H
|
||||
|
||||
namespace QskQmlModule
|
||||
{
|
||||
const char name[] = "Skinny";
|
||||
|
||||
// major, minor
|
||||
const int version[] = { 1, 0 };
|
||||
}
|
||||
|
||||
#endif
|
131
qmlexport/QskQmlRegister.h
Normal file
131
qmlexport/QskQmlRegister.h
Normal file
@ -0,0 +1,131 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) The authors
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_QML_REGISTER_H
|
||||
#define QSK_QML_REGISTER_H
|
||||
|
||||
#include "QskQmlModule.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
#include "QskQmlClassInfo.h"
|
||||
#endif
|
||||
|
||||
#include <qqml.h>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
#define QSK_QML_REGISTER 0
|
||||
#else
|
||||
#define QSK_QML_REGISTER 1
|
||||
#endif
|
||||
|
||||
// Required for QFlags to be constructed from an enum value
|
||||
#define QSK_REGISTER_FLAGS( Type ) \
|
||||
QMetaType::registerConverter< int, Type >( []( int value ) { return Type( value ); } )
|
||||
|
||||
namespace QskQml
|
||||
{
|
||||
inline const char* classNameQml( const QMetaObject& metaObject )
|
||||
{
|
||||
// without the "Qsk" prefix
|
||||
return metaObject.className() + 3;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline int registerUncreatableType( const char* qmlName )
|
||||
{
|
||||
#if QSK_QML_REGISTER
|
||||
ClassInfo typeInfo( qmlName, &T::staticMetaObject );
|
||||
typeInfo.setTypeInfo< T >();
|
||||
|
||||
return typeInfo.registerType();
|
||||
#else
|
||||
return qmlRegisterUncreatableType< T >( QskQmlModule::name,
|
||||
QskQmlModule::version[0], QskQmlModule::version[1], qmlName, QString() );
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int registerUncreatableMetaObject(
|
||||
const QMetaObject& staticMetaObject, const char* qmlName )
|
||||
{
|
||||
#if QSK_QML_REGISTER
|
||||
ClassInfo typeInfo( qmlName, &staticMetaObject );
|
||||
return typeInfo.registerType();
|
||||
#else
|
||||
return qmlRegisterUncreatableMetaObject( staticMetaObject,
|
||||
QskQmlModule::name, QskQmlModule::version[0], QskQmlModule::version[1],
|
||||
qmlName, QString() );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline int registerObject( const char* qmlName = nullptr )
|
||||
{
|
||||
// the class name without the "Qsk" prefix
|
||||
if ( qmlName == nullptr )
|
||||
qmlName = classNameQml( T::staticMetaObject );
|
||||
|
||||
#if QSK_QML_REGISTER
|
||||
ClassInfo typeInfo( qmlName, &T::staticMetaObject );
|
||||
typeInfo.setTypeInfo< T >();
|
||||
|
||||
return typeInfo.registerType();
|
||||
#else
|
||||
return qmlRegisterType< T >( QskQmlModule::name,
|
||||
QskQmlModule::version[0], QskQmlModule::version[1], qmlName );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline int registerGadget()
|
||||
{
|
||||
auto className = classNameQml( T::staticMetaObject );
|
||||
|
||||
#if QSK_QML_REGISTER
|
||||
/*
|
||||
According to the QML naming rules uncreatables have to
|
||||
start with a lowercase letter, while namespaces
|
||||
and creatable items usually start with a upper letter.
|
||||
This results in an odd naming scheme for the enums defined inside of gadgets.
|
||||
|
||||
To work around this we register the gadget twice - starting with
|
||||
upper or lower letter.
|
||||
|
||||
Maybe it would make sense to only pass stripped metaObjects, where all
|
||||
enums are removed from the first and everything else than the enums from
|
||||
the second. TODO ...
|
||||
*/
|
||||
|
||||
if ( T::staticMetaObject.enumeratorCount() > 0 )
|
||||
registerUncreatableMetaObject( T::staticMetaObject, className );
|
||||
|
||||
QByteArray name = className;
|
||||
name.data()[0] = std::tolower( name.data()[0] );
|
||||
|
||||
return registerUncreatableType< T >( name.constData() );
|
||||
#else
|
||||
return registerUncreatableType< T >( className );
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int registerNamespace( const QMetaObject& metaObject )
|
||||
{
|
||||
return registerUncreatableMetaObject( metaObject, classNameQml( metaObject ) );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline int registerSingleton( QObject* singleton )
|
||||
{
|
||||
const auto name = classNameQml( T::staticMetaObject );
|
||||
|
||||
return qmlRegisterSingletonInstance( QskQmlModule::name,
|
||||
QskQmlModule::version[0], QskQmlModule::version[1], name, singleton );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef QSK_QML_REGISTER
|
||||
#undef QSK_QML_REGISTER
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user