Merge remote-tracking branch 'origin/174-add-godot-wallpaper-support' into 174-add-godot-wallpaper-support
@ -35,7 +35,7 @@
|
||||
- cd ..
|
||||
- git clone https://invent.kde.org/plasma/layer-shell-qt.git
|
||||
- cd layer-shell-qt
|
||||
- cmake configure . -DCMAKE_PREFIX_PATH="./../../../aqt/6.6.0/gcc_64"
|
||||
- cmake configure . -DCMAKE_PREFIX_PATH="./../../../aqt/6.6.1/gcc_64"
|
||||
- make
|
||||
- make install
|
||||
- cd ..
|
||||
|
2
.vscode/launch.json
vendored
@ -17,7 +17,7 @@
|
||||
"environment": [
|
||||
{
|
||||
"name": "Path",
|
||||
"value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.6.0\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.6.0\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.6.0\\msvc2019_64\\qml\\;${workspaceFolder}\\..\\vcpkg\\installed\\x64-windows\\debug\\bin;"
|
||||
"value": "${env:Path};${workspaceFolder}\\..\\aqt\\6.6.1\\msvc2019_64\\bin\\;${workspaceFolder}\\..\\aqt\\6.6.1\\msvc2019_64\\modules\\;${workspaceFolder}\\..\\aqt\\6.6.1\\msvc2019_64\\qml\\;${workspaceFolder}\\..\\vcpkg\\installed\\x64-windows\\debug\\bin;"
|
||||
}
|
||||
],
|
||||
"visualizerFile": "${workspaceFolder}/.vscode/qt.natvis.xml"
|
||||
|
@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#define SCREENPLAY_VERSION "@SCREENPLAY_VERSION@"
|
||||
#define SCREENPLAY_SOURCE_DIR "@SCREENPLAY_SOURCE_DIR@"
|
||||
#define SCREENPLAY_GODOT_VERSION "@SCREENPLAY_GODOT_VERSION@"
|
||||
#define SCREENPLAY_GODOT_VERSION_MAJOR @SCREENPLAY_GODOT_VERSION_MAJOR@
|
||||
#define SCREENPLAY_GODOT_VERSION_MINOR @SCREENPLAY_GODOT_VERSION_MINOR@
|
||||
#define SCREENPLAY_GODOT_RELEASE_TYPE "@SCREENPLAY_GODOT_RELEASE_TYPE@"
|
||||
#define SCREENPLAY_BUILD_TYPE "@SCREENPLAY_BUILD_TYPE@"
|
||||
#define SCREENPLAY_GIT_BRANCH_NAME "@SCREENPLAY_GIT_BRANCH_NAME@"
|
||||
|
@ -1,17 +1,24 @@
|
||||
# ! generate_cmake_variable_header : Generates a header CmakeVariables.h that contains defines for the variables specified in CmakeVariables.h.in!
|
||||
# ! generate_cmake_variable_header : Generates a header CmakeVariables.h that contains defines for the variables specified in
|
||||
# CmakeVariables.h.in!
|
||||
#
|
||||
# The generated CmakeVariables.h header can then be used to access e.g. the PROJECT_NAME define in C++ code.
|
||||
#
|
||||
# Example
|
||||
# generate_cmake_variable_header(${PROJECT_NAME})
|
||||
# Example generate_cmake_variable_header(${PROJECT_NAME})
|
||||
#
|
||||
function(generate_cmake_variable_header TARGET)
|
||||
# NOTE: Also add to CMakeVariables.h.in !
|
||||
# ⚠️ Also add to CMakeVariables.h.in ⚠️
|
||||
|
||||
set(SCREENPLAY_SOURCE_DIR ${CMAKE_SOURCE_DIR})
|
||||
# Like v4.2-beta3 or v5.0.1-stable
|
||||
set(SCREENPLAY_GODOT_VERSION ${GODOT_VERSION})
|
||||
# Only single numbers
|
||||
set(SCREENPLAY_GODOT_VERSION_MAJOR ${GODOT_VERSION_MAJOR})
|
||||
set(SCREENPLAY_GODOT_VERSION_MINOR ${GODOT_VERSION_MINOR})
|
||||
# stable, rc1 or beta5
|
||||
set(SCREENPLAY_GODOT_RELEASE_TYPE ${GODOT_RELEASE_TYPE})
|
||||
set(SCREENPLAY_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
|
||||
set(SCREENPLAY_BUILD_DATE "${BUILD_DATE}")
|
||||
set(SCREENPLAY_VERSION "${SCREENPLAY_VERSION}")
|
||||
set(SCREENPLAY_GIT_BRANCH_NAME "${GIT_BRANCH_NAME}")
|
||||
set(SCREENPLAY_GIT_COMMIT_HASH "${GIT_COMMIT_HASH}")
|
||||
|
||||
@ -19,7 +26,7 @@ function(generate_cmake_variable_header TARGET)
|
||||
if(${SCREENPLAY_DEPLOY})
|
||||
set(SCREENPLAY_DEPLOY_VERSION 1)
|
||||
endif()
|
||||
|
||||
|
||||
set(SCREENPLAY_STEAM_VERSION 0)
|
||||
if(${SCREENPLAY_STEAM})
|
||||
set(SCREENPLAY_STEAM_VERSION 1)
|
||||
@ -27,7 +34,8 @@ function(generate_cmake_variable_header TARGET)
|
||||
|
||||
# Specify the configuration file from which the header file will be generated
|
||||
configure_file(${CMAKE_SOURCE_DIR}/CMake/CMakeVariables.h.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/CMakeVariables.h @ONLY)
|
||||
message(STATUS "GENERATE: ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/CMakeVariables.h and add ${TARGET} to ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
message(
|
||||
STATUS "GENERATE: ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/CMakeVariables.h and add ${TARGET} to ${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
# Add the directory containing the generated header
|
||||
target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.22.0)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
|
||||
include(GetProjectVersion)
|
||||
get_project_version(PROJECT_VERSION)
|
||||
get_project_version(SCREENPLAY_VERSION)
|
||||
|
||||
# This must be set before project()
|
||||
if(APPLE)
|
||||
@ -13,7 +13,7 @@ endif()
|
||||
|
||||
project(
|
||||
ScreenPlay
|
||||
VERSION ${PROJECT_VERSION}
|
||||
VERSION ${SCREENPLAY_VERSION}
|
||||
DESCRIPTION "Modern, Cross Plattform, Live Wallpaper, Widgets and AppDrawer!"
|
||||
HOMEPAGE_URL "https://screen-play.app/"
|
||||
LANGUAGES CXX)
|
||||
@ -43,9 +43,11 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0")
|
||||
# This subdirectoy is needed for OSX and Linux to fix linker errors because we would have ScreenPlayApp executable and folder for the qml
|
||||
# files in the same directory.
|
||||
set(SCREENPLAY_QML_MODULES_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qml")
|
||||
|
||||
if(APPLE)
|
||||
set(SCREENPLAY_QML_MODULES_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ScreenPlay.app/Contents/MacOS/qml")
|
||||
endif()
|
||||
|
||||
# Adds the qml import path so QtCreator can find them
|
||||
list(APPEND QML_DIRS "${SCREENPLAY_QML_MODULES_PATH}")
|
||||
set(QML_IMPORT_PATH
|
||||
@ -57,15 +59,26 @@ set(VCPKG_INSTALLED_PATH "${VCPKG_PATH}/installed/${VCPKG_ARCH}")
|
||||
set(VCPKG_BIN_PATH "${VCPKG_INSTALLED_PATH}/bin")
|
||||
|
||||
# Godot Editor
|
||||
set(GODOT_VERSION "v4.2")
|
||||
set(GODOT_RELEASE_TYPE "beta4")
|
||||
set(GODOT_VERSION_MAJOR "4")
|
||||
set(GODOT_VERSION_MINOR "2")
|
||||
set(GODOT_VERSION_PATCH "")
|
||||
set(GODOT_RELEASE_TYPE "rc2")
|
||||
|
||||
# Use an if statement to check if GODOT_VERSION_PATCH is empty or not
|
||||
if(GODOT_VERSION_PATCH STREQUAL "")
|
||||
# If patch version is empty, don't include it and the preceding dot
|
||||
set(GODOT_VERSION "v${GODOT_VERSION_MAJOR}.${GODOT_VERSION_MINOR}-${GODOT_RELEASE_TYPE}")
|
||||
else()
|
||||
# If patch version is not empty, include it and the preceding dot
|
||||
set(GODOT_VERSION "v${GODOT_VERSION_MAJOR}.${GODOT_VERSION_MINOR}.${GODOT_VERSION_PATCH}-${GODOT_RELEASE_TYPE}")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(GODOT_EDITOR_NAME "Godot_${GODOT_VERSION}-${GODOT_RELEASE_TYPE}_win64.exe")
|
||||
set(GODOT_EDITOR_NAME "Godot_${GODOT_VERSION}_win64.exe")
|
||||
elseif(APPLE)
|
||||
set(GODOT_EDITOR_NAME "Godot.app")
|
||||
elseif(UNIX)
|
||||
set(GODOT_EDITOR_NAME "Godot_${GODOT_VERSION}-${GODOT_RELEASE_TYPE}_linux.x86_64")
|
||||
set(GODOT_EDITOR_NAME "Godot_${GODOT_VERSION}_linux.x86_64")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported OS")
|
||||
endif()
|
||||
@ -73,7 +86,7 @@ endif()
|
||||
option(SCREENPLAY_OSX_BUNDLE "Enable distribution macOS bundle" OFF)
|
||||
option(SCREENPLAY_STEAM "For FOSS distribution so we do not bundle proprietary code." ON)
|
||||
option(SCREENPLAY_DEPLOY "Marks this version as an official deploy version. This version uses different import paths and other settings."
|
||||
OFF)
|
||||
OFF)
|
||||
option(SCREENPLAY_TESTS "Enables UI tests." ON)
|
||||
option(SCREENPLAY_INSTALLER "Indicates whether an installer via the Qt Installer Framework is created." OFF)
|
||||
option(SCREENPLAY_GODOT "Compiles ScreenPlayGodotWallpaper." ON)
|
||||
@ -166,7 +179,6 @@ if(${SCREENPLAY_INSTALLER})
|
||||
endif()
|
||||
|
||||
message(STATUS "[PROJECT] CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}")
|
||||
message(STATUS "[PROJECT] PROJECT_VERSION = ${PROJECT_VERSION}")
|
||||
message(STATUS "[PROJECT] CMAKE_VERSION = ${CMAKE_VERSION}")
|
||||
message(STATUS "[PROJECT] SCREENPLAY_QML_MODULES_PATH = ${SCREENPLAY_QML_MODULES_PATH}")
|
||||
message(STATUS "[PROJECT] CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
|
||||
@ -176,6 +188,7 @@ message(STATUS "[PROJECT] VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}
|
||||
message(STATUS "[PROJECT] CMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
|
||||
message(STATUS "[PROJECT] GODOT_VERSION = ${GODOT_VERSION}")
|
||||
message(STATUS "[PROJECT] GODOT_EDITOR_NAME = ${GODOT_EDITOR_NAME}")
|
||||
message(STATUS "[PROJECT] SCREENPLAY_VERSION = ${SCREENPLAY_VERSION}")
|
||||
message(STATUS "[OPTION] SCREENPLAY_DEPLOY = ${SCREENPLAY_DEPLOY}")
|
||||
message(STATUS "[OPTION] SCREENPLAY_INSTALLER = ${SCREENPLAY_INSTALLER}")
|
||||
message(STATUS "[OPTION] SCREENPLAY_STEAM = ${SCREENPLAY_STEAM}")
|
||||
|
@ -19,7 +19,7 @@
|
||||
},
|
||||
"environment": {
|
||||
"qt_path": "${sourceDir}/../aqt",
|
||||
"qt_version": "6.6.0"
|
||||
"qt_version": "6.6.1"
|
||||
},
|
||||
"toolset": {
|
||||
"value": "host=x64",
|
||||
@ -38,46 +38,46 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-debug-qt-6.6.0",
|
||||
"name": "windows-debug-qt-6.6.1",
|
||||
"inherits": "default-windows",
|
||||
"displayName": "MSVC SP Qt 6.6.0 Debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_MSVC_Debug",
|
||||
"displayName": "MSVC SP Qt 6.6.1 Debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_MSVC_Debug",
|
||||
"environment": {
|
||||
"qt_version": "6.6.0"
|
||||
"qt_version": "6.6.1"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-relwithdebinfo-qt-6.6.0",
|
||||
"name": "windows-relwithdebinfo-qt-6.6.1",
|
||||
"inherits": "default-windows",
|
||||
"displayName": "MSVC SP Qt 6.6.0 RelWithDebInfo",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_MSVC_RelWithDebInfo",
|
||||
"displayName": "MSVC SP Qt 6.6.1 RelWithDebInfo",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_MSVC_RelWithDebInfo",
|
||||
"environment": {
|
||||
"qt_version": "6.6.0"
|
||||
"qt_version": "6.6.1"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-release-qt-6.6.0",
|
||||
"name": "windows-release-qt-6.6.1",
|
||||
"inherits": "default-windows",
|
||||
"displayName": "MSVC SP Qt 6.6.0 Release",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_MSVC_Release",
|
||||
"displayName": "MSVC SP Qt 6.6.1 Release",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_MSVC_Release",
|
||||
"environment": {
|
||||
"qt_version": "6.6.0"
|
||||
"qt_version": "6.6.1"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-release-qt-6.6.0-release-deploy",
|
||||
"inherits": "windows-release-qt-6.6.0",
|
||||
"displayName": "MSVC SP Qt 6.6.0 Release Steam Deploy",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_MSVC_Release_Steam_Deploy",
|
||||
"name": "windows-release-qt-6.6.1-release-deploy",
|
||||
"inherits": "windows-release-qt-6.6.1",
|
||||
"displayName": "MSVC SP Qt 6.6.1 Release Steam Deploy",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_MSVC_Release_Steam_Deploy",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"SCREENPLAY_DEPLOY": "ON",
|
||||
@ -89,7 +89,7 @@
|
||||
"displayName": "ScreenPlay 64bit Debug Linux",
|
||||
"description": "Linux only!",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_GCC_Debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_GCC_Debug",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
@ -113,7 +113,7 @@
|
||||
"name": "linux-relwithdebinfo",
|
||||
"displayName": "ScreenPlay 64bit RelWithDebInfo Linux",
|
||||
"inherits": "linux-generic-debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_GCC_RelWithDebInfo",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_GCC_RelWithDebInfo",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
@ -123,7 +123,7 @@
|
||||
"displayName": "ScreenPlay 64bit Debug Linux using aqt",
|
||||
"description": "Linux only!",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_GCC_Debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_GCC_Debug",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
@ -140,7 +140,7 @@
|
||||
"CMAKE_CXX_COMPILER": "g++",
|
||||
"CMAKE_C_COMPILER": "gcc",
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_PREFIX_PATH": "$env{qt_path}/6.6.0/gcc_64",
|
||||
"CMAKE_PREFIX_PATH": "$env{qt_path}/6.6.1/gcc_64",
|
||||
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||
"VCPKG_TARGET_TRIPLET": "x64-linux"
|
||||
}
|
||||
@ -149,7 +149,7 @@
|
||||
"name": "linux-aqt-relwithdebinfo",
|
||||
"displayName": "ScreenPlay 64bit RelWithDebInfo Linux using aqt",
|
||||
"inherits": "linux-ubuntu-debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_GCC_RelWithDebInfo",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_GCC_RelWithDebInfo",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
@ -159,7 +159,7 @@
|
||||
"displayName": "ScreenPlay 64bit Debug osx",
|
||||
"description": "Osx only!",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_Clang_Debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_Clang_Debug",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
@ -174,7 +174,7 @@
|
||||
"CMAKE_CXX_COMPILER": "clang++",
|
||||
"CMAKE_C_COMPILER": "clang",
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_PREFIX_PATH": "$env{qt_path}/6.6.0/macos",
|
||||
"CMAKE_PREFIX_PATH": "$env{qt_path}/6.6.1/macos",
|
||||
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/../vcpkg/scripts/buildsystems/vcpkg.cmake"
|
||||
}
|
||||
},
|
||||
@ -182,7 +182,7 @@
|
||||
"name": "osx-relwithdebinfo",
|
||||
"displayName": "ScreenPlay 64bit RelWithDebInfo osx",
|
||||
"inherits": "osx-debug",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.0_Clang_RelWithDebInfo",
|
||||
"binaryDir": "${sourceDir}/../build_ScreenPlay_Qt_6.6.1_Clang_RelWithDebInfo",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
@ -207,7 +207,7 @@
|
||||
"name": "Test",
|
||||
"description": "",
|
||||
"displayName": "",
|
||||
"configurePreset": "windows-release-qt-6.6.0"
|
||||
"configurePreset": "windows-release-qt-6.6.1"
|
||||
}
|
||||
]
|
||||
}
|
@ -12,7 +12,7 @@ config_version=5
|
||||
|
||||
config/name="Fjord"
|
||||
run/main_scene="res://wallpaper.tscn"
|
||||
config/features=PackedStringArray("4.1", "Mobile")
|
||||
config/features=PackedStringArray("4.2", "Mobile")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[rendering]
|
||||
|
@ -60,6 +60,7 @@ set(QML
|
||||
qml/Create/StartInfoLinkImage.qml
|
||||
qml/Create/Wizard.qml
|
||||
qml/Create/Wizards/GifWallpaper.qml
|
||||
qml/Create/Wizards/GodotWallpaper.qml
|
||||
qml/Create/Wizards/HTMLWallpaper.qml
|
||||
qml/Create/Wizards/HTMLWidget.qml
|
||||
qml/Create/Wizards/Importh264/Importh264.qml
|
||||
@ -76,8 +77,6 @@ set(QML
|
||||
qml/Create/Wizards/QMLWidget.qml
|
||||
qml/Create/Wizards/WebsiteWallpaper.qml
|
||||
qml/Create/Wizards/WizardPage.qml
|
||||
qml/Create/WizardsFiles/QMLWallpaperMain.qml
|
||||
qml/Create/WizardsFiles/QMLWidgetMain.qml
|
||||
qml/Installed/Installed.qml
|
||||
qml/Installed/InstalledNavigation.qml
|
||||
qml/Installed/InstalledWelcomeScreen.qml
|
||||
@ -129,6 +128,7 @@ set(RESOURCES
|
||||
assets/icons/brand_reddit.svg
|
||||
assets/icons/brand_twitch.svg
|
||||
assets/icons/brand_twitter.svg
|
||||
assets/icons/icon_cancel_presentation.svg
|
||||
assets/icons/exclamation-triangle-solid.svg
|
||||
assets/icons/font-awsome/close.svg
|
||||
assets/icons/font-awsome/frown-o.svg
|
||||
@ -146,6 +146,7 @@ set(RESOURCES
|
||||
assets/icons/icon_document.svg
|
||||
assets/icons/icon_done.svg
|
||||
assets/icons/icon_download.svg
|
||||
assets/icons/icon_edit.svg
|
||||
assets/icons/icon_emptyWidget.svg
|
||||
assets/icons/icon_folder_open.svg
|
||||
assets/icons/icon_forum.svg
|
||||
@ -159,6 +160,7 @@ set(RESOURCES
|
||||
assets/icons/icon_movie.svg
|
||||
assets/icons/icon_new_releases.svg
|
||||
assets/icons/icon_open_in_new.svg
|
||||
assets/icons/icon_open_in_new_black.svg
|
||||
assets/icons/icon_pause.svg
|
||||
assets/icons/icon_people.svg
|
||||
assets/icons/icon_play.svg
|
||||
@ -175,7 +177,7 @@ set(RESOURCES
|
||||
assets/icons/icon_thumb_down.svg
|
||||
assets/icons/icon_thumb_up.svg
|
||||
assets/icons/icon_upload.svg
|
||||
assets/icons/icon_video_settings_black_24dp.svg
|
||||
assets/icons/icon_video_settings.svg
|
||||
assets/icons/icon_volume.svg
|
||||
assets/icons/icon_volume_mute.svg
|
||||
assets/icons/icon_volume_up.svg
|
||||
@ -201,9 +203,6 @@ set(RESOURCES
|
||||
assets/licenses/Apache2.txt
|
||||
assets/licenses/OFL.txt
|
||||
assets/macos/app.screenplay.plist
|
||||
assets/particle/backgroundGlow.png
|
||||
assets/particle/dot.png
|
||||
assets/shader/movingcolorramp.fsh
|
||||
assets/startinfo/blender.png
|
||||
assets/startinfo/flaticon.png
|
||||
assets/startinfo/forums.png
|
||||
@ -232,7 +231,6 @@ set(RESOURCES
|
||||
assets/wizards/License_CC_Attribution-ShareAlike_4.0.txt
|
||||
assets/wizards/License_CC_Attribution_4.0.txt
|
||||
assets/wizards/License_GPL_3.0.txt
|
||||
assets/wizards/QmlProject.qmlproject
|
||||
assets/WorkshopPreview.html
|
||||
legal/DataProtection.txt
|
||||
legal/gpl-3.0.txt
|
||||
@ -242,6 +240,13 @@ set(RESOURCES
|
||||
profiles.json
|
||||
qml/Create/WizardsFiles/HTMLWallpaperMain.html
|
||||
qml/Create/WizardsFiles/HTMLWidgetMain.html
|
||||
qml/Create/WizardsFiles/QmlProject.qmlproject
|
||||
qml/Create/WizardsFiles/QMLWallpaperMain.qml
|
||||
qml/Create/WizardsFiles/QMLWidgetMain.qml
|
||||
qml/Create/WizardsFiles/Godot_v5/export_presets.cfg
|
||||
qml/Create/WizardsFiles/Godot_v5/project.godot
|
||||
qml/Create/WizardsFiles/Godot_v5/spinner.gd
|
||||
qml/Create/WizardsFiles/Godot_v5/wallpaper.tscn
|
||||
qml/Create/WizardsFiles/QMLWallpaperMain.qml
|
||||
qml/Create/WizardsFiles/QMLWidgetMain.qml
|
||||
qtquickcontrols2.conf)
|
||||
|
1
ScreenPlay/assets/icons/icon_cancel_presentation.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m376-320 104-104 104 104 56-56-104-104 104-104-56-56-104 104-104-104-56 56 104 104-104 104 56 56ZM160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h640v-480H160v480Zm0 0v-480 480Z"/></svg>
|
After Width: | Height: | Size: 358 B |
1
ScreenPlay/assets/icons/icon_edit.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M200-200h57l391-391-57-57-391 391v57Zm-80 80v-170l528-527q12-11 26.5-17t30.5-6q16 0 31 6t26 18l55 56q12 11 17.5 26t5.5 30q0 16-5.5 30.5T817-647L290-120H120Zm640-584-56-56 56 56Zm-141 85-28-29 57 57-29-28Z"/></svg>
|
After Width: | Height: | Size: 310 B |
1
ScreenPlay/assets/icons/icon_open_in_new_black.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"/></svg>
|
After Width: | Height: | Size: 281 B |
@ -1 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><path id="steam-square" d="M413.982,173.02c0,-35.325 -28.99,-64.336 -64.656,-64.336c-35.326,0 -64.336,28.99 -64.336,64.336c0,35.667 28.989,64.336 64.336,64.336c35.666,0 64.656,-28.669 64.656,-64.336Zm-203.312,195.995c0,36.669 -29.33,65.999 -65.999,65.999c-25.342,0 -47.335,-14.334 -58.321,-35.325c11.007,4.331 21.673,8.661 32.659,13.333c26.664,10.665 57.339,-2.326 68.325,-29.331c10.666,-26.665 -2.325,-57.34 -29.331,-67.984l-27.326,-11.007c4.33,-1.003 9.343,-1.664 13.994,-1.664c36.669,0 65.999,29.331 65.999,66l0,-0.021Zm301.309,-272.98l0,319.973c0,52.988 -43.005,95.992 -95.992,95.992l-319.974,0c-52.987,0 -95.992,-43.004 -95.992,-95.992l0,-51.004l57.34,22.996c8.66,40.338 44.668,70.671 87.331,70.671c46.652,0 84.985,-35.666 89.336,-80.996l114.999,-84.003c66.661,0 120.331,-53.991 120.331,-119.99c0,-66.662 -53.67,-120.332 -120.331,-120.332c-65.659,0 -119.329,53.329 -119.99,118.988l-75.002,107.319c-3.008,-0.342 -5.994,-0.342 -9.343,-0.342c-16.66,0 -32.339,4.331 -45.671,12.33l-99,-39.655l0,-155.998c0,-52.988 43.005,-95.992 95.992,-95.992l319.974,0c52.987,0 95.992,43.004 95.992,95.992l0,0.043Zm-82.319,77.668c0,44.327 -35.986,80.334 -80.654,80.334c-44.327,0 -80.335,-35.986 -80.335,-80.334c0,-44.668 35.986,-80.655 80.335,-80.655c44.668,0 80.654,35.987 80.654,80.655Z" style="fill:#bebebe;fill-rule:nonzero;"/></svg>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path id="steam-square" d="M413.982,173.02C413.982,137.695 384.992,108.684 349.326,108.684C314,108.684 284.99,137.674 284.99,173.02C284.99,208.687 313.979,237.356 349.326,237.356C384.992,237.356 413.982,208.687 413.982,173.02ZM210.67,369.015C210.67,405.684 181.34,435.014 144.671,435.014C119.329,435.014 97.336,420.68 86.35,399.689C97.357,404.02 108.023,408.35 119.009,413.022C145.673,423.687 176.348,410.696 187.334,383.691C198,357.026 185.009,326.351 158.003,315.707L130.677,304.7C135.007,303.697 140.02,303.036 144.671,303.036C181.34,303.036 210.67,332.367 210.67,369.036L210.67,369.015ZM511.979,95.992L511.979,416.008C511.979,468.996 468.974,512 415.987,512L96.013,512C43.026,512 0.021,468.996 0.021,416.008L0.021,365.004L57.361,388C66.021,428.338 102.029,458.671 144.692,458.671C191.344,458.671 229.677,423.005 234.028,377.675L349.027,293.672C415.688,293.672 469.358,239.681 469.358,173.682C469.358,107.02 415.688,53.35 349.027,53.35C283.368,53.35 229.698,106.679 229.037,172.338L154.035,279.657C151.027,279.315 148.041,279.315 144.692,279.315C128.032,279.315 112.353,283.646 99.021,291.645L0.021,251.99L0.021,95.992C0.021,43.004 43.026,-0 96.013,-0L415.987,-0C468.974,-0 511.979,43.004 511.979,95.992ZM429.66,173.703C429.66,218.03 393.674,254.037 349.006,254.037C304.679,254.037 268.671,218.051 268.671,173.703C268.671,129.035 304.657,93.048 349.006,93.048C393.674,93.048 429.66,129.035 429.66,173.703Z" style="fill-rule:nonzero;"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 3.2 KiB |
@ -1,18 +0,0 @@
|
||||
uniform float time;
|
||||
uniform float shaderOpacity;
|
||||
uniform vec2 resolution;
|
||||
|
||||
void main( void ) {
|
||||
|
||||
|
||||
vec2 position = ( gl_FragCoord.xy / resolution.xy );
|
||||
|
||||
vec3 color1 = vec3(1.0, 0.6, 0.01);
|
||||
vec3 color2 = vec3(0.97, 0.24, 0.24);
|
||||
float mixValue = distance(position,vec2(0,1));
|
||||
|
||||
vec3 color = mix( color1, color2, mixValue);
|
||||
|
||||
gl_FragColor = vec4(color,mixValue) * shaderOpacity;
|
||||
|
||||
}
|
@ -32,6 +32,7 @@ namespace ScreenPlay {
|
||||
class Create : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
Q_PROPERTY(QString workingDir READ workingDir WRITE setWorkingDir NOTIFY workingDirChanged)
|
||||
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
|
||||
|
@ -16,6 +16,7 @@ namespace ScreenPlay {
|
||||
class GlobalVariables : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
Q_PROPERTY(QVersionNumber version READ version CONSTANT)
|
||||
Q_PROPERTY(QUrl localStoragePath READ localStoragePath WRITE setLocalStoragePath NOTIFY localStoragePathChanged FINAL)
|
||||
|
@ -77,7 +77,7 @@ public slots:
|
||||
void append(const QString& projectJsonFilePath);
|
||||
void reset();
|
||||
void init();
|
||||
void deinstallItemAt(const QString& absoluteStoragePath);
|
||||
bool deinstallItemAt(const QString& absoluteStoragePath);
|
||||
|
||||
void setCount(int count)
|
||||
{
|
||||
@ -96,6 +96,7 @@ private:
|
||||
QFileSystemWatcher m_fileSystemWatcher;
|
||||
QVector<ProjectFile> m_screenPlayFiles;
|
||||
int m_count { 0 };
|
||||
QTimer m_reloadLimiter;
|
||||
std::atomic_bool m_isLoading { false };
|
||||
|
||||
const std::shared_ptr<GlobalVariables>& m_globalVariables;
|
||||
|
@ -41,6 +41,7 @@ struct Monitor {
|
||||
class MonitorListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
public:
|
||||
explicit MonitorListModel(QObject* parent = nullptr);
|
||||
|
@ -24,6 +24,7 @@ namespace ScreenPlay {
|
||||
class ScreenPlayManager : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
Q_PROPERTY(int activeWallpaperCounter READ activeWallpaperCounter WRITE setActiveWallpaperCounter NOTIFY activeWallpaperCounterChanged)
|
||||
Q_PROPERTY(int activeWidgetsCounter READ activeWidgetsCounter WRITE setActiveWidgetsCounter NOTIFY activeWidgetsCounterChanged)
|
||||
|
@ -3,10 +3,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFileInfoList>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <memory>
|
||||
|
||||
#include "ScreenPlay/globalvariables.h"
|
||||
@ -19,27 +22,21 @@ namespace ScreenPlay {
|
||||
class ScreenPlayWallpaper : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
Q_PROPERTY(bool isConnected READ isConnected WRITE setIsConnected NOTIFY isConnectedChanged)
|
||||
|
||||
Q_PROPERTY(QVector<int> screenNumber READ screenNumber WRITE setScreenNumber NOTIFY screenNumberChanged)
|
||||
|
||||
Q_PROPERTY(float volume READ volume WRITE setVolume NOTIFY volumeChanged)
|
||||
Q_PROPERTY(float playbackRate READ playbackRate WRITE setPlaybackRate NOTIFY playbackRateChanged)
|
||||
Q_PROPERTY(bool isLooping READ isLooping WRITE setIsLooping NOTIFY isLoopingChanged)
|
||||
|
||||
Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged)
|
||||
Q_PROPERTY(QString absolutePath READ absolutePath WRITE setAbsolutePath NOTIFY absolutePathChanged)
|
||||
Q_PROPERTY(QString previewImage READ previewImage WRITE setPreviewImage NOTIFY previewImageChanged)
|
||||
Q_PROPERTY(QString appID READ appID WRITE setAppID NOTIFY appIDChanged)
|
||||
|
||||
Q_PROPERTY(FillMode::FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
|
||||
Q_PROPERTY(InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged)
|
||||
|
||||
public:
|
||||
// Default constructor needed for qml engine
|
||||
ScreenPlayWallpaper() { }
|
||||
|
||||
explicit ScreenPlayWallpaper(
|
||||
const QVector<int>& screenNumber,
|
||||
const std::shared_ptr<GlobalVariables>& globalVariables,
|
||||
@ -210,7 +207,7 @@ public slots:
|
||||
}
|
||||
|
||||
private:
|
||||
bool exportGodotProject(const QString& absolutePath, int timeoutMilliseconds = 30000);
|
||||
bool exportGodotProject();
|
||||
|
||||
private:
|
||||
const std::shared_ptr<GlobalVariables> m_globalVariables;
|
||||
@ -218,6 +215,7 @@ private:
|
||||
const std::shared_ptr<Settings> m_settings;
|
||||
|
||||
ProjectSettingsListModel m_projectSettingsListModel;
|
||||
QJsonObject m_projectJson;
|
||||
QVector<int> m_screenNumber;
|
||||
QProcess m_process;
|
||||
QString m_previewImage;
|
||||
|
@ -23,6 +23,7 @@ namespace ScreenPlay {
|
||||
class ScreenPlayWidget : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
|
||||
Q_PROPERTY(QString absolutePath READ absolutePath WRITE setAbsolutePath NOTIFY absolutePathChanged)
|
||||
Q_PROPERTY(QString previewImage READ previewImage WRITE setPreviewImage NOTIFY previewImageChanged)
|
||||
|
@ -58,7 +58,8 @@ class Util : public QObject {
|
||||
Q_PROPERTY(QString debugMessages READ debugMessages NOTIFY debugMessagesChanged)
|
||||
|
||||
public:
|
||||
Util();
|
||||
Util(
|
||||
const std::shared_ptr<GlobalVariables>& globalVariables);
|
||||
~Util();
|
||||
|
||||
QString debugMessages() const { return m_debugMessages; }
|
||||
@ -82,6 +83,7 @@ public slots:
|
||||
void openFolderInExplorer(const QString& url) const;
|
||||
QString toLocal(const QString& url) const;
|
||||
bool exportProject(QString contentPath, QString exportFileName);
|
||||
bool openGodotEditor(QString contentPath) const;
|
||||
bool importProject(QString archivePath, QString extractionPath);
|
||||
void requestAllLicenses();
|
||||
void requestDataProtection();
|
||||
@ -124,6 +126,7 @@ private:
|
||||
QFuture<void> m_requestAllLicensesFuture;
|
||||
std::unique_ptr<QArchive::DiskCompressor> m_compressor;
|
||||
std::unique_ptr<QArchive::DiskExtractor> m_extractor;
|
||||
const std::shared_ptr<GlobalVariables>& m_globalVariables;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QColor>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
@ -34,9 +35,11 @@ namespace ScreenPlay {
|
||||
class Wizards : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("CPP ONLY")
|
||||
public:
|
||||
explicit Wizards(const std::shared_ptr<GlobalVariables>& globalVariables, QObject* parent = nullptr);
|
||||
Wizards() { }
|
||||
explicit Wizards(
|
||||
const std::shared_ptr<GlobalVariables>& globalVariables,
|
||||
QObject* parent = nullptr);
|
||||
|
||||
enum class WizardResult {
|
||||
Ok,
|
||||
@ -82,6 +85,14 @@ public slots:
|
||||
const QString& previewThumbnail,
|
||||
const QVector<QString>& tags);
|
||||
|
||||
void createGodotWallpaper(
|
||||
const QString& title,
|
||||
const QString& licenseName,
|
||||
const QString& licenseFile,
|
||||
const QString& createdBy,
|
||||
const QString& previewThumbnail,
|
||||
const QVector<QString>& tags);
|
||||
|
||||
void createGifWallpaper(
|
||||
const QString& title,
|
||||
const QString& licenseName,
|
||||
@ -103,8 +114,16 @@ signals:
|
||||
private:
|
||||
const std::shared_ptr<GlobalVariables> m_globalVariables;
|
||||
const std::optional<QString> createTemporaryFolder() const;
|
||||
void createPreviewImage(const QString& name, const QString& targetPath);
|
||||
|
||||
private:
|
||||
QFuture<void> m_wizardFuture;
|
||||
QVector<QColor> m_gradientColors = {
|
||||
QColor("#B71C1C"),
|
||||
QColor("#1B5E20"),
|
||||
QColor("#0D47A1"),
|
||||
QColor("#FFD600"),
|
||||
QColor("#4A148C")
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ ApplicationWindow {
|
||||
stackView.replace("qrc:/qml/ScreenPlayApp/qml/" + name + "/" + name + ".qml", {
|
||||
"modalSource": content
|
||||
});
|
||||
nav.setNavigation(name);
|
||||
sidebar.state = "inactive";
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ ApplicationWindow {
|
||||
visible: false
|
||||
width: 1400
|
||||
height: 810
|
||||
title: "ScreenPlay Alpha - V" + App.version()
|
||||
title: "ScreenPlay Alpha - v" + App.version()
|
||||
minimumHeight: 450
|
||||
minimumWidth: 1050
|
||||
|
||||
@ -72,9 +73,10 @@ ApplicationWindow {
|
||||
// https://bugreports.qt.io/browse/QTBUG-86047
|
||||
Material.accent: Material.color(Material.Orange)
|
||||
onVisibilityChanged: {
|
||||
if (root.visibility === 2)
|
||||
App.installedListModel.reset();
|
||||
if (root.visibility !== 2)
|
||||
return;
|
||||
}
|
||||
|
||||
onClosing: close => {
|
||||
close.accepted = false;
|
||||
if (App.screenPlayManager.activeWallpaperCounter === 0 && App.screenPlayManager.activeWidgetsCounter === 0) {
|
||||
@ -111,6 +113,7 @@ ApplicationWindow {
|
||||
App.showDockIcon(true);
|
||||
root.show();
|
||||
}
|
||||
App.installedListModel.reset();
|
||||
}
|
||||
|
||||
Item {
|
||||
|
@ -42,9 +42,7 @@ Rectangle {
|
||||
|
||||
function onWizardExited() {
|
||||
root.expanded = true;
|
||||
stackView.clear(StackView.PushTransition);
|
||||
stackView.push("qrc:/qml/ScreenPlayApp/qml/Create/StartInfo.qml");
|
||||
listView.currentIndex = 0;
|
||||
App.util.setNavigation("Installed");
|
||||
App.util.setNavigationActive(true);
|
||||
}
|
||||
|
||||
@ -87,6 +85,13 @@ Rectangle {
|
||||
objectName: ""
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("Godot Wallpaper")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/GodotWallpaper.qml"
|
||||
category: "Code Wallpaper"
|
||||
objectName: ""
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("QML Wallpaper")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/QMLWallpaper.qml"
|
||||
|
101
ScreenPlay/qml/Create/Wizards/GodotWallpaper.qml
Normal file
@ -0,0 +1,101 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import ScreenPlayApp
|
||||
import ScreenPlay
|
||||
import ScreenPlay.Create
|
||||
import ScreenPlayUtil as Util
|
||||
|
||||
WizardPage {
|
||||
id: root
|
||||
|
||||
sourceComponent: ColumnLayout {
|
||||
id: rightWrapper
|
||||
|
||||
function create() {
|
||||
App.wizards.createGodotWallpaper(tfTitle.text, cbLicense.name, cbLicense.licenseFile, tfCreatedBy.text, previewSelector.imageSource, tagSelector.getTags());
|
||||
}
|
||||
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
Util.Headline {
|
||||
text: qsTr("Create a Godot Wallpaper")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Util.HeadlineSection {
|
||||
text: qsTr("General")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
|
||||
Util.TextField {
|
||||
id: tfTitle
|
||||
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Wallpaper name")
|
||||
required: true
|
||||
onTextChanged: root.ready = text.length >= 1
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: tfCreatedBy
|
||||
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Created By")
|
||||
}
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: tfDescription
|
||||
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Description")
|
||||
}
|
||||
|
||||
Item {
|
||||
height: 30
|
||||
}
|
||||
|
||||
Util.HeadlineSection {
|
||||
text: qsTr("License & Tags")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
|
||||
Util.LicenseSelector {
|
||||
id: cbLicense
|
||||
}
|
||||
|
||||
Util.TagSelector {
|
||||
id: tagSelector
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: 30
|
||||
}
|
||||
|
||||
Util.HeadlineSection {
|
||||
text: qsTr("Preview Image")
|
||||
}
|
||||
|
||||
Util.ImageSelector {
|
||||
id: previewSelector
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
@ -10,16 +10,21 @@ import ScreenPlayUtil as Util
|
||||
|
||||
WizardPage {
|
||||
id: root
|
||||
|
||||
function isValidURL(string) {
|
||||
var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
|
||||
return (res !== null);
|
||||
}
|
||||
sourceComponent: ColumnLayout {
|
||||
property bool ready: tfTitle.text.length >= 1 && tfUrl.text.length > 1
|
||||
id: layout
|
||||
function validate() {
|
||||
root.ready = tfTitle.text.length >= 1 && root.isValidURL(tfUrl.text);
|
||||
}
|
||||
|
||||
function create() {
|
||||
App.wizards.createWebsiteWallpaper(tfTitle.text, previewSelector.imageSource, tfUrl.text, tagSelector.getTags());
|
||||
}
|
||||
|
||||
spacing: 10
|
||||
onReadyChanged: root.ready = ready
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
@ -41,11 +46,10 @@ WizardPage {
|
||||
|
||||
Util.TextField {
|
||||
id: tfTitle
|
||||
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Wallpaper name")
|
||||
required: true
|
||||
onTextChanged: root.ready = text.length >= 1
|
||||
onTextChanged: layout.validate()
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
@ -65,10 +69,10 @@ WizardPage {
|
||||
|
||||
Util.TextField {
|
||||
id: tfUrl
|
||||
|
||||
Layout.fillWidth: true
|
||||
required: true
|
||||
text: "https://"
|
||||
onTextChanged: layout.validate()
|
||||
}
|
||||
|
||||
Item {
|
||||
|
@ -0,0 +1,15 @@
|
||||
[preset.0]
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter=""
|
||||
export_path=""
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
encrypt_directory=false
|
15
ScreenPlay/qml/Create/WizardsFiles/Godot_v5/project.godot
Normal file
@ -0,0 +1,15 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Test"
|
||||
run/main_scene="res://wallpaper.tscn"
|
||||
config/features=PackedStringArray("4.2", "Forward Plus")
|
6
ScreenPlay/qml/Create/WizardsFiles/Godot_v5/spinner.gd
Normal file
@ -0,0 +1,6 @@
|
||||
extends CSGBox3D
|
||||
|
||||
var rotation_speed = 3.0
|
||||
|
||||
func _process(delta):
|
||||
rotate_y(rotation_speed * delta)
|
19
ScreenPlay/qml/Create/WizardsFiles/Godot_v5/wallpaper.tscn
Normal file
@ -0,0 +1,19 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://d105uliklnkd5"]
|
||||
|
||||
[ext_resource type="Script" path="res://spinner.gd" id="1_ggnsn"]
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5)
|
||||
|
||||
[node name="CSGBox3D" type="CSGBox3D" parent="."]
|
||||
transform = Transform3D(0.707107, -0.5, -0.5, 0, 0.707107, -0.707107, 0.707107, 0.5, 0.5, 0, 0, 0)
|
||||
script = ExtResource("1_ggnsn")
|
||||
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.41283, 1.52646)
|
||||
|
||||
[node name="Label3D" type="Label3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.874896, 0.37249)
|
||||
text = "Godot Wallpaper"
|
@ -41,7 +41,6 @@ Item {
|
||||
|
||||
StackView.onActivated: {
|
||||
navWrapper.state = "in";
|
||||
App.installedListFilter.sortBySearchType(SearchType.All);
|
||||
checkIsContentInstalled();
|
||||
}
|
||||
|
||||
@ -86,8 +85,6 @@ Item {
|
||||
property bool isScrolling: gridView.verticalVelocity !== 0
|
||||
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
maximumFlickVelocity: 3000
|
||||
flickDeceleration: 7500
|
||||
anchors.fill: parent
|
||||
cellWidth: 340
|
||||
cellHeight: 200
|
||||
@ -240,11 +237,19 @@ Item {
|
||||
contextMenu.publishedFileID = delegate.publishedFileID;
|
||||
contextMenu.absoluteStoragePath = delegate.absoluteStoragePath;
|
||||
contextMenu.fileName = delegate.customTitle;
|
||||
contextMenu.type = delegate.type;
|
||||
print(delegate.publishedFileID);
|
||||
if (contextMenu.godotItem)
|
||||
contextMenu.godotItem.destroy();
|
||||
const pos = delegate.mapToItem(root, position.x, position.y);
|
||||
// Disable duplicate opening. The can happen if we
|
||||
// call popup when we are in the closing animtion.
|
||||
if (contextMenu.visible || contextMenu.opened)
|
||||
return;
|
||||
if (delegate.type === InstalledType.GodotWallpaper) {
|
||||
contextMenu.godotItem = editGodotWallpaperComp.createObject();
|
||||
contextMenu.insertItem(0, contextMenu.godotItem);
|
||||
}
|
||||
contextMenu.popup(pos.x, pos.y);
|
||||
}
|
||||
}
|
||||
@ -253,14 +258,30 @@ Item {
|
||||
snapMode: ScrollBar.SnapOnRelease
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: editGodotWallpaperComp
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Edit Wallpaper")
|
||||
objectName: "editWallpaper"
|
||||
enabled: contextMenu.type === InstalledType.GodotWallpaper
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_edit.svg"
|
||||
onClicked: {
|
||||
App.util.openGodotEditor(contextMenu.absoluteStoragePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
Menu {
|
||||
id: contextMenu
|
||||
objectName: "installedItemContextMenu"
|
||||
|
||||
// Must be var to support 64-bit size!
|
||||
property var publishedFileID: 0
|
||||
property var type: 0
|
||||
property url absoluteStoragePath
|
||||
property string fileName
|
||||
// We need to dynamically add this menu item
|
||||
// if it is a Godot Wallpaper, see onOpenContextMenu
|
||||
property var godotItem
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Open containing folder")
|
||||
@ -312,7 +333,9 @@ Item {
|
||||
anchors.centerIn: Overlay.overlay
|
||||
onAccepted: {
|
||||
root.sidebar.clear();
|
||||
App.installedListModel.deinstallItemAt(contextMenu.absoluteStoragePath);
|
||||
if (!App.installedListModel.deinstallItemAt(contextMenu.absoluteStoragePath)) {
|
||||
console.error("Unable to uninstall item", contextMenu.absoluteStoragePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +415,8 @@ Item {
|
||||
importProjectErrorDialog.open();
|
||||
return;
|
||||
}
|
||||
var file = ""; // Convert url to string
|
||||
var file = "";
|
||||
// Convert url to string
|
||||
file = "" + drop.urls[0];
|
||||
if (!file.endsWith('.screenplay')) {
|
||||
importProjectErrorDialog.title = qsTr("File type not supported. We only support '.screenplay' files.");
|
||||
|
@ -14,6 +14,7 @@ Item {
|
||||
property string screenId
|
||||
property url absoluteStoragePath
|
||||
property int type: InstalledType.Unknown
|
||||
// Must be var to make it work wit 64bit ints
|
||||
property var publishedFileID: 0
|
||||
property int itemIndex
|
||||
property bool isScrolling: false
|
||||
|
@ -13,7 +13,7 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
property string currentNavigationName: "Installed"
|
||||
property var navArray: [navCreate, navWorkshop, navInstalled, navSettings, navCommunity]
|
||||
property var navArray: [navCreate, navWorkshop, navInstalled, navCommunity, navSettings]
|
||||
property bool navActive: true
|
||||
property Item modalSource
|
||||
property int iconWidth: 16
|
||||
@ -28,13 +28,12 @@ Rectangle {
|
||||
else
|
||||
root.state = "disabled";
|
||||
}
|
||||
|
||||
function setNavigation(name) {
|
||||
var i = 0;
|
||||
for (; i < navArray.length; i++) {
|
||||
if (navArray[i].name === name) {
|
||||
for (var i = 0; i < navArray.length; i++) {
|
||||
if (navArray[i].objectName === name) {
|
||||
navArray[i].state = "active";
|
||||
root.currentNavigationName = name;
|
||||
tabBar.currentIndex = navArray[i].index;
|
||||
} else {
|
||||
navArray[i].state = "inactive";
|
||||
}
|
||||
@ -70,7 +69,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: row
|
||||
id: tabBar
|
||||
height: 50
|
||||
currentIndex: 2
|
||||
|
||||
@ -84,55 +83,60 @@ Rectangle {
|
||||
|
||||
CustomTabButton {
|
||||
id: navCreate
|
||||
index: 0
|
||||
icon.height: 22
|
||||
icon.width: 22
|
||||
text: qsTr("Create")
|
||||
objectName: "Create"
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg"
|
||||
onClicked: {
|
||||
root.onPageChanged("Create");
|
||||
}
|
||||
objectName: "createTab"
|
||||
}
|
||||
|
||||
CustomTabButton {
|
||||
id: navWorkshop
|
||||
index: 1
|
||||
enabled: App.settings.steamVersion
|
||||
text: qsTr("Workshop")
|
||||
objectName: "Workshop"
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg"
|
||||
onClicked: {
|
||||
root.onPageChanged("Workshop");
|
||||
}
|
||||
objectName: "workshopTab"
|
||||
}
|
||||
|
||||
CustomTabButton {
|
||||
id: navInstalled
|
||||
index: 2
|
||||
text: qsTr("Installed") + " " + App.installedListModel.count
|
||||
objectName: "Installed"
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_installed.svg"
|
||||
onClicked: {
|
||||
root.onPageChanged("Installed");
|
||||
}
|
||||
objectName: "installedTab"
|
||||
}
|
||||
|
||||
CustomTabButton {
|
||||
id: navCommunity
|
||||
index: 3
|
||||
text: qsTr("Community")
|
||||
objectName: "Community"
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_community.svg"
|
||||
onClicked: {
|
||||
root.onPageChanged("Community");
|
||||
}
|
||||
objectName: "communityTab"
|
||||
}
|
||||
|
||||
CustomTabButton {
|
||||
id: navSettings
|
||||
index: 4
|
||||
text: qsTr("Settings")
|
||||
objectName: "Settings"
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_settings.svg"
|
||||
onClicked: {
|
||||
root.onPageChanged("Settings");
|
||||
}
|
||||
objectName: "settingsTab"
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,6 +146,7 @@ Rectangle {
|
||||
font.pointSize: 12
|
||||
height: parent.height
|
||||
width: implicitWidth
|
||||
property int index: 0
|
||||
background: Item {
|
||||
}
|
||||
font.capitalization: Font.MixedCase
|
||||
@ -260,7 +265,7 @@ Rectangle {
|
||||
ToolButton {
|
||||
id: miConfig
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_video_settings_black_24dp.svg"
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_video_settings.svg"
|
||||
icon.width: root.iconWidth
|
||||
icon.height: root.iconHeight
|
||||
onClicked: App.util.setToggleWallpaperConfiguration()
|
||||
@ -278,7 +283,7 @@ Rectangle {
|
||||
name: "disabled"
|
||||
|
||||
PropertyChanges {
|
||||
target: row
|
||||
target: tabBar
|
||||
opacity: 0.3
|
||||
}
|
||||
}
|
||||
@ -289,7 +294,7 @@ Rectangle {
|
||||
to: "*"
|
||||
|
||||
PropertyAnimation {
|
||||
target: row
|
||||
target: tabBar
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ Item {
|
||||
id: radioButton
|
||||
|
||||
checked: settingsBool.isChecked
|
||||
onCheckedChanged: {
|
||||
onClicked: {
|
||||
if (radioButton.checkState === Qt.Checked)
|
||||
checkboxChanged(true);
|
||||
else
|
||||
|
@ -403,7 +403,7 @@ Item {
|
||||
Image {
|
||||
id: imgLogoHead
|
||||
|
||||
source: "https://assets.gitlab-static.net/uploads/-/system/user/avatar/64172/avatar.png"
|
||||
source: "https://gitlab.com/uploads/-/system/user/avatar/64172/avatar.png"
|
||||
width: 120
|
||||
height: 120
|
||||
visible: false
|
||||
|
@ -27,29 +27,99 @@ SystemTrayIcon {
|
||||
}
|
||||
}
|
||||
|
||||
function open() {
|
||||
App.showDockIcon(true);
|
||||
window.show();
|
||||
}
|
||||
|
||||
menu: Menu {
|
||||
MenuItem {
|
||||
id: miOpenScreenPlay
|
||||
text: qsTr("Open ScreenPlay")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_open_in_new_black.svg"
|
||||
onTriggered: {
|
||||
App.showDockIcon(true);
|
||||
window.show();
|
||||
root.open();
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
id: miChangeWallpaperSettings
|
||||
text: qsTr("Change Wallpaper settings")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_video_settings.svg"
|
||||
onTriggered: {
|
||||
root.open();
|
||||
App.util.setNavigation("Installed");
|
||||
App.util.setToggleWallpaperConfiguration();
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
separator: true
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Browse Workshop")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg"
|
||||
onTriggered: {
|
||||
root.open();
|
||||
App.util.setNavigation("Workshop");
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
id: miCreate
|
||||
text: qsTr("Create new Wallpaper or Widgets")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg"
|
||||
onTriggered: {
|
||||
root.open();
|
||||
App.util.setNavigation("Create");
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
id: miSettings
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_settings.svg"
|
||||
text: qsTr("Settings")
|
||||
onTriggered: {
|
||||
root.open();
|
||||
App.util.setNavigation("Settings");
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
separator: true
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Forums and Help")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_supervisor_account.svg"
|
||||
onTriggered: {
|
||||
Qt.openUrlExternally("https://forum.screen-play.app/");
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Frequently Asked Questions (FAQ)")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_help_center.svg"
|
||||
onTriggered: {
|
||||
Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/Frequently%20Asked%20Questions/");
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
separator: true
|
||||
}
|
||||
MenuItem {
|
||||
id: miMuteAll
|
||||
|
||||
property bool isMuted: true
|
||||
|
||||
text: qsTr("Mute all")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume_mute.svg"
|
||||
onTriggered: {
|
||||
if (miMuteAll.isMuted) {
|
||||
isMuted = false;
|
||||
miMuteAll.text = qsTr("Mute all");
|
||||
miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume_mute.svg"
|
||||
App.screenPlayManager.setAllWallpaperValue("muted", "true");
|
||||
} else {
|
||||
isMuted = true;
|
||||
miMuteAll.text = qsTr("Unmute all");
|
||||
miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume_up.svg"
|
||||
App.screenPlayManager.setAllWallpaperValue("muted", "false");
|
||||
}
|
||||
}
|
||||
@ -61,14 +131,17 @@ SystemTrayIcon {
|
||||
property bool isPlaying: false
|
||||
|
||||
text: qsTr("Pause all")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_pause.svg"
|
||||
onTriggered: {
|
||||
if (miStopAll.isPlaying) {
|
||||
isPlaying = false;
|
||||
miStopAll.text = qsTr("Pause all");
|
||||
miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_pause.svg"
|
||||
App.screenPlayManager.setAllWallpaperValue("isPlaying", "true");
|
||||
} else {
|
||||
isPlaying = true;
|
||||
miStopAll.text = qsTr("Play all");
|
||||
miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_play.svg"
|
||||
App.screenPlayManager.setAllWallpaperValue("isPlaying", "false");
|
||||
}
|
||||
}
|
||||
@ -76,6 +149,7 @@ SystemTrayIcon {
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Quit ScreenPlay")
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_cancel_presentation.svg"
|
||||
onTriggered: App.exit()
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "ScreenPlayUtil/macutils.h"
|
||||
#endif
|
||||
|
||||
#include "ScreenPlay/CMakeVariables.h"
|
||||
#include "app.h"
|
||||
#include "steam/steam_qt_enums_generated.h"
|
||||
#include <QGuiApplication>
|
||||
@ -71,8 +72,22 @@ App::App()
|
||||
QGuiApplication::setOrganizationName("ScreenPlay");
|
||||
QGuiApplication::setOrganizationDomain("screen-play.app");
|
||||
QGuiApplication::setApplicationName("ScreenPlay");
|
||||
QGuiApplication::setApplicationVersion(QVersionNumber(0, 15, 0).toString());
|
||||
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
|
||||
another ScreenPlay instance is running and then quit early. This is also because we cannot
|
||||
call QGuiApplication::quit(); in the SDKConnector before the app.exec(); ( the Qt main event
|
||||
loop ) has started.
|
||||
*/
|
||||
void App::init()
|
||||
{
|
||||
qInfo() << "Init ScreenPlay";
|
||||
|
||||
QString fontsPath = QGuiApplication::instance()->applicationDirPath() + "/assets/fonts/";
|
||||
#if defined(Q_OS_MACOS)
|
||||
@ -121,26 +136,11 @@ App::App()
|
||||
"SearchType",
|
||||
"Error: only enums");
|
||||
|
||||
// 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
|
||||
another ScreenPlay instance is running and then quit early. This is also because we cannot
|
||||
call QGuiApplication::quit(); in the SDKConnector before the app.exec(); ( the Qt main event
|
||||
loop ) has started.
|
||||
*/
|
||||
void App::init()
|
||||
{
|
||||
|
||||
using std::make_shared, std::make_unique;
|
||||
|
||||
// Util should be created as first so we redirect qDebugs etc. into the log
|
||||
m_util = make_unique<Util>();
|
||||
m_globalVariables = make_shared<GlobalVariables>();
|
||||
m_monitorListModel = make_shared<MonitorListModel>();
|
||||
m_util = make_unique<Util>(m_globalVariables);
|
||||
m_profileListModel = make_shared<ProfileListModel>(m_globalVariables);
|
||||
m_settings = make_shared<Settings>(m_globalVariables);
|
||||
m_installedListModel = make_shared<InstalledListModel>(m_globalVariables, m_settings);
|
||||
|
@ -35,18 +35,23 @@ InstalledListModel::InstalledListModel(
|
||||
*/
|
||||
void InstalledListModel::init()
|
||||
{
|
||||
if (!m_fileSystemWatcher.addPath(m_globalVariables->localStoragePath().toLocalFile())) {
|
||||
qWarning() << "Could not setup file system watcher for changed files with path: " << m_globalVariables->localStoragePath().toLocalFile();
|
||||
QString projectsPath = m_globalVariables->localStoragePath().toLocalFile();
|
||||
QDirIterator projectFilesIter(projectsPath, { "*.qml", "*.html", "*.css", "*.js", "*.png", "project.json" }, QDir::Files | QDir::NoSymLinks, QDirIterator::Subdirectories);
|
||||
while (projectFilesIter.hasNext()) {
|
||||
m_fileSystemWatcher.addPath(projectFilesIter.next());
|
||||
}
|
||||
m_reloadLimiter.setInterval(500);
|
||||
m_reloadLimiter.setSingleShot(true);
|
||||
QObject::connect(&m_reloadLimiter, &QTimer::timeout, this, [this]() {
|
||||
reset();
|
||||
});
|
||||
|
||||
auto reloadLambda = [this]() {
|
||||
QTimer::singleShot(500, this, [this]() {
|
||||
reset();
|
||||
});
|
||||
auto restartTimer = [this]() {
|
||||
m_reloadLimiter.start();
|
||||
};
|
||||
|
||||
QObject::connect(&m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, reloadLambda);
|
||||
QObject::connect(&m_fileSystemWatcher, &QFileSystemWatcher::fileChanged, this, reloadLambda);
|
||||
QObject::connect(&m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, restartTimer);
|
||||
QObject::connect(&m_fileSystemWatcher, &QFileSystemWatcher::fileChanged, this, restartTimer);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -54,28 +59,27 @@ void InstalledListModel::init()
|
||||
installed list. We wait for the qml engine to free all resources before
|
||||
we proceed. This like the preview.gif will be in use when clicking on an item
|
||||
*/
|
||||
void InstalledListModel::deinstallItemAt(const QString& absoluteStoragePath)
|
||||
bool InstalledListModel::deinstallItemAt(const QString& absoluteStoragePath)
|
||||
{
|
||||
QTimer::singleShot(1000, this, [this, absoluteStoragePath]() {
|
||||
int index = -1;
|
||||
for (int i = 0; i < m_screenPlayFiles.size(); ++i) {
|
||||
if (m_screenPlayFiles.at(i).projectJsonFilePath.absoluteFilePath() == absoluteStoragePath) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
const QString path = ScreenPlayUtil::toLocal(absoluteStoragePath);
|
||||
int index = -1;
|
||||
for (int i = 0; i < m_screenPlayFiles.size(); ++i) {
|
||||
if (m_screenPlayFiles.at(i).projectJsonFilePath.path() == path) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < 0 || index >= m_screenPlayFiles.count()) {
|
||||
qWarning() << "Remove folder error, invalid index " << index;
|
||||
return;
|
||||
}
|
||||
if (index < 0 || index >= m_screenPlayFiles.count()) {
|
||||
qWarning() << "Remove folder error, invalid index " << index;
|
||||
return false;
|
||||
}
|
||||
|
||||
beginRemoveRows(QModelIndex(), index, index);
|
||||
m_screenPlayFiles.removeAt(index);
|
||||
endRemoveRows();
|
||||
|
||||
const QString path = ScreenPlayUtil::toLocal(absoluteStoragePath);
|
||||
beginRemoveRows(QModelIndex(), index, index);
|
||||
m_screenPlayFiles.removeAt(index);
|
||||
endRemoveRows();
|
||||
|
||||
QTimer::singleShot(1000, this, [this, path]() {
|
||||
QDir dir(path);
|
||||
bool success = true;
|
||||
if (!dir.exists()) {
|
||||
@ -110,6 +114,7 @@ void InstalledListModel::deinstallItemAt(const QString& absoluteStoragePath)
|
||||
m_fileSystemWatcher.blockSignals(false);
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -288,6 +293,10 @@ QVariantMap InstalledListModel::get(const QString& folderName) const
|
||||
*/
|
||||
void InstalledListModel::reset()
|
||||
{
|
||||
if (m_isLoading) {
|
||||
qInfo() << "loadInstalledContent is already running. Skip.";
|
||||
return;
|
||||
}
|
||||
beginResetModel();
|
||||
m_screenPlayFiles.clear();
|
||||
m_screenPlayFiles.squeeze();
|
||||
|
@ -114,16 +114,15 @@ void MonitorListModel::loadMonitors()
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QModelIndex index;
|
||||
WinMonitorStats monitors;
|
||||
auto monitors = WindowsIntegration().getAllMonitors();
|
||||
|
||||
// This offset lets us center the monitor selection view in the center
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
const int moinitorCount = monitors.iMonitors.size();
|
||||
|
||||
for (int i = 0; i < moinitorCount; i++) {
|
||||
const int x = monitors.rcMonitors[i].left;
|
||||
const int y = monitors.rcMonitors[i].top;
|
||||
for (auto& monitor : monitors) {
|
||||
const int x = monitor.position.left;
|
||||
const int y = monitor.position.top;
|
||||
if (x < 0) {
|
||||
offsetX += (x * -1);
|
||||
}
|
||||
@ -132,11 +131,11 @@ void MonitorListModel::loadMonitors()
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < moinitorCount; i++) {
|
||||
const int width = std::abs(monitors.rcMonitors[i].right - monitors.rcMonitors[i].left);
|
||||
const int height = std::abs(monitors.rcMonitors[i].top - monitors.rcMonitors[i].bottom);
|
||||
const int x = monitors.rcMonitors[i].left;
|
||||
const int y = monitors.rcMonitors[i].top;
|
||||
for (int i = 0; auto& monitor : monitors) {
|
||||
const int width = std::abs(monitor.position.right - monitor.position.left);
|
||||
const int height = std::abs(monitor.position.top - monitor.position.bottom);
|
||||
const int x = monitor.position.left;
|
||||
const int y = monitor.position.top;
|
||||
QRect geometry(
|
||||
x + offsetX,
|
||||
y + offsetY,
|
||||
@ -145,6 +144,7 @@ void MonitorListModel::loadMonitors()
|
||||
beginInsertRows(index, m_monitorList.size(), m_monitorList.size());
|
||||
m_monitorList.append(Monitor { i, geometry });
|
||||
endInsertRows();
|
||||
i++;
|
||||
}
|
||||
#else
|
||||
QModelIndex index;
|
||||
|
@ -22,7 +22,9 @@ namespace ScreenPlay {
|
||||
/*!
|
||||
Constructor
|
||||
*/
|
||||
ProfileListModel::ProfileListModel(const std::shared_ptr<GlobalVariables>& globalVariables, QObject* parent)
|
||||
ProfileListModel::ProfileListModel(
|
||||
const std::shared_ptr<GlobalVariables>& globalVariables,
|
||||
QObject* parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_globalVariables { globalVariables }
|
||||
{
|
||||
|
@ -303,7 +303,7 @@ bool ScreenPlayManager::removeWallpaperAt(int index)
|
||||
*/
|
||||
bool ScreenPlayManager::requestProjectSettingsAtMonitorIndex(const int index)
|
||||
{
|
||||
for (const std::shared_ptr<ScreenPlayWallpaper>& uPtrWallpaper : qAsConst(m_screenPlayWallpapers)) {
|
||||
for (const std::shared_ptr<ScreenPlayWallpaper>& uPtrWallpaper : std::as_const(m_screenPlayWallpapers)) {
|
||||
if (uPtrWallpaper->screenNumber()[0] == index) {
|
||||
|
||||
emit projectSettingsListModelResult(
|
||||
@ -514,12 +514,12 @@ bool ScreenPlayManager::saveProfiles()
|
||||
m_saveLimiter.stop();
|
||||
|
||||
QJsonArray wallpaper {};
|
||||
for (const auto& activeWallpaper : qAsConst(m_screenPlayWallpapers)) {
|
||||
for (const auto& activeWallpaper : std::as_const(m_screenPlayWallpapers)) {
|
||||
wallpaper.append(activeWallpaper->getActiveSettingsJson());
|
||||
}
|
||||
|
||||
QJsonArray widgets {};
|
||||
for (const auto& activeWidget : qAsConst(m_screenPlayWidgets)) {
|
||||
for (const auto& activeWidget : std::as_const(m_screenPlayWidgets)) {
|
||||
widgets.append(activeWidget->getActiveSettingsJson());
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,8 @@ namespace ScreenPlay {
|
||||
/*!
|
||||
\brief Constructor for ScreenPlayWallpaper.
|
||||
*/
|
||||
ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
|
||||
ScreenPlayWallpaper::ScreenPlayWallpaper(
|
||||
const QVector<int>& screenNumber,
|
||||
const std::shared_ptr<GlobalVariables>& globalVariables,
|
||||
const QString& appID,
|
||||
const QString& absolutePath,
|
||||
@ -42,7 +43,10 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
|
||||
, m_playbackRate { playbackRate }
|
||||
, m_settings { settings }
|
||||
{
|
||||
|
||||
std::optional<QJsonObject> projectOpt = ScreenPlayUtil::openJsonFileToObject(absolutePath + "/project.json");
|
||||
if (projectOpt.has_value()) {
|
||||
m_projectJson = projectOpt.value();
|
||||
}
|
||||
QJsonObject projectSettingsListModelProperties;
|
||||
if (type == InstalledType::InstalledType::VideoWallpaper) {
|
||||
projectSettingsListModelProperties.insert("volume", m_volume);
|
||||
@ -66,7 +70,7 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
|
||||
|
||||
QString tmpScreenNumber;
|
||||
if (m_screenNumber.length() > 1) {
|
||||
for (const int number : qAsConst(m_screenNumber)) {
|
||||
for (const int number : std::as_const(m_screenNumber)) {
|
||||
// IMPORTANT: NO TRAILING COMMA!
|
||||
if (number == m_screenNumber.back()) {
|
||||
tmpScreenNumber += QString::number(number);
|
||||
@ -92,13 +96,22 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
|
||||
if (m_type != InstalledType::InstalledType::GodotWallpaper) {
|
||||
m_appArgumentsList.append(" --disable-features=HardwareMediaKeyHandling");
|
||||
}
|
||||
if (m_type == InstalledType::InstalledType::GodotWallpaper) {
|
||||
if (m_projectJson.contains("version")) {
|
||||
const quint64 version = m_projectJson.value("version").toInt();
|
||||
const QString packageFileName = QString("project-v%1.zip").arg(version);
|
||||
m_appArgumentsList.append(packageFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ScreenPlayWallpaper::start()
|
||||
{
|
||||
if (m_type == InstalledType::InstalledType::GodotWallpaper) {
|
||||
exportGodotProject(m_absolutePath);
|
||||
if (!exportGodotProject())
|
||||
return false;
|
||||
}
|
||||
|
||||
m_process.setArguments(m_appArgumentsList);
|
||||
if (m_type == InstalledType::InstalledType::GodotWallpaper) {
|
||||
m_process.setProgram(m_globalVariables->godotWallpaperExecutablePath().toString());
|
||||
@ -126,7 +139,7 @@ bool ScreenPlayWallpaper::start()
|
||||
QJsonObject ScreenPlayWallpaper::getActiveSettingsJson()
|
||||
{
|
||||
QJsonArray screenNumber;
|
||||
for (const int i : qAsConst(m_screenNumber)) {
|
||||
for (const int i : std::as_const(m_screenNumber)) {
|
||||
screenNumber.append(i);
|
||||
}
|
||||
|
||||
@ -293,22 +306,40 @@ bool ScreenPlayWallpaper::replace(
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ScreenPlayWallpaper::exportGodotProject(const QString& absolutePath, int timeoutMilliseconds)
|
||||
/*!
|
||||
\brief .
|
||||
*/
|
||||
bool ScreenPlayWallpaper::exportGodotProject()
|
||||
{
|
||||
if (!m_projectJson.contains("version"))
|
||||
return false;
|
||||
|
||||
const quint64 version = m_projectJson.value("version").toInt();
|
||||
const QString packageFileName = QString("project-v%1.zip").arg(version);
|
||||
QFileInfo godotPackageFile(m_absolutePath + "/" + packageFileName);
|
||||
// Skip reexport
|
||||
if (godotPackageFile.exists())
|
||||
return true;
|
||||
|
||||
qInfo() << "No suitable version found for Godot package" << packageFileName << " at" << godotPackageFile.absoluteFilePath() << " exporting a new pck as zip.";
|
||||
|
||||
// Prepare the Godot export command
|
||||
const QList<QString> godotCmd = { "--export-pack", "--headless", "Windows Desktop", "project.zip" };
|
||||
const QList<QString>
|
||||
godotCmd
|
||||
= { "--export-pack", "--headless", "Windows Desktop", packageFileName };
|
||||
|
||||
// Create QProcess instance to run the command
|
||||
QProcess process;
|
||||
|
||||
// Set the working directory to the given absolute path
|
||||
process.setWorkingDirectory(absolutePath);
|
||||
process.setWorkingDirectory(m_absolutePath);
|
||||
process.setProgram(m_globalVariables->godotEditorExecutablePath().toString());
|
||||
// Start the Godot export process
|
||||
process.setArguments(godotCmd);
|
||||
process.start();
|
||||
|
||||
// Wait for the process to finish or timeout
|
||||
const int timeoutMilliseconds = 30000;
|
||||
if (!process.waitForFinished(timeoutMilliseconds)) {
|
||||
qCritical() << "Godot export process timed out or failed to start.";
|
||||
return false;
|
||||
@ -331,9 +362,9 @@ bool ScreenPlayWallpaper::exportGodotProject(const QString& absolutePath, int ti
|
||||
}
|
||||
|
||||
// Check if the project.zip file was created
|
||||
QString zipPath = QDir(absolutePath).filePath("project.zip");
|
||||
QString zipPath = QDir(m_absolutePath).filePath(packageFileName);
|
||||
if (!QFile::exists(zipPath)) {
|
||||
qCritical() << "Expected export file (project.zip) was not created.";
|
||||
qCritical() << "Expected export file (" << packageFileName << ") was not created.";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -342,7 +373,7 @@ bool ScreenPlayWallpaper::exportGodotProject(const QString& absolutePath, int ti
|
||||
// but for simplicity, we're just checking its size here)
|
||||
QFileInfo zipInfo(zipPath);
|
||||
if (zipInfo.size() <= 0) {
|
||||
qCritical() << "The exported project.zip file seems to be invalid.";
|
||||
qCritical() << "The exported " << packageFileName << " file seems to be invalid.";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ void Settings::setupWidgetAndWindowPaths()
|
||||
m_globalVariables->setWidgetExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWidget" + ScreenPlayUtil::executableBinEnding()));
|
||||
m_globalVariables->setWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaper" + ScreenPlayUtil::executableBinEnding()));
|
||||
m_globalVariables->setGodotWallpaperExecutablePath(QUrl(workingDir.path() + "/ScreenPlayWallpaperGodot" + ScreenPlayUtil::executableBinEnding()));
|
||||
const auto godotEditorName = "Godot_" + godotVersion + "-" + godotReleaseType + "_win64.exe";
|
||||
const auto godotEditorName = "Godot_" + godotVersion + "_win64.exe";
|
||||
m_globalVariables->setGodotEditorExecutablePath(QUrl(workingDir.path() + "/" + godotEditorName));
|
||||
} else if (osType == "macos") {
|
||||
// ScreenPlayTest is not bundled in an .app so the working directory
|
||||
|
@ -23,8 +23,10 @@ namespace ScreenPlay {
|
||||
/*!
|
||||
\brief Constructor.
|
||||
*/
|
||||
Util::Util()
|
||||
Util::Util(
|
||||
const std::shared_ptr<GlobalVariables>& globalVariables)
|
||||
: QObject(nullptr)
|
||||
, m_globalVariables { globalVariables }
|
||||
{
|
||||
m_extractor = std::make_unique<QArchive::DiskExtractor>();
|
||||
m_compressor = std::make_unique<QArchive::DiskCompressor>();
|
||||
@ -144,6 +146,15 @@ bool Util::exportProject(QString contentPath, QString exportFileName)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Util::openGodotEditor(QString contentPath) const
|
||||
{
|
||||
const QList<QString> godotCmd = { "--editor", "--path", toLocal(contentPath) };
|
||||
QProcess process;
|
||||
process.setProgram(m_globalVariables->godotEditorExecutablePath().toString());
|
||||
process.setArguments(godotCmd);
|
||||
return process.startDetached();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Imports a given project from a .screenplay zip file. The argument extractionPath
|
||||
must be copied otherwise it will get reset in qml before extracting.
|
||||
|
@ -1,6 +1,11 @@
|
||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||
#include "ScreenPlay/wizards.h"
|
||||
#include "ScreenPlay/CMakeVariables.h"
|
||||
#include "ScreenPlayUtil/util.h"
|
||||
#include <QFont>
|
||||
#include <QLinearGradient>
|
||||
#include <QPainter>
|
||||
#include <QTextOption>
|
||||
|
||||
namespace ScreenPlay {
|
||||
/*!
|
||||
@ -67,15 +72,13 @@ void Wizards::createQMLWidget(const QString& title,
|
||||
}
|
||||
|
||||
if (!previewThumbnail.isEmpty()) {
|
||||
QUrl previewThumbnailUrl { previewThumbnail };
|
||||
QFileInfo previewImageFile(previewThumbnailUrl.toLocalFile());
|
||||
obj.insert("previewThumbnail", previewImageFile.fileName());
|
||||
obj.insert("preview", previewImageFile.fileName());
|
||||
if (!QFile::copy(previewThumbnailUrl.toLocalFile(), workingPath + "/" + previewImageFile.fileName())) {
|
||||
qWarning() << "Could not copy" << previewThumbnailUrl.toLocalFile() << " to " << workingPath + "/" + previewImageFile.fileName();
|
||||
emit widgetCreationFinished(WizardResult::CopyError);
|
||||
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
|
||||
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
obj.insert("preview", "preview.png");
|
||||
createPreviewImage(title, workingPath);
|
||||
}
|
||||
|
||||
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
|
||||
@ -136,13 +139,13 @@ void Wizards::createHTMLWidget(const QString& title,
|
||||
QFileInfo previewImageFile(previewThumbnailUrl.toLocalFile());
|
||||
|
||||
if (!previewThumbnail.isEmpty()) {
|
||||
obj.insert("previewThumbnail", previewImageFile.fileName());
|
||||
obj.insert("preview", previewImageFile.fileName());
|
||||
if (!QFile::copy(previewThumbnailUrl.toLocalFile(), workingPath + "/" + previewImageFile.fileName())) {
|
||||
qWarning() << "Could not copy" << previewThumbnailUrl.toLocalFile() << " to " << workingPath + "/" + previewImageFile.fileName();
|
||||
emit widgetCreationFinished(WizardResult::CopyError);
|
||||
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
|
||||
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
obj.insert("preview", "preview.png");
|
||||
createPreviewImage(title, workingPath);
|
||||
}
|
||||
|
||||
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
|
||||
@ -201,15 +204,13 @@ void Wizards::createHTMLWallpaper(
|
||||
}
|
||||
|
||||
if (!previewThumbnail.isEmpty()) {
|
||||
QUrl previewThumbnailUrl { previewThumbnail };
|
||||
QFileInfo previewImageFile(previewThumbnailUrl.toLocalFile());
|
||||
obj.insert("previewThumbnail", previewImageFile.fileName());
|
||||
obj.insert("preview", previewImageFile.fileName());
|
||||
if (!QFile::copy(previewThumbnailUrl.toLocalFile(), workingPath + "/" + previewImageFile.fileName())) {
|
||||
qWarning() << "Could not copy" << previewThumbnailUrl.toLocalFile() << " to " << workingPath + "/" + previewImageFile.fileName();
|
||||
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
|
||||
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
obj.insert("preview", "preview.png");
|
||||
createPreviewImage(title, workingPath);
|
||||
}
|
||||
|
||||
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
|
||||
@ -260,6 +261,9 @@ void Wizards::createQMLWallpaper(
|
||||
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
obj.insert("preview", "preview.png");
|
||||
createPreviewImage(title, workingPath);
|
||||
}
|
||||
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
|
||||
@ -269,7 +273,7 @@ void Wizards::createQMLWallpaper(
|
||||
}
|
||||
|
||||
const QString qmlproject = workingPath + "/" + title + ".qmlproject";
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + QString("QmlProject.qmlproject"), qmlproject)) {
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/" + QString("QmlProject.qmlproject"), qmlproject)) {
|
||||
qWarning() << "Could not write " << qmlproject;
|
||||
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
|
||||
return;
|
||||
@ -289,6 +293,95 @@ void Wizards::createQMLWallpaper(
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief .
|
||||
*/
|
||||
void Wizards::createGodotWallpaper(
|
||||
const QString& title,
|
||||
const QString& licenseName,
|
||||
const QString& licenseFile,
|
||||
const QString& createdBy,
|
||||
const QString& previewThumbnail,
|
||||
const QVector<QString>& tags)
|
||||
{
|
||||
if (m_wizardFuture.isRunning()) {
|
||||
qWarning() << "Another wizard is already running! Abort.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_wizardFuture = QtConcurrent::run([=]() {
|
||||
std::optional<QString> folderName = createTemporaryFolder();
|
||||
|
||||
if (!folderName.has_value()) {
|
||||
emit widgetCreationFinished(WizardResult::CreateProjectFolderError);
|
||||
return;
|
||||
}
|
||||
|
||||
const QString workingPath = ScreenPlayUtil::toLocal(m_globalVariables->localStoragePath().toString() + "/" + folderName.value());
|
||||
|
||||
QJsonObject obj;
|
||||
obj.insert("license", licenseName);
|
||||
obj.insert("title", title);
|
||||
obj.insert("createdBy", createdBy);
|
||||
// Every version change will trigger an reexport
|
||||
obj.insert("version", 1);
|
||||
// Something like v4.2-beta3 or v5.0.1-stable
|
||||
QString godotVersionMajor = QString::number(SCREENPLAY_GODOT_VERSION_MAJOR);
|
||||
QString godotVersionMinor = QString::number(SCREENPLAY_GODOT_VERSION_MINOR);
|
||||
obj.insert("godotVersionMajor", godotVersionMajor);
|
||||
obj.insert("godotVersionMinor", godotVersionMinor);
|
||||
obj.insert("tags", ScreenPlayUtil::fillArray(tags));
|
||||
obj.insert("type", QVariant::fromValue(InstalledType::InstalledType::GodotWallpaper).toString());
|
||||
obj.insert("file", "wallpaper.tscn");
|
||||
|
||||
if (!previewThumbnail.isEmpty()) {
|
||||
if (!Util::copyPreviewThumbnail(obj, previewThumbnail, workingPath)) {
|
||||
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
obj.insert("preview", "preview.png");
|
||||
createPreviewImage(title, workingPath);
|
||||
}
|
||||
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/assets/wizards/" + licenseFile, workingPath + "/" + licenseFile)) {
|
||||
qWarning() << "Could not write " << licenseFile;
|
||||
emit widgetCreationFinished(WizardResult::WriteLicenseFileError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
|
||||
emit widgetCreationFinished(WizardResult::WriteProjectFileError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/project.godot", workingPath + "/project.godot")) {
|
||||
qWarning() << "Could not write project.godot";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/spinner.gd", workingPath + "/spinner.gd")) {
|
||||
qWarning() << "Could not write spinner.gd";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/wallpaper.tscn", workingPath + "/wallpaper.tscn")) {
|
||||
qWarning() << "Could not write wallpaper.tscn";
|
||||
return;
|
||||
}
|
||||
|
||||
// This presets file is needed for the export. Because we do only export
|
||||
// package files, it does not matter that we hardcode "Windows Desktop" as
|
||||
// export preset.
|
||||
if (!Util::writeFileFromQrc(":/qml/ScreenPlayApp/qml/Create/WizardsFiles/Godot_v5/export_presets.cfg", workingPath + "/export_presets.cfg")) {
|
||||
qWarning() << "Could not write export_presets.cfg";
|
||||
return;
|
||||
}
|
||||
|
||||
emit widgetCreationFinished(WizardResult::Ok, workingPath);
|
||||
});
|
||||
}
|
||||
|
||||
void Wizards::createGifWallpaper(
|
||||
const QString& title,
|
||||
const QString& licenseName,
|
||||
@ -378,6 +471,9 @@ void Wizards::createWebsiteWallpaper(
|
||||
emit widgetCreationFinished(WizardResult::CopyPreviewThumbnailError);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
obj.insert("preview", "preview.png");
|
||||
createPreviewImage(title, workingPath);
|
||||
}
|
||||
|
||||
if (!Util::writeSettings(obj, workingPath + "/project.json")) {
|
||||
@ -408,6 +504,48 @@ const std::optional<QString> Wizards::createTemporaryFolder() const
|
||||
|
||||
return folderName;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Creates a default preview.png.
|
||||
*/
|
||||
void Wizards::createPreviewImage(const QString& name, const QString& targetPath)
|
||||
{
|
||||
// Step 1: Create QImage and QPainter
|
||||
QImage image(749, 442, QImage::Format_ARGB32);
|
||||
QPainter painter(&image);
|
||||
|
||||
// Step 2: Select Random Colors (example colors, replace with Material colors)
|
||||
// These are just placeholder colors, replace with actual Material colors
|
||||
int randomIndex1 = QRandomGenerator::global()->bounded(5);
|
||||
int randomIndex2 = QRandomGenerator::global()->bounded(5);
|
||||
|
||||
// Step 3: Create and Set Gradient
|
||||
QLinearGradient gradient(QPointF(0, image.height()), QPointF(image.width(), 0));
|
||||
gradient.setColorAt(0, m_gradientColors[randomIndex1].darker()); // Dark color
|
||||
gradient.setColorAt(1, m_gradientColors[randomIndex2].lighter()); // Bright color
|
||||
|
||||
painter.fillRect(image.rect(), gradient);
|
||||
|
||||
// Step 4: Draw Text
|
||||
// Set the font size depending on the size of the image
|
||||
painter.setPen(Qt::white);
|
||||
int fontSize = qMin(image.width(), image.height()) / 10; // Adjust proportion as needed
|
||||
QFont font = painter.font();
|
||||
font.setFamily("Noto Sans Light");
|
||||
font.setPointSize(fontSize);
|
||||
painter.setFont(font);
|
||||
|
||||
// Define a margin and adjust the rect accordingly
|
||||
int margin = 30;
|
||||
QRect rect(margin, margin, image.width() - 2 * margin, image.height() - 2 * margin);
|
||||
|
||||
// Draw text within the adjusted rect
|
||||
QTextOption option(Qt::AlignCenter);
|
||||
painter.drawText(rect, name, option);
|
||||
|
||||
// Step 5: Save Image
|
||||
image.save(targetPath + "/preview.png");
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_wizards.cpp"
|
||||
|
@ -102,7 +102,7 @@ void ScreenPlayTest::import_convert_video()
|
||||
auto* createWallpaperInit = m_window->findChild<QQuickItem*>("createWallpaperInit");
|
||||
QVERIFY(createWallpaperInit);
|
||||
|
||||
const QString originalVideoPath = QString(SCREENPLAY_SOURCE_DIR) + "/ScreenPlay/assets/tests/video_import.mp4";
|
||||
const QString originalVideoPath = QString(SCREENPLAY_SOURCE_DIR) + "/Content/wallpaper_video_nebula_h264/mantissa.xyz_loop_072.mp4";
|
||||
qInfo() << originalVideoPath;
|
||||
|
||||
QVERIFY(QMetaObject::invokeMethod(createWallpaperInit,
|
||||
|
@ -107,3 +107,7 @@ if(WIN32)
|
||||
# Used for query windows monitor data
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC shcore.lib)
|
||||
endif()
|
||||
|
||||
# ##### USE CMAKE VARIABLES IN CODE #####
|
||||
include(GenerateCMakeVariableHeader)
|
||||
generate_cmake_variable_header(${PROJECT_NAME})
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <QUrl>
|
||||
#include <fmt/color.h>
|
||||
|
||||
#include "ScreenPlayUtil/CMakeVariables.h"
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
@ -29,11 +31,14 @@ LoggingHandler::LoggingHandler(const QString& logFileName)
|
||||
#ifdef Q_OS_WINDOWS
|
||||
// Enable UTF-8 support
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
// QtCreator has issues with fmt prints
|
||||
// https://bugreports.qt.io/browse/QTCREATORBUG-3994
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
// This is a QtCreator workaround and crashes std::fmt
|
||||
// when running standalone.
|
||||
if (!SCREENPLAY_DEPLOY_VERSION) {
|
||||
// QtCreator has issues with fmt prints
|
||||
// https://bugreports.qt.io/browse/QTCREATORBUG-3994
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
qInfo() << "Setting setvbuf(stdout, NULL, _IONBF, 0); This unbuffered output causes crashes in release with threaded fmt!";
|
||||
}
|
||||
#endif
|
||||
|
||||
qSetMessagePattern("[%{time dd.MM.yyyy h:mm:ss.zzz} %{if-debug}Debug%{endif}%{if-info}Info%{endif}%{if-warning}Warning%{endif}%{if-critical}Critical%{endif}%{if-fatal}Fatal%{endif}] %{file}:%{line} - %{message}");
|
||||
@ -227,7 +232,6 @@ void LoggingHandler::writeToConsole(QtMsgType type, const QMessageLogContext& co
|
||||
const auto filename = extractFileName(context);
|
||||
const auto function = extractFunction(context);
|
||||
const auto line = context.line;
|
||||
|
||||
fmt::print(
|
||||
"[{}] {} {}:{} - {}\n",
|
||||
fmt::styled(now.toStdString(), fmt::emphasis::bold),
|
||||
|
@ -36,22 +36,25 @@ bool ProjectFile::init()
|
||||
}
|
||||
type = typeParsed.value();
|
||||
|
||||
// Required:
|
||||
if (!obj.contains("file"))
|
||||
// File is required. Website Wallpaper doe not have a file, but a url
|
||||
if (!obj.contains("file") && type != ScreenPlay::InstalledType::InstalledType::WebsiteWallpaper)
|
||||
return false;
|
||||
file = obj.value("file").toString();
|
||||
|
||||
if (type == ScreenPlay::InstalledType::InstalledType::GodotWallpaper) {
|
||||
QFileInfo fileInfo(folder.path() + "/wallpaper.tscn");
|
||||
if (!fileInfo.exists()) {
|
||||
qCritical() << "Requested file:" << fileInfo.absoluteFilePath() << "does not exist!";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
QFileInfo fileInfo(folder.path() + "/" + file);
|
||||
if (!fileInfo.exists()) {
|
||||
qCritical() << "Requested file:" << fileInfo.absoluteFilePath() << "does not exist!";
|
||||
return false;
|
||||
if (type != ScreenPlay::InstalledType::InstalledType::WebsiteWallpaper) {
|
||||
file = obj.value("file").toString();
|
||||
|
||||
if (type == ScreenPlay::InstalledType::InstalledType::GodotWallpaper) {
|
||||
QFileInfo fileInfo(folder.path() + "/wallpaper.tscn");
|
||||
if (!fileInfo.exists()) {
|
||||
qCritical() << "Requested file:" << fileInfo.absoluteFilePath() << "does not exist!";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
QFileInfo fileInfo(folder.path() + "/" + file);
|
||||
if (!fileInfo.exists()) {
|
||||
qCritical() << "Requested file:" << fileInfo.absoluteFilePath() << "does not exist!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,13 +108,13 @@ bool ProjectFile::init()
|
||||
qWarning("Invalid videoCodec was specified inside the json object!");
|
||||
}
|
||||
} else if (type == ScreenPlay::InstalledType::InstalledType::VideoWallpaper) {
|
||||
qWarning("No videoCodec was specified inside the json object!");
|
||||
// qWarning("No videoCodec was specified inside the json object!");
|
||||
if (file.endsWith(".mp4")) {
|
||||
videoCodec = ScreenPlay::VideoCodec::VideoCodec::H264;
|
||||
qWarning("Eyeball to h264 because of .mp4");
|
||||
// qWarning("Eyeball to h264 because of .mp4");
|
||||
} else if (file.endsWith(".webm")) {
|
||||
videoCodec = ScreenPlay::VideoCodec::VideoCodec::VP8;
|
||||
qWarning("Eyeball to VP8 because of .webm");
|
||||
// qWarning("Eyeball to VP8 because of .webm");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ set(QML
|
||||
qml/Wallpaper.qml
|
||||
qml/WebsiteWallpaper.qml)
|
||||
|
||||
set(RESOURCES dot.png qtquickcontrols2.conf index.html)
|
||||
set(RESOURCES qtquickcontrols2.conf index.html)
|
||||
|
||||
set(LIB_SOURCES)
|
||||
set(LIB_HEADER)
|
||||
|
@ -32,8 +32,15 @@ project(ScreenPlayGodotWallpaper LANGUAGES CXX)
|
||||
|
||||
# Create our library
|
||||
add_library(${PROJECT_NAME} SHARED)
|
||||
# Runs after compilation Enable executing python scripts
|
||||
find_package(Python COMPONENTS Interpreter)
|
||||
|
||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME}
|
||||
POST_BUILD
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/Tools"
|
||||
COMMAND "${Python_EXECUTABLE}" "build_godot.py" "--build_path" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
|
||||
COMMENT "Running post-build step")
|
||||
|
||||
# LIB_ARCH is the architecture being built. It is set to the build system's architecture. For macOS, we build a universal library (both
|
||||
# arm64 and x86_64).
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c1196a1ab0a1ca166d0e5e2f08f9fe4156118c5e
|
||||
Subproject commit 32409472b785fd6f9062300664fa55b46bfd07e7
|
@ -33,6 +33,9 @@ void ScreenPlayGodotWallpaper::_bind_methods()
|
||||
ClassDB::bind_method(godot::D_METHOD("get_activeScreensList"), &ScreenPlayGodotWallpaper::get_activeScreensList);
|
||||
ClassDB::bind_method(godot::D_METHOD("set_activeScreensList", "screens"), &ScreenPlayGodotWallpaper::set_activeScreensList);
|
||||
|
||||
ClassDB::bind_method(godot::D_METHOD("get_projectPackageFile"), &ScreenPlayGodotWallpaper::get_projectPackageFile);
|
||||
ClassDB::bind_method(godot::D_METHOD("set_projectPackageFile", "projectPackageFile"), &ScreenPlayGodotWallpaper::set_projectPackageFile);
|
||||
|
||||
ClassDB::bind_method(godot::D_METHOD("get_projectPath"), &ScreenPlayGodotWallpaper::get_projectPath);
|
||||
ClassDB::bind_method(godot::D_METHOD("set_projectPath", "path"), &ScreenPlayGodotWallpaper::set_projectPath);
|
||||
|
||||
@ -54,6 +57,16 @@ void ScreenPlayGodotWallpaper::hideFromTaskbar(HWND hwnd)
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);
|
||||
}
|
||||
|
||||
godot::String ScreenPlayGodotWallpaper::get_projectPackageFile() const
|
||||
{
|
||||
return m_projectPackageFile;
|
||||
}
|
||||
|
||||
void ScreenPlayGodotWallpaper::set_projectPackageFile(const godot::String& projectPackageFile)
|
||||
{
|
||||
m_projectPackageFile = projectPackageFile;
|
||||
}
|
||||
|
||||
bool ScreenPlayGodotWallpaper::configureWindowGeometry()
|
||||
{
|
||||
if (!m_windowsIntegration.searchWorkerWindowToParentTo()) {
|
||||
@ -74,18 +87,26 @@ bool ScreenPlayGodotWallpaper::configureWindowGeometry()
|
||||
bool ScreenPlayGodotWallpaper::init(int activeScreen)
|
||||
{
|
||||
auto* displayServer = DisplayServer::get_singleton();
|
||||
{
|
||||
int64_t handle_int = displayServer->window_get_native_handle(godot::DisplayServer::HandleType::WINDOW_HANDLE, activeScreen);
|
||||
HWND hwnd = reinterpret_cast<HWND>(static_cast<intptr_t>(handle_int));
|
||||
m_windowsIntegration.setWindowHandle(hwnd);
|
||||
|
||||
int64_t handle_int = displayServer->window_get_native_handle(godot::DisplayServer::HandleType::WINDOW_HANDLE);
|
||||
HWND hwnd = reinterpret_cast<HWND>(handle_int);
|
||||
m_windowsIntegration.setWindowHandle(hwnd);
|
||||
ShowWindow(m_windowsIntegration.windowHandle(), SW_HIDE);
|
||||
if (!IsWindow(hwnd)) {
|
||||
UtilityFunctions::print("ScreenPlayGodotWallpaper::init Could not get a valid window handle !", activeScreen, handle_int);
|
||||
UtilityFunctions::print("init hwnd: ", (int64_t)hwnd, activeScreen, handle_int);
|
||||
|
||||
std::vector<Monitor> monitors = m_windowsIntegration.getAllMonitors();
|
||||
for (const auto& monitor : monitors) {
|
||||
UtilityFunctions::print(monitor.toString().c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
hideFromTaskbar(m_windowsIntegration.windowHandle());
|
||||
|
||||
if (!configureWindowGeometry()) {
|
||||
return false;
|
||||
}
|
||||
ShowWindow(m_windowsIntegration.windowHandle(), SW_HIDE);
|
||||
|
||||
hideFromTaskbar(m_windowsIntegration.windowHandle());
|
||||
auto updateWindowSize = [&displayServer](const int width, const int height) {
|
||||
displayServer->window_set_size(godot::Vector2((real_t)width, (real_t)height));
|
||||
};
|
||||
@ -101,38 +122,38 @@ bool ScreenPlayGodotWallpaper::init(int activeScreen)
|
||||
SetWindowText(m_windowsIntegration.windowHandle(), windowTitle.c_str());
|
||||
ShowWindow(m_windowsIntegration.windowHandle(), SW_SHOW);
|
||||
|
||||
m_windowsIntegration.setupWindowMouseHook();
|
||||
// m_windowsIntegration.setupWindowMouseHook();
|
||||
// Set up the mouse event handler
|
||||
m_windowsIntegration.setMouseEventHandler([this](DWORD mouseButton, UINT type, POINT p) {
|
||||
Ref<InputEventMouseButton> mouse_event;
|
||||
Ref<InputEventMouseMotion> motion_event;
|
||||
switch (type) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
mouse_event.instantiate();
|
||||
mouse_event->set_position(Vector2(p.x, p.y));
|
||||
mouse_event->set_global_position(Vector2(p.x, p.y)); // Assuming global == local for this context
|
||||
mouse_event->set_button_index(
|
||||
type == WM_LBUTTONDOWN || type == WM_LBUTTONUP ? MOUSE_BUTTON_LEFT : MOUSE_BUTTON_RIGHT);
|
||||
mouse_event->set_pressed(type == WM_LBUTTONDOWN || type == WM_RBUTTONDOWN);
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
motion_event.instantiate();
|
||||
motion_event->set_position(Vector2(p.x, p.y));
|
||||
motion_event->set_global_position(Vector2(p.x, p.y));
|
||||
break;
|
||||
// Add more cases as needed
|
||||
}
|
||||
// m_windowsIntegration.setMouseEventHandler([this](DWORD mouseButton, UINT type, POINT p) {
|
||||
// Ref<InputEventMouseButton> mouse_event;
|
||||
// Ref<InputEventMouseMotion> motion_event;
|
||||
// switch (type) {
|
||||
// case WM_LBUTTONDOWN:
|
||||
// case WM_LBUTTONUP:
|
||||
// case WM_RBUTTONDOWN:
|
||||
// case WM_RBUTTONUP:
|
||||
// mouse_event.instantiate();
|
||||
// mouse_event->set_position(Vector2(p.x, p.y));
|
||||
// mouse_event->set_global_position(Vector2(p.x, p.y)); // Assuming global == local for this context
|
||||
// mouse_event->set_button_index(
|
||||
// type == WM_LBUTTONDOWN || type == WM_LBUTTONUP ? MOUSE_BUTTON_LEFT : MOUSE_BUTTON_RIGHT);
|
||||
// mouse_event->set_pressed(type == WM_LBUTTONDOWN || type == WM_RBUTTONDOWN);
|
||||
// break;
|
||||
// case WM_MOUSEMOVE:
|
||||
// motion_event.instantiate();
|
||||
// motion_event->set_position(Vector2(p.x, p.y));
|
||||
// motion_event->set_global_position(Vector2(p.x, p.y));
|
||||
// break;
|
||||
// // Add more cases as needed
|
||||
// }
|
||||
|
||||
if (mouse_event.is_valid()) {
|
||||
get_tree()->get_root()->get_viewport()->push_input(mouse_event);
|
||||
}
|
||||
if (motion_event.is_valid()) {
|
||||
get_tree()->get_root()->get_viewport()->push_input(motion_event);
|
||||
}
|
||||
});
|
||||
// if (mouse_event.is_valid()) {
|
||||
// get_tree()->get_root()->get_viewport()->push_input(mouse_event);
|
||||
// }
|
||||
// if (motion_event.is_valid()) {
|
||||
// get_tree()->get_root()->get_viewport()->push_input(motion_event);
|
||||
// }
|
||||
// }); 2
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -222,18 +243,6 @@ void ScreenPlayGodotWallpaper::messageReceived(const std::string& key, const std
|
||||
std::cerr << "Out of range: " << oor.what() << std::endl;
|
||||
}
|
||||
}
|
||||
void ScreenPlayGodotWallpaper::set_checkWallpaperVisible(bool visible)
|
||||
{
|
||||
m_checkWallpaperVisible = visible;
|
||||
}
|
||||
bool ScreenPlayGodotWallpaper::get_screenPlayConnected() const
|
||||
{
|
||||
return m_screenPlayConnected;
|
||||
}
|
||||
bool ScreenPlayGodotWallpaper::get_pipeConnected() const
|
||||
{
|
||||
return m_pipeConnected;
|
||||
}
|
||||
bool ScreenPlayGodotWallpaper::exit()
|
||||
{
|
||||
// Somehow this gets called at editor startup
|
||||
@ -247,6 +256,18 @@ bool ScreenPlayGodotWallpaper::exit()
|
||||
ShowWindow(m_windowsIntegration.windowHandleWorker(), SW_HIDE);
|
||||
return true;
|
||||
}
|
||||
void ScreenPlayGodotWallpaper::set_checkWallpaperVisible(bool visible)
|
||||
{
|
||||
m_checkWallpaperVisible = visible;
|
||||
}
|
||||
bool ScreenPlayGodotWallpaper::get_screenPlayConnected() const
|
||||
{
|
||||
return m_screenPlayConnected;
|
||||
}
|
||||
bool ScreenPlayGodotWallpaper::get_pipeConnected() const
|
||||
{
|
||||
return m_pipeConnected;
|
||||
}
|
||||
bool ScreenPlayGodotWallpaper::get_checkWallpaperVisible() const
|
||||
{
|
||||
return m_checkWallpaperVisible;
|
||||
|
@ -57,6 +57,9 @@ public:
|
||||
bool send_ping();
|
||||
bool exit();
|
||||
|
||||
godot::String get_projectPackageFile() const;
|
||||
void set_projectPackageFile(const godot::String& projectPackageFile);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
@ -70,6 +73,7 @@ private:
|
||||
|
||||
godot::String m_appID = "";
|
||||
godot::String m_projectPath = "";
|
||||
godot::String m_projectPackageFile = "";
|
||||
WindowsIntegration m_windowsIntegration;
|
||||
double m_timesinceLastRead = 0.0;
|
||||
bool m_pipeConnected = false;
|
||||
|
@ -44,7 +44,7 @@ func _ready():
|
||||
get_tree().quit()
|
||||
return
|
||||
#screen_play_wallpaper.set_projectPath("C:\\Code\\cpp\\ScreenPlay\\ScreenPlay\\Content\\wallpaper_godot_fjord")
|
||||
path = screen_play_wallpaper.get_projectPath() + "/project.zip"
|
||||
path = screen_play_wallpaper.get_projectPath() + "/" + screen_play_wallpaper.get_projectPackageFile()
|
||||
else:
|
||||
get_tree().quit()
|
||||
return
|
||||
@ -55,7 +55,7 @@ func _ready():
|
||||
# yet setup via screenplay_manager.init()
|
||||
get_tree().quit()
|
||||
return
|
||||
Engine.set_max_fps(24)
|
||||
Engine.set_max_fps(144)
|
||||
|
||||
var ok = screen_play_wallpaper.init(screen_play_wallpaper.get_activeScreensList()[0])
|
||||
if not ok:
|
||||
@ -99,7 +99,7 @@ func parse_args():
|
||||
if args[0] == "res://main.tscn":
|
||||
offset = 1
|
||||
|
||||
if args.size() < 7: # Adjust this number based on the expected number of arguments
|
||||
if args.size() < 8: # Adjust this number based on the expected number of arguments
|
||||
print("Not enough arguments provided!")
|
||||
return false
|
||||
|
||||
@ -122,6 +122,7 @@ func parse_args():
|
||||
var type = args[5] # This might need further parsing depending on its expected format
|
||||
screen_play_wallpaper.set_checkWallpaperVisible(args[6 + offset].to_lower() == "true")
|
||||
screen_play_wallpaper.set_activeScreensList(activeScreensList)
|
||||
screen_play_wallpaper.set_projectPackageFile(args[7 + offset])
|
||||
|
||||
# Print or use the parsed values as needed
|
||||
print("Parsing done:", activeScreensList, screen_play_wallpaper.get_projectPath(), screen_play_wallpaper.get_appID(), screen_play_wallpaper.get_volume(), type, screen_play_wallpaper.get_checkWallpaperVisible())
|
||||
|
@ -23,14 +23,14 @@ config/icon="res://icon.svg"
|
||||
|
||||
window/size/viewport_width=1
|
||||
window/size/viewport_height=1
|
||||
window/size/mode=1
|
||||
window/size/initial_position_type=0
|
||||
window/size/initial_position=Vector2i(9999999, 9999999)
|
||||
window/size/resizable=false
|
||||
window/size/borderless=true
|
||||
window/size/transparent=true
|
||||
window/energy_saving/keep_screen_on=false
|
||||
|
||||
[editor]
|
||||
|
||||
run/main_run_args="\"0\" \"C:/Code/Cpp/ScreenPlay/ScreenPlay/Content/wallpaper_godot_fjord\" \"appID=test\" \"1\" \"Cover\" \"GodotWallpaper\" \"1\""
|
||||
run/main_run_args="\"1\" \"C:/Code/Cpp/ScreenPlay/ScreenPlay/Content/wallpaper_godot_fjord\" \"appID=test\" \"1\" \"Cover\" \"GodotWallpaper\" \"1\" \"project-v1.zip\""
|
||||
|
||||
[filesystem]
|
||||
|
||||
|
@ -104,14 +104,6 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
ImageParticle {
|
||||
height: 16
|
||||
width: 16
|
||||
source: "dot.png"
|
||||
system: particleSystem
|
||||
opacity: root.imgOpacity
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txtMousePos
|
||||
|
||||
@ -216,20 +208,17 @@ Rectangle {
|
||||
spacing: 20
|
||||
TextField {
|
||||
placeholderText: "Edit me"
|
||||
|
||||
}
|
||||
Button {
|
||||
text: "Exit"
|
||||
onClicked: {
|
||||
Qt.callLater(function () {
|
||||
Wallpaper.terminate();
|
||||
});
|
||||
Qt.callLater(function () {
|
||||
Wallpaper.terminate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
MultimediaView {
|
||||
width: 1000
|
||||
height: 400
|
||||
|
@ -1,111 +0,0 @@
|
||||
#include "windowshook.h"
|
||||
|
||||
BOOL CALLBACK WinMonitorStats::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(static_cast<int>(pThis->hdcMonitors.size()));
|
||||
|
||||
// qInfo() << std::abs(lprcMonitor->right - lprcMonitor->left) << std::abs(lprcMonitor->top - lprcMonitor->bottom);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*!
|
||||
\brief Searches for the worker window for our window to parent to.
|
||||
*/
|
||||
BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam)
|
||||
{
|
||||
// 0xXXXXXXX "" WorkerW
|
||||
// ...
|
||||
// 0xXXXXXXX "" SHELLDLL_DefView
|
||||
// 0xXXXXXXXX "FolderView" SysListView32
|
||||
// 0xXXXXXXXX "" WorkerW <---- We want this one
|
||||
// 0xXXXXXXXX "Program Manager" Progman
|
||||
if (FindWindowExW(hwnd, nullptr, L"SHELLDLL_DefView", nullptr))
|
||||
*reinterpret_cast<HWND*>(lparam) = FindWindowExW(nullptr, hwnd, L"WorkerW", nullptr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool WindowsHook::searchWorkerWindowToParentTo()
|
||||
{
|
||||
|
||||
HWND progman_hwnd = FindWindowW(L"Progman", L"Program Manager");
|
||||
const DWORD WM_SPAWN_WORKER = 0x052C;
|
||||
SendMessageTimeoutW(progman_hwnd, WM_SPAWN_WORKER, 0xD, 0x1, SMTO_NORMAL,
|
||||
10000, nullptr);
|
||||
|
||||
return EnumWindows(SearchForWorkerWindow, reinterpret_cast<LPARAM>(&windowHandleWorker));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns scaling factor as reported by Windows.
|
||||
*/
|
||||
float WindowsHook::getScaling(const int monitorIndex) const
|
||||
{
|
||||
// Get all monitors
|
||||
int monitorCount = GetSystemMetrics(SM_CMONITORS);
|
||||
|
||||
if (monitorIndex < 0 || monitorIndex >= monitorCount) {
|
||||
// Invalid monitor index
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
DISPLAY_DEVICE displayDevice;
|
||||
ZeroMemory(&displayDevice, sizeof(displayDevice));
|
||||
displayDevice.cb = sizeof(displayDevice);
|
||||
|
||||
// Enumerate through monitors until we find the one we're looking for
|
||||
for (int i = 0; EnumDisplayDevices(NULL, i, &displayDevice, 0); i++) {
|
||||
if (i == monitorIndex) {
|
||||
DEVMODE devMode;
|
||||
ZeroMemory(&devMode, sizeof(devMode));
|
||||
devMode.dmSize = sizeof(devMode);
|
||||
|
||||
// Get settings for selected monitor
|
||||
if (!EnumDisplaySettings(displayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &devMode)) {
|
||||
// Unable to get monitor settings
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
// Get DPI for selected monitor
|
||||
HMONITOR hMonitor = MonitorFromPoint({ devMode.dmPosition.x, devMode.dmPosition.y }, MONITOR_DEFAULTTONEAREST);
|
||||
UINT dpiX = 0, dpiY = 0;
|
||||
if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
|
||||
return (float)dpiX / 96.0f; // Standard DPI is 96
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we reach here, it means we couldn't find the monitor with the given index or couldn't get the DPI.
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns true of at least one monitor has active scaling enabled.
|
||||
*/
|
||||
bool WindowsHook::hasWindowScaling() const
|
||||
{
|
||||
auto enumMonitorCallback = [](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) -> BOOL {
|
||||
int scaling = GetDeviceCaps(hdcMonitor, LOGPIXELSX) / 96;
|
||||
if (scaling != 1) {
|
||||
*(bool*)dwData = true;
|
||||
return false; // Stop enumeration
|
||||
}
|
||||
return true; // Continue enumeration
|
||||
};
|
||||
|
||||
bool hasScaling = false;
|
||||
EnumDisplayMonitors(NULL, NULL, enumMonitorCallback, (LPARAM)&hasScaling);
|
||||
|
||||
return hasScaling;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <shellscalingapi.h>
|
||||
#include <vector>
|
||||
|
||||
struct WinMonitorStats {
|
||||
|
||||
WinMonitorStats()
|
||||
{
|
||||
EnumDisplayMonitors(NULL, NULL, MonitorEnum, (LPARAM)this);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData);
|
||||
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;
|
||||
int index = 0;
|
||||
};
|
||||
|
||||
struct Point {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
};
|
||||
|
||||
struct WindowsHook {
|
||||
bool searchWorkerWindowToParentTo();
|
||||
float getScaling(const int monitorIndex) const;
|
||||
bool hasWindowScaling() const;
|
||||
HWND windowHandle {};
|
||||
HWND windowHandleWorker {};
|
||||
Point zeroPoint;
|
||||
};
|
@ -68,7 +68,7 @@ BOOL SearchForWorkerWindow(HWND hwnd, LPARAM lparam)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
std::vector<Monitor> WindowsIntegration::GetAllMonitors()
|
||||
std::vector<Monitor> WindowsIntegration::getAllMonitors()
|
||||
{
|
||||
std::vector<Monitor> monitors;
|
||||
|
||||
@ -150,7 +150,7 @@ WindowsIntegration::MonitorResult WindowsIntegration::setupWallpaperForOneScreen
|
||||
return { std::nullopt, MonitorResultStatus::WorkerWindowHandleInvalidError };
|
||||
}
|
||||
|
||||
std::vector<Monitor> monitors = GetAllMonitors();
|
||||
std::vector<Monitor> monitors = getAllMonitors();
|
||||
for (const auto& monitor : monitors) {
|
||||
monitor.print();
|
||||
if (monitor.index != activeScreen)
|
||||
@ -212,7 +212,7 @@ WindowsIntegration::MonitorResult WindowsIntegration::setupWallpaperForOneScreen
|
||||
*/
|
||||
WindowsIntegration::SpanResult WindowsIntegration::setupWallpaperForMultipleScreens(const std::vector<int>& activeScreens)
|
||||
{
|
||||
std::vector<Monitor> monitors = GetAllMonitors();
|
||||
std::vector<Monitor> monitors = getAllMonitors();
|
||||
|
||||
int leftmost = INT_MAX;
|
||||
int topmost = INT_MAX;
|
||||
@ -272,7 +272,7 @@ WindowsIntegration::SpanResult WindowsIntegration::setupWallpaperForMultipleScre
|
||||
*/
|
||||
WindowsIntegration::SpanResult WindowsIntegration::setupWallpaperForAllScreens()
|
||||
{
|
||||
std::vector<Monitor> monitors = GetAllMonitors();
|
||||
std::vector<Monitor> monitors = getAllMonitors();
|
||||
|
||||
int leftmost = INT_MAX;
|
||||
int topmost = INT_MAX;
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
// Do not change windows.h order !
|
||||
#include <algorithm>
|
||||
#include <format>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
@ -22,16 +23,21 @@ struct Monitor {
|
||||
RECT position; // Monitor's position and size
|
||||
SIZE size; // Monitor's width and height
|
||||
float scaleFactor; // Scale factor (DPI scaling as a factor, e.g., 1.5 for 150% scaling)
|
||||
|
||||
std::string toString() const
|
||||
{
|
||||
return std::format(
|
||||
"Monitor Info:\n"
|
||||
"Monitor ID: {}\n"
|
||||
"Index: {}\n"
|
||||
"Position: ({}, {}, {}, {})\n"
|
||||
"Size: ({}x{})\n"
|
||||
"Scale Factor: {}\n",
|
||||
(int64_t)monitorID, index, position.left, position.top,
|
||||
position.right, position.bottom, size.cx, size.cy, scaleFactor);
|
||||
}
|
||||
void print() const
|
||||
{
|
||||
std::cout << "Monitor Info:" << std::endl;
|
||||
std::cout << "Monitor ID: " << monitorID << std::endl;
|
||||
std::cout << "Index: " << index << std::endl;
|
||||
std::cout << "Position: (" << position.left << ", " << position.top << ", "
|
||||
<< position.right << ", " << position.bottom << ")" << std::endl;
|
||||
std::cout << "Size: (" << size.cx << "x" << size.cy << ")" << std::endl;
|
||||
std::cout << "Scale Factor: " << scaleFactor << std::endl;
|
||||
std::cout << toString() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
@ -41,39 +47,6 @@ BOOL CALLBACK GetMonitorByHandle(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcM
|
||||
BOOL CALLBACK FindTheDesiredWnd(HWND hWnd, LPARAM lParam);
|
||||
BOOL WINAPI SearchForWorkerWindow(HWND hwnd, LPARAM lparam);
|
||||
|
||||
struct WinMonitorStats {
|
||||
|
||||
WinMonitorStats()
|
||||
{
|
||||
EnumDisplayMonitors(NULL, NULL, MonitorEnum, (LPARAM)this);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
std::vector<size_t> 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;
|
||||
};
|
||||
|
||||
struct Point {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
@ -112,7 +85,7 @@ public:
|
||||
|
||||
bool searchWorkerWindowToParentTo();
|
||||
float getScaling(const int monitorIndex) const;
|
||||
std::vector<Monitor> GetAllMonitors();
|
||||
std::vector<Monitor> getAllMonitors();
|
||||
int GetMonitorIndex(HMONITOR hMonitor);
|
||||
bool checkForFullScreenWindow(HWND windowHandle);
|
||||
WindowsIntegration::MonitorResult setupWallpaperForOneScreen(const int activeScreen, std::function<void(int, int)> updateWindowSize);
|
||||
|
2
ThirdParty/CMakeLists.txt
vendored
@ -11,7 +11,7 @@ FetchContent_Populate(
|
||||
FetchContent_Populate(
|
||||
qml-plausible
|
||||
GIT_REPOSITORY https://gitlab.com/kelteseth/qml-plausible.git
|
||||
GIT_TAG 5069ba3bf25663ea06be8b94c398d6c61058d4d5
|
||||
GIT_TAG 322d8e17cab77b496f0d7fafb19f6dcda4193ed7
|
||||
# Workaround because: 1. QtCreator cannot handle QML_ELEMENT stuff when it is in bin folder
|
||||
# https://bugreports.qt.io/browse/QTCREATORBUG-27083
|
||||
SOURCE_DIR ${THIRD_PARTY_PATH}/qml-plausible)
|
||||
|
@ -46,16 +46,18 @@ def execute(
|
||||
# temporary files in the build directory.
|
||||
clean_build_dir(build_config.build_folder)
|
||||
|
||||
# Build Godot Wallpaper
|
||||
# Note: This must happen before building ScreenPlay!
|
||||
if platform.system() == "Windows" and build_config.build_godot == "ON":
|
||||
build_godot.build_godot(str(build_config.bin_dir), build_config.build_type)
|
||||
|
||||
# Runs cmake configure and cmake build
|
||||
step_time = time.time()
|
||||
build_result = build(build_config, build_result)
|
||||
build_duration = time.time() - step_time
|
||||
print(f"⏱️ build_duration: {build_duration}s")
|
||||
|
||||
|
||||
# Build Godot Wallpaper
|
||||
# Note: This must happen after building ScreenPlay!
|
||||
if platform.system() == "Windows":
|
||||
build_godot.build_godot(str(build_config.bin_dir), build_config.build_type)
|
||||
|
||||
|
||||
# Copies all needed libraries and assets into the bin folder
|
||||
step_time = time.time()
|
||||
@ -181,7 +183,6 @@ def build(build_config: BuildConfig, build_result: BuildResult) -> BuildResult:
|
||||
-DSCREENPLAY_STEAM={build_config.build_steam} \
|
||||
-DSCREENPLAY_TESTS={build_config.build_tests} \
|
||||
-DSCREENPLAY_DEPLOY={build_config.build_deploy} \
|
||||
-DSCREENPLAY_GODOT={build_config.build_godot} \
|
||||
-DSCREENPLAY_INSTALLER={build_config.create_installer} \
|
||||
-DSCREENPLAY_IFW_ROOT:STRING={build_config.ifw_root_path} \
|
||||
-G "Ninja" \
|
||||
@ -287,14 +288,6 @@ def package(build_config: BuildConfig):
|
||||
print("Copy: ", file, build_config.bin_dir)
|
||||
shutil.copy2(file, build_config.bin_dir)
|
||||
|
||||
# Use Qt OpenSSLv3
|
||||
openSLL_path = Path(
|
||||
f"{defines.QT_PATH}/Tools/OpenSSLv3/Win_x64/bin").resolve()
|
||||
for file in openSLL_path.iterdir():
|
||||
if file.suffix == ".dll" and file.is_file():
|
||||
print("Copy: ", file, build_config.bin_dir)
|
||||
shutil.copy2(file, build_config.bin_dir)
|
||||
|
||||
if not platform.system() == "Darwin":
|
||||
file_endings = [".ninja_deps", ".ninja", ".ninja_log", ".lib", ".a", ".exp",
|
||||
".manifest", ".cmake", ".cbp", "CMakeCache.txt"]
|
||||
@ -365,7 +358,6 @@ if __name__ == "__main__":
|
||||
help="Create a deploy version of ScreenPlay for sharing with the world. A not deploy version is for local development only!")
|
||||
parser.add_argument('--architecture', action="store", dest="build_architecture", default="",
|
||||
help="Sets the build architecture. Used to build x86 and ARM osx versions. Currently only works with x86_64 and arm64")
|
||||
parser.add_argument('--build-godot', action="store", dest="build_godot", default="", help="Builds the Godot Wallpaper")
|
||||
args = parser.parse_args()
|
||||
|
||||
qt_version = defines.QT_VERSION
|
||||
@ -409,10 +401,6 @@ if __name__ == "__main__":
|
||||
if args.build_deploy:
|
||||
build_deploy = "ON"
|
||||
|
||||
build_godot = "OFF"
|
||||
if args.build_godot:
|
||||
build_godot = "ON"
|
||||
|
||||
create_installer = "OFF"
|
||||
if args.create_installer:
|
||||
create_installer = "ON"
|
||||
@ -429,7 +417,6 @@ if __name__ == "__main__":
|
||||
build_config.build_steam = build_steam
|
||||
build_config.build_tests = build_tests
|
||||
build_config.build_deploy = build_deploy
|
||||
build_config.build_godot = build_godot
|
||||
build_config.create_installer = create_installer
|
||||
build_config.build_type = build_type
|
||||
build_config.screenplay_version = screenplay_version
|
||||
|
@ -67,7 +67,6 @@ if __name__ == "__main__":
|
||||
build_config.build_tests = "OFF"
|
||||
build_config.build_deploy = "ON"
|
||||
build_config.create_installer = "OFF"
|
||||
build_config.build_godot = "OFF"
|
||||
build_config.build_type = "release"
|
||||
build_config.screenplay_version = screenplay_version
|
||||
|
||||
|
@ -12,7 +12,7 @@ import argparse
|
||||
def main():
|
||||
# Parse build folder as arugment
|
||||
|
||||
parser = argparse.ArgumentParser(description='Build K3000Map to the bin build folder: D:/Backup/Code/Qt/build_ScreenPlay_Qt_6.6.0_MSVC_Debug/bin')
|
||||
parser = argparse.ArgumentParser(description='Build K3000Map to the bin build folder: D:/Backup/Code/Qt/build_ScreenPlay_Qt_6.6.1_MSVC_Debug/bin')
|
||||
parser.add_argument('--build_path', dest="build_path", type=str, help='Build folder')
|
||||
parser.add_argument('--skip_if_exists', dest="skip_if_exists", default=False, action="store_true", help='Skips the build if the index.html file exists. This is used for faster CMake configure')
|
||||
|
||||
@ -20,7 +20,7 @@ def main():
|
||||
|
||||
if not args.build_path:
|
||||
print("ERROR: Please specify the build folder")
|
||||
print("py build_godot.py --build_path D:/Backup/Code/Qt/build_ScreenPlay_Qt_6.6.0_MSVC_Debug/bin/")
|
||||
print("py build_godot.py --build_path D:/Backup/Code/Qt/build_ScreenPlay_Qt_6.6.1_MSVC_Debug/bin/")
|
||||
exit()
|
||||
|
||||
# if build path exists and contains a index.html file, skip the build
|
||||
|
@ -21,14 +21,15 @@ elif sys.platform == "linux":
|
||||
REPO_PATH = Path(__file__, "../../").resolve()
|
||||
THIRDPATH_PATH = Path(REPO_PATH, "ThirdParty").resolve()
|
||||
QT_PATH = path = Path(REPO_PATH, "../aqt").resolve()
|
||||
QT_VERSION = "6.6.0"
|
||||
QT_VERSION = "6.6.1"
|
||||
QT_BIN_PATH = QT_PATH.joinpath(f"{QT_VERSION}/{QT_PLATFORM}/bin")
|
||||
QT_TOOLS_PATH = QT_PATH.joinpath("Tools/")
|
||||
QT_IFW_VERSION = "4.6"
|
||||
# 02.06.2023 https://gitlab.com/kelteseth/screenplay-vcpkg :
|
||||
VCPKG_VERSION = "f06975f46d8c7a1dad916e1e997584f77ae0c34a"
|
||||
# 25.11.2023 https://gitlab.com/kelteseth/screenplay-vcpkg :
|
||||
VCPKG_VERSION = "cabba0d0379b78e34d0a0d37edb4c459c5a03337"
|
||||
VCPKG_BASE_PACKAGES = [
|
||||
"curl",
|
||||
"openssl",
|
||||
"cpp-httplib",
|
||||
"libarchive",
|
||||
"fmt",
|
||||
@ -37,20 +38,25 @@ VCPKG_BASE_PACKAGES = [
|
||||
PYTHON_EXECUTABLE = "python" if sys.platform == "win32" else "python3"
|
||||
FFMPEG_VERSION = "6.0"
|
||||
GODOT_VERSION = "4.2"
|
||||
GODOT_RELEASE_TYPE = "beta5"
|
||||
GODOT_DOWNLOAD_SERVER = "https://downloads.tuxfamily.org/godotengine"
|
||||
GODOT_RELEASE_TYPE = "rc2"
|
||||
GODOT_DOWNLOAD_SERVER = "https://github.com/godotengine/godot-builds/releases/download"
|
||||
if sys.platform == "win32":
|
||||
SCREENPLAYWALLPAPER_GODOT_EXECUTABLE = "ScreenPlayWallpaperGodot.exe"
|
||||
GODOT_EDITOR_EXECUTABLE = f"Godot_v{GODOT_VERSION}-{GODOT_RELEASE_TYPE}_win64.exe"
|
||||
GODOT_EDITOR_DOWNLOAD_NAME = GODOT_EDITOR_EXECUTABLE + ".zip"
|
||||
GODOT_TEMPLATES_PATH = os.path.join(os.getenv(
|
||||
'APPDATA'), f"Godot/templates/{GODOT_VERSION}.{GODOT_RELEASE_TYPE}")
|
||||
elif sys.platform == "darwin":
|
||||
SCREENPLAYWALLPAPER_GODOT_EXECUTABLE = "ScreenPlayWallpaperGodot.app"
|
||||
GODOT_EDITOR_EXECUTABLE = f"Godot_v{GODOT_VERSION}-{GODOT_RELEASE_TYPE}_osx.universal"
|
||||
# Godot_v4.2-beta6_macos.universal.zip
|
||||
GODOT_EDITOR_EXECUTABLE = "Godot.app"
|
||||
GODOT_EDITOR_DOWNLOAD_NAME = f"Godot_v{GODOT_VERSION}-{GODOT_RELEASE_TYPE}_macos.universal.zip"
|
||||
GODOT_TEMPLATES_PATH = "TODO"
|
||||
elif sys.platform == "linux":
|
||||
SCREENPLAYWALLPAPER_GODOT_EXECUTABLE = "ScreenPlayWallpaperGodot"
|
||||
GODOT_EDITOR_EXECUTABLE = f"Godot_v{GODOT_VERSION}-{GODOT_RELEASE_TYPE}_x11.64"
|
||||
# Godot_v4.2-beta6_linux.x86_64
|
||||
GODOT_EDITOR_EXECUTABLE = f"Godot_v{GODOT_VERSION}-{GODOT_RELEASE_TYPE}_linux.x86_64"
|
||||
GODOT_EDITOR_DOWNLOAD_NAME = GODOT_EDITOR_EXECUTABLE + ".zip"
|
||||
# /home/eli/.local/share/godot/templates/
|
||||
GODOT_TEMPLATES_PATH = os.path.join(
|
||||
Path.home(), f".local/share/godot/templates/{GODOT_VERSION}.{GODOT_RELEASE_TYPE}")
|
||||
|
95
Tools/macos_make_universal.py
Normal file
@ -0,0 +1,95 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||
from distutils.dir_util import mkpath
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
import util
|
||||
from util import run, run_and_capture_output
|
||||
from sys import stdout
|
||||
|
||||
stdout.reconfigure(encoding='utf-8')
|
||||
|
||||
|
||||
def listfiles(path):
|
||||
files = []
|
||||
ignored = ('.DS_Store',) # Ignored files
|
||||
print(f"WALK: {path}")
|
||||
|
||||
for dirName, _, fileList in os.walk(path):
|
||||
for fname in fileList:
|
||||
if fname in ignored:
|
||||
continue # Skip ignored files
|
||||
|
||||
file_path = os.path.join(dirName, fname)
|
||||
if os.path.isfile(file_path) and (fname.endswith('.a')):
|
||||
files.append(file_path)
|
||||
if os.path.islink(file_path):
|
||||
print(f"Warning: file {file_path} is a symlink!")
|
||||
print("Symlink target: ", os.readlink(file_path))
|
||||
return files
|
||||
|
||||
def is_mach_o_binary(file_path):
|
||||
"""
|
||||
Check if a file is a Mach-O binary using the file command.
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(["file", file_path], capture_output=True, text=True)
|
||||
return 'Mach-O' in result.stdout
|
||||
except Exception as e:
|
||||
print(f"Error checking file type of {file_path}: {e}")
|
||||
return False
|
||||
|
||||
# Merges x64 and arm64 vcpkg build into universal
|
||||
def run_lipo():
|
||||
workspace_path = util.workspace_path()
|
||||
vcpkg_installed_path = str(Path(workspace_path).joinpath("vcpkg/installed/").absolute())
|
||||
arm64_dir = f"{vcpkg_installed_path}/arm64-osx"
|
||||
x64_dir = f"{vcpkg_installed_path}/x64-osx"
|
||||
universal_dir = f"{vcpkg_installed_path}/64-osx-universal"
|
||||
# Ensure the universal directory is created and empty
|
||||
run(f"rm -rf {universal_dir}", workspace_path)
|
||||
# Copy the x64 build as a base for the universal build
|
||||
run(f"cp -a {arm64_dir} {universal_dir}", workspace_path)
|
||||
|
||||
files = listfiles(str(universal_dir))
|
||||
|
||||
for file in files:
|
||||
# Extract the relative path for file
|
||||
rel_path = os.path.relpath(file, universal_dir)
|
||||
|
||||
# Construct the corresponding arm64 and x64 file paths
|
||||
arm64_file = os.path.join(arm64_dir, rel_path)
|
||||
x64_file = os.path.join(x64_dir, rel_path)
|
||||
universal_file = file # file is already in universal_dir
|
||||
|
||||
#and is_mach_o_binary(arm64_file)
|
||||
if os.path.exists(x64_file) :
|
||||
run(f"lipo -create {arm64_file} {x64_file} -output {universal_file}")
|
||||
print(f"Processing binary file: {universal_file}")
|
||||
run(f"lipo -info {universal_file}")
|
||||
else:
|
||||
print(f"Skipping non-binary file: {universal_file}")
|
||||
|
||||
def check_fat_binary():
|
||||
# Ensure the script starts from the correct directory
|
||||
workspace_path = Path(util.workspace_path())
|
||||
|
||||
dir = 'vcpkg/installed/64-osx-universal'
|
||||
universal_dir = str(workspace_path.joinpath(dir))
|
||||
print(f"check_fat_binary {universal_dir}")
|
||||
files = listfiles(universal_dir)
|
||||
|
||||
for file in files:
|
||||
out = run_and_capture_output(f"lipo -info {file}")
|
||||
if out.startswith('Non-fat'):
|
||||
out = out.replace("\n","")
|
||||
print(f"❌ {out}")
|
||||
else:
|
||||
print(f"✅ {file}")
|
||||
def execute():
|
||||
run_lipo()
|
||||
check_fat_binary()
|
||||
|
||||
if __name__ == "__main__":
|
||||
execute()
|
@ -7,6 +7,7 @@ import download_ffmpeg
|
||||
import defines
|
||||
import argparse
|
||||
import util
|
||||
import macos_make_universal
|
||||
import datetime
|
||||
import setup_godot
|
||||
from sys import stdout
|
||||
@ -54,17 +55,15 @@ def download(aqt_path: Path, qt_platform: Path):
|
||||
qt_packages = "qtwaylandcompositor "
|
||||
os = "linux"
|
||||
|
||||
# Windows: python -m aqt list-qt windows desktop --modules 6.6.0 win64_msvc2019_64
|
||||
# Linux: python3 -m aqt list-qt linux desktop --modules 6.6.0 gcc_64
|
||||
qt_packages += "qt3d qtquick3d qtconnectivity qt5compat qtimageformats qtmultimedia qtshadertools qtwebchannel qtwebengine qtwebsockets qtwebview qtpositioning"
|
||||
# Windows: python -m aqt list-qt windows desktop --modules 6.6.1 win64_msvc2019_64
|
||||
# Linux: python3 -m aqt list-qt linux desktop --modules 6.6.1 gcc_64
|
||||
print(f"Downloading: {qt_packages} to {aqt_path}")
|
||||
execute(f"{defines.PYTHON_EXECUTABLE} -m aqt install-qt -O {aqt_path} {os} desktop {defines.QT_VERSION} {qt_platform} -m {qt_packages}")
|
||||
|
||||
# Tools can only be installed one at the time:
|
||||
# see: python -m aqt list-tool windows desktop
|
||||
tools = ["tools_ifw", "tools_qtcreator", "tools_ninja", "tools_cmake"]
|
||||
if system() == "Windows":
|
||||
tools += ["tools_opensslv3_x64"]
|
||||
tools = ["tools_ifw"]
|
||||
for tool in tools:
|
||||
execute(
|
||||
f"{defines.PYTHON_EXECUTABLE} -m aqt install-tool -O {aqt_path} {os} desktop {tool}")
|
||||
@ -107,9 +106,7 @@ def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Build and Package ScreenPlay')
|
||||
parser.add_argument('--skip-aqt', action="store_true", dest="skip_aqt",
|
||||
help="Downloads QtCreator and needed binaries \Windows: C:\aqt\nLinux & macOS:~/aqt/.")
|
||||
parser.add_argument('--setup-godot', action="store_true", dest="setup_godot",
|
||||
help="Downloads Godot Editor.")
|
||||
help="Downloads QtCreator and needed binaries Windows: C:\\aqt\\nLinux & macOS:~/aqt/.")
|
||||
args = parser.parse_args()
|
||||
|
||||
root_path = Path(util.cd_repo_root_path())
|
||||
@ -117,7 +114,7 @@ def main():
|
||||
vcpkg_path = project_source_parent_path.joinpath("vcpkg").resolve()
|
||||
vcpkg_packages_list = defines.VCPKG_BASE_PACKAGES
|
||||
|
||||
if system() == "Windows" and args.setup_godot:
|
||||
if system() != "Darwin":
|
||||
if not setup_godot.execute():
|
||||
raise RuntimeError("Unable to download godot")
|
||||
|
||||
@ -140,7 +137,7 @@ def main():
|
||||
platform_command.add("chmod +x bootstrap-vcpkg.sh", vcpkg_path)
|
||||
platform_command.add("./bootstrap-vcpkg.sh", vcpkg_path, False)
|
||||
platform_command.add("chmod +x vcpkg", vcpkg_path)
|
||||
vcpkg_triplet = ["64-osx-universal"]
|
||||
vcpkg_triplet = ["x64-osx","arm64-osx"]
|
||||
elif system() == "Linux":
|
||||
vcpkg_command = "./vcpkg"
|
||||
# vcpkg_packages_list.append("infoware[opengl]")
|
||||
@ -153,7 +150,7 @@ def main():
|
||||
raise NotImplementedError("Unknown system: {}".format(system()))
|
||||
|
||||
print(f"Clone into {vcpkg_path}")
|
||||
execute("git clone https://gitlab.com/kelteseth/screenplay-vcpkg vcpkg",
|
||||
execute("git clone https://github.com/microsoft/vcpkg vcpkg",
|
||||
project_source_parent_path, True)
|
||||
execute("git fetch", vcpkg_path)
|
||||
execute(f"git checkout {defines.VCPKG_VERSION}", vcpkg_path)
|
||||
@ -167,9 +164,15 @@ def main():
|
||||
vcpkg_packages = " ".join(vcpkg_packages_list)
|
||||
execute(
|
||||
f"{vcpkg_command} install {vcpkg_packages} --triplet {triplet} --recurse", vcpkg_path, False)
|
||||
|
||||
# Combine x64 and arm
|
||||
if system() == "Darwin":
|
||||
macos_make_universal.execute()
|
||||
|
||||
if not args.skip_aqt:
|
||||
setup_qt()
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -8,19 +8,22 @@ from pathlib import Path
|
||||
import defines
|
||||
import util
|
||||
|
||||
def download_godot(version: str, exe_zip_filename: str, export_templates: str, download_destination_path: str) -> bool:
|
||||
# https://downloads.tuxfamily.org/godotengine/4.2/beta4/Godot_v4.2-beta4_win64.exe.zip
|
||||
# https://downloads.tuxfamily.org/godotengine/4.2/Godot_v4.2-beta4_win64.exe.zip
|
||||
download_export_templates = f"{defines.GODOT_DOWNLOAD_SERVER}/{version}/{defines.GODOT_RELEASE_TYPE}/{export_templates}"
|
||||
def download_godot(exe_zip_filename: str, export_templates: str, download_destination_path: str) -> bool:
|
||||
# https://github.com/godotengine/godot-builds/releases/download/4.2-beta6/Godot_v4.2-beta6_win64.exe.zip
|
||||
subfolder = f"{defines.GODOT_VERSION}-{defines.GODOT_RELEASE_TYPE}"
|
||||
base_url = f"{defines.GODOT_DOWNLOAD_SERVER}/{subfolder}"
|
||||
|
||||
download_export_templates = f"{base_url}/{export_templates}"
|
||||
exe_destination_filepath = os.path.join(
|
||||
download_destination_path, exe_zip_filename)
|
||||
export_templates_destination_path = os.path.join(
|
||||
download_destination_path, export_templates)
|
||||
|
||||
# Godot adds ".stable" to the folder names for full releases: "AppData/Roaming/Godot/templates/3.4.stable":
|
||||
print(f"Downloading Godot from {defines.GODOT_DOWNLOAD_SERVER}/")
|
||||
download_link = f"{defines.GODOT_DOWNLOAD_SERVER}/{version}/{defines.GODOT_RELEASE_TYPE}/{exe_zip_filename}"
|
||||
util.download(download_link, exe_destination_filepath, False)
|
||||
# Godot adds ".stable" to the folder names for full releases: "AppData/Roaming/Godot/templates/4.2.stable":
|
||||
download_editor = f"{base_url}/{exe_zip_filename}"
|
||||
print(f"⬇️ Downloading Godot editor {download_editor}")
|
||||
util.download(download_editor, exe_destination_filepath, False)
|
||||
print(f"⬇️ Downloading Godot export templates {download_export_templates}")
|
||||
util.download(download_export_templates,
|
||||
export_templates_destination_path, False)
|
||||
|
||||
@ -28,20 +31,20 @@ def download_godot(version: str, exe_zip_filename: str, export_templates: str, d
|
||||
|
||||
|
||||
def unzip_godot(exe_zip_filepath: str, export_templates_filepath: str, destination_path: str) -> bool:
|
||||
print("Unzip Godot")
|
||||
print("🪛 Unzip Godot")
|
||||
util.unzip(exe_zip_filepath, destination_path)
|
||||
|
||||
# The export templates contain a templates subfolder in which the content is. This is bad because it clashes
|
||||
# with the folder structure where the version comes after: AppData\Roaming\Godot\templates\3.3.4.stable
|
||||
# Rename: AppData\Roaming\Godot\templates\templates
|
||||
# to : AppData\Roaming\Godot\templates\3.4.stable
|
||||
# with the folder structure where the version comes after: /home/eli/.local/share/godot/export_templates/
|
||||
# Rename: AppData\Roaming\Godot\export_templates\templates
|
||||
# to : AppData\Roaming\Godot\export_templates\3.4.stable
|
||||
godot_templates_dir = ""
|
||||
if sys.platform == "win32":
|
||||
godot_templates_dir = os.path.join(
|
||||
os.getenv('APPDATA'), "Godot/templates/")
|
||||
os.getenv('APPDATA'), "Godot/export_templates")
|
||||
elif sys.platform == "linux":
|
||||
godot_templates_dir = os.path.join(
|
||||
str(Path.home()), ".local/share/godot/templates/")
|
||||
str(Path.home()), ".local/share/godot/export_templates")
|
||||
os.makedirs(godot_templates_dir, exist_ok=True)
|
||||
export_templates_destination_version = f"{godot_templates_dir}/{defines.GODOT_VERSION}.{defines.GODOT_RELEASE_TYPE}"
|
||||
|
||||
@ -54,14 +57,14 @@ def unzip_godot(exe_zip_filepath: str, export_templates_filepath: str, destinati
|
||||
os.rename(os.path.join(godot_templates_dir, "templates"),
|
||||
export_templates_destination_version)
|
||||
|
||||
print(f"Remove {exe_zip_filepath}")
|
||||
print(f"🚮 Remove {exe_zip_filepath}")
|
||||
try:
|
||||
os.remove(exe_zip_filepath)
|
||||
except OSError as error:
|
||||
print(f"Error deleting file: {error}")
|
||||
return False
|
||||
|
||||
print(f"Remove {export_templates_filepath}")
|
||||
print(f"🚮 Remove {export_templates_filepath}")
|
||||
try:
|
||||
os.remove(export_templates_filepath)
|
||||
except OSError as error:
|
||||
@ -72,22 +75,22 @@ def unzip_godot(exe_zip_filepath: str, export_templates_filepath: str, destinati
|
||||
|
||||
|
||||
def setup_godot() -> bool:
|
||||
print(f"Set up GODOT version {defines.GODOT_VERSION} {defines.GODOT_RELEASE_TYPE}")
|
||||
print(f"🚀 Set up GODOT version {defines.GODOT_VERSION} {defines.GODOT_RELEASE_TYPE}")
|
||||
destination_path = os.path.join(defines.THIRDPATH_PATH, "Godot")
|
||||
export_templates = f"Godot_v{defines.GODOT_VERSION}-{defines.GODOT_RELEASE_TYPE}_export_templates.tpz"
|
||||
export_templates_filepath = os.path.join(
|
||||
destination_path, export_templates)
|
||||
exe_zip_filename = defines.GODOT_EDITOR_EXECUTABLE + '.zip'
|
||||
exe_zip_filepath = os.path.join(destination_path, exe_zip_filename)
|
||||
download_godot(defines.GODOT_VERSION, exe_zip_filename,
|
||||
exe_zip_filepath = os.path.join(destination_path, defines.GODOT_EDITOR_DOWNLOAD_NAME)
|
||||
download_godot( defines.GODOT_EDITOR_DOWNLOAD_NAME,
|
||||
export_templates, destination_path)
|
||||
if not unzip_godot(exe_zip_filepath, export_templates_filepath, destination_path):
|
||||
return False
|
||||
|
||||
|
||||
# Linux needs to change file permission to be able to run godot
|
||||
if sys.platform == "linux":
|
||||
execute(f"chmod +x {defines.GODOT_EDITOR_EXECUTABLE}",
|
||||
destination_path, False)
|
||||
command = f"chmod +x {defines.GODOT_EDITOR_EXECUTABLE}"
|
||||
print(f"Make editor executable: {command} at {destination_path}")
|
||||
util.run(command,destination_path)
|
||||
|
||||
return True
|
||||
|
||||
|