1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-22 10:42:29 +01:00

Update ScreenPlay App type to be a QML_SINGLETON

This should in theory fix QtCreator autocompletion,
but https://bugreports.qt.io/browse/QTCREATORBUG-30197
must be fixed first
This commit is contained in:
Elias Steurer 2024-01-12 16:10:34 +01:00
parent ca30748c69
commit 59a6523f28
72 changed files with 543 additions and 496 deletions

View File

@ -11,6 +11,7 @@ include(GenerateCMakeVariableHeader)
set(SOURCES set(SOURCES
# cmake-format: sort # cmake-format: sort
src/applicationengine.cpp
src/app.cpp src/app.cpp
src/create.cpp src/create.cpp
src/createimportvideo.cpp src/createimportvideo.cpp
@ -31,6 +32,7 @@ set(HEADER
# cmake-format: sort # cmake-format: sort
inc/public/ScreenPlay/app.h inc/public/ScreenPlay/app.h
inc/public/ScreenPlay/applicationengine.h
inc/public/ScreenPlay/create.h inc/public/ScreenPlay/create.h
inc/public/ScreenPlay/createimportstates.h inc/public/ScreenPlay/createimportstates.h
inc/public/ScreenPlay/createimportvideo.h inc/public/ScreenPlay/createimportvideo.h
@ -96,6 +98,7 @@ set(QML
qml/Settings/SettingsPage.qml qml/Settings/SettingsPage.qml
qml/Settings/SettingsView.qml qml/Settings/SettingsView.qml
qml/TrayIcon.qml qml/TrayIcon.qml
qml/Base.qml
qml/Workshop/WorkshopView.qml) qml/Workshop/WorkshopView.qml)
set(TS_FILES set(TS_FILES
@ -351,6 +354,9 @@ if(WIN32
file(MAKE_DIRECTORY ${FONTS_OUT_DIR}) file(MAKE_DIRECTORY ${FONTS_OUT_DIR})
copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.ttf") copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.ttf")
copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.otf") copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.otf")
set(RESOURCES_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/assets")
file(MAKE_DIRECTORY ${RESOURCES_DIR})
endif() endif()
if(WIN32) if(WIN32)
@ -412,14 +418,14 @@ if(APPLE)
add_custom_command( add_custom_command(
TARGET ${PROJECT_NAME} TARGET ${PROJECT_NAME}
POST_BUILD POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/ffmpeg/ffmpeg COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/ffmpeg/ffmpeg"
${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/) "${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
add_custom_command( add_custom_command(
TARGET ${PROJECT_NAME} TARGET ${PROJECT_NAME}
POST_BUILD POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/ffmpeg/ffprobe COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/ffmpeg/ffprobe"
${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/) "${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
# fonts # fonts
include(CopyRecursive) include(CopyRecursive)
@ -428,11 +434,12 @@ if(APPLE)
copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.ttf") copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.ttf")
copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.otf") copy_recursive(${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts ${FONTS_OUT_DIR} "*.otf")
endif()
# .qm translations # .qm translations
set(QM_OUT_DIR "${RESOURCES_DIR}/translations") set(QM_OUT_DIR "${RESOURCES_DIR}/translations")
file(MAKE_DIRECTORY ${QM_OUT_DIR}) file(MAKE_DIRECTORY ${QM_OUT_DIR})
set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION ${QM_OUT_DIR}) set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION ${QM_OUT_DIR})
endif()
# Must be called here, because we need to change the OUTPUT_LOCATION for macos # Must be called here, because we need to change the OUTPUT_LOCATION for macos
qt_add_lrelease(${PROJECT_NAME} TS_FILES ${TS_FILES}) qt_add_lrelease(${PROJECT_NAME} TS_FILES ${TS_FILES})

View File

@ -1,21 +1,7 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#pragma once #pragma once
#include <QString>
#include <QDir>
#include <QElapsedTimer>
#include <QGuiApplication>
#include <QIcon>
#include <QObject>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickWindow>
#include <QStringList>
#include <QUrl>
#include <QtGlobal>
#include <QtQml>
#include <QtSvg>
#include "ScreenPlay/create.h" #include "ScreenPlay/create.h"
#include "ScreenPlay/globalvariables.h" #include "ScreenPlay/globalvariables.h"
@ -27,6 +13,7 @@
#include "ScreenPlay/settings.h" #include "ScreenPlay/settings.h"
#include "ScreenPlay/wizards.h" #include "ScreenPlay/wizards.h"
#include "ScreenPlayUtil/util.h" #include "ScreenPlayUtil/util.h"
#include <QQmlEngine>
#include <memory> #include <memory>
@ -38,25 +25,26 @@ namespace ScreenPlay {
class App : public QObject { class App : public QObject {
Q_OBJECT Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(QQmlApplicationEngine* mainWindowEngine READ mainWindowEngine WRITE setMainWindowEngine NOTIFY mainWindowEngineChanged) Q_PROPERTY(GlobalVariables* globalVariables READ globalVariables WRITE setGlobalVariables NOTIFY globalVariablesChanged FINAL)
Q_PROPERTY(GlobalVariables* globalVariables READ globalVariables WRITE setGlobalVariables NOTIFY globalVariablesChanged) Q_PROPERTY(ScreenPlayManager* screenPlayManager READ screenPlayManager WRITE setScreenPlayManager NOTIFY screenPlayManagerChanged FINAL)
Q_PROPERTY(ScreenPlayManager* screenPlayManager READ screenPlayManager WRITE setScreenPlayManager NOTIFY screenPlayManagerChanged) Q_PROPERTY(Create* create READ create WRITE setCreate NOTIFY createChanged FINAL)
Q_PROPERTY(Create* create READ create WRITE setCreate NOTIFY createChanged) Q_PROPERTY(Wizards* wizards READ wizards WRITE setWizards NOTIFY wizardsChanged FINAL)
Q_PROPERTY(Wizards* wizards READ wizards WRITE setWizards NOTIFY wizardsChanged) Q_PROPERTY(Util* util READ util WRITE setUtil NOTIFY utilChanged FINAL)
Q_PROPERTY(Util* util READ util WRITE setUtil NOTIFY utilChanged) Q_PROPERTY(Settings* settings READ settings WRITE setSettings NOTIFY settingsChanged FINAL)
Q_PROPERTY(Settings* settings READ settings WRITE setSettings NOTIFY settingsChanged) Q_PROPERTY(InstalledListModel* installedListModel READ installedListModel WRITE setInstalledListModel NOTIFY installedListModelChanged FINAL)
Q_PROPERTY(InstalledListFilter* installedListFilter READ installedListFilter WRITE setInstalledListFilter NOTIFY installedListFilterChanged FINAL)
Q_PROPERTY(InstalledListModel* installedListModel READ installedListModel WRITE setInstalledListModel NOTIFY installedListModelChanged) Q_PROPERTY(MonitorListModel* monitorListModel READ monitorListModel WRITE setMonitorListModel NOTIFY monitorListModelChanged FINAL)
Q_PROPERTY(InstalledListFilter* installedListFilter READ installedListFilter WRITE setInstalledListFilter NOTIFY installedListFilterChanged) Q_PROPERTY(ProfileListModel* profileListModel READ profileListModel WRITE setProfileListModel NOTIFY profileListModelChanged FINAL)
Q_PROPERTY(MonitorListModel* monitorListModel READ monitorListModel WRITE setMonitorListModel NOTIFY monitorListModelChanged)
Q_PROPERTY(ProfileListModel* profileListModel READ profileListModel WRITE setProfileListModel NOTIFY profileListModelChanged)
public: public:
explicit App(); // QML callable functions
Q_INVOKABLE void init();
void init(); Q_INVOKABLE QString version() const;
bool m_isAnotherScreenPlayInstanceRunning { false }; Q_INVOKABLE void showDockIcon(const bool show);
Q_INVOKABLE void exit();
GlobalVariables* globalVariables() const { return m_globalVariables.get(); } GlobalVariables* globalVariables() const { return m_globalVariables.get(); }
ScreenPlayManager* screenPlayManager() const { return m_screenPlayManager.get(); } ScreenPlayManager* screenPlayManager() const { return m_screenPlayManager.get(); }
@ -67,9 +55,11 @@ public:
MonitorListModel* monitorListModel() const { return m_monitorListModel.get(); } MonitorListModel* monitorListModel() const { return m_monitorListModel.get(); }
ProfileListModel* profileListModel() const { return m_profileListModel.get(); } ProfileListModel* profileListModel() const { return m_profileListModel.get(); }
InstalledListFilter* installedListFilter() const { return m_installedListFilter.get(); } InstalledListFilter* installedListFilter() const { return m_installedListFilter.get(); }
QQmlApplicationEngine* mainWindowEngine() const { return m_mainWindowEngine.get(); }
Wizards* wizards() const { return m_wizards.get(); } Wizards* wizards() const { return m_wizards.get(); }
QQmlEngine* engine() const;
void setEngine(QQmlEngine* engine);
signals: signals:
void globalVariablesChanged(ScreenPlay::GlobalVariables* globalVariables); void globalVariablesChanged(ScreenPlay::GlobalVariables* globalVariables);
void screenPlayManagerChanged(ScreenPlay::ScreenPlayManager* screenPlayManager); void screenPlayManagerChanged(ScreenPlay::ScreenPlayManager* screenPlayManager);
@ -80,15 +70,11 @@ signals:
void monitorListModelChanged(ScreenPlay::MonitorListModel* monitorListModel); void monitorListModelChanged(ScreenPlay::MonitorListModel* monitorListModel);
void profileListModelChanged(ScreenPlay::ProfileListModel* profileListModel); void profileListModelChanged(ScreenPlay::ProfileListModel* profileListModel);
void installedListFilterChanged(ScreenPlay::InstalledListFilter* installedListFilter); void installedListFilterChanged(ScreenPlay::InstalledListFilter* installedListFilter);
void mainWindowEngineChanged(QQmlApplicationEngine* mainWindowEngine);
void wizardsChanged(ScreenPlay::Wizards* wizards); void wizardsChanged(ScreenPlay::Wizards* wizards);
void requestExit();
void requestRetranslation();
public slots: public slots:
QString version() const;
void showDockIcon(const bool show);
void exit();
QPointF cursorPos() { return QCursor::pos(); }
void setGlobalVariables(GlobalVariables* globalVariables); void setGlobalVariables(GlobalVariables* globalVariables);
void setScreenPlayManager(ScreenPlayManager* screenPlayManager); void setScreenPlayManager(ScreenPlayManager* screenPlayManager);
void setCreate(Create* create); void setCreate(Create* create);
@ -98,20 +84,16 @@ public slots:
void setMonitorListModel(MonitorListModel* monitorListModel); void setMonitorListModel(MonitorListModel* monitorListModel);
void setProfileListModel(ProfileListModel* profileListModel); void setProfileListModel(ProfileListModel* profileListModel);
void setInstalledListFilter(InstalledListFilter* installedListFilter); void setInstalledListFilter(InstalledListFilter* installedListFilter);
void setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine);
void setWizards(Wizards* wizards); void setWizards(Wizards* wizards);
private: private:
QNetworkAccessManager m_networkAccessManager; QQmlEngine* m_engine = nullptr;
std::unique_ptr<QQmlApplicationEngine> m_mainWindowEngine;
std::unique_ptr<Create> m_create; std::unique_ptr<Create> m_create;
std::unique_ptr<Wizards> m_wizards; std::unique_ptr<Wizards> m_wizards;
std::unique_ptr<ScreenPlayManager> m_screenPlayManager; std::unique_ptr<ScreenPlayManager> m_screenPlayManager;
std::unique_ptr<Util> m_util; std::unique_ptr<Util> m_util;
std::shared_ptr<GlobalVariables> m_globalVariables; std::shared_ptr<GlobalVariables> m_globalVariables;
std::shared_ptr<Settings> m_settings; std::shared_ptr<Settings> m_settings;
std::shared_ptr<InstalledListModel> m_installedListModel; std::shared_ptr<InstalledListModel> m_installedListModel;
std::shared_ptr<MonitorListModel> m_monitorListModel; std::shared_ptr<MonitorListModel> m_monitorListModel;

View File

@ -0,0 +1,18 @@
#pragma once
#include <QByteArray>
#include <QGuiApplication>
#include <QLocalSocket>
#include <QObject>
#include <QQmlApplicationEngine>
namespace ScreenPlay {
class ApplicationEngine : public QQmlApplicationEngine {
Q_OBJECT
public:
explicit ApplicationEngine(QObject* parent = nullptr);
bool isAnotherScreenPlayInstanceRunning();
void init();
};
}

View File

@ -17,8 +17,9 @@ class GlobalVariables : public QObject {
Q_OBJECT Q_OBJECT
QML_ELEMENT QML_ELEMENT
QML_UNCREATABLE("") QML_UNCREATABLE("")
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
Q_PROPERTY(QVersionNumber version READ version CONSTANT) Q_PROPERTY(Version version READ version WRITE setVersion NOTIFY versionChanged FINAL)
Q_PROPERTY(QUrl localStoragePath READ localStoragePath WRITE setLocalStoragePath NOTIFY localStoragePathChanged FINAL) Q_PROPERTY(QUrl localStoragePath READ localStoragePath WRITE setLocalStoragePath NOTIFY localStoragePathChanged FINAL)
Q_PROPERTY(QUrl localSettingsPath READ localSettingsPath WRITE setLocalSettingsPath NOTIFY localSettingsPathChanged FINAL) Q_PROPERTY(QUrl localSettingsPath READ localSettingsPath WRITE setLocalSettingsPath NOTIFY localSettingsPathChanged FINAL)
Q_PROPERTY(QUrl wallpaperExecutablePath READ wallpaperExecutablePath WRITE setWallpaperExecutablePath NOTIFY wallpaperExecutablePathChanged FINAL) Q_PROPERTY(QUrl wallpaperExecutablePath READ wallpaperExecutablePath WRITE setWallpaperExecutablePath NOTIFY wallpaperExecutablePathChanged FINAL)
@ -29,43 +30,24 @@ class GlobalVariables : public QObject {
public: public:
explicit GlobalVariables(QObject* parent = nullptr); explicit GlobalVariables(QObject* parent = nullptr);
/*! enum class Version {
\property GlobalVariables::m_version OpenSource,
\brief Returns the current app version. Not yet used. OpenSourceSteam,
*/ OpenSourcePlus,
QVersionNumber version() const { return m_version; } OpenSourcePlusSteam
/*! };
\property GlobalVariables::localStoragePath Q_ENUM(Version)
\brief Returns the localStoragePath.
*/ Version version() const { return m_version; }
QUrl localStoragePath() const { return m_localStoragePath; } QUrl localStoragePath() const { return m_localStoragePath; }
/*!
\property GlobalVariables::localSettingsPath
\brief Returns the localSettingsPath.
*/
QUrl localSettingsPath() const { return m_localSettingsPath; } QUrl localSettingsPath() const { return m_localSettingsPath; }
/*!
\property GlobalVariables::wallpaperExecutablePath
\brief Returns the wallpaperExecutablePath. This only differes in development builds.
*/
QUrl wallpaperExecutablePath() const { return m_wallpaperExecutablePath; } QUrl wallpaperExecutablePath() const { return m_wallpaperExecutablePath; }
/*!
\property GlobalVariables::widgetExecutablePath
\brief Returns the widgetExecutablePath. This only differes in development builds.
*/
QUrl widgetExecutablePath() const { return m_widgetExecutablePath; } QUrl widgetExecutablePath() const { return m_widgetExecutablePath; }
/*!
\property GlobalVariables::m_version
\brief Returns the current app version. Not yet used.
*/
QUrl godotWallpaperExecutablePath() const { return m_godotWallpaperExecutablePath; } QUrl godotWallpaperExecutablePath() const { return m_godotWallpaperExecutablePath; }
/*!
\property GlobalVariables::m_version
\brief Returns the current app version. Not yet used.
*/
QUrl godotEditorExecutablePath() const { return m_godotEditorExecutablePath; } QUrl godotEditorExecutablePath() const { return m_godotEditorExecutablePath; }
signals: signals:
void versionChanged(Version version);
void localStoragePathChanged(QUrl localStoragePath); void localStoragePathChanged(QUrl localStoragePath);
void localSettingsPathChanged(QUrl localSettingsPath); void localSettingsPathChanged(QUrl localSettingsPath);
void wallpaperExecutablePathChanged(QUrl wallpaperExecutablePath); void wallpaperExecutablePathChanged(QUrl wallpaperExecutablePath);
@ -74,6 +56,7 @@ signals:
void godotEditorExecutablePathChanged(QUrl godotEditorExecutablePath); void godotEditorExecutablePathChanged(QUrl godotEditorExecutablePath);
public slots: public slots:
void setVersion(Version version);
void setLocalStoragePath(QUrl localStoragePath); void setLocalStoragePath(QUrl localStoragePath);
void setLocalSettingsPath(QUrl localSettingsPath); void setLocalSettingsPath(QUrl localSettingsPath);
void setWallpaperExecutablePath(QUrl wallpaperExecutablePath); void setWallpaperExecutablePath(QUrl wallpaperExecutablePath);
@ -93,8 +76,8 @@ private:
QUrl m_localSettingsPath; QUrl m_localSettingsPath;
QUrl m_wallpaperExecutablePath; QUrl m_wallpaperExecutablePath;
QUrl m_widgetExecutablePath; QUrl m_widgetExecutablePath;
QVersionNumber m_version { 1, 0, 0 };
QUrl m_godotWallpaperExecutablePath; QUrl m_godotWallpaperExecutablePath;
QUrl m_godotEditorExecutablePath; QUrl m_godotEditorExecutablePath;
Version m_version = Version::OpenSource;
}; };
} }

View File

@ -39,7 +39,6 @@ public:
int activeWallpaperCounter() const { return m_activeWallpaperCounter; } int activeWallpaperCounter() const { return m_activeWallpaperCounter; }
int activeWidgetsCounter() const { return m_activeWidgetsCounter; } int activeWidgetsCounter() const { return m_activeWidgetsCounter; }
bool isAnotherScreenPlayInstanceRunning() { return m_isAnotherScreenPlayInstanceRunning; }
signals: signals:
void activeWallpaperCounterChanged(int activeWallpaperCounter); void activeWallpaperCounterChanged(int activeWallpaperCounter);
@ -77,8 +76,8 @@ public slots:
const QJsonObject& properties, const QJsonObject& properties,
const bool saveToProfilesConfigFile); const bool saveToProfilesConfigFile);
bool removeAllWallpapers(); bool removeAllWallpapers(bool saveToProfile = false);
bool removeAllWidgets(); bool removeAllWidgets(bool saveToProfile = false);
bool removeWallpaperAt(const int index); bool removeWallpaperAt(const int index);
bool requestProjectSettingsAtMonitorIndex(const int index); bool requestProjectSettingsAtMonitorIndex(const int index);
@ -159,7 +158,6 @@ private:
int m_activeWallpaperCounter { 0 }; int m_activeWallpaperCounter { 0 };
int m_activeWidgetsCounter { 0 }; int m_activeWidgetsCounter { 0 };
bool m_isAnotherScreenPlayInstanceRunning = false;
QTimer m_saveLimiter; QTimer m_saveLimiter;
const quint16 m_webSocketPort = 16395; const quint16 m_webSocketPort = 16395;

View File

@ -1,7 +1,7 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#include "ScreenPlay/CMakeVariables.h" #include "ScreenPlay/CMakeVariables.h"
#include "ScreenPlay/app.h" #include "ScreenPlay/applicationengine.h"
#include "ScreenPlayUtil/logginghandler.h" #include "ScreenPlayUtil/logginghandler.h"
#include "qcorotask.h" #include "qcorotask.h"
#include "qml/qcoroqml.h" #include "qml/qcoroqml.h"
@ -18,6 +18,7 @@
Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin)
#endif #endif
#include <QQmlEngineExtensionPlugin>
Q_IMPORT_QML_PLUGIN(ScreenPlayAppPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayAppPlugin)
Q_IMPORT_QML_PLUGIN(ScreenPlayUtilPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayUtilPlugin)
Q_IMPORT_QML_PLUGIN(PlausiblePlugin) Q_IMPORT_QML_PLUGIN(PlausiblePlugin)
@ -30,14 +31,14 @@ int main(int argc, char* argv[])
#endif #endif
QGuiApplication qtGuiApp(argc, argv); QGuiApplication qtGuiApp(argc, argv);
ScreenPlay::App app; ScreenPlay::ApplicationEngine appEngine;
if (app.m_isAnotherScreenPlayInstanceRunning) { if (appEngine.isAnotherScreenPlayInstanceRunning()) {
return 0; return 0;
} }
auto logging = std::make_unique<const ScreenPlayUtil::LoggingHandler>("ScreenPlay"); auto logging = std::make_unique<const ScreenPlayUtil::LoggingHandler>("ScreenPlay");
app.init(); appEngine.init();
const int status = qtGuiApp.exec(); const int status = qtGuiApp.exec();
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
sentry_shutdown(); sentry_shutdown();

View File

@ -1,57 +1,16 @@
import QtCore as QCore
import QtQml import QtQml
import QtQuick import QtQuick
import QtQuick.Window import QtQuick.Window
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts
import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util
import Qt5Compat.GraphicalEffects
import Plausible 1.0 import Plausible 1.0
import "qml/Monitors" as Monitors import ScreenPlayApp 1.0
import "qml/Installed" as Installed import QtCore as QCore
import "qml/Navigation" as Navigation
import "qml/Community" as Community
import "qml"
ApplicationWindow { ApplicationWindow {
id: root id: root
color: Material.theme === Material.Dark ? Qt.darker(
function setTheme(theme) { Material.background) : Material.background
switch (theme) {
case Settings.Theme.System:
root.Material.theme = Material.System;
break;
case Settings.Theme.Dark:
root.Material.theme = Material.Dark;
break;
case Settings.Theme.Light:
root.Material.theme = Material.Light;
break;
}
}
function switchPage(name) {
if (nav.currentNavigationName === name) {
if (name === "Installed")
App.installedListModel.reset();
}
if (name === "Installed") {
stackView.replace("qrc:/qml/ScreenPlayApp/qml/Installed/InstalledView.qml", {
"sidebar": sidebar
});
return;
}
stackView.replace("qrc:/qml/ScreenPlayApp/qml/" + name + "/" + name + "View.qml", {
"modalSource": content
});
nav.setNavigation(name);
sidebar.state = "inactive";
}
color: Material.theme === Material.Dark ? Qt.darker(Material.background) : Material.background
// Set visible if the -silent parameter was not set (see app.cpp end of constructor). // Set visible if the -silent parameter was not set (see app.cpp end of constructor).
visible: false visible: false
width: 1400 width: 1400
@ -59,6 +18,71 @@ ApplicationWindow {
title: "ScreenPlay - v" + App.version() title: "ScreenPlay - v" + App.version()
minimumHeight: 450 minimumHeight: 450
minimumWidth: 1050 minimumWidth: 1050
Component.onCompleted: {
// App is now a qml singleton to fix QtC autocompletion.
// This also now means we have to make sure to init it here
// and do _not_ access any other properties before we called init.
App.init()
setTheme(App.settings.theme)
if (!App.settings.silentStart) {
App.showDockIcon(true)
root.show()
}
baseLoader.setSource("qrc:/qml/ScreenPlayApp/qml/Base.qml")
}
Connections {
target: App
function onRequestExit(){
Qt.exit(0)
}
}
function setTheme(theme) {
switch (theme) {
case Settings.Theme.System:
root.Material.theme = Material.System
break
case Settings.Theme.Dark:
root.Material.theme = Material.Dark
break
case Settings.Theme.Light:
root.Material.theme = Material.Light
break
}
}
// Partial workaround for
// https://bugreports.qt.io/browse/QTBUG-86047
Material.accent: Material.color(Material.Orange)
onVisibilityChanged: {
if (root.visibility !== 2)
return
}
QCore.Settings {
id: settings
}
onClosing: close => {
close.accepted = false
if (App.screenPlayManager.activeWallpaperCounter === 0
&& App.screenPlayManager.activeWidgetsCounter === 0) {
App.exit()
}
const alwaysMinimize = settings.value("alwaysMinimize", null)
if (alwaysMinimize === null) {
console.error(
"Unable to retreive alwaysMinimize setting")
}
if (alwaysMinimize === "true") {
root.hide()
App.showDockIcon(false)
return
}
exitDialog.open()
}
Plausible { Plausible {
id: plausible id: plausible
@ -68,204 +92,9 @@ ApplicationWindow {
enabled: false enabled: false
} }
// Partial workaround for Loader {
// https://bugreports.qt.io/browse/QTBUG-86047 id: baseLoader
Material.accent: Material.color(Material.Orange) asynchronous: true
onVisibilityChanged: {
if (root.visibility !== 2)
return;
}
onClosing: close => {
close.accepted = false;
if (App.screenPlayManager.activeWallpaperCounter === 0 && App.screenPlayManager.activeWidgetsCounter === 0) {
App.exit();
}
const alwaysMinimize = settings.value("alwaysMinimize", null);
if (alwaysMinimize === null) {
console.error("Unable to retreive alwaysMinimize setting");
}
if (alwaysMinimize === "true") {
root.hide();
App.showDockIcon(false);
return;
}
exitDialog.open();
}
QCore.Settings {
id: settings
}
Navigation.ExitPopup {
id: exitDialog
applicationWindow: root
modalSource: content
}
Component.onCompleted: {
setTheme(App.settings.theme);
stackView.push("qrc:/qml/ScreenPlayApp/qml/Installed/InstalledView.qml", {
"sidebar": sidebar
});
if (!App.settings.silentStart) {
App.showDockIcon(true);
root.show();
}
App.installedListModel.reset();
}
Item {
id: noneContentItems
Util.SteamNotAvailable {
id: dialogSteam
modalSource: content
}
Util.MonitorConfiguration {
modalSource: content
}
Util.CriticalError {
window: root
modalSource: content
}
Monitors.MonitorsView {
id: monitors
modalSource: content
}
TrayIcon {
window: root
}
}
Connections {
function onThemeChanged(theme) {
setTheme(theme);
}
target: App.settings
}
Connections {
function onRequestNavigation(nav) {
switchPage(nav);
}
target: App.util
}
Connections {
function onRequestRaise() {
App.showDockIcon(true);
root.show();
}
function onActiveWidgetsCounterChanged() {
plausible.pageView("widget/count/" + App.screenPlayManager.activeWidgetsCounter);
}
function onActiveWallpaperCounterChanged() {
plausible.pageView("wallpaper/count/" + App.screenPlayManager.activeWallpaperCounter);
}
target: App.screenPlayManager
}
Item {
id: content
anchors.fill: parent anchors.fill: parent
StackView {
id: stackView
objectName: "stackView"
property int duration: 300
anchors {
top: nav.bottom
right: parent.right
bottom: parent.bottom
left: parent.left
}
replaceEnter: Transition {
OpacityAnimator {
from: 0
to: 1
duration: stackView.duration
easing.type: Easing.InOutQuart
}
ScaleAnimator {
from: 0.8
to: 1
duration: stackView.duration
easing.type: Easing.InOutQuart
}
}
replaceExit: Transition {
OpacityAnimator {
from: 1
to: 0
duration: stackView.duration
easing.type: Easing.InOutQuart
}
ScaleAnimator {
from: 1
to: 0.8
duration: stackView.duration
easing.type: Easing.InOutQuart
}
}
}
Connections {
function onSetSidebarActive(active) {
if (active)
sidebar.state = "active";
else
sidebar.state = "inactive";
}
function onSetNavigationItem(pos) {
if (pos === 0)
nav.onPageChanged("Create");
else
nav.onPageChanged("Workshop");
}
target: stackView.currentItem
ignoreUnknownSignals: true
}
Installed.Sidebar {
id: sidebar
objectName: "installedSidebar"
navHeight: nav.height
anchors {
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
Navigation.Navigation {
id: nav
modalSource: content
anchors {
top: parent.top
right: parent.right
left: parent.left
}
onChangePage: function (name) {
monitors.close();
switchPage(name);
}
}
} }
} }

202
ScreenPlay/qml/Base.qml Normal file
View File

@ -0,0 +1,202 @@
import QtQuick
import QtQuick.Controls
import ScreenPlayUtil as Util
import ScreenPlayApp 1.0
import "Monitors" as Monitors
import "Installed" as Installed
import "Navigation" as Navigation
import "Community" as Community
Item {
id: content
anchors.fill: parent
Component.onCompleted: {
stackView.push(
"qrc:/qml/ScreenPlayApp/qml/Installed/InstalledView.qml", {
"sidebar": sidebar
})
startTimer.start()
}
Timer {
id: startTimer
interval: 10
onTriggered: App.installedListModel.reset()
}
function switchPage(name) {
if (nav.currentNavigationName === name) {
if (name === "Installed")
App.installedListModel.reset();
}
if (name === "Installed") {
stackView.replace("qrc:/qml/ScreenPlayApp/qml/Installed/InstalledView.qml", {
"sidebar": sidebar
});
return;
}
stackView.replace("qrc:/qml/ScreenPlayApp/qml/" + name + "/" + name + "View.qml", {
"modalSource": content
});
nav.setNavigation(name);
sidebar.state = "inactive";
}
Navigation.ExitPopup {
id: exitDialog
applicationWindow: root
modalSource: content
}
Item {
id: noneContentItems
Util.SteamNotAvailable {
id: dialogSteam
modalSource: content
}
Util.MonitorConfiguration {
modalSource: content
}
Util.CriticalError {
window: root
modalSource: content
}
Monitors.MonitorsView {
id: monitors
modalSource: content
}
TrayIcon {
window: root
}
}
Connections {
function onThemeChanged(theme) {
setTheme(theme);
}
target: App.settings
}
Connections {
function onRequestNavigation(nav) {
switchPage(nav);
}
target: App.util
}
Connections {
function onRequestRaise() {
App.showDockIcon(true);
root.show();
}
function onActiveWidgetsCounterChanged() {
plausible.pageView("widget/count/" + App.screenPlayManager.activeWidgetsCounter);
}
function onActiveWallpaperCounterChanged() {
plausible.pageView("wallpaper/count/" + App.screenPlayManager.activeWallpaperCounter);
}
target: App.screenPlayManager
}
StackView {
id: stackView
objectName: "stackView"
property int duration: 300
anchors {
top: nav.bottom
right: parent.right
bottom: parent.bottom
left: parent.left
}
replaceEnter: Transition {
OpacityAnimator {
from: 0
to: 1
duration: stackView.duration
easing.type: Easing.InOutQuart
}
ScaleAnimator {
from: 0.8
to: 1
duration: stackView.duration
easing.type: Easing.InOutQuart
}
}
replaceExit: Transition {
OpacityAnimator {
from: 1
to: 0
duration: stackView.duration
easing.type: Easing.InOutQuart
}
ScaleAnimator {
from: 1
to: 0.8
duration: stackView.duration
easing.type: Easing.InOutQuart
}
}
}
Connections {
function onSetSidebarActive(active) {
if (active)
sidebar.state = "active";
else
sidebar.state = "inactive";
}
function onSetNavigationItem(pos) {
if (pos === 0)
nav.onPageChanged("Create");
else
nav.onPageChanged("Workshop");
}
target: stackView.currentItem
ignoreUnknownSignals: true
}
Installed.Sidebar {
id: sidebar
objectName: "installedSidebar"
navHeight: nav.height
anchors {
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
Navigation.Navigation {
id: nav
modalSource: content
anchors {
top: parent.top
right: parent.right
left: parent.left
}
onChangePage: function (name) {
monitors.close();
switchPage(name);
}
}
}

View File

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
TabButton { TabButton {
id: control id: control

View File

@ -4,7 +4,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -5,7 +5,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Layouts import QtQuick.Layouts
import QtQml.XmlListModel import QtQml.XmlListModel
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Rectangle { Rectangle {

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Item { Item {

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Item { Item {

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Item { Item {

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Item { Item {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls.Material
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
WizardPage { WizardPage {

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
WizardPage { WizardPage {

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
WizardPage { WizardPage {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls.Material
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
WizardPage { WizardPage {

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Dialogs import QtQuick.Dialogs
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
import "../../" import "../../"

View File

@ -4,7 +4,7 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: wrapperError id: wrapperError

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Dialogs import QtQuick.Dialogs
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Item { Item {

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Item { Item {

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
WizardPage { WizardPage {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls.Material
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
WizardPage { WizardPage {

View File

@ -4,7 +4,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
WizardPage { WizardPage {

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Window import QtQuick.Window
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
FocusScope { FocusScope {
id: root id: root

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Item { Item {

View File

@ -7,7 +7,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import QtCore as QCore import QtCore as QCore
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Item { Item {

View File

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Item { Item {

View File

@ -3,7 +3,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Item { Item {

View File

@ -6,7 +6,7 @@ import QtQuick.Dialogs
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
import "../Monitors" import "../Monitors"

View File

@ -4,7 +4,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
ColumnLayout { ColumnLayout {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Rectangle { Rectangle {
id: root id: root

View File

@ -2,7 +2,7 @@ import QtQuick
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Item { Item {

View File

@ -5,7 +5,7 @@ import QtQuick.Layouts
import QtQuick.Dialogs import QtQuick.Dialogs
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Util.Popup { Util.Popup {
@ -142,7 +142,7 @@ Util.Popup {
font.family: App.settings.font font.family: App.settings.font
enabled: App.screenPlayManager.activeWallpaperCounter > 0 enabled: App.screenPlayManager.activeWallpaperCounter > 0
onClicked: { onClicked: {
if (!App.screenPlayManager.removeAllWallpapers()) if (!App.screenPlayManager.removeAllWallpapers(true))
print("Unable to close all wallpaper!"); print("Unable to close all wallpaper!");
root.close(); root.close();
} }

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Rectangle { Rectangle {
id: root id: root

View File

@ -6,7 +6,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects

View File

@ -6,7 +6,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Rectangle { Rectangle {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: settingsBool id: settingsBool

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: settingsButton id: settingsButton

View File

@ -1,7 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlay
import ScreenPlayApp import ScreenPlayApp
Control { Control {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: settingsHeader id: settingsHeader

View File

@ -6,7 +6,6 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil import ScreenPlayUtil
Item { Item {
@ -200,7 +199,8 @@ Item {
} }
} }
onActivated: { onActivated: {
App.settings.setLanguage(settingsLanguage.comboBox.currentValue); let language = settingsLanguage.comboBox.currentValue
App.settings.setLanguage(language);
App.settings.retranslateUI(); App.settings.retranslateUI();
} }
} }

View File

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Window import QtQuick.Window
import Qt.labs.platform import Qt.labs.platform
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
SystemTrayIcon { SystemTrayIcon {
id: root id: root

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlay
import ScreenPlayWorkshop import ScreenPlayWorkshop
Item { Item {

View File

@ -1,18 +1,24 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only // SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#include "ScreenPlay/app.h" #include "ScreenPlay/app.h"
#include <QDir>
#include <QElapsedTimer>
#include <QGuiApplication>
#include <QIcon>
#include <QObject>
#include <QProcessEnvironment>
#include <QQuickStyle>
#include <QStringList>
#include <QUrl>
#include <QVersionNumber>
#include <QtGlobal>
#include <QtSvg>
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
#include "ScreenPlayUtil/macutils.h" #include "ScreenPlayUtil/macutils.h"
#endif #endif
#include "ScreenPlay/CMakeVariables.h"
#include "ScreenPlayUtil/steamenumsgenerated.h"
#include "app.h"
#include <QGuiApplication>
#include <QProcessEnvironment>
#include <QQuickStyle>
#include <QVersionNumber>
namespace ScreenPlay { namespace ScreenPlay {
/*! /*!
@ -32,25 +38,6 @@ namespace ScreenPlay {
\brief The App class contains all members for ScreenPlay. \brief The App class contains all members for ScreenPlay.
*/ */
/*!
\brief Constructor creates and holds all classes used by ScreenPlay via unique_ptr or
shared_ptr.
*/
App::App()
: QObject(nullptr)
{
QGuiApplication::setWindowIcon(QIcon(":/qml/ScreenPlayApp/assets/icons/app.ico"));
QGuiApplication::setOrganizationName("ScreenPlay");
QGuiApplication::setOrganizationDomain("screen-play.app");
QGuiApplication::setApplicationName("ScreenPlay");
QGuiApplication::setApplicationVersion(QString(SCREENPLAY_VERSION));
QGuiApplication::setQuitOnLastWindowClosed(false);
// ScreenPlayManager first to check if another ScreenPlay Instace is running
m_screenPlayManager = std::make_unique<ScreenPlayManager>();
m_isAnotherScreenPlayInstanceRunning = m_screenPlayManager->isAnotherScreenPlayInstanceRunning();
}
/*! /*!
\brief Used for initialization after the constructor. The sole purpose is to check if \brief Used for initialization after the constructor. The sole purpose is to check if
another ScreenPlay instance is running and then quit early. This is also because we cannot another ScreenPlay instance is running and then quit early. This is also because we cannot
@ -77,6 +64,7 @@ void App::init()
using std::make_shared, std::make_unique; using std::make_shared, std::make_unique;
m_screenPlayManager = make_unique<ScreenPlayManager>();
m_globalVariables = make_shared<GlobalVariables>(); m_globalVariables = make_shared<GlobalVariables>();
m_monitorListModel = make_shared<MonitorListModel>(); m_monitorListModel = make_shared<MonitorListModel>();
m_util = make_unique<Util>(); m_util = make_unique<Util>();
@ -84,7 +72,6 @@ void App::init()
m_settings = make_shared<Settings>(m_globalVariables); m_settings = make_shared<Settings>(m_globalVariables);
m_installedListModel = make_shared<InstalledListModel>(m_globalVariables, m_settings); m_installedListModel = make_shared<InstalledListModel>(m_globalVariables, m_settings);
m_installedListFilter = make_shared<InstalledListFilter>(m_installedListModel); m_installedListFilter = make_shared<InstalledListFilter>(m_installedListModel);
m_mainWindowEngine = make_unique<QQmlApplicationEngine>();
// Only create anonymousTelemetry if user did not disallow! // Only create anonymousTelemetry if user did not disallow!
if (m_settings->anonymousTelemetry()) { if (m_settings->anonymousTelemetry()) {
@ -114,7 +101,7 @@ void App::init()
// When the installed storage path changed // When the installed storage path changed
QObject::connect(m_settings.get(), &Settings::resetInstalledListmodel, m_installedListModel.get(), &InstalledListModel::reset); QObject::connect(m_settings.get(), &Settings::resetInstalledListmodel, m_installedListModel.get(), &InstalledListModel::reset);
QObject::connect(m_settings.get(), &Settings::requestRetranslation, m_mainWindowEngine.get(), &QQmlEngine::retranslate); QObject::connect(m_settings.get(), &Settings::requestRetranslation, this, &App::requestRetranslation);
m_settings->setupLanguage(); m_settings->setupLanguage();
QObject::connect(m_globalVariables.get(), &GlobalVariables::localStoragePathChanged, this, [this](QUrl localStoragePath) { QObject::connect(m_globalVariables.get(), &GlobalVariables::localStoragePathChanged, this, [this](QUrl localStoragePath) {
@ -122,9 +109,6 @@ void App::init()
m_settings->setqSetting("ScreenPlayContentPath", localStoragePath.toString()); m_settings->setqSetting("ScreenPlayContentPath", localStoragePath.toString());
}); });
// Init after we have the paths from settings
m_installedListModel->init();
auto* guiAppInst = dynamic_cast<QGuiApplication*>(QGuiApplication::instance()); auto* guiAppInst = dynamic_cast<QGuiApplication*>(QGuiApplication::instance());
// Set visible if the -silent parameter was not set // Set visible if the -silent parameter was not set
@ -133,16 +117,15 @@ void App::init()
settings()->setSilentStart(true); settings()->setSilentStart(true);
} }
qmlRegisterSingletonInstance("ScreenPlay", 1, 0, "App", this);
m_mainWindowEngine->addImportPath(guiAppInst->applicationDirPath() + "/qml");
guiAppInst->addLibraryPath(guiAppInst->applicationDirPath() + "/qml");
QQuickStyle::setStyle("Material");
m_mainWindowEngine->load(QUrl(QStringLiteral("qrc:/qml/ScreenPlayApp/main.qml")));
// Must be called last to display a error message on startup by the qml engine // Must be called last to display a error message on startup by the qml engine
m_screenPlayManager->init(m_globalVariables, m_monitorListModel, m_settings); m_screenPlayManager->init(m_globalVariables, m_monitorListModel, m_settings);
QObject::connect(m_monitorListModel.get(), &MonitorListModel::monitorConfigurationChanged, m_screenPlayManager.get(), &ScreenPlayManager::removeAllWallpapers);
QObject::connect(
m_monitorListModel.get(),
&MonitorListModel::monitorConfigurationChanged,
m_screenPlayManager.get(), [this]() {
m_screenPlayManager->removeAllWallpapers(true);
});
} }
QString App::version() const QString App::version() const
@ -156,18 +139,13 @@ QString App::version() const
*/ */
void App::exit() void App::exit()
{ {
m_screenPlayManager->removeAllWallpapers(); m_screenPlayManager->removeAllWallpapers(false);
m_screenPlayManager->removeAllWidgets(); m_screenPlayManager->removeAllWidgets(false);
// Must be called inside a separate event loop otherwise we // Must be called inside a separate event loop otherwise we
// would kill the qml engine while it is calling this function. // would kill the qml engine while it is calling this function.
// A single shot timer is a handy woraround for this. // A single shot timer is a handy woraround for this.
QTimer::singleShot(0, this, [this]() { QTimer::singleShot(0, this, [this]() {
auto* appInst = QGuiApplication::instance(); emit requestExit();
// We must ensure that we kill the qml engine first
// before we destory the rest of the app
m_mainWindowEngine->clearSingletons();
m_mainWindowEngine.reset();
appInst->quit();
}); });
} }
@ -303,20 +281,6 @@ void App::setInstalledListFilter(InstalledListFilter* installedListFilter)
m_installedListFilter.reset(installedListFilter); m_installedListFilter.reset(installedListFilter);
emit installedListFilterChanged(m_installedListFilter.get()); emit installedListFilterChanged(m_installedListFilter.get());
} }
/*!
\property App::mainWindowEngine
\brief .
.
*/
void App::setMainWindowEngine(QQmlApplicationEngine* mainWindowEngine)
{
if (m_mainWindowEngine.get() == mainWindowEngine)
return;
m_mainWindowEngine.reset(mainWindowEngine);
emit mainWindowEngineChanged(m_mainWindowEngine.get());
}
/*! /*!
\property App::wizards \property App::wizards
\brief . \brief .
@ -331,6 +295,24 @@ void App::setWizards(Wizards* wizards)
m_wizards.reset(wizards); m_wizards.reset(wizards);
emit wizardsChanged(m_wizards.get()); emit wizardsChanged(m_wizards.get());
} }
QQmlEngine* App::engine() const
{
return m_engine;
}
void App::setEngine(QQmlEngine* engine)
{
m_engine = engine;
if (!m_engine) {
qFatal("QQmlEngine not set");
}
QObject::connect(
m_settings.get(),
&Settings::requestRetranslation,
m_engine,
&QQmlEngine::retranslate);
}
} }
#include "moc_app.cpp" #include "moc_app.cpp"

View File

@ -0,0 +1,59 @@
#include "ScreenPlay/applicationengine.h"
#include "ScreenPlay/CMakeVariables.h"
#include "ScreenPlay/app.h"
#include "ScreenPlay/applicationengine.h"
#include <QIcon>
#include <QQuickStyle>
namespace ScreenPlay {
ApplicationEngine::ApplicationEngine(QObject* parent)
: QQmlApplicationEngine { parent }
{
QGuiApplication::setWindowIcon(QIcon(":/qml/ScreenPlayApp/assets/icons/app.ico"));
QGuiApplication::setOrganizationName("ScreenPlay");
QGuiApplication::setOrganizationDomain("screen-play.app");
QGuiApplication::setApplicationName("ScreenPlay");
QGuiApplication::setApplicationVersion(QString(SCREENPLAY_VERSION));
QGuiApplication::setQuitOnLastWindowClosed(false);
}
/*!
\brief Checks if another ScreenPlay instance is running by trying to connect to a pipe
with the name ScreenPlay.
If successful we send a raise command and quit via m_isAnotherScreenPlayInstanceRunning = true.
*/
bool ScreenPlay::ApplicationEngine::isAnotherScreenPlayInstanceRunning()
{
QLocalSocket socket;
socket.connectToServer("ScreenPlay", QIODeviceBase::ExistingOnly);
// If we cannot connect to a running ScreenPlay
// pipe we are alone
if (!socket.isOpen()) {
socket.close();
return false;
}
qInfo("Another ScreenPlay app is already running!");
QByteArray msg = "command=requestRaise";
socket.write(msg);
socket.waitForBytesWritten(500);
socket.close();
return true;
}
void ApplicationEngine::init()
{
auto* guiAppInst = dynamic_cast<QGuiApplication*>(QGuiApplication::instance());
addImportPath(guiAppInst->applicationDirPath() + "/qml");
guiAppInst->addLibraryPath(guiAppInst->applicationDirPath() + "/qml");
QQuickStyle::setStyle("Material");
load(QUrl(QStringLiteral("qrc:/qml/ScreenPlayApp/main.qml")));
App* singleton = singletonInstance<App*>("ScreenPlayApp", "App");
singleton->setEngine(this);
}
}

View File

@ -13,7 +13,7 @@ namespace ScreenPlay {
/*! /*!
\brief Constructs the global variabls. \brief Constructs the global variabls.
*/ */
ScreenPlay::GlobalVariables::GlobalVariables(QObject* parent) GlobalVariables::GlobalVariables(QObject* parent)
: QObject(parent) : QObject(parent)
{ {
setLocalSettingsPath(QUrl { QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) }); setLocalSettingsPath(QUrl { QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) });
@ -71,6 +71,13 @@ void GlobalVariables::setGodotEditorExecutablePath(QUrl godotEditorExecutablePat
emit godotEditorExecutablePathChanged(m_godotEditorExecutablePath); emit godotEditorExecutablePathChanged(m_godotEditorExecutablePath);
} }
void GlobalVariables::setVersion(Version version)
{
if (m_version == version)
return;
m_version = version;
emit versionChanged(m_version);
}
} }
#include "moc_globalvariables.cpp" #include "moc_globalvariables.cpp"

View File

@ -23,12 +23,6 @@ ScreenPlayManager::ScreenPlayManager(
QObject* parent) QObject* parent)
: QObject { parent } : QObject { parent }
{ {
if (checkIsAnotherScreenPlayInstanceRunning()) {
m_isAnotherScreenPlayInstanceRunning = true;
return;
}
m_server = std::make_unique<QLocalServer>(); m_server = std::make_unique<QLocalServer>();
QObject::connect(m_server.get(), &QLocalServer::newConnection, this, &ScreenPlayManager::newConnection); QObject::connect(m_server.get(), &QLocalServer::newConnection, this, &ScreenPlayManager::newConnection);
@ -47,29 +41,6 @@ ScreenPlayManager::ScreenPlayManager(
}); });
} }
/*!
\brief Checks if another ScreenPlay instance is running by trying to connect to a pipe
with the name ScreenPlay.
If successful we send a raise command and quit via m_isAnotherScreenPlayInstanceRunning = true.
*/
bool ScreenPlayManager::checkIsAnotherScreenPlayInstanceRunning()
{
QLocalSocket socket;
socket.connectToServer("ScreenPlay");
if (!socket.isOpen()) {
socket.close();
return false;
}
qInfo("Another ScreenPlay app is already running!");
QByteArray msg = "command=requestRaise";
socket.write(msg);
socket.waitForBytesWritten(500);
socket.close();
return true;
}
/*! /*!
\brief Inits this class instead of init in the constructor. This is because we need to check \brief Inits this class instead of init in the constructor. This is because we need to check
first if another ScreenPlay instance is running. If it is not the case we call this function. first if another ScreenPlay instance is running. If it is not the case we call this function.
@ -227,11 +198,11 @@ bool ScreenPlayManager::createWidget(
/*! /*!
\brief Removes all wallpaper entries in the profiles.json. \brief Removes all wallpaper entries in the profiles.json.
*/ */
bool ScreenPlayManager::removeAllWallpapers() bool ScreenPlayManager::removeAllWallpapers(bool saveToProfile)
{ {
if (m_screenPlayWallpapers.empty()) { if (m_screenPlayWallpapers.empty()) {
qWarning() << "Trying to remove all Wallpapers while m_screenPlayWallpapers is not empty. Count: " << m_screenPlayWallpapers.size(); qWarning() << "Trying to remove all Wallpapers while m_screenPlayWallpapers is not empty.";
return false; return false;
} }
@ -247,6 +218,7 @@ bool ScreenPlayManager::removeAllWallpapers()
} }
} }
if (saveToProfile)
emit requestSaveProfiles(); emit requestSaveProfiles();
return true; return true;
@ -255,10 +227,10 @@ bool ScreenPlayManager::removeAllWallpapers()
/*! /*!
\brief Removes all widgets and resets the activeWidgetCounter to 0. \brief Removes all widgets and resets the activeWidgetCounter to 0.
*/ */
bool ScreenPlayManager::removeAllWidgets() bool ScreenPlayManager::removeAllWidgets(bool saveToProfile)
{ {
if (m_screenPlayWidgets.empty()) { if (m_screenPlayWidgets.empty()) {
qWarning() << "Trying to remove all Widgets while m_screenPlayWidgets is empty. Count: " << m_screenPlayWidgets.size(); qWarning() << "Trying to remove all Widgets while m_screenPlayWidgets is empty.";
return false; return false;
} }
@ -274,6 +246,7 @@ bool ScreenPlayManager::removeAllWidgets()
} }
} }
if (saveToProfile)
emit requestSaveProfiles(); emit requestSaveProfiles();
return true; return true;
@ -557,9 +530,9 @@ bool ScreenPlayManager::loadProfiles()
} }
std::optional<QVersionNumber> version = util.getVersionNumberFromString(configObj->value("version").toString()); std::optional<QVersionNumber> version = util.getVersionNumberFromString(configObj->value("version").toString());
QVersionNumber requiredVersion { 1, 0, 0 };
if (version && *version != m_globalVariables->version()) { if (version && *version != requiredVersion) {
qWarning() << "Version missmatch fileVersion: " << version->toString() << "m_version: " << m_globalVariables->version().toString(); qWarning() << "Version missmatch fileVersion: " << version->toString() << "m_version: " << requiredVersion.toString();
return false; return false;
} }

View File

@ -302,7 +302,7 @@ bool Settings::retranslateUI()
QString langCode = fixLanguageCode(QVariant::fromValue(language()).toString()); QString langCode = fixLanguageCode(QVariant::fromValue(language()).toString());
QFile tsFile; QFile tsFile;
const QString qmPath = QGuiApplication::applicationDirPath() + "/translations/ScreenPlay_" + langCode + ".qm"; const QString qmPath = QGuiApplication::applicationDirPath() + "/assets/translations/ScreenPlay_" + langCode + ".qm";
if (tsFile.exists(qmPath)) { if (tsFile.exists(qmPath)) {
if (!m_translator.load(qmPath)) { if (!m_translator.load(qmPath)) {
qWarning() << "Unable to load translation file: " << qmPath; qWarning() << "Unable to load translation file: " << qmPath;

View File

@ -10,14 +10,18 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QGuiApplication> #include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem> #include <QQuickItem>
#include <QQuickWindow>
#include <QtTest> #include <QtTest>
#include <QQmlEngineExtensionPlugin>
Q_IMPORT_QML_PLUGIN(ScreenPlayAppPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayAppPlugin)
Q_IMPORT_QML_PLUGIN(ScreenPlayUtilPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayUtilPlugin)
#ifdef SCREENPLAY_STEAM #ifdef SCREENPLAY_STEAM
Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin) Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin)
#endif #endif
class ScreenPlayTest : public QObject { class ScreenPlayTest : public QObject {
Q_OBJECT Q_OBJECT
@ -26,7 +30,7 @@ private slots:
{ {
app.init(); app.init();
m_window = qobject_cast<QQmlApplicationEngine*>(app.mainWindowEngine()->rootObjects().first()); // m_window = qobject_cast<QQmlApplicationEngine*>(app.mainWindowEngine()->rootObjects().first());
m_window->addImportPath(QGuiApplication::instance()->applicationDirPath() + "/qml"); m_window->addImportPath(QGuiApplication::instance()->applicationDirPath() + "/qml");
QVERIFY(m_window); QVERIFY(m_window);

View File

@ -5,7 +5,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Dialog { Dialog {
id: root id: root

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import QtQuick.Window import QtQuick.Window
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Util.Dialog { Util.Dialog {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
Util.Dialog { Util.Dialog {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Dialogs import QtQuick.Dialogs
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
/*! /*!
\qmltype Image Selector \qmltype Image Selector

View File

@ -1,7 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -1,7 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Text { Text {
text: qsTr("Headline Section") text: qsTr("Headline Section")

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Dialogs import QtQuick.Dialogs
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
/*! /*!
\qmltype Image Selector \qmltype Image Selector

View File

@ -3,7 +3,7 @@ import QtQuick.Controls.Material 2.0 as QQCM
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls as QQC import QtQuick.Controls as QQC
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
ColumnLayout { ColumnLayout {
id: root id: root

View File

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: tag id: tag

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -4,7 +4,7 @@ import QtQuick.Controls.Material
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
ColumnLayout { ColumnLayout {
id: root id: root

View File

@ -254,7 +254,9 @@ void LoggingHandler::writeToConsole(QtMsgType type, const QMessageLogContext& co
fmt::styled(now.toStdString(), fmt::emphasis::bold), fmt::styled(now.toStdString(), fmt::emphasis::bold),
fmt::styled(typeIndicator.toStdString(), fg(color)), fmt::styled(typeIndicator.toStdString(), fg(color)),
message.toStdString(), message.toStdString(),
context.file, // Using context.file (char*) directly results
// in a runtime crash in release
QString::fromUtf8(context.file).toStdString(),
line); line);
} }
} }

View File

@ -4,7 +4,7 @@ import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import ScreenPlayApp import ScreenPlayApp
import ScreenPlay
Item { Item {
id: root id: root

View File

@ -5,7 +5,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import ScreenPlayWorkshop import ScreenPlayWorkshop
import ScreenPlayUtil import ScreenPlayUtil
import ScreenPlay
import ScreenPlayApp import ScreenPlayApp
Popup { Popup {

View File

@ -3,7 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Layouts import QtQuick.Layouts
import ScreenPlay
Item { Item {
id: root id: root