Skip to content

Commit f1cd4b6

Browse files
committed
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.
1 parent 69d2740 commit f1cd4b6

2 files changed

Lines changed: 93 additions & 10 deletions

File tree

UI/properties-view.cpp

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
709709
{
710710
const char *name = obs_property_name(prop);
711711
OBSDataArrayAutoRelease array = obs_data_get_array(settings, name);
712+
if (array == NULL) {
713+
array = obs_data_array_create();
714+
obs_data_set_array(settings, name, array);
715+
}
716+
712717
QListWidget *list = new QListWidget();
713718
size_t count = obs_data_array_count(array);
714719

@@ -731,8 +736,8 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
731736
WidgetInfo *info = new WidgetInfo(this, prop, list);
732737

733738
list->setDragDropMode(QAbstractItemView::InternalMove);
734-
connect(list->model(), &QAbstractItemModel::rowsMoved,
735-
[info]() { info->EditableListChanged(); });
739+
connect(list->model(), &QAbstractItemModel::rowsMoved, info,
740+
&WidgetInfo::EditListReordered);
736741

737742
QVBoxLayout *sideLayout = new QVBoxLayout();
738743
NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
@@ -1998,24 +2003,52 @@ void WidgetInfo::GroupChanged(const char *setting)
19982003
: true);
19992004
}
20002005

2006+
void WidgetInfo::EditListReordered(const QModelIndex &sourceParent,
2007+
int sourceStart, int sourceEnd,
2008+
const QModelIndex &destinationParent,
2009+
int destinationRow)
2010+
{
2011+
UNUSED_PARAMETER(sourceParent);
2012+
UNUSED_PARAMETER(destinationParent);
2013+
2014+
const char *setting = obs_property_name(property);
2015+
OBSDataArrayAutoRelease array =
2016+
obs_data_get_array(view->settings, setting);
2017+
2018+
for (int i = sourceStart; i <= sourceEnd; i++) {
2019+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
2020+
obs_data_array_insert(array, destinationRow, arrayItem);
2021+
// if moved to top, destination row increases
2022+
obs_data_array_erase(array, (i > destinationRow) ? i + 1 : i);
2023+
++destinationRow;
2024+
}
2025+
EditableListChanged();
2026+
}
2027+
2028+
void WidgetInfo::EditableListArrayPushBack(obs_data_array_t *array,
2029+
const char *text)
2030+
{
2031+
OBSDataAutoRelease arrayItem = obs_data_create();
2032+
obs_data_set_string(arrayItem, "value", text);
2033+
obs_data_set_bool(arrayItem, "selected", false);
2034+
obs_data_set_bool(arrayItem, "hidden", false);
2035+
obs_data_array_push_back(array, arrayItem);
2036+
}
2037+
20012038
void WidgetInfo::EditableListChanged()
20022039
{
20032040
const char *setting = obs_property_name(property);
20042041
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
2005-
OBSDataArrayAutoRelease array = obs_data_array_create();
2042+
OBSDataArrayAutoRelease array =
2043+
obs_data_get_array(view->settings, setting);
20062044

20072045
for (int i = 0; i < list->count(); i++) {
20082046
QListWidgetItem *item = list->item(i);
2009-
OBSDataAutoRelease arrayItem = obs_data_create();
2010-
obs_data_set_string(arrayItem, "value",
2011-
QT_TO_UTF8(item->text()));
2047+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
20122048
obs_data_set_bool(arrayItem, "selected", item->isSelected());
20132049
obs_data_set_bool(arrayItem, "hidden", item->isHidden());
2014-
obs_data_array_push_back(array, arrayItem);
20152050
}
20162051

2017-
obs_data_set_array(view->settings, setting, array);
2018-
20192052
ControlChanged();
20202053
}
20212054

@@ -2269,6 +2302,9 @@ void WidgetInfo::EditListAddText()
22692302
{
22702303
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
22712304
const char *desc = obs_property_description(property);
2305+
const char *setting = obs_property_name(property);
2306+
OBSDataArrayAutoRelease array =
2307+
obs_data_get_array(view->settings, setting);
22722308

22732309
EditableItemDialog dialog(widget->window(), QString(), false);
22742310
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry")
@@ -2282,6 +2318,7 @@ void WidgetInfo::EditListAddText()
22822318
return;
22832319

22842320
list->addItem(text);
2321+
EditableListArrayPushBack(array, QT_TO_UTF8(text));
22852322
EditableListChanged();
22862323
}
22872324

@@ -2292,6 +2329,9 @@ void WidgetInfo::EditListAddFiles()
22922329
const char *filter = obs_property_editable_list_filter(property);
22932330
const char *default_path =
22942331
obs_property_editable_list_default_path(property);
2332+
const char *setting = obs_property_name(property);
2333+
OBSDataArrayAutoRelease array =
2334+
obs_data_get_array(view->settings, setting);
22952335

22962336
QString title = QTStr("Basic.PropertiesWindow.AddEditableListFiles")
22972337
.arg(QT_UTF8(desc));
@@ -2307,6 +2347,9 @@ void WidgetInfo::EditListAddFiles()
23072347
return;
23082348

23092349
list->addItems(files);
2350+
for (QString &file : files) {
2351+
EditableListArrayPushBack(array, QT_TO_UTF8(file));
2352+
}
23102353
EditableListChanged();
23112354
}
23122355

@@ -2316,6 +2359,9 @@ void WidgetInfo::EditListAddDir()
23162359
const char *desc = obs_property_description(property);
23172360
const char *default_path =
23182361
obs_property_editable_list_default_path(property);
2362+
const char *setting = obs_property_name(property);
2363+
OBSDataArrayAutoRelease array =
2364+
obs_data_get_array(view->settings, setting);
23192365

23202366
QString title = QTStr("Basic.PropertiesWindow.AddEditableListDir")
23212367
.arg(QT_UTF8(desc));
@@ -2331,16 +2377,23 @@ void WidgetInfo::EditListAddDir()
23312377
return;
23322378

23332379
list->addItem(dir);
2380+
EditableListArrayPushBack(array, QT_TO_UTF8(dir));
23342381
EditableListChanged();
23352382
}
23362383

23372384
void WidgetInfo::EditListRemove()
23382385
{
23392386
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23402387
QList<QListWidgetItem *> items = list->selectedItems();
2388+
const char *setting = obs_property_name(property);
2389+
OBSDataArrayAutoRelease array =
2390+
obs_data_get_array(view->settings, setting);
23412391

2342-
for (QListWidgetItem *item : items)
2392+
for (qsizetype i = items.size() - 1; i >= 0; i--) {
2393+
QListWidgetItem *item = items.at(i);
2394+
obs_data_array_erase(array, list->row(item));
23432395
delete item;
2396+
}
23442397
EditableListChanged();
23452398
}
23462399

@@ -2349,6 +2402,7 @@ void WidgetInfo::EditListEdit()
23492402
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23502403
enum obs_editable_list_type type =
23512404
obs_property_editable_list_type(property);
2405+
const char *setting = obs_property_name(property);
23522406
const char *desc = obs_property_description(property);
23532407
const char *filter = obs_property_editable_list_filter(property);
23542408
QList<QListWidgetItem *> selectedItems = list->selectedItems();
@@ -2357,6 +2411,10 @@ void WidgetInfo::EditListEdit()
23572411
return;
23582412

23592413
QListWidgetItem *item = selectedItems[0];
2414+
int row = list->row(item);
2415+
OBSDataArrayAutoRelease array =
2416+
obs_data_get_array(view->settings, setting);
2417+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, row);
23602418

23612419
if (type == OBS_EDITABLE_LIST_TYPE_FILES) {
23622420
QDir pathDir(item->text());
@@ -2373,6 +2431,7 @@ void WidgetInfo::EditListEdit()
23732431
return;
23742432

23752433
item->setText(path);
2434+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(path));
23762435
EditableListChanged();
23772436
return;
23782437
}
@@ -2391,13 +2450,17 @@ void WidgetInfo::EditListEdit()
23912450
return;
23922451

23932452
item->setText(text);
2453+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(text));
23942454
EditableListChanged();
23952455
}
23962456

23972457
void WidgetInfo::EditListUp()
23982458
{
23992459
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
24002460
int lastItemRow = -1;
2461+
const char *setting = obs_property_name(property);
2462+
OBSDataArrayAutoRelease array =
2463+
obs_data_get_array(view->settings, setting);
24012464

24022465
for (int i = 0; i < list->count(); i++) {
24032466
QListWidgetItem *item = list->item(i);
@@ -2411,6 +2474,11 @@ void WidgetInfo::EditListUp()
24112474
list->takeItem(row);
24122475
list->insertItem(lastItemRow, item);
24132476
item->setSelected(true);
2477+
2478+
OBSDataAutoRelease arrayItem =
2479+
obs_data_array_item(array, row);
2480+
obs_data_array_insert(array, lastItemRow, arrayItem);
2481+
obs_data_array_erase(array, row + 1);
24142482
} else {
24152483
lastItemRow = row;
24162484
}
@@ -2423,6 +2491,9 @@ void WidgetInfo::EditListDown()
24232491
{
24242492
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
24252493
int lastItemRow = list->count();
2494+
const char *setting = obs_property_name(property);
2495+
OBSDataArrayAutoRelease array =
2496+
obs_data_get_array(view->settings, setting);
24262497

24272498
for (int i = list->count() - 1; i >= 0; i--) {
24282499
QListWidgetItem *item = list->item(i);
@@ -2436,6 +2507,12 @@ void WidgetInfo::EditListDown()
24362507
list->takeItem(row);
24372508
list->insertItem(lastItemRow, item);
24382509
item->setSelected(true);
2510+
2511+
OBSDataAutoRelease arrayItem =
2512+
obs_data_array_item(array, row);
2513+
obs_data_array_insert(array, lastItemRow + 1,
2514+
arrayItem);
2515+
obs_data_array_erase(array, row);
24392516
} else {
24402517
lastItemRow = row;
24412518
}

UI/properties-view.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class WidgetInfo : public QObject {
4747
void ButtonClicked();
4848

4949
void TogglePasswordText(bool checked);
50+
void EditableListArrayPushBack(obs_data_array_t *array,
51+
const char *text);
5052

5153
public:
5254
inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
@@ -79,6 +81,10 @@ public slots:
7981
void EditListEdit();
8082
void EditListUp();
8183
void EditListDown();
84+
void EditListReordered(const QModelIndex &sourceParent, int sourceStart,
85+
int sourceEnd,
86+
const QModelIndex &destinationParent,
87+
int destinationRow);
8288
};
8389

8490
/* ------------------------------------------------------------------------- */

0 commit comments

Comments
 (0)