Skip to content

Commit 6895c95

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 b45a732 commit 6895c95

File tree

2 files changed

+89
-9
lines changed

2 files changed

+89
-9
lines changed

UI/properties-view.cpp

Lines changed: 85 additions & 9 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

@@ -732,7 +737,7 @@ void OBSPropertiesView::AddEditableList(obs_property_t *prop,
732737

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

737742
QVBoxLayout *sideLayout = new QVBoxLayout();
738743
NewButton(sideLayout, info, "addIconSmall", &WidgetInfo::EditListAdd);
@@ -1992,24 +1997,51 @@ void WidgetInfo::GroupChanged(const char *setting)
19921997
: true);
19931998
}
19941999

2000+
void WidgetInfo::EditListReordered(const QModelIndex &parent, int start,
2001+
int end, const QModelIndex &destination,
2002+
int row)
2003+
{
2004+
UNUSED_PARAMETER(parent);
2005+
UNUSED_PARAMETER(destination);
2006+
2007+
const char *setting = obs_property_name(property);
2008+
OBSDataArrayAutoRelease array =
2009+
obs_data_get_array(view->settings, setting);
2010+
2011+
for (int i = start; i <= end; i++) {
2012+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
2013+
obs_data_array_insert(array, row, arrayItem);
2014+
// if moved to top, item row increases
2015+
obs_data_array_erase(array, (i > row) ? i + 1 : i);
2016+
++row;
2017+
}
2018+
EditableListChanged();
2019+
}
2020+
2021+
void WidgetInfo::EditableListArrayPushBack(obs_data_array_t *array,
2022+
const char *text)
2023+
{
2024+
OBSDataAutoRelease arrayItem = obs_data_create();
2025+
obs_data_set_string(arrayItem, "value", text);
2026+
obs_data_set_bool(arrayItem, "selected", false);
2027+
obs_data_set_bool(arrayItem, "hidden", false);
2028+
obs_data_array_push_back(array, arrayItem);
2029+
}
2030+
19952031
void WidgetInfo::EditableListChanged()
19962032
{
19972033
const char *setting = obs_property_name(property);
19982034
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
1999-
OBSDataArrayAutoRelease array = obs_data_array_create();
2035+
OBSDataArrayAutoRelease array =
2036+
obs_data_get_array(view->settings, setting);
20002037

20012038
for (int i = 0; i < list->count(); i++) {
20022039
QListWidgetItem *item = list->item(i);
2003-
OBSDataAutoRelease arrayItem = obs_data_create();
2004-
obs_data_set_string(arrayItem, "value",
2005-
QT_TO_UTF8(item->text()));
2040+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, i);
20062041
obs_data_set_bool(arrayItem, "selected", item->isSelected());
20072042
obs_data_set_bool(arrayItem, "hidden", item->isHidden());
2008-
obs_data_array_push_back(array, arrayItem);
20092043
}
20102044

2011-
obs_data_set_array(view->settings, setting, array);
2012-
20132045
ControlChanged();
20142046
}
20152047

@@ -2263,6 +2295,9 @@ void WidgetInfo::EditListAddText()
22632295
{
22642296
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
22652297
const char *desc = obs_property_description(property);
2298+
const char *setting = obs_property_name(property);
2299+
OBSDataArrayAutoRelease array =
2300+
obs_data_get_array(view->settings, setting);
22662301

22672302
EditableItemDialog dialog(widget->window(), QString(), false);
22682303
auto title = QTStr("Basic.PropertiesWindow.AddEditableListEntry")
@@ -2276,6 +2311,7 @@ void WidgetInfo::EditListAddText()
22762311
return;
22772312

22782313
list->addItem(text);
2314+
EditableListArrayPushBack(array, QT_TO_UTF8(text));
22792315
EditableListChanged();
22802316
}
22812317

@@ -2286,6 +2322,9 @@ void WidgetInfo::EditListAddFiles()
22862322
const char *filter = obs_property_editable_list_filter(property);
22872323
const char *default_path =
22882324
obs_property_editable_list_default_path(property);
2325+
const char *setting = obs_property_name(property);
2326+
OBSDataArrayAutoRelease array =
2327+
obs_data_get_array(view->settings, setting);
22892328

22902329
QString title = QTStr("Basic.PropertiesWindow.AddEditableListFiles")
22912330
.arg(QT_UTF8(desc));
@@ -2301,6 +2340,9 @@ void WidgetInfo::EditListAddFiles()
23012340
return;
23022341

23032342
list->addItems(files);
2343+
for (QString &file : files) {
2344+
EditableListArrayPushBack(array, QT_TO_UTF8(file));
2345+
}
23042346
EditableListChanged();
23052347
}
23062348

@@ -2310,6 +2352,9 @@ void WidgetInfo::EditListAddDir()
23102352
const char *desc = obs_property_description(property);
23112353
const char *default_path =
23122354
obs_property_editable_list_default_path(property);
2355+
const char *setting = obs_property_name(property);
2356+
OBSDataArrayAutoRelease array =
2357+
obs_data_get_array(view->settings, setting);
23132358

23142359
QString title = QTStr("Basic.PropertiesWindow.AddEditableListDir")
23152360
.arg(QT_UTF8(desc));
@@ -2325,16 +2370,23 @@ void WidgetInfo::EditListAddDir()
23252370
return;
23262371

23272372
list->addItem(dir);
2373+
EditableListArrayPushBack(array, QT_TO_UTF8(dir));
23282374
EditableListChanged();
23292375
}
23302376

23312377
void WidgetInfo::EditListRemove()
23322378
{
23332379
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23342380
QList<QListWidgetItem *> items = list->selectedItems();
2381+
const char *setting = obs_property_name(property);
2382+
OBSDataArrayAutoRelease array =
2383+
obs_data_get_array(view->settings, setting);
23352384

2336-
for (QListWidgetItem *item : items)
2385+
for (qsizetype i = items.size() - 1; i >= 0; i--) {
2386+
QListWidgetItem *item = items.at(i);
2387+
obs_data_array_erase(array, list->row(item));
23372388
delete item;
2389+
}
23382390
EditableListChanged();
23392391
}
23402392

@@ -2343,6 +2395,7 @@ void WidgetInfo::EditListEdit()
23432395
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23442396
enum obs_editable_list_type type =
23452397
obs_property_editable_list_type(property);
2398+
const char *setting = obs_property_name(property);
23462399
const char *desc = obs_property_description(property);
23472400
const char *filter = obs_property_editable_list_filter(property);
23482401
QList<QListWidgetItem *> selectedItems = list->selectedItems();
@@ -2351,6 +2404,10 @@ void WidgetInfo::EditListEdit()
23512404
return;
23522405

23532406
QListWidgetItem *item = selectedItems[0];
2407+
int row = list->row(item);
2408+
OBSDataArrayAutoRelease array =
2409+
obs_data_get_array(view->settings, setting);
2410+
OBSDataAutoRelease arrayItem = obs_data_array_item(array, row);
23542411

23552412
if (type == OBS_EDITABLE_LIST_TYPE_FILES) {
23562413
QDir pathDir(item->text());
@@ -2367,6 +2424,7 @@ void WidgetInfo::EditListEdit()
23672424
return;
23682425

23692426
item->setText(path);
2427+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(path));
23702428
EditableListChanged();
23712429
return;
23722430
}
@@ -2385,13 +2443,17 @@ void WidgetInfo::EditListEdit()
23852443
return;
23862444

23872445
item->setText(text);
2446+
obs_data_set_string(arrayItem, "value", QT_TO_UTF8(text));
23882447
EditableListChanged();
23892448
}
23902449

23912450
void WidgetInfo::EditListUp()
23922451
{
23932452
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
23942453
int lastItemRow = -1;
2454+
const char *setting = obs_property_name(property);
2455+
OBSDataArrayAutoRelease array =
2456+
obs_data_get_array(view->settings, setting);
23952457

23962458
for (int i = 0; i < list->count(); i++) {
23972459
QListWidgetItem *item = list->item(i);
@@ -2405,6 +2467,11 @@ void WidgetInfo::EditListUp()
24052467
list->takeItem(row);
24062468
list->insertItem(lastItemRow, item);
24072469
item->setSelected(true);
2470+
2471+
OBSDataAutoRelease arrayItem =
2472+
obs_data_array_item(array, row);
2473+
obs_data_array_insert(array, lastItemRow, arrayItem);
2474+
obs_data_array_erase(array, row + 1);
24082475
} else {
24092476
lastItemRow = row;
24102477
}
@@ -2417,6 +2484,9 @@ void WidgetInfo::EditListDown()
24172484
{
24182485
QListWidget *list = reinterpret_cast<QListWidget *>(widget);
24192486
int lastItemRow = list->count();
2487+
const char *setting = obs_property_name(property);
2488+
OBSDataArrayAutoRelease array =
2489+
obs_data_get_array(view->settings, setting);
24202490

24212491
for (int i = list->count() - 1; i >= 0; i--) {
24222492
QListWidgetItem *item = list->item(i);
@@ -2430,6 +2500,12 @@ void WidgetInfo::EditListDown()
24302500
list->takeItem(row);
24312501
list->insertItem(lastItemRow, item);
24322502
item->setSelected(true);
2503+
2504+
OBSDataAutoRelease arrayItem =
2505+
obs_data_array_item(array, row);
2506+
obs_data_array_insert(array, lastItemRow + 1,
2507+
arrayItem);
2508+
obs_data_array_erase(array, row);
24332509
} else {
24342510
lastItemRow = row;
24352511
}

UI/properties-view.hpp

Lines changed: 4 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,8 @@ public slots:
7981
void EditListEdit();
8082
void EditListUp();
8183
void EditListDown();
84+
void EditListReordered(const QModelIndex &parent, int start, int end,
85+
const QModelIndex &destination, int row);
8286
};
8387

8488
/* ------------------------------------------------------------------------- */

0 commit comments

Comments
 (0)