mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-21 18:22:29 +01:00
Refactor timelines
Fix monitorlistmodel and add mock monitor list for easier testing Add working active wallpaper preview based on selected timeline Change many calls to use coroutines that make the async handling of wallpaper closing 1000x easier Fix wallpaper count based on actual connected wallpaper and not based on started Add LineIndicator user selected indicator
This commit is contained in:
parent
ee47a6d968
commit
0ad84736c0
@ -31,8 +31,8 @@ Rectangle {
|
||||
text: "Exit"
|
||||
onClicked: {
|
||||
Qt.callLater(function () {
|
||||
Wallpaper.terminate();
|
||||
});
|
||||
Wallpaper.terminate();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,14 @@ Item {
|
||||
|
||||
Component.onCompleted: {
|
||||
request("http://xkcd.com/info.0.json", function (o) {
|
||||
if (o.status === 200) {
|
||||
var d = eval('new Object(' + o.responseText + ')');
|
||||
console.log(o.responseText);
|
||||
img.source = d.img;
|
||||
} else {
|
||||
console.log("Some error has occurred");
|
||||
}
|
||||
});
|
||||
if (o.status === 200) {
|
||||
var d = eval('new Object(' + o.responseText + ')');
|
||||
console.log(o.responseText);
|
||||
img.source = d.img;
|
||||
} else {
|
||||
console.log("Some error has occurred");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Image {
|
||||
|
@ -1,8 +1,6 @@
|
||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||
|
||||
#pragma once
|
||||
#include <QString>
|
||||
|
||||
#include "ScreenPlay/create.h"
|
||||
#include "ScreenPlay/globalvariables.h"
|
||||
#include "ScreenPlay/installedlistfilter.h"
|
||||
@ -13,8 +11,9 @@
|
||||
#include "ScreenPlay/settings.h"
|
||||
#include "ScreenPlay/wizards.h"
|
||||
#include "ScreenPlayUtil/util.h"
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <optional>
|
||||
|
||||
#include "ScreenPlay/wallpapertimelinesection.h"
|
||||
#include "ScreenPlayUtil/contenttypes.h"
|
||||
|
||||
namespace ScreenPlay {
|
||||
|
||||
@ -28,6 +29,9 @@ struct Monitor {
|
||||
|
||||
int m_index { 0 };
|
||||
QRect m_geometry;
|
||||
QString m_wallpaperPreviewImage;
|
||||
QString m_appID;
|
||||
ContentTypes::InstalledType m_installedType = ContentTypes::InstalledType::Unknown;
|
||||
};
|
||||
|
||||
class MonitorListModel : public QAbstractListModel {
|
||||
@ -50,15 +54,15 @@ public:
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
void setWallpaperMonitor(const std::shared_ptr<WallpaperTimelineSection>& timelineSection,
|
||||
const QVector<int> monitors);
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
std::optional<QString> getAppIDByMonitorIndex(const int index) const;
|
||||
Q_INVOKABLE void reset();
|
||||
Q_INVOKABLE QRect absoluteDesktopSize() const;
|
||||
|
||||
Q_INVOKABLE QRect absoluteDesktopSize() const;
|
||||
Q_INVOKABLE QSize totalDesktopSize() const;
|
||||
|
||||
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
|
||||
signals:
|
||||
void monitorReloadCompleted();
|
||||
void setNewActiveMonitor(int index, QString path);
|
||||
@ -82,7 +86,7 @@ private:
|
||||
|
||||
private:
|
||||
QVector<Monitor> m_monitorList;
|
||||
std::shared_ptr<WallpaperTimelineSection> m_activeTimelineSection;
|
||||
bool m_useMockMonitors = false;
|
||||
QVector<QVector<Monitor>> m_mockMonitorList;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
namespace ScreenPlay {
|
||||
|
||||
|
||||
|
||||
class ScreenPlayManager : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
@ -36,13 +35,9 @@ public:
|
||||
const std::shared_ptr<MonitorListModel>& mlm,
|
||||
const std::shared_ptr<Settings>& settings);
|
||||
|
||||
std::shared_ptr<ScreenPlayWallpaper> startWallpaper(
|
||||
WallpaperData wallpaperData,
|
||||
const bool saveToProfilesConfigFile);
|
||||
|
||||
Q_INVOKABLE bool removeAllWallpapers(bool saveToProfile = false);
|
||||
Q_INVOKABLE QCoro::QmlTask removeAllWallpapers(bool saveToProfile = false);
|
||||
Q_INVOKABLE bool removeAllWidgets(bool saveToProfile = false);
|
||||
Q_INVOKABLE bool removeWallpaperAt(const int index);
|
||||
Q_INVOKABLE QCoro::QmlTask removeWallpaperAt(const int timelineIndex, const QString timelineIdentifier, const int monitorIndex);
|
||||
|
||||
Q_INVOKABLE ScreenPlayWallpaper* getWallpaperByAppID(const QString& appID);
|
||||
|
||||
@ -58,7 +53,7 @@ public:
|
||||
Q_INVOKABLE QCoro::QmlTask removeAllTimlineSections();
|
||||
Q_INVOKABLE bool removeTimelineAt(const int index);
|
||||
Q_INVOKABLE QJsonArray initialSectionsList();
|
||||
Q_INVOKABLE bool setWallpaperAtTimelineIndex(
|
||||
Q_INVOKABLE QCoro::QmlTask setWallpaperAtTimelineIndex(
|
||||
const ScreenPlay::ContentTypes::InstalledType type,
|
||||
const QString& absolutePath,
|
||||
const QString& previewImage,
|
||||
@ -77,12 +72,14 @@ public:
|
||||
const QJsonObject& properties,
|
||||
const bool saveToProfilesConfigFile);
|
||||
|
||||
Q_INVOKABLE void setSelectedTimelineIndex(const int selectedTimelineIndex);
|
||||
|
||||
Q_INVOKABLE bool requestProjectSettingsAtMonitorIndex(const int index);
|
||||
Q_INVOKABLE bool setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value);
|
||||
Q_INVOKABLE bool setWallpaperFillModeAtMonitorIndex(const int index, const int fillmode);
|
||||
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 int activeTimelineIndex();
|
||||
int activeWallpaperCounter() const { return m_activeWallpaperCounter; }
|
||||
int activeWidgetsCounter() const { return m_activeWidgetsCounter; }
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QTimer>
|
||||
#include <memory>
|
||||
|
||||
#include "ScreenPlay/monitorlistmodel.h"
|
||||
#include "ScreenPlay/wallpapertimelinesection.h"
|
||||
|
||||
namespace ScreenPlay {
|
||||
@ -19,6 +20,8 @@ public:
|
||||
std::optional<std::shared_ptr<WallpaperTimelineSection>> activeWallpaperSectionByAppID(const QString& appID);
|
||||
std::shared_ptr<WallpaperTimelineSection> findActiveWallpaperTimelineSection();
|
||||
std::shared_ptr<WallpaperTimelineSection> findTimelineForCurrentTime();
|
||||
|
||||
void startup();
|
||||
bool addTimelineFromSettings(const QJsonObject& timelineObj);
|
||||
bool deactivateCurrentTimeline();
|
||||
bool moveTimelineAt(const int index, const QString identifier, const float relativePosition, QString positionTimeString);
|
||||
@ -26,24 +29,38 @@ public:
|
||||
bool addTimelineAt(const int index, const float reltiaveLinePosition, QString identifier);
|
||||
bool removeTimelineAt(const int index);
|
||||
QCoro::Task<bool> removeAllTimlineSections();
|
||||
QCoro::Task<bool> removeAllWallpaperFromActiveTimlineSections();
|
||||
QCoro::Task<bool> removeWallpaperAt(
|
||||
const int timelineIndex,
|
||||
const QString timelineIdentifier,
|
||||
const int monitorIndex);
|
||||
void updateIndices();
|
||||
void printTimelines();
|
||||
bool setWallpaperAtTimelineIndex(WallpaperData wallpaperData,
|
||||
QCoro::Task<bool> setWallpaperAtTimelineIndex(
|
||||
WallpaperData wallpaperData,
|
||||
const int timelineIndex,
|
||||
const QString& identifier);
|
||||
QJsonArray initialSectionsList();
|
||||
QJsonArray timelineWallpaperList();
|
||||
void setGlobalVariables(const std::shared_ptr<GlobalVariables>& globalVariables);
|
||||
void setSettings(const std::shared_ptr<Settings>& settings);
|
||||
void startupFirstTimeline();
|
||||
void setMonitorListModel(const std::shared_ptr<MonitorListModel>& monitorListModel);
|
||||
void updateMonitorListModelData(const int selectedTimelineIndex);
|
||||
|
||||
private slots:
|
||||
void checkActiveWallpaperTimeline();
|
||||
|
||||
signals:
|
||||
void requestSaveProfiles();
|
||||
void activeWallpaperCountChanged(const int count);
|
||||
|
||||
private:
|
||||
std::optional<std::shared_ptr<WallpaperTimelineSection>> activeWallpaperSection(const int timelineIndex, const QString timelineIdentifier);
|
||||
|
||||
private:
|
||||
QVector<std::shared_ptr<WallpaperTimelineSection>> m_wallpaperTimelineSectionsList;
|
||||
std::shared_ptr<MonitorListModel> m_monitorListModel;
|
||||
|
||||
// We use a 24 hour system
|
||||
const QString m_timelineTimeFormat = "hh:mm:ss";
|
||||
QTimer m_contentTimer;
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ScreenPlayUtil/contenttypes.h"
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFileInfoList>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include "ScreenPlayUtil/contenttypes.h"
|
||||
#include <QUuid>
|
||||
|
||||
namespace ScreenPlay {
|
||||
|
||||
@ -30,6 +30,5 @@ struct WallpaperData {
|
||||
QJsonObject serialize() const;
|
||||
|
||||
static std::optional<WallpaperData> loadWallpaperConfig(const QJsonObject& wallpaperObj);
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -45,15 +45,22 @@ public:
|
||||
|
||||
std::shared_ptr<GlobalVariables> globalVariables;
|
||||
std::shared_ptr<Settings> settings;
|
||||
|
||||
public:
|
||||
// Check if currentTime falls within the timeline section
|
||||
bool containsTime(const QTime& time) const;
|
||||
|
||||
QJsonObject serialize() const;
|
||||
|
||||
bool activateTimeline();
|
||||
QCoro::Task<bool> deactivateTimeline();
|
||||
|
||||
QCoro::Task<bool> deactivateTimeline();
|
||||
QCoro::Task<bool> removeWallpaper(const int monitorIndex);
|
||||
private slots:
|
||||
void updateActiveWallpaperCounter();
|
||||
|
||||
private:
|
||||
std::optional<std::shared_ptr<ScreenPlayWallpaper>> wallpaperByMonitorIndex(const int index);
|
||||
signals:
|
||||
void requestSaveProfiles();
|
||||
void activeWallpaperCountChanged(const int count);
|
||||
};
|
||||
}
|
||||
|
@ -8,64 +8,57 @@ import QtCore as QCore
|
||||
|
||||
ApplicationWindow {
|
||||
id: root
|
||||
color: Material.theme === Material.Dark ? Qt.darker(
|
||||
Material.background) : Material.background
|
||||
color: Material.theme === Material.Dark ? Qt.darker(Material.background) : Material.background
|
||||
// Set visible if the -silent parameter was not set (see app.cpp end of constructor).
|
||||
visible: false
|
||||
width: 1400
|
||||
height: 810
|
||||
|
||||
|
||||
minimumHeight: 450
|
||||
minimumWidth: 1050
|
||||
Component.onCompleted: {
|
||||
// App is now a qml singleton to fix QtC autocompletion.
|
||||
// This also now means we have to make sure to init it here
|
||||
// and do _not_ access any other properties before we called init.
|
||||
App.init()
|
||||
|
||||
|
||||
setTheme(App.settings.theme)
|
||||
App.init();
|
||||
setTheme(App.settings.theme);
|
||||
if (!App.settings.silentStart) {
|
||||
App.showDockIcon(true)
|
||||
root.show()
|
||||
App.showDockIcon(true);
|
||||
root.show();
|
||||
}
|
||||
baseLoader.setSource("qrc:/qml/ScreenPlayApp/qml/MainApp.qml")
|
||||
|
||||
const isSteamVersion = App.globalVariables.isSteamVersion()
|
||||
let platform = ""
|
||||
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 = ""
|
||||
platform = qsTr("Steam");
|
||||
const isProVersion = App.globalVariables.isProVersion();
|
||||
let featureLevel = "";
|
||||
if (isProVersion)
|
||||
featureLevel = qsTr("Pro")
|
||||
const isUltraVersion = App.globalVariables.isUltraVersion()
|
||||
featureLevel = qsTr("Pro");
|
||||
const isUltraVersion = App.globalVariables.isUltraVersion();
|
||||
if (isUltraVersion)
|
||||
featureLevel = qsTr("Ultra")
|
||||
|
||||
root.title = "ScreenPlay - v" + App.version() + " " + featureLevel + " " + platform
|
||||
featureLevel = qsTr("Ultra");
|
||||
root.title = "ScreenPlay - v" + App.version() + " " + featureLevel + " " + platform;
|
||||
}
|
||||
|
||||
|
||||
Connections {
|
||||
target: App
|
||||
function onRequestExit(){
|
||||
Qt.exit(0)
|
||||
function onRequestExit() {
|
||||
Qt.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
function setTheme(theme) {
|
||||
switch (theme) {
|
||||
case Settings.Theme.System:
|
||||
root.Material.theme = Material.System
|
||||
break
|
||||
root.Material.theme = Material.System;
|
||||
break;
|
||||
case Settings.Theme.Dark:
|
||||
root.Material.theme = Material.Dark
|
||||
break
|
||||
root.Material.theme = Material.Dark;
|
||||
break;
|
||||
case Settings.Theme.Light:
|
||||
root.Material.theme = Material.Light
|
||||
break
|
||||
root.Material.theme = Material.Light;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +67,7 @@ ApplicationWindow {
|
||||
Material.accent: Material.color(Material.Orange)
|
||||
onVisibilityChanged: {
|
||||
if (root.visibility !== 2)
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
QCore.Settings {
|
||||
@ -82,23 +75,21 @@ ApplicationWindow {
|
||||
}
|
||||
|
||||
onClosing: close => {
|
||||
close.accepted = false
|
||||
if (App.screenPlayManager.activeWallpaperCounter === 0
|
||||
&& App.screenPlayManager.activeWidgetsCounter === 0) {
|
||||
App.exit()
|
||||
}
|
||||
const alwaysMinimize = settings.value("alwaysMinimize", null)
|
||||
if (alwaysMinimize === null) {
|
||||
console.error(
|
||||
"Unable to retreive alwaysMinimize setting")
|
||||
}
|
||||
if (alwaysMinimize === "true") {
|
||||
root.hide()
|
||||
App.showDockIcon(false)
|
||||
return
|
||||
}
|
||||
baseLoader.item.openExitDialog()
|
||||
}
|
||||
close.accepted = false;
|
||||
if (App.screenPlayManager.activeWallpaperCounter === 0 && App.screenPlayManager.activeWidgetsCounter === 0) {
|
||||
App.exit();
|
||||
}
|
||||
const alwaysMinimize = settings.value("alwaysMinimize", null);
|
||||
if (alwaysMinimize === null) {
|
||||
console.error("Unable to retreive alwaysMinimize setting");
|
||||
}
|
||||
if (alwaysMinimize === "true") {
|
||||
root.hide();
|
||||
App.showDockIcon(false);
|
||||
return;
|
||||
}
|
||||
baseLoader.item.openExitDialog();
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: baseLoader
|
||||
|
@ -6,10 +6,13 @@ Item {
|
||||
property real lineWidth: 1
|
||||
property real linePosition: (root.x / lineWidth).toFixed(4)
|
||||
property string timeString: {
|
||||
const normalized = root.x / root.lineWidth; // Your existing normalization
|
||||
const normalized = root.x / root.lineWidth;
|
||||
// Your existing normalization
|
||||
let totalHours = normalized * 24;
|
||||
let hours = Math.floor(totalHours); // Gets the whole hour part
|
||||
let minutes = Math.round((totalHours - hours) * 60); // Calculates the minutes
|
||||
let hours = Math.floor(totalHours);
|
||||
// Gets the whole hour part
|
||||
let minutes = Math.round((totalHours - hours) * 60);
|
||||
// Calculates the minutes
|
||||
// Check if minutes rolled over to 60, adjust hours and minutes accordingly
|
||||
if (minutes === 60) {
|
||||
hours += 1; // Increment hours by 1
|
||||
@ -35,15 +38,18 @@ Item {
|
||||
width: 20
|
||||
height: width
|
||||
Rectangle {
|
||||
id: handleCircle
|
||||
visible: !root.isLast
|
||||
radius: width
|
||||
color: dragHandler.active ? "orange" : "white"
|
||||
anchors.fill: parent
|
||||
width: 20
|
||||
height: width
|
||||
}
|
||||
|
||||
// To block ➕
|
||||
MouseArea {
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: false
|
||||
anchors.centerIn: parent
|
||||
width: 50
|
||||
height: 50
|
||||
}
|
||||
@ -54,7 +60,7 @@ Item {
|
||||
color: "white"
|
||||
visible: !root.isLast
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
horizontalCenter: handleCircle.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: -20
|
||||
}
|
||||
|
@ -6,7 +6,8 @@ Rectangle {
|
||||
z: selected ? 99 : 0
|
||||
property int index: 0
|
||||
property string identifier
|
||||
property bool selected: false
|
||||
property bool selected: false // User selected
|
||||
property bool isActive: false // Active based on time
|
||||
property bool isLast: false
|
||||
property alias text: text.text
|
||||
|
||||
@ -24,6 +25,22 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
opacity: root.isActive ? 1 : 0
|
||||
color: "gold"
|
||||
height: root.height
|
||||
anchors {
|
||||
right: parent.right
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
visible: root.selected
|
||||
color: "gold"
|
||||
@ -45,10 +62,17 @@ Rectangle {
|
||||
top: parent.bottom
|
||||
topMargin: 0
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
id: monitorBackground
|
||||
width: 70
|
||||
height: 48
|
||||
radius: 5
|
||||
@ -60,6 +84,13 @@ Rectangle {
|
||||
top: indicatorLineVertical.bottom
|
||||
topMargin: -1
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
@ -80,8 +111,8 @@ Rectangle {
|
||||
font.pointSize: 10
|
||||
|
||||
anchors {
|
||||
left: background.right
|
||||
bottom: background.top
|
||||
left: monitorBackground.right
|
||||
bottom: monitorBackground.top
|
||||
margins: -20
|
||||
}
|
||||
}
|
||||
|
@ -14,23 +14,31 @@ Control {
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
|
||||
property int activeTimelineIndex: -1
|
||||
property int length: timeLine.sectionsList.length
|
||||
|
||||
function getActiveTimeline() {
|
||||
return timeLine.sectionsList[root.activeTimelineIndex]
|
||||
}
|
||||
// User selected
|
||||
property int selectedTimelineIndex: -1
|
||||
property var selectedTimeline: timeline.sectionsList[root.selectedTimelineIndex]
|
||||
property int length: timeline.sectionsList.length
|
||||
|
||||
function removeAll() {
|
||||
timeLine.removeAll()
|
||||
timeline.removeAll();
|
||||
}
|
||||
|
||||
function printTimelines() {
|
||||
print("################# qml:")
|
||||
for (var i = 0; i < timeLine.sectionsList.length; i++) {
|
||||
print(timeLine.sectionsList[i].index,
|
||||
timeLine.sectionsList[i].identifier,
|
||||
timeLine.sectionsList[i].relativeLinePosition)
|
||||
function reset() {
|
||||
timeline.reset();
|
||||
}
|
||||
LoggingCategory {
|
||||
id: timelineLogging
|
||||
name: "timeline"
|
||||
defaultLogLevel: LoggingCategory.Debug
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: App.screenPlayManager
|
||||
function onPrintQmlTimeline() {
|
||||
console.debug(timelineLogging, "################# qml:");
|
||||
for (var i = 0; i < timeline.sectionsList.length; i++) {
|
||||
console.debug(timelineLogging, timeline.sectionsList[i].index, timeline.sectionsList[i].identifier, timeline.sectionsList[i].relativeLinePosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,60 +48,71 @@ Control {
|
||||
property string identifier
|
||||
property int index: 0
|
||||
property real relativeLinePosition: lineHandle.linePosition
|
||||
onRelativeLinePositionChanged: print("relativelinepos: ",
|
||||
relativeLinePosition)
|
||||
onRelativeLinePositionChanged: console.debug("relativelinepos: ", relativeLinePosition)
|
||||
property LineHandle lineHandle
|
||||
property LineIndicator lineIndicator
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
id: timeLine
|
||||
id: timeline
|
||||
height: 160
|
||||
implicitWidth: 600
|
||||
|
||||
property var sectionsList: []
|
||||
property var lineColors: ["#1E88E5", "#00897B", "#43A047", "#C0CA33", "#FFB300", "#FB8C00", "#F4511E", "#E53935", "#D81B60", "#8E24AA", "#5E35B1", "#3949AB"]
|
||||
onWidthChanged: timeLine.updatePositions()
|
||||
property var initialSectionsList: []
|
||||
Component.onCompleted: {
|
||||
let sectionObects = App.screenPlayManager.initialSectionsList()
|
||||
for (let sectionObject in sectionObects) {
|
||||
initialSectionsList.push(sectionObects[sectionObject])
|
||||
|
||||
onWidthChanged: timeline.updatePositions()
|
||||
Component.onCompleted: reset()
|
||||
|
||||
Timer {
|
||||
running: true
|
||||
repeat: true
|
||||
interval: 500
|
||||
onTriggered: {
|
||||
const activeTimelineIndex = App.screenPlayManager.activeTimelineIndex();
|
||||
if (activeTimelineIndex === -1) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < timeline.sectionsList.length; i++) {
|
||||
let section = timeline.sectionsList[i];
|
||||
section.lineIndicator.isActive = (activeTimelineIndex === i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
removeAll();
|
||||
let initialSectionsList = App.screenPlayManager.initialSectionsList();
|
||||
if (App.globalVariables.isBasicVersion()) {
|
||||
if (initialSectionsList.length > 1) {
|
||||
console.error(timelineLogging, "Invalid section list count for basic version");
|
||||
// Create dummy
|
||||
addSection("INVALID", 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
initialSectionsList.sort(function (a, b) {
|
||||
return b.index - a.index
|
||||
})
|
||||
return b.index - a.index;
|
||||
});
|
||||
for (let index in initialSectionsList) {
|
||||
let section = initialSectionsList[index]
|
||||
addSection(section.identifier, section.relativePosition)
|
||||
let section = initialSectionsList[index];
|
||||
addSection(section.identifier, section.relativePosition);
|
||||
}
|
||||
}
|
||||
|
||||
function removeAll() {
|
||||
print("removeAll", timeLine.sectionsList.length)
|
||||
for (var i = 0; i < timeLine.sectionsList.length; i++) {
|
||||
console.debug(timelineLogging, "removeAll", timeline.sectionsList.length);
|
||||
for (var i = 0; i < timeline.sectionsList.length; i++) {
|
||||
// ORDER is important here! Destory the children first
|
||||
print("remove index ", i)
|
||||
let section = timeLine.sectionsList[i]
|
||||
section.lineHandle.destroy()
|
||||
section.lineIndicator.destroy()
|
||||
section.destroy()
|
||||
console.debug(timelineLogging, "remove index ", i);
|
||||
let section = timeline.sectionsList[i];
|
||||
section.lineHandle.destroy();
|
||||
section.lineIndicator.destroy();
|
||||
section.destroy();
|
||||
}
|
||||
timeLine.sectionsList = []
|
||||
App.screenPlayManager.removeAllTimlineSections().then(result => {
|
||||
|
||||
if (!result.success) {
|
||||
console.error("removeAllTimlineSections failed")
|
||||
return
|
||||
}
|
||||
|
||||
const position = 1.0
|
||||
const identifier = App.util.generateRandomString(
|
||||
4)
|
||||
const sectionObject = timeLine.addSection(
|
||||
identifier,
|
||||
position)
|
||||
App.screenPlayManager.addTimelineAt(sectionObject.index, sectionObject.relativeLinePosition, sectionObject.identifier)
|
||||
})
|
||||
timeline.sectionsList = [];
|
||||
root.selectedTimelineIndex = -1;
|
||||
}
|
||||
|
||||
// IMPORTANT: The new element is always on the left. The first
|
||||
@ -101,215 +120,208 @@ Control {
|
||||
// user can never delete it. It only gets "pushed" further
|
||||
// to the right, by decreasing its size.
|
||||
function addSection(identifier, stopPosition) {
|
||||
print("stopPosition", stopPosition)
|
||||
console.debug(timelineLogging, "stopPosition", stopPosition);
|
||||
|
||||
// Make sure to limit float precision
|
||||
const fixedStopPosition = stopPosition
|
||||
print("addSection at: ", fixedStopPosition)
|
||||
const fixedStopPosition = stopPosition;
|
||||
console.debug(timelineLogging, "addSection at: ", fixedStopPosition);
|
||||
if (stopPosition < 0 || fixedStopPosition > 1) {
|
||||
console.error("Invalid position:", fixedStopPosition)
|
||||
return
|
||||
console.error(timelineLogging, "Invalid position:", fixedStopPosition);
|
||||
return;
|
||||
}
|
||||
let sectionObject = sectionComp.createObject(timeLine, {
|
||||
"identifier": identifier,
|
||||
"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, identifier)
|
||||
updatePositions()
|
||||
return sectionObject
|
||||
let sectionObject = sectionComp.createObject(timeline, {
|
||||
"identifier": identifier,
|
||||
"relativeLinePosition": fixedStopPosition
|
||||
});
|
||||
timeline.sectionsList.push(sectionObject);
|
||||
timeline.sectionsList.sort(function (a, b) {
|
||||
return a.relativeLinePosition - b.relativeLinePosition;
|
||||
});
|
||||
const index = timeline.sectionsList.indexOf(sectionObject);
|
||||
console.debug(timelineLogging, "Addsection:", index);
|
||||
createSection(index, fixedStopPosition, sectionObject, identifier);
|
||||
updatePositions();
|
||||
return sectionObject;
|
||||
}
|
||||
|
||||
function createSection(index, stopPosition, section, identifier) {
|
||||
console.log("Adding at:", index, stopPosition, identifier)
|
||||
console.debug(timelineLogging, "Adding at:", index, stopPosition, identifier);
|
||||
|
||||
//console.assert(isFloat(stopPosition))
|
||||
let haComponent = Qt.createComponent("LineHandle.qml")
|
||||
let haComponent = Qt.createComponent("LineHandle.qml");
|
||||
if (haComponent.status === Component.Error) {
|
||||
console.assert(haComponent.errorString())
|
||||
return
|
||||
console.assert(timelineLogging, 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
|
||||
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.onHandleMoved)
|
||||
let liComponent = Qt.createComponent("LineIndicator.qml")
|
||||
section.lineHandle.lineMinimum = timeline.x;
|
||||
section.lineHandle.lineMaximum = timeline.x;
|
||||
section.lineHandle.handleMoved.connect(timeline.onHandleMoved);
|
||||
let liComponent = Qt.createComponent("LineIndicator.qml");
|
||||
if (liComponent.status === Component.Error) {
|
||||
console.assert(liComponent.errorString())
|
||||
return
|
||||
console.assert(timelineLogging, 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.identifier = identifier
|
||||
section.lineIndicator.color = getColorAtIndex(index)
|
||||
section.lineIndicator.remove.connect(timeLine.removeSection)
|
||||
section.lineIndicator.lineSelected.connect(
|
||||
timeLine.lineIndicatorSelected)
|
||||
};
|
||||
section.lineIndicator = liComponent.createObject(lineIndicatorWrapper, lineIndicatorProperties);
|
||||
section.lineIndicator.height = lineIndicatorWrapper.height;
|
||||
section.lineIndicator.index = index;
|
||||
section.lineIndicator.identifier = identifier;
|
||||
section.lineIndicator.color = getColorAtIndex(index);
|
||||
section.lineIndicator.remove.connect(timeline.removeSection);
|
||||
section.lineIndicator.lineSelected.connect(timeline.lineIndicatorSelected);
|
||||
}
|
||||
|
||||
function sectionFromHandle(lineHandle) {
|
||||
for (var i = 0; i < timeLine.sectionsList.length; i++) {
|
||||
if (timeLine.sectionsList[i].lineHandle === lineHandle)
|
||||
return timeLine.sectionsList[i]
|
||||
for (var i = 0; i < timeline.sectionsList.length; i++) {
|
||||
if (timeline.sectionsList[i].lineHandle === lineHandle)
|
||||
return timeline.sectionsList[i];
|
||||
}
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
function onHandleMoved(lineHandle) {
|
||||
updatePositions()
|
||||
const section = sectionFromHandle(lineHandle)
|
||||
updatePositions();
|
||||
const section = sectionFromHandle(lineHandle);
|
||||
if (section === null) {
|
||||
print(lineHandle.linePosition)
|
||||
console.error("Unable to match handle to section list")
|
||||
return
|
||||
console.debug(timelineLogging, lineHandle.linePosition);
|
||||
console.error(timelineLogging, "Unable to match handle to section list");
|
||||
return;
|
||||
}
|
||||
App.screenPlayManager.moveTimelineAt(section.index,
|
||||
section.identifier,
|
||||
lineHandle.linePosition,
|
||||
lineHandle.timeString)
|
||||
App.screenPlayManager.moveTimelineAt(section.index, section.identifier, lineHandle.linePosition, lineHandle.timeString);
|
||||
}
|
||||
|
||||
function lineIndicatorSelected(activeTimelineIndex) {
|
||||
for (var i = 0; i < timeLine.sectionsList.length; i++) {
|
||||
if (i === activeTimelineIndex) {
|
||||
timeLine.sectionsList[i].lineIndicator.selected = true
|
||||
continue
|
||||
function lineIndicatorSelected(selectedTimelineIndex) {
|
||||
console.debug(timelineLogging, "selectedTimelineIndex:", selectedTimelineIndex, "section cout: ", timeline.sectionsList.length);
|
||||
for (var i = 0; i < timeline.sectionsList.length; i++) {
|
||||
if (i === selectedTimelineIndex) {
|
||||
timeline.sectionsList[i].lineIndicator.selected = true;
|
||||
continue;
|
||||
}
|
||||
timeLine.sectionsList[i].lineIndicator.selected = false
|
||||
timeline.sectionsList[i].lineIndicator.selected = false;
|
||||
}
|
||||
root.activeTimelineIndex = activeTimelineIndex
|
||||
root.selectedTimelineIndex = selectedTimelineIndex;
|
||||
App.screenPlayManager.setSelectedTimelineIndex(selectedTimelineIndex);
|
||||
}
|
||||
|
||||
// We must update all indexes when removing/adding an element
|
||||
function updateIndicatorIndexes() {
|
||||
if (timeLine.sectionsList === null
|
||||
|| timeLine.sectionsList === undefined)
|
||||
return
|
||||
timeLine.sectionsList.sort(function (a, b) {
|
||||
return a.relativeLinePosition - b.relativeLinePosition
|
||||
})
|
||||
for (var i = 0; i < timeLine.sectionsList.length; i++) {
|
||||
timeLine.sectionsList[i].index = i
|
||||
timeLine.sectionsList[i].lineIndicator.index = i
|
||||
//print("updateIndicatorIndexes:", timeLine.sectionsList[i].index, timeLine.sectionsList[i].relativeLinePosition)
|
||||
if (timeline.sectionsList === null || timeline.sectionsList === undefined)
|
||||
return;
|
||||
timeline.sectionsList.sort(function (a, b) {
|
||||
return a.relativeLinePosition - b.relativeLinePosition;
|
||||
});
|
||||
for (var i = 0; i < timeline.sectionsList.length; i++) {
|
||||
timeline.sectionsList[i].index = i;
|
||||
timeline.sectionsList[i].lineIndicator.index = i;
|
||||
//console.debug("updateIndicatorIndexes:", timeline.sectionsList[i].index, timeline.sectionsList[i].relativeLinePosition)
|
||||
}
|
||||
}
|
||||
|
||||
function removeSection(index) {
|
||||
print(timeLine.stopPositionList)
|
||||
print(timeLine.sectionList)
|
||||
const isLast = index === timeLine.sectionsList.length - 1
|
||||
console.debug(timelineLogging, timeline.stopPositionList);
|
||||
console.debug(timelineLogging, timeline.sectionList);
|
||||
const isLast = index === timeline.sectionsList.length - 1;
|
||||
if (isLast)
|
||||
return
|
||||
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()
|
||||
App.screenPlayManager.removeTimelineAt(index)
|
||||
let section = timeline.sectionsList[index];
|
||||
section.lineHandle.destroy();
|
||||
section.lineIndicator.destroy();
|
||||
section.destroy();
|
||||
timeline.sectionsList.splice(index, 1);
|
||||
updatePositions();
|
||||
App.screenPlayManager.removeTimelineAt(index);
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
let prevPos;
|
||||
if (i === 0) {
|
||||
// If it's the first handle, its minimum is 0
|
||||
prevPos = 0
|
||||
prevPos = 0;
|
||||
} else {
|
||||
// Otherwise, it's directly the position of the previous handle
|
||||
prevPos = timeLine.sectionsList[i - 1].lineHandle.x
|
||||
prevPos = timeline.sectionsList[i - 1].lineHandle.x;
|
||||
}
|
||||
|
||||
// Determine the maximum position for the current handle
|
||||
let nextPos
|
||||
if (i === timeLine.sectionsList.length - 1) {
|
||||
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
|
||||
nextPos = timeline.width;
|
||||
} else {
|
||||
// Otherwise, it's directly the position of the next handle
|
||||
nextPos = timeLine.sectionsList[i + 1].lineHandle.x
|
||||
nextPos = timeline.sectionsList[i + 1].lineHandle.x;
|
||||
}
|
||||
|
||||
// Set the determined minimum and maximum positions for the current handle
|
||||
handle.lineMinimum = prevPos
|
||||
handle.lineMaximum = nextPos
|
||||
handle.lineMinimum = prevPos;
|
||||
handle.lineMaximum = nextPos;
|
||||
|
||||
//timeLine.sectionsList[i].relativeLinePosition =prevPos / timeLine.width
|
||||
// print("sections: ", i, "prev minimum ",prevPos,"next maximum", nextPos, timeLine.sectionsList[i].relativeLinePosition)
|
||||
//timeline.sectionsList[i].relativeLinePosition =prevPos / timeline.width
|
||||
// console.debug("sections: ", i, "prev minimum ",prevPos,"next maximum", nextPos, timeline.sectionsList[i].relativeLinePosition)
|
||||
}
|
||||
for (var i = 0; i < timeLine.sectionsList.length; i++) {
|
||||
let section = timeLine.sectionsList[i]
|
||||
section.relativeLinePosition = section.lineHandle.linePosition
|
||||
// print(section.relativeLinePosition, section.lineHandle.lineMinimum, section.lineHandle.lineMaximum)
|
||||
for (var j = 0; j < timeline.sectionsList.length; j++) {
|
||||
let section = timeline.sectionsList[j];
|
||||
section.relativeLinePosition = section.lineHandle.linePosition;
|
||||
// console.debug(section.relativeLinePosition, section.lineHandle.lineMinimum, section.lineHandle.lineMaximum)
|
||||
}
|
||||
updateIndicatorPositions()
|
||||
updateLastHandle()
|
||||
updateIndicatorColor()
|
||||
updateIndicatorIndexes()
|
||||
updateIndicatorPositions();
|
||||
updateLastHandle();
|
||||
updateIndicatorColor();
|
||||
updateIndicatorIndexes();
|
||||
}
|
||||
|
||||
function getColorAtIndex(index) {
|
||||
let i = index
|
||||
let i = index;
|
||||
// Start from the beginnging again
|
||||
if (index >= timeLine.lineColors.length) {
|
||||
i = index % timeLine.lineColors.length
|
||||
if (index >= timeline.lineColors.length) {
|
||||
i = index % timeline.lineColors.length;
|
||||
}
|
||||
return timeLine.lineColors[i]
|
||||
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)
|
||||
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
|
||||
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, timeLine.sectionsList[i].relativeLinePosition)
|
||||
const handle = timeLine.sectionsList[i].lineHandle
|
||||
lineIndicator.x = handle.dragHandler.xAxis.minimum
|
||||
lineIndicator.width = (handle.linePosition * handle.lineWidth).toFixed(
|
||||
2) - lineIndicator.x
|
||||
for (var i = 0; i < timeline.sectionsList.length; i++) {
|
||||
const lineIndicator = timeline.sectionsList[i].lineIndicator;
|
||||
//console.debug(i, lineIndicator.x, lineIndicator.width, timeline.sectionsList[i].relativeLinePosition)
|
||||
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)
|
||||
return n === +n && n !== (n | 0);
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@ -332,13 +344,10 @@ Control {
|
||||
color: Material.color(Material.BlueGrey)
|
||||
width: 2
|
||||
height: 30
|
||||
y: (addHandleWrapper.height - height)
|
||||
/ 2 // Vertically center within addHandleWrapper
|
||||
y: (addHandleWrapper.height - height) / 2 // Vertically center within addHandleWrapper
|
||||
|
||||
property int totalSeconds: 86400 // Total seconds in a day
|
||||
property int currentSeconds: (new Date().getHours(
|
||||
) * 3600) + (new Date().getMinutes(
|
||||
) * 60) + new Date().getSeconds()
|
||||
property int currentSeconds: 0
|
||||
|
||||
x: addHandleWrapper.width * (currentSeconds / totalSeconds)
|
||||
|
||||
@ -347,15 +356,9 @@ Control {
|
||||
repeat: true
|
||||
running: true
|
||||
onTriggered: {
|
||||
currentTimeIndicator.currentSeconds
|
||||
= (new Date().getHours(
|
||||
) * 3600) + (new Date().getMinutes(
|
||||
) * 60) + new Date().getSeconds(
|
||||
)
|
||||
currentTimeIndicator.x = addHandleWrapper.width
|
||||
* (currentTimeIndicator.currentSeconds / currentTimeIndicator.totalSeconds)
|
||||
currentTimeText.text = Qt.formatTime(new Date(),
|
||||
"hh:mm:ss")
|
||||
currentTimeIndicator.currentSeconds = (new Date().getHours() * 3600) + (new Date().getMinutes() * 60) + new Date().getSeconds();
|
||||
currentTimeIndicator.x = addHandleWrapper.width * (currentTimeIndicator.currentSeconds / currentTimeIndicator.totalSeconds);
|
||||
currentTimeText.text = Qt.formatTime(new Date(), "hh:mm:ss");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,14 +375,22 @@ Control {
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
height: 30
|
||||
uniformCellSizes: true
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
left: parent.left
|
||||
leftMargin: -5
|
||||
}
|
||||
Repeater {
|
||||
model: 24
|
||||
model: 25
|
||||
Item {
|
||||
width: 20
|
||||
height: 60
|
||||
height: 30
|
||||
required property int index
|
||||
Text {
|
||||
id: txtHours
|
||||
color: "gray"
|
||||
text: index
|
||||
anchors {
|
||||
@ -390,9 +401,9 @@ Control {
|
||||
Rectangle {
|
||||
color: "gray"
|
||||
width: 1
|
||||
height: 5
|
||||
height: 10
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
horizontalCenter: txtHours.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
@ -403,15 +414,18 @@ Control {
|
||||
ToolButton {
|
||||
text: "➕"
|
||||
onClicked: {
|
||||
const p = this.x / timeLine.width
|
||||
const position = p.toFixed(4)
|
||||
const identifier = App.util.generateRandomString(4)
|
||||
const sectionObject = timeLine.addSection(identifier,
|
||||
position)
|
||||
App.screenPlayManager.addTimelineAt(
|
||||
sectionObject.index,
|
||||
sectionObject.relativeLinePosition,
|
||||
sectionObject.identifier)
|
||||
if (App.globalVariables.isBasicVersion()) {
|
||||
screenPlayProView.open();
|
||||
return;
|
||||
}
|
||||
const p = this.x / timeline.width;
|
||||
const position = p.toFixed(4);
|
||||
const identifier = App.util.generateRandomString(4);
|
||||
const sectionObject = timeline.addSection(identifier, position);
|
||||
App.screenPlayManager.addTimelineAt(sectionObject.index, sectionObject.relativeLinePosition, sectionObject.identifier);
|
||||
}
|
||||
ScreenPlayProPopup {
|
||||
id: screenPlayProView
|
||||
}
|
||||
|
||||
x: hoverHandler.point.position.x - width * .5
|
||||
@ -436,23 +450,49 @@ Control {
|
||||
top: addHandleWrapper.bottom
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Rectangle {
|
||||
height: 18
|
||||
width: 5
|
||||
color: "#757575"
|
||||
width: 2
|
||||
anchors {
|
||||
right: parent.left
|
||||
top: addHandleWrapper.bottom
|
||||
topMargin: -9
|
||||
verticalCenter: lineIndicatorWrapper.verticalCenter
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
height: 18
|
||||
width: 5
|
||||
width: 2
|
||||
color: "#757575"
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: addHandleWrapper.bottom
|
||||
topMargin: -9
|
||||
verticalCenter: lineIndicatorWrapper.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
text: "❌ Reset" //qsTr("Remove all timeline ranges")
|
||||
z: 99
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
onClicked: {
|
||||
timeline.removeAll();
|
||||
App.screenPlayManager.removeAllTimlineSections().then(result => {
|
||||
if (!result.success) {
|
||||
console.error("removeAllTimlineSections failed");
|
||||
return;
|
||||
}
|
||||
const position = 1.0;
|
||||
const identifier = App.util.generateRandomString(4);
|
||||
const sectionObject = timeline.addSection(identifier, position);
|
||||
App.screenPlayManager.addTimelineAt(sectionObject.index, sectionObject.relativeLinePosition, sectionObject.identifier);
|
||||
});
|
||||
}
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
topMargin: -height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ Util.Popup {
|
||||
height: 768
|
||||
onOpened: {
|
||||
monitorSelection.selectMonitorAt(0);
|
||||
timeline.reset();
|
||||
}
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
@ -72,6 +73,7 @@ Util.Popup {
|
||||
}
|
||||
|
||||
Timeline {
|
||||
id: timeline
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
@ -123,8 +125,6 @@ Util.Popup {
|
||||
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";
|
||||
|
@ -13,7 +13,6 @@ Rectangle {
|
||||
property bool monitorWithoutContentSelectable: true
|
||||
property bool multipleMonitorsSelectable: false
|
||||
property bool isSelected: false
|
||||
// We preselect the main monitor
|
||||
property var activeMonitors: []
|
||||
property alias background: root.color
|
||||
property alias bgRadius: root.radius
|
||||
@ -22,6 +21,11 @@ Rectangle {
|
||||
resize();
|
||||
selectOnly(0);
|
||||
}
|
||||
LoggingCategory {
|
||||
id: logger
|
||||
name: "MonitorSelection"
|
||||
defaultLogLevel: LoggingCategory.Debug
|
||||
}
|
||||
|
||||
signal requestProjectSettings(var index, var installedType, var appID)
|
||||
|
||||
@ -50,8 +54,6 @@ Rectangle {
|
||||
if (rp.itemAt(i).isSelected)
|
||||
root.activeMonitors.push(rp.itemAt(i).index);
|
||||
}
|
||||
// Must be called manually. When QML properties are getting altered in js the
|
||||
// property binding breaks
|
||||
root.activeMonitorsChanged();
|
||||
root.isSelected = root.activeMonitors.length > 0;
|
||||
return root.activeMonitors;
|
||||
@ -68,42 +70,45 @@ Rectangle {
|
||||
}
|
||||
|
||||
function resize() {
|
||||
print("resize");
|
||||
var absoluteDesktopSize = App.monitorListModel.absoluteDesktopSize();
|
||||
var isWidthGreaterThanHeight = false;
|
||||
var windowsDelta = 0;
|
||||
if (absoluteDesktopSize.width < absoluteDesktopSize.height) {
|
||||
windowsDelta = absoluteDesktopSize.width / absoluteDesktopSize.height;
|
||||
isWidthGreaterThanHeight = false;
|
||||
} else {
|
||||
windowsDelta = absoluteDesktopSize.height / absoluteDesktopSize.width;
|
||||
isWidthGreaterThanHeight = true;
|
||||
}
|
||||
if (rp.count === 1)
|
||||
availableWidth = availableWidth * 0.66;
|
||||
var dynamicHeight = availableWidth * windowsDelta;
|
||||
var dynamicWidth = availableHeight * windowsDelta;
|
||||
// Delta (height/width)
|
||||
var monitorHeightRationDelta = 0;
|
||||
var monitorWidthRationDelta = 0;
|
||||
if (isWidthGreaterThanHeight) {
|
||||
monitorHeightRationDelta = dynamicHeight / absoluteDesktopSize.height;
|
||||
monitorWidthRationDelta = availableWidth / absoluteDesktopSize.width;
|
||||
} else {
|
||||
monitorHeightRationDelta = availableHeight / absoluteDesktopSize.height;
|
||||
monitorWidthRationDelta = dynamicWidth / absoluteDesktopSize.width;
|
||||
}
|
||||
console.debug(logger, "MonitorSelection resize started");
|
||||
|
||||
// 1. Get the total desktop size
|
||||
let totalDesktopSize = App.monitorListModel.totalDesktopSize();
|
||||
console.debug(logger, "Total desktop size:", totalDesktopSize.width, "x", totalDesktopSize.height);
|
||||
|
||||
// 2. Get root item dimensions
|
||||
let rootWidth = root.width;
|
||||
let rootHeight = root.height;
|
||||
console.debug(logger, "Root dimensions:", rootWidth, "x", rootHeight);
|
||||
|
||||
// 3. Calculate scaling factor
|
||||
let margin = 10;
|
||||
let availableWidth = rootWidth - 2 * margin;
|
||||
let availableHeight = rootHeight - 2 * margin;
|
||||
let scaleX = availableWidth / totalDesktopSize.width;
|
||||
let scaleY = availableHeight / totalDesktopSize.height;
|
||||
let scaleFactor = Math.min(scaleX, scaleY, 1);
|
||||
|
||||
// Ensure we don't scale up
|
||||
console.debug(logger, "Scale factor:", scaleFactor);
|
||||
|
||||
// 4. Resize and position repeater items
|
||||
let scaledWidth = totalDesktopSize.width * scaleFactor;
|
||||
let scaledHeight = totalDesktopSize.height * scaleFactor;
|
||||
for (var i = 0; i < rp.count; i++) {
|
||||
rp.itemAt(i).index = i;
|
||||
rp.itemAt(i).height = rp.itemAt(i).height * monitorHeightRationDelta;
|
||||
rp.itemAt(i).width = rp.itemAt(i).width * monitorWidthRationDelta;
|
||||
rp.itemAt(i).x = rp.itemAt(i).x * monitorWidthRationDelta;
|
||||
rp.itemAt(i).y = rp.itemAt(i).y * monitorHeightRationDelta;
|
||||
rp.contentWidth += rp.itemAt(i).width;
|
||||
rp.contentHeight += rp.itemAt(i).height;
|
||||
let item = rp.itemAt(i);
|
||||
if (item) {
|
||||
item.width = item.geometry.width * scaleFactor;
|
||||
item.height = item.geometry.height * scaleFactor;
|
||||
item.x = item.geometry.x * scaleFactor;
|
||||
item.y = item.geometry.y * scaleFactor;
|
||||
}
|
||||
}
|
||||
rp.contentWidth += 200;
|
||||
rp.contentHeight += 200;
|
||||
|
||||
// 6. Center content within Flickable
|
||||
flickable.contentWidth = scaledWidth;
|
||||
flickable.contentHeight = scaledHeight;
|
||||
console.debug(logger, "MonitorSelection resize completed", flickable.contentWidth, flickable.contentHeight);
|
||||
}
|
||||
|
||||
color: Material.theme === Material.Light ? Material.background : Qt.darker(Material.background)
|
||||
@ -148,18 +153,11 @@ Rectangle {
|
||||
onMonitorSelected: function (index) {
|
||||
root.selectMonitorAt(index);
|
||||
}
|
||||
// onRemoveWallpaper: function(index) {
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
policy: ScrollBar.AlwaysOff
|
||||
snapMode: ScrollBar.SnapOnRelease
|
||||
}
|
||||
|
||||
ScrollBar.horizontal: ScrollBar {
|
||||
policy: ScrollBar.AlwaysOff
|
||||
snapMode: ScrollBar.SnapOnRelease
|
||||
}
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
|
@ -26,6 +26,7 @@ Item {
|
||||
property bool isSelected: false
|
||||
|
||||
signal monitorSelected(var index)
|
||||
signal remoteWallpaper(var index)
|
||||
|
||||
onIsSelectedChanged: root.state = isSelected ? "selected" : "default"
|
||||
onPreviewImageChanged: {
|
||||
@ -81,11 +82,23 @@ Item {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (monitorWithoutContentSelectable) {
|
||||
monitorSelected(index);
|
||||
root.monitorSelected(index);
|
||||
return;
|
||||
}
|
||||
if (root.hasContent && !root.monitorWithoutContentSelectable)
|
||||
monitorSelected(index);
|
||||
root.monitorSelected(index);
|
||||
}
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
text: "❌"
|
||||
enabled: root.hasContent && !root.monitorWithoutContentSelectable
|
||||
visible: enabled
|
||||
onClicked: root.remoteWallpaper(index)
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ Drawer {
|
||||
background: Rectangle {
|
||||
color: Material.color(Material.Grey, Material.Shade900)
|
||||
}
|
||||
onOpened: {
|
||||
timeline.reset();
|
||||
}
|
||||
|
||||
property bool hasPreviewGif: false
|
||||
property var type: ContentTypes.InstalledType.QMLWallpaper
|
||||
@ -25,27 +28,29 @@ Drawer {
|
||||
|
||||
function setInstalledDrawerItem(folderName, type) {
|
||||
|
||||
// Toggle sidebar if clicked on the same content twice
|
||||
if (root.contentFolderName === folderName)
|
||||
return;
|
||||
// Toggle drawer if clicked on the same content twice
|
||||
if (root.contentFolderName === folderName) {
|
||||
if (root.visible) {
|
||||
root.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!App.util.isWallpaper(type)) {
|
||||
return;
|
||||
}
|
||||
print("setInstalledDrawerItem", root.contentFolderName, folderName, typeof (folderName), type);
|
||||
root.contentFolderName = folderName;
|
||||
root.type = type;
|
||||
print("setInstalledDrawerItem", folderName,typeof(folderName), type);
|
||||
if (type === ContentTypes.InstalledType.VideoWallpaper)
|
||||
installedDrawerWrapper.state = "wallpaper";
|
||||
else
|
||||
installedDrawerWrapper.state = "scene";
|
||||
|
||||
root.open();
|
||||
}
|
||||
|
||||
// This is used for removing wallpaper. We need to clear
|
||||
// the preview image/gif so we can release the file for deletion.
|
||||
function clear() {
|
||||
|
||||
root.close();
|
||||
root.contentFolderName = "";
|
||||
root.type = ContentTypes.InstalledType.Unknown;
|
||||
@ -56,11 +61,10 @@ Drawer {
|
||||
}
|
||||
|
||||
onContentFolderNameChanged: {
|
||||
if (root.contentFolderName === ""){
|
||||
console.error("empty folder name")
|
||||
return
|
||||
if (root.contentFolderName === "") {
|
||||
console.error("empty folder name");
|
||||
return;
|
||||
}
|
||||
|
||||
const item = App.installedListModel.get(root.contentFolderName);
|
||||
print(root.contentFolderName);
|
||||
txtHeadline.text = item.m_title;
|
||||
@ -108,22 +112,6 @@ Drawer {
|
||||
Layout.topMargin: 50
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Connections {
|
||||
target: App.screenPlayManager
|
||||
function onPrintQmlTimeline() {
|
||||
timeline.printTimelines();
|
||||
}
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
text: "❌" //qsTr("Remove all timeline ranges")
|
||||
// enabled: timeline.length > 1
|
||||
onClicked: timeline.removeAll()
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,11 +132,8 @@ Drawer {
|
||||
MonitorSelection {
|
||||
id: monitorSelection
|
||||
objectName: "monitorSelection"
|
||||
height: 180
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
availableWidth: width
|
||||
availableHeight: height - 20
|
||||
fontSize: 11
|
||||
}
|
||||
}
|
||||
@ -249,8 +234,8 @@ Drawer {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
objectName: "btnLaunchContent"
|
||||
text: qsTr("Set Wallpaper");
|
||||
// enabled: App.util.isWidget(root.type) && activeMonitors.length > 0 ? true : monitorSelection.isSelected
|
||||
text: qsTr("Set Wallpaper")
|
||||
enabled: monitorSelection.isSelected && timeline.selectedTimelineIndex > -1
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_plus.svg"
|
||||
icon.color: "white"
|
||||
font.pointSize: 12
|
||||
@ -281,9 +266,18 @@ Drawer {
|
||||
root.close();
|
||||
return;
|
||||
}
|
||||
const activeTimeline = timeline.getActiveTimeline();
|
||||
const selectedTimeline = timeline.selectedTimeline;
|
||||
if (selectedTimeline === undefined) {
|
||||
console.error("No active timeline");
|
||||
return;
|
||||
}
|
||||
const file = item.m_file;
|
||||
let success = App.screenPlayManager.setWallpaperAtTimelineIndex(root.type, absoluteStoragePath, previewImage, file, activeMonitors, timeline.activeTimelineIndex, activeTimeline.identifier, true);
|
||||
let success = App.screenPlayManager.setWallpaperAtTimelineIndex(root.type, absoluteStoragePath, previewImage, file, activeMonitors, selectedTimeline.index, selectedTimeline.identifier, true).then(result => {
|
||||
if (!result.success) {
|
||||
console.error("setWallpaperAtTimelineIndex failed");
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
root.close();
|
||||
monitorSelection.reset();
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
namespace ScreenPlay {
|
||||
|
||||
@ -33,11 +34,33 @@ namespace ScreenPlay {
|
||||
MonitorListModel::MonitorListModel(QObject* parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
loadMonitors();
|
||||
|
||||
auto* guiAppInst = dynamic_cast<QGuiApplication*>(QGuiApplication::instance());
|
||||
connect(guiAppInst, &QGuiApplication::screenAdded, this, &MonitorListModel::screenAdded);
|
||||
connect(guiAppInst, &QGuiApplication::screenRemoved, this, &MonitorListModel::screenRemoved);
|
||||
|
||||
// Setup 1: Two Full HD monitors
|
||||
m_mockMonitorList.append({ Monitor(0, QRect(0, 0, 1920, 1080)),
|
||||
Monitor(1, QRect(1920, 0, 1920, 1080)) });
|
||||
|
||||
// Setup 2: One 4K monitor and one Full HD above
|
||||
m_mockMonitorList.append({ Monitor(0, QRect(0, 0, 3840, 2160)),
|
||||
Monitor(1, QRect((-3840 / 2), 3840, 1920, 1080)) });
|
||||
|
||||
// Setup 3: One WQHD and one Full HD
|
||||
m_mockMonitorList.append({ Monitor(0, QRect(0, 0, 2560, 1440)),
|
||||
Monitor(1, QRect(2560, 0, 1920, 1080)) });
|
||||
|
||||
// Setup 4: Three Full HD monitors (two horizontal, one vertical)
|
||||
m_mockMonitorList.append({ Monitor(0, QRect(0, 0, 1920, 1080)),
|
||||
Monitor(1, QRect(1920, 0, 1920, 1080)),
|
||||
Monitor(2, QRect(3840, 0, 1080, 1920)) });
|
||||
|
||||
// Setup 5: One ultrawide and one regular monitor
|
||||
m_mockMonitorList.append({ Monitor(0, QRect(0, 0, 3440, 1440)),
|
||||
Monitor(1, QRect(3440, 0, 1920, 1080)) });
|
||||
|
||||
loadMonitors();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -79,40 +102,23 @@ QVariant MonitorListModel::data(const QModelIndex& index, int role) const
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
|
||||
auto roleEnum = static_cast<MonitorRole>(role);
|
||||
|
||||
if (row > rowCount())
|
||||
return {};
|
||||
return QVariant();
|
||||
|
||||
switch (roleEnum) {
|
||||
case MonitorRole::AppID:
|
||||
return 1;
|
||||
// if (m_monitorList.at(row).m_activeWallpaper) {
|
||||
// return m_monitorList.at(row).m_activeWallpaper->appID();
|
||||
// } else {
|
||||
// return QVariant("");
|
||||
// }
|
||||
return m_monitorList.at(row).m_appID;
|
||||
case MonitorRole::Index:
|
||||
return m_monitorList.at(row).m_index;
|
||||
case MonitorRole::Geometry:
|
||||
return m_monitorList.at(row).m_geometry;
|
||||
case MonitorRole::InstalledType:
|
||||
// if (m_monitorList.at(row).m_activeWallpaper) {
|
||||
// return static_cast<int>(m_monitorList.at(row).m_activeWallpaper->type());
|
||||
// } else {
|
||||
return { "" };
|
||||
// }
|
||||
return QVariant::fromValue(m_monitorList.at(row).m_installedType);
|
||||
case MonitorRole::PreviewImage:
|
||||
// if (m_monitorList.at(row).m_activeWallpaper) {
|
||||
// QString absolutePath = m_monitorList.at(row).m_activeWallpaper->absolutePath();
|
||||
// return absolutePath + "/" + m_monitorList.at(row).m_activeWallpaper->previewImage();
|
||||
// } else {
|
||||
return QVariant("");
|
||||
}
|
||||
|
||||
|
||||
return m_monitorList.at(row).m_wallpaperPreviewImage;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
@ -121,9 +127,27 @@ QVariant MonitorListModel::data(const QModelIndex& index, int role) const
|
||||
*/
|
||||
void MonitorListModel::loadMonitors()
|
||||
{
|
||||
if (m_useMockMonitors) {
|
||||
|
||||
// Generate a random index
|
||||
const int selectedMockIndex = QRandomGenerator::global()->bounded(m_mockMonitorList.size());
|
||||
const auto& mockMonitorList = m_mockMonitorList[selectedMockIndex];
|
||||
qDebug() << "Using mock" << selectedMockIndex
|
||||
<< "of" << m_mockMonitorList.size()
|
||||
<< " with monitor count:" << mockMonitorList.count();
|
||||
beginInsertRows(index(rowCount()), rowCount(), rowCount() + mockMonitorList.count() - 1);
|
||||
// Use the randomly selected mock monitor setup
|
||||
for (const auto& monitor : mockMonitorList) {
|
||||
m_monitorList.append(monitor);
|
||||
qDebug() << "Adding mock monitor: " << monitor.m_index << monitor.m_geometry;
|
||||
}
|
||||
endInsertRows();
|
||||
|
||||
emit monitorReloadCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QModelIndex index;
|
||||
auto monitors = WindowsIntegration().getAllMonitors();
|
||||
|
||||
// This offset lets us center the monitor selection view in the center
|
||||
@ -151,13 +175,12 @@ void MonitorListModel::loadMonitors()
|
||||
y + offsetY,
|
||||
width,
|
||||
height);
|
||||
beginInsertRows(index, m_monitorList.size(), m_monitorList.size());
|
||||
beginInsertRows(index(rowCount()), m_monitorList.size(), m_monitorList.size());
|
||||
m_monitorList.append(Monitor { i, geometry });
|
||||
endInsertRows();
|
||||
i++;
|
||||
}
|
||||
#else
|
||||
QModelIndex index;
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
|
||||
@ -178,7 +201,7 @@ void MonitorListModel::loadMonitors()
|
||||
if (screen->geometry().width() == 0 || screen->geometry().height() == 0)
|
||||
continue;
|
||||
|
||||
beginInsertRows(index, m_monitorList.size(), m_monitorList.size());
|
||||
beginInsertRows(index(rowCount()), m_monitorList.size(), m_monitorList.size());
|
||||
m_monitorList.append(Monitor { i, screen->geometry() });
|
||||
endInsertRows();
|
||||
}
|
||||
@ -191,31 +214,22 @@ void MonitorListModel::loadMonitors()
|
||||
* \brief MonitorListModel::getAbsoluteDesktopSize
|
||||
* \return
|
||||
*/
|
||||
QRect MonitorListModel::absoluteDesktopSize() const
|
||||
QSize MonitorListModel::totalDesktopSize() const
|
||||
{
|
||||
auto* guiAppInst = dynamic_cast<QGuiApplication*>(QGuiApplication::instance());
|
||||
return guiAppInst->screens().at(0)->availableVirtualGeometry();
|
||||
QRect totalRect;
|
||||
for (const auto& monitor : m_monitorList) {
|
||||
totalRect = totalRect.united(monitor.m_geometry);
|
||||
}
|
||||
return totalRect.size();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Sets a shared_ptr to the monitor list. This should be used to set and
|
||||
remove the shared_ptr.
|
||||
*/
|
||||
void MonitorListModel::setWallpaperMonitor(
|
||||
const std::shared_ptr<WallpaperTimelineSection>& timelineSection, const QVector<int> monitors)
|
||||
QRect MonitorListModel::absoluteDesktopSize() const
|
||||
{
|
||||
m_activeTimelineSection = timelineSection;
|
||||
for (const int monitor : monitors) {
|
||||
// m_monitorList[monitor].m_activeWallpaper = wallpaper;
|
||||
|
||||
emit dataChanged(
|
||||
index(monitor, 0),
|
||||
index(monitor, 0),
|
||||
QVector<int> {
|
||||
static_cast<int>(MonitorRole::PreviewImage),
|
||||
static_cast<int>(MonitorRole::InstalledType),
|
||||
static_cast<int>(MonitorRole::AppID) });
|
||||
QRect totalRect;
|
||||
for (const auto& monitor : m_monitorList) {
|
||||
totalRect = totalRect.united(monitor.m_geometry);
|
||||
}
|
||||
return totalRect;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -243,6 +257,22 @@ void MonitorListModel::reset()
|
||||
loadMonitors();
|
||||
}
|
||||
|
||||
bool MonitorListModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
if (role == static_cast<int>(MonitorRole::PreviewImage)) {
|
||||
m_monitorList[index.column()].m_wallpaperPreviewImage = value.toString();
|
||||
emit dataChanged(index, index, { role });
|
||||
}
|
||||
if (role == static_cast<int>(MonitorRole::AppID)) {
|
||||
m_monitorList[index.column()].m_appID = value.toString();
|
||||
emit dataChanged(index, index, { role });
|
||||
}
|
||||
if (role == static_cast<int>(MonitorRole::InstalledType)) {
|
||||
m_monitorList[index.column()].m_installedType = static_cast<ContentTypes::InstalledType>(value.toInt());
|
||||
emit dataChanged(index, index, { role });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_monitorlistmodel.cpp"
|
||||
|
@ -26,6 +26,7 @@ ScreenPlayManager::ScreenPlayManager(
|
||||
m_server = std::make_unique<QLocalServer>();
|
||||
QObject::connect(m_server.get(), &QLocalServer::newConnection, this, &ScreenPlayManager::newConnection);
|
||||
QObject::connect(&m_screenPlayTimelineManager, &ScreenPlayTimelineManager::requestSaveProfiles, this, &ScreenPlayManager::requestSaveProfiles);
|
||||
QObject::connect(&m_screenPlayTimelineManager, &ScreenPlayTimelineManager::activeWallpaperCountChanged, this, &ScreenPlayManager::setActiveWallpaperCounter);
|
||||
m_server->setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
if (!m_server->listen("ScreenPlay")) {
|
||||
qCritical("Could not open Local Socket with the name ScreenPlay!");
|
||||
@ -56,6 +57,7 @@ void ScreenPlayManager::init(
|
||||
|
||||
m_screenPlayTimelineManager.setGlobalVariables(m_globalVariables);
|
||||
m_screenPlayTimelineManager.setSettings(m_settings);
|
||||
m_screenPlayTimelineManager.setMonitorListModel(m_monitorListModel);
|
||||
|
||||
// Reset to default settings if we are unable to load
|
||||
// the existing one
|
||||
@ -68,7 +70,7 @@ void ScreenPlayManager::init(
|
||||
/*!
|
||||
\brief Sets the wallpaper at a spesific timeline.
|
||||
*/
|
||||
bool ScreenPlayManager::setWallpaperAtTimelineIndex(
|
||||
QCoro::QmlTask ScreenPlayManager::setWallpaperAtTimelineIndex(
|
||||
const ScreenPlay::ContentTypes::InstalledType type,
|
||||
const QString& absolutePath,
|
||||
const QString& previewImage,
|
||||
@ -85,20 +87,28 @@ bool ScreenPlayManager::setWallpaperAtTimelineIndex(
|
||||
wallpaperData.file = file;
|
||||
wallpaperData.monitors = monitorIndex;
|
||||
wallpaperData.fillMode = m_settings->videoFillMode();
|
||||
const bool success = m_screenPlayTimelineManager.setWallpaperAtTimelineIndex(wallpaperData, timelineIndex, identifier);
|
||||
|
||||
if (!success) {
|
||||
qCritical() << "Invalid timeline index or identifier: " << timelineIndex << identifier;
|
||||
m_screenPlayTimelineManager.printTimelines();
|
||||
emit printQmlTimeline();
|
||||
return false;
|
||||
}
|
||||
return QCoro::QmlTask([this, wallpaperData, timelineIndex, identifier]() -> QCoro::Task<Result> {
|
||||
if (timelineIndex < 0 || identifier.isEmpty()) {
|
||||
|
||||
// We do not start the wallpaper here, but let
|
||||
// ScreenPlayTimelineManager::checkActiveWallpaperTimeline decide
|
||||
// if the wallpaper
|
||||
emit requestSaveProfiles();
|
||||
return true;
|
||||
co_return Result { false };
|
||||
}
|
||||
|
||||
const bool success = co_await m_screenPlayTimelineManager.setWallpaperAtTimelineIndex(wallpaperData, timelineIndex, identifier);
|
||||
|
||||
if (!success) {
|
||||
qCritical() << "Invalid timeline index or identifier: " << timelineIndex << identifier;
|
||||
m_screenPlayTimelineManager.printTimelines();
|
||||
emit printQmlTimeline();
|
||||
co_return Result { success };
|
||||
}
|
||||
|
||||
// We do not start the wallpaper here, but let
|
||||
// ScreenPlayTimelineManager::checkActiveWallpaperTimeline decide
|
||||
// if the wallpaper
|
||||
emit requestSaveProfiles();
|
||||
co_return Result { success };
|
||||
}());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -147,37 +157,23 @@ bool ScreenPlayManager::startWidget(
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScreenPlayManager::setSelectedTimelineIndex(const int selectedTimelineIndex)
|
||||
{
|
||||
m_screenPlayTimelineManager.updateMonitorListModelData(selectedTimelineIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Removes all wallpaper entries in the profiles.json.
|
||||
*/
|
||||
bool ScreenPlayManager::removeAllWallpapers(bool saveToProfile)
|
||||
QCoro::QmlTask ScreenPlayManager::removeAllWallpapers(bool saveToProfile)
|
||||
{
|
||||
// TODO
|
||||
// if (m_screenPlayTimelineManager.m_wallpaperTimelineSectionsList.empty()) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// QStringList appIDs;
|
||||
// auto activeTimelineSection = m_screenPlayTimelineManager.findActiveWallpaperTimelineSection();
|
||||
// if (!activeTimelineSection) {
|
||||
// qWarning() << "Trying to remove all Wallpapers while findActiveSection is empty.";
|
||||
// return false;
|
||||
// }
|
||||
// // Do not remove items from the vector you iterate on.
|
||||
// for (auto& client : activeTimelineSection->activeWallpaperList) {
|
||||
// appIDs.append(client->appID());
|
||||
// }
|
||||
|
||||
// for (const auto& appID : appIDs) {
|
||||
// if (!removeWallpaper(appID)) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (saveToProfile)
|
||||
// emit requestSaveProfiles();
|
||||
|
||||
return true;
|
||||
return QCoro::QmlTask([this]() -> QCoro::Task<Result> {
|
||||
// call with coro
|
||||
const bool success = co_await m_screenPlayTimelineManager.removeAllWallpaperFromActiveTimlineSections();
|
||||
qDebug() << "Task: removeAllWallpaperFromActiveTimlineSections" << success;
|
||||
// emit requestSaveProfiles();
|
||||
co_return Result { success };
|
||||
}());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -212,18 +208,16 @@ bool ScreenPlayManager::removeAllWidgets(bool saveToProfile)
|
||||
given monitor index and then closes the sdk connection, removes the entries in the
|
||||
monitor list model and decreases the active wallpaper counter property of ScreenPlayManager.
|
||||
*/
|
||||
bool ScreenPlayManager::removeWallpaperAt(int index)
|
||||
QCoro::QmlTask ScreenPlayManager::removeWallpaperAt(int timelineIndex, QString timelineIdentifier, int monitorIndex)
|
||||
{
|
||||
|
||||
if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) {
|
||||
if (removeWallpaper(*appID)) {
|
||||
emit requestSaveProfiles();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
qWarning() << "Could not remove Wallpaper at index:" << index;
|
||||
return false;
|
||||
return QCoro::QmlTask([this, timelineIndex, timelineIdentifier, monitorIndex]() -> QCoro::Task<Result> {
|
||||
// call with coro
|
||||
const bool success = co_await m_screenPlayTimelineManager.removeWallpaperAt(timelineIndex, timelineIdentifier, monitorIndex);
|
||||
qDebug() << "Task: removeAllWallpaperFromActiveTimlineSections" << success;
|
||||
// crash? mit requestSaveProfiles();
|
||||
co_return Result { success };
|
||||
}());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -531,6 +525,16 @@ bool ScreenPlayManager::setWallpaperValue(const QString& appID, const QString& k
|
||||
return false;
|
||||
}
|
||||
|
||||
int ScreenPlayManager::activeTimelineIndex()
|
||||
{
|
||||
std::shared_ptr<WallpaperTimelineSection> activeTimelineSection = m_screenPlayTimelineManager.findActiveWallpaperTimelineSection();
|
||||
if (!activeTimelineSection) {
|
||||
qCritical() << "setWallpaperValue failed, because no active timeline section was found";
|
||||
return -1;
|
||||
}
|
||||
return activeTimelineSection->index;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Saves a given wallpaper \a newProfileObject to a \a profileName. We ignore the profileName argument
|
||||
because we currently only support one profile. Returns \c true if successfuly saved to profiles.json, otherwise \c false.
|
||||
@ -604,6 +608,7 @@ bool ScreenPlayManager::loadProfiles()
|
||||
QJsonObject wallpaperObj = timelineWallpaper.toObject();
|
||||
if (!m_screenPlayTimelineManager.addTimelineFromSettings(wallpaperObj)) {
|
||||
qCritical() << "Unable to add wallpaper timeline";
|
||||
containsInvalidData = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -618,10 +623,11 @@ bool ScreenPlayManager::loadProfiles()
|
||||
// The can happen if the user unpluggs a wallpaper but it still exists
|
||||
// in the profiles.json. For this we save all profiles with now active
|
||||
// content.
|
||||
if (containsInvalidData)
|
||||
if (containsInvalidData) {
|
||||
saveProfiles();
|
||||
|
||||
m_screenPlayTimelineManager.startupFirstTimeline();
|
||||
} else {
|
||||
m_screenPlayTimelineManager.startup();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <iostream>
|
||||
#include <ranges>
|
||||
|
||||
namespace ScreenPlay {
|
||||
|
||||
@ -24,7 +25,7 @@ ScreenPlayTimelineManager::ScreenPlayTimelineManager(
|
||||
// Do not start the timer here. This will be done after
|
||||
// we have loaded all timeline wallpaper from the config.json
|
||||
QObject::connect(&m_contentTimer, &QTimer::timeout, this, &ScreenPlayTimelineManager::checkActiveWallpaperTimeline);
|
||||
m_contentTimer.start(1000);
|
||||
m_contentTimer.setInterval(250);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -92,32 +93,33 @@ bool ScreenPlayTimelineManager::addTimelineFromSettings(const QJsonObject& timel
|
||||
}
|
||||
|
||||
// TODO check license
|
||||
auto timelineSection = std::make_shared<WallpaperTimelineSection>();
|
||||
QObject::connect(timelineSection.get(), &WallpaperTimelineSection::requestSaveProfiles, this, &ScreenPlayTimelineManager::requestSaveProfiles);
|
||||
timelineSection->startTime = startTime;
|
||||
timelineSection->endTime = endTime;
|
||||
timelineSection->settings = m_settings;
|
||||
timelineSection->globalVariables = m_globalVariables;
|
||||
timelineSection->relativePosition = Util().calculateRelativePosition(endTime);
|
||||
auto newTimelineSection = std::make_shared<WallpaperTimelineSection>();
|
||||
QObject::connect(newTimelineSection.get(), &WallpaperTimelineSection::requestSaveProfiles, this, &ScreenPlayTimelineManager::requestSaveProfiles);
|
||||
QObject::connect(newTimelineSection.get(), &WallpaperTimelineSection::activeWallpaperCountChanged, this, &ScreenPlayTimelineManager::activeWallpaperCountChanged);
|
||||
newTimelineSection->startTime = startTime;
|
||||
newTimelineSection->endTime = endTime;
|
||||
newTimelineSection->settings = m_settings;
|
||||
newTimelineSection->globalVariables = m_globalVariables;
|
||||
newTimelineSection->relativePosition = Util().calculateRelativePosition(endTime);
|
||||
const auto wallpaperList = timelineObj.value("wallpaper").toArray();
|
||||
for (auto& wallpaper : wallpaperList) {
|
||||
std::optional<WallpaperData> wallpaperDataOpt = WallpaperData::loadWallpaperConfig(wallpaper.toObject());
|
||||
if (!wallpaperDataOpt.has_value())
|
||||
return false;
|
||||
timelineSection->wallpaperDataList.push_back(wallpaperDataOpt.value());
|
||||
newTimelineSection->wallpaperDataList.push_back(wallpaperDataOpt.value());
|
||||
}
|
||||
|
||||
// Todo: Should we use addTimelineAt?
|
||||
timelineSection->index = m_wallpaperTimelineSectionsList.length();
|
||||
timelineSection->identifier = Util().generateRandomString(4);
|
||||
newTimelineSection->index = m_wallpaperTimelineSectionsList.length();
|
||||
newTimelineSection->identifier = Util().generateRandomString(4);
|
||||
|
||||
qInfo() << timelineSection->index
|
||||
<< timelineSection->startTime
|
||||
<< timelineSection->endTime;
|
||||
qInfo() << newTimelineSection->index
|
||||
<< newTimelineSection->startTime
|
||||
<< newTimelineSection->endTime;
|
||||
|
||||
// Todo: Should we use addTimelineAt?
|
||||
m_wallpaperTimelineSectionsList.append(timelineSection);
|
||||
return false;
|
||||
m_wallpaperTimelineSectionsList.append(newTimelineSection);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -181,12 +183,26 @@ void ScreenPlayTimelineManager::checkActiveWallpaperTimeline()
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::shared_ptr<WallpaperTimelineSection>> ScreenPlayTimelineManager::activeWallpaperSection(const int timelineIndex, const QString timelineIdentifier)
|
||||
{
|
||||
for (const auto& section : m_wallpaperTimelineSectionsList) {
|
||||
const bool indexMatches = section->index == timelineIndex;
|
||||
const bool timelineIdentifierMatches = section->identifier == timelineIdentifier;
|
||||
if (indexMatches && timelineIdentifierMatches) {
|
||||
return section;
|
||||
}
|
||||
}
|
||||
qCritical() << "No matching timeline for index:" << timelineIndex << "timelineIdentifier: " << timelineIdentifier;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ScreenPlayTimelineManager::setSettings(const std::shared_ptr<Settings>& settings)
|
||||
{
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
void ScreenPlayTimelineManager::startupFirstTimeline()
|
||||
void ScreenPlayTimelineManager::startup()
|
||||
{
|
||||
std::shared_ptr<WallpaperTimelineSection> currentTimeline = findTimelineForCurrentTime();
|
||||
if (!currentTimeline) {
|
||||
@ -194,6 +210,31 @@ void ScreenPlayTimelineManager::startupFirstTimeline()
|
||||
return;
|
||||
}
|
||||
currentTimeline->activateTimeline();
|
||||
m_contentTimer.start();
|
||||
}
|
||||
|
||||
void ScreenPlayTimelineManager::setMonitorListModel(const std::shared_ptr<MonitorListModel>& monitorListModel)
|
||||
{
|
||||
m_monitorListModel = monitorListModel;
|
||||
}
|
||||
|
||||
void ScreenPlayTimelineManager::updateMonitorListModelData(const int selectedTimelineIndex)
|
||||
{
|
||||
|
||||
auto selectedTimeline = m_wallpaperTimelineSectionsList | std::views::drop(selectedTimelineIndex) | std::views::take(1);
|
||||
// Clear current list model. This is needed to make sure
|
||||
// that we do not show any old active wallpaper
|
||||
m_monitorListModel->reset();
|
||||
|
||||
if (!selectedTimeline.empty()) {
|
||||
auto& timeline = selectedTimeline.front();
|
||||
for (const auto& wallpaper : timeline->wallpaperDataList) {
|
||||
const auto previewImg = wallpaper.absolutePath + "/" + wallpaper.previewImage;
|
||||
m_monitorListModel->setData(m_monitorListModel->index(0, wallpaper.monitors.first()), previewImg, (int)MonitorListModel::MonitorRole::PreviewImage);
|
||||
}
|
||||
} else {
|
||||
qCritical() << "No selectedTimelineIndex found" << selectedTimelineIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenPlayTimelineManager::setGlobalVariables(const std::shared_ptr<GlobalVariables>& globalVariables)
|
||||
@ -281,6 +322,7 @@ bool ScreenPlayTimelineManager::addTimelineAt(const int index, const float relti
|
||||
|
||||
auto newTimelineSection = std::make_shared<WallpaperTimelineSection>();
|
||||
QObject::connect(newTimelineSection.get(), &WallpaperTimelineSection::requestSaveProfiles, this, &ScreenPlayTimelineManager::requestSaveProfiles);
|
||||
QObject::connect(newTimelineSection.get(), &WallpaperTimelineSection::activeWallpaperCountChanged, this, &ScreenPlayTimelineManager::activeWallpaperCountChanged);
|
||||
newTimelineSection->settings = m_settings;
|
||||
newTimelineSection->globalVariables = m_globalVariables;
|
||||
newTimelineSection->index = index;
|
||||
@ -332,6 +374,39 @@ QCoro::Task<bool> ScreenPlayTimelineManager::removeAllTimlineSections()
|
||||
co_return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Qml function that removes all wallpaper for the current Timeline section.
|
||||
*/
|
||||
QCoro::Task<bool> ScreenPlayTimelineManager::removeAllWallpaperFromActiveTimlineSections()
|
||||
{
|
||||
|
||||
// First check if there is any active wallpaper and disable it
|
||||
auto activeTimelineSection = findActiveWallpaperTimelineSection();
|
||||
if (activeTimelineSection) {
|
||||
// First deactivate so the wallpaper has time to shutdown
|
||||
activeTimelineSection->deactivateTimeline();
|
||||
activeTimelineSection->wallpaperDataList.clear();
|
||||
}
|
||||
co_return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Qml function that removes all wallpaper for the current Timeline section.
|
||||
*/
|
||||
QCoro::Task<bool> ScreenPlayTimelineManager::removeWallpaperAt(const int timelineIndex, const QString timelineIdentifier, const int monitorIndex)
|
||||
{
|
||||
m_contentTimer.stop();
|
||||
auto updateTimer = qScopeGuard([this] { m_contentTimer.start(); });
|
||||
|
||||
auto sectionOpt = activeWallpaperSection(timelineIndex, timelineIdentifier);
|
||||
if (!sectionOpt)
|
||||
co_return false;
|
||||
|
||||
const bool success = co_await sectionOpt.value()->removeWallpaper(monitorIndex);
|
||||
|
||||
co_return success;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Removes a timeline at a given index. Expands the timeline next to it
|
||||
to fill the space.
|
||||
@ -405,7 +480,10 @@ void ScreenPlayTimelineManager::printTimelines()
|
||||
}
|
||||
}
|
||||
|
||||
bool ScreenPlayTimelineManager::setWallpaperAtTimelineIndex(WallpaperData wallpaperData, const int timelineIndex, const QString& identifier)
|
||||
QCoro::Task<bool> ScreenPlayTimelineManager::setWallpaperAtTimelineIndex(
|
||||
WallpaperData wallpaperData,
|
||||
const int timelineIndex,
|
||||
const QString& identifier)
|
||||
{
|
||||
bool found = false;
|
||||
for (auto& timelineSection : m_wallpaperTimelineSectionsList) {
|
||||
@ -426,6 +504,9 @@ bool ScreenPlayTimelineManager::setWallpaperAtTimelineIndex(WallpaperData wallpa
|
||||
if (it != timelineSection->wallpaperDataList.end()) {
|
||||
// Overwrite the existing wallpaper
|
||||
*it = wallpaperData;
|
||||
// TODO: Do not replace but
|
||||
co_await timelineSection->deactivateTimeline();
|
||||
timelineSection->activateTimeline();
|
||||
} else {
|
||||
// Append the new wallpaper data
|
||||
timelineSection->wallpaperDataList.push_back(wallpaperData);
|
||||
@ -436,7 +517,7 @@ bool ScreenPlayTimelineManager::setWallpaperAtTimelineIndex(WallpaperData wallpa
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
co_return found;
|
||||
}
|
||||
|
||||
QJsonArray ScreenPlayTimelineManager::initialSectionsList()
|
||||
|
@ -71,22 +71,6 @@ bool WallpaperTimelineSection::activateTimeline()
|
||||
const QString appID = Util().generateRandomString();
|
||||
qInfo() << "Start wallpaper" << wallpaperData.absolutePath << appID;
|
||||
|
||||
// Only support remove wallpaper that spans over 1 monitor
|
||||
// if (wallpaper.monitors.length() == 1) {
|
||||
// int i = 0;
|
||||
// for (auto& wallpaper : m_screenPlayWallpapers) {
|
||||
// if (wallpaper->monitors().length() == 1) {
|
||||
// if (monitors.at(0) == wallpaper->monitors().at(0)) {
|
||||
// return wallpaper->replace(
|
||||
// wallpaper,
|
||||
// settings->checkWallpaperVisible());
|
||||
// m_monitorListModel->setWallpaperMonitor(wallpaper, wallpaper.monitors);
|
||||
// }
|
||||
// }
|
||||
// i++;
|
||||
// }
|
||||
// }
|
||||
|
||||
auto screenPlayWallpaper = std::make_shared<ScreenPlayWallpaper>(
|
||||
globalVariables,
|
||||
appID,
|
||||
@ -100,6 +84,7 @@ bool WallpaperTimelineSection::activateTimeline()
|
||||
QObject::connect(screenPlayWallpaper.get(), &ScreenPlayWallpaper::requestClose, this, []() {
|
||||
// , &ScreenPlayManager::removeWallpaper);
|
||||
});
|
||||
QObject::connect(screenPlayWallpaper.get(), &ScreenPlayWallpaper::isConnectedChanged, this, &WallpaperTimelineSection::updateActiveWallpaperCounter);
|
||||
|
||||
// QObject::connect(screenPlayWallpaper.get(), &ScreenPlayWallpaper::error, this, this, []() {
|
||||
// // , &ScreenPlayManager::displayErrorPopup);
|
||||
@ -144,4 +129,44 @@ QCoro::Task<bool> WallpaperTimelineSection::deactivateTimeline()
|
||||
co_return false;
|
||||
}
|
||||
|
||||
QCoro::Task<bool> WallpaperTimelineSection::removeWallpaper(const int monitorIndex)
|
||||
{
|
||||
auto wallpaperOpt = wallpaperByMonitorIndex(monitorIndex);
|
||||
if (!wallpaperOpt.has_value()) {
|
||||
qCritical() << "No wallpaper found for monitor index:" << monitorIndex;
|
||||
co_return false;
|
||||
}
|
||||
|
||||
QTimer timer;
|
||||
timer.start(250);
|
||||
const int maxRetries = 30;
|
||||
wallpaperOpt.value()->close();
|
||||
for (int i = 1; i <= maxRetries; ++i) {
|
||||
// Wait for the timer to tick
|
||||
co_await timer;
|
||||
if (!wallpaperOpt.value()->isConnected()) {
|
||||
co_return true;
|
||||
}
|
||||
}
|
||||
co_return false;
|
||||
}
|
||||
|
||||
void WallpaperTimelineSection::updateActiveWallpaperCounter()
|
||||
{
|
||||
quint64 activeWallpaperCount = 0;
|
||||
for (const auto& screenPlayWallpaper : activeWallpaperList) {
|
||||
if (screenPlayWallpaper->isConnected())
|
||||
activeWallpaperCount++;
|
||||
}
|
||||
emit activeWallpaperCountChanged(activeWallpaperCount);
|
||||
}
|
||||
|
||||
std::optional<std::shared_ptr<ScreenPlayWallpaper>> WallpaperTimelineSection::wallpaperByMonitorIndex(const int monitorIndex)
|
||||
{
|
||||
for (const auto& screenPlayWallpaper : activeWallpaperList) {
|
||||
if (screenPlayWallpaper->monitors().contains(monitorIndex))
|
||||
return screenPlayWallpaper;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls as QQC
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import ScreenPlayUtil
|
||||
|
||||
Popup {
|
||||
QQC.Popup {
|
||||
id: root
|
||||
property Item modalSource
|
||||
// Workaround for missing animation on hide
|
||||
|
@ -1,9 +1,9 @@
|
||||
// SPDX-License-Identifier: LicenseRef-EliasSteurerTachiom OR AGPL-3.0-only
|
||||
#include "ScreenPlayUtil/util.h"
|
||||
#include "qguiapplication.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QFile>
|
||||
#include <QGuiApplication>
|
||||
#include <QJsonParseError>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
|
@ -58,11 +58,10 @@ Rectangle {
|
||||
return;
|
||||
}
|
||||
// For example if background is a solid color
|
||||
if(Wallpaper.windowsDesktopProperties.wallpaperPath === ""){
|
||||
if (Wallpaper.windowsDesktopProperties.wallpaperPath === "") {
|
||||
root.canFadeByWallpaperFillMode = false;
|
||||
return;
|
||||
}
|
||||
|
||||
imgCover.source = Qt.resolvedUrl("file:///" + Wallpaper.windowsDesktopProperties.wallpaperPath);
|
||||
switch (Wallpaper.windowsDesktopProperties.wallpaperStyle) {
|
||||
case 10:
|
||||
|
@ -356,7 +356,6 @@ protected:
|
||||
QVector<int> m_activeScreensList;
|
||||
QFileSystemWatcher m_fileSystemWatcher;
|
||||
QTimer m_liveReloadLimiter;
|
||||
QSysInfo m_sysinfo;
|
||||
std::unique_ptr<ScreenPlaySDK> m_sdk;
|
||||
QUrl m_projectSourceFileAbsolute;
|
||||
ScreenPlay::Video::VideoCodec m_videoCodec = ScreenPlay::Video::VideoCodec::Unknown;
|
||||
|
Loading…
Reference in New Issue
Block a user