1
0
mirror of https://gitlab.com/kelteseth/ScreenPlay.git synced 2024-11-23 11:13:00 +01:00

WIP: Refactor saving/loading of profiles

We now partially support saving and loading custom properties. This is acomplished
via a flat ProjectSettingsListModel that is only used for the properties. We still
display the DefaultVideoControls.qml if the content is a video. For this I added
the m_installedType to the MonitorListModel.
This commit is contained in:
Elias Steurer 2020-08-08 19:39:58 +02:00
parent 9852b09abe
commit c4423a1497
16 changed files with 339 additions and 211 deletions

View File

@ -51,7 +51,6 @@ set(headers app.h
src/profile.h src/profile.h
src/projectfile.h src/projectfile.h
src/installedlistfilter.h src/installedlistfilter.h
src/projectsettingslistitem.h
src/projectsettingslistmodel.h src/projectsettingslistmodel.h
src/screenplaymanager.h src/screenplaymanager.h
src/sdkconnection.h src/sdkconnection.h

View File

@ -7,7 +7,6 @@ import QtQuick.Layouts 1.3
import ScreenPlay 1.0 import ScreenPlay 1.0
import ScreenPlay.Enums.FillMode 1.0 import ScreenPlay.Enums.FillMode 1.0
import "../Common/" as SP import "../Common/" as SP
ColumnLayout { ColumnLayout {
@ -30,26 +29,29 @@ ColumnLayout {
SP.Slider { SP.Slider {
headline: qsTr("Volume") headline: qsTr("Volume")
slider.onMoved: { slider.stepSize: 0.1
print("MODEV") slider.onMoved: {
ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex( ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex(
activeMonitorIndex, "volume", slider.value) activeMonitorIndex, "volume", slider.value)
} }
Layout.fillWidth: true Layout.fillWidth: true
} }
SP.Slider { SP.Slider {
headline: qsTr("Playback rate") headline: qsTr("Playback rate")
slider.onMoved: ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex( slider.onMoved: ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex(
activeMonitorIndex, "playbackRate", slider.value) activeMonitorIndex, "playbackRate", slider.value)
Layout.fillWidth: true Layout.fillWidth: true
slider.stepSize: 0.1
} }
SP.Slider { SP.Slider {
headline: qsTr("Current Video Time") headline: qsTr("Current Video Time")
slider.onMoved: ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex( slider.onMoved: ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex(
activeMonitorIndex, "currentTime", slider.value) activeMonitorIndex, "currentTime", slider.value)
Layout.fillWidth: true Layout.fillWidth: true
slider.stepSize: 0.1
} }
ColumnLayout { ColumnLayout {
height: 50 height: 50
Layout.fillWidth: true Layout.fillWidth: true
@ -78,10 +80,8 @@ ColumnLayout {
textRole: "text" textRole: "text"
valueRole: "value" valueRole: "value"
currentIndex: root.indexOfValue( currentIndex: root.indexOfValue(settingsComboBox.model,
settingsComboBox.model, ScreenPlay.settings.videoFillMode)
ScreenPlay.settings.videoFillMode)
model: [{ model: [{
"value": FillMode.Stretch, "value": FillMode.Stretch,

View File

@ -6,7 +6,7 @@ import QtQuick.Controls.Material 2.12
import ScreenPlay 1.0 import ScreenPlay 1.0
Rectangle { Rectangle {
id: rect id: root
color: Material.theme === Material.Light ? Material.background : Qt.darker( color: Material.theme === Material.Light ? Material.background : Qt.darker(
Material.background) Material.background)
@ -18,15 +18,15 @@ Rectangle {
property real availableWidth: 0 property real availableWidth: 0
property real availableHeight: 0 property real availableHeight: 0
property int fontSize: 12 property int fontSize: 12
property bool multipleMonitorsSelectable: true property bool multipleMonitorsSelectable: false
// We preselect the main monitor // We preselect the main monitor
property var activeMonitors: [0] property var activeMonitors: [0]
property alias background: rect.color property alias background: root.color
property alias radius: rect.radius property alias radius: root.radius
signal requestProjectSettings(var at) signal requestProjectSettings(int index, var installedType, string appID)
Component.onCompleted: { Component.onCompleted: {
resize() resize()
@ -59,16 +59,16 @@ Rectangle {
} }
function getActiveMonitors() { function getActiveMonitors() {
rect.activeMonitors = [] root.activeMonitors = []
for (var i = 0; i < rp.count; i++) { for (var i = 0; i < rp.count; i++) {
if (rp.itemAt(i).isSelected) { if (rp.itemAt(i).isSelected) {
rect.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 // Must be called manually. When QML properties are getting altered in js the
// property binding breaks // property binding breaks
rect.activeMonitorsChanged() root.activeMonitorsChanged()
return rect.activeMonitors return root.activeMonitors
} }
function resize() { function resize() {
@ -134,7 +134,6 @@ Rectangle {
snapMode: ScrollBar.SnapOnRelease snapMode: ScrollBar.SnapOnRelease
} }
Repeater { Repeater {
id: rp id: rp
model: ScreenPlay.monitorListModel model: ScreenPlay.monitorListModel
@ -147,6 +146,7 @@ Rectangle {
id: delegate id: delegate
monitorID: m_monitorID monitorID: m_monitorID
monitorName: m_name monitorName: m_name
appID: m_appID
height: m_availableGeometry.height height: m_availableGeometry.height
width: m_availableGeometry.width width: m_availableGeometry.width
x: m_availableGeometry.x x: m_availableGeometry.x
@ -154,9 +154,10 @@ Rectangle {
monitorManufacturer: m_manufacturer monitorManufacturer: m_manufacturer
monitorModel: m_model monitorModel: m_model
monitorSize: m_availableGeometry monitorSize: m_availableGeometry
fontSize: rect.fontSize fontSize: root.fontSize
index: m_number index: m_number
previewImage: m_previewImage previewImage: m_previewImage
installedType: m_installedType
onMonitorSelected: { onMonitorSelected: {
@ -169,7 +170,7 @@ Rectangle {
getActiveMonitors() getActiveMonitors()
requestProjectSettings(index) root.requestProjectSettings(delegate.index, delegate.installedType, delegate.appID)
} }
} }
} }

View File

@ -12,6 +12,10 @@ Item {
property string monitorName property string monitorName
property string monitorID property string monitorID
property string previewImage: "" property string previewImage: ""
property string appID
property var installedType
onPreviewImageChanged: { onPreviewImageChanged: {
if (previewImage === "") { if (previewImage === "") {
imgPreview.opacity = 0 imgPreview.opacity = 0

View File

@ -5,6 +5,7 @@ import QtQuick.Controls.Material 2.2
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import ScreenPlay 1.0 import ScreenPlay 1.0
import ScreenPlay.Enums.InstalledType 1.0 import ScreenPlay.Enums.InstalledType 1.0
import "../Common/" as SP import "../Common/" as SP
@ -89,15 +90,28 @@ Item {
} }
availableWidth: width - 20 availableWidth: width - 20
availableHeight: 150 availableHeight: 150
onRequestProjectSettings: { onRequestProjectSettings: {
ScreenPlay.screenPlayManager.requestProjectSettingsAtMonitorIndex( if (installedType === InstalledType.VideoWallpaper) {
at) videoControlWrapper.state = "visible"
activeMonitorIndex = at customPropertiesGridView.visible = false
print(appID)
const wallpaper = ScreenPlay.screenPlayManager.getWallpaperByAppID(appID)
print("volume", wallpaper.volume)
} else {
videoControlWrapper.state = "hidden"
customPropertiesGridView.visible = true
ScreenPlay.screenPlayManager.requestProjectSettingsAtMonitorIndex(
index)
}
activeMonitorIndex = index
} }
Connections { Connections {
target: ScreenPlay.screenPlayManager target: ScreenPlay.screenPlayManager
function onProjectSettingsListModelResult(listModel) { function onProjectSettingsListModelResult(listModel) {
customPropertiesGridView.model = listModel customPropertiesGridView.projectSettingsListmodelRef = listModel
} }
} }
} }
@ -165,6 +179,14 @@ Item {
left: itmLeftWrapper.right left: itmLeftWrapper.right
} }
DefaultVideoControls {
id: videoControlWrapper
activeMonitorIndex: monitors.activeMonitorIndex
state: "hidden"
anchors.fill: parent
anchors.margins: 10
}
GridView { GridView {
id: customPropertiesGridView id: customPropertiesGridView
boundsBehavior: Flickable.DragOverBounds boundsBehavior: Flickable.DragOverBounds
@ -176,6 +198,9 @@ Item {
clip: true clip: true
anchors.fill: parent anchors.fill: parent
anchors.margins: 10 anchors.margins: 10
visible: false
model: customPropertiesGridView.projectSettingsListmodelRef
property var projectSettingsListmodelRef
delegate: MonitorsProjectSettingItem { delegate: MonitorsProjectSettingItem {
id: delegate id: delegate
@ -184,6 +209,8 @@ Item {
name: m_name name: m_name
isHeadline: m_isHeadline isHeadline: m_isHeadline
value: m_value value: m_value
itemIndex: index
projectSettingsListmodelRef: customPropertiesGridView.projectSettingsListmodelRef
} }
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {

View File

@ -15,6 +15,8 @@ Item {
property string name property string name
property var value property var value
property bool isHeadline property bool isHeadline
property int itemIndex
property var projectSettingsListmodelRef
Text { Text {
id: txtDescription id: txtDescription
@ -42,38 +44,44 @@ Item {
right: parent.right right: parent.right
} }
Component.onCompleted: { Loader {
if (root.value.toString() === "") { id: loader
return anchors.fill: parent
} anchors.rightMargin: 10
Connections {
target: loader.item
function onSave(value) {
projectSettingsListmodelRef.setValueAtIndex(root.itemIndex,
name, value)
}
}
}
Component.onCompleted: {
if (root.isHeadline) if (root.isHeadline)
return return
switch (root.value["type"]) {
case "slider":
loader.sourceComponent = compSlider
loader.item.from = root.value["from"]
loader.item.to = root.value["to"]
loader.item.value = root.value["value"]
loader.item.stepSize = root.value["stepSize"]
break
case "bool":
loader.sourceComponent = compCheckbox
loader.item.value = root.value["value"]
break
case "color":
loader.sourceComponent = compColorpicker
loader.item.value = root.value["value"]
break
}
for (let item in root.value) { if (root.value["text"]) {
// print(item.toString()) txtDescription.text = root.value["text"]
switch (item["type"]) {
case "slider":
loader.sourceComponent = compSlider
loader.item.from = obj["from"]
loader.item.to = obj["to"]
loader.item.value = obj["value"]
loader.item.stepSize = obj["stepSize"]
break
case "bool":
loader.sourceComponent = compCheckbox
loader.item.value = obj["value"]
break
case "color":
loader.sourceComponent = compColorpicker
loader.item.value = obj["value"]
break
}
if (item["text"]) {
txtDescription.text = obj["text"]
}
} }
} }
@ -94,6 +102,13 @@ Item {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
onCheckedChanged: { onCheckedChanged: {
let obj = {
"value": checkbox.checked,
"type": "checkBox",
}
root.save(obj)
ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex( ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex(
selectedMonitor, name, checkbox.checked) selectedMonitor, name, checkbox.checked)
} }
@ -109,6 +124,8 @@ Item {
anchors.fill: parent anchors.fill: parent
property color value property color value
signal save(var value)
Button { Button {
id: btnSetColor id: btnSetColor
text: qsTr("Set color") text: qsTr("Set color")
@ -138,6 +155,15 @@ Item {
onAccepted: { onAccepted: {
rctPreviewColor.color = colorDialog.color rctPreviewColor.color = colorDialog.color
let tmpColor = "'" + colorDialog.color.toString() + "'" let tmpColor = "'" + colorDialog.color.toString() + "'"
let obj = {
"value": colorDialog.color,
"type": "color",
}
root.save(obj)
ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex( ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex(
selectedMonitor, name, tmpColor) selectedMonitor, name, tmpColor)
} }
@ -156,6 +182,8 @@ Item {
property int value property int value
property int stepSize property int stepSize
signal save(var value)
Slider { Slider {
id: slider id: slider
from: root.from from: root.from
@ -175,6 +203,17 @@ Item {
onValueChanged: { onValueChanged: {
var value = Math.round(slider.value * 100) / 100 var value = Math.round(slider.value * 100) / 100
txtSliderValue.text = value txtSliderValue.text = value
let obj = {
"from": root.from,
"to": root.to,
"value": value,
"type": "slider",
"stepSize": root.stepSize
}
root.save(obj)
ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex( ScreenPlay.screenPlayManager.setWallpaperValueAtMonitorIndex(
selectedMonitor, name, value) selectedMonitor, name, value)
} }
@ -191,12 +230,6 @@ Item {
} }
} }
} }
Loader {
id: loader
anchors.fill: parent
anchors.rightMargin: 10
}
} }
} }

View File

@ -47,11 +47,11 @@ QHash<int, QByteArray> MonitorListModel::roleNames() const
{ static_cast<int>(MonitorRole::Model), "m_model" }, { static_cast<int>(MonitorRole::Model), "m_model" },
{ static_cast<int>(MonitorRole::Manufacturer), "m_manufacturer" }, { static_cast<int>(MonitorRole::Manufacturer), "m_manufacturer" },
{ static_cast<int>(MonitorRole::PreviewImage), "m_previewImage" }, { static_cast<int>(MonitorRole::PreviewImage), "m_previewImage" },
{ static_cast<int>(MonitorRole::InstalledType), "m_installedType" },
}; };
return roles; return roles;
} }
/*! /*!
\brief Returns the amount of active monitors. \brief Returns the amount of active monitors.
*/ */
@ -78,7 +78,6 @@ QVariant MonitorListModel::data(const QModelIndex& index, int role) const
auto roleEnum = static_cast<MonitorRole>(role); auto roleEnum = static_cast<MonitorRole>(role);
if (row < rowCount()) if (row < rowCount())
switch (roleEnum) { switch (roleEnum) {
case MonitorRole::AppID: case MonitorRole::AppID:
@ -113,10 +112,16 @@ QVariant MonitorListModel::data(const QModelIndex& index, int role) const
return m_monitorList.at(row).m_screen->model(); return m_monitorList.at(row).m_screen->model();
case MonitorRole::Manufacturer: case MonitorRole::Manufacturer:
return m_monitorList.at(row).m_screen->manufacturer(); return m_monitorList.at(row).m_screen->manufacturer();
case MonitorRole::InstalledType:
if (m_monitorList.at(row).m_activeWallpaper) {
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) { if (m_monitorList.at(row).m_activeWallpaper) {
QString absolutePath = m_monitorList.at(row).m_activeWallpaper->absolutePath(); QString absolutePath = m_monitorList.at(row).m_activeWallpaper->absolutePath();
return absolutePath + "/" + m_monitorList.at(row).m_activeWallpaper->previewImage(); return absolutePath + "/" + m_monitorList.at(row).m_activeWallpaper->previewImage();
} else { } else {
return QVariant(""); return QVariant("");
} }
@ -176,6 +181,7 @@ void MonitorListModel::clearActiveWallpaper()
index(i, 0), index(i, 0),
QVector<int> { QVector<int> {
static_cast<int>(MonitorRole::PreviewImage), static_cast<int>(MonitorRole::PreviewImage),
static_cast<int>(MonitorRole::InstalledType),
static_cast<int>(MonitorRole::AppID) }); static_cast<int>(MonitorRole::AppID) });
++i; ++i;
} }
@ -196,6 +202,7 @@ void MonitorListModel::closeWallpaper(const QString& appID)
index(i, 0), index(i, 0),
QVector<int> { QVector<int> {
static_cast<int>(MonitorRole::PreviewImage), static_cast<int>(MonitorRole::PreviewImage),
static_cast<int>(MonitorRole::InstalledType),
static_cast<int>(MonitorRole::AppID) }); static_cast<int>(MonitorRole::AppID) });
} }
} }
@ -203,6 +210,16 @@ void MonitorListModel::closeWallpaper(const QString& appID)
} }
} }
/*!
* \brief MonitorListModel::getAbsoluteDesktopSize
* \return
*/
QRect MonitorListModel::getAbsoluteDesktopSize() const
{
auto* app = static_cast<QApplication*>(QApplication::instance());
return app->screens().at(0)->availableVirtualGeometry();
}
/*! /*!
\brief Sets the previewImage and appID for a list item. \brief Sets the previewImage and appID for a list item.
*/ */
@ -217,6 +234,7 @@ void MonitorListModel::setWallpaperActiveMonitor(const std::shared_ptr<ScreenPla
index(monitor, 0), index(monitor, 0),
QVector<int> { QVector<int> {
static_cast<int>(MonitorRole::PreviewImage), static_cast<int>(MonitorRole::PreviewImage),
static_cast<int>(MonitorRole::InstalledType),
static_cast<int>(MonitorRole::AppID) }); static_cast<int>(MonitorRole::AppID) });
} }
} }

View File

@ -79,11 +79,6 @@ class MonitorListModel : public QAbstractListModel {
public: public:
explicit MonitorListModel(QObject* parent = nullptr); explicit MonitorListModel(QObject* parent = nullptr);
~MonitorListModel() override
{
m_monitorList.clear();
}
enum class MonitorRole { enum class MonitorRole {
AppID = Qt::UserRole, AppID = Qt::UserRole,
MonitorID, MonitorID,
@ -96,6 +91,7 @@ public:
Model, Model,
Manufacturer, Manufacturer,
PreviewImage, PreviewImage,
InstalledType,
}; };
Q_ENUM(MonitorRole) Q_ENUM(MonitorRole)
@ -103,18 +99,11 @@ 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 setWallpaperActiveMonitor( void setWallpaperActiveMonitor(const std::shared_ptr<ScreenPlayWallpaper>& wallpaper,
const std::shared_ptr<ScreenPlayWallpaper>& wallpaper,
const QVector<int> monitors); const QVector<int> monitors);
std::optional<QString> getAppIDByMonitorIndex(const int index) const; std::optional<QString> getAppIDByMonitorIndex(const int index) const;
QRect getAbsoluteDesktopSize() const
{
auto* app = static_cast<QApplication*>(QApplication::instance());
return app->screens().at(0)->availableVirtualGeometry();
}
signals: signals:
void monitorReloadCompleted(); void monitorReloadCompleted();
void setNewActiveMonitor(int index, QString path); void setNewActiveMonitor(int index, QString path);
@ -124,6 +113,7 @@ public slots:
void reset(); void reset();
void clearActiveWallpaper(); void clearActiveWallpaper();
void closeWallpaper(const QString& appID); void closeWallpaper(const QString& appID);
QRect getAbsoluteDesktopSize() const;
void screenAdded(QScreen* screen) void screenAdded(QScreen* screen)
{ {

View File

@ -42,6 +42,8 @@
#include <QUrl> #include <QUrl>
#include <QVariant> #include <QVariant>
#include <memory>
namespace ScreenPlay { namespace ScreenPlay {
/*! /*!
@ -53,106 +55,76 @@ namespace ScreenPlay {
*/ */
struct IListItem { struct IListItem {
//MOC complains otherwise WTF Q_GADGET
bool operator!=(const IListItem& val) public:
{ QVariant m_value;
return true; virtual QJsonObject getItemSettings() = 0;
} public slots:
virtual void setData(const QJsonObject& obj){}
}; };
struct SliderItem : public IListItem { struct SliderItem : public IListItem {
Q_GADGET Q_GADGET
Q_PROPERTY(double from MEMBER m_from) Q_PROPERTY(double from MEMBER m_from)
Q_PROPERTY(double to MEMBER m_to) Q_PROPERTY(double to MEMBER m_to)
Q_PROPERTY(double stepSize MEMBER m_stepSize) Q_PROPERTY(double stepSize MEMBER m_stepSize)
Q_PROPERTY(double value MEMBER m_value) Q_PROPERTY(double value MEMBER m_value)
public: public:
double m_from = { 0.0 }; double m_from = { 0.0 };
double m_value = { 0.0 };
double m_to = { 0.1 }; double m_to = { 0.1 };
double m_stepSize = { 0.1 }; double m_stepSize = { 0.1 };
double m_value = { 0.0 }; QJsonObject getItemSettings() override;
public slots:
void setData(const QJsonObject& obj) override;
}; };
struct ColorItem : public IListItem { struct ColorItem : public IListItem {
Q_GADGET Q_GADGET
Q_PROPERTY(QColor color MEMBER m_color) Q_PROPERTY(QColor color MEMBER m_color)
public: public:
QJsonObject getItemSettings() override;
QColor m_color = { QColor::fromRgb(0, 0, 0) }; QColor m_color = { QColor::fromRgb(0, 0, 0) };
public slots:
void setData(const QJsonObject& obj) override;
}; };
struct CheckBoxItem : public IListItem { struct CheckBoxItem : public IListItem {
Q_GADGET Q_GADGET
Q_PROPERTY(bool value MEMBER m_value) Q_PROPERTY(bool checked MEMBER m_checked)
public: public:
bool m_value = { false }; QJsonObject getItemSettings() override;
bool m_checked = { false };
public slots:
void setData(const QJsonObject& obj) override;
}; };
struct FileItem : public IListItem { struct FileItem : public IListItem {
Q_GADGET Q_GADGET
Q_PROPERTY(QUrl file MEMBER m_file) Q_PROPERTY(QUrl file MEMBER m_file)
Q_PROPERTY(QString formats MEMBER m_formats)
public: public:
QJsonObject getItemSettings() override;
QUrl m_file = {}; QUrl m_file = {};
QString m_formats = {};
public slots:
void setData(const QJsonObject& obj) override;
}; };
struct ProjectSettingsListItem { struct ProjectSettingsListItem {
Q_GADGET Q_GADGET
Q_PROPERTY(IListItem item MEMBER m_item)
public: public:
ProjectSettingsListItem( ProjectSettingsListItem(
const QString& headline) const QString& headline);
{
m_isHeadline = true;
m_key = headline;
}
ProjectSettingsListItem( ProjectSettingsListItem(
const QString& key, const QString& key,
const QJsonObject& obj) const QJsonObject& obj);
{
m_isHeadline = false;
m_key = key;
QString type = obj.value("type").toString();
qInfo() << type;
if (type == "slider") {
SliderItem item;
item.m_from = obj.value("from").toDouble(0);
item.m_to = obj.value("to").toDouble(1);
item.m_stepSize = obj.value("stepSize").toDouble(0.1);
item.m_value = obj.value("value").toDouble(1);
m_item = item;
return;
}
if (type == "file") {
FileItem item;
item.m_file = obj.value("file").toString();
m_item = item;
return;
}
if (type == "color") {
ColorItem item;
item.m_color = { obj.value("file").toString() };
m_item = item;
return;
}
if (type == "bool") {
CheckBoxItem item;
m_item = item;
return;
}
}
QString m_key; QString m_key;
bool m_isHeadline { false }; bool m_isHeadline { false };
QVariant m_value; std::shared_ptr<IListItem> m_item;
IListItem m_item;
QVariant value() const
{
return m_value;
}
}; };
} }

View File

@ -36,41 +36,115 @@ namespace ScreenPlay {
/*! /*!
Constructor when loading properties from settings.json Constructor when loading properties from settings.json
We need to _flatten_ the json to make it work with a flat list model!
See \sa getActiveSettingsJson to make the flat list to a hierarchical json object
*/ */
void ProjectSettingsListModel::init(const InstalledType::InstalledType& type, const QJsonObject& properties) void ProjectSettingsListModel::init(const InstalledType::InstalledType& type, const QJsonObject& properties)
{ {
if (type == InstalledType::InstalledType::VideoWallpaper) {
// beginInsertRows(QModelIndex(), m_projectSettings.size(), m_projectSettings.size());
// m_projectSettings.append("General"); for (QJsonObject::const_iterator itParent = properties.begin(); itParent != properties.end(); itParent++) {
// if (properties.contains("volume")) // The first object is always a category
// append({"slider", properties.value("volume")}=; const QJsonObject category = properties.value(itParent.key()).toObject();
// if (properties.contains("playbackRate")) append(SettingsItem { itParent.key() });
// append("slider", properties.value("playbackRate").toObject());
// endInsertRows();
} else { // Children of this category
for (QJsonObject::const_iterator itParent = properties.begin(); itParent != properties.end(); itParent++) { for (QJsonObject::const_iterator itChild = category.begin(); itChild != category.end(); itChild++) {
const QJsonObject child = category.value(itChild.key()).toObject();
// The first object is always a category append(SettingsItem { itChild.key(), child });
const QJsonObject category = properties.value(itParent.key()).toObject();
beginInsertRows(QModelIndex(), m_projectSettings.size(), m_projectSettings.size());
m_projectSettings.append(ProjectSettingsListItem { itParent.key() });
endInsertRows();
// Children of this category
for (QJsonObject::const_iterator itChild = category.begin(); itChild != category.end(); itChild++) {
qInfo() << itChild.key() << itChild.value();
beginInsertRows(QModelIndex(), m_projectSettings.size(), m_projectSettings.size());
m_projectSettings.append(ProjectSettingsListItem {itChild.key(), itChild.value().toObject() });
endInsertRows();
}
} }
} }
} }
/*!
* \brief ProjectSettingsListModel::getActiveSettingsJson
* \return
*/
QJsonObject ProjectSettingsListModel::getActiveSettingsJson()
{
if (m_projectSettings.isEmpty()) {
qWarning() << "Trying to read empty projectSettings. Abort!";
return {};
}
// This creates a hierarchical json from the flat list model:
// Category 1 // <- this is a headline item
// emitRate:
// "from": 0,
// "stepSize": 1,
// "to": 2500,
// "type": "slider",
// "value": 25
// Category 2
// property 1
// ...
QString currentCategory;
QJsonObject ret;
std::unique_ptr<QJsonObject> properties = std::make_unique<QJsonObject>();
for (auto& item : m_projectSettings) {
if (item.m_isHeadline) {
// It is empty the first time
if (!properties->isEmpty()) {
// We only write the current category right _before_
// we start with the next one. This way we need to save
// the last category below!
ret.insert(currentCategory, *properties);
}
currentCategory = item.m_name;
properties = std::make_unique<QJsonObject>();
} else {
properties->insert(item.m_name, item.m_value);
}
// Because the last item is never a headline,
// we need to add the last category here because
if (&item == &m_projectSettings.last()) {
ret.insert(currentCategory, *properties);
}
}
return ret;
}
void ProjectSettingsListModel::append(const SettingsItem&& item)
{
beginInsertRows(QModelIndex(), m_projectSettings.size(), m_projectSettings.size());
m_projectSettings.append(item);
endInsertRows();
}
void ProjectSettingsListModel::setValueAtIndex(const int row, const QString& key, const QJsonObject& value)
{
if (row >= m_projectSettings.size() || row < 0) {
qWarning() << "Cannot setValueAtIndex when index is out of bounce! Row: " << row << ", m_projectSettings size: " << m_projectSettings.size();
return;
}
if (m_projectSettings.at(row).m_isHeadline) {
qWarning() << "Cannot set settings item from type headline!";
return;
}
if (m_projectSettings.at(row).m_name != key) {
qWarning() << "Name of the element does not match current settings";
return;
}
m_projectSettings.replace(row, SettingsItem { key, value });
QVector<int> roles = { ValueRole };
emit dataChanged(index(row, 0), index(row, 0), roles);
}
int ProjectSettingsListModel::rowCount(const QModelIndex& parent) const int ProjectSettingsListModel::rowCount(const QModelIndex& parent) const
{ {
// For list models only the root node (an invalid parent) should return the list's size. For all // For list models only the root node (an invalid parent) should return the list's size. For all
@ -91,7 +165,7 @@ QVariant ProjectSettingsListModel::data(const QModelIndex& index, int role) cons
if (index.row() < rowCount()) if (index.row() < rowCount())
switch (role) { switch (role) {
case NameRole: case NameRole:
return m_projectSettings.at(rowIndex).m_key; return m_projectSettings.at(rowIndex).m_name;
case IsHeadlineRole: case IsHeadlineRole:
return m_projectSettings.at(rowIndex).m_isHeadline; return m_projectSettings.at(rowIndex).m_isHeadline;
case ValueRole: case ValueRole:
@ -114,26 +188,4 @@ QHash<int, QByteArray> ProjectSettingsListModel::roleNames() const
return roles; return roles;
} }
QJsonObject ProjectSettingsListModel::getActiveSettingsJson()
{
if (m_projectSettings.isEmpty()) {
qWarning() << "Trying to read emppty projectSettings. Abort!";
return {};
}
QJsonObject obj;
for (const auto& itemCategory : m_projectSettings) {
QJsonObject category;
if (itemCategory.m_isHeadline) {
for (const auto& itemProperties : m_projectSettings) {
if (itemProperties.m_isHeadline)
continue;
category.insert(itemProperties.m_key, QJsonValue::fromVariant(itemProperties.m_value));
}
obj.insert(itemCategory.m_key, category);
}
}
return obj;
}
} }

View File

@ -43,11 +43,38 @@
#include <QJsonObject> #include <QJsonObject>
#include <QVector> #include <QVector>
#include "projectsettingslistitem.h"
#include "util.h" #include "util.h"
namespace ScreenPlay { namespace ScreenPlay {
struct SettingsItem {
SettingsItem(
const QString& name,
const QJsonObject& value)
{
m_name = name;
m_isHeadline = false;
m_value = value;
}
SettingsItem(
const QString& name)
{
m_name = name;
m_isHeadline = true;
}
QString m_name;
bool m_isHeadline;
QJsonObject m_value;
QString m_type;
public:
void SettingsItem::setValue(const QJsonObject& value)
{
m_value = value;
}
};
class ProjectSettingsListModel : public QAbstractListModel { class ProjectSettingsListModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
@ -65,8 +92,12 @@ public:
QJsonObject getActiveSettingsJson(); QJsonObject getActiveSettingsJson();
void init(const InstalledType::InstalledType& type, const QJsonObject& properties); void init(const InstalledType::InstalledType& type, const QJsonObject& properties);
void append(const SettingsItem&& item);
public slots:
void setValueAtIndex(const int row, const QString& key, const QJsonObject& value);
private: private:
QVector<ProjectSettingsListItem> m_projectSettings; QVector<SettingsItem> m_projectSettings;
}; };
} }

View File

@ -85,14 +85,16 @@ void ScreenPlayManager::init(
a \a fillMode, a \a type (htmlWallpaper, qmlWallpaper etc.), a \a saveToProfilesConfigFile bool only set to flase a \a fillMode, a \a type (htmlWallpaper, qmlWallpaper etc.), a \a saveToProfilesConfigFile bool only set to flase
if we call the method when using via the settings on startup to skip a unnecessary save. if we call the method when using via the settings on startup to skip a unnecessary save.
*/ */
void ScreenPlayManager::createWallpaper(const InstalledType::InstalledType type, void ScreenPlayManager::createWallpaper(
const InstalledType::InstalledType type,
const FillMode::FillMode fillMode, const FillMode::FillMode fillMode,
const QString& absoluteStoragePath, const QString& absoluteStoragePath,
const QString& previewImage, const QString& previewImage,
const QString& file, const QString& file,
const QVector<int>& monitorIndex, const QVector<int>& monitorIndex,
const float volume, const float volume,
const float playbackRate, const QJsonObject& properties, const float playbackRate,
const QJsonObject& properties,
const bool saveToProfilesConfigFile) const bool saveToProfilesConfigFile)
{ {
auto saveToProfile = qScopeGuard([=, this] { auto saveToProfile = qScopeGuard([=, this] {
@ -160,7 +162,8 @@ void ScreenPlayManager::createWallpaper(const InstalledType::InstalledType type,
/*! /*!
\brief Creates a ScreenPlayWidget object via a \a absoluteStoragePath and a \a preview image (relative path). \brief Creates a ScreenPlayWidget object via a \a absoluteStoragePath and a \a preview image (relative path).
*/ */
void ScreenPlayManager::createWidget(const InstalledType::InstalledType type, void ScreenPlayManager::createWidget(
const InstalledType::InstalledType type,
const QPoint& position, const QPoint& position,
const QString& absoluteStoragePath, const QString& absoluteStoragePath,
const QString& previewImage, const QString& previewImage,
@ -178,7 +181,7 @@ void ScreenPlayManager::createWidget(const InstalledType::InstalledType type,
const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile(); const QString path = QUrl::fromUserInput(absoluteStoragePath).toLocalFile();
if (path.isEmpty()) { if (path.isEmpty()) {
qInfo() << "Path is empty, Abort! String: " << absoluteStoragePath; qWarning() << "Path is empty, Abort! String: " << absoluteStoragePath;
return; return;
} }
@ -198,14 +201,14 @@ void ScreenPlayManager::createWidget(const InstalledType::InstalledType type,
void ScreenPlayManager::appConnected(const std::shared_ptr<SDKConnection>& connection) void ScreenPlayManager::appConnected(const std::shared_ptr<SDKConnection>& connection)
{ {
for (const auto& item : m_screenPlayWidgets) { for (const auto& item : qAsConst(m_screenPlayWidgets)) {
if (item->appID() == connection->appID()) { if (item->appID() == connection->appID()) {
item->setSDKConnection(connection); item->setSDKConnection(connection);
return; return;
} }
} }
for (const auto& item : m_screenPlayWallpapers) { for (const auto& item : qAsConst(m_screenPlayWallpapers)) {
if (item->appID() == connection->appID()) { if (item->appID() == connection->appID()) {
item->setSDKConnection(connection); item->setSDKConnection(connection);
return; return;
@ -313,11 +316,9 @@ void ScreenPlayManager::requestProjectSettingsAtMonitorIndex(const int index)
void ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value) void ScreenPlayManager::setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value)
{ {
if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) { if (auto appID = m_monitorListModel->getAppIDByMonitorIndex(index)) {
setWallpaperValue(*appID, key, value); setWallpaperValue(*appID, key, value);
} else {
if (auto wallpaper = getWallpaperByAppID(*appID)) { qWarning() << "Could net get appID from m_monitorListModel!";
}
} }
} }
@ -334,14 +335,14 @@ void ScreenPlayManager::setAllWallpaperValue(const QString& key, const QString&
/*! /*!
\brief Returns \c a ScreenPlayWallpaper if successful, otherwhise \c std::nullopt. \brief Returns \c a ScreenPlayWallpaper if successful, otherwhise \c std::nullopt.
*/ */
std::optional<std::shared_ptr<ScreenPlayWallpaper>> ScreenPlayManager::getWallpaperByAppID(const QString& appID) ScreenPlayWallpaper* ScreenPlayManager::getWallpaperByAppID(const QString& appID) const
{ {
for (auto& wallpaper : m_screenPlayWallpapers) { for (auto& wallpaper : m_screenPlayWallpapers) {
if (wallpaper->appID() == appID) { if (wallpaper->appID() == appID) {
return wallpaper; return wallpaper.get();
} }
} }
return std::nullopt; return nullptr;
} }
/*! /*!
@ -426,7 +427,7 @@ bool ScreenPlayManager::closeWallpaper(const QString& appID)
*/ */
void ScreenPlayManager::setWallpaperValue(const QString& appID, const QString& key, const QVariant& value) void ScreenPlayManager::setWallpaperValue(const QString& appID, const QString& key, const QVariant& value)
{ {
for (const auto& wallpaper : m_screenPlayWallpapers) { for (const auto& wallpaper : qAsConst(m_screenPlayWallpapers)) {
if (wallpaper->appID() == appID) { if (wallpaper->appID() == appID) {
wallpaper->setWallpaperValue(key, value, true); wallpaper->setWallpaperValue(key, value, true);
} }
@ -442,12 +443,12 @@ void ScreenPlayManager::saveProfiles()
m_saveLimiter.stop(); m_saveLimiter.stop();
qInfo() << "Save profiles!"; qInfo() << "Save profiles!";
QJsonArray wallpaper {}; QJsonArray wallpaper {};
for (const auto& activeWallpaper : m_screenPlayWallpapers) { for (const auto& activeWallpaper : qAsConst(m_screenPlayWallpapers)) {
wallpaper.append(activeWallpaper->getActiveSettingsJson()); wallpaper.append(activeWallpaper->getActiveSettingsJson());
} }
QJsonArray widgets {}; QJsonArray widgets {};
for (const auto& activeWidget : m_screenPlayWidgets) { for (const auto& activeWidget : qAsConst(m_screenPlayWidgets)) {
widgets.append(activeWidget->getActiveSettingsJson()); widgets.append(activeWidget->getActiveSettingsJson());
} }

View File

@ -125,7 +125,7 @@ public slots:
void requestProjectSettingsAtMonitorIndex(const int index); void requestProjectSettingsAtMonitorIndex(const int index);
void setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value); void setWallpaperValueAtMonitorIndex(const int index, const QString& key, const QString& value);
void setAllWallpaperValue(const QString& key, const QString& value); void setAllWallpaperValue(const QString& key, const QString& value);
std::optional<std::shared_ptr<ScreenPlayWallpaper>> getWallpaperByAppID(const QString& appID); ScreenPlayWallpaper* getWallpaperByAppID(const QString& appID) const;
void newConnection(); void newConnection();
void closeAllWallpapers(); void closeAllWallpapers();

View File

@ -13,6 +13,8 @@ namespace ScreenPlay {
/*! /*!
\brief Constructor for video Wallpaper. \brief Constructor for video Wallpaper.
*/ */
ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber, ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
const std::shared_ptr<GlobalVariables>& globalVariables, const std::shared_ptr<GlobalVariables>& globalVariables,
const QString& appID, const QString& appID,
@ -88,7 +90,6 @@ ScreenPlayWallpaper::ScreenPlayWallpaper(const QVector<int>& screenNumber,
// Fixes issue 84 media key overlay // Fixes issue 84 media key overlay
" --disable-features=HardwareMediaKeyHandling" " --disable-features=HardwareMediaKeyHandling"
}; };
qInfo() << proArgs;
m_process.setArguments(proArgs); m_process.setArguments(proArgs);
m_process.setProgram(m_globalVariables->wallpaperExecutablePath().toString()); m_process.setProgram(m_globalVariables->wallpaperExecutablePath().toString());
@ -110,7 +111,7 @@ QJsonObject ScreenPlayWallpaper::getActiveSettingsJson()
obj.insert("volume", m_volume); obj.insert("volume", m_volume);
obj.insert("playbackRate", m_playbackRate); obj.insert("playbackRate", m_playbackRate);
} else { } else {
auto properties = m_projectSettingsListModel.getActiveSettingsJson(); QJsonObject properties = m_projectSettingsListModel.getActiveSettingsJson();
if (!properties.isEmpty()) if (!properties.isEmpty())
obj.insert("properties", properties); obj.insert("properties", properties);
} }
@ -156,7 +157,7 @@ void ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QVariant&
} }
m_connection->sendMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact)); m_connection->sendMessage(QJsonDocument(obj).toJson(QJsonDocument::Compact));
qInfo() << "save" << save;
if (save) if (save)
emit requestSave(); emit requestSave();
} }
@ -164,8 +165,6 @@ void ScreenPlayWallpaper::setWallpaperValue(const QString& key, const QVariant&
void ScreenPlayWallpaper::setSDKConnection(const std::shared_ptr<SDKConnection>& connection) void ScreenPlayWallpaper::setSDKConnection(const std::shared_ptr<SDKConnection>& connection)
{ {
m_connection = connection; m_connection = connection;
qInfo() << "App Wallpaper connected!";
qInfo() << playbackRate() << (playbackRate() != 1.0);
QTimer::singleShot(500, [this]() { QTimer::singleShot(500, [this]() {
if (playbackRate() != 1.0) { if (playbackRate() != 1.0) {
setWallpaperValue("playbackRate", playbackRate(), false); setWallpaperValue("playbackRate", playbackRate(), false);

View File

@ -67,6 +67,7 @@ class ScreenPlayWallpaper : public QObject {
Q_PROPERTY(InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged) Q_PROPERTY(InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged)
public: public:
ScreenPlayWallpaper(){}
explicit ScreenPlayWallpaper(const QVector<int>& screenNumber, explicit ScreenPlayWallpaper(const QVector<int>& screenNumber,
const std::shared_ptr<GlobalVariables>& globalVariables, const std::shared_ptr<GlobalVariables>& globalVariables,
const QString& appID, const QString& appID,
@ -259,7 +260,7 @@ public slots:
} }
private: private:
const std::shared_ptr<GlobalVariables>& m_globalVariables; const std::shared_ptr<GlobalVariables> m_globalVariables;
std::shared_ptr<SDKConnection> m_connection; std::shared_ptr<SDKConnection> m_connection;
ProjectSettingsListModel m_projectSettingsListModel; ProjectSettingsListModel m_projectSettingsListModel;

View File

@ -96,14 +96,14 @@ public:
void setSDKConnection(const std::shared_ptr<SDKConnection>& connection); void setSDKConnection(const std::shared_ptr<SDKConnection>& connection);
public slots:
QJsonObject getActiveSettingsJson();
ProjectSettingsListModel* getProjectSettingsListModel() ProjectSettingsListModel* getProjectSettingsListModel()
{ {
return &m_projectSettingsListModel; return &m_projectSettingsListModel;
} }
public slots:
QJsonObject getActiveSettingsJson();
void setPreviewImage(QString previewImage) void setPreviewImage(QString previewImage)
{ {
if (m_previewImage == previewImage) if (m_previewImage == previewImage)