1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-25 04:02:50 +01:00

WIP: Add basic timeline

Remove plausible
Add basic FOSS plus version
This commit is contained in:
Elias Steurer 2024-03-01 09:20:11 +01:00
parent 830aaacfc4
commit 471a407246
40 changed files with 1530 additions and 551 deletions

View File

@ -9,10 +9,9 @@ set(CMAKE_AUTOMOC ON)
include(GenerateCMakeVariableHeader)
set(SOURCES
# cmake-format: sort
src/applicationengine.cpp
src/app.cpp
src/applicationengine.cpp
src/create.cpp
src/createimportvideo.cpp
src/globalvariables.cpp
@ -29,7 +28,6 @@ set(SOURCES
src/wizards.cpp)
set(HEADER
# cmake-format: sort
inc/public/ScreenPlay/app.h
inc/public/ScreenPlay/applicationengine.h
@ -51,9 +49,14 @@ set(HEADER
inc/public/ScreenPlay/wizards.h)
set(QML
# cmake-format: sort
main.qml
qml/Components/TrayIcon.qml
qml/Components/LineHandle.qml
qml/Components/LineIndicator.qml
qml/Components/ScreenPlayProPopup.qml
qml/Components/Section.qml
qml/Components/Timeline.qml
qml/Community/CommunityNavItem.qml
qml/Community/CommunityView.qml
qml/Community/XMLNewsfeed.qml
@ -68,8 +71,8 @@ set(QML
qml/Create/Wizards/HTMLWidget.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperFileSelect.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperSettings.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperSettings.qml
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml
qml/Create/Wizards/QMLWallpaper.qml
qml/Create/Wizards/QMLWidget.qml
@ -81,12 +84,14 @@ set(QML
qml/Installed/ScreenPlayItem.qml
qml/Installed/ScreenPlayItemImage.qml
qml/Installed/Sidebar.qml
qml/MainApp.qml
qml/Monitors/DefaultVideoControls.qml
qml/Monitors/MonitorSelection.qml
qml/Monitors/MonitorSelectionItem.qml
qml/Monitors/MonitorsProjectSettingItem.qml
qml/Monitors/MonitorsView.qml
qml/Monitors/SaveNotification.qml
qml/Monitors/WallpaperTimeline.qml
qml/Navigation/ExitPopup.qml
qml/Navigation/Navigation.qml
qml/Settings/SettingBool.qml
@ -97,12 +102,9 @@ set(QML
qml/Settings/SettingsHorizontalSeperator.qml
qml/Settings/SettingsPage.qml
qml/Settings/SettingsView.qml
qml/TrayIcon.qml
qml/Base.qml
qml/Workshop/WorkshopView.qml)
set(TS_FILES
# cmake-format: sort
translations/ScreenPlay_.ts
translations/ScreenPlay_de_DE.ts
@ -119,7 +121,6 @@ set(TS_FILES
translations/ScreenPlay_zh_CN.ts)
set(RESOURCES
# cmake-format: sort
"legal/Font Awesome Free License.txt"
"legal/Qt LGPLv3.txt"
@ -130,9 +131,11 @@ set(RESOURCES
assets/icons/brand_twitch.svg
assets/icons/brand_twitter.svg
assets/icons/exclamation-triangle-solid.svg
assets/icons/font-awsome/lock-solid.svg
assets/icons/font-awsome/close.svg
assets/icons/font-awsome/frown-o.svg
assets/icons/font-awsome/patreon-brands.svg
assets/icons/font-awsome/rotate-right-solid.svg
assets/icons/icon_arrow_left.svg
assets/icons/icon_arrow_right.svg
assets/icons/icon_build.svg
@ -187,7 +190,8 @@ set(RESOURCES
assets/icons/item_banner_new.svg
assets/icons/monitor_setup.svg
assets/icons/steam_default_avatar.png
assets/images/Early_Access.png
assets/images/rocket_3d.png
assets/images/pro_version.png
assets/images/Intro.png
assets/images/Intro_PC.png
assets/images/Intro_shine.png
@ -266,15 +270,15 @@ endif()
find_package(
Qt6
COMPONENTS Core
Quick
QuickControls2
Gui
Widgets
WebSockets
Svg
Xml
LinguistTools
Test)
Quick
QuickControls2
Gui
Widgets
WebSockets
Svg
Xml
LinguistTools
Test)
add_library(ScreenPlayApp STATIC)
@ -309,21 +313,20 @@ qt_add_qml_module(
target_link_libraries(
ScreenPlayApp
PUBLIC ScreenPlaySDK
LibArchive::LibArchive
ScreenPlayUtil
ScreenPlayUtilplugin
QArchive
Plausibleplugin
Threads::Threads
QCoro6::Qml
Qt6::Quick
Qt6::Gui
Qt6::Widgets
Qt6::Core
Qt6::WebSockets
Qt6::Svg
Qt6::QuickControls2
Qt6::Xml)
LibArchive::LibArchive
ScreenPlayUtil
ScreenPlayUtilplugin
QArchive
Threads::Threads
QCoro6::Qml
Qt6::Quick
Qt6::Gui
Qt6::Widgets
Qt6::Core
Qt6::WebSockets
Qt6::Svg
Qt6::QuickControls2
Qt6::Xml)
if(${SCREENPLAY_STEAM})
target_link_libraries(ScreenPlayApp PUBLIC ScreenPlayWorkshopplugin ScreenPlayWorkshop)
@ -347,8 +350,8 @@ if(${SCREENPLAY_TESTS})
endif()
if(WIN32
OR UNIX
AND NOT APPLE)
OR UNIX
AND NOT APPLE)
include(CopyRecursive)
set(FONTS_OUT_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/assets/fonts)
file(MAKE_DIRECTORY ${FONTS_OUT_DIR})
@ -406,26 +409,26 @@ if(APPLE)
set_target_properties(
${PROJECT_NAME}
PROPERTIES OUTPUT_NAME ${PROJECT_NAME}
MACOSX_BUNDLE TRUE
MACOSX_RPATH TRUE
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
MACOSX_FRAMEWORK_IDENTIFIER app.screenplay
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@loader_path/Libraries"
RESOURCE "${RESOURCE_FILES};${APP_ICON_MACOSX}" # Include the icon in the resources
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE
XCODE_ATTRIBUTE_EXECUTABLE_NAME ${PROJECT_NAME})
MACOSX_BUNDLE TRUE
MACOSX_RPATH TRUE
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist
MACOSX_FRAMEWORK_IDENTIFIER app.screenplay
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@loader_path/Libraries"
RESOURCE "${RESOURCE_FILES};${APP_ICON_MACOSX}" # Include the icon in the resources
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE
XCODE_ATTRIBUTE_EXECUTABLE_NAME ${PROJECT_NAME})
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/ffmpeg/ffmpeg"
"${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
"${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/ffmpeg/ffprobe"
"${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
"${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
# fonts
include(CopyRecursive)

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z"/></svg>

After

Width:  |  Height:  |  Size: 443 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M463.5 224H472c13.3 0 24-10.7 24-24V72c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8H463.5z"/></svg>

After

Width:  |  Height:  |  Size: 589 B

View File

@ -0,0 +1 @@
<?xml version="1.0" ?><svg height="24" version="1.1" width="24" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><g transform="translate(0 -1028.4)"><path d="m16 21.5a0.5 1.5 0 1 1 0 -0.016l-0.5 0.016z" fill="#7f8c8d" transform="matrix(3 0 0 1 -28 1027.4)"/><path d="m3 8v3 4 6c0 1.105 0.8954 2 2 2h14c1.105 0 2-0.895 2-2v-6-4-3h-18z" fill="#7f8c8d" transform="translate(0 1028.4)"/><path d="m3 8v2 4 6c0 1.105 0.8954 2 2 2h14c1.105 0 2-0.895 2-2v-6-4-2h-18z" fill="#95a5a6" transform="translate(0 1028.4)"/><path d="m3 8v3 6c0 1.105 0.8954 2 2 2h14c1.105 0 2-0.895 2-2v-6-3h-18z" fill="#bdc3c7" transform="translate(0 1028.4)"/><path d="m16 21.5a0.5 1.5 0 1 1 0 -0.016l-0.5 0.016z" fill="#7f8c8d" transform="matrix(3 0 0 1 -28 1022.4)"/><path d="m3 1031.4v3 4 6c0 1.1 0.8954 2 2 2h14c1.105 0 2-0.9 2-2v-6-4-3h-18z" fill="#7f8c8d"/><path d="m3 1031.4v2 4 6c0 1.1 0.8954 2 2 2h14c1.105 0 2-0.9 2-2v-6-4-2h-18z" fill="#95a5a6"/><path d="m3 1031.4v3 6c0 1.1 0.8954 2 2 2h14c1.105 0 2-0.9 2-2v-6-3h-18z" fill="#bdc3c7"/><path d="m16 21.5a0.5 1.5 0 1 1 0 -0.016l-0.5 0.016z" fill="#7f8c8d" transform="matrix(3 0 0 1 -28 1017.4)"/><path d="m3 4v1 6c0 1.105 0.8954 2 2 2h14c1.105 0 2-0.895 2-2v-6-1h-18z" fill="#7f8c8d" transform="translate(0 1028.4)"/><path d="m3 4v6c0 1.105 0.8954 2 2 2h14c1.105 0 2-0.895 2-2v-6h-18z" fill="#95a5a6" transform="translate(0 1028.4)"/><path d="m3 4v3c0 1.1046 0.8954 2 2 2h14c1.105 0 2-0.8954 2-2v-3h-18z" fill="#bdc3c7" transform="translate(0 1028.4)"/><path d="m21 1034.4v-3c0-1.1-0.895-2-2-2h-14c-1.1046 0-2 0.9-2 2v3h18z" fill="#bdc3c7"/></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" ?><svg height="250px" version="1.1" viewBox="0 0 250 250" width="250px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title/><desc/><defs><linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%"><stop offset="0%" stop-color="#111D2E"/><stop offset="21.248%" stop-color="#051839"/><stop offset="40.695%" stop-color="#0A1B48"/><stop offset="58.11%" stop-color="#132E62"/><stop offset="73.76%" stop-color="#144B7E"/><stop offset="87.279%" stop-color="#136497"/><stop offset="100%" stop-color="#1387B8"/></linearGradient></defs><g fill="none" fill-rule="evenodd" id="steam_squircle" stroke="none" stroke-width="1"><rect fill="url(#linearGradient-1)" height="250" id="squircle" rx="32" width="250" x="0" y="0"/><path d="M250,208 L250,218 C250,235.673112 235.673112,250 218,250 L32,250 C14.326888,250 2.164332e-15,235.673112 0,218 L0,208 C2.164332e-15,225.673112 14.326888,240 32,240 L218,240 C235.673112,240 250,225.673112 250,208 Z" fill="#000000" fill-opacity="0.25" id="shadow"/><path d="M194.165542,58.240456 L249.933594,121.239989 L249.933594,207.986328 C249.933594,225.14675 236.425883,239.152278 219.462947,239.950426 L219.132798,239.584961 C217.47759,239.849108 215.78004,239.986328 214.05044,239.986328 L82.1738281,239.986328 L57.2793822,195.345523 L62.9082031,159.898438 L73.9465185,147.78688 L93.7633885,141.693359 L152.982629,61.0661839 L194.165542,58.240456 Z" fill="#000000" id="3d-shadow" opacity="0.15452939"/><path d="M118.897563,96.6260544 C118.897563,96.833012 118.897563,97.0399696 118.908337,97.2342564 L88.192176,140.961447 C83.2164768,140.739706 78.2235382,141.59499 73.4891895,143.506181 C71.4021541,144.340347 69.4465686,145.364576 67.6116582,146.547191 L0.1638896,119.336486 L0.168945313,160.384766 L52.789074,182.532476 C55.1831848,193.017625 62.522826,202.214569 73.3512749,206.638816 C91.0679103,213.892892 111.495429,205.625146 118.865239,188.255488 C120.783114,183.715091 121.677403,178.952954 121.548109,174.201376 L165.497604,143.421708 C165.853165,143.432267 166.219501,143.442826 166.575062,143.442826 C192.875802,143.442826 214.252561,122.430292 214.252561,96.6260544 C214.252561,70.8197053 192.875802,49.826177 166.575062,49.826177 C140.285096,49.826177 118.897563,70.8197053 118.897563,96.6260544 Z M111.527753,185.235596 C105.823692,198.656165 90.0863464,205.02328 76.4069447,199.437536 C70.0962755,196.861124 65.331758,192.141223 62.5831636,186.513243 L78.1039404,192.817003 C88.192176,196.935038 99.7662256,192.246814 103.959691,182.363531 C108.166085,172.46969 103.394025,161.108138 93.3111771,156.990104 L77.2667559,150.475162 C83.4578273,148.173286 90.4957803,148.088814 97.0715041,150.770816 C103.701101,153.473936 108.844883,158.563404 111.570851,165.067787 C114.296819,171.572169 114.286044,178.752332 111.527753,185.235596 Z M166.575062,127.815414 C149.066376,127.815414 134.811612,113.824656 134.811612,96.6260544 C134.811612,79.4411799 149.066376,65.4461983 166.575062,65.4461983 C184.094523,65.4461983 198.349287,79.4411799 198.349287,96.6260544 C198.349287,113.824656 184.094523,127.815414 166.575062,127.815414 Z M142.774023,96.5785386 C142.774023,83.6405192 153.462403,73.1469227 166.628935,73.1469227 C179.806241,73.1469227 190.494621,83.6405192 190.494621,96.5785386 C190.494621,109.517614 179.806241,120.001707 166.628935,120.001707 C153.462403,120.001707 142.774023,109.517614 142.774023,96.5785386 Z" fill="#F2F2F2" fill-rule="nonzero" id="logo"/></g></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 KiB

After

Width:  |  Height:  |  Size: 599 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -31,14 +31,21 @@ public:
explicit GlobalVariables(QObject* parent = nullptr);
enum class Version {
OpenSource,
OpenSourceStandalone,
OpenSourceSteam,
OpenSourcePlus,
OpenSourcePlusSteam
OpenSourceProStandalone,
OpenSourceProSteam,
OpenSourceUltraStandalone,
OpenSourceUltraSteam
};
Q_ENUM(Version)
Q_INVOKABLE bool isBasicVersion() const;
Q_INVOKABLE bool isStandaloneVersion() const;
Q_INVOKABLE bool isSteamVersion() const;
Q_INVOKABLE bool isProVersion() const;
Q_INVOKABLE bool isUltraVersion() const;
Version version() const { return m_version; }
ScreenPlay::GlobalVariables::Version version() const { return m_version; }
QUrl localStoragePath() const { return m_localStoragePath; }
QUrl localSettingsPath() const { return m_localSettingsPath; }
QUrl wallpaperExecutablePath() const { return m_wallpaperExecutablePath; }
@ -78,6 +85,6 @@ private:
QUrl m_widgetExecutablePath;
QUrl m_godotWallpaperExecutablePath;
QUrl m_godotEditorExecutablePath;
Version m_version = Version::OpenSource;
Version m_version = Version::OpenSourceStandalone;
};
}

View File

@ -53,8 +53,6 @@ class Settings : public QObject {
Q_PROPERTY(bool autostart READ autostart WRITE setAutostart NOTIFY autostartChanged)
Q_PROPERTY(bool highPriorityStart READ highPriorityStart WRITE setHighPriorityStart NOTIFY highPriorityStartChanged)
Q_PROPERTY(bool checkWallpaperVisible READ checkWallpaperVisible WRITE setCheckWallpaperVisible NOTIFY checkWallpaperVisibleChanged)
Q_PROPERTY(bool offlineMode READ offlineMode WRITE setOfflineMode NOTIFY offlineModeChanged)
Q_PROPERTY(bool steamVersion READ steamVersion WRITE setSteamVersion NOTIFY steamVersionChanged)
Q_PROPERTY(ScreenPlay::Video::FillMode videoFillMode READ videoFillMode WRITE setVideoFillMode NOTIFY videoFillModeChanged)
Q_PROPERTY(ScreenPlay::Settings::DesktopEnvironment desktopEnvironment READ desktopEnvironment WRITE setDesktopEnvironment NOTIFY desktopEnvironmentChanged)
@ -111,8 +109,6 @@ public:
};
Q_ENUM(Theme)
bool offlineMode() const { return m_offlineMode; }
bool getOfflineMode() const { return m_offlineMode; }
bool autostart() const { return m_autostart; }
bool highPriorityStart() const { return m_highPriorityStart; }
QString decoder() const { return m_decoder; }
@ -123,7 +119,6 @@ public:
ScreenPlay::Settings::Language language() const { return m_language; }
QString font() const { return m_font; }
ScreenPlay::Settings::Theme theme() const { return m_theme; }
bool steamVersion() const { return m_steamVersion; }
ScreenPlay::Settings::DesktopEnvironment desktopEnvironment() const { return m_desktopEnvironment; }
const QString& buildInfos() const { return m_buildInfos; }
bool showDefaultContent() const { return m_showDefaultContent; }
@ -161,7 +156,6 @@ public slots:
void setHighPriorityStart(bool highPriorityStart);
void setLocalStoragePath(QUrl localStoragePath);
void setDecoder(QString decoder);
void setOfflineMode(bool offlineMode);
void setSilentStart(bool silentStart);
void setAnonymousTelemetry(bool anonymousTelemetry);
void setCheckWallpaperVisible(bool checkWallpaperVisible);
@ -169,7 +163,6 @@ public slots:
void setLanguage(ScreenPlay::Settings::Language language);
void setFont(QString font);
void setTheme(ScreenPlay::Settings::Theme theme);
void setSteamVersion(bool steamVersion);
void setDesktopEnvironment(ScreenPlay::Settings::DesktopEnvironment desktopEnvironment);
void setBuildInfos(const QString& buildInfos);
@ -187,7 +180,6 @@ private:
bool m_autostart { true };
bool m_highPriorityStart { false };
bool m_offlineMode { true };
bool m_checkWallpaperVisible { false };
bool m_silentStart { false };
bool m_anonymousTelemetry { true };
@ -199,7 +191,6 @@ private:
ScreenPlay::Settings::DesktopEnvironment m_desktopEnvironment { DesktopEnvironment::Unknown };
QString m_font { "Roboto" };
QString m_decoder;
bool m_steamVersion { false };
QString m_buildInfos;
};
}

View File

@ -21,7 +21,6 @@ Q_IMPORT_QML_PLUGIN(ScreenPlayWorkshopPlugin)
#include <QQmlEngineExtensionPlugin>
Q_IMPORT_QML_PLUGIN(ScreenPlayAppPlugin)
Q_IMPORT_QML_PLUGIN(ScreenPlayUtilPlugin)
Q_IMPORT_QML_PLUGIN(PlausiblePlugin)
int main(int argc, char* argv[])
{

View File

@ -3,7 +3,6 @@ import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Controls.Material
import Plausible 1.0
import ScreenPlayApp 1.0
import QtCore as QCore
@ -15,7 +14,8 @@ ApplicationWindow {
visible: false
width: 1400
height: 810
title: "ScreenPlay - v" + App.version()
minimumHeight: 450
minimumWidth: 1050
Component.onCompleted: {
@ -24,14 +24,30 @@ ApplicationWindow {
// and do _not_ access any other properties before we called init.
App.init()
setTheme(App.settings.theme)
if (!App.settings.silentStart) {
App.showDockIcon(true)
root.show()
}
baseLoader.setSource("qrc:/qml/ScreenPlayApp/qml/Base.qml")
baseLoader.setSource("qrc:/qml/ScreenPlayApp/qml/MainApp.qml")
const isSteamVersion = App.globalVariables.isSteamVersion()
let platform = ""
if (isSteamVersion)
platform = qsTr("Steam")
const isProVersion = App.globalVariables.isProVersion()
let featureLevel = ""
if (isProVersion)
featureLevel = qsTr("Pro")
const isUltraVersion = App.globalVariables.isUltraVersion()
if (isUltraVersion)
featureLevel = qsTr("Ultra")
root.title = "ScreenPlay - v" + App.version() + " " + featureLevel + " " + platform
}
Connections {
target: App
function onRequestExit(){
@ -84,14 +100,6 @@ ApplicationWindow {
exitDialog.open()
}
Plausible {
id: plausible
screenSize: Qt.size(root.width, root.height)
domain: "app.screen-play.app"
debug: false
enabled: false
}
Loader {
id: baseLoader
asynchronous: true

View File

@ -0,0 +1,51 @@
import QtQuick
import QtQuick.Controls
Item {
id: root
property real lineWidth: 100
property real linePosition: (root.x / lineWidth).toFixed(2)
property real lineMinimum: .5
property real lineMaximum: .5
property bool isLast: false
property alias dragHandler: dragHandler
signal handleMoved(var handle)
signal removeHandle(var handle)
signal updateNeighbors(var handle)
width: 20
height: width
Rectangle {
visible: !root.isLast
radius: width
color: dragHandler.active ? "orange" : "white"
anchors.fill: parent
}
Text {
id: txt
text: root.linePosition + "-"+ (root.linePosition * root.lineWidth).toFixed(2) + "\n" + Math.floor( dragHandler.xAxis.minimum) + " - "+ Math.floor(dragHandler.xAxis.maximum)
color: "white"
visible: false
anchors{
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: -20
}
}
DragHandler {
id: dragHandler
enabled: !root.isLast
target: root
yAxis.enabled: false
xAxis {
enabled: true
minimum: root.lineMinimum
maximum: root.lineMaximum
onActiveValueChanged: delta => {
root.handleMoved(root)
}
}
}
}

View File

@ -0,0 +1,82 @@
import QtQuick
import QtQuick.Controls
Rectangle {
id: root
property int index: 0
property bool selected: false
property bool isLast: false
property alias text: text.text
signal remove(var index)
signal lineSelected(var index)
border.width: root.selected ? 2 : 0
border.color: "gold"
Behavior on color {
id: colorBehavior
ColorAnimation {
duration: 400
}
}
Text {
id: text
color: "white"
text: root.index
anchors{
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 10
}
}
Rectangle {
id: indicatorLineVertical
width: 5
height: 30
color: parent.color
border.width: root.selected ? 2 : 0
border.color: "gold"
anchors{
horizontalCenter: parent.horizontalCenter
top: parent.bottom
topMargin: 0
}
}
Rectangle {
id: background
width: 70
height: 48
radius: 5
border.width: root.selected ? 2 : 0
border.color: "gold"
color: parent.color
anchors{
horizontalCenter: parent.horizontalCenter
top: indicatorLineVertical.bottom
topMargin: -1
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked:{
root.lineSelected(root.index)
}
}
}
ToolButton {
text:"❌"
visible: !root.isLast
enabled: visible
onClicked: root.remove(root.index)
font.pointSize: 10
anchors{
left: background.right
bottom: background.top
margins: - 20
}
}
}

View File

@ -0,0 +1,314 @@
import QtQuick
import QtQuick.Controls
import ScreenPlayUtil
import ScreenPlayApp
Dialog {
id: dialog
width: 1200
height: 700
dim: true
anchors.centerIn: Overlay.overlay
modal: true
focus: true
property alias message: messageText.text
Text {
id: messageText
color: Material.primaryTextColor
}
onOpened: wrapper.state = "in"
onClosed: wrapper.state = "out"
Rectangle {
id: wrapper
state: "out"
color: Material.backgroundColor
anchors {
fill: parent
}
clip: true
Image {
id: imgBg
source: "qrc:/qml/ScreenPlayApp/assets/images/Intro.png"
anchors.fill: parent
}
Item {
height: parent.height
anchors {
top: parent.top
topMargin: parent.height * 0.5 + 50
right: parent.right
left: parent.left
}
Image {
id: imgShine
source: "qrc:/qml/ScreenPlayApp/assets/images/Intro_shine.png"
height: 1753
width: 1753
opacity: 0
anchors.centerIn: parent
RotationAnimator {
target: imgShine
from: 0
to: 360
duration: 1000000
running: true
loops: Animation.Infinite
}
}
}
Image {
id: imgLogo
source: "qrc:/qml/ScreenPlayApp/assets/images/pro_version.png"
width: 539
height: 148
sourceSize: Qt.size(width, height)
anchors {
top: parent.top
topMargin: -200
horizontalCenter: parent.horizontalCenter
}
}
Text {
id: txtHeadline
y: 80
text: qsTr("✅ 3D Wallpaper\n✅ Wallpaper Timeline")
font.family: App.settings.font
font.capitalization: Font.Capitalize
wrapMode: Text.WordWrap
color: "white"
font.pointSize: 21
horizontalAlignment: Text.AlignHCenter
anchors {
right: parent.right
left: parent.left
top: parent.top
}
}
Image {
id: imgPC
source: "qrc:/qml/ScreenPlayApp/assets/images/Intro_PC.png"
width: 500 * 0.8
height: 500 * 0.8
sourceSize: Qt.size(width, height)
anchors {
top: parent.top
topMargin: 50
horizontalCenter: parent.horizontalCenter
}
}
Button {
id: btnWorkshop
text: qsTr("Get ScreenPlay Pro")
Material.background: Material.color(Material.Orange)
Material.foreground: "white"
font.pointSize: 16
width: implicitWidth + 20
height: implicitHeight + 10
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_community.svg"
icon.width: 18
icon.height: 18
onClicked: {
if (App.globalVariables.isSteamVersion()) {
Qt.openUrlExternally("https://forum.screen-play.app/")
} else {
Qt.openUrlExternally("https://forum.screen-play.app/")
}
}
anchors {
bottom: parent.bottom
bottomMargin: -100
horizontalCenter: parent.horizontalCenter
}
}
ToolButton {
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_close.svg"
icon.color: "transparent"
onClicked: dialog.close()
anchors {
top: parent.top
right: parent.right
}
}
states: [
State {
name: "out"
PropertyChanges {
target: imgBg
opacity: 0
}
PropertyChanges {
target: imgShine
opacity: 0
}
PropertyChanges {
target: imgPC
opacity: 0
anchors.topMargin: -500
}
PropertyChanges {
target: imgLogo
opacity: 1
anchors.topMargin: -500
}
PropertyChanges {
target: txtHeadline
opacity: 0
anchors.topMargin: 0
}
PropertyChanges {
target: btnWorkshop
anchors.bottomMargin: -100
}
},
State {
name: "in"
PropertyChanges {
target: imgBg
opacity: 1
}
PropertyChanges {
target: imgShine
opacity: 0.5
}
PropertyChanges {
target: imgPC
opacity: 1
anchors.topMargin: 250
}
PropertyChanges {
target: imgLogo
opacity: 1
anchors.topMargin: 50
}
PropertyChanges {
target: txtHeadline
color: "#ffffff"
opacity: 1
anchors.topMargin: 250
}
PropertyChanges {
target: btnWorkshop
anchors.bottomMargin: 50
}
}
]
transitions: [
Transition {
from: "out"
to: "in"
reversible: true
ParallelAnimation {
PropertyAnimation {
targets: imgBg
property: "opacity"
duration: 400
}
PropertyAnimation {
targets: imgShine
property: "opacity"
duration: 600
}
}
SequentialAnimation {
PauseAnimation {
duration: 200
}
PropertyAnimation {
targets: imgPC
property: "topMargin"
duration: 700
easing.type: Easing.OutBack
}
PropertyAnimation {
targets: imgPC
property: "opacity"
duration: 600
easing.type: Easing.OutBack
}
}
ParallelAnimation {
PropertyAnimation {
targets: imgLogo
property: "opacity"
duration: 600
easing.type: Easing.InOutExpo
}
PropertyAnimation {
targets: imgLogo
property: "topMargin"
duration: 1000
easing.type: Easing.InOutExpo
}
}
SequentialAnimation {
PauseAnimation {
duration: 400
}
PropertyAnimation {
targets: txtHeadline
properties: "topMargin, opacity"
duration: 1100
easing.type: Easing.InOutExpo
}
}
SequentialAnimation {
PauseAnimation {
duration: 600
}
PropertyAnimation {
targets: btnWorkshop
properties: "bottomMargin"
duration: 1500
easing.type: Easing.OutBack
}
}
}
]
}
}

View File

@ -0,0 +1,8 @@
import QtQuick
Item {
property int index: 0
property real relativeLinePosition: 0
property LineHandle lineHandle
property LineIndicator lineIndicator
}

View File

@ -0,0 +1,277 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Control {
id: root
height: 250
implicitWidth: 800
topPadding: 40
leftPadding: 40
rightPadding: 40
contentItem: Item {
id: timeLine
property var sectionsList: []
property var lineColors: ["#E53935", "#D81B60", "#8E24AA", "#5E35B1", "#3949AB", "#1E88E5", "#00897B", "#43A047", "#C0CA33", "#FFB300", "#FB8C00", "#F4511E"]
onWidthChanged: timeLine.updatePositions()
Component.onCompleted: {
const initialStopPositions = [1]
createAllSections(initialStopPositions)
}
function createAllSections(initialStopPositions) {
for (let index in initialStopPositions) {
addSection(initialStopPositions[Number(index)])
}
}
function addSection(stopPosition) {
print("stopPosition", stopPosition)
//if (!isFloat(stopPosition))
// console.error(typeof (stopPosition), stopPosition)
// Make sure to limit float precision
const fixedStopPosition = stopPosition
print("addSection at: ", fixedStopPosition)
if (stopPosition < 0 || fixedStopPosition > 1) {
console.error("Invalid position:", fixedStopPosition)
return
}
let sectionComponent = Qt.createComponent("Section.qml")
if (sectionComponent.status === Component.Error) {
console.error(sectionComponent.errorString())
return
}
let sectionObject = sectionComponent.createObject(timeLine, {
"relativeLinePosition": fixedStopPosition
})
timeLine.sectionsList.push(sectionObject)
timeLine.sectionsList.sort(function (a, b) {
return a.relativeLinePosition - b.relativeLinePosition
})
const index = timeLine.sectionsList.indexOf(sectionObject)
console.log("Addsection:", index)
createSection(index, fixedStopPosition, sectionObject)
updatePositions()
}
function createSection(index, stopPosition, section) {
console.log("Adding at:", index, stopPosition)
//console.assert(isFloat(stopPosition))
let haComponent = Qt.createComponent("LineHandle.qml")
if (haComponent.status === Component.Error) {
console.assert(haComponent.errorString())
return
}
section.lineHandle = haComponent.createObject(handleWrapper)
section.lineHandle.lineWidth = timeLine.width
section.lineHandle.x = Math.round(
handleWrapper.width * timeLine.sectionsList[index].relativeLinePosition)
section.lineHandle.y = -section.lineHandle.height / 2
// Will be set later
section.lineHandle.lineMinimum = timeLine.x
section.lineHandle.lineMaximum = timeLine.x
section.lineHandle.handleMoved.connect(timeLine.updatePositions)
let liComponent = Qt.createComponent("LineIndicator.qml")
if (liComponent.status === Component.Error) {
console.assert(liComponent.errorString())
return
}
// Set color initially so we do not have a weird color animation at start
const lineIndicatorProperties = {
"color": getColorAtIndex(index)
}
section.lineIndicator = liComponent.createObject(
lineIndicatorWrapper, lineIndicatorProperties)
section.lineIndicator.height = lineIndicatorWrapper.height
section.lineIndicator.index = index
section.lineIndicator.color = getColorAtIndex(index)
section.lineIndicator.remove.connect(timeLine.removeSection)
section.lineIndicator.lineSelected.connect(
timeLine.lineIndicatorSelected)
}
function lineIndicatorSelected(selectedIndicatorindex) {
for (var i = 0; i < timeLine.sectionsList.length; i++) {
if (i === selectedIndicatorindex) {
timeLine.sectionsList[i].lineIndicator.selected = true
continue
}
timeLine.sectionsList[i].lineIndicator.selected = false
}
}
// We must update all indexes when removing/adding an element
function updateIndicatorIndexes() {
for (var i = 0; i < timeLine.sectionsList.length; i++) {
timeLine.sectionsList[i].index = i
timeLine.sectionsList[i].lineIndicator.index = i
}
}
function removeSection(index) {
print(timeLine.stopPositionList)
print(timeLine.sectionList)
const isLast = index === timeLine.sectionsList.length - 1
if (isLast)
return
// ORDER is important here! First destory the object
// and then remove i f
let section = timeLine.sectionsList[index]
section.lineHandle.destroy()
section.lineIndicator.destroy()
section.destroy()
timeLine.sectionsList.splice(index, 1)
updatePositions()
}
function updatePositions() {
// Iterate through each handle in the 'sectionList' array
for (var i = 0; i < timeLine.sectionsList.length; i++) {
let handle = timeLine.sectionsList[i].lineHandle
// Determine the minimum position for the current handle
let prevPos
if (i === 0) {
// If it's the first handle, its minimum is 0
prevPos = 0
} else {
// Otherwise, it's directly the position of the previous handle
prevPos = timeLine.sectionsList[i - 1].lineHandle.x
}
// Determine the maximum position for the current handle
let nextPos
if (i === timeLine.sectionsList.length - 1) {
// If it's the last handle, its maximum is the width of the line
nextPos = timeLine.width
} else {
// Otherwise, it's directly the position of the next handle
nextPos = timeLine.sectionsList[i + 1].lineHandle.x
}
// Set the determined minimum and maximum positions for the current handle
handle.lineMinimum = prevPos
handle.lineMaximum = nextPos
}
updateIndicatorIndexes()
updateIndicatorPositions()
updateLastHandle()
updateIndicatorColor()
}
function getColorAtIndex(index) {
let i = index
// Start from the beginnging again
if (index >= timeLine.lineColors.length) {
i = index % timeLine.lineColors.length
}
return timeLine.lineColors[i]
}
function updateIndicatorColor() {
for (var i = 0; i < timeLine.sectionsList.length; i++) {
let lineIndicator = timeLine.sectionsList[i].lineIndicator
lineIndicator.color = getColorAtIndex(i)
}
}
function updateLastHandle() {
for (var i = 0; i < timeLine.sectionsList.length; i++) {
timeLine.sectionsList[i].lineHandle.isLast = i === timeLine.sectionsList.length - 1
timeLine.sectionsList[i].lineIndicator.isLast = i
=== timeLine.sectionsList.length - 1
}
}
function updateIndicatorPositions() {
for (var i = 0; i < timeLine.sectionsList.length; i++) {
const lineIndicator = timeLine.sectionsList[i].lineIndicator
print(i, lineIndicator.x, lineIndicator.width)
const handle = timeLine.sectionsList[i].lineHandle
lineIndicator.x = handle.dragHandler.xAxis.minimum
lineIndicator.width = (handle.linePosition * handle.lineWidth).toFixed(
2) - lineIndicator.x
}
}
// https://stackoverflow.com/a/3885844
function isFloat(n) {
return n === +n && n !== (n | 0)
}
Rectangle {
id: addHandleWrapper
color: Material.color(Material.Grey, Material.Shade900)
height: 30
anchors {
left: parent.left
right: parent.right
top: parent.top
}
HoverHandler {
id: hoverHandler
enabled: true
}
ToolButton {
text: ""
onClicked: {
const p = this.x / timeLine.width
const position = p.toFixed(2)
timeLine.addSection(position)
}
x: hoverHandler.point.position.x - width * .5
anchors.verticalCenter: parent.verticalCenter
}
}
Item {
id: lineIndicatorWrapper
height: 5
anchors {
left: parent.left
right: parent.right
top: addHandleWrapper.bottom
}
}
Item {
id: handleWrapper
height: 5
anchors {
left: parent.left
right: parent.right
top: addHandleWrapper.bottom
}
}
Item {
height: 18
width: 5
anchors {
right: parent.left
top: addHandleWrapper.bottom
topMargin: -9
}
}
Rectangle {
height: 18
width: 5
color: "#757575"
anchors {
right: parent.right
top: addHandleWrapper.bottom
topMargin: -9
}
}
}
}

View File

@ -5,8 +5,8 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl
import ScreenPlayApp
import ScreenPlayUtil
import "../Components"
Rectangle {
id: root
@ -36,13 +36,13 @@ Rectangle {
id: loaderConnections
function onWizardStarted() {
root.expanded = false;
root.expanded = false
}
function onWizardExited() {
root.expanded = true;
App.util.setNavigation("Installed");
App.util.setNavigationActive(true);
root.expanded = true
App.util.setNavigation("Installed")
App.util.setNavigationActive(true)
}
ignoreUnknownSignals: true
@ -53,6 +53,7 @@ Rectangle {
headline: qsTr("Tools Overview")
source: "qrc:/qml/ScreenPlayApp/qml/Create/StartInfo.qml"
category: "Home"
proFeature: false
}
ListElement {
@ -60,48 +61,56 @@ Rectangle {
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml"
category: "Video Wallpaper"
objectName: "videoImportConvert"
proFeature: false
}
ListElement {
headline: qsTr("GIF Wallpaper")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/GifWallpaper.qml"
category: "Video Wallpaper"
proFeature: false
}
ListElement {
headline: qsTr("3D Engine Wallpaper (Godot 4.2)")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/GodotWallpaper.qml"
category: "3D Engine & \nCode Wallpaper"
proFeature: true
}
ListElement {
headline: qsTr("QML Wallpaper")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/QMLWallpaper.qml"
category: "3D Engine & \nCode Wallpaper"
proFeature: false
}
ListElement {
headline: qsTr("HTML5 Wallpaper")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/HTMLWallpaper.qml"
category: "3D Engine & \nCode Wallpaper"
proFeature: false
}
ListElement {
headline: qsTr("Website Wallpaper")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/WebsiteWallpaper.qml"
category: "3D Engine & \nCode Wallpaper"
proFeature: false
}
ListElement {
headline: qsTr("QML Widget")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/QMLWidget.qml"
category: "Widgets"
proFeature: false
}
ListElement {
headline: qsTr("HTML Widget")
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/HTMLWidget.qml"
category: "Widgets"
proFeature: false
}
}
@ -114,7 +123,7 @@ Rectangle {
height: headline.contentHeight + 20
Text {
id:headline
id: headline
font.pointSize: 18
color: Material.primaryTextColor
text: section
@ -135,13 +144,32 @@ Rectangle {
highlighted: ListView.isCurrentItem
text: headline
onClicked: {
listView.currentIndex = index;
const item = stackView.push(source);
loaderConnections.target = item;
if (proFeature && App.globalVariables.isBasicVersion())
return screenPlayProView.open()
listView.currentIndex = index
const item = stackView.push(source)
loaderConnections.target = item
}
ToolButton {
enabled: false
visible: proFeature && App.globalVariables.isBasicVersion()
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/font-awsome/lock-solid.svg"
icon.width: 10
icon.height: 10
icon.color: "gold"
anchors {
top: listItem.top
topMargin: -10
right: listItem.right
rightMargin: -10
}
}
}
}
ScreenPlayProPopup {
id: screenPlayProView
}
layer.effect: ElevationEffect {
elevation: 6
}

View File

@ -125,7 +125,6 @@ Item {
implicitWidth: height
icon.width: height
icon.height: height
icon.color: Material.iconColor
}
}

View File

@ -7,8 +7,8 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl
import QtCore as QCore
import ScreenPlayApp
import ScreenPlayUtil as Util
import "../Components"
Item {
id: root
@ -23,23 +23,21 @@ Item {
function checkIsContentInstalled() {
if (App.installedListModel.count === 0) {
loaderHelp.active = true;
gridView.footerItem.isVisible = true;
gridView.visible = false;
navWrapper.visible = false;
gridView.footerItem.isVisible = true
gridView.visible = false
navWrapper.visible = false
} else {
loaderHelp.active = false;
gridView.footerItem.isVisible = false;
refresh = false;
gridView.contentY = -82;
gridView.visible = true;
navWrapper.visible = true;
gridView.footerItem.isVisible = false
refresh = false
gridView.contentY = -82
gridView.visible = true
navWrapper.visible = true
}
}
StackView.onActivated: {
navWrapper.state = "in";
checkIsContentInstalled();
navWrapper.state = "in"
checkIsContentInstalled()
}
Action {
@ -49,27 +47,24 @@ Item {
Connections {
function onInstalledLoadingFinished() {
checkIsContentInstalled();
checkIsContentInstalled()
}
function onCountChanged(count) {
if (count === 0)
checkIsContentInstalled();
checkIsContentInstalled()
}
target: App.installedListModel
}
Loader {
id: loaderHelp
active: false
anchors.fill: parent
source: "qrc:/qml/ScreenPlayApp/qml/Installed/InstalledWelcomeScreen.qml"
ScreenPlayProPopup {
id: screenPlayProView
}
Connections {
function onSortChanged() {
gridView.positionViewAtBeginning();
gridView.positionViewAtBeginning()
}
target: App.installedListFilter
@ -122,12 +117,12 @@ Item {
}
onContentYChanged: {
if (contentY <= -180)
gridView.headerItem.isVisible = true;
gridView.headerItem.isVisible = true
else
gridView.headerItem.isVisible = false;
gridView.headerItem.isVisible = false
//Pull to refresh
if (contentY <= -180 && !refresh && !isDragging)
App.installedListModel.reset();
App.installedListModel.reset()
}
anchors {
@ -144,11 +139,11 @@ Item {
opacity: 0
onIsVisibleChanged: {
if (isVisible) {
txtHeader.color = Material.accent;
txtHeader.text = qsTr("Refreshing!");
txtHeader.color = Material.accent
txtHeader.text = qsTr("Refreshing!")
} else {
txtHeader.color = "gray";
txtHeader.text = qsTr("Pull to refresh!");
txtHeader.color = "gray"
txtHeader.text = qsTr("Pull to refresh!")
}
}
@ -156,7 +151,7 @@ Item {
interval: 150
running: true
onTriggered: {
animFadeIn.start();
animFadeIn.start()
}
}
@ -200,7 +195,7 @@ Item {
interval: 400
running: true
onTriggered: {
animFadeInTxtFooter.start();
animFadeInTxtFooter.start()
}
}
@ -228,25 +223,30 @@ Item {
publishedFileID: m_publishedFileID
itemIndex: index
isScrolling: gridView.isScrolling
onOpenOpenLicensePopup: function () {
screenPlayProView.open()
}
onOpenContextMenu: function (position) {
// Set the menu to the current item informations
contextMenu.publishedFileID = delegate.publishedFileID;
contextMenu.absoluteStoragePath = delegate.absoluteStoragePath;
contextMenu.fileName = delegate.customTitle;
contextMenu.type = delegate.type;
print(delegate.publishedFileID);
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);
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;
return
if (delegate.type === Util.ContentTypes.InstalledType.GodotWallpaper) {
contextMenu.godotItem = editGodotWallpaperComp.createObject();
contextMenu.insertItem(0, contextMenu.godotItem);
contextMenu.godotItem = editGodotWallpaperComp.createObject(
)
contextMenu.insertItem(0, contextMenu.godotItem)
}
contextMenu.popup(pos.x, pos.y);
contextMenu.popup(pos.x, pos.y)
}
}
@ -263,7 +263,9 @@ Item {
enabled: contextMenu.type === Util.ContentTypes.InstalledType.GodotWallpaper
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_edit.svg"
onClicked: {
App.util.openGodotEditor(contextMenu.absoluteStoragePath, App.globalVariables.godotEditorExecutablePath);
App.util.openGodotEditor(
contextMenu.absoluteStoragePath,
App.globalVariables.godotEditorExecutablePath)
}
}
}
@ -284,7 +286,7 @@ Item {
objectName: "openFolder"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_folder_open.svg"
onClicked: {
App.util.openFolderInExplorer(contextMenu.absoluteStoragePath);
App.util.openFolderInExplorer(contextMenu.absoluteStoragePath)
}
}
@ -293,10 +295,12 @@ Item {
objectName: enabled ? "removeItem" : "removeWorkshopItem"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_import_export_.svg"
onClicked: {
exportFileDialog.absoluteStoragePath = contextMenu.absoluteStoragePath;
let urlFileName = QCore.StandardPaths.writableLocation(QCore.StandardPaths.DesktopLocation) + "/" + contextMenu.fileName + ".screenplay";
exportFileDialog.currentFile = urlFileName;
exportFileDialog.open();
exportFileDialog.absoluteStoragePath = contextMenu.absoluteStoragePath
let urlFileName = QCore.StandardPaths.writableLocation(
QCore.StandardPaths.DesktopLocation) + "/"
+ contextMenu.fileName + ".screenplay"
exportFileDialog.currentFile = urlFileName
exportFileDialog.open()
}
}
@ -304,18 +308,21 @@ Item {
text: enabled ? qsTr("Remove Item") : qsTr("Remove via Workshop")
objectName: enabled ? "removeItem" : "removeWorkshopItem"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_delete.svg"
enabled: contextMenu.publishedFileID === 0 || !App.settings.steamVersion
enabled: contextMenu.publishedFileID === 0
|| !App.globalVariables.isSteamVersion()
onClicked: {
deleteDialog.open();
deleteDialog.open()
}
}
MenuItem {
text: qsTr("Open Workshop Page")
enabled: contextMenu.publishedFileID !== 0 && App.settings.steamVersion
enabled: contextMenu.publishedFileID !== 0
&& App.globalVariables.isSteamVersion()
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg"
onClicked: {
Qt.openUrlExternally("steam://url/CommunityFilePage/" + contextMenu.publishedFileID);
Qt.openUrlExternally(
"steam://url/CommunityFilePage/" + contextMenu.publishedFileID)
}
}
}
@ -328,9 +335,11 @@ Item {
modalSource: root.modalSource
anchors.centerIn: Overlay.overlay
onAccepted: {
root.sidebar.clear();
if (!App.installedListModel.deinstallItemAt(contextMenu.absoluteStoragePath)) {
console.error("Unable to uninstall item", contextMenu.absoluteStoragePath);
root.sidebar.clear()
if (!App.installedListModel.deinstallItemAt(
contextMenu.absoluteStoragePath)) {
console.error("Unable to uninstall item",
contextMenu.absoluteStoragePath)
}
}
}
@ -340,7 +349,7 @@ Item {
fileMode: FileDialog.SaveFile
property string absoluteStoragePath
onAccepted: {
exportFileProgressDialog.open();
exportFileProgressDialog.open()
}
}
@ -353,10 +362,11 @@ Item {
modalSource: root.modalSource
closePolicy: Popup.NoAutoClose
onOpened: {
const success = archive.exportProject(exportFileDialog.absoluteStoragePath, exportFileDialog.currentFile);
const success = archive.exportProject(
exportFileDialog.absoluteStoragePath,
exportFileDialog.currentFile)
}
onClosed: exportProgressBar.value = 0
ColumnLayout {
width: parent.width
@ -380,10 +390,10 @@ Item {
id: exportConnections
target: archive
function onCompressionProgressChanged(file, proc, total, br, bt) {
exportProgressBar.value = (br * 100 / bt);
exportProgressBar.value = (br * 100 / bt)
}
function onCompressionFinished() {
exportFileProgressDialog.close();
exportFileProgressDialog.close()
}
}
}
@ -399,7 +409,7 @@ Item {
}
Util.Archive {
id:archive
id: archive
}
DropArea {
@ -407,29 +417,31 @@ Item {
anchors.fill: parent
property string filePath
onEntered: function (drag) {
dropPopup.open();
dropPopup.open()
}
onDropped: function (drop) {
dropPopup.close();
dropArea.enabled = false;
dropPopup.close()
dropArea.enabled = false
if (drop.urls.length > 1) {
importProjectErrorDialog.title = qsTr("We only support adding one item at once.");
importProjectErrorDialog.open();
return;
importProjectErrorDialog.title = qsTr(
"We only support adding one item at once.")
importProjectErrorDialog.open()
return
}
var file = "";
var file = ""
// Convert url to string
file = "" + drop.urls[0];
file = "" + drop.urls[0]
if (!file.endsWith('.screenplay')) {
importProjectErrorDialog.title = qsTr("File type not supported. We only support '.screenplay' files.");
importProjectErrorDialog.open();
return;
importProjectErrorDialog.title = qsTr(
"File type not supported. We only support '.screenplay' files.")
importProjectErrorDialog.open()
return
}
importDialog.open();
dropArea.filePath = file;
importDialog.open()
dropArea.filePath = file
}
onExited: {
dropPopup.close();
dropPopup.close()
}
Util.Dialog {
@ -450,9 +462,11 @@ Item {
closePolicy: Popup.NoAutoClose
onClosed: importProgressBar.value = 0
onOpened: {
const success = archive.importProject(dropArea.filePath, App.globalVariables.localStoragePath);
print("finished", success);
dropArea.filePath = "";
const success = archive.importProject(
dropArea.filePath,
App.globalVariables.localStoragePath)
print("finished", success)
dropArea.filePath = ""
}
ColumnLayout {
width: parent.width
@ -474,10 +488,10 @@ Item {
id: importConnections
target: archive
function onExtractionProgressChanged(file, proc, total, br, bt) {
importProgressBar.value = (br * 100 / bt);
importProgressBar.value = (br * 100 / bt)
}
function onExtractionFinished() {
importDialog.close();
importDialog.close()
}
}
}
@ -493,8 +507,8 @@ Item {
modal: true
onOpened: fileDropAnimation.state = "fileDrop"
onClosed: {
fileDropAnimation.state = "";
dropArea.enabled = true;
fileDropAnimation.state = ""
dropArea.enabled = true
}
Util.FileDropAnimation {

View File

@ -2,7 +2,6 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import ScreenPlayApp
import ScreenPlayUtil
Item {
@ -70,7 +69,7 @@ Item {
id: txtHeadline
y: 80
text: App.settings.steamVersion ? qsTr("Get free Widgets and Wallpaper via the Steam Workshop") : qsTr("Get content via our forum")
text: App.globalVariables.isSteamVersion() ? qsTr("Get free Widgets and Wallpaper via the Steam Workshop") : qsTr("Get content via our forum")
font.family: App.settings.font
font.capitalization: Font.Capitalize
wrapMode: Text.WordWrap
@ -104,7 +103,7 @@ Item {
id: btnWorkshop
text: {
if (App.settings.steamVersion) {
if (App.globalVariables.isSteamVersion()) {
return qsTr("Browse the Steam Workshop");
} else {
return qsTr("Open the ScreenPlay forum");
@ -116,7 +115,7 @@ Item {
width: implicitWidth + 20
height: implicitHeight + 10
icon.source: {
if (App.settings.steamVersion) {
if (App.globalVariables.isSteamVersion()) {
return "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg";
} else {
return "qrc:/qml/ScreenPlayApp/assets/icons/icon_community.svg";
@ -125,7 +124,7 @@ Item {
icon.width: 18
icon.height: 18
onClicked: {
if (App.settings.steamVersion) {
if (App.globalVariables.isSteamVersion()) {
App.util.setNavigation("Workshop");
} else {
Qt.openUrlExternally("https://forum.screen-play.app/");

View File

@ -3,7 +3,6 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Controls
import QtQuick.Controls.Material
import ScreenPlayApp
import ScreenPlayUtil as Util
Item {
@ -12,15 +11,25 @@ Item {
property string customTitle
property string screenId
property url absoluteStoragePath
property int type: ContentTypes.InstalledType.Unknown
property int type: Util.ContentTypes.InstalledType.Unknown
// Must be var to make it work wit 64bit ints
property var publishedFileID: 0
property int itemIndex
property bool isScrolling: false
property bool isNew: false
property bool containsAudio: false
property int version: App.globalVariables.version
property bool hasLicense: {
if ((root.version === GlobalVariables.OpenSourceStandalone
|| root.version === GlobalVariables.OpenSourceSteam)
&& root.type === Util.ContentTypes.InstalledType.GodotWallpaper) {
return false
}
return true
}
signal openContextMenu(point position)
signal openOpenLicensePopup
width: 320
height: 180
@ -140,7 +149,7 @@ Item {
text: root.customTitle
font.family: App.settings.font
font.pointSize: 16
visible: !screenPlayItemImage.visible
visible: !screenPlayItemImage.visible && root.hasLicense
color: Material.primaryTextColor
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
@ -148,7 +157,7 @@ Item {
ScreenPlayItemImage {
id: screenPlayItemImage
opacity: root.hasLicense ? 1 : 0.3
anchors.fill: parent
enabled: visible
visible: m_preview !== "" || m_previewGIF !== ""
@ -219,6 +228,20 @@ Item {
anchors.centerIn: parent
}
}
ToolButton {
enabled: false
visible: !root.hasLicense
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/font-awsome/lock-solid.svg"
icon.height: 14
icon.width: 11
icon.color: "gold"
opacity: .5
anchors {
top: parent.top
right: parent.right
}
}
}
OpacityMask {
@ -232,6 +255,8 @@ Item {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
onEntered: {
if (!root.hasLicense)
return
root.state = "hover"
screenPlayItemImage.state = "hover"
screenPlayItemImage.enter()
@ -242,6 +267,11 @@ Item {
screenPlayItemImage.exit()
}
onClicked: function (mouse) {
if (!root.hasLicense) {
root.openOpenLicensePopup()
return
}
if (mouse.button === Qt.LeftButton)
App.util.setSidebarItem(root.screenId, root.type)
else if (mouse.button === Qt.RightButton)
@ -250,7 +280,6 @@ Item {
}
}
}
transitions: [
Transition {
from: ""

View File

@ -1,4 +1,5 @@
import QtQuick
import ScreenPlayUtil as Util
Item {
id: root
@ -6,7 +7,7 @@ Item {
property string absoluteStoragePath
property string sourceImage
property string sourceImageGIF
property var type: ContentTypes.InstalledType.Unknown
property var type: Util.ContentTypes.InstalledType.Unknown
function enter() {
if (root.sourceImageGIF != "")

View File

@ -365,6 +365,14 @@ Item {
const absoluteStoragePath = item.m_absoluteStoragePath
const previewImage = item.m_preview
if (App.util.isWallpaper(root.type)) {
if (type === ContentTypes.InstalledType.GodotWallpaper){
if(!App.globalVariables.isBasicVersion()) {
root.state = "inactive"
return
}
}
let activeMonitors = monitorSelection.getActiveMonitors(
)
// TODO Alert user to choose a monitor

View File

@ -2,7 +2,6 @@ import QtQuick
import QtQuick.Controls
import ScreenPlayUtil as Util
import ScreenPlayApp 1.0
import "Monitors" as Monitors
import "Installed" as Installed
import "Navigation" as Navigation
@ -96,15 +95,6 @@ Item {
App.showDockIcon(true);
root.show();
}
function onActiveWidgetsCounterChanged() {
plausible.pageView("widget/count/" + App.screenPlayManager.activeWidgetsCounter);
}
function onActiveWallpaperCounterChanged() {
plausible.pageView("wallpaper/count/" + App.screenPlayManager.activeWallpaperCounter);
}
target: App.screenPlayManager
}

View File

@ -5,8 +5,8 @@ import QtQuick.Controls.Material
import QtQuick.Layouts
import QtQuick.Controls.Material.impl
import ScreenPlayApp
import ScreenPlayUtil as Util
import "../Components"
Util.Popup {
id: root
@ -14,249 +14,11 @@ Util.Popup {
property string activeMonitorName: ""
property int activeMonitorIndex
width: 1000
height: 500
width: 1366
height: 768
onOpened: {
monitorSelection.selectMonitorAt(0);
monitorSelection.selectMonitorAt(0)
}
Connections {
function onRequestToggleWallpaperConfiguration() {
root.open();
}
target: App.util
}
Item {
id: monitorsSettingsWrapper
clip: true
anchors {
fill: parent
margins: 10
}
Item {
id: itmLeftWrapper
width: parent.width * 0.5
anchors {
top: parent.top
left: parent.left
bottom: parent.bottom
margins: 10
}
Text {
id: txtHeadline
text: qsTr("Wallpaper Configuration")
font.pointSize: 21
color: Material.primaryTextColor
font.family: App.settings.font
font.weight: Font.Light
width: 400
anchors {
top: parent.top
topMargin: 10
left: parent.left
leftMargin: 20
}
}
MonitorSelection {
id: monitorSelection
bgRadius: 3
height: 200
width: parent.width * 0.9
multipleMonitorsSelectable: false
monitorWithoutContentSelectable: false
availableWidth: width - 20
availableHeight: 150
onRequestProjectSettings: function (index, installedType, appID) {
if (installedType === Util.ContentTypes.InstalledType.VideoWallpaper) {
videoControlWrapper.state = "visible";
customPropertiesGridView.visible = false;
const wallpaper = App.screenPlayManager.getWallpaperByAppID(appID);
videoControlWrapper.wallpaper = wallpaper;
} else {
videoControlWrapper.state = "hidden";
customPropertiesGridView.visible = true;
if (!App.screenPlayManager.requestProjectSettingsAtMonitorIndex(index)) {
console.warn("Unable to get requested settings from index: ", index);
}
}
activeMonitorIndex = index;
}
anchors {
top: txtHeadline.bottom
topMargin: 20
left: parent.left
leftMargin: 20
}
Connections {
function onProjectSettingsListModelResult(listModel) {
customPropertiesGridView.projectSettingsListmodelRef = listModel;
}
target: App.screenPlayManager
}
}
ColumnLayout {
spacing: 5
anchors {
top: monitorSelection.bottom
right: parent.right
left: parent.left
margins: 20
}
Button {
id: btnRemoveSelectedWallpaper
Material.background: Material.accent
highlighted: true
text: qsTr("Remove selected")
font.family: App.settings.font
enabled: monitorSelection.activeMonitors.length == 1 && App.screenPlayManager.activeWallpaperCounter > 0
onClicked: {
if (!App.screenPlayManager.removeWallpaperAt(monitorSelection.activeMonitors[0]))
print("Unable to close singel wallpaper");
}
}
Button {
id: btnRemoveAllWallpape
text: qsTr("Remove all ") + App.screenPlayManager.activeWallpaperCounter + " " + qsTr("Wallpapers")
Material.background: Material.accent
highlighted: true
font.family: App.settings.font
enabled: App.screenPlayManager.activeWallpaperCounter > 0
onClicked: {
if (!App.screenPlayManager.removeAllWallpapers(true))
print("Unable to close all wallpaper!");
root.close();
}
}
Button {
id: btnRemoveAllWidgets
text: qsTr("Remove all ") + App.screenPlayManager.activeWidgetsCounter + " " + qsTr("Widgets")
Material.background: Material.accent
Material.foreground: Material.primaryTextColor
highlighted: true
font.family: App.settings.font
enabled: App.screenPlayManager.activeWidgetsCounter > 0
onClicked: {
if (!App.screenPlayManager.removeAllWidgets())
print("Unable to close all widgets!");
root.close();
}
}
}
}
Rectangle {
color: Material.theme === Material.Light ? Material.background : Qt.darker(Material.background)
radius: 3
clip: true
anchors {
top: parent.top
topMargin: 75
right: parent.right
rightMargin: 40
bottom: parent.bottom
bottomMargin: 30
left: itmLeftWrapper.right
}
DefaultVideoControls {
id: videoControlWrapper
activeMonitorIndex: root.activeMonitorIndex
state: "hidden"
anchors.fill: parent
anchors.margins: 10
}
GridView {
id: customPropertiesGridView
property var projectSettingsListmodelRef
boundsBehavior: Flickable.DragOverBounds
maximumFlickVelocity: 7000
flickDeceleration: 5000
cellWidth: 340
cellHeight: 50
cacheBuffer: 10000
clip: true
anchors.fill: parent
anchors.margins: 10
visible: false
model: customPropertiesGridView.projectSettingsListmodelRef
delegate: MonitorsProjectSettingItem {
id: delegate
width: parent.width - 40
selectedMonitor: activeMonitorIndex
name: m_name
isHeadline: m_isHeadline
value: m_value
itemIndex: index
projectSettingsListmodelRef: customPropertiesGridView.projectSettingsListmodelRef
}
ScrollBar.vertical: ScrollBar {
snapMode: ScrollBar.SnapOnRelease
policy: ScrollBar.AlwaysOn
}
}
}
ToolButton {
width: 32
height: width
icon.width: 16
icon.height: 16
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/font-awsome/close.svg"
icon.color: Material.iconColor
onClicked: root.close()
anchors {
top: parent.top
right: parent.right
}
}
SaveNotification {
id: saveNotification
width: parent.width - 40
Connections {
function onProfilesSaved() {
if (root.opened)
saveNotification.open();
}
target: App.screenPlayManager
}
}
}
background: Rectangle {
anchors.fill: parent
radius: 4
@ -267,4 +29,290 @@ Util.Popup {
elevation: 6
}
}
Connections {
function onRequestToggleWallpaperConfiguration() {
root.open()
}
target: App.util
}
ColumnLayout {
anchors {
fill: parent
margins: 10
}
Rectangle {
id: timelineWrapper
color: Material.theme === Material.Light ? Material.background : "#242424"
border.color: "#44FFD700"
border.width: 1
radius: 3
Layout.fillWidth: true
Layout.preferredHeight: 280
ColumnLayout {
spacing: 20
anchors {
fill: parent
margins: 40
}
Text {
text: qsTr("Timeline")
font.pointSize: 21
color: Material.primaryTextColor
font.family: App.settings.font
font.weight: Font.Light
width: 400
Layout.fillWidth: true
Layout.preferredHeight: 30
}
Timeline {
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
Item {
id: monitorsSettingsWrapper
clip: true
Layout.fillWidth: true
Layout.fillHeight: true
Item {
id: itmLeftWrapper
width: parent.width * 0.5
anchors {
top: parent.top
left: parent.left
bottom: parent.bottom
margins: 10
}
Text {
id: txtHeadline
text: qsTr("Wallpaper Configuration")
font.pointSize: 21
color: Material.primaryTextColor
font.family: App.settings.font
font.weight: Font.Light
width: 400
anchors {
top: parent.top
topMargin: 10
left: parent.left
leftMargin: 20
}
}
MonitorSelection {
id: monitorSelection
bgRadius: 3
height: 200
width: parent.width * 0.9
multipleMonitorsSelectable: false
monitorWithoutContentSelectable: false
availableWidth: width - 20
availableHeight: 150
onRequestProjectSettings: function (index, installedType, appID) {
if (installedType === Util.ContentTypes.InstalledType.VideoWallpaper) {
videoControlWrapper.state = "visible"
customPropertiesGridView.visible = false
const wallpaper = App.screenPlayManager.getWallpaperByAppID(
appID)
videoControlWrapper.wallpaper = wallpaper
} else {
videoControlWrapper.state = "hidden"
customPropertiesGridView.visible = true
if (!App.screenPlayManager.requestProjectSettingsAtMonitorIndex(
index)) {
console.warn("Unable to get requested settings from index: ",
index)
}
}
activeMonitorIndex = index
}
anchors {
top: txtHeadline.bottom
topMargin: 20
left: parent.left
leftMargin: 20
}
Connections {
function onProjectSettingsListModelResult(listModel) {
customPropertiesGridView.projectSettingsListmodelRef = listModel
}
target: App.screenPlayManager
}
}
ColumnLayout {
spacing: 5
anchors {
top: monitorSelection.bottom
right: parent.right
left: parent.left
margins: 20
}
Button {
id: btnRemoveSelectedWallpaper
Material.background: Material.accent
highlighted: true
text: qsTr("Remove selected")
font.family: App.settings.font
enabled: monitorSelection.activeMonitors.length == 1
&& App.screenPlayManager.activeWallpaperCounter > 0
onClicked: {
if (!App.screenPlayManager.removeWallpaperAt(
monitorSelection.activeMonitors[0]))
print("Unable to close singel wallpaper")
}
}
Button {
id: btnRemoveAllWallpape
text: qsTr("Remove all ")
+ App.screenPlayManager.activeWallpaperCounter + " " + qsTr(
"Wallpapers")
Material.background: Material.accent
highlighted: true
font.family: App.settings.font
enabled: App.screenPlayManager.activeWallpaperCounter > 0
onClicked: {
if (!App.screenPlayManager.removeAllWallpapers(
true))
print("Unable to close all wallpaper!")
root.close()
}
}
Button {
id: btnRemoveAllWidgets
text: qsTr("Remove all ")
+ App.screenPlayManager.activeWidgetsCounter + " " + qsTr(
"Widgets")
Material.background: Material.accent
Material.foreground: Material.primaryTextColor
highlighted: true
font.family: App.settings.font
enabled: App.screenPlayManager.activeWidgetsCounter > 0
onClicked: {
if (!App.screenPlayManager.removeAllWidgets())
print("Unable to close all widgets!")
root.close()
}
}
}
}
Rectangle {
color: Material.theme === Material.Light ? Material.background : Qt.darker(
Material.background)
radius: 3
clip: true
anchors {
top: parent.top
topMargin: 75
right: parent.right
rightMargin: 40
bottom: parent.bottom
bottomMargin: 30
left: itmLeftWrapper.right
}
DefaultVideoControls {
id: videoControlWrapper
activeMonitorIndex: root.activeMonitorIndex
state: "hidden"
anchors.fill: parent
anchors.margins: 10
}
GridView {
id: customPropertiesGridView
property var projectSettingsListmodelRef
boundsBehavior: Flickable.DragOverBounds
maximumFlickVelocity: 7000
flickDeceleration: 5000
cellWidth: 340
cellHeight: 50
cacheBuffer: 10000
clip: true
anchors.fill: parent
anchors.margins: 10
visible: false
model: customPropertiesGridView.projectSettingsListmodelRef
delegate: MonitorsProjectSettingItem {
id: delegate
width: parent.width - 40
selectedMonitor: activeMonitorIndex
name: m_name
isHeadline: m_isHeadline
value: m_value
itemIndex: index
projectSettingsListmodelRef: customPropertiesGridView.projectSettingsListmodelRef
}
ScrollBar.vertical: ScrollBar {
snapMode: ScrollBar.SnapOnRelease
policy: ScrollBar.AlwaysOn
}
}
}
SaveNotification {
id: saveNotification
width: parent.width - 40
Connections {
function onProfilesSaved() {
if (root.opened)
saveNotification.open()
}
target: App.screenPlayManager
}
}
}
}
ToolButton {
width: 32
height: width
icon.width: 16
icon.height: 16
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/font-awsome/close.svg"
icon.color: Material.iconColor
onClicked: root.close()
anchors {
top: parent.top
right: parent.right
}
}
}

View File

@ -0,0 +1,74 @@
import QtQuick
import QtQuick.Controls
Pane {
id: root
Component.onCompleted: {
// Add the second handle at 100% after the component is fully created
sliderHandles.append({"position": sliderLine.width});
}
ListModel {
id: sliderHandles
ListElement { position: 0 } // Initial handle at 0%
}
Rectangle {
id: sliderLine
width: parent.width
height: 10
anchors.centerIn: parent
color: "grey"
MouseArea {
anchors.fill: parent
onClicked: {
var newHandlePosition = Math.max(0, Math.min(mouseX, sliderLine.width));
sliderHandles.append({"position": newHandlePosition});
// Sort handles after adding a new one
sortHandles();
}
}
}
Repeater {
model: sliderHandles
delegate: Rectangle {
id: handle
width: 10
height: 20
x: model.position - width / 2
y: sliderLine.y - height / 2 + sliderLine.height / 2
color: "blue"
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: handle
drag.axis: Drag.XAxis
drag.minimumX: getMinimumX(index)
drag.maximumX: getMaximumX(index)
onReleased: {
sliderHandles.set(index, {"position": handle.x + width / 2});
}
}
}
}
function getMinimumX(index) {
return index > 0 ? sliderHandles.get(index - 1).position : 0;
}
function getMaximumX(index) {
return index < sliderHandles.count - 1 ? sliderHandles.get(index + 1).position - handle.width : sliderLine.width;
}
function sortHandles() {
sliderHandles.sort(function(a, b) {
return a.position - b.position;
});
}
}

View File

@ -6,8 +6,8 @@ import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects
import QtQuick.Controls.Material.impl
import ScreenPlayApp
import ScreenPlayUtil
import "../Components"
Rectangle {
id: root
@ -22,29 +22,29 @@ Rectangle {
signal changePage(string name)
function setActive(active) {
navActive = active;
navActive = active
if (active)
root.state = "enabled";
root.state = "enabled"
else
root.state = "disabled";
root.state = "disabled"
}
function setNavigation(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;
navArray[i].state = "active"
root.currentNavigationName = name
tabBar.currentIndex = navArray[i].index
} else {
navArray[i].state = "inactive";
navArray[i].state = "inactive"
}
}
}
function onPageChanged(name) {
if (!navActive)
return;
root.changePage(name);
setNavigation(name);
return
root.changePage(name)
setNavigation(name)
}
implicitWidth: 1366
@ -58,11 +58,11 @@ Rectangle {
Connections {
function onRequestNavigationActive(isActive) {
setActive(isActive);
setActive(isActive)
}
function onRequestNavigation(nav) {
onPageChanged(nav);
onPageChanged(nav)
}
target: App.util
@ -90,19 +90,19 @@ Rectangle {
objectName: "Create"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg"
onClicked: {
root.onPageChanged("Create");
root.onPageChanged("Create")
}
}
CustomTabButton {
id: navWorkshop
index: 1
enabled: App.settings.steamVersion
enabled: App.globalVariables.isSteamVersion()
text: qsTr("Workshop")
objectName: "Workshop"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg"
onClicked: {
root.onPageChanged("Workshop");
root.onPageChanged("Workshop")
}
}
@ -113,7 +113,7 @@ Rectangle {
objectName: "Installed"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_installed.svg"
onClicked: {
root.onPageChanged("Installed");
root.onPageChanged("Installed")
}
}
@ -124,7 +124,7 @@ Rectangle {
objectName: "Community"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_community.svg"
onClicked: {
root.onPageChanged("Community");
root.onPageChanged("Community")
}
}
@ -135,7 +135,7 @@ Rectangle {
objectName: "Settings"
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_settings.svg"
onClicked: {
root.onPageChanged("Settings");
root.onPageChanged("Settings")
}
}
}
@ -147,37 +147,74 @@ Rectangle {
height: parent.height
width: implicitWidth
property int index: 0
background: Item {
}
background: Item {}
font.capitalization: Font.MixedCase
}
Rectangle {
id: premiumBackground
anchors.centerIn: premium
width: premium.width
height: premium.height
color: Material.theme === Material.Light ? Material.background : "#242424"
border.color: "#44FFD700"
border.width: 1
radius: 3
}
SwipeView {
id:premium
clip: true
anchors {
top: parent.top
topMargin: 5
right: quickActionRow.left
rightMargin: 20
bottom: parent.bottom
bottomMargin: 5
}
interactive: false
currentIndex: {
if (App.globalVariables.isBasicVersion())
return 0
if (App.globalVariables.isProVersion())
return 1
if (App.globalVariables.isUltraVersion())
return 2
return 0
}
ScreenPlayProPopup {
id:screenPlayProView
}
ToolButton {
icon.source: "qrc:/qml/ScreenPlayApp/assets/images/rocket_3d.png"
icon.color: "transparent"
text: qsTr("Get ScreenPlay Pro 3D Wallpaper and Timelines!")
onClicked: screenPlayProView.open()
}
ToolButton {
text: qsTr("ScreenPlay Pro Active")
}
ToolButton {
text: qsTr("ScreenPlay ULTRA Active")
}
}
Rectangle {
id: quickActionRowBackground
anchors.centerIn: quickActionRow
width: quickActionRow.width + 5
height: quickActionRow.height - 16
color: Material.theme === Material.Light ? Material.background : "#242424"
border.color: Material.theme === Material.Light ? Material.iconDisabledColor : Qt.darker(Material.background)
border.color: Material.theme === Material.Light ? Material.iconDisabledColor : Qt.darker(
Material.background)
border.width: 1
radius: 3
}
RowLayout {
anchors {
top: parent.top
right: quickActionRow.left
rightMargin: 20
bottom: parent.bottom
}
ToolButton {
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/font-awsome/patreon-brands.svg"
text: qsTr("Support me on Patreon!")
onClicked: Qt.openUrlExternally("https://www.patreon.com/ScreenPlayApp")
}
}
RowLayout {
id: quickActionRow
anchors {
@ -187,12 +224,13 @@ Rectangle {
bottom: parent.bottom
}
property bool contentActive: App.screenPlayManager.activeWallpaperCounter > 0 || App.screenPlayManager.activeWidgetsCounter > 0
property bool contentActive: App.screenPlayManager.activeWallpaperCounter > 0
|| App.screenPlayManager.activeWidgetsCounter > 0
onContentActiveChanged: {
if (!contentActive) {
miMuteAll.soundEnabled = true;
miStopAll.isPlaying = true;
miMuteAll.soundEnabled = true
miStopAll.isPlaying = true
}
}
@ -208,11 +246,12 @@ Rectangle {
property bool soundEnabled: true
onSoundEnabledChanged: {
if (miMuteAll.soundEnabled) {
miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume.svg";
App.screenPlayManager.setAllWallpaperValue("muted", "false");
miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume.svg"
App.screenPlayManager.setAllWallpaperValue("muted", "false")
} else {
miMuteAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume_mute.svg";
App.screenPlayManager.setAllWallpaperValue("muted", "true");
miMuteAll.icon.source
= "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume_mute.svg"
App.screenPlayManager.setAllWallpaperValue("muted", "true")
}
}
@ -231,18 +270,19 @@ Rectangle {
property bool isPlaying: true
onIsPlayingChanged: {
if (miStopAll.isPlaying) {
miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_pause.svg";
App.screenPlayManager.setAllWallpaperValue("isPlaying", "true");
miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_pause.svg"
App.screenPlayManager.setAllWallpaperValue("isPlaying",
"true")
} else {
miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_play.svg";
App.screenPlayManager.setAllWallpaperValue("isPlaying", "false");
miStopAll.icon.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_play.svg"
App.screenPlayManager.setAllWallpaperValue("isPlaying",
"false")
}
}
hoverEnabled: true
ToolTip.text: qsTr("Pause/Play all Wallpaper")
ToolTip.visible: hovered
}
ToolButton {
id: miCloseAll
enabled: quickActionRow.contentActive
@ -251,19 +291,19 @@ Rectangle {
icon.width: root.iconWidth
icon.height: root.iconHeight
onClicked: {
App.screenPlayManager.removeAllWallpapers();
App.screenPlayManager.removeAllWidgets();
miStopAll.isPlaying = true;
miMuteAll.soundEnabled = true;
App.screenPlayManager.removeAllWallpapers(true)
App.screenPlayManager.removeAllWidgets(true)
miStopAll.isPlaying = true
miMuteAll.soundEnabled = true
}
hoverEnabled: true
ToolTip.text: qsTr("Close All Content")
ToolTip.visible: hovered
}
ToolButton {
id: miConfig
enabled: quickActionRow.contentActive
Layout.alignment: Qt.AlignVCenter
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_video_settings.svg"
icon.width: root.iconWidth

View File

@ -3,8 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import ScreenPlayWorkshop
import ScreenPlayApp
Item {
id: root
@ -12,7 +11,7 @@ Item {
property Item modalSource
Component.onCompleted: {
if (App.settings.steamVersion) {
if (App.globalVariables.isSteamVersion()) {
workshopLoader.setSource("qrc:/qml/ScreenPlayWorkshop/qml/SteamWorkshop.qml", {
"modalSource": modalSource
});

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
#include "ScreenPlay/globalvariables.h"
#include "ScreenPlay/CMakeVariables.h"
namespace ScreenPlay {
@ -16,9 +17,47 @@ namespace ScreenPlay {
GlobalVariables::GlobalVariables(QObject* parent)
: QObject(parent)
{
if (SCREENPLAY_STEAM_VERSION) {
setVersion(GlobalVariables::Version::OpenSourceSteam);
} else {
setVersion(GlobalVariables::Version::OpenSourceStandalone);
}
setVersion(GlobalVariables::Version::OpenSourceUltraSteam);
setLocalSettingsPath(QUrl { QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) });
}
bool GlobalVariables::isBasicVersion() const
{
return (m_version == Version::OpenSourceSteam
|| m_version == Version::OpenSourceStandalone);
}
bool GlobalVariables::isSteamVersion() const
{
return (m_version == Version::OpenSourceSteam
|| m_version == Version::OpenSourceProSteam
|| m_version == Version::OpenSourceUltraSteam);
}
bool GlobalVariables::isStandaloneVersion() const
{
return (m_version == Version::OpenSourceStandalone
|| m_version == Version::OpenSourceProStandalone
|| m_version == Version::OpenSourceUltraStandalone);
}
bool GlobalVariables::isProVersion() const
{
return (m_version == Version::OpenSourceProStandalone
|| m_version == Version::OpenSourceProSteam);
}
bool GlobalVariables::isUltraVersion() const
{
return (m_version == Version::OpenSourceUltraStandalone
|| m_version == Version::OpenSourceUltraSteam);
}
void GlobalVariables::setLocalStoragePath(QUrl localStoragePath)
{
if (m_localStoragePath == localStoragePath)

View File

@ -55,8 +55,6 @@ Settings::Settings(const std::shared_ptr<GlobalVariables>& globalVariables,
const QString isSteamVersion = QString("Is steam version: %1").arg((SCREENPLAY_STEAM_VERSION ? QString("✅ Yes") : QString("❌ No")));
setBuildInfos(qtVersion + buildType + buildDate + commitHash + isDeployVersion + isSteamVersion);
setSteamVersion(SCREENPLAY_STEAM_VERSION);
#ifdef Q_OS_WIN
setDesktopEnvironment(DesktopEnvironment::Windows);
#endif
@ -212,7 +210,9 @@ void Settings::initInstalledPath()
const QString contentPath = m_qSettings.value("ScreenPlayContentPath", "").toString();
// Steamless
if (!steamVersion() && contentPath.isEmpty()) {
const GlobalVariables::Version version = m_globalVariables->version();
const bool steamVersion = version == GlobalVariables::Version::OpenSourceSteam || version == GlobalVariables::Version::OpenSourceProSteam;
if (!steamVersion && contentPath.isEmpty()) {
const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
m_qSettings.setValue("ScreenPlayContentPath", QUrl::fromUserInput(path));
m_qSettings.sync();
@ -312,7 +312,8 @@ bool Settings::retranslateUI()
guiAppInst->installTranslator(&m_translator);
emit requestRetranslation();
if (language() == Settings::Language::Ko_KR) {
const Language lang = language();
if (lang == Settings::Language::Ko_KR) {
setFont("Noto Sans CJK KR Regular");
} else {
setFont("Roboto");
@ -516,14 +517,6 @@ void Settings::setDecoder(QString decoder)
emit decoderChanged(m_decoder);
}
void Settings::setOfflineMode(bool offlineMode)
{
if (m_offlineMode == offlineMode)
return;
m_offlineMode = offlineMode;
emit offlineModeChanged(m_offlineMode);
}
void Settings::setSilentStart(bool silentStart)
{
@ -598,14 +591,6 @@ void Settings::setTheme(ScreenPlay::Settings::Theme theme)
emit themeChanged(m_theme);
}
void Settings::setSteamVersion(bool steamVersion)
{
if (m_steamVersion == steamVersion)
return;
m_steamVersion = steamVersion;
emit steamVersionChanged(m_steamVersion);
}
void Settings::setDesktopEnvironment(DesktopEnvironment desktopEnvironment)
{

View File

@ -21,7 +21,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC inc/public/)
target_link_libraries(
${PROJECT_NAME}
PUBLIC Qt6::Core
Qt6::Quick
Qt6::Gui
Qt6::Network
ScreenPlayUtil)
Qt6::Quick
Qt6::Gui
Qt6::Network
ScreenPlayUtil)

View File

@ -16,7 +16,6 @@ find_package(
REQUIRED)
set(QML
# cmake-format: sort
qml/CloseIcon.qml
qml/ColorImage.qml
@ -31,37 +30,37 @@ set(QML
qml/Headline.qml
qml/HeadlineSection.qml
qml/ImageSelector.qml
qml/LabelSlider.qml
qml/LicenseSelector.qml
qml/ModalBackgroundBlur.qml
qml/MouseHoverBlocker.qml
qml/Popup.qml
qml/RippleEffect.qml
qml/Shake.qml
qml/LabelSlider.qml
qml/Tag.qml
qml/TagSelector.qml
qml/TextField.qml)
set(SOURCES
# cmake-format: sort
src/processmanager.cpp
src/archive.cpp
src/contenttypes.cpp
src/exitcodes.cpp
src/logginghandler.cpp
src/processmanager.cpp
src/projectfile.cpp
src/steamenumsgenerated.cpp
src/util.cpp)
set(HEADER
# cmake-format: sort
inc/public/ScreenPlayUtil/processmanager.h
inc/public/ScreenPlayUtil/archive.h
inc/public/ScreenPlayUtil/contenttypes.h
inc/public/ScreenPlayUtil/exitcodes.h
inc/public/ScreenPlayUtil/HelpersCommon.h
inc/public/ScreenPlayUtil/ListPropertyHelper.h
inc/public/ScreenPlayUtil/logginghandler.h
inc/public/ScreenPlayUtil/processmanager.h
inc/public/ScreenPlayUtil/projectfile.h
inc/public/ScreenPlayUtil/PropertyHelpers.h
inc/public/ScreenPlayUtil/steamenumsgenerated.h
@ -73,7 +72,7 @@ if(APPLE)
endif()
set(RESOURCES # cmake-format: sort
assets/icons/attach_file.svg assets/icons/description.svg assets/icons/folder.svg)
assets/icons/attach_file.svg assets/icons/description.svg assets/icons/folder.svg)
qt_add_library(
${PROJECT_NAME}
@ -107,15 +106,14 @@ target_include_directories(${PROJECT_NAME}plugin PUBLIC inc/public/ScreenPlayUti
target_link_libraries(
${PROJECT_NAME}
PUBLIC
Qt6::Core
Qt6::Quick
Qt6::Gui
QCoro6::Core
QCoro6::Qml
fmt::fmt-header-only
LibArchive::LibArchive
QArchive)
PUBLIC Qt6::Core
Qt6::Quick
Qt6::Gui
QCoro6::Core
QCoro6::Qml
fmt::fmt-header-only
LibArchive::LibArchive
QArchive)
if(WIN32)
# Used for query windows monitor data

View File

@ -84,4 +84,4 @@
"configurePreset": "osx-debug"
}
]
}
}

View File

@ -15,7 +15,6 @@ find_package(
REQUIRED)
set(QML
# cmake-format: sort
qml/Background.qml
qml/Forum.qml
@ -37,7 +36,6 @@ set(QML
qml/WorkshopItem.qml)
set(SOURCES
# cmake-format: sort
src/installedlistmodel.cpp
src/screenplayworkshop.cpp
@ -49,7 +47,6 @@ set(SOURCES
src/steamworkshoplistmodel.cpp)
set(HEADER
# cmake-format: sort
src/installedlistmodel.h
src/screenplayworkshop.h
@ -63,7 +60,6 @@ set(HEADER
src/workshopitem.h)
set(RESOURCES
# cmake-format: sort
assets/icons/icon_account_circle.svg
assets/icons/icon_arrow_left.svg
@ -103,10 +99,10 @@ target_include_directories(${PROJECT_NAME} PUBLIC src/)
target_link_libraries(
${PROJECT_NAME}
PUBLIC Qt6::Core
Qt6::Quick
${STEAM_LIB}
ScreenPlayUtil
SteamSDK)
Qt6::Quick
${STEAM_LIB}
ScreenPlayUtil
SteamSDK)
qt_add_qml_module(
${PROJECT_NAME}
@ -142,14 +138,14 @@ if(${SCREENPLAY_STEAM})
target_link_libraries(
tst_ScreenPlayWorkshop
PRIVATE Qt6::Quick
Qt6::QuickControls2
${PROJECT_NAME}plugin
ScreenPlayUtilplugin
SteamSDK)
Qt6::QuickControls2
${PROJECT_NAME}plugin
ScreenPlayUtilplugin
SteamSDK)
if(APPLE)
set_target_properties(tst_ScreenPlayWorkshop PROPERTIES RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
"${CMAKE_BINARY_DIR}/bin/ScreenPlay.app/Contents/MacOS/")
endif()
endif()
endif()

View File

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

View File

@ -3,6 +3,7 @@ import QtQuick.Controls
import QtQuick.Controls.Material
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import ScreenPlayApp
Item {
@ -11,7 +12,7 @@ Item {
property Item modalSource
Component.onCompleted: {
if (App.settings.steamVersion) {
if (App.globalVariables.isSteamVersion()) {
workshopLoader.setSource("qrc:/qml/ScreenPlayApp/qml/Workshop/SteamWorkshop.qml", {
"modalSource": modalSource
});

View File

@ -4,30 +4,19 @@ FetchContent_Populate(
QArchive
GIT_REPOSITORY https://github.com/antony-jr/QArchive.git
GIT_TAG e587f30507c0e6d92f79a2dc1a6aa7ebb1f8e679
# 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}/QArchive)
FetchContent_Populate(
qml-plausible
GIT_REPOSITORY https://gitlab.com/kelteseth/qml-plausible.git
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)
FetchContent_Populate(
qcoro
GIT_REPOSITORY https://github.com/danvratil/qcoro.git
GIT_TAG 12c052e
# 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}/qqcoro)
add_subdirectory(qml-plausible)
add_subdirectory(QArchive)
add_subdirectory(qqcoro)
@ -38,7 +27,6 @@ if(UNIX AND NOT APPLE)
qt-layer-shell
GIT_REPOSITORY https://github.com/KDE/layer-shell-qt.git
GIT_TAG 721c0ae334554eb2396a2d4d3358f896b8c77412
# 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}/qt-layer-shell)