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