/****************************************************************************** * QSkinny - Copyright (C) The authors * SPDX-License-Identifier: BSD-3-Clause *****************************************************************************/ #include "QskQml.h" #include "QskQml.hpp" #include "QskLayoutQml.h" #include "QskShortcutQml.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION < QT_VERSION_CHECK( 6, 2, 0 ) QSK_QT_PRIVATE_BEGIN #include QSK_QT_PRIVATE_END #endif #if QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 ) #include #include namespace { /* Since Qt 6.5 we have QML_STRUCTURED_VALUE and do not need to write our own converter. However: we should also be able to implement a generic converter from the metatype information: TODO ... For the moment we have these converters: */ QskGradientStop toGradientStop( const QJSValue& value ) { return QskGradientStop( value.property( QStringLiteral( "position" ) ).toNumber(), value.property( QStringLiteral( "color" ) ).toVariant().value< QColor >() ); } QskLinearDirection toLinearDirection( const QJSValue& value ) { return QskLinearDirection( value.property( QStringLiteral( "x1" ) ).toNumber(), value.property( QStringLiteral( "y1" ) ).toNumber(), value.property( QStringLiteral( "x2" ) ).toNumber(), value.property( QStringLiteral( "y2" ) ).toNumber() ); } QskConicDirection toConicDirection( const QJSValue& value ) { return QskConicDirection( value.property( QStringLiteral( "x" ) ).toNumber(), value.property( QStringLiteral( "y" ) ).toNumber(), value.property( QStringLiteral( "startAngle" ) ).toNumber(), value.property( QStringLiteral( "spanAngle" ) ).toNumber() ); } QskRadialDirection toRadialDirection( const QJSValue& value ) { return QskRadialDirection( value.property( QStringLiteral( "x" ) ).toNumber(), value.property( QStringLiteral( "y" ) ).toNumber(), value.property( QStringLiteral( "radiusX" ) ).toNumber(), value.property( QStringLiteral( "radiusY" ) ).toNumber() ); } QskGradient toGradient( const QJSValue& value ) { QskGradient gradient; QJSValueIterator it( value ); while ( it.hasNext() ) { it.next(); auto v = it.value(); if ( v.isObject() ) { if ( v.isArray() ) { if ( it.name() == QStringLiteral( "stops" ) ) { QskGradientStops stops; const int n = v.property( QStringLiteral( "length" ) ).toInt(); for ( int i = 0; i < n; i++ ) stops += toGradientStop( v.property( i ) ); gradient.setStops( stops ); } } else { if ( it.name() == QStringLiteral( "linear" ) ) { gradient.setLinearDirection( toLinearDirection( v ) ); } else if ( it.name() == QStringLiteral( "conic" ) ) { gradient.setConicDirection( toConicDirection( v ) ); } else if ( it.name() == QStringLiteral( "radial" ) ) { gradient.setRadialDirection( toRadialDirection( v ) ); } } } else if ( v.isNumber() ) { if ( it.name() == QStringLiteral( "spreadMode" ) ) { const auto s = v.toNumber(); if ( s >= QskGradient::PadSpread && s <= QskGradient::RepeatSpread ) { gradient.setSpreadMode( static_cast< QskGradient::SpreadMode >( s ) ); } } } } return gradient; } void registerJSConverters() { QMetaType::registerConverter< QJSValue, QskGradient >( toGradient ); QMetaType::registerConverter< QJSValue, QskLinearDirection >( toLinearDirection ); QMetaType::registerConverter< QJSValue, QskConicDirection >( toConicDirection ); QMetaType::registerConverter< QJSValue, QskRadialDirection >( toRadialDirection ); QMetaType::registerConverter< QJSValue, QskGradientStop >( toGradientStop ); } } #endif void QskQml::registerTypes() { qmlRegisterUncreatableType< QskSkin >( QSK_MODULE_NAME, 1, 0, "Skin", QString() ); qRegisterMetaType< QskSkin* >(); registerObject< QskShortcutQml >( "Shortcut" ); registerObject< QskWindow >(); registerObject< QskDialogWindow >(); registerObject< QskMessageWindow >(); registerObject< QskSelectionWindow >(); registerObject< QskGridBoxQml >( "GridBox" ); registerObject< QskLinearBoxQml >( "LinearBox" ); registerObject< QskControl >(); registerObject< QskMainView >(); registerObject< QskComboBox >(); registerObject< QskGraphicLabel >(); registerObject< QskVirtualKeyboard >(); registerObject< QskRadioBox >(); registerObject< QskSpinBox >(); registerObject< QskTextLabel >(); registerObject< QskTabButton >(); registerObject< QskTabBar >(); registerObject< QskTabView >(); registerObject< QskDrawer >(); registerObject< QskFocusIndicator >(); registerObject< QskSeparator >(); registerObject< QskProgressBar >(); registerObject< QskProgressRing >(); registerObject< QskPushButton >(); registerObject< QskScrollView >(); registerObject< QskScrollArea >(); registerObject< QskSlider >(); registerObject< QskSimpleListBox >(); registerObject< QskDialogButton >(); registerObject< QskDialogButtonBox >(); registerObject< QskPopup >(); registerObject< QskStatusIndicator >(); registerObject< QskSubWindow >(); registerObject< QskSubWindowArea >(); registerObject< QskDialogSubWindow >(); registerSingleton< QskDialog >( QskDialog::instance() ); #if 0 qmlRegisterUncreatableType< QskSkin >( "Skinny.Skins", QSK_VERSION_MAJOR, QSK_VERSION_MINOR, "Skin", QString() ); #endif QSK_REGISTER_FLAGS( QskItem::UpdateFlag ); QSK_REGISTER_FLAGS( QskItem::UpdateFlags ); QSK_REGISTER_FLAGS( QskSizePolicy::Policy ); QSK_REGISTER_FLAGS( QskDialog::Actions ); registerGadget< QskBoxBorderMetrics >(); registerGadget< QskBoxShapeMetrics >(); registerGadget< QskGraduationMetrics >(); registerGadget< QskShadowMetrics >(); registerGadget< QskIntervalF >(); registerGadget< QskLayoutMetrics >(); registerGadget< QskMargins >(); registerGadget< QskIcon >(); registerGadget< QskLabelData >(); registerGadget< QskGradient >(); registerGadget< QskGradientStop >(); registerGadget< QskLinearDirection >(); registerGadget< QskConicDirection >(); registerGadget< QskRadialDirection >(); registerGadget< QskAspect >(); registerGadget< QskPlacementPolicy >(); registerGadget< QskSizePolicy >(); registerGadget< QskTextOptions >(); registerGadget< QskFontRole >(); registerNamespace( QskStandardSymbol::staticMetaObject ); #if QT_VERSION < QT_VERSION_CHECK( 6, 5, 0 ) registerJSConverters(); #endif #if QT_VERSION < QT_VERSION_CHECK( 6, 2, 0 ) /* Since Qt 6.5 invokable constructors are accessible from QML, something what was possibe until Qt 6.2 with string converters. For Qt [6.2,6.4] we do not have any solution. */ QQmlMetaType::registerCustomStringConverter( qMetaTypeId< QskMargins >(), []( const QString& s ) { return QVariant::fromValue( QskMargins( s.toDouble() ) ); } ); #endif }