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

Add basic refactoring for installed drawer and

now so called content settings
This commit is contained in:
Elias Steurer 2024-05-29 13:01:16 +02:00
parent 59ce122225
commit a71b3ea53e
22 changed files with 624 additions and 654 deletions

View File

@ -51,6 +51,7 @@ set(HEADER
set(QML set(QML
# cmake-format: sort # cmake-format: sort
main.qml main.qml
qml/MainApp.qml
qml/Components/TrayIcon.qml qml/Components/TrayIcon.qml
qml/Components/LineHandle.qml qml/Components/LineHandle.qml
qml/Components/LineIndicator.qml qml/Components/LineIndicator.qml
@ -84,14 +85,12 @@ set(QML
qml/Installed/ScreenPlayItem.qml qml/Installed/ScreenPlayItem.qml
qml/Installed/ScreenPlayItemImage.qml qml/Installed/ScreenPlayItemImage.qml
qml/Installed/InstalledDrawer.qml qml/Installed/InstalledDrawer.qml
qml/MainApp.qml qml/ContentSettings/DefaultVideoControls.qml
qml/Monitors/DefaultVideoControls.qml qml/ContentSettings/MonitorSelection.qml
qml/Monitors/MonitorSelection.qml qml/ContentSettings/MonitorSelectionItem.qml
qml/Monitors/MonitorSelectionItem.qml qml/ContentSettings/MonitorsProjectSettingItem.qml
qml/Monitors/MonitorsProjectSettingItem.qml qml/ContentSettings/ContentSettingsView.qml
qml/Monitors/MonitorsView.qml qml/ContentSettings/SaveNotification.qml
qml/Monitors/SaveNotification.qml
qml/Monitors/WallpaperTimeline.qml
qml/Navigation/ExitPopup.qml qml/Navigation/ExitPopup.qml
qml/Navigation/Navigation.qml qml/Navigation/Navigation.qml
qml/Settings/SettingBool.qml qml/Settings/SettingBool.qml

View File

@ -69,14 +69,10 @@ public:
Q_INVOKABLE QVariantMap initialStopPositions(); Q_INVOKABLE QVariantMap initialStopPositions();
Q_INVOKABLE bool setWallpaperAtTimelineIndex( Q_INVOKABLE bool setWallpaperAtTimelineIndex(
const ScreenPlay::ContentTypes::InstalledType type, const ScreenPlay::ContentTypes::InstalledType type,
const ScreenPlay::Video::FillMode fillMode,
const QString& absolutePath, const QString& absolutePath,
const QString& previewImage, const QString& previewImage,
const QString& file, const QString& file,
const QVector<int>& monitorIndex, const QVector<int>& monitorIndex,
const float volume,
const float playbackRate,
const QJsonObject& properties,
const int timelineIndex, const int timelineIndex,
const QString& identifier, const QString& identifier,
const bool saveToProfilesConfigFile); const bool saveToProfilesConfigFile);
@ -95,7 +91,7 @@ public:
Q_INVOKABLE bool setWallpaperFillModeAtMonitorIndex(const int index, const int fillmode); Q_INVOKABLE bool setWallpaperFillModeAtMonitorIndex(const int index, const int fillmode);
Q_INVOKABLE bool setAllWallpaperValue(const QString& key, const QString& value); Q_INVOKABLE bool setAllWallpaperValue(const QString& key, const QString& value);
Q_INVOKABLE bool setWallpaperValue(const QString& appID, const QString& key, const QString& value); Q_INVOKABLE bool setWallpaperValue(const QString& appID, const QString& key, const QString& value);
QVersionNumber getProfilesVersion() const;
signals: signals:
void activeWallpaperCounterChanged(int activeWallpaperCounter); void activeWallpaperCounterChanged(int activeWallpaperCounter);
@ -113,56 +109,9 @@ private slots:
bool saveProfiles(); bool saveProfiles();
void checkActiveWallpaperTimeline(); void checkActiveWallpaperTimeline();
void newConnection(); void newConnection();
void setActiveWallpaperCounter(int activeWallpaperCounter);
void setActiveWidgetsCounter(int activeWidgetsCounter);
public slots:
void setActiveWallpaperCounter(int activeWallpaperCounter)
{
if (m_activeWallpaperCounter == activeWallpaperCounter)
return;
m_activeWallpaperCounter = activeWallpaperCounter;
emit activeWallpaperCounterChanged(m_activeWallpaperCounter);
}
void setActiveWidgetsCounter(int activeWidgetsCounter)
{
if (m_activeWidgetsCounter == activeWidgetsCounter)
return;
m_activeWidgetsCounter = activeWidgetsCounter;
emit activeWidgetsCounterChanged(m_activeWidgetsCounter);
}
void increaseActiveWidgetsCounter()
{
m_activeWidgetsCounter++;
emit activeWidgetsCounterChanged(m_activeWidgetsCounter);
}
void decreaseActiveWidgetsCounter()
{
if (m_activeWidgetsCounter <= 0) {
return;
}
m_activeWidgetsCounter--;
emit activeWidgetsCounterChanged(m_activeWidgetsCounter);
}
void increaseActiveWallpaperCounter()
{
m_activeWallpaperCounter++;
emit activeWallpaperCounterChanged(m_activeWallpaperCounter);
}
void decreaseActiveWallpaperCounter()
{
if (m_activeWallpaperCounter <= 0) {
return;
}
m_activeWallpaperCounter--;
emit activeWallpaperCounterChanged(m_activeWallpaperCounter);
}
private: private:
void printTimelines(); void printTimelines();
@ -195,6 +144,8 @@ private:
QTimer m_saveLimiter; QTimer m_saveLimiter;
QTimer m_contentTimer; QTimer m_contentTimer;
Util m_util;
// We use a 24 hour system // We use a 24 hour system
const QString m_timelineTimeFormat = "hh:mm:ss"; const QString m_timelineTimeFormat = "hh:mm:ss";
const quint16 m_webSocketPort = 16395; const quint16 m_webSocketPort = 16395;

View File

@ -60,6 +60,10 @@ class ScreenPlayWallpaper;
// WallpaperTimeline. Only the active timeline section has // WallpaperTimeline. Only the active timeline section has
// a filled vector of ScreenPlayWallpaper // a filled vector of ScreenPlayWallpaper
struct WallpaperTimelineSection { struct WallpaperTimelineSection {
// Is active is needed as an additional flag during switching.
// When timeline A is no longer in the time range, then we can
// use this flag to know that it was the last active timeline and
// remove all active wallpaper.
bool isActive = false; bool isActive = false;
QString identifier; QString identifier;

View File

@ -28,7 +28,6 @@ int main(int argc, char* argv[])
#if !defined(Q_OS_LINUX) #if !defined(Q_OS_LINUX)
qputenv("QT_MEDIA_BACKEND", "ffmpeg"); qputenv("QT_MEDIA_BACKEND", "ffmpeg");
#endif #endif
QGuiApplication qtGuiApp(argc, argv); QGuiApplication qtGuiApp(argc, argv);
ScreenPlay::ApplicationEngine appEngine; ScreenPlay::ApplicationEngine appEngine;

View File

@ -13,7 +13,8 @@ Control {
leftPadding: 20 leftPadding: 20
rightPadding: 20 rightPadding: 20
property int activeTimelineIndex: 0 property int activeTimelineIndex: -1
property int length: timeLine.sectionsList.length
function getActiveTimeline() { function getActiveTimeline() {
return timeLine.sectionsList[root.activeTimelineIndex]; return timeLine.sectionsList[root.activeTimelineIndex];

View File

@ -56,6 +56,7 @@ SystemTrayIcon {
MenuItem { MenuItem {
text: qsTr("Browse Workshop") text: qsTr("Browse Workshop")
enabled: App.globalVariables.isSteamVersion()
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg" icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_steam.svg"
onTriggered: { onTriggered: {
root.open(); root.open();

View File

@ -6,6 +6,7 @@ import QtQuick.Layouts
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
import "../Components" import "../Components"
Util.Popup { Util.Popup {

View File

@ -7,104 +7,112 @@ import QtQuick.Controls.Material
import QtQuick.Controls.Material.impl import QtQuick.Controls.Material.impl
import ScreenPlayApp import ScreenPlayApp
import ScreenPlayUtil import ScreenPlayUtil
import "../Monitors" import "../ContentSettings"
import "../Components" import "../Components"
Drawer { Drawer {
id: root id: root
height: 500 height: 250
modal: false modal: false
edge: Qt.BottomEdge edge: Qt.BottomEdge
background: Rectangle {
color: Material.color(Material.Grey, Material.Shade900)
}
property bool hasPreviewGif: false property bool hasPreviewGif: false
property var type: ContentTypes.InstalledType.QMLWallpaper property var type: ContentTypes.InstalledType.QMLWallpaper
property string contentFolderName property string contentFolderName
onClosed: { onClosed: {
root.contentFolderName = ""; root.contentFolderName = ""
root.type = ContentTypes.InstalledType.Unknown; root.type = ContentTypes.InstalledType.Unknown
} }
function setInstalledDrawerItem(folderName, type) { function setInstalledDrawerItem(folderName, type) {
// Toggle sidebar if clicked on the same content twice // Toggle sidebar if clicked on the same content twice
if (root.contentFolderName === folderName) if (root.contentFolderName === folderName)
return; return
root.contentFolderName = folderName;
root.type = type; if (!App.util.isWallpaper(root.type)){
if (App.util.isWallpaper(root.type)) { return
if (type === ContentTypes.InstalledType.VideoWallpaper)
installedDrawerWrapper.state = "wallpaper";
else
installedDrawerWrapper.state = "scene";
btnLaunchContent.text = qsTr("Set Wallpaper");
} else {
installedDrawerWrapper.state = "widget";
btnLaunchContent.text = qsTr("Set Widget");
} }
root.open();
root.contentFolderName = folderName
root.type = type
if (type === ContentTypes.InstalledType.VideoWallpaper)
installedDrawerWrapper.state = "wallpaper"
else
installedDrawerWrapper.state = "scene"
btnLaunchContent.text = qsTr("Set Wallpaper")
root.open()
} }
function indexOfValue(model, value) { function indexOfValue(model, value) {
for (var i = 0; i < model.length; i++) { for (var i = 0; i < model.length; i++) {
let ourValue = model[i].value; let ourValue = model[i].value
if (value === ourValue) if (value === ourValue)
return i; return i
} }
return -1; return -1
} }
// This is used for removing wallpaper. We need to clear // This is used for removing wallpaper. We need to clear
// the preview image/gif so we can release the file for deletion. // the preview image/gif so we can release the file for deletion.
function clear() { function clear() {
root.close(); root.close()
imagePreview.source = ""; imagePreview.source = ""
animatedImagePreview.source = ""; animatedImagePreview.source = ""
txtHeadline.text = ""; txtHeadline.text = ""
installedDrawerWrapper.state = "inactive"; installedDrawerWrapper.state = "inactive"
} }
onContentFolderNameChanged: { onContentFolderNameChanged: {
const item = App.installedListModel.get(root.contentFolderName); const item = App.installedListModel.get(root.contentFolderName)
//txtHeadline.text = item.m_title //txtHeadline.text = item.m_title
const previewGiFilePath = Qt.resolvedUrl(item.m_absoluteStoragePath + "/" + item.m_previewGIF); const previewGiFilePath = Qt.resolvedUrl(
const previewImageFilePath = Qt.resolvedUrl(item.m_absoluteStoragePath + "/" + item.m_preview); item.m_absoluteStoragePath + "/" + item.m_previewGIF)
root.hasPreviewGif = App.util.fileExists(previewGiFilePath); const previewImageFilePath = Qt.resolvedUrl(
item.m_absoluteStoragePath + "/" + item.m_preview)
root.hasPreviewGif = App.util.fileExists(previewGiFilePath)
if (hasPreviewGif) { if (hasPreviewGif) {
animatedImagePreview.source = previewGiFilePath; animatedImagePreview.source = previewGiFilePath
animatedImagePreview.playing = true; animatedImagePreview.playing = true
} else { } else {
imagePreview.source = previewImageFilePath; imagePreview.source = previewImageFilePath
} }
if (App.util.isWidget(root.type) || (monitorSelection.activeMonitors.length > 0)) { if (App.util.isWidget(root.type)
btnLaunchContent.enabled = true; || (monitorSelection.activeMonitors.length > 0)) {
return; btnLaunchContent.enabled = true
return
} }
btnLaunchContent.enabled = false; btnLaunchContent.enabled = false
} }
RowLayout { Item {
id: installedDrawerWrapper
state: "inactive"
spacing: 20
anchors.fill: parent anchors.fill: parent
ColumnLayout { RowLayout {
Layout.fillWidth: true id: installedDrawerWrapper
Layout.fillHeight: true state: "inactive"
Layout.leftMargin: 10 spacing: 30
spacing: 5
anchors {
margins: 10
fill: parent
}
ColumnLayout { ColumnLayout {
spacing: 5 spacing: 5
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 160 Layout.fillHeight: true
Layout.horizontalStretchFactor: 3
Text { Text {
Layout.leftMargin: 20 Layout.leftMargin: 20
text: qsTr("Select the duration your wallpaper should be visible") text: qsTr("1. Select the duration your wallpaper should be visible")
font.family: App.settings.font font.family: App.settings.font
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font.pointSize: 11 font.pointSize: 14
color: Material.secondaryTextColor color: Material.secondaryTextColor
} }
@ -115,443 +123,364 @@ Drawer {
Connections { Connections {
target: App.screenPlayManager target: App.screenPlayManager
function onPrintQmlTimeline() { function onPrintQmlTimeline() {
timeline.printTimelines(); timeline.printTimelines()
} }
} }
}
ColumnLayout { ToolButton {
Layout.fillWidth: true text: "❌" //qsTr("Remove all timeline ranges")
Layout.fillHeight: true enabled: timeline.length > 1
Layout.horizontalStretchFactor: 1
Button {
text: qsTr("Remove all timeline ranges")
onClicked: timeline.removeAll() onClicked: timeline.removeAll()
anchors {
right: parent.right
top: parent.top
}
} }
} }
} }
ColumnLayout { ColumnLayout {
Layout.horizontalStretchFactor: 2
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
spacing: 10 spacing: 10
Text { Text {
text: qsTr("Select a Monitor to display the content") text: qsTr("2. Select a Monitor to display the content")
font.family: App.settings.font font.family: App.settings.font
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font.pointSize: 11 font.pointSize: 14
color: Material.secondaryTextColor color: Material.secondaryTextColor
} }
MonitorSelection { MonitorSelection {
id: monitorSelection id: monitorSelection
objectName: "monitorSelection" objectName: "monitorSelection"
height: 200 height: 180
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
availableWidth: width availableWidth: width
availableHeight: height availableHeight: height - 20
fontSize: 11 fontSize: 11
} }
} }
}
ColumnLayout {
Layout.preferredWidth: 260
Layout.fillHeight: true
spacing: 10
Rectangle {
id: imageWrapper
color: "#2b2b2b"
Layout.preferredHeight: 180
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
// Do NOT enable async image loading!
// Otherwhise it will still hold the file
// when calling InstalledListModel::deinstallItemAt
// -> asynchronous: false
AnimatedImage {
id: animatedImagePreview
asynchronous: false
playing: true
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
visible: enabled
enabled: root.hasPreviewGif
}
Image {
id: imagePreview
asynchronous: false
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
enabled: !root.hasPreviewGif
visible: enabled
}
Rectangle {
id: tabShadow
height: 70
anchors {
bottom: parent.bottom
right: parent.right
left: parent.left
}
gradient: Gradient {
GradientStop {
position: 1
color: "#EE000000"
}
GradientStop {
position: 0
color: "#00000000"
}
}
}
Text {
id: txtHeadline
text: qsTr("Headline")
font.family: App.settings.font
verticalAlignment: Text.AlignBottom
font.pointSize: 16
color: "white"
wrapMode: Text.WordWrap
height: 50
anchors {
bottom: parent.bottom
right: parent.right
margins: 20
left: parent.left
}
}
}
ColumnLayout { ColumnLayout {
spacing: 20 Layout.horizontalStretchFactor: 1
Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignTop spacing: 10
LabelSlider { Rectangle {
id: sliderVolume id: imageWrapper
color: "#2b2b2b"
Layout.preferredHeight: 100
Layout.fillWidth: true Layout.fillWidth: true
headline: qsTr("Set Volume") Layout.alignment: Qt.AlignTop
Layout.topMargin: 20
slider { // Do NOT enable async image loading!
stepSize: 0.01 // Otherwhise it will still hold the file
from: 0 // when calling InstalledListModel::deinstallItemAt
value: 1 // -> asynchronous: false
to: 1 AnimatedImage {
id: animatedImagePreview
asynchronous: false
playing: true
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
visible: enabled
enabled: root.hasPreviewGif
} }
}
ColumnLayout { Image {
Layout.fillWidth: true id: imagePreview
spacing: 5 asynchronous: false
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
enabled: !root.hasPreviewGif
visible: enabled
}
Rectangle {
id: tabShadow
height: 70
anchors {
bottom: parent.bottom
right: parent.right
left: parent.left
}
gradient: Gradient {
GradientStop {
position: 1
color: "#EE000000"
}
GradientStop {
position: 0
color: "#00000000"
}
}
}
Text { Text {
id: txtComboBoxFillMode id: txtHeadline
visible: false text: qsTr("Headline")
text: qsTr("Fill Mode")
font.family: App.settings.font font.family: App.settings.font
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignBottom
font.pointSize: 10 font.pointSize: 16
color: "#626262" color: "white"
wrapMode: Text.WrapAnywhere wrapMode: Text.WordWrap
Layout.fillWidth: true height: 50
}
ComboBox { anchors {
id: cbVideoFillMode bottom: parent.bottom
right: parent.right
visible: false margins: 20
Layout.fillWidth: true left: parent.left
textRole: "text"
valueRole: "value"
font.family: App.settings.font
model: [
{
"value": Settings.FillMode.Stretch,
"text": qsTr("Stretch")
},
{
"value": Settings.FillMode.Fill,
"text": qsTr("Fill")
},
{
"value": Settings.FillMode.Contain,
"text": qsTr("Contain")
},
{
"value": Settings.FillMode.Cover,
"text": qsTr("Cover")
},
{
"value": Settings.FillMode.Scale_Down,
"text": qsTr("Scale-Down")
}
]
Component.onCompleted: {
cbVideoFillMode.currentIndex = root.indexOfValue(cbVideoFillMode.model, App.settings.videoFillMode);
} }
} }
} }
}
Dialog { Dialog {
id: dialog id: dialog
standardButtons: Dialog.Ok standardButtons: Dialog.Ok
title: qsTr("Export Godot project") title: qsTr("Export Godot project")
property alias message: messageText.text property alias message: messageText.text
Text { Text {
id: messageText id: messageText
}
} }
}
Button { Button {
id: btnLaunchContent id: btnLaunchContent
objectName: "btnLaunchContent" Layout.fillWidth: true
enabled: App.util.isWidget(root.type) ? true : monitorSelection.isSelected Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg" objectName: "btnLaunchContent"
icon.color: "white" enabled: App.util.isWidget(root.type) && activeMonitors.length > 0 ? true : monitorSelection.isSelected
font.pointSize: 12 icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg"
onClicked: { icon.color: "white"
const item = App.installedListModel.get(root.contentFolderName); font.pointSize: 12
const absoluteStoragePath = item.m_absoluteStoragePath; onClicked: {
const previewImage = item.m_preview; const item = App.installedListModel.get(
if (App.util.isWallpaper(root.type)) { root.contentFolderName)
if (type === ContentTypes.InstalledType.GodotWallpaper) { const absoluteStoragePath = item.m_absoluteStoragePath
if (App.globalVariables.isBasicVersion()) { const previewImage = item.m_preview
installedDrawerWrapper.state = "inactive"; if (App.util.isWallpaper(root.type)) {
return; if (type === ContentTypes.InstalledType.GodotWallpaper) {
} if (App.globalVariables.isBasicVersion()) {
} installedDrawerWrapper.state = "inactive"
let activeMonitors = monitorSelection.getActiveMonitors(); return
// TODO Alert user to choose a monitor
if (activeMonitors.length === 0)
return;
// We only have sliderVolume if it is a VideoWallpaper
let volume = 0;
if (type === ContentTypes.InstalledType.VideoWallpaper)
volume = Math.round(sliderVolume.slider.value * 100) / 100;
if (type === ContentTypes.InstalledType.GodotWallpaper) {
App.util.exportGodotProject(absoluteStoragePath, App.globalVariables.godotEditorExecutablePath).then(result => {
if (!result.success) {
dialog.title = ("Error exporting Godot");
dialog.message = result.message;
dialog.open();
} else {
const screenFile = item.m_file;
let success = App.screenPlayManager.createWallpaper(root.type, cbVideoFillMode.currentValue, absoluteStoragePath, previewImage, screenFile, activeMonitors, volume, 1, {}, true);
} }
}); }
root.close(); let activeMonitors = monitorSelection.getActiveMonitors()
return; if (type === ContentTypes.InstalledType.GodotWallpaper) {
App.util.exportGodotProject(
absoluteStoragePath,
App.globalVariables.godotEditorExecutablePath).then(
result => {
if (!result.success) {
dialog.title = ("Error exporting Godot")
dialog.message = result.message
dialog.open()
} else {
const screenFile = item.m_file
let volume = 1
let success = App.screenPlayManager.createWallpaper(
root.type,
cbVideoFillMode.currentValue,
absoluteStoragePath,
previewImage,
screenFile,
activeMonitors,
volume,
1, {}, true)
}
})
root.close()
return
}
const activeTimeline = timeline.getActiveTimeline()
const file = item.m_file
let success = App.screenPlayManager.setWallpaperAtTimelineIndex(
root.type,
absoluteStoragePath,
previewImage,
file,
activeMonitors,
timeline.activeTimelineIndex,
activeTimeline.identifier, true)
} }
const activeTimeline = timeline.getActiveTimeline(); root.close()
const screenFile = item.m_file; monitorSelection.reset()
const playbackRate = 1;
const jsonProperties = {};
let success = App.screenPlayManager.setWallpaperAtTimelineIndex(
root.type, cbVideoFillMode.currentValue, absoluteStoragePath, previewImage, screenFile, activeMonitors, volume, playbackRate, jsonProperties, timeline.activeTimelineIndex, activeTimeline.identifier, true);
} }
if (App.util.isWidget(root.type))
App.screenPlayManager.startWidget(type, Qt.point(0, 0), absoluteStoragePath, previewImage, {}, true);
root.close();
monitorSelection.reset();
} }
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
} }
states: [
State {
name: "inactive"
PropertyChanges {
target: imagePreview
opacity: 0
anchors.topMargin: 20
}
PropertyChanges {
target: animatedImagePreview
opacity: 0
anchors.topMargin: 20
}
},
State {
name: "activeWidget"
PropertyChanges {
target: monitorSelection
visible: false
enabled: false
}
PropertyChanges {
target: imagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: animatedImagePreview
opacity: 1
anchors.topMargin: 0
}
},
State {
name: "wallpaper"
PropertyChanges {
target: imagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: animatedImagePreview
opacity: 1
anchors.topMargin: 0
}
},
State {
name: "scene"
PropertyChanges {
target: imagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: animatedImagePreview
opacity: 1
anchors.topMargin: 0
}
}
]
transitions: [
Transition {
to: "inactive"
from: "*"
reversible: true
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 400
}
},
Transition {
to: "widget"
from: "*"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 100
}
}
}
},
Transition {
to: "wallpaper"
from: "*"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 100
}
}
}
},
Transition {
to: "scene"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 100
}
}
}
}
]
} }
ToolButton { ToolButton {
id: button id: button
Layout.alignment: Qt.AlignTop anchors {
top: parent.top
topMargin: -20
right: parent.right
}
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_close.svg" icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_close.svg"
icon.width: 15 icon.width: 15
icon.height: 15 icon.height: 15
onClicked: { onClicked: {
root.close(); root.close()
installedDrawerWrapper.state = "inactive"; installedDrawerWrapper.state = "inactive"
} }
} }
states: [
State {
name: "inactive"
PropertyChanges {
target: imagePreview
opacity: 0
anchors.topMargin: 20
}
PropertyChanges {
target: animatedImagePreview
opacity: 0
anchors.topMargin: 20
}
},
State {
name: "activeWidget"
PropertyChanges {
target: sliderVolume
visible: false
}
PropertyChanges {
target: monitorSelection
visible: false
enabled: false
}
PropertyChanges {
target: imagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: animatedImagePreview
opacity: 1
anchors.topMargin: 0
}
},
State {
name: "wallpaper"
PropertyChanges {
target: imagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: animatedImagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: txtComboBoxFillMode
opacity: 1
visible: true
}
PropertyChanges {
target: cbVideoFillMode
opacity: 1
visible: true
}
},
State {
name: "scene"
PropertyChanges {
target: imagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: animatedImagePreview
opacity: 1
anchors.topMargin: 0
}
PropertyChanges {
target: sliderVolume
opacity: 0
visible: false
}
}
]
transitions: [
Transition {
to: "inactive"
from: "*"
reversible: true
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 400
}
},
Transition {
to: "widget"
from: "*"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 100
}
}
}
},
Transition {
to: "wallpaper"
from: "*"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 100
}
}
}
},
Transition {
to: "scene"
SequentialAnimation {
ParallelAnimation {
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "opacity"
duration: 200
}
NumberAnimation {
targets: [animatedImagePreview, imagePreview]
property: "anchors.topMargin"
duration: 100
}
}
}
}
]
} }
} }

View File

@ -223,7 +223,7 @@ Item {
type: m_type type: m_type
isNew: m_isNew isNew: m_isNew
containsAudio: m_containsAudio containsAudio: m_containsAudio
screenId: m_folderName folderName: m_folderName
absoluteStoragePath: m_absoluteStoragePath absoluteStoragePath: m_absoluteStoragePath
publishedFileID: m_publishedFileID publishedFileID: m_publishedFileID
itemIndex: index itemIndex: index

View File

@ -4,12 +4,13 @@ import QtQuick.Controls
import QtQuick.Controls.Material import QtQuick.Controls.Material
import ScreenPlayApp import ScreenPlayApp
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
import QtQuick.Window
Item { Item {
id: root id: root
property string customTitle property string customTitle
property string screenId property string folderName
property url absoluteStoragePath property url absoluteStoragePath
property int type: Util.ContentTypes.InstalledType.Unknown property int type: Util.ContentTypes.InstalledType.Unknown
// Must be var to make it work wit 64bit ints // Must be var to make it work wit 64bit ints
@ -20,13 +21,15 @@ Item {
property bool containsAudio: false property bool containsAudio: false
property int version: App.globalVariables.version property int version: App.globalVariables.version
property bool hasLicense: { property bool hasLicense: {
if ((root.version === GlobalVariables.OpenSourceStandalone || root.version === GlobalVariables.OpenSourceSteam) && root.type === Util.ContentTypes.InstalledType.GodotWallpaper) { if ((root.version === GlobalVariables.OpenSourceStandalone
return false; || root.version === GlobalVariables.OpenSourceSteam)
&& root.type === Util.ContentTypes.InstalledType.GodotWallpaper) {
return false
} }
return true; return true
} }
signal clicked(var screenId, var type) signal clicked(var folderName, var type)
signal openContextMenu(var point) signal openContextMenu(var point)
signal openOpenLicensePopup signal openOpenLicensePopup
@ -34,16 +37,16 @@ Item {
height: 180 height: 180
onTypeChanged: { onTypeChanged: {
if (App.util.isWidget(type)) { if (App.util.isWidget(type)) {
icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_widgets.svg"; icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_widgets.svg"
return; return
} }
if (App.util.isScene(type)) { if (App.util.isScene(type)) {
icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_code.svg"; icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_code.svg"
return; return
} }
if (App.util.isVideo(type)) { if (App.util.isVideo(type)) {
icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_movie.svg"; icnType.source = "qrc:/qml/ScreenPlayApp/assets/icons/icon_movie.svg"
return; return
} }
} }
@ -51,10 +54,10 @@ Item {
running: true running: true
onTriggered: showAnim.start() onTriggered: showAnim.start()
interval: { interval: {
var itemIndexMax = itemIndex; var itemIndexMax = itemIndex
if (itemIndex > 30) if (itemIndex > 30)
itemIndexMax = 3; itemIndexMax = 3
5 * itemIndexMax * Math.random(); 5 * itemIndexMax * Math.random()
} }
} }
@ -249,31 +252,74 @@ Item {
maskSource: mask maskSource: mask
MouseArea { MouseArea {
id: hoverArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: !root.isScrolling && !showAnim.running hoverEnabled: !root.isScrolling && !showAnim.running
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
onEntered: { onEntered: handleMouseEnter()
if (!root.hasLicense) onExited: handleMouseExit()
return;
root.state = "hover";
screenPlayItemImage.state = "hover";
screenPlayItemImage.enter();
}
onExited: {
root.state = "";
screenPlayItemImage.state = "loaded";
screenPlayItemImage.exit();
}
onClicked: function (mouse) { onClicked: function (mouse) {
if (!root.hasLicense) { if (!root.hasLicense) {
root.openOpenLicensePopup(); root.openOpenLicensePopup()
return; return
} }
if (App.util.isWidget(root.type))
return
if (mouse.button === Qt.LeftButton) if (mouse.button === Qt.LeftButton)
root.clicked(root.screenId, root.type); root.clicked(root.folderName, root.type)
else if (mouse.button === Qt.RightButton) else if (mouse.button === Qt.RightButton)
root.openContextMenu(Qt.point(mouseX, mouseY)); root.openContextMenu(Qt.point(mouseX, mouseY))
}
function handleMouseEnter(){
if (!root.hasLicense)
return
root.state = "hover"
screenPlayItemImage.state = "hover"
screenPlayItemImage.enter()
}
function handleMouseExit(){
if(widgetStartButton.enabled && widgetStartButton.hovered)
return
root.state = ""
screenPlayItemImage.state = "loaded"
screenPlayItemImage.exit()
}
}
Button {
id: widgetStartButton
enabled: App.util.isWidget(root.type)
hoverEnabled: enabled
text: qsTr("Start")
opacity: enabled && (widgetStartButton.hovered || hoverArea.containsMouse) ? 1 : 0
onClicked: {
App.screenPlayManager.startWidget(
root.type, Qt.point(0, 0),
root.absoluteStoragePath,
m_preview, {}, true)
}
onHoveredChanged: {
print(hovered)
if(hovered)
hoverArea.handleMouseEnter()
else
hoverArea.handleMouseExit()
}
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 5
}
Behavior on opacity {
PropertyAnimation {
property: "opacity"
duration: 250
}
} }
} }
} }
@ -322,11 +368,11 @@ Item {
to: 1 to: 1
easing.type: Easing.OutQuart easing.type: Easing.OutQuart
} }
}, },
Transition { Transition {
from: "hover" from: "hover"
to: "" to: ""
ScaleAnimator { ScaleAnimator {
target: screenPlayItemWrapper target: screenPlayItemWrapper
duration: 2000 duration: 2000

View File

@ -2,7 +2,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import ScreenPlayUtil as Util import ScreenPlayUtil as Util
import ScreenPlayApp 1.0 import ScreenPlayApp 1.0
import "Monitors" as Monitors import "ContentSettings" as ContentSettings
import "Installed" as Installed import "Installed" as Installed
import "Navigation" as Navigation import "Navigation" as Navigation
import "Community" as Community import "Community" as Community
@ -58,8 +58,8 @@ Item {
modalSource: content modalSource: content
} }
Monitors.MonitorsView { ContentSettings.ContentSettingsView {
id: monitors id: contentSettingsView
modalSource: content modalSource: content
} }
TrayIcon { TrayIcon {
@ -145,7 +145,9 @@ Item {
} }
onChangePage: function (name) { onChangePage: function (name) {
monitors.close(); // Close in case the user clicks
// on the tray icon
contentSettingsView.close();
switchPage(name); switchPage(name);
} }
} }

View File

@ -1,81 +0,0 @@
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

@ -295,16 +295,41 @@ Rectangle {
ToolTip.text: qsTr("Close All Content") ToolTip.text: qsTr("Close All Content")
ToolTip.visible: hovered ToolTip.visible: hovered
} }
ToolButton { }
id: miConfig
Layout.alignment: Qt.AlignVCenter Button {
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_video_settings.svg" id: miConfig
icon.width: root.iconWidth icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_video_settings.svg"
icon.height: root.iconHeight icon.width: root.iconWidth
onClicked: App.util.setToggleWallpaperConfiguration() icon.height: root.iconHeight
hoverEnabled: true onClicked: App.util.setToggleWallpaperConfiguration()
ToolTip.text: qsTr("Configure Wallpaper") hoverEnabled: true
ToolTip.visible: hovered text: contentActive ? qsTr("Configure Content") : qsTr("No Active Content")
bottomInset: 10
topInset: 10
anchors {
top: parent.top
right: parent.right
rightMargin: 10
bottom: parent.bottom
}
Material.accent: contentActive ? "gold" : Material.secondaryTextColor
property bool contentActive: App.screenPlayManager.activeWallpaperCounter > 0
background: Rectangle {
color: Material.theme === Material.Light ? Material.background : "#242424"
border.color: {
if(contentActive){
return "gold"
} else {
Material.theme === Material.Light ? Material.iconDisabledColor : Qt.darker(
Material.background)
}
}
border.width: 1
radius: 3
} }
} }

View File

@ -61,6 +61,9 @@ std::shared_ptr<WallpaperTimelineSection> ScreenPlayManager::findActiveWallpaper
return nullptr; return nullptr;
} }
/*!
\brief Returns the current active timline. There must always be an active timeline!
*/
std::shared_ptr<WallpaperTimelineSection> ScreenPlayManager::getCurrentTimeline() std::shared_ptr<WallpaperTimelineSection> ScreenPlayManager::getCurrentTimeline()
{ {
const QTime currentTime = QTime::currentTime(); const QTime currentTime = QTime::currentTime();
@ -69,6 +72,7 @@ std::shared_ptr<WallpaperTimelineSection> ScreenPlayManager::getCurrentTimeline(
return section; return section;
} }
} }
qCritical() << "No active timeline";
return nullptr; return nullptr;
} }
@ -109,6 +113,10 @@ void ScreenPlayManager::checkActiveWallpaperTimeline()
} }
} }
/*!
\brief Change active timeline. We need an extra flags to know if our
timeline is active and out of time range.
*/
void ScreenPlayManager::activateNewTimeline() void ScreenPlayManager::activateNewTimeline()
{ {
// Remove old timeline content // Remove old timeline content
@ -150,29 +158,21 @@ void ScreenPlayManager::activateNewTimeline()
\brief Sets the wallpaper at a spesific timeline. \brief Sets the wallpaper at a spesific timeline.
*/ */
bool ScreenPlayManager::setWallpaperAtTimelineIndex( bool ScreenPlayManager::setWallpaperAtTimelineIndex(
const ContentTypes::InstalledType type, const ScreenPlay::ContentTypes::InstalledType type,
const Video::FillMode fillMode,
const QString& absolutePath, const QString& absolutePath,
const QString& previewImage, const QString& previewImage,
const QString& file, const QString& file,
const QVector<int>& monitorIndex, const QVector<int>& monitorIndex,
const float volume,
const float playbackRate,
const QJsonObject& properties,
const int timelineIndex, const int timelineIndex,
const QString& identifier, const QString& identifier,
const bool saveToProfilesConfigFile) const bool saveToProfilesConfigFile)
{ {
WallpaperData wallpaperData; WallpaperData wallpaperData;
wallpaperData.type = type; wallpaperData.type = type;
wallpaperData.fillMode = fillMode;
wallpaperData.absolutePath = absolutePath; wallpaperData.absolutePath = absolutePath;
wallpaperData.previewImage = previewImage; wallpaperData.previewImage = previewImage;
wallpaperData.file = file; wallpaperData.file = file;
wallpaperData.monitors = monitorIndex; wallpaperData.monitors = monitorIndex;
wallpaperData.volume = volume;
wallpaperData.playbackRate = playbackRate;
wallpaperData.properties = properties;
bool ok = false; bool ok = false;
for (auto& timelineSection : m_wallpaperTimelineSectionsList) { for (auto& timelineSection : m_wallpaperTimelineSectionsList) {
const bool sameIndex = timelineSection->index == timelineIndex; const bool sameIndex = timelineSection->index == timelineIndex;
@ -251,6 +251,7 @@ std::shared_ptr<ScreenPlayWallpaper> ScreenPlayManager::startWallpaper(
// Remove file:/// // Remove file:///
wallpaperData.absolutePath = QUrl::fromUserInput(wallpaperData.absolutePath).toLocalFile(); wallpaperData.absolutePath = QUrl::fromUserInput(wallpaperData.absolutePath).toLocalFile();
const QString appID = Util().generateRandomString(); const QString appID = Util().generateRandomString();
qInfo() << "Start wallpaper" << wallpaperData.absolutePath << appID;
// Only support remove wallpaper that spans over 1 monitor // Only support remove wallpaper that spans over 1 monitor
// if (wallpaperData.monitors.length() == 1) { // if (wallpaperData.monitors.length() == 1) {
@ -281,7 +282,6 @@ std::shared_ptr<ScreenPlayWallpaper> ScreenPlayManager::startWallpaper(
return nullptr; return nullptr;
} }
m_monitorListModel->setWallpaperMonitor(wallpaper, wallpaperData.monitors); m_monitorListModel->setWallpaperMonitor(wallpaper, wallpaperData.monitors);
increaseActiveWallpaperCounter();
return wallpaper; return wallpaper;
} }
@ -326,7 +326,7 @@ bool ScreenPlayManager::startWidget(
if (!widget->start()) { if (!widget->start()) {
return false; return false;
} }
increaseActiveWidgetsCounter(); setActiveWidgetsCounter(activeWidgetsCounter() + 1);
m_screenPlayWidgets.append(widget); m_screenPlayWidgets.append(widget);
return true; return true;
} }
@ -495,8 +495,10 @@ ScreenPlayWallpaper* ScreenPlayManager::getWallpaperByAppID(const QString& appID
return nullptr; return nullptr;
} }
// We always handle the endTimeString, because it is the handle for the /*!
// timeline. The last, default, timeline does not have a handle. \brief We always handle the endTimeString, because it is the handle for the
timeline. The last, default, timeline does not have a handle.
*/
bool ScreenPlayManager::moveTimelineAt(const int index, const QString identifier, const float relativePosition, QString positionTimeString) bool ScreenPlayManager::moveTimelineAt(const int index, const QString identifier, const float relativePosition, QString positionTimeString)
{ {
m_contentTimer.stop(); m_contentTimer.stop();
@ -528,6 +530,9 @@ bool ScreenPlayManager::moveTimelineAt(const int index, const QString identifier
return true; return true;
} }
/*!
\brief Converts a range from 0.0f - 1.0f to 00:00:00 0 23:59:59
*/
QString ScreenPlayManager::getTimeString(double relativeLinePosition) QString ScreenPlayManager::getTimeString(double relativeLinePosition)
{ {
if (relativeLinePosition == 1.0) { if (relativeLinePosition == 1.0) {
@ -562,6 +567,9 @@ QString ScreenPlayManager::getTimeString(double relativeLinePosition)
return QString("%1:%2:%3").arg(hours, 2, 10, QChar('0')).arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0')); return QString("%1:%2:%3").arg(hours, 2, 10, QChar('0')).arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0'));
} }
/*!
\brief Update m_wallpaperTimelineSectionsList index based on the startTime;
*/
void ScreenPlayManager::updateIndices() void ScreenPlayManager::updateIndices()
{ {
// Sort the vector based on startTime // Sort the vector based on startTime
@ -576,6 +584,12 @@ void ScreenPlayManager::updateIndices()
} }
} }
/*!
\brief Adds a new timeline at relative position. We always shrink the timeline at the input
position and append the new one to the left. There must always (lightning) an active
timeline section.
*/
bool ScreenPlayManager::addTimelineAt(const int index, const float reltiaveLinePosition, QString identifier) bool ScreenPlayManager::addTimelineAt(const int index, const float reltiaveLinePosition, QString identifier)
{ {
@ -632,7 +646,10 @@ bool ScreenPlayManager::addTimelineAt(const int index, const float reltiaveLineP
return true; return true;
} }
// Gets called from qml /*!
\brief Qml function that removes all Timeline sections. Qml then creates
a new default section.
*/
void ScreenPlayManager::removeAllTimlineSections() void ScreenPlayManager::removeAllTimlineSections()
{ {
m_contentTimer.stop(); m_contentTimer.stop();
@ -665,6 +682,10 @@ void ScreenPlayManager::removeAllTimlineSections()
// the default timeline after this function // the default timeline after this function
} }
/*!
\brief Removes a timeline at a given index. Expands the timeline next to it
to fill the space.
*/
bool ScreenPlayManager::removeTimelineAt(const int index) bool ScreenPlayManager::removeTimelineAt(const int index)
{ {
printTimelines(); printTimelines();
@ -726,6 +747,9 @@ bool ScreenPlayManager::removeTimelineAt(const int index)
return true; return true;
} }
/*!
\brief Print to check if our qml data matches our c++.
*/
void ScreenPlayManager::printTimelines() void ScreenPlayManager::printTimelines()
{ {
std::cout << "#############################\n"; std::cout << "#############################\n";
@ -734,6 +758,9 @@ void ScreenPlayManager::printTimelines()
} }
} }
/*!
\brief Qml function to build our timeline on creation in qml.
*/
QVariantMap ScreenPlayManager::initialStopPositions() QVariantMap ScreenPlayManager::initialStopPositions()
{ {
QVariantMap sectionPositions; QVariantMap sectionPositions;
@ -803,6 +830,24 @@ void ScreenPlayManager::newConnection()
m_unconnectedClients.push_back(std::move(connection)); m_unconnectedClients.push_back(std::move(connection));
} }
void ScreenPlayManager::setActiveWallpaperCounter(int activeWallpaperCounter)
{
if (m_activeWallpaperCounter == activeWallpaperCounter)
return;
m_activeWallpaperCounter = activeWallpaperCounter;
emit activeWallpaperCounterChanged(m_activeWallpaperCounter);
}
void ScreenPlayManager::setActiveWidgetsCounter(int activeWidgetsCounter)
{
if (m_activeWidgetsCounter == activeWidgetsCounter)
return;
m_activeWidgetsCounter = activeWidgetsCounter;
emit activeWidgetsCounterChanged(m_activeWidgetsCounter);
}
/*! /*!
\brief Removes a wallpaper from the given appID. Returns true on success. \brief Removes a wallpaper from the given appID. Returns true on success.
*/ */
@ -814,10 +859,9 @@ bool ScreenPlayManager::removeWallpaper(const QString& appID)
qCritical() << "No timeline found."; qCritical() << "No timeline found.";
return false; return false;
} }
if (activeTimelineSection->activeWallpaperList.empty()) {
qCritical() << "No activeWallpaperList is empty for the current active timeline."; if(activeTimelineSection->activeWallpaperList.empty())
return false; return true;
}
activeTimelineSection->activeWallpaperList.erase( activeTimelineSection->activeWallpaperList.erase(
std::remove_if( std::remove_if(
@ -836,8 +880,6 @@ bool ScreenPlayManager::removeWallpaper(const QString& appID)
wallpaper->close(); wallpaper->close();
decreaseActiveWallpaperCounter();
return true; return true;
})); }));
@ -869,7 +911,8 @@ bool ScreenPlayManager::removeWidget(const QString& appID)
qInfo() << "Remove widget " << appID; qInfo() << "Remove widget " << appID;
decreaseActiveWidgetsCounter(); setActiveWidgetsCounter(activeWidgetsCounter() - 1);
return true; return true;
}), }),
@ -889,11 +932,18 @@ bool ScreenPlayManager::removeWidget(const QString& appID)
*/ */
bool ScreenPlayManager::setWallpaperValue(const QString& appID, const QString& key, const QString& value) bool ScreenPlayManager::setWallpaperValue(const QString& appID, const QString& key, const QString& value)
{ {
// for (auto& wallpaper : m_screenPlayWallpapers) { std::shared_ptr<WallpaperTimelineSection> activeTimelineSection = findActiveWallpaperTimelineSection();
// if (wallpaper->appID() == appID) { if(!activeTimelineSection){
// return wallpaper->setWallpaperValue(key, value, true); qCritical() << "setWallpaperValue failed, because no active timeline section was found";
// } return false;
// } }
for (auto& wallpaper : activeTimelineSection->activeWallpaperList) {
if (wallpaper->appID() == appID) {
return wallpaper->setWallpaperValue(key, value, true);
}
}
qCritical() << "No wallpaper with matching appID was found";
return false; return false;
} }
@ -937,8 +987,8 @@ bool ScreenPlayManager::saveProfiles()
profile.insert("version", m_settings->getProfilesVersion().toString()); profile.insert("version", m_settings->getProfilesVersion().toString());
profile.insert("profiles", activeProfileList); profile.insert("profiles", activeProfileList);
Util util;
if (util.writeJsonObjectToFile({ m_globalVariables->localSettingsPath().toString() + "/profiles.json" }, profile)) { if (m_util.writeJsonObjectToFile({ m_globalVariables->localSettingsPath().toString() + "/profiles.json" }, profile)) {
emit profilesSaved(); emit profilesSaved();
return true; return true;
} }
@ -946,19 +996,20 @@ bool ScreenPlayManager::saveProfiles()
} }
/*! /*!
\brief Loads all wallpaper from profiles.json when the version number matches and starts the available wallpaper \brief Loads all wallpaper from C:\Users\XXX\AppData\Local\ScreenPlay\ScreenPlay\profiles.json
when the version number matches and starts the available wallpaper
*/ */
bool ScreenPlayManager::loadProfiles() bool ScreenPlayManager::loadProfiles()
{ {
Util util;
const auto configObj = util.openJsonFileToObject(m_globalVariables->localSettingsPath().toString() + "/profiles.json"); const auto configObj = m_util.openJsonFileToObject(m_globalVariables->localSettingsPath().toString() + "/profiles.json");
if (!configObj) { if (!configObj) {
qWarning() << "Could not load active profiles at path: " << m_globalVariables->localSettingsPath().toString() + "/profiles.json"; qWarning() << "Could not load active profiles at path: " << m_globalVariables->localSettingsPath().toString() + "/profiles.json";
return false; return false;
} }
std::optional<QVersionNumber> version = util.getVersionNumberFromString(configObj->value("version").toString()); std::optional<QVersionNumber> version = m_util.getVersionNumberFromString(configObj->value("version").toString());
QVersionNumber requiredVersion = m_settings->getProfilesVersion(); QVersionNumber requiredVersion = m_settings->getProfilesVersion();
if (version && *version != requiredVersion) { if (version && *version != requiredVersion) {
qWarning() << "Version missmatch fileVersion: " << version->toString() << "m_version: " << requiredVersion.toString(); qWarning() << "Version missmatch fileVersion: " << version->toString() << "m_version: " << requiredVersion.toString();
@ -989,7 +1040,7 @@ bool ScreenPlayManager::loadProfiles()
std::shared_ptr<WallpaperTimelineSection> wallpaperData = wallpaperDataOpt.value(); std::shared_ptr<WallpaperTimelineSection> wallpaperData = wallpaperDataOpt.value();
wallpaperData->index = m_wallpaperTimelineSectionsList.length(); wallpaperData->index = m_wallpaperTimelineSectionsList.length();
wallpaperData->identifier = util.generateRandomString(4); wallpaperData->identifier = m_util.generateRandomString(4);
qInfo() << wallpaperData->index qInfo() << wallpaperData->index
<< wallpaperData->startTime << wallpaperData->startTime
@ -1016,6 +1067,7 @@ bool ScreenPlayManager::loadProfiles()
return true; return true;
} }
/*! /*!
* \brief Calculates the relative position of a given time within a day. * \brief Calculates the relative position of a given time within a day.
* *
@ -1044,6 +1096,18 @@ float calculateRelativePosition(const QTime& endTime)
return qRound(relativePosition * 10000.0) / 10000.0; return qRound(relativePosition * 10000.0) / 10000.0;
} }
/*!
\brief Parses one timeline wallpaper:
"timelineWallpaper": [
{
"endTime": "08:32:00",
"startTime": "00:00:00",
"wallpaper": [
[...]
]
},
*/
std::optional<std::shared_ptr<WallpaperTimelineSection>> ScreenPlayManager::loadTimelineWallpaperConfig(const QJsonObject& timelineObj) std::optional<std::shared_ptr<WallpaperTimelineSection>> ScreenPlayManager::loadTimelineWallpaperConfig(const QJsonObject& timelineObj)
{ {
const QTime startTime = QTime::fromString(timelineObj.value("startTime").toString(), m_timelineTimeFormat); const QTime startTime = QTime::fromString(timelineObj.value("startTime").toString(), m_timelineTimeFormat);
@ -1068,6 +1132,32 @@ std::optional<std::shared_ptr<WallpaperTimelineSection>> ScreenPlayManager::load
return timelineSection; return timelineSection;
} }
/*!
\brief Loads the wallpaper object in the wallpaper array:
"timelineWallpaper": [
{
"endTime": "08:32:00",
"startTime": "00:00:00",
"wallpaper": [
{
"absolutePath": "file:///C:/Code/Cpp/ScreenPlay/672870/1234567",
"file": "AAA.webm",
"fillMode": "Cover",
"isLooping": false,
"monitors": [
0
],
"playbackRate": 1,
"previewImage": "previewThumbnail.jpg",
"properties": {
},
"type": "VideoWallpaper",
"volume": 1
}
]
},
*/
std::optional<WallpaperData> ScreenPlayManager::loadWallpaperConfig(const QJsonObject& wallpaperObj) std::optional<WallpaperData> ScreenPlayManager::loadWallpaperConfig(const QJsonObject& wallpaperObj)
{ {
if (wallpaperObj.empty()) if (wallpaperObj.empty())
@ -1111,6 +1201,9 @@ std::optional<WallpaperData> ScreenPlayManager::loadWallpaperConfig(const QJsonO
return wallpaperData; return wallpaperData;
} }
/*!
\brief Loads a widget from C:\Users\XXX\AppData\Local\ScreenPlay\ScreenPlay\profiles.json
*/
bool ScreenPlayManager::loadWidgetConfig(const QJsonObject& widgetObj) bool ScreenPlayManager::loadWidgetConfig(const QJsonObject& widgetObj)
{ {
if (widgetObj.empty()) if (widgetObj.empty())

View File

@ -9,7 +9,7 @@ Item {
property bool refresh: false property bool refresh: false
property bool enabled: true property bool enabled: true
signal setSidebaractiveItem(var screenId, var type) signal setSidebaractiveItem(var folderName, var type)
signal setNavigationItem(var pos) signal setNavigationItem(var pos)
signal setSidebarActive(var active) signal setSidebarActive(var active)

View File

@ -81,7 +81,7 @@ Item {
width: gridView.cellWidth - 30 width: gridView.cellWidth - 30
customTitle: m_title customTitle: m_title
type: m_type type: m_type
screenId: m_folderName folderName: m_folderName
absoluteStoragePath: m_absoluteStoragePath absoluteStoragePath: m_absoluteStoragePath
publishedFileID: m_publishedFileID publishedFileID: m_publishedFileID
preview: m_preview preview: m_preview

View File

@ -14,14 +14,14 @@ Item {
property bool isSelected: false property bool isSelected: false
property string customTitle: "name here" property string customTitle: "name here"
property string absoluteStoragePath: "" property string absoluteStoragePath: ""
property string screenId: "" property string folderName: ""
property string preview: "" property string preview: ""
property var type property var type
property bool hasMenuOpen: false property bool hasMenuOpen: false
property var publishedFileID: 0 property var publishedFileID: 0
property int itemIndex property int itemIndex
signal itemClicked(var screenId, var type, var isActive) signal itemClicked(var folderName, var type, var isActive)
height: 250 height: 250
onTypeChanged: { onTypeChanged: {
@ -140,7 +140,7 @@ Item {
isSelected = true; isSelected = true;
else else
isSelected = false; isSelected = false;
itemClicked(screenId, type, isSelected); root.itemClicked(folderName, type, isSelected);
} }
anchors { anchors {