diff --git a/cmake/QskFindMacros.cmake b/cmake/QskFindMacros.cmake index 88adb67e..71a36778 100644 --- a/cmake/QskFindMacros.cmake +++ b/cmake/QskFindMacros.cmake @@ -68,6 +68,9 @@ macro(qsk_setup_Qt) find_package(Qt${QT_VERSION_MAJOR} QUIET OPTIONAL_COMPONENTS QuickShapesPrivate) + + find_package(Qt${QT_VERSION_MAJOR} QUIET + OPTIONAL_COMPONENTS QuickDialogs2Utils QuickDialogs2 ) endif() if( NOT Qt${QT_VERSION_MAJOR}WebEngineQuick_FOUND) @@ -77,6 +80,10 @@ macro(qsk_setup_Qt) if (NOT Qt${QT_VERSION_MAJOR}QuickShapesPrivate_FOUND) message(STATUS "No Qt/Quick Shapes support: skipping some unimportant examples") endif() + + if( NOT Qt${QT_VERSION_MAJOR}QuickDialogs2_FOUND) + message(STATUS "No Qt/Quick Dialogs2 support: skipping some unimportant examples") + endif() endif() endmacro() diff --git a/playground/CMakeLists.txt b/playground/CMakeLists.txt index 2bc146fa..30ddc7d1 100644 --- a/playground/CMakeLists.txt +++ b/playground/CMakeLists.txt @@ -32,3 +32,7 @@ endif() if(TARGET Qt::QuickWidgets) add_subdirectory(grids) endif() + +if(TARGET Qt::QuickDialogs2) + add_subdirectory(systemdialogs) +endif() diff --git a/playground/systemdialogs/CMakeLists.txt b/playground/systemdialogs/CMakeLists.txt new file mode 100644 index 00000000..1f19f20c --- /dev/null +++ b/playground/systemdialogs/CMakeLists.txt @@ -0,0 +1,14 @@ +############################################################################ +# QSkinny - Copyright (C) The authors +# SPDX-License-Identifier: BSD-3-Clause +############################################################################ + +set(SOURCES main.cpp) +set(target systemdialogs) + +qsk_add_example(${target} ${SOURCES}) + +target_link_libraries(${target} PRIVATE + Qt::QuickDialogs2UtilsPrivate + Qt::QuickDialogs2Private +) diff --git a/playground/systemdialogs/main.cpp b/playground/systemdialogs/main.cpp new file mode 100644 index 00000000..0a144e92 --- /dev/null +++ b/playground/systemdialogs/main.cpp @@ -0,0 +1,195 @@ +/****************************************************************************** + * QSkinny - Copyright (C) The authors + * SPDX-License-Identifier: BSD-3-Clause + *****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +static QQuickAbstractDialog* createQml( const char* className ) +{ + static QQmlEngine engine( nullptr ); + + QByteArray qmlCode = "import QtQuick.Dialogs\n"; + qmlCode += className; + qmlCode += " {}"; + + auto component = new QQmlComponent( &engine ); + component->setData( qmlCode.constData(), QUrl() ); + + if ( component->status() != QQmlComponent::Ready ) + { + qWarning() << component->errorString(); + delete component; + + return nullptr; + } + + auto dialog = qobject_cast< QQuickAbstractDialog* >( component->create() ); + QObject::connect( dialog, &QObject::destroyed, + component, &QObject::deleteLater ); + + return dialog; +} + +namespace +{ + class ButtonBox : public QskLinearBox + { + Q_OBJECT + + public: + enum DialogType + { + ColorDialog, + FileDialog, + FolderDialog, + FontDialog, + MessageDialog, + }; + Q_ENUM( DialogType ) + + ButtonBox( QQuickItem* parent = nullptr ) + : QskLinearBox( Qt::Vertical, parent ) + { + setDefaultAlignment( Qt::AlignCenter ); + + setMargins( 10 ); + setSpacing( 20 ); + + const auto metaEnum = QMetaEnum::fromType(); + + for ( int i = ColorDialog; i <= MessageDialog; i++ ) + { + auto button = new QskPushButton( metaEnum.key( i ), this ); + button->setPreferredWidth( 200 ); + button->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); + + connect( button, &QskPushButton::clicked, + this, [ this, i ]() { openDialog( i ); } ); + } + + setExtraSpacingAt( Qt::BottomEdge ); + } + + private: + void openDialog( int dialogType ) + { + /* + Qt/Quick Dialogs implements a thin wrapper to make + QPlatformTheme::createPlatformDialogHelper accessible from QML. + There is not much value for the QSkinny use case and we could + use QPlatformTheme in our QskDialog classes without the wrapper. + + However Qt/Quick Dialogs also offers a fallback implementation + that is used when a dialog type is not supported by the platform. + These classes are implemented in QML and we need QmlEngine/QmlComponent + to use them. Once we have our own fallback implementation we can + drop this QML dependency. + */ + delete m_dialog; + m_dialog = nullptr; + + if ( qGuiApp->testAttribute( Qt::AA_DontUseNativeDialogs ) ) + { + const auto metaEnum = QMetaEnum::fromType(); + m_dialog = createQml( metaEnum.key( dialogType ) ); + if ( m_dialog ) + m_dialog->setParentWindow( window() ); + } + else + { + switch( dialogType ) + { + case ColorDialog: + m_dialog = new QQuickColorDialog(); + break; + + case FileDialog: + m_dialog = new QQuickFileDialog(); + break; + + case FolderDialog: + m_dialog = new QQuickFolderDialog(); + break; + + case FontDialog: + m_dialog = new QQuickFontDialog(); + break; + + case MessageDialog: + m_dialog = new QQuickMessageDialog(); + break; + } + } + + if ( m_dialog ) + { + if ( auto messageDialog = qobject_cast< QQuickMessageDialog* >( m_dialog ) ) + messageDialog->setText( "The quick brown fox jumps over the lazy dog" ); + + //m_dialog->setModality( Qt::WindowModal ); + m_dialog->open(); + } + } + + QQuickAbstractDialog* m_dialog = nullptr; + }; + + class MainView : public QskMainView + { + public: + MainView( QQuickItem* parent = nullptr ) + : QskMainView( parent ) + { + auto header = new QskLinearBox(); + header->setExtraSpacingAt( Qt::LeftEdge ); + header->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed ); + + auto button = new QskCheckBox( "Try Native Dialogs", header ); + button->setChecked( true ); + + connect( button, &QskCheckBox::toggled, + []( bool on ) { qGuiApp->setAttribute( Qt::AA_DontUseNativeDialogs, !on ); } ); + + setHeader( header ); + setBody( new ButtonBox() ); + } + }; +} + +int main( int argc, char* argv[] ) +{ +#ifdef ITEM_STATISTICS + QskObjectCounter counter( true ); +#endif + + QGuiApplication app( argc, argv ); + + SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts ); + + QskWindow window; + window.addItem( new MainView() ); + window.resize( 800, 600 ); + window.show(); + + return app.exec(); +} + +#include "main.moc"