1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-09-02 16:49:47 +02:00

Merge remote-tracking branch 'origin/174-add-godot-wallpaper-support' into 174-add-godot-wallpaper-support

This commit is contained in:
Elias Steurer 2023-11-29 11:33:18 +01:00
commit c5d2871440
74 changed files with 1020 additions and 566 deletions

View File

@ -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
View File

@ -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"

View File

@ -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@"

View File

@ -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})

View File

@ -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}")

View File

@ -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"
}
]
}

View File

@ -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]

View File

@ -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)

View 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

View 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

View 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

View File

@ -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

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -41,6 +41,7 @@ struct Monitor {
class MonitorListModel : public QAbstractListModel {
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
explicit MonitorListModel(QObject* parent = nullptr);

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;
};
}

View File

@ -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")
};
};
}

View File

@ -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 {

View File

@ -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"

View 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
}
}
}

View File

@ -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 {

View File

@ -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

View 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")

View File

@ -0,0 +1,6 @@
extends CSGBox3D
var rotation_speed = 3.0
func _process(delta):
rotate_y(rotation_speed * delta)

View 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"

View File

@ -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.");

View File

@ -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

View File

@ -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
}
}

View File

@ -78,7 +78,7 @@ Item {
id: radioButton
checked: settingsBool.isChecked
onCheckedChanged: {
onClicked: {
if (radioButton.checkState === Qt.Checked)
checkboxChanged(true);
else

View File

@ -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

View File

@ -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()
}
}

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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 }
{

View File

@ -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());
}

View File

@ -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;
}

View File

@ -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

View File

@ -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.

View File

@ -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"

View File

@ -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,

View File

@ -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})

View File

@ -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),

View File

@ -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");
}
}

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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())

View File

@ -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]

View File

@ -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

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}")

View 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()

View File

@ -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()

View File

@ -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