diff options
Diffstat (limited to 'tests/manual/helloswift')
-rw-r--r-- | tests/manual/helloswift/CMakeLists.txt | 97 | ||||
-rw-r--r-- | tests/manual/helloswift/greeter.h | 43 | ||||
-rw-r--r-- | tests/manual/helloswift/hello.swift | 21 | ||||
-rw-r--r-- | tests/manual/helloswift/main.cpp | 34 | ||||
-rw-r--r-- | tests/manual/helloswift/main.qml | 33 | ||||
-rw-r--r-- | tests/manual/helloswift/module.modulemap | 3 |
6 files changed, 231 insertions, 0 deletions
diff --git a/tests/manual/helloswift/CMakeLists.txt b/tests/manual/helloswift/CMakeLists.txt new file mode 100644 index 0000000000..2549577172 --- /dev/null +++ b/tests/manual/helloswift/CMakeLists.txt @@ -0,0 +1,97 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.26) +project(helloswift LANGUAGES CXX Swift) + +# --------------- Qt ---------------- + +find_package(Qt6 REQUIRED COMPONENTS Core Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/quick/helloswift") + +qt_add_executable(helloswift WIN32 MACOSX_BUNDLE + main.cpp +) + +target_include_directories(helloswift PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} +) +target_link_libraries(helloswift PRIVATE + Qt6::Quick +) + +qt_add_qml_module(helloswift + URI helloswift + QML_FILES + "main.qml" +) + +install(TARGETS helloswift + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) + +# ------------- Swift --------------- + +# Verify that we have a new enough compiler +if("${CMAKE_Swift_COMPILER_VERSION}" VERSION_LESS 5.9) + message(FATAL_ERROR "Swift 5.9 required for C++ interoperability") +endif() + +set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0) +set(CMAKE_CXX_STANDARD 17) + +get_target_property(QT_CORE_INCLUDES Qt6::Core INTERFACE_INCLUDE_DIRECTORIES) + +# Swift library +set(SWIFT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/hello.swift") +add_library(hello-swift STATIC ${SWIFT_SOURCES}) +set_target_properties(hello-swift PROPERTIES Swift_MODULE_NAME "HelloSwift") +target_include_directories(hello-swift PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}" + "${QT_CORE_INCLUDES}" +) +target_compile_options(hello-swift PUBLIC + $<$<COMPILE_LANGUAGE:Swift>:-cxx-interoperability-mode=default> + $<$<COMPILE_LANGUAGE:Swift>:-Xcc -std=c++17>) + +# Swift to C++ bridging header +set(SWIFT_BRIDGING_HEADER "${CMAKE_CURRENT_BINARY_DIR}/hello-swift.h") +list(TRANSFORM QT_CORE_INCLUDES PREPEND "-I") +add_custom_command( + COMMAND + ${CMAKE_Swift_COMPILER} -frontend -typecheck + ${SWIFT_SOURCES} + -I ${CMAKE_CURRENT_SOURCE_DIR} + ${QT_CORE_INCLUDES} + -sdk ${CMAKE_OSX_SYSROOT} + -module-name HelloSwift + -cxx-interoperability-mode=default + -Xcc -std=c++17 + -emit-clang-header-path "${SWIFT_BRIDGING_HEADER}" + OUTPUT + "${SWIFT_BRIDGING_HEADER}" + DEPENDS + ${SWIFT_SOURCES} + ) + +add_custom_target(swift-bridging-header + DEPENDS + "${SWIFT_BRIDGING_HEADER}" +) + +add_dependencies(hello-swift swift-bridging-header) + +# Tie everything together + +target_link_libraries(helloswift PRIVATE + hello-swift +) diff --git a/tests/manual/helloswift/greeter.h b/tests/manual/helloswift/greeter.h new file mode 100644 index 0000000000..722380051c --- /dev/null +++ b/tests/manual/helloswift/greeter.h @@ -0,0 +1,43 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef GREETER_H +#define GREETER_H + +#include <QtCore/qobject.h> +#include <string> +#include <swift/bridging> + +namespace HelloSwift { +class SwiftGreeter; +class Test; +} + +template <typename SwiftType, typename QtType> +class SwiftWrapper +{ +public: + template <typename ...Args> + SwiftWrapper(Args && ...args) + : swiftImpl(new SwiftType( + SwiftType::init( + static_cast<QtType*>(this), + std::forward<Args>(args)...))) + { + } + +protected: + std::unique_ptr<SwiftType> swiftImpl; +}; + +class Greeter : public QObject, public SwiftWrapper<HelloSwift::SwiftGreeter, Greeter> +{ + Q_OBJECT +public: + Q_PRIVATE_PROPERTY(swiftImpl, std::string greeting READ getGreeting NOTIFY greetingChanged) + Q_PRIVATE_SLOT(swiftImpl, void updateGreeting()) + Q_SIGNAL void greetingChanged(); +} SWIFT_UNSAFE_REFERENCE; + + +#endif // GREETER_H diff --git a/tests/manual/helloswift/hello.swift b/tests/manual/helloswift/hello.swift new file mode 100644 index 0000000000..99043c328d --- /dev/null +++ b/tests/manual/helloswift/hello.swift @@ -0,0 +1,21 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import Greeter + +public class SwiftGreeter { + private let qtImpl: Greeter + + public init(greeter: Greeter ) { + self.qtImpl = greeter; + } + + public var greeting: String { + let greetings = ["Hello", "Howdy", "Hey", "Hola", "Heisan"] + return greetings[Int.random(in: 0..<greetings.count)] + } + + public func updateGreeting() { + qtImpl.greetingChanged(); + } +} diff --git a/tests/manual/helloswift/main.cpp b/tests/manual/helloswift/main.cpp new file mode 100644 index 0000000000..264c4cb136 --- /dev/null +++ b/tests/manual/helloswift/main.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QGuiApplication> +#include <QStringList> + +#include <qqmlengine.h> +#include <qqmlcontext.h> +#include <qqml.h> +#include <QtQuick/qquickitem.h> +#include <QtQuick/qquickview.h> + +#include "greeter.h" +#include "hello-swift.h" + +int main(int argc, char ** argv) +{ + QGuiApplication app(argc, argv); + + QMetaType::registerConverter<std::string, QString>(&QString::fromStdString); + + Greeter greeter; + + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.engine()->rootContext()->setContextProperty("greeter", &greeter); + + view.setSource(QUrl("qrc:/qt/qml/helloswift/main.qml")); + view.show(); + + return app.exec(); +} + +#include "moc_greeter.cpp" diff --git a/tests/manual/helloswift/main.qml b/tests/manual/helloswift/main.qml new file mode 100644 index 0000000000..3992cde4e4 --- /dev/null +++ b/tests/manual/helloswift/main.qml @@ -0,0 +1,33 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick + +Rectangle { + id: rectangle + width: 500; height: 500 + color: "lightgray" + + Text { + id: text; + anchors.centerIn: parent + anchors.verticalCenterOffset: -50 + font.pointSize: 40 + text: greeter.greeting + } + + Image { + anchors.top: text.bottom + anchors.topMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + anchors.horizontalCenterOffset: -8 + source: "https://www.swift.org/assets/images/swift.svg" + fillMode: Image.PreserveAspectFit + sourceSize.width: 150 + + MouseArea { + anchors.fill: parent + onClicked: greeter.updateGreeting(); + } + } +} diff --git a/tests/manual/helloswift/module.modulemap b/tests/manual/helloswift/module.modulemap new file mode 100644 index 0000000000..4cc079abea --- /dev/null +++ b/tests/manual/helloswift/module.modulemap @@ -0,0 +1,3 @@ +module Greeter { + header "greeter.h" +} |