From 4df4f78694383496bba09a71d71e210cd31b38c7 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Fri, 30 Jan 2026 21:15:18 +0400 Subject: [PATCH] Move files for QML architecture --- metadata.json | 14 ++- plugin/StorageUIPlugin.cpp | 44 --------- plugin/qml/StorageView.qml | 38 -------- plugin/src/StorageBackend.cpp | 97 ------------------- plugin/src/StorageBackend.h | 48 --------- plugin/storage_resources.qrc | 5 - qml/CMakeLists.txt | 42 -------- qml/Main.qml | 8 -- src/StorageBackend.cpp | 156 ++++++++++++++++++++++++++++++ src/StorageBackend.h | 54 +++++++++++ src/StorageUIPlugin.cpp | 115 ++++++++++++++++++++++ {plugin => src}/StorageUIPlugin.h | 4 +- src/main.cpp | 17 ---- src/qml/CMakeLists.txt | 147 ++++++++++++++++++++++++++++ src/qml/StorageView.qml | 63 ++++++++++++ {qml => src/qml}/main.cpp | 2 +- src/storage_resources.qrc | 5 + 17 files changed, 549 insertions(+), 310 deletions(-) delete mode 100644 plugin/StorageUIPlugin.cpp delete mode 100644 plugin/qml/StorageView.qml delete mode 100644 plugin/src/StorageBackend.cpp delete mode 100644 plugin/src/StorageBackend.h delete mode 100644 plugin/storage_resources.qrc delete mode 100644 qml/CMakeLists.txt delete mode 100644 qml/Main.qml create mode 100644 src/StorageBackend.cpp create mode 100644 src/StorageBackend.h create mode 100644 src/StorageUIPlugin.cpp rename {plugin => src}/StorageUIPlugin.h (82%) delete mode 100644 src/main.cpp create mode 100644 src/qml/CMakeLists.txt create mode 100644 src/qml/StorageView.qml rename {qml => src/qml}/main.cpp (89%) create mode 100644 src/storage_resources.qrc diff --git a/metadata.json b/metadata.json index b2d3521..d93a177 100644 --- a/metadata.json +++ b/metadata.json @@ -12,17 +12,15 @@ "build": { "type": "cmake", "files": [ - "src/storage_ui_plugin.cpp", - "src/storage_ui_plugin.h", - "src/storagewindow.cpp", - "src/storagewindow.h", - "src/storagewidget.cpp", - "src/storagewidget.h", - "src/storage_ui_resources.qrc" + "src/StorageUIPlugin.cpp", + "src/StorageUIPlugin.h", + "src/StorageBackend.cpp", + "src/StorageBackend.h", + "src/storage_resources.qrc" ] }, "capabilities": [ "ui_components", "storage" ] -} \ No newline at end of file +} diff --git a/plugin/StorageUIPlugin.cpp b/plugin/StorageUIPlugin.cpp deleted file mode 100644 index 472ab5b..0000000 --- a/plugin/StorageUIPlugin.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "StorageUIPlugin.h" -#include "src/StorageBackend.h" -#include -#include -#include -#include -#include -#include - -QWidget* StorageUIPlugin::createWidget(LogosAPI* logosAPI) { - qDebug() << "StorageUIPlugin::createWidget called"; - - QQuickWidget* quickWidget = new QQuickWidget(); - quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); - - // Register StorageBackend type with QML engine to expose the enum - qmlRegisterType("StorageBackend", 1, 0, "StorageBackend"); - - // Create backend instance - StorageBackend* backend = new StorageBackend(logosAPI, quickWidget); - - // Set backend as context property - quickWidget->rootContext()->setContextProperty("backend", backend); - - // For development: check environment variable, otherwise use qrc - QString qmlPath = "qrc:/StorageView.qml"; - QString envPath = qgetenv("STORAGE_UI_QML_PATH"); - if (!envPath.isEmpty() && QFile::exists(envPath)) { - qmlPath = QUrl::fromLocalFile(QFileInfo(envPath).absoluteFilePath()).toString(); - qDebug() << "Loading QML from file system:" << qmlPath; - } - - quickWidget->setSource(QUrl(qmlPath)); - - if (quickWidget->status() == QQuickWidget::Error) { - qWarning() << "StorageUIPlugin: Failed to load QML:" << quickWidget->errors(); - } - - return quickWidget; -} - -void StorageUIPlugin::destroyWidget(QWidget* widget) { - delete widget; -} \ No newline at end of file diff --git a/plugin/qml/StorageView.qml b/plugin/qml/StorageView.qml deleted file mode 100644 index 80540c9..0000000 --- a/plugin/qml/StorageView.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts -import StorageBackend - -Item { - id: root - - Rectangle { - anchors.fill: parent - anchors.leftMargin: 0 - anchors.rightMargin: 0 - anchors.topMargin: 0 - anchors.bottomMargin: 0 - color: "#202428" - } - - Text { - text: qsTr("Storage UI") - color: "black" - anchors.centerIn: parent - font.pointSize: 20 - } - - Text { - objectName: "status" - text: "..." - color: "white" - font.pointSize: 20 - anchors.topMargin: 32 - } - - Button { - objectName: "startButton" - anchors.leftMargin: 50 - text: "Stop" - } -} diff --git a/plugin/src/StorageBackend.cpp b/plugin/src/StorageBackend.cpp deleted file mode 100644 index 02927b2..0000000 --- a/plugin/src/StorageBackend.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "StorageBackend.h" -#include -#include -#include -#include -#include -#include - -StorageBackend::StorageBackend(LogosAPI* logosAPI, QObject* parent) - : QObject(parent), - m_status(NotStarted), - m_logosAPI(nullptr), - m_logos(nullptr) -{ - qDebug() << "Initializing StorageBackend..."; - - if (logosAPI) { - m_logosAPI = logosAPI; - } else { - m_logosAPI = new LogosAPI("core", this); - } - - m_logos = new LogosModules(m_logosAPI); -} - -StorageBackend::~StorageBackend() -{ - stopStorage(); -} - -void StorageBackend::setStatus(StorageStatus newStatus) -{ - if (m_status != newStatus) { - m_status = newStatus; - emit statusChanged(); - qDebug() << "StorageBackend: Status changed to" << m_status; - } -} - -void StorageBackend::startStorage() -{ - setStatus(Starting); - - auto& storageModule = m_logos->storage_module; - - QString configStr = R"({ - - })"; - - if (!storageModule.initStorage(configStr)) { - setStatus(Error); - return; - } - - // Subscribe to connectedPeersResponse events - // if (!storageModule.on("connectedPeersResponse", [this](const QVariantList& data) { - // if (data.size() < 1) { - // qWarning() << "StorageBackend: connectedPeersResponse payload missing fields"; - // return; - // } - // onConnectedPeersResponse(data); - // })) { - // qWarning() << "StorageBackend: failed to subscribe to connectedPeersResponse events"; - // } - - if (!storageModule.startStorage()) { - setStatus(Error); - return; - } - - setStatus(Running); - - // Refresh peers and metrics after a delay to allow Storage to fully start - // QTimer::singleShot(1000, this, [this]() { - // refreshPeers(); - // refreshMetrics(); - // }); -} - -void StorageBackend::stopStorage() -{ - if (m_status != Running && m_status != Starting) { - return; - } - - setStatus(Stopping); - - auto& storageModule = m_logos->storage_module; - - if (!storageModule.stopStorage()) { - qWarning() << "StorageBackend::stopStorage: stopStorage() returned false"; - setStatus(Error); - return; - } - - setStatus(Stopped); -} diff --git a/plugin/src/StorageBackend.h b/plugin/src/StorageBackend.h deleted file mode 100644 index a7fa226..0000000 --- a/plugin/src/StorageBackend.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "logos_api.h" -#include "logos_api_client.h" -#include "logos_sdk.h" - -class StorageBackend : public QObject { - Q_OBJECT - -public: - enum StorageStatus { - NotStarted = 0, - Starting, - Running, - Stopping, - Stopped, - Error - }; - Q_ENUM(StorageStatus) - - Q_PROPERTY(StorageStatus status READ status NOTIFY statusChanged) - - explicit StorageBackend(LogosAPI* logosAPI = nullptr, QObject* parent = nullptr); - ~StorageBackend(); - - StorageStatus status() const { return m_status; } - -public slots: - Q_INVOKABLE void startStorage(); - Q_INVOKABLE void stopStorage(); - -signals: - void statusChanged(); - -private slots: - // void onConnectedPeersResponse(const QVariantList& data); - -private: - void setStatus(StorageStatus newStatus); - - StorageStatus m_status; - LogosAPI* m_logosAPI; - LogosModules* m_logos; -}; \ No newline at end of file diff --git a/plugin/storage_resources.qrc b/plugin/storage_resources.qrc deleted file mode 100644 index 096fc83..0000000 --- a/plugin/storage_resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - StorageView.qml - - diff --git a/qml/CMakeLists.txt b/qml/CMakeLists.txt deleted file mode 100644 index f64257a..0000000 --- a/qml/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -project(qml VERSION 0.1 LANGUAGES CXX) - -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -find_package(Qt6 REQUIRED COMPONENTS Quick) - -qt_standard_project_setup(REQUIRES 6.8) - -qt_add_executable(appqml - main.cpp -) - -qt_add_qml_module(appqml - URI qml - VERSION 1.0 - QML_FILES - Main.qml -) - -# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. -# If you are developing for iOS or macOS you should consider setting an -# explicit, fixed bundle identifier manually though. -set_target_properties(appqml PROPERTIES -# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appqml - MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} - MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} - MACOSX_BUNDLE TRUE - WIN32_EXECUTABLE TRUE -) - -target_link_libraries(appqml - PRIVATE Qt6::Quick -) - -include(GNUInstallDirs) -install(TARGETS appqml - BUNDLE DESTINATION . - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) diff --git a/qml/Main.qml b/qml/Main.qml deleted file mode 100644 index 41424f8..0000000 --- a/qml/Main.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick - -Window { - width: 640 - height: 480 - visible: true - title: qsTr("Hello World") -} diff --git a/src/StorageBackend.cpp b/src/StorageBackend.cpp new file mode 100644 index 0000000..2cab9dc --- /dev/null +++ b/src/StorageBackend.cpp @@ -0,0 +1,156 @@ +#include "StorageBackend.h" +#include +#include +#include +#include +#include +#include + +StorageBackend::StorageBackend(LogosAPI* logosAPI, QObject* parent) + : QObject(parent), m_status(Destroyed), m_logosAPI(nullptr), m_logos(nullptr) { + qDebug() << "Initializing StorageBackend..."; + + if (logosAPI) { + m_logosAPI = logosAPI; + } else { + m_logosAPI = new LogosAPI("core", this); + } + + m_logos = new LogosModules(m_logosAPI); + + initStorage(); +} + +StorageBackend::~StorageBackend() +{ + m_logosAPI = nullptr; + m_logos = nullptr; +} + +void StorageBackend::initStorage() { + qDebug() << "StorageBackend::initStorage called"; + + bool result = m_logos->storage_module.init("{}"); + + qDebug() << "StorageBackend::initStorage: init result =" << result; + + if (!result) { + qDebug() << "StorageBackend: Failed to initialise Storage module."; + setStatus(Destroyed, "Failed to initialise Storage module."); + return; + } + + setStatus(Stopped, "Storage module ready."); + + if (!m_logos->storage_module.on("storageStart", [this](const QVariantList& data) { + int code = data[0].toInt(); + + if (code != RET_OK) { + qDebug() << "StorageBackend: storageStart event failure with code" << code; + setStatus(Stopped, "Failed to start Storage module."); + } else { + qDebug() << "StorageBackend: storageStart event success"; + setStatus(Running, "Storage module started."); + } + })) { + qWarning() << "StorageWidget: failed to subscribe to storageStart events"; + } + + if (!m_logos->storage_module.on("storageStop", [this](const QVariantList& data) { + int code = data[0].toInt(); + + if (code != RET_OK) { + qDebug() << "StorageBackend: storageStop event failure with code" << code; + setStatus(Running, "Failed to stop Storage module."); + } else { + qDebug() << "StorageBackend: storageStop event success"; + setStatus(Stopped, "Storage module stopped."); + emit stopped(); + } + })) { + qWarning() << "StorageWidget: failed to subscribe to storageStop events"; + } + + startStop(); +} + +void StorageBackend::setStatus(StorageStatus newStatus, QString statusText) { + if (m_status != newStatus || m_statusText != statusText) { + m_status = newStatus; + m_statusText = statusText; + emit statusChanged(); + qDebug() << "StorageBackend: Status changed to" << m_status; + } +} + +void StorageBackend::startStop() { + qDebug() << "StorageBackend: startStop method called"; + + if (m_status == Destroyed || m_status == Starting || m_status == Stopping) { + qDebug() << "StorageBackend: Cannot start/stop Storage in current state:" << m_status; + return; + } + + if (m_status != Running) { + qDebug() << "StorageBackend: Starting Storage..."; + setStatus(Starting, "Starting Storage module..."); + + bool result = m_logos->storage_module.start(); + + if (!result) { + qDebug() << "StorageBackend: Failed to start Storage."; + setStatus(Stopped, "Failed to start Storage module."); + return; + } + + qDebug() << "StorageBackend: start command sent, waiting for events."; + } else { + stop(); + } +} + +void StorageBackend::stop() { + qDebug() << "StorageBackend: Stopping Storage..."; + setStatus(Stopping, "Stopping Storage module..."); + + bool result = m_logos->storage_module.stop(); + + if (!result) { + qDebug() << "StorageBackend: Failed to stop Storage."; + setStatus(Running, "Failed to stop Storage module."); + return; + } + + qDebug() << "StorageBackend: stop command sent, waiting for events."; +} + +void StorageBackend::destroy() { + qDebug() << "StorageBackend: destroy method called"; + + StorageStatus status = m_status; + int result = m_logos->storage_module.destroy(); + + if (!result) { + qDebug() << "StorageBackend: Failed to destroy Storage module." << result; + setStatus(status, "Failed to destroy Storage module."); + return; + } + + qDebug() << "StorageBackend: Storage module destroyed."; +} + +QString StorageBackend::statusText() const { return m_statusText; } + +QString StorageBackend::startStopText() const { + if (m_status != Running) { + return "Start"; + } else { + return "Stop"; + } +} + +bool StorageBackend::canStartStop() const { return m_status == Running || m_status == Stopped; } + +bool StorageBackend::isRunning() { return m_status == Running; } + +bool StorageBackend::isInitialised() { return m_status != Destroyed; } diff --git a/src/StorageBackend.h b/src/StorageBackend.h new file mode 100644 index 0000000..76d0b7b --- /dev/null +++ b/src/StorageBackend.h @@ -0,0 +1,54 @@ +#pragma once +#include "logos_api.h" +#include "logos_sdk.h" +#include +#include +#include +#include +#include + +static const int RET_OK = 0; + +class StorageBackend : public QObject { + Q_OBJECT + QML_ELEMENT + + public: + enum StorageStatus { Stopped = 0, Starting, Running, Stopping, Destroyed }; + Q_ENUM(StorageStatus) + + Q_PROPERTY(bool canStartStop READ canStartStop NOTIFY statusChanged) + bool canStartStop() const; + + Q_PROPERTY(QString startStopText READ startStopText NOTIFY statusChanged) + QString startStopText() const; + + Q_PROPERTY(QString statusText READ statusText NOTIFY statusChanged) + QString statusText() const; + + explicit StorageBackend(LogosAPI* logosAPI = nullptr, QObject* parent = nullptr); + ~StorageBackend(); + + public slots: + void startStop(); + void destroy(); + bool isRunning(); + bool isInitialised(); + void stop(); + + signals: + void statusChanged(); + void stopped(); + + private slots: + + private: + void setStatus(StorageStatus newStatus, QString statusText); + void initStorage(); + + StorageStatus m_status; + LogosAPI* m_logosAPI; + LogosModules* m_logos; + + QString m_statusText; +}; diff --git a/src/StorageUIPlugin.cpp b/src/StorageUIPlugin.cpp new file mode 100644 index 0000000..c8badd4 --- /dev/null +++ b/src/StorageUIPlugin.cpp @@ -0,0 +1,115 @@ +#include "StorageUIPlugin.h" +#include "StorageBackend.h" +#include +#include +#include +#include +#include +#include +#include + +QWidget* StorageUIPlugin::createWidget(LogosAPI* logosAPI) { + qDebug() << "StorageUIPlugin::createWidget called"; + + QQuickWidget* quickWidget = new QQuickWidget(); + quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + + QString qmlPath = "qrc:/StorageView.qml"; + + quickWidget->setSource(QUrl(qmlPath)); + + if (quickWidget->status() == QQuickWidget::Error) { + qWarning() << "StorageUIPlugin: Failed to load QML:" << quickWidget->errors(); + } + + // Create backend instance + StorageBackend* backend = new StorageBackend(logosAPI, quickWidget); + + // Set backend as context property + QQuickItem* root = quickWidget->rootObject(); + Q_ASSERT(root); + + root->setProperty("backend", QVariant::fromValue(static_cast(backend))); + + return quickWidget; +} + +// Destroy the widget and clean up the backend. +// It will block the event loop up to 2 seconds to ensure proper cleanup. +// It will try to stop the backend if it is running.` +void StorageUIPlugin::destroyWidget(QWidget* widget) { + qDebug() << "StorageUIPlugin: Destroy widget"; + + auto* quickWidget = qobject_cast(widget); + if (!quickWidget) { + delete widget; + return; + } + + QQuickItem* root = quickWidget->rootObject(); + if (!root) { + qWarning() << "StorageUIPlugin::destroyWidget: No rootObject, deleting widget"; + quickWidget->deleteLater(); + return; + } + + // Disable QML to ensure that not updated are pushed in the UI + root->setEnabled(false); + + // Retrieve the backend object from the root element + // as it was set in createWidget + QObject* value = root->property("backend").value(); + auto* backend = qobject_cast(value); + if (!backend) { + qWarning() << "StorageUIPlugin::destroyWidget: No backend found on root property 'backend'."; + quickWidget->deleteLater(); + return; + } + + if (!backend->isInitialised()) { + qDebug() << "StorageUIPlugin::destroyWidget: backend is not initialised so let's detroy it."; + quickWidget->deleteLater(); + return; + } + + if (!backend->isRunning()) { + qDebug() << "StorageUIPlugin::destroyWidget: backend is not running so let's detroy it."; + + backend->destroy(); + + quickWidget->deleteLater(); + + return; + } + + qDebug() << "StorageUIPlugin::destroyWidget: backend is running so let's stop it."; + + // Here we create a QEventLoop to wait for the stopped signal + QEventLoop loop; + QTimer timeout; + // Single shot means that the timer will only fire once. + timeout.setSingleShot(true); + + // Connect to timeout and unblock the event loop after 2 seconds + QObject::connect(&timeout, &QTimer::timeout, &loop, [&]() { + qWarning() << "StorageUIPlugin::destroyWidget: stop timeout"; + loop.quit(); + }); + + // Connect to stop signal + QObject::connect(backend, &StorageBackend::stopped, &loop, [&]() { loop.quit(); }, Qt::QueuedConnection); + + // Call the stop method asynchronously + QMetaObject::invokeMethod(backend, "stop", Qt::QueuedConnection); + + // Set the timeout to 2 sec + timeout.start(2000); + + // Block + loop.exec(); + + // Try to cleanup, event if the stop method failed + backend->destroy(); + + delete quickWidget; +} diff --git a/plugin/StorageUIPlugin.h b/src/StorageUIPlugin.h similarity index 82% rename from plugin/StorageUIPlugin.h rename to src/StorageUIPlugin.h index b1150e4..bafd8ea 100644 --- a/plugin/StorageUIPlugin.h +++ b/src/StorageUIPlugin.h @@ -10,5 +10,5 @@ class StorageUIPlugin : public QObject, public IComponent { public: Q_INVOKABLE QWidget* createWidget(LogosAPI* logosAPI = nullptr) override; - void destroyWidget(QWidget* widget) override; -}; \ No newline at end of file + Q_INVOKABLE void destroyWidget(QWidget* widget) override; +}; diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index f221b09..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include "StorageWindow.h" - -int main(int argc, char *argv[]) { - QApplication app(argc, argv); - - qDebug() << "Starting Storage Qt Application"; - - // Create and show the main window - StorageWindow mainWindow; - mainWindow.setWindowTitle("Logos Storage App"); - mainWindow.resize(800, 600); - mainWindow.show(); - - return app.exec(); -} \ No newline at end of file diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt new file mode 100644 index 0000000..fdc96e2 --- /dev/null +++ b/src/qml/CMakeLists.txt @@ -0,0 +1,147 @@ +cmake_minimum_required(VERSION 3.16) + +project(qml VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_AUTOMOC ON) + +########### DEPENDENCIES ########### + +# This section locates the required dependencies in 3 different ways: +# 1- With NIX, the root folders (LOGOS_LIBLOGOS_ROOT, LOGOS_CPP_SDK_ROO) +# are defined and point to the correct locations in +# the Nix store. +# 2- If the root folders are fetched from source (basically using git) in the +# parent folder, this is detected and used. +# 3- If none of the above apply, the vendor folders inside this project are used, +# meaning the dependencies need to be fetched using git submodules. + +# Locate logos-cpp-sdk +if(NOT DEFINED LOGOS_CPP_SDK_ROOT) + set(_parent_cpp_sdk "${CMAKE_SOURCE_DIR}/../../../logos-cpp-sdk") + set(_use_vendor ${LOGOS_STORAGE_UI_USE_VENDOR}) + + if(NOT _use_vendor) + if(NOT EXISTS "${_parent_cpp_sdk}/cpp/logos_api.h") + set(_use_vendor ON) + endif() + endif() + + if(_use_vendor) + set(LOGOS_CPP_SDK_ROOT "${CMAKE_SOURCE_DIR}/../../vendor/logos-cpp-sdk") + else() + set(LOGOS_CPP_SDK_ROOT "${_parent_cpp_sdk}") + endif() +endif() + +# Locate the logos_api header file. +# If the file is found, the sdk is considered found. +set(_cpp_sdk_found FALSE) +if(EXISTS "${LOGOS_CPP_SDK_ROOT}/cpp/logos_api.h") + set(_cpp_sdk_found TRUE) + set(_cpp_sdk_is_source TRUE) +elseif(EXISTS "${LOGOS_CPP_SDK_ROOT}/include/cpp/logos_api.h") + set(_cpp_sdk_found TRUE) + set(_cpp_sdk_is_source FALSE) +endif() + +# Fails if the SDK is not found. +if(NOT _cpp_sdk_found) + message(FATAL_ERROR + "logos-cpp-sdk not found at ${LOGOS_CPP_SDK_ROOT}. " + "Set LOGOS_CPP_SDK_ROOT or run git submodule update --init --recursive." + ) +endif() + +########### DEPENDENCIES END ########### + +########### QML DEFINITION ########### + +set(PLUGIN_UI_BUILD_DIR "../../build/generated_code") + +list(APPEND SOURCES + ${PLUGIN_UI_BUILD_DIR}/logos_sdk.cpp +) + +# Create a library with the Logos SDK and generated sources to keep them separate +add_library(storage_generated STATIC + ${PLUGIN_UI_BUILD_DIR}/logos_sdk.cpp + ${PLUGIN_UI_BUILD_DIR}/storage_module_api.cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/logos_api.cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/logos_api_client.cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/logos_api_provider.cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/module_proxy.cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/token_manager.cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/logos_api_consumer.cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/logos_api_provider.cpp +) + +# Define the dependencies needed for storage_generated +target_link_libraries(storage_generated PUBLIC + Qt6::Core + Qt6::RemoteObjects +) + +# Discover the required dependencies +find_package(Qt6 REQUIRED COMPONENTS Quick RemoteObjects) + +# Standard project setup for Qt applications +qt_standard_project_setup(REQUIRES 6.8) + +# Add the Qt Quick application executable +qt_add_executable(appqml + main.cpp +) + +# Use these required dependencies. +target_link_libraries(appqml PRIVATE + Qt6::Quick + Qt6::Qml + storage_generated +) + +# Define the qml module and the StorageBackend sources. +qt_add_qml_module(appqml + URI StorageBackend + VERSION 1.0 + SOURCES + ../src/StorageBackend.cpp + ../src/StorageBackend.h + QML_FILES + StorageView.qml +) + +########### QML DEFINITION END ########### + +########### HEADERS ########### + +target_include_directories(storage_generated PUBLIC + "${PLUGIN_UI_BUILD_DIR}" + "${PLUGIN_UI_BUILD_DIR}/include" +) + +# Include directories +if(_cpp_sdk_is_source) + target_include_directories(storage_generated PUBLIC + ${LOGOS_CPP_SDK_ROOT}/cpp + ${LOGOS_CPP_SDK_ROOT}/cpp/generated + ) +else() + target_include_directories(storage_generated PUBLIC + ${LOGOS_CPP_SDK_ROOT}/include + ${LOGOS_CPP_SDK_ROOT}/include/cpp + ${LOGOS_CPP_SDK_ROOT}/include/core + ${PLUGIN_UI_BUILD_DIR}/include + ) +endif() + +# Import the application headers. +target_include_directories(appqml PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../src + ${PLUGINS_OUTPUT_DIR} +) + +########### HEADERS END ########### + +message(STATUS "Qt Quick app configured successfully") diff --git a/src/qml/StorageView.qml b/src/qml/StorageView.qml new file mode 100644 index 0000000..0cf8f89 --- /dev/null +++ b/src/qml/StorageView.qml @@ -0,0 +1,63 @@ +import QtQuick +import QtQuick.Controls + +//import QtQuick.Layouts +Item { + property var backend: mockBackend + readonly property int stopped: 0 + readonly property int starting: 1 + readonly property int running: 2 + readonly property int stopping: 3 + readonly property int destroyed: 4 + + id: root + width: 400 + height: 300 + + QtObject { + id: mockBackend + + property var status: root.stopped + property var statusText: "Destroyed" + property var startStopText: "Start" + property var canStartStop: true + + function startStop() { + if (status == root.running) { + status = root.stopped + statusText = "Stopped" + startStopText = "Start" + } else { + status = root.running + statusText = "Started" + startStopText = "Stop" + } + } + } + + Rectangle { + anchors.fill: parent + anchors.leftMargin: 0 + anchors.rightMargin: 0 + anchors.topMargin: 0 + anchors.bottomMargin: 0 + color: "#202428" + } + + Text { + objectName: "status" + text: root.backend.statusText + color: "white" + font.pointSize: 20 + anchors.centerIn: parent + anchors.topMargin: 0 + } + + Button { + objectName: "startStopButton" + anchors.leftMargin: 50 + text: root.backend.startStopText + enabled: root.backend.canStartStop + onClicked: root.backend.startStop() + } +} diff --git a/qml/main.cpp b/src/qml/main.cpp similarity index 89% rename from qml/main.cpp rename to src/qml/main.cpp index 2ae0fe7..c930aa9 100644 --- a/qml/main.cpp +++ b/src/qml/main.cpp @@ -1,5 +1,6 @@ #include #include +#include int main(int argc, char* argv[]) { QGuiApplication app(argc, argv); @@ -8,7 +9,6 @@ int main(int argc, char* argv[]) { QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); - engine.loadFromModule("qml", "Main"); return app.exec(); } diff --git a/src/storage_resources.qrc b/src/storage_resources.qrc new file mode 100644 index 0000000..6b04df3 --- /dev/null +++ b/src/storage_resources.qrc @@ -0,0 +1,5 @@ + + + qml/StorageView.qml + +