obs-studio/patches/8051.patch

284 lines
9.7 KiB
Diff
Raw Normal View History

2024-02-25 20:22:58 +01:00
From 01f0cab97d222f5cd4d7468f730370e76f08b42a Mon Sep 17 00:00:00 2001
From: CodeYan01 <65320293+CodeYan01@users.noreply.github.com>
Date: Thu, 12 Jan 2023 01:01:14 +0800
Subject: [PATCH] UI: Refactor editable list modification
Previously would unnecessarily recreating the data array for every
modification (adding/removing/reordering/editing). This clears the
fields in the associated data array that other code/scripts would add,
such as an ID field for each item that could be used to distinguish
each item from their duplicates in the list.
I initially wanted to remove EditableListChanged, but it no longer saved
the item selection whenever the list is modified, so I kept the function
and just changed it to update the selected state in the data array.
---
UI/properties-view.cpp | 97 +++++++++++++++++++++++++++++++++++++-----
UI/properties-view.hpp | 6 +++
2 files changed, 93 insertions(+), 10 deletions(-)
diff --git a/UI/properties-view.cpp b/UI/properties-view.cpp
index 7d8838b3603a2..025b104d0db27 100644
--- a/UI/properties-view.cpp
+++ b/UI/properties-view.cpp
@@ -709,6 +709,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
{
const char *name = obs_property_name(prop);
OBSDataArrayAutoRelease array = obs_data_get_array(settings, name);
+ if (array == NULL) {
+ array = obs_data_array_create();
+ obs_data_set_array(settings, name, array);
+ }
+
QListWidget *list = new QListWidget();
size_t count = obs_data_array_count(array);
@@ -731,8 +736,8 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
WidgetInfo *info = new WidgetInfo(this, prop, list);
list->setDragDropMode(QAbstractItemView::InternalMove);
- connect(list->model(), &QAbstractItemModel::rowsMoved,
- [info]() { info->EditableListChanged(); });
+ connect(list->model(), &QAbstractItemModel::rowsMoved, info,
+ &WidgetInfo::EditListReordered);
QVBoxLayout *sideLayout = new QVBoxLayout();
NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
@@ -1992,24 +1997,52 @@ void WidgetInfo::GroupChanged(const char *setting)
: true);
}
+void WidgetInfo::EditListReordered(const QModelIndex &sourceParent,
+ int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent,
+ int destinationRow)
+{
+ UNUSED_PARAMETER(sourceParent);
+ UNUSED_PARAMETER(destinationParent);
+
+ const char *setting = obs_property_name(property);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
+
+ for (int i = sourceStart; i <= sourceEnd; i++) {
+ OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
+ obs_data_array_insert(array, destinationRow, arrayItem);
+ // if moved to top, destination row increases
+ obs_data_array_erase(array, (i > destinationRow) ? i + 1 : i);
+ ++destinationRow;
+ }
+ EditableListChanged();
+}
+
+void WidgetInfo::EditableListArrayPushBack(obs_data_array_t *array,
+ const char *text)
+{
+ OBSDataAutoRelease arrayItem = obs_data_create();
+ obs_data_set_string(arrayItem, "value", text);
+ obs_data_set_bool(arrayItem, "selected", false);
+ obs_data_set_bool(arrayItem, "hidden", false);
+ obs_data_array_push_back(array, arrayItem);
+}
+
void WidgetInfo::EditableListChanged()
{
const char *setting = obs_property_name(property);
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
- OBSDataArrayAutoRelease array = obs_data_array_create();
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
for (int i = 0; i < list->count(); i++) {
QListWidgetItem *item = list->item(i);
- OBSDataAutoRelease arrayItem = obs_data_create();
- obs_data_set_string(arrayItem, "value",
- QT_TO_UTF8(item->text()));
+ OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
obs_data_set_bool(arrayItem, "selected", item->isSelected());
obs_data_set_bool(arrayItem, "hidden", item->isHidden());
- obs_data_array_push_back(array, arrayItem);
}
- obs_data_set_array(view->settings, setting, array);
-
ControlChanged();
}
@@ -2263,6 +2296,9 @@ void WidgetInfo::EditListAddText()
{
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
const char *desc = obs_property_description(property);
+ const char *setting = obs_property_name(property);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
EditableItemDialog dialog(widget->window(), QString(), false);
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry")
@@ -2276,6 +2312,7 @@ void WidgetInfo::EditListAddText()
return;
list->addItem(text);
+ EditableListArrayPushBack(array, QT_TO_UTF8(text));
EditableListChanged();
}
@@ -2286,6 +2323,9 @@ void WidgetInfo::EditListAddFiles()
const char *filter = obs_property_editable_list_filter(property);
const char *default_path =
obs_property_editable_list_default_path(property);
+ const char *setting = obs_property_name(property);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
QString title = QTStr("Basic.PropertiesWindow.AddEditableListFiles")
.arg(QT_UTF8(desc));
@@ -2301,6 +2341,9 @@ void WidgetInfo::EditListAddFiles()
return;
list->addItems(files);
+ for (QString &file : files) {
+ EditableListArrayPushBack(array, QT_TO_UTF8(file));
+ }
EditableListChanged();
}
@@ -2310,6 +2353,9 @@ void WidgetInfo::EditListAddDir()
const char *desc = obs_property_description(property);
const char *default_path =
obs_property_editable_list_default_path(property);
+ const char *setting = obs_property_name(property);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
QString title = QTStr("Basic.PropertiesWindow.AddEditableListDir")
.arg(QT_UTF8(desc));
@@ -2325,6 +2371,7 @@ void WidgetInfo::EditListAddDir()
return;
list->addItem(dir);
+ EditableListArrayPushBack(array, QT_TO_UTF8(dir));
EditableListChanged();
}
@@ -2332,9 +2379,15 @@ void WidgetInfo::EditListRemove()
{
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
QList<QListWidgetItem *> items = list->selectedItems();
+ const char *setting = obs_property_name(property);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
- for (QListWidgetItem *item : items)
+ for (qsizetype i = items.size() - 1; i >= 0; i--) {
+ QListWidgetItem *item = items.at(i);
+ obs_data_array_erase(array, list->row(item));
delete item;
+ }
EditableListChanged();
}
@@ -2343,6 +2396,7 @@ void WidgetInfo::EditListEdit()
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
enum obs_editable_list_type type =
obs_property_editable_list_type(property);
+ const char *setting = obs_property_name(property);
const char *desc = obs_property_description(property);
const char *filter = obs_property_editable_list_filter(property);
QList<QListWidgetItem *> selectedItems = list->selectedItems();
@@ -2351,6 +2405,10 @@ void WidgetInfo::EditListEdit()
return;
QListWidgetItem *item = selectedItems[0];
+ int row = list->row(item);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
+ OBSDataAutoRelease arrayItem = obs_data_array_item(array, row);
if (type == OBS_EDITABLE_LIST_TYPE_FILES) {
QDir pathDir(item->text());
@@ -2367,6 +2425,7 @@ void WidgetInfo::EditListEdit()
return;
item->setText(path);
+ obs_data_set_string(arrayItem, "value", QT_TO_UTF8(path));
EditableListChanged();
return;
}
@@ -2385,6 +2444,7 @@ void WidgetInfo::EditListEdit()
return;
item->setText(text);
+ obs_data_set_string(arrayItem, "value", QT_TO_UTF8(text));
EditableListChanged();
}
@@ -2392,6 +2452,9 @@ void WidgetInfo::EditListUp()
{
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
int lastItemRow = -1;
+ const char *setting = obs_property_name(property);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
for (int i = 0; i < list->count(); i++) {
QListWidgetItem *item = list->item(i);
@@ -2405,6 +2468,11 @@ void WidgetInfo::EditListUp()
list->takeItem(row);
list->insertItem(lastItemRow, item);
item->setSelected(true);
+
+ OBSDataAutoRelease arrayItem =
+ obs_data_array_item(array, row);
+ obs_data_array_insert(array, lastItemRow, arrayItem);
+ obs_data_array_erase(array, row + 1);
} else {
lastItemRow = row;
}
@@ -2417,6 +2485,9 @@ void WidgetInfo::EditListDown()
{
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
int lastItemRow = list->count();
+ const char *setting = obs_property_name(property);
+ OBSDataArrayAutoRelease array =
+ obs_data_get_array(view->settings, setting);
for (int i = list->count() - 1; i >= 0; i--) {
QListWidgetItem *item = list->item(i);
@@ -2430,6 +2501,12 @@ void WidgetInfo::EditListDown()
list->takeItem(row);
list->insertItem(lastItemRow, item);
item->setSelected(true);
+
+ OBSDataAutoRelease arrayItem =
+ obs_data_array_item(array, row);
+ obs_data_array_insert(array, lastItemRow + 1,
+ arrayItem);
+ obs_data_array_erase(array, row);
} else {
lastItemRow = row;
}
diff --git a/UI/properties-view.hpp b/UI/properties-view.hpp
index e520dcdde2c90..89546b1317fba 100644
--- a/UI/properties-view.hpp
+++ b/UI/properties-view.hpp
@@ -47,6 +47,8 @@ class WidgetInfo : public QObject {
void ButtonClicked();
void TogglePasswordText(bool checked);
+ void EditableListArrayPushBack(obs_data_array_t *array,
+ const char *text);
public:
inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
@@ -79,6 +81,10 @@ public slots:
void EditListEdit();
void EditListUp();
void EditListDown();
+ void EditListReordered(const QModelIndex &sourceParent, int sourceStart,
+ int sourceEnd,
+ const QModelIndex &destinationParent,
+ int destinationRow);
};
/* ------------------------------------------------------------------------- */