Skip to content

Commit aa4ea1a

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 5854f3b commit aa4ea1a

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
@@ -723,6 +723,11 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
723723
{
724724
const char *name = obs_property_name(prop);
725725
OBSDataArrayAutoRelease array = obs_data_get_array(settings, name);
726+
if (array == NULL) {
727+
array = obs_data_array_create();
728+
obs_data_set_array(settings, name, array);
729+
}
730+
726731
QListWidget *list = new QListWidget();
727732
size_t count = obs_data_array_count(array);
728733

@@ -745,8 +750,8 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
745750
WidgetInfo *info = new WidgetInfo(this, prop, list);
746751

747752
list->setDragDropMode(QAbstractItemView::InternalMove);
748-
connect(list->model(), &QAbstractItemModel::rowsMoved,
749-
[info]() { info->EditableListChanged(); });
753+
connect(list->model(), &QAbstractItemModel::rowsMoved, info,
754+
&WidgetInfo::EditListReordered);
750755

751756
QVBoxLayout *sideLayout = new QVBoxLayout();
752757
NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
@@ -2012,24 +2017,52 @@ void WidgetInfo::GroupChanged(const char *setting)
20122017
: true);
20132018
}
20142019

2020+
void WidgetInfo::EditListReordered(const QModelIndex &sourceParent,
2021+
int sourceStart, int sourceEnd,
2022+
const QModelIndex &destinationParent,
2023+
int destinationRow)
2024+
{
2025+
UNUSED_PARAMETER(sourceParent);
2026+
UNUSED_PARAMETER(destinationParent);
2027+
2028+
const char *setting = obs_property_name(property);
2029+
OBSDataArrayAutoRelease array =
2030+
obs_data_get_array(view->settings, setting);
2031+
2032+
for (int i = sourceStart; i <= sourceEnd; i++) {
2033+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
2034+
obs_data_array_insert(array, destinationRow, arrayItem);
2035+
// if moved to top, destination row increases
2036+
obs_data_array_erase(array, (i > destinationRow) ? i + 1 : i);
2037+
++destinationRow;
2038+
}
2039+
EditableListChanged();
2040+
}
2041+
2042+
void WidgetInfo::EditableListArrayPushBack(obs_data_array_t *array,
2043+
const char *text)
2044+
{
2045+
OBSDataAutoRelease arrayItem = obs_data_create();
2046+
obs_data_set_string(arrayItem, "value", text);
2047+
obs_data_set_bool(arrayItem, "selected", false);
2048+
obs_data_set_bool(arrayItem, "hidden", false);
2049+
obs_data_array_push_back(array, arrayItem);
2050+
}
2051+
20152052
void WidgetInfo::EditableListChanged()
20162053
{
20172054
const char *setting = obs_property_name(property);
20182055
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
2019-
OBSDataArrayAutoRelease array = obs_data_array_create();
2056+
OBSDataArrayAutoRelease array =
2057+
obs_data_get_array(view->settings, setting);
20202058

20212059
for (int i = 0; i < list->count(); i++) {
20222060
QListWidgetItem *item = list->item(i);
2023-
OBSDataAutoRelease arrayItem = obs_data_create();
2024-
obs_data_set_string(arrayItem, "value",
2025-
QT_TO_UTF8(item->text()));
2061+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
20262062
obs_data_set_bool(arrayItem, "selected", item->isSelected());
20272063
obs_data_set_bool(arrayItem, "hidden", item->isHidden());
2028-
obs_data_array_push_back(array, arrayItem);
20292064
}
20302065

2031-
obs_data_set_array(view->settings, setting, array);
2032-
20332066
ControlChanged();
20342067
}
20352068

@@ -2283,6 +2316,9 @@ void WidgetInfo::EditListAddText()
22832316
{
22842317
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
22852318
const char *desc = obs_property_description(property);
2319+
const char *setting = obs_property_name(property);
2320+
OBSDataArrayAutoRelease array =
2321+
obs_data_get_array(view->settings, setting);
22862322

22872323
EditableItemDialog dialog(widget->window(), QString(), false);
22882324
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry")
@@ -2296,6 +2332,7 @@ void WidgetInfo::EditListAddText()
22962332
return;
22972333

22982334
list->addItem(text);
2335+
EditableListArrayPushBack(array, QT_TO_UTF8(text));
22992336
EditableListChanged();
23002337
}
23012338

@@ -2306,6 +2343,9 @@ void WidgetInfo::EditListAddFiles()
23062343
const char *filter = obs_property_editable_list_filter(property);
23072344
const char *default_path =
23082345
obs_property_editable_list_default_path(property);
2346+
const char *setting = obs_property_name(property);
2347+
OBSDataArrayAutoRelease array =
2348+
obs_data_get_array(view->settings, setting);
23092349

23102350
QString title = QTStr("Basic.PropertiesWindow.AddEditableListFiles")
23112351
.arg(QT_UTF8(desc));
@@ -2321,6 +2361,9 @@ void WidgetInfo::EditListAddFiles()
23212361
return;
23222362

23232363
list->addItems(files);
2364+
for (QString &file : files) {
2365+
EditableListArrayPushBack(array, QT_TO_UTF8(file));
2366+
}
23242367
EditableListChanged();
23252368
}
23262369

@@ -2330,6 +2373,9 @@ void WidgetInfo::EditListAddDir()
23302373
const char *desc = obs_property_description(property);
23312374
const char *default_path =
23322375
obs_property_editable_list_default_path(property);
2376+
const char *setting = obs_property_name(property);
2377+
OBSDataArrayAutoRelease array =
2378+
obs_data_get_array(view->settings, setting);
23332379

23342380
QString title = QTStr("Basic.PropertiesWindow.AddEditableListDir")
23352381
.arg(QT_UTF8(desc));
@@ -2345,16 +2391,23 @@ void WidgetInfo::EditListAddDir()
23452391
return;
23462392

23472393
list->addItem(dir);
2394+
EditableListArrayPushBack(array, QT_TO_UTF8(dir));
23482395
EditableListChanged();
23492396
}
23502397

23512398
void WidgetInfo::EditListRemove()
23522399
{
23532400
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23542401
QList<QListWidgetItem *> items = list->selectedItems();
2402+
const char *setting = obs_property_name(property);
2403+
OBSDataArrayAutoRelease array =
2404+
obs_data_get_array(view->settings, setting);
23552405

2356-
for (QListWidgetItem *item : items)
2406+
for (qsizetype i = items.size() - 1; i >= 0; i--) {
2407+
QListWidgetItem *item = items.at(i);
2408+
obs_data_array_erase(array, list->row(item));
23572409
delete item;
2410+
}
23582411
EditableListChanged();
23592412
}
23602413

@@ -2363,6 +2416,7 @@ void WidgetInfo::EditListEdit()
23632416
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23642417
enum obs_editable_list_type type =
23652418
obs_property_editable_list_type(property);
2419+
const char *setting = obs_property_name(property);
23662420
const char *desc = obs_property_description(property);
23672421
const char *filter = obs_property_editable_list_filter(property);
23682422
QList<QListWidgetItem *> selectedItems = list->selectedItems();
@@ -2371,6 +2425,10 @@ void WidgetInfo::EditListEdit()
23712425
return;
23722426

23732427
QListWidgetItem *item = selectedItems[0];
2428+
int row = list->row(item);
2429+
OBSDataArrayAutoRelease array =
2430+
obs_data_get_array(view->settings, setting);
2431+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, row);
23742432

23752433
if (type == OBS_EDITABLE_LIST_TYPE_FILES) {
23762434
QDir pathDir(item->text());
@@ -2387,6 +2445,7 @@ void WidgetInfo::EditListEdit()
23872445
return;
23882446

23892447
item->setText(path);
2448+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(path));
23902449
EditableListChanged();
23912450
return;
23922451
}
@@ -2405,13 +2464,17 @@ void WidgetInfo::EditListEdit()
24052464
return;
24062465

24072466
item->setText(text);
2467+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(text));
24082468
EditableListChanged();
24092469
}
24102470

24112471
void WidgetInfo::EditListUp()
24122472
{
24132473
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
24142474
int lastItemRow = -1;
2475+
const char *setting = obs_property_name(property);
2476+
OBSDataArrayAutoRelease array =
2477+
obs_data_get_array(view->settings, setting);
24152478

24162479
for (int i = 0; i < list->count(); i++) {
24172480
QListWidgetItem *item = list->item(i);
@@ -2425,6 +2488,11 @@ void WidgetInfo::EditListUp()
24252488
list->takeItem(row);
24262489
list->insertItem(lastItemRow, item);
24272490
item->setSelected(true);
2491+
2492+
OBSDataAutoRelease arrayItem =
2493+
obs_data_array_item(array, row);
2494+
obs_data_array_insert(array, lastItemRow, arrayItem);
2495+
obs_data_array_erase(array, row + 1);
24282496
} else {
24292497
lastItemRow = row;
24302498
}
@@ -2437,6 +2505,9 @@ void WidgetInfo::EditListDown()
24372505
{
24382506
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
24392507
int lastItemRow = list->count();
2508+
const char *setting = obs_property_name(property);
2509+
OBSDataArrayAutoRelease array =
2510+
obs_data_get_array(view->settings, setting);
24402511

24412512
for (int i = list->count() - 1; i >= 0; i--) {
24422513
QListWidgetItem *item = list->item(i);
@@ -2450,6 +2521,12 @@ void WidgetInfo::EditListDown()
24502521
list->takeItem(row);
24512522
list->insertItem(lastItemRow, item);
24522523
item->setSelected(true);
2524+
2525+
OBSDataAutoRelease arrayItem =
2526+
obs_data_array_item(array, row);
2527+
obs_data_array_insert(array, lastItemRow + 1,
2528+
arrayItem);
2529+
obs_data_array_erase(array, row);
24532530
} else {
24542531
lastItemRow = row;
24552532
}

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)