1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-10-06 09:17:07 +02:00

Merge commit 'db4a7c7391f0a8dc80a7c9b282b4a531efc6454c' into qt6-kde

This commit is contained in:
Elias Steurer 2021-11-14 19:14:43 +01:00
commit 20fa5de37d
50 changed files with 227 additions and 5744 deletions

View File

@ -9,7 +9,7 @@ function(qt_update_translations SOURCE_PATH TS_FILES)
foreach(_ts_file ${TS_FILES}) foreach(_ts_file ${TS_FILES})
message(STATUS "Update Translation: ${_ts_file}") message(STATUS "Update Translation: ${_ts_file}")
execute_process(COMMAND ${LUPDATE_EXECUTABLE} -noobsolete -recursive ${SOURCE_PATH} -ts ${_ts_file} OUTPUT_QUIET) execute_process(COMMAND ${LUPDATE_EXECUTABLE} -noobsolete -locations none -recursive ${SOURCE_PATH} -ts ${_ts_file} OUTPUT_QUIET)
execute_process(COMMAND ${LRELEASE_EXECUTABLE} ${_ts_file} OUTPUT_QUIET) execute_process(COMMAND ${LRELEASE_EXECUTABLE} ${_ts_file} OUTPUT_QUIET)
endforeach() endforeach()

View File

@ -56,7 +56,7 @@ execute_process(
OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
add_compile_definitions(COMPILE_INFO="${BUILD_DATE} + ${GIT_COMMIT_HASH}") add_compile_definitions(COMPILE_INFO="Build Date: ${BUILD_DATE}. Git Hash: ${GIT_COMMIT_HASH}. ")
add_compile_definitions(SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") add_compile_definitions(SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
add_compile_definitions(SCREENPLAY_STEAM="${SCREENPLAY_STEAM}") add_compile_definitions(SCREENPLAY_STEAM="${SCREENPLAY_STEAM}")
@ -76,6 +76,9 @@ add_subdirectory(CMake)
if(${SCREENPLAY_STEAM}) if(${SCREENPLAY_STEAM})
add_subdirectory(ScreenPlayWorkshop) add_subdirectory(ScreenPlayWorkshop)
else()
# Only add target SteamSDKQtEnums
add_subdirectory(ScreenPlayWorkshop/SteamSDK)
endif() endif()
if(WIN32) if(WIN32)

View File

@ -5,7 +5,7 @@
``` bash ``` bash
git clone --recursive https://gitlab.com/kelteseth/ScreenPlay.git ScreenPlay git clone --recursive https://gitlab.com/kelteseth/ScreenPlay.git ScreenPlay
``` ```
4. Download the latest __Qt 5.15.x__ for you platform. Earlier versions are not supported! 4. Download the latest __Qt 6.2.x__ for you platform. Earlier versions are not supported!
1. [Install instructions Windows](#windows) 1. [Install instructions Windows](#windows)
1. [Install instructions Linux](#linux) 1. [Install instructions Linux](#linux)
1. [Install instructions MacOSX](#macosx) 1. [Install instructions MacOSX](#macosx)
@ -15,10 +15,9 @@ cd Tools
py setup.py py setup.py
``` ```
* This will install these dependencies via __vcpkg__ * This will install these dependencies via __vcpkg__
* openSSL 1.1.1d * openSSL
* sentry-native * sentry-native
* doctest * doctest
* benchmark
* infoware * infoware
<div> <div>
@ -26,7 +25,7 @@ py setup.py
</div> </div>
5. Open __QtCreator__ and open the settings `Tools -> Options` 5. Open __QtCreator__ and open the settings `Tools -> Options`
6. Clone an existing kit like `Qt 6.2.0 MSVC2019 64bit` and add `ScreenPlay` to the new kit name 6. Clone an existing kit like `Qt 6.2.1 MSVC2019 64bit` and add `ScreenPlay` to the new kit name
5. Edit CMake variables amd add CMAKE_TOOLCHAIN_FILE and VCPKG_TARGET_TRIPLET 5. Edit CMake variables amd add CMAKE_TOOLCHAIN_FILE and VCPKG_TARGET_TRIPLET
* `Kits -> <Your_Kit> -> CMake Configuration` * `Kits -> <Your_Kit> -> CMake Configuration`
@ -54,9 +53,9 @@ VCPKG_TARGET_TRIPLET:STRING=x64-osx
1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer) 1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer)
- Install the Maintaince tool - Install the Maintaince tool
- Select the following features to install: - Select the following features to install:
- Qt 6.2.0 - Qt 6.2.1
- MSVC 2019 64-bit - MSVC 2019 64-bit
- ALL Additional Libraries - **ALL Additional Libraries**
- Qt Quick 3d - Qt Quick 3d
- Qt 5 Compatibility Module - Qt 5 Compatibility Module
- Qt Shader Tools - Qt Shader Tools
@ -80,9 +79,9 @@ sudo zypper install -t pattern devel_basis
1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer) 1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer)
- Install the Maintaince tool - Install the Maintaince tool
- Select the following features to install: - Select the following features to install:
- Qt 6.2.0 - Qt 6.2.1
- GCC - GCC
- ALL Additional Libraries - **ALL Additional Libraries**
- Qt Quick 3d - Qt Quick 3d
- Qt 5 Compatibility Module - Qt 5 Compatibility Module
- Qt Shader Tools - Qt Shader Tools
@ -95,9 +94,9 @@ sudo zypper install -t pattern devel_basis
1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer) 1. [Download and install Qt 5 binary installer from qt.io](https://www.qt.io/download-qt-installer)
- Install the Maintaince tool - Install the Maintaince tool
- Select the following features to install: - Select the following features to install:
- Qt 6.2.0 - Qt 6.2.1
- Qt WebEngine - Qt WebEngine
- ALL Additional Libraries - **ALL Additional Libraries**
- Qt Quick 3d - Qt Quick 3d
- Qt 5 Compatibility Module - Qt 5 Compatibility Module
- Qt Shader Tools - Qt Shader Tools

View File

@ -1,15 +1,19 @@
# Overview # Overview
ScreenPlay consists of 5 projects: ScreenPlay consists of 7 projects:
1. **ScreenPlay** 1. **ScreenPlay executable**
* The main ScreenPlay App UI with Create, Installed, Community and Settings * The main ScreenPlay App UI with Create, Installed, Community and Settings.
2. **ScreenPlaySDK** 2. **ScreenPlayWallpaper executable**
* A SDK used internally in the ScreenPlayWallpaper and ScreenPlayWidget to talk to the main ScreenPlay app via QLocalsockets (Windows Pipes and Unix sockets)
3. **ScreenPlaySysInfo**
* A qml plugin to read CPU, GPU, Network and all sort of statisitcs
4. **ScreenPlayWallpaper**
* The Wallpaper executable that is used for displaying a single wallpaper. This uses ScreenPlaySDK to talk via QLocalsockets with the main ScreenPlayApp. * The Wallpaper executable that is used for displaying a single wallpaper. This uses ScreenPlaySDK to talk via QLocalsockets with the main ScreenPlayApp.
5. **ScreenPlayWidget** 3. **ScreenPlayWidget executable**
* The Widget executable that is used for displaying a single widget. This uses ScreenPlaySDK to talk via QLocalsockets with the main ScreenPlayApp . * The Widget executable that is used for displaying a single widget. This uses ScreenPlaySDK to talk via QLocalsockets with the main ScreenPlayApp.
4. **ScreenPlayUtil lib**
* Util function, like project.json loading, that are needed in ScreenPlay and Workshop plugin.
5. **ScreenPlaySDK lLib**
* A SDK used internally in the ScreenPlayWallpaper and ScreenPlayWidget to talk to the main ScreenPlay app via QLocalsockets (Windows Pipes and Unix sockets).
6. **ScreenPlaySysInfo lib**
* A qml plugin to read CPU, GPU, Network and all sort of statisitcs.
7. **ScreenPlayWorkshop plugin**
* The Steam workshop plugin that is loaded at runtime.
![ProjectOverview.png](ProjectOverview.png) ![ProjectOverview.png](ProjectOverview.png)

View File

@ -206,7 +206,8 @@ target_link_libraries(
Qt6::Svg Qt6::Svg
Qt6::WebEngineQuick Qt6::WebEngineQuick
Qt6::WebEngineCore Qt6::WebEngineCore
${LibArchive_LIBRARIES}) ${LibArchive_LIBRARIES}
SteamSDKQtEnums)
if(${TESTS_ENABLED}) if(${TESTS_ENABLED})
add_executable(tst_ScreenPlay tests/tst_main.cpp) add_executable(tst_ScreenPlay tests/tst_main.cpp)

View File

@ -1,5 +1,7 @@
#include "app.h" #include "app.h"
#include "steam/steam_qt_enums_generated.h"
namespace ScreenPlay { namespace ScreenPlay {
/*! /*!
\module ScreenPlay \module ScreenPlay
@ -96,6 +98,16 @@ App::App()
qRegisterMetaType<MonitorListModel*>(); qRegisterMetaType<MonitorListModel*>();
qRegisterMetaType<ProfileListModel*>(); qRegisterMetaType<ProfileListModel*>();
// TODO: This is a workaround because I don't know how to
// init this in the ScreenPlayWorkshop plugin.
// Move to workshop plugin.
qmlRegisterUncreatableMetaObject(ScreenPlayWorkshopSteamEnums::staticMetaObject,
"WorkshopEnums",
1, 0,
"SteamEnums",
"Error: only enums");
// Registers the enums from globalvariables. // Registers the enums from globalvariables.
// Apparently this is the only way for qml to work // Apparently this is the only way for qml to work
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/ // https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/

View File

@ -478,7 +478,7 @@ Item {
SettingsButton { SettingsButton {
icon.source: "qrc:/assets/icons/icon_launch.svg" icon.source: "qrc:/assets/icons/icon_launch.svg"
headline: qsTr("Version") headline: qsTr("Version")
description: qsTr("ScreenPlay Build Version ") + ScreenPlay.settings.gitBuildHash description: qsTr("ScreenPlay Build Version \n") + ScreenPlay.settings.gitBuildHash
buttonText: qsTr("Open Changelog") buttonText: qsTr("Open Changelog")
onButtonPressed: Qt.openUrlExternally("https://gitlab.com/kelteseth/ScreenPlay/-/releases") onButtonPressed: Qt.openUrlExternally("https://gitlab.com/kelteseth/ScreenPlay/-/releases")
} }

View File

@ -1,6 +1,5 @@
import QtQuick import QtQuick
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import Workshop 1.0
Rectangle { Rectangle {
id: root id: root

View File

@ -4,6 +4,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Layouts import QtQuick.Layouts
import Workshop 1.0 import Workshop 1.0
import WorkshopEnums 1.0
import ScreenPlay 1.0 import ScreenPlay 1.0
import "upload/" import "upload/"

View File

@ -4,6 +4,7 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick.Layouts import QtQuick.Layouts
import Workshop 1.0 import Workshop 1.0
import WorkshopEnums 1.0
import ScreenPlay 1.0 import ScreenPlay 1.0
import "upload/" import "upload/"
import "../Common" as Common import "../Common" as Common

View File

@ -4,7 +4,8 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material import QtQuick.Controls.Material
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import Workshop import Workshop 1.0
import WorkshopEnums 1.0
Page { Page {

View File

@ -175,6 +175,11 @@ void ScreenPlayWallpaper::processError(QProcess::ProcessError error)
*/ */
bool ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& value, const bool save) bool ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QString& value, const bool save)
{ {
if (!m_connection) {
qWarning() << "Cannot set value for unconnected wallpaper!";
return false;
}
QJsonObject obj; QJsonObject obj;
obj.insert(key, value); obj.insert(key, value);

View File

@ -101,7 +101,8 @@ Settings::Settings(const std::shared_ptr<GlobalVariables>& globalVariables,
initInstalledPath(); initInstalledPath();
setupWidgetAndWindowPaths(); setupWidgetAndWindowPaths();
setGitBuildHash(COMPILE_INFO); const QString qtVersion = QString("Qt Version: %1.%2.%3").arg(QT_VERSION_MAJOR).arg(QT_VERSION_MINOR).arg(QT_VERSION_PATCH);
setGitBuildHash(COMPILE_INFO + qtVersion);
setSteamVersion(!(QString(SCREENPLAY_STEAM).compare("OFF", Qt::CaseInsensitive) ? false : true)); setSteamVersion(!(QString(SCREENPLAY_STEAM).compare("OFF", Qt::CaseInsensitive) ? false : true));
} }
@ -194,7 +195,7 @@ void Settings::restoreDefault(const QString& appConfigLocation, const QString& s
void Settings::initInstalledPath() void Settings::initInstalledPath()
{ {
//If empty use steam workshop location // If empty use steam workshop location
if (QString(m_qSettings.value("ScreenPlayContentPath").toString()).isEmpty()) { if (QString(m_qSettings.value("ScreenPlayContentPath").toString()).isEmpty()) {
/* /*
@ -267,8 +268,12 @@ bool Settings::retranslateUI()
QString langCode = fixLanguageCode(QVariant::fromValue(language()).toString()); QString langCode = fixLanguageCode(QVariant::fromValue(language()).toString());
QFile tsFile; QFile tsFile;
if (tsFile.exists(":/translations/ScreenPlay_" + langCode + ".qm")) { const QString qmPath = ":/translations/ScreenPlay_" + langCode + ".qm";
m_translator.load(":/translations/ScreenPlay_" + langCode + ".qm"); if (tsFile.exists(qmPath)) {
if (!m_translator.load(qmPath)) {
qWarning() << "Unable to load translation file: " << qmPath;
return false;
}
auto* app = static_cast<QApplication*>(QApplication::instance()); auto* app = static_cast<QApplication*>(QApplication::instance());
app->installTranslator(&m_translator); app->installTranslator(&m_translator);
emit requestRetranslation(); emit requestRetranslation();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,3 +26,8 @@ target_include_directories(
PRIVATE src/) PRIVATE src/)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core) target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core)
if(WIN32)
# Used for query windows monitor data
target_link_libraries(${PROJECT_NAME} PUBLIC shcore.lib)
endif()

View File

@ -33,6 +33,17 @@
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
#include <QtGlobal>
#if defined(Q_OS_WIN)
// Must be first!
#include <qt_windows.h>
#include "WinUser.h"
#include <ShellScalingApi.h>
#endif
#include "ScreenPlayUtil/contenttypes.h" #include "ScreenPlayUtil/contenttypes.h"
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
@ -41,6 +52,37 @@
#include <optional> #include <optional>
namespace ScreenPlayUtil { namespace ScreenPlayUtil {
#if defined(Q_OS_WIN)
struct WinMonitorStats {
std::vector<int> iMonitors;
std::vector<HMONITOR> hMonitors;
std::vector<HDC> hdcMonitors;
std::vector<RECT> rcMonitors;
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
std::vector<std::pair<UINT, UINT>> sizes;
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor,
LPARAM pData)
{
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
auto scaleFactor = DEVICE_SCALE_FACTOR::DEVICE_SCALE_FACTOR_INVALID;
GetScaleFactorForMonitor(hMon, &scaleFactor);
UINT x = 0;
UINT y = 0;
GetDpiForMonitor(hMon, MONITOR_DPI_TYPE::MDT_RAW_DPI, &x, &y);
pThis->sizes.push_back({ x, y });
pThis->scaleFactor.push_back(scaleFactor);
pThis->hMonitors.push_back(hMon);
pThis->hdcMonitors.push_back(hdc);
pThis->rcMonitors.push_back(*lprcMonitor);
pThis->iMonitors.push_back(pThis->hdcMonitors.size());
return TRUE;
}
WinMonitorStats() { EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); }
};
#endif
QJsonArray fillArray(const QVector<QString>& items); QJsonArray fillArray(const QVector<QString>& items);
ScreenPlay::SearchType::SearchType getSearchTypeFromInstalledType(const ScreenPlay::InstalledType::InstalledType type); ScreenPlay::SearchType::SearchType getSearchTypeFromInstalledType(const ScreenPlay::InstalledType::InstalledType type);
std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromString(const QString& type); std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromString(const QString& type);

View File

@ -233,7 +233,7 @@ std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromStri
{ {
using ScreenPlay::InstalledType::InstalledType; using ScreenPlay::InstalledType::InstalledType;
if (type.endsWith("Wallpaper")) { if (type.endsWith("Wallpaper", Qt::CaseInsensitive)) {
if (type.startsWith("video", Qt::CaseInsensitive)) { if (type.startsWith("video", Qt::CaseInsensitive)) {
return InstalledType::VideoWallpaper; return InstalledType::VideoWallpaper;
} }
@ -254,7 +254,7 @@ std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromStri
} }
} }
if (type.endsWith("Widget")) { if (type.endsWith("Widget", Qt::CaseInsensitive)) {
if (type.startsWith("qml", Qt::CaseInsensitive)) { if (type.startsWith("qml", Qt::CaseInsensitive)) {
return InstalledType::QMLWidget; return InstalledType::QMLWidget;
} }
@ -266,28 +266,27 @@ std::optional<ScreenPlay::InstalledType::InstalledType> getInstalledTypeFromStri
return std::nullopt; return std::nullopt;
} }
/*! /*!
\brief Maps the video codec type from a QString to an enum. Used for parsing the project.json. \brief Maps the video codec type from a QString to an enum. Used for parsing the project.json.
*/ */
std::optional<ScreenPlay::VideoCodec::VideoCodec> getVideoCodecFromString(const QString &type) std::optional<ScreenPlay::VideoCodec::VideoCodec> getVideoCodecFromString(const QString& type)
{ {
if(type.isEmpty()) if (type.isEmpty())
return std::nullopt; return std::nullopt;
if(type.contains("vp8",Qt::CaseInsensitive)) if (type.contains("vp8", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::VP8; return ScreenPlay::VideoCodec::VideoCodec::VP8;
if(type.contains("vp9",Qt::CaseInsensitive)) if (type.contains("vp9", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::VP9; return ScreenPlay::VideoCodec::VideoCodec::VP9;
if(type.contains("av1",Qt::CaseInsensitive)) if (type.contains("av1", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::AV1; return ScreenPlay::VideoCodec::VideoCodec::AV1;
if(type.contains("h264",Qt::CaseInsensitive)) if (type.contains("h264", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::H264; return ScreenPlay::VideoCodec::VideoCodec::H264;
if(type.contains("h265",Qt::CaseInsensitive)) if (type.contains("h265", Qt::CaseInsensitive))
return ScreenPlay::VideoCodec::VideoCodec::H264; return ScreenPlay::VideoCodec::VideoCodec::H264;
return std::nullopt; return std::nullopt;
@ -395,5 +394,4 @@ std::optional<QVector<int>> parseStringToIntegerList(const QString string)
return list; return list;
} }
} }

View File

@ -39,7 +39,7 @@ set(SOURCES ${SOURCES} main.cpp src/basewindow.cpp)
set(HEADER ${HEADER} src/basewindow.h) set(HEADER ${HEADER} src/basewindow.h)
set(QML # cmake-format: sortable set(QML # cmake-format: sortable
qml/GifWallpaper.qml qml/Test.qml qml/Wallpaper.qml qml/WebsiteWallpaper.qml qml/WebView.qml qml/MultimediaView.qml qml/MultimediaWebView.qml) qml/GifWallpaper.qml qml/Test.qml qml/Wallpaper.qml qml/WebsiteWallpaper.qml qml/MultimediaView.qml qml/MultimediaWebView.qml)
qt_add_resources(RESOURCES Resources.qrc) qt_add_resources(RESOURCES Resources.qrc)
@ -83,6 +83,5 @@ if(WIN32)
# Disable console window on Windows # Disable console window on Windows
# https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows # https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windows
set_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true) set_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true)
target_link_libraries(${PROJECT_NAME} PRIVATE shcore.lib)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/index.html ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/index.html COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/index.html ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/index.html COPYONLY)
endif() endif()

View File

@ -6,7 +6,7 @@ Item {
id: root id: root
anchors.fill: parent anchors.fill: parent
property bool loops: Wallpaper.loops property bool loops: Wallpaper.loops
property bool isWindows: Qt.platform === "windows" property bool isWindows: Qt.platform.os === "windows"
signal requestFadeIn signal requestFadeIn
MediaPlayer { MediaPlayer {

View File

@ -17,17 +17,24 @@ Rectangle {
if (Wallpaper.videoCodec === VideoCodec.Unknown) { if (Wallpaper.videoCodec === VideoCodec.Unknown) {
Wallpaper.terminate() Wallpaper.terminate()
} }
// macOS only supports h264 via the native Qt MM // macOS only supports h264 via the native Qt MM
if (Qt.platform === "osx" && (Wallpaper.videoCodec === VideoCodec.VP8 if (Qt.platform.os === "osx") {
|| Wallpaper.videoCodec === VideoCodec.VP9)) { if ((Wallpaper.videoCodec === VideoCodec.VP8
loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaWebView.qml" || Wallpaper.videoCodec === VideoCodec.VP9)) {
} else { loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaWebView.qml"
} else {
loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaView.qml"
}
}
if (Qt.platform.os === "windows") {
loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaView.qml" loader.source = "qrc:/ScreenPlayWallpaper/qml/MultimediaView.qml"
} }
fadeIn() fadeIn()
break break
case InstalledType.HTMLWallpaper: case InstalledType.HTMLWallpaper:
loader.setSource("qrc:/ScreenPlayWallpaper/qml/WebView.qml", { loader.setSource("qrc:/ScreenPlayWallpaper/qml/WebsiteWallpaper.qml", {
"url": Qt.resolvedUrl( "url": Qt.resolvedUrl(
Wallpaper.projectSourceFileAbsolute) Wallpaper.projectSourceFileAbsolute)
}) })
@ -100,7 +107,7 @@ Rectangle {
} }
// This function only gets called here (the same function // This function only gets called here (the same function
// is inside the WebView.qml) when the previous Wallpaper type // is inside the MultimediaWebView.qml) when the previous Wallpaper type
// was not a video // was not a video
function onReloadVideo(oldType) { function onReloadVideo(oldType) {
// We need to check if the old type // We need to check if the old type

View File

@ -1,154 +0,0 @@
import QtQuick
import QtWebEngine
import ScreenPlay.Enums.InstalledType 1.0
import ScreenPlayWallpaper 1.0
Item {
id: root
property alias url: webView.url
signal requestFadeIn
function getSetVideoCommand() {
// TODO 30:
// Currently wont work. Commit anyways til QtCreator and Qt work with js template literals
var src = ""
src += "var videoPlayer = document.getElementById('videoPlayer');"
src += "var videoSource = document.getElementById('videoSource');"
src += "videoSource.src = '" + Wallpaper.projectSourceFileAbsolute + "';"
src += "videoPlayer.load();"
src += "videoPlayer.volume = " + Wallpaper.volume + ";"
src += "videoPlayer.setAttribute('style', 'object-fit :" + Wallpaper.fillMode + ";');"
src += "videoPlayer.play();"
return src
}
Component.onCompleted: {
WebEngine.settings.localContentCanAccessFileUrls = true
WebEngine.settings.localContentCanAccessRemoteUrls = true
WebEngine.settings.allowRunningInsecureContent = true
WebEngine.settings.accelerated2dCanvasEnabled = true
WebEngine.settings.javascriptCanOpenWindows = false
WebEngine.settings.showScrollBars = false
WebEngine.settings.playbackRequiresUserGesture = false
WebEngine.settings.focusOnNavigationEnabled = true
}
WebEngineView {
id: webView
anchors.fill: parent
url: "qrc:/ScreenPlayWallpaper/index.html"
backgroundColor: "transparent"
onJavaScriptConsoleMessage:(lineNumber, message)=> print(lineNumber, message)
onLoadProgressChanged: {
if ((loadProgress === 100)) {
if (Wallpaper.type === InstalledType.VideoWallpaper)
webView.runJavaScript(root.getSetVideoCommand(),
function (result) {
requestFadeIn()
})
else
requestFadeIn()
}
}
}
Text {
id: txtVisualsPaused
text: qsTr("If you can read this, then the VisualsPaused optimization does not work on your system. You can fix this by disable this in: \n Settings -> Perfromance -> Pause wallpaper video rendering while another app is in the foreground ")
font.pointSize: 32
visible: false
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
anchors.centerIn: parent
width: parent.width * 0.8
color: "white"
}
Timer {
id: timerCover
interval: 300
onTriggered: {
webView.visible = !Wallpaper.visualsPaused
txtVisualsPaused.visible = Wallpaper.visualsPaused
}
}
Connections {
function onReloadVideo(oldType) {
webView.runJavaScript(root.getSetVideoCommand())
}
function onQmlExit() {
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;")
}
function onMutedChanged(muted) {
if (muted)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = 0;")
else
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + Wallpaper.volume + ";")
}
function onFillModeChanged(fillMode) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.setAttribute('style', 'object-fit :" + fillMode + ";');")
}
function onLoopsChanged(loops) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.loop = " + loops + ";")
}
function onVolumeChanged(volume) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.volume = " + volume + ";")
}
function onCurrentTimeChanged(currentTime) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.currentTime = "
+ currentTime + " * videoPlayer.duration;")
}
function onPlaybackRateChanged(playbackRate) {
if (webView.loadProgress === 100)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.playbackRate = " + playbackRate + ";")
}
function onVisualsPausedChanged(visualsPaused) {
if (visualsPaused) {
// Wait until Wallpaper animation is finsihed
timerCover.restart()
} else {
webView.visible = true
txtVisualsPaused.visible = false
}
}
function onIsPlayingChanged(isPlaying) {
if (webView.loadProgress === 100) {
if (isPlaying)
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.play();")
else
webView.runJavaScript(
"var videoPlayer = document.getElementById('videoPlayer'); videoPlayer.pause();")
}
}
target: Wallpaper
}
}

View File

@ -24,7 +24,7 @@ Item {
id: webView id: webView
anchors.fill: parent anchors.fill: parent
url: root.url url: Qt.resolvedUrl(root.url)
onJavaScriptConsoleMessage: print(lineNumber, message) onJavaScriptConsoleMessage: print(lineNumber, message)
onLoadProgressChanged: { onLoadProgressChanged: {
if ((loadProgress === 100)) if ((loadProgress === 100))

View File

@ -1,41 +1,8 @@
#include "winwindow.h" #include "winwindow.h"
#include "WinUser.h"
#include "qqml.h" #include "qqml.h"
#include <ShellScalingApi.h>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <windows.h>
struct WinMonitorStats {
std::vector<int> iMonitors;
std::vector<HMONITOR> hMonitors;
std::vector<HDC> hdcMonitors;
std::vector<RECT> rcMonitors;
std::vector<DEVICE_SCALE_FACTOR> scaleFactor;
std::vector<std::pair<UINT, UINT>> sizes;
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor,
LPARAM pData)
{
WinMonitorStats* pThis = reinterpret_cast<WinMonitorStats*>(pData);
auto scaleFactor = DEVICE_SCALE_FACTOR::DEVICE_SCALE_FACTOR_INVALID;
GetScaleFactorForMonitor(hMon, &scaleFactor);
UINT x = 0;
UINT y = 0;
GetDpiForMonitor(hMon, MONITOR_DPI_TYPE::MDT_RAW_DPI, &x, &y);
pThis->sizes.push_back({ x, y });
pThis->scaleFactor.push_back(scaleFactor);
pThis->hMonitors.push_back(hMon);
pThis->hdcMonitors.push_back(hdc);
pThis->rcMonitors.push_back(*lprcMonitor);
pThis->iMonitors.push_back(pThis->hdcMonitors.size());
return TRUE;
}
WinMonitorStats() { EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); }
};
/*! /*!
\brief Searches for the worker window for our window to parent to. \brief Searches for the worker window for our window to parent to.
@ -107,8 +74,8 @@ LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
if (type == QMouseEvent::Type::MouseButtonPress) { if (type == QMouseEvent::Type::MouseButtonPress) {
} }
QTimer::singleShot(100, [&]() { QTimer::singleShot(100, [&]() {
//auto eventPress = QMouseEvent(QMouseEvent::Type::MouseButtonPress, g_LastMousePosition, mouseButton, mouseButtons, {}); // auto eventPress = QMouseEvent(QMouseEvent::Type::MouseButtonPress, g_LastMousePosition, mouseButton, mouseButtons, {});
//qInfo() << mouseButton << QApplication::sendEvent(g_winGlobalHook, &eventPress) << g_globalOffset.x() << g_globalOffset.y(); // qInfo() << mouseButton << QApplication::sendEvent(g_winGlobalHook, &eventPress) << g_globalOffset.x() << g_globalOffset.y();
auto eventRelease = QMouseEvent(QMouseEvent::Type::MouseButtonRelease, g_LastMousePosition, mouseButton, mouseButtons, {}); auto eventRelease = QMouseEvent(QMouseEvent::Type::MouseButtonRelease, g_LastMousePosition, mouseButton, mouseButtons, {});
QApplication::sendEvent(g_winGlobalHook, &eventRelease); QApplication::sendEvent(g_winGlobalHook, &eventRelease);
}); });
@ -224,17 +191,6 @@ WinWindow::WinWindow(
qmlRegisterSingletonInstance<WinWindow>("ScreenPlayWallpaper", 1, 0, "Wallpaper", this); qmlRegisterSingletonInstance<WinWindow>("ScreenPlayWallpaper", 1, 0, "Wallpaper", this);
configureWindowGeometry(); configureWindowGeometry();
bool hasWindowScaling = false;
for (int i = 0; i < screens.count(); i++) {
if (getScaling(i) != 1) {
hasWindowScaling = true;
break;
}
}
if (hasWindowScaling) {
qInfo() << "Monitor with scaling detected!";
configureWindowGeometry();
}
// We do not support autopause for multi monitor wallpaper // We do not support autopause for multi monitor wallpaper
if (this->activeScreensList().length() == 1) { if (this->activeScreensList().length() == 1) {
@ -296,45 +252,27 @@ BOOL CALLBACK GetMonitorByIndex(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMo
*/ */
void WinWindow::setupWallpaperForOneScreen(int activeScreen) void WinWindow::setupWallpaperForOneScreen(int activeScreen)
{ {
const QRect screenRect = QApplication::screens().at(activeScreen)->geometry(); const QRect screenRect = QApplication::screens().at(activeScreen)->geometry();
const float scaling = 1; //getScaling(activeScreen);
for (int i = 0; i < QApplication::screens().count(); i++) {
// qInfo() << i << "scaling " << getScaling(i) << QApplication::screens().at(i)->geometry();
}
// qInfo() << activeScreen << "Monitor 0" << getScaling(0) << QApplication::screens().at(0)->geometry();
// qInfo() << activeScreen << "Monitor 1" << getScaling(1) << QApplication::screens().at(1)->geometry();
WinMonitorStats Monitors;
int width = std::abs(Monitors.rcMonitors[activeScreen].right - Monitors.rcMonitors[activeScreen].left);
int height = std::abs(Monitors.rcMonitors[activeScreen].top - Monitors.rcMonitors[activeScreen].bottom);
//qInfo() << "scaling " << scaling << width << height << " activeScreen " << activeScreen;
//qInfo() << "scaling " << scaling << screenRect.width() << screenRect.height() << " activeScreen " << activeScreen;
const int boderWidth = 2; const int boderWidth = 2;
const float scaling = getScaling(activeScreen);
const int borderOffset = -1; const int borderOffset = -1;
// Needs to be set like to this work. I do not know why...
if (!SetWindowPos(
m_windowHandle,
nullptr,
Monitors.rcMonitors[activeScreen].left + borderOffset,
Monitors.rcMonitors[activeScreen].top + borderOffset,
width + boderWidth,
height + boderWidth,
SWP_HIDEWINDOW)) {
qFatal("Could not set window pos");
}
if (!SetWindowPos( ScreenPlayUtil::WinMonitorStats Monitors;
m_windowHandle, const int width = std::abs(Monitors.rcMonitors[activeScreen].right - Monitors.rcMonitors[activeScreen].left);
nullptr, const int height = std::abs(Monitors.rcMonitors[activeScreen].top - Monitors.rcMonitors[activeScreen].bottom);
screenRect.x() + m_zeroPoint.x() + borderOffset, const int x = Monitors.rcMonitors[activeScreen].left + m_zeroPoint.x() + borderOffset;
screenRect.y() + m_zeroPoint.y() + borderOffset, const int y = Monitors.rcMonitors[activeScreen].top + m_zeroPoint.y() + borderOffset;
screenRect.width() * scaling + boderWidth, qInfo() << QString("Setup window activeScreen: %1 scaling: %2 x: %3 y: %4 width: %5 height: %6").arg(activeScreen).arg(scaling).arg(x).arg(y).arg(width).arg(height);
screenRect.height() * scaling + boderWidth,
SWP_HIDEWINDOW)) { {
qFatal("Could not set window pos"); // Must be called twice for some reason when window has scaling...
if (!SetWindowPos(m_windowHandle, nullptr, x, y, width, height, SWP_HIDEWINDOW)) {
qFatal("Could not set window pos");
}
if (!SetWindowPos(m_windowHandle, nullptr, x, y, width, height, SWP_HIDEWINDOW)) {
qFatal("Could not set window pos");
}
} }
if (SetParent(m_windowHandle, m_windowHandleWorker) == nullptr) { if (SetParent(m_windowHandle, m_windowHandleWorker) == nullptr) {
@ -407,44 +345,48 @@ bool WinWindow::searchWorkerWindowToParentTo()
} }
/*! /*!
\brief Reads the logicalDotsPerInch and mapps them to scaling factors. \brief Reads the physicalDotsPerInch and mapps them to scaling factors.
This is needed to detect if the user has different monitors with This is needed to detect if the user has different monitors with
different scaling factors. different scaling factors.
screen->logicalDotsPerInch() screen->physicalDotsPerInch()
100% -> 96 -> 1 100% -> 109 -> 1
125% -> 120 -> 1.25 125% -> 120 -> 1.25
150% -> 144 -> 1.5 150% -> 161 -> 1.5
... ...
*/ */
float WinWindow::getScaling(const int monitorIndex) float WinWindow::getScaling(const int monitorIndex)
{ {
QScreen* screen = QApplication::screens().at(monitorIndex); QScreen* screen = QApplication::screens().at(monitorIndex);
const int factor = screen->logicalDotsPerInch(); const int factor = screen->physicalDotsPerInch();
switch (factor) { switch (factor) {
case 96: case 72:
return 1; return 1;
case 120: case 107:
return 1.25;
case 144:
return 1.5; return 1.5;
case 168:
return 1.75; case 109:
case 192: return 1;
return 2; case 161:
case 216: return 1;
return 2.25;
case 240:
return 2.5;
case 288:
return 3;
case 336:
return 3.5;
default: default:
qWarning() << "Monitor with factor: " << factor << " detected! This is not supported!"; qWarning() << "Monitor with factor: " << factor << " detected! This is not supported!";
return 1; return 1;
} }
} }
/*!
\brief Returns true of at least one monitor has active scaling enabled.
*/
bool WinWindow::hasWindowScaling()
{
const auto screens = QApplication::screens();
for (int i = 0; i < screens.count(); i++) {
if (getScaling(i) != 1) {
return true;
}
}
return false;
}
/*! /*!
\brief Sets the size and the parent to the worker handle to be displayed behind the \brief Sets the size and the parent to the worker handle to be displayed behind the
@ -452,7 +394,7 @@ float WinWindow::getScaling(const int monitorIndex)
*/ */
void WinWindow::configureWindowGeometry() void WinWindow::configureWindowGeometry()
{ {
ShowWindow(m_windowHandle, SW_HIDE); setVisible(false);
if (!searchWorkerWindowToParentTo()) { if (!searchWorkerWindowToParentTo()) {
qFatal("No worker window found"); qFatal("No worker window found");

View File

@ -96,6 +96,7 @@ private:
bool searchWorkerWindowToParentTo(); bool searchWorkerWindowToParentTo();
void configureWindowGeometry(); void configureWindowGeometry();
float getScaling(const int monitorIndex); float getScaling(const int monitorIndex);
bool hasWindowScaling();
private slots: private slots:
void checkForFullScreenWindow(); void checkForFullScreenWindow();

View File

@ -1,4 +1,4 @@
project(workshopplugin LANGUAGES CXX) project(ScreenPlayWorkshop LANGUAGES CXX)
add_subdirectory(SteamSDK) add_subdirectory(SteamSDK)
@ -16,7 +16,6 @@ set(SOURCES
src/steamworkshopitem.cpp src/steamworkshopitem.cpp
src/workshop.cpp src/workshop.cpp
src/installedlistmodel.cpp src/installedlistmodel.cpp
src/screenplayworkshop_plugin.cpp
src/steamworkshop.cpp src/steamworkshop.cpp
src/steamworkshoplistmodel.cpp src/steamworkshoplistmodel.cpp
src/steamaccount.cpp src/steamaccount.cpp
@ -31,55 +30,35 @@ set(HEADER
src/workshop.h src/workshop.h
src/workshopitem.h src/workshopitem.h
src/installedlistmodel.h src/installedlistmodel.h
src/screenplayworkshop_plugin.h
src/steamworkshop.h src/steamworkshop.h
src/steamaccount.h src/steamaccount.h
src/steamqmlimageprovider.h) src/steamqmlimageprovider.h)
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADER})
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/workshop)
file(MAKE_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set_target_properties(${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set_target_properties(${PROJECT_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR})
set(STEAM_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/SteamSDK/redistributable_bin/") set(STEAM_LIB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/SteamSDK/redistributable_bin/")
if(WIN32) if(WIN32)
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/Workshop)
set(STEAM_LIB "${STEAM_LIB_PATH}/win64/steam_api64.lib") set(STEAM_LIB "${STEAM_LIB_PATH}/win64/steam_api64.lib")
set(STEAM_BIN "${STEAM_LIB_PATH}/win64/steam_api64.dll") set(STEAM_BIN "${STEAM_LIB_PATH}/win64/steam_api64.dll")
elseif(APPLE) elseif(APPLE)
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop)
set(STEAM_LIB "${STEAM_LIB_PATH}/osx/libsteam_api.dylib") set(STEAM_LIB "${STEAM_LIB_PATH}/osx/libsteam_api.dylib")
set(STEAM_BIN ${STEAM_LIB}) set(STEAM_BIN ${STEAM_LIB})
elseif(UNIX) elseif(UNIX)
set(WORKSHOP_PLUGIN_DIR ${CMAKE_BINARY_DIR}/bin/Workshop)
set(STEAM_LIB "${STEAM_LIB_PATH}/linux64/libsteam_api.so") set(STEAM_LIB "${STEAM_LIB_PATH}/linux64/libsteam_api.so")
set(STEAM_BIN ${STEAM_LIB}) set(STEAM_BIN ${STEAM_LIB})
endif() endif()
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick ${STEAM_LIB} ScreenPlayUtil SteamSDK) qt_add_qml_module(
${PROJECT_NAME}
OUTPUT_DIRECTORY ${WORKSHOP_PLUGIN_DIR}
URI "Workshop"
SOURCES ${SOURCES} ${HEADER}
VERSION
1.0)
if(APPLE) if(APPLE)
set(workshop_install_dir ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/Workshop)
add_custom_target(
build-time-make-directory
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${workshop_install_dir})
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMENT "Copying workshop plugin into ScreenPlay.app bundle"
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/Workshop/libworkshopplugin.dylib ${workshop_install_dir})
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMENT "Copying steam library into ScreenPlay.app bundle"
COMMAND ${CMAKE_COMMAND} -E copy ${STEAM_BIN} ${workshop_install_dir})
if(${SCREENPLAY_STEAM}) if(${SCREENPLAY_STEAM})
add_custom_command( add_custom_command(
TARGET ${PROJECT_NAME} TARGET ${PROJECT_NAME}
@ -87,11 +66,24 @@ if(APPLE)
COMMENT "Copying steam_appid.txt into ScreenPlay.app bundle. This is for development only!" COMMENT "Copying steam_appid.txt into ScreenPlay.app bundle. This is for development only!"
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt
${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/) ${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/)
endif()
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMENT "Copying libsteam_api.dylib into ScreenPlay.app bundle."
COMMAND ${CMAKE_COMMAND} -E copy ${STEAM_LIB}
${WORKSHOP_PLUGIN_DIR})
endif()
else() else()
if(${SCREENPLAY_STEAM}) if(${SCREENPLAY_STEAM})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/steam_appid.txt COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/steam_appid.txt ${CMAKE_BINARY_DIR}/bin/steam_appid.txt COPYONLY)
configure_file(${STEAM_BIN} ${CMAKE_BINARY_DIR}/bin/ COPYONLY) configure_file(${STEAM_BIN} ${CMAKE_BINARY_DIR}/bin/ COPYONLY)
endif() endif()
endif() endif()
# Needed by the automatic generated target missing includes
# https://github.com/qt/qtdeclarative/blob/7a7064e14f094e843e1ee832cc927e86f887621a/src/qml/Qt6QmlMacros.cmake#L2042
target_include_directories(${PROJECT_NAME} PUBLIC src/)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick ${STEAM_LIB} ScreenPlayUtil SteamSDK SteamSDKQtEnums)

View File

@ -50,11 +50,17 @@ set(HEADER
public/steam/steamps3params.h public/steam/steamps3params.h
public/steam/steamtypes.h public/steam/steamtypes.h
public/steam/steamuniverse.h public/steam/steamuniverse.h
# CUSTOM
public/steam/steam_qt_enums_generated.h
# ENDCUSTOM
) )
add_library(${PROJECT_NAME} STATIC ${HEADER})
target_include_directories(${PROJECT_NAME} PUBLIC public/) if(${SCREENPLAY_STEAM})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core) add_library(${PROJECT_NAME} STATIC ${HEADER})
target_include_directories(${PROJECT_NAME} PUBLIC public/)
target_link_libraries(${PROJECT_NAME})
endif()
# We allaways need the generated enums as a workaround to register these enums in app.cpp.
# Registering in the ScreenPlayWorkshop plugin does not work for some reason.
add_library(SteamSDKQtEnums STATIC public/steam/steam_qt_enums_generated.h)
target_include_directories(SteamSDKQtEnums PUBLIC public/)
target_link_libraries(SteamSDKQtEnums PRIVATE Qt6::Core)

View File

@ -19,6 +19,7 @@
#include <QVariantList> #include <QVariantList>
#include <QVector> #include <QVector>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include <QtQml>
#include "ScreenPlayUtil/projectfile.h" #include "ScreenPlayUtil/projectfile.h"
#include "ScreenPlayUtil/util.h" #include "ScreenPlayUtil/util.h"
@ -33,6 +34,7 @@ namespace ScreenPlayWorkshop {
class InstalledListModel : public QAbstractListModel { class InstalledListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(InstalledListModel)
Q_PROPERTY(QUrl absoluteStoragePath READ absoluteStoragePath WRITE setabsoluteStoragePath NOTIFY absoluteStoragePathChanged) Q_PROPERTY(QUrl absoluteStoragePath READ absoluteStoragePath WRITE setabsoluteStoragePath NOTIFY absoluteStoragePathChanged)
public: public:

View File

@ -1,19 +0,0 @@
#include "screenplayworkshop_plugin.h"
void ScreenPlayWorkshopPlugin::registerTypes(const char* uri)
{
qRegisterMetaType<ScreenPlayWorkshop::SteamQMLImageProvider*>("SteamQMLImageProvider*");
qmlRegisterType<ScreenPlayWorkshop::SteamQMLImageProvider>("Workshop", 1, 0, "SteamImage");
qmlRegisterUncreatableMetaObject(ScreenPlayWorkshopSteamEnums::staticMetaObject,
"Workshop",
1, 0,
"SteamEnums",
"Error: only enums");
qRegisterMetaType<ScreenPlayWorkshop::SteamAccount*>("SteamAccount*");
qRegisterMetaType<ScreenPlayWorkshop::InstalledListModel*>("InstalledListModel*");
qmlRegisterType<ScreenPlayWorkshop::SteamWorkshop>("Workshop", 1, 0, "SteamWorkshop");
qmlRegisterType<ScreenPlayWorkshop::Workshop>("Workshop", 1, 0, "ScreenPlayWorkshop");
}

View File

@ -1,21 +0,0 @@
#pragma once
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlExtensionPlugin>
#include <QSettings>
#include <QtQml>
#include "steam/steam_qt_enums_generated.h"
#include "workshop.h"
#include "steamqmlimageprovider.h"
class ScreenPlayWorkshopPlugin : public QQmlExtensionPlugin {
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
void registerTypes(const char* uri) override;
};

View File

@ -7,6 +7,7 @@
#include <QString> #include <QString>
#include <QTimer> #include <QTimer>
#include <QtGlobal> #include <QtGlobal>
#include <QtQml>
#include <memory> #include <memory>
#include <steam/steam_api.h> #include <steam/steam_api.h>
@ -15,7 +16,7 @@ namespace ScreenPlayWorkshop {
class SteamAccount : public QObject { class SteamAccount : public QObject {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(SteamAccount)
Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged) Q_PROPERTY(QString username READ username WRITE setUsername NOTIFY usernameChanged)
Q_PROPERTY(quint32 accountID READ accountID WRITE setAccountID NOTIFY accountIDChanged) Q_PROPERTY(quint32 accountID READ accountID WRITE setAccountID NOTIFY accountIDChanged)
Q_PROPERTY(QImage avatar READ avatar WRITE setAvatar NOTIFY avatarChanged) Q_PROPERTY(QImage avatar READ avatar WRITE setAvatar NOTIFY avatarChanged)

View File

@ -5,10 +5,12 @@
#include <QSGNode> #include <QSGNode>
#include <QSGSimpleTextureNode> #include <QSGSimpleTextureNode>
#include <QSGTexture> #include <QSGTexture>
#include <QtQml>
namespace ScreenPlayWorkshop { namespace ScreenPlayWorkshop {
class SteamQMLImageProvider : public QQuickItem { class SteamQMLImageProvider : public QQuickItem {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(SteamImage)
public: public:
SteamQMLImageProvider(QQuickItem* parent); SteamQMLImageProvider(QQuickItem* parent);
@ -28,7 +30,6 @@ public:
node->setRect(boundingRect()); node->setRect(boundingRect());
return node; return node;
} }
public slots: public slots:
void setImage(QImage image) void setImage(QImage image)
{ {

View File

@ -13,6 +13,7 @@
#include <QTimer> #include <QTimer>
#include <QUrl> #include <QUrl>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include <QtQml>
// Steam // Steam
#include "cstring" #include "cstring"
@ -40,6 +41,7 @@ struct SteamItemUpdate {
class SteamWorkshop : public QObject { class SteamWorkshop : public QObject {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(SteamWorkshop)
Q_PROPERTY(bool online READ online WRITE setOnline NOTIFY onlineChanged) Q_PROPERTY(bool online READ online WRITE setOnline NOTIFY onlineChanged)
Q_PROPERTY(unsigned long long itemProcessed READ itemProcessed WRITE setItemProcessed NOTIFY itemProcessedChanged) Q_PROPERTY(unsigned long long itemProcessed READ itemProcessed WRITE setItemProcessed NOTIFY itemProcessedChanged)
Q_PROPERTY(unsigned long long bytesTotal READ bytesTotal WRITE setBytesTotal NOTIFY bytesTotalChanged) Q_PROPERTY(unsigned long long bytesTotal READ bytesTotal WRITE setBytesTotal NOTIFY bytesTotalChanged)

View File

@ -14,7 +14,7 @@ namespace ScreenPlayWorkshop {
class Workshop : public QQuickItem { class Workshop : public QQuickItem {
Q_OBJECT Q_OBJECT
QML_NAMED_ELEMENT(ScreenPlayWorkshop)
Q_PROPERTY(InstalledListModel* installedListModel READ installedListModel NOTIFY installedListModelChanged) Q_PROPERTY(InstalledListModel* installedListModel READ installedListModel NOTIFY installedListModelChanged)
Q_PROPERTY(SteamWorkshop* steamWorkshop READ steamWorkshop NOTIFY steamWorkshopChanged) Q_PROPERTY(SteamWorkshop* steamWorkshop READ steamWorkshop NOTIFY steamWorkshopChanged)

View File

@ -45,7 +45,7 @@ if not args.build_type:
print("Build type argument is missing (release,debug). Example: python build.py -t release -steam=True") print("Build type argument is missing (release,debug). Example: python build.py -t release -steam=True")
sys.exit(1) sys.exit(1)
qt_version = "6.2.0" qt_version = "6.2.1"
steam_build = "OFF" steam_build = "OFF"
if args.steam_build: if args.steam_build:
if args.steam_build: if args.steam_build: