1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-09-18 08:22:33 +02:00

Fix timeline activation

This commit is contained in:
Elias Steurer 2024-05-25 10:53:57 +02:00
parent 8be660390a
commit d88859927d
6 changed files with 170 additions and 88 deletions

View File

@ -81,7 +81,7 @@ public:
const QString& identifier,
const bool saveToProfilesConfigFile);
Q_INVOKABLE bool createWidget(
Q_INVOKABLE bool startWidget(
// moc needs full enum namespace info see QTBUG-58454
const ScreenPlay::ContentTypes::InstalledType type,
const QPoint& position,
@ -106,6 +106,7 @@ signals:
void requestSaveProfiles();
void requestRaise();
void profilesSaved();
void printQmlTimeline();
void displayErrorPopup(const QString& msg);
private slots:
@ -175,6 +176,8 @@ private:
bool removeWidget(const QString& appID);
std::optional<std::shared_ptr<WallpaperTimelineSection>> loadTimelineWallpaperConfig(const QJsonObject& timelineObj);
std::shared_ptr<WallpaperTimelineSection> findActiveWallpaperTimelineSection();
std::shared_ptr<WallpaperTimelineSection> getCurrentTimeline();
void activateNewTimeline();
private:
std::shared_ptr<GlobalVariables> m_globalVariables;

View File

@ -31,7 +31,8 @@ struct WallpaperData {
ContentTypes::InstalledType type = ContentTypes::InstalledType::Unknown;
Video::FillMode fillMode = Video::FillMode::Fill;
QVector<int> monitors;
QJsonObject serialize() const {
QJsonObject serialize() const
{
QJsonObject data;
data.insert("isLooping", isLooping);
data.insert("absolutePath", absolutePath);
@ -40,8 +41,8 @@ struct WallpaperData {
data.insert("volume", volume);
data.insert("file", file);
data.insert("properties", properties);
data.insert("type", QVariant::fromValue(type).toString() );
data.insert("fillMode", QVariant::fromValue(fillMode).toString());
data.insert("type", QVariant::fromValue(type).toString());
data.insert("fillMode", QVariant::fromValue(fillMode).toString());
// Serialize QVector<int> monitors
QJsonArray monitorArray;

View File

@ -24,6 +24,18 @@ Control {
timeLine.removeAll()
}
function printTimelines(){
print("################# qml:")
for (let i = 0; i < timeLine.sectionsList.length; i++) {
print(
timeLine.sectionsList[i].index,
timeLine.sectionsList[i].identifier,
timeLine.sectionsList[i].relativeLinePosition)
}
}
Component {
id: sectionComp
QtObject {
@ -48,6 +60,12 @@ Control {
createAllSections(initialStopPositions)
}
function createAllSections(initialStopPositions) {
for (let identifier in initialStopPositions) {
let stopPosition = initialStopPositions[identifier];
addSection(identifier, stopPosition);
}
}
function removeAll(){
print("removeAll",timeLine.sectionsList.length)
@ -74,12 +92,6 @@ Control {
sectionObject.identifier)
}
function createAllSections(initialStopPositions) {
for (let identifier in initialStopPositions) {
let stopPosition = initialStopPositions[identifier];
addSection(identifier, stopPosition);
}
}
// IMPORTANT: The new element is always on the left. The first
// handle always persists because the
@ -250,9 +262,8 @@ Control {
//timeLine.sectionsList[i].relativeLinePosition =prevPos / timeLine.width
print("sections: ", i, "prev minimum ",prevPos,"next maximum", nextPos, timeLine.sectionsList[i].relativeLinePosition)
// print("sections: ", i, "prev minimum ",prevPos,"next maximum", nextPos, timeLine.sectionsList[i].relativeLinePosition)
}
print("++++++++++++++++++")
for (let i = 0; i < timeLine.sectionsList.length; i++) {
let section = timeLine.sectionsList[i]
section.relativeLinePosition = section.lineHandle.linePosition
@ -319,13 +330,51 @@ Control {
enabled: true
}
// Current time indicator
Rectangle {
id: currentTimeIndicator
color: Material.color(Material.BlueGrey)
width: 2
height: 30
y: (addHandleWrapper.height - height) / 2 // Vertically center within addHandleWrapper
property int totalSeconds: 86400 // Total seconds in a day
property int currentSeconds: (new Date().getHours() * 3600) + (new Date().getMinutes() * 60) + new Date().getSeconds()
x: addHandleWrapper.width * (currentSeconds / totalSeconds)
Timer {
interval: 1000
repeat: true
running: true
onTriggered: {
currentTimeIndicator.currentSeconds = (new Date().getHours() * 3600) + (new Date().getMinutes() * 60) + new Date().getSeconds();
currentTimeIndicator.x = addHandleWrapper.width * (currentTimeIndicator.currentSeconds / currentTimeIndicator.totalSeconds);
currentTimeText.text = Qt.formatTime(new Date(), "hh:mm:ss");
}
}
}
Text {
id: currentTimeText
color: Material.color(Material.Grey)
text: Qt.formatTime(new Date(), "hh:mm:ss")
font.pointSize: 12
anchors {
bottom: addHandleWrapper.top
horizontalCenter: currentTimeIndicator.horizontalCenter
}
}
RowLayout {
anchors.fill: parent
Repeater {
model: 24
Item {
width: 20
height: 40
height: 60
required property int index
Text {
color: "gray"

View File

@ -116,6 +116,12 @@ Drawer {
id: timeline
Layout.fillWidth: true
Layout.fillHeight: true
Connections {
target: App.screenPlayManager
function onPrintQmlTimeline(){
timeline.printTimelines()
}
}
}
ColumnLayout {
@ -130,13 +136,9 @@ Drawer {
}
}
RowLayout {
spacing: 10
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.horizontalStretchFactor: 3
spacing: 10
Text {
@ -157,13 +159,6 @@ Drawer {
fontSize: 11
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.horizontalStretchFactor: 1
}
}
}
ColumnLayout {
@ -393,7 +388,7 @@ Drawer {
true)
}
if (App.util.isWidget(root.type))
App.screenPlayManager.createWidget(type,
App.screenPlayManager.startWidget(type,
Qt.point(0, 0),
absoluteStoragePath,
previewImage, {},

View File

@ -61,33 +61,30 @@ std::shared_ptr<WallpaperTimelineSection> ScreenPlayManager::findActiveWallpaper
return nullptr;
}
std::shared_ptr<WallpaperTimelineSection> ScreenPlayManager::getCurrentTimeline()
{
const QTime currentTime = QTime::currentTime();
for (const auto& section : m_wallpaperTimelineSectionsList) {
if (section->containsTime(currentTime)) {
return section;
}
}
return nullptr;
}
/*!
\brief Checks if we need to display a different wallpaper at the current time.
CurrentTimeline => Timeline that should currently run, based on start and endtime.
ActiveTimeline => Timeline with isActive flag set to true
*/
void ScreenPlayManager::checkActiveWallpaperTimeline()
{
// Retrieve the current time only once to improve efficiency.
const QTime currentTime = QTime::currentTime();
//Function to find the active timeline section based on the current time.
auto getCurrentTimeline = [this, &currentTime]() -> std::shared_ptr<WallpaperTimelineSection> {
for (const auto& section : m_wallpaperTimelineSectionsList) {
if (section->containsTime(currentTime)) {
return section;
}
}
return nullptr;
};
// Function to activate a new wallpaper.
auto activateWallpaper = [this](std::shared_ptr<WallpaperTimelineSection> activeTimelineSection) {
for (const auto& wallpaper : activeTimelineSection->wallpaperData) {
auto activeWallpaper = startWallpaper(wallpaper, false);
if (activeWallpaper) {
activeTimelineSection->activeWallpaperList.push_back(activeWallpaper);
}
}
};
std::shared_ptr<WallpaperTimelineSection> currentTimeline = getCurrentTimeline();
if (!currentTimeline) {
qCritical() << "No active timeline found. There must always be an active timeline.";
return;
}
// Check for currently active timeline.
std::shared_ptr<WallpaperTimelineSection> activeTimelineSection = nullptr;
@ -98,26 +95,59 @@ void ScreenPlayManager::checkActiveWallpaperTimeline()
}
}
// If no active timeline or active timeline does not match current time, switch to new timeline.
if (!activeTimelineSection || !activeTimelineSection->containsTime(currentTime)) {
if (activeTimelineSection) {
activeTimelineSection->isActive = false;
}
// We start the first timeline section,if there is currently no active timeline section.
// This happens at every startup.
if (!activeTimelineSection) {
activateNewTimeline();
}
std::shared_ptr<WallpaperTimelineSection> newActiveTimelineSection = getCurrentTimeline();
if (!newActiveTimelineSection) {
qCritical() << "No active timeline found. There must always be an active timeline.";
return;
// If timeline does not match current time, switch to new timeline.
if (activeTimelineSection) {
if (!activeTimelineSection->containsTime(QTime::currentTime()) || !activeTimelineSection->isActive) {
activateNewTimeline();
}
newActiveTimelineSection->isActive = true;
activateWallpaper(newActiveTimelineSection);
qInfo() << "Timeline switched successfully.";
}
}
void ScreenPlayManager::activateNewTimeline()
{
// Remove old timeline content
auto oldTimeline = findActiveWallpaperTimelineSection();
// Will be null on startup, where there is no old timeline
if (oldTimeline) {
oldTimeline->isActive = false;
for (auto& activeWallpaper : oldTimeline->activeWallpaperList) {
activeWallpaper->close();
}
// Clear all active wallpaper connections, but do not
// clear WallpaperData in case we need it again later
oldTimeline->activeWallpaperList.clear();
}
// Activate new timeline content
std::shared_ptr<WallpaperTimelineSection> newTimelineSection = getCurrentTimeline();
if (!newTimelineSection) {
qCritical() << "No active timeline found. There must always be an active timeline.";
return;
}
newTimelineSection->isActive = true;
// Activate new wallpaper
for (const auto& wallpaper : newTimelineSection->wallpaperData) {
auto activeWallpaper = startWallpaper(wallpaper, false);
if (!activeWallpaper) {
qCritical() << "Unable to start the new wallpaper at timeline:" << newTimelineSection->identifier
<< newTimelineSection->startTime << "-" << newTimelineSection->endTime;
return;
}
newTimelineSection->activeWallpaperList.push_back(activeWallpaper);
}
qInfo() << "Timeline switched successfully.";
}
/*!
\brief Qml function, because we cannot create the WallpaperData in qml.
\brief Sets the wallpaper at a spesific timeline.
*/
bool ScreenPlayManager::setWallpaperAtTimelineIndex(
const ContentTypes::InstalledType type,
@ -143,23 +173,28 @@ bool ScreenPlayManager::setWallpaperAtTimelineIndex(
wallpaperData.volume = volume;
wallpaperData.playbackRate = playbackRate;
wallpaperData.properties = properties;
bool ok = false;
for (auto& timelineSection : m_wallpaperTimelineSectionsList) {
const bool sameIndex = timelineSection->index == timelineIndex;
const bool sameIdentifier = timelineSection->identifier == identifier;
if (sameIndex && sameIdentifier) {
// TODO vec
timelineSection->wallpaperData = { wallpaperData };
ok = true;
break;
} else if (sameIdentifier || sameIdentifier) {
qCritical() << "Invalid";
}
}
if (!ok) {
qCritical() << "Invalid sameIdentifier: " << timelineIndex << identifier;
auto wallpaper = startWallpaper(
wallpaperData,
saveToProfilesConfigFile);
// TODO
printTimelines();
emit printQmlTimeline();
return false;
}
// We do not start the wallpaper here, but let
// ScreenPlayManager::checkActiveWallpaperTimeline decide
// if the wallpaper
emit requestSaveProfiles();
return true;
}
@ -253,7 +288,7 @@ std::shared_ptr<ScreenPlayWallpaper> ScreenPlayManager::startWallpaper(
/*!
\brief Creates a ScreenPlayWidget object via a \a absoluteStoragePath and a \a preview image (relative path).
*/
bool ScreenPlayManager::createWidget(
bool ScreenPlayManager::startWidget(
const ContentTypes::InstalledType type,
const QPoint& position,
const QString& absoluteStoragePath,
@ -384,6 +419,7 @@ bool ScreenPlayManager::requestProjectSettingsAtMonitorIndex(const int index)
if (!activeTimelineSection) {
return false;
}
// TODO CHANGE TO WP SECTION
for (const auto& wallpaper : std::as_const(activeTimelineSection->activeWallpaperList)) {
if (wallpaper->monitors()[0] == index) {
@ -486,6 +522,7 @@ bool ScreenPlayManager::moveTimelineAt(const int index, const QString identifier
auto& wallpapterTimelineSectionNext = m_wallpaperTimelineSectionsList.at(index + 1);
wallpapterTimelineSectionNext->startTime = newPositionTime;
}
printTimelines();
emit requestSaveProfiles();
return true;
@ -595,6 +632,7 @@ bool ScreenPlayManager::addTimelineAt(const int index, const float reltiaveLineP
return true;
}
// Gets called from qml
void ScreenPlayManager::removeAllTimlineSections()
{
m_contentTimer.stop();
@ -621,6 +659,10 @@ void ScreenPlayManager::removeAllTimlineSections()
}
m_wallpaperTimelineSectionsList.clear();
removeAllWallpapers();
removeAllWidgets();
// Do not call requestSaveProfiles, because qml will add
// the default timeline after this function
}
bool ScreenPlayManager::removeTimelineAt(const int index)
@ -769,8 +811,14 @@ bool ScreenPlayManager::removeWallpaper(const QString& appID)
auto activeTimelineSection = findActiveWallpaperTimelineSection();
if (!activeTimelineSection) {
qCritical() << "No timeline found.";
return false;
}
if (activeTimelineSection->activeWallpaperList.empty()) {
qCritical() << "No activeWallpaperList is empty for the current active timeline.";
return false;
}
activeTimelineSection->activeWallpaperList.erase(
std::remove_if(
activeTimelineSection->activeWallpaperList.begin(),
@ -824,7 +872,8 @@ bool ScreenPlayManager::removeWidget(const QString& appID)
decreaseActiveWidgetsCounter();
return true;
}));
}),
m_screenPlayWidgets.end());
if (activeWidgetsCounter() != m_screenPlayWidgets.length()) {
qWarning() << "activeWidgetsCounter value: " << activeWidgetsCounter()
@ -864,7 +913,7 @@ bool ScreenPlayManager::saveProfiles()
QJsonArray wallpaper;
// Every timeline section can have multiple wallpaper
for (const auto& wallpaperData : activeTimelineWallpaper->wallpaperData) {
wallpaper.append(wallpaperData.serialize());
wallpaper.append(wallpaperData.serialize());
}
timelineWallpaper.insert("wallpaper", wallpaper);
@ -930,21 +979,6 @@ bool ScreenPlayManager::loadProfiles()
if (wallpaper.toObject().value("name").toString() != "default")
continue;
// Dry run to check if the config is outdated. This is when a wallpaper is configured
// but no longer available.
// for (QJsonValueRef wallpaper : wallpaper.toObject().value("timelineWallpaper").toArray()) {
// QJsonObject wallpaperObj = wallpaper.toObject();
// if (wallpaperObj.empty())
// continue;
// const QString absolutePath = wallpaperObj.value("absolutePath").toString();
// if (!QFile(absolutePath).exists()) {
// qWarning() << "Specified file does not exist! This means the profiles.json is no longer valid.";
// return false;
// }
// }
for (QJsonValueRef timelineWallpaper : wallpaper.toObject().value("timelineWallpaper").toArray()) {
QJsonObject wallpaperObj = timelineWallpaper.toObject();
std::optional<std::shared_ptr<WallpaperTimelineSection>> wallpaperDataOpt = loadTimelineWallpaperConfig(wallpaperObj);
@ -1012,8 +1046,6 @@ float calculateRelativePosition(const QTime& endTime)
std::optional<std::shared_ptr<WallpaperTimelineSection>> ScreenPlayManager::loadTimelineWallpaperConfig(const QJsonObject& timelineObj)
{
const QString name = timelineObj.value("name").toString();
const QTime startTime = QTime::fromString(timelineObj.value("startTime").toString(), m_timelineTimeFormat);
const QTime endTime = QTime::fromString(timelineObj.value("endTime").toString(), m_timelineTimeFormat);
if (startTime > endTime) {
@ -1093,7 +1125,7 @@ bool ScreenPlayManager::loadWidgetConfig(const QJsonObject& widgetObj)
const auto type = QStringToEnum<ContentTypes::InstalledType>(typeString, ContentTypes::InstalledType::QMLWidget);
const QJsonObject properties = widgetObj.value("properties").toObject();
const bool success = createWidget(type, position, absolutePath, previewImage, properties, false);
const bool success = startWidget(type, position, absolutePath, previewImage, properties, false);
if (!success) {
qWarning() << "Unable to start Widget! " << type << position << absolutePath;

View File

@ -153,6 +153,7 @@ QJsonObject ScreenPlayWallpaper::getActiveSettingsJson()
*/
void ScreenPlayWallpaper::close()
{
qInfo() << "Close wallpaper with appID:" << m_appID;
// When the wallpaper never connected, this is invalid
if (!m_connection) {
qCritical() << "Cannot request quit, wallpaper never connected!";
@ -165,6 +166,7 @@ void ScreenPlayWallpaper::close()
}
m_isExiting = true;
}
/*!
\brief Prints the exit code if != 0.
*/