diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed7477a1..5a29ae60 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -223,6 +223,7 @@ target_sources(
lib/variables/variable-spinbox.hpp
lib/variables/variable-string.cpp
lib/variables/variable-string.hpp
+ lib/variables/variable-tab.cpp
lib/variables/variable-text-edit.cpp
lib/variables/variable-text-edit.hpp
lib/variables/variable.cpp
diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini
index 4b7eb76a..383f165c 100644
--- a/data/locale/en-US.ini
+++ b/data/locale/en-US.ini
@@ -65,6 +65,18 @@ AdvSceneSwitcher.generalTab.transitionOverride="Set transition overrides"
AdvSceneSwitcher.generalTab.adjustActiveTransitionType="Change active transition type"
AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="At least one option must be enabled:\n\n - Use transition overrides\n\n - Change active transition type"
+; Variables Tab
+AdvSceneSwitcher.variableTab.title="Variables"
+AdvSceneSwitcher.variableTab.help="Variables can be used in many places throughout the plugin.\n\nClick on the highlighted plus symbol to add a new variable."
+AdvSceneSwitcher.variableTab.tooltip.variableAddButton="Add new variable"
+AdvSceneSwitcher.variableTab.tooltip.variableRemoveButton="Remove selected variables"
+AdvSceneSwitcher.variableTab.header.name="Name"
+AdvSceneSwitcher.variableTab.header.value="Value"
+AdvSceneSwitcher.variableTab.header.saveLoadBehavior="Save/Load behavior"
+AdvSceneSwitcher.variableTab.header.lastUse="Last used"
+AdvSceneSwitcher.variableTab.neverNused="Never"
+AdvSceneSwitcher.variableTab.lastUsed="%1 seconds ago"
+
; Macro Tab
AdvSceneSwitcher.macroTab.title="Macro"
AdvSceneSwitcher.macroTab.macros="Macros"
diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui
index 9b1ef626..c9e788a2 100644
--- a/forms/advanced-scene-switcher.ui
+++ b/forms/advanced-scene-switcher.ui
@@ -1577,6 +1577,104 @@
+
+
+ AdvSceneSwitcher.variableTab.title
+
+
+ -
+
+
-
+
+
+ QAbstractItemView::NoEditTriggers
+
+
+ QAbstractItemView::SelectRows
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+ -
+
+
+ AdvSceneSwitcher.variableTab.help
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 22
+ 22
+
+
+
+ AdvSceneSwitcher.variableTab.tooltip.variableAddButton
+
+
+ true
+
+
+ addIconSmall
+
+
+
+ -
+
+
+
+ 22
+ 22
+
+
+
+ AdvSceneSwitcher.variableTab.tooltip.variableRemoveButton
+
+
+ true
+
+
+ removeIconSmall
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
AdvSceneSwitcher.networkTab.title
diff --git a/lib/advanced-scene-switcher.cpp b/lib/advanced-scene-switcher.cpp
index 7d258813..c91444f0 100644
--- a/lib/advanced-scene-switcher.cpp
+++ b/lib/advanced-scene-switcher.cpp
@@ -111,6 +111,7 @@ void AdvSceneSwitcher::LoadUI()
SetupSceneGroupTab();
SetupTriggerTab();
SetupMacroTab();
+ SetupVariableTab();
SetDeprecationWarnings();
SetTabOrder();
diff --git a/lib/advanced-scene-switcher.hpp b/lib/advanced-scene-switcher.hpp
index f84fc6c2..90556315 100644
--- a/lib/advanced-scene-switcher.hpp
+++ b/lib/advanced-scene-switcher.hpp
@@ -208,6 +208,16 @@ private:
/* --- End of macro tab section --- */
+ /* --- Begin of variable tab section --- */
+public:
+ void SetupVariableTab();
+
+public slots:
+ void on_variableAdd_clicked();
+ void on_variableRemove_clicked();
+
+ /* --- End of variable tab section --- */
+
/* --- Begin of legacy tab section --- */
public:
void ClearFrames(QListWidget *list);
diff --git a/lib/general.cpp b/lib/general.cpp
index 7b7e5d21..0567f7b9 100644
--- a/lib/general.cpp
+++ b/lib/general.cpp
@@ -18,6 +18,17 @@
namespace advss {
+static constexpr std::array tabNames = {
+ "generalTab", "macroTab", "variableTab",
+ "windowTitleTab", "executableTab", "screenRegionTab",
+ "mediaTab", "fileTab", "randomTab",
+ "timeTab", "idleTab", "sceneSequenceTab",
+ "audioTab", "videoTab", "networkTab",
+ "sceneGroupTab", "transitionsTab", "pauseTab",
+ "sceneTriggerTab"};
+
+static std::vector tabOrder = std::vector(tabNames.size());
+
void AdvSceneSwitcher::reject()
{
close();
@@ -355,65 +366,7 @@ void AdvSceneSwitcher::on_importSettings_clicked()
static int findTabIndex(QTabWidget *tabWidget, int pos)
{
int at = -1;
-
- QString tabName = "";
- switch (pos) {
- case 0:
- tabName = "generalTab";
- break;
- case 1:
- tabName = "macroTab";
- break;
- case 2:
- tabName = "transitionsTab";
- break;
- case 3:
- tabName = "pauseTab";
- break;
- case 4:
- tabName = "windowTitleTab";
- break;
- case 5:
- tabName = "executableTab";
- break;
- case 6:
- tabName = "screenRegionTab";
- break;
- case 7:
- tabName = "mediaTab";
- break;
- case 8:
- tabName = "fileTab";
- break;
- case 9:
- tabName = "randomTab";
- break;
- case 10:
- tabName = "timeTab";
- break;
- case 11:
- tabName = "idleTab";
- break;
- case 12:
- tabName = "sceneSequenceTab";
- break;
- case 13:
- tabName = "audioTab";
- break;
- case 14:
- tabName = "videoTab";
- break;
- case 15:
- tabName = "networkTab";
- break;
- case 16:
- tabName = "sceneGroupTab";
- break;
- case 17:
- tabName = "sceneTriggerTab";
- break;
- }
-
+ QString tabName = tabNames.at(pos);
QWidget *page = tabWidget->findChild(tabName);
if (page) {
at = tabWidget->indexOf(page);
@@ -426,15 +379,35 @@ static int findTabIndex(QTabWidget *tabWidget, int pos)
return at;
}
+static bool tabWidgetOrderValid()
+{
+ auto tmp = std::vector(tabNames.size());
+ std::iota(tmp.begin(), tmp.end(), 0);
+
+ for (auto &p : tmp) {
+ auto it = std::find(tabOrder.begin(), tabOrder.end(), p);
+ if (it == tabOrder.end()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void resetTabWidgetOrder()
+{
+ tabOrder = std::vector(tabNames.size());
+ std::iota(tabOrder.begin(), tabOrder.end(), 0);
+}
+
void AdvSceneSwitcher::SetTabOrder()
{
- if (!switcher->TabOrderValid()) {
- switcher->ResetTabOrder();
+ if (!tabWidgetOrderValid()) {
+ resetTabWidgetOrder();
}
QTabBar *bar = ui->tabWidget->tabBar();
for (int i = 0; i < bar->count(); ++i) {
- int curPos = findTabIndex(ui->tabWidget, switcher->tabOrder[i]);
+ int curPos = findTabIndex(ui->tabWidget, tabOrder[i]);
if (i != curPos && curPos != -1) {
bar->moveTab(curPos, i);
@@ -479,7 +452,7 @@ void AdvSceneSwitcher::on_tabMoved(int from, int to)
return;
}
- std::swap(switcher->tabOrder[from], switcher->tabOrder[to]);
+ std::swap(tabOrder[from], tabOrder[to]);
}
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
@@ -712,24 +685,13 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
void SwitcherData::SaveUISettings(obs_data_t *obj)
{
- obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
- obs_data_set_int(obj, "macroTabPos", tabOrder[1]);
- obs_data_set_int(obj, "transitionTabPos", tabOrder[2]);
- obs_data_set_int(obj, "pauseTabPos", tabOrder[3]);
- obs_data_set_int(obj, "titleTabPos", tabOrder[4]);
- obs_data_set_int(obj, "exeTabPos", tabOrder[5]);
- obs_data_set_int(obj, "regionTabPos", tabOrder[6]);
- obs_data_set_int(obj, "mediaTabPos", tabOrder[7]);
- obs_data_set_int(obj, "fileTabPos", tabOrder[8]);
- obs_data_set_int(obj, "randomTabPos", tabOrder[9]);
- obs_data_set_int(obj, "timeTabPos", tabOrder[10]);
- obs_data_set_int(obj, "idleTabPos", tabOrder[11]);
- obs_data_set_int(obj, "sequenceTabPos", tabOrder[12]);
- obs_data_set_int(obj, "audioTabPos", tabOrder[13]);
- obs_data_set_int(obj, "videoTabPos", tabOrder[14]);
- obs_data_set_int(obj, "networkTabPos", tabOrder[15]);
- obs_data_set_int(obj, "sceneGroupTabPos", tabOrder[16]);
- obs_data_set_int(obj, "triggerTabPos", tabOrder[17]);
+ OBSDataArrayAutoRelease tabWidgetOrder = obs_data_array_create();
+ for (size_t i = 0; i < tabNames.size(); i++) {
+ OBSDataAutoRelease entry = obs_data_create();
+ obs_data_set_int(entry, tabNames[i], tabOrder[i]);
+ obs_data_array_push_back(tabWidgetOrder, entry);
+ }
+ obs_data_set_array(obj, "tabWidgetOrder", tabWidgetOrder);
obs_data_set_bool(obj, "saveWindowGeo", saveWindowGeo);
obs_data_set_int(obj, "windowPosX", windowPos.x());
@@ -743,47 +705,27 @@ void SwitcherData::SaveUISettings(obs_data_t *obj)
void SwitcherData::LoadUISettings(obs_data_t *obj)
{
- obs_data_set_default_int(obj, "generalTabPos", 0);
- obs_data_set_default_int(obj, "macroTabPos", 1);
- obs_data_set_default_int(obj, "networkTabPos", 13);
- obs_data_set_default_int(obj, "sceneGroupTabPos", 14);
- obs_data_set_default_int(obj, "transitionTabPos", 15);
- obs_data_set_default_int(obj, "pauseTabPos", 16);
- obs_data_set_default_int(obj, "titleTabPos", 2);
- obs_data_set_default_int(obj, "exeTabPos", 3);
- obs_data_set_default_int(obj, "regionTabPos", 4);
- obs_data_set_default_int(obj, "mediaTabPos", 5);
- obs_data_set_default_int(obj, "fileTabPos", 6);
- obs_data_set_default_int(obj, "randomTabPos", 7);
- obs_data_set_default_int(obj, "timeTabPos", 8);
- obs_data_set_default_int(obj, "idleTabPos", 9);
- obs_data_set_default_int(obj, "sequenceTabPos", 10);
- obs_data_set_default_int(obj, "audioTabPos", 11);
- obs_data_set_default_int(obj, "videoTabPos", 12);
- obs_data_set_default_int(obj, "triggerTabPos", 17);
+ OBSDataArrayAutoRelease defaultTabWidgetOrder = obs_data_array_create();
+ for (size_t i = 0; i < tabNames.size(); i++) {
+ OBSDataAutoRelease entry = obs_data_create();
+ obs_data_set_default_int(entry, tabNames[i], i);
+ obs_data_array_push_back(defaultTabWidgetOrder, entry);
+ }
+ obs_data_set_default_array(obj, "tabWidgetOrder",
+ defaultTabWidgetOrder);
tabOrder.clear();
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "generalTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "macroTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "transitionTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "pauseTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "titleTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "exeTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "regionTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "mediaTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "fileTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "randomTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "timeTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "idleTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "sequenceTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "audioTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "videoTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "networkTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "sceneGroupTabPos")));
- tabOrder.emplace_back((int)(obs_data_get_int(obj, "triggerTabPos")));
+ OBSDataArrayAutoRelease tabWidgetOrder =
+ obs_data_get_array(obj, "tabWidgetOrder");
+ for (size_t i = 0; i < tabNames.size(); i++) {
+ OBSDataAutoRelease entry =
+ obs_data_array_item(tabWidgetOrder, i);
+ tabOrder.emplace_back(
+ (int)(obs_data_get_int(entry, tabNames[i])));
+ }
- if (!TabOrderValid()) {
- ResetTabOrder();
+ if (!tabWidgetOrderValid()) {
+ resetTabWidgetOrder();
}
saveWindowGeo = obs_data_get_bool(obj, "saveWindowGeo");
@@ -796,26 +738,6 @@ void SwitcherData::LoadUISettings(obs_data_t *obj)
"macroListMacroEditSplitterPosition");
}
-bool SwitcherData::TabOrderValid()
-{
- auto tmp = std::vector(tab_count);
- std::iota(tmp.begin(), tmp.end(), 0);
-
- for (auto &p : tmp) {
- auto it = std::find(tabOrder.begin(), tabOrder.end(), p);
- if (it == tabOrder.end()) {
- return false;
- }
- }
- return true;
-}
-
-void SwitcherData::ResetTabOrder()
-{
- tabOrder = std::vector(tab_count);
- std::iota(tabOrder.begin(), tabOrder.end(), 0);
-}
-
void SwitcherData::CheckNoMatchSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition, int &sleep)
{
diff --git a/lib/switcher-data.hpp b/lib/switcher-data.hpp
index d8faafb4..a83c2bf4 100644
--- a/lib/switcher-data.hpp
+++ b/lib/switcher-data.hpp
@@ -32,7 +32,6 @@
namespace advss {
constexpr auto default_interval = 300;
-constexpr auto tab_count = 18;
typedef const char *(*translateFunc)(const char *);
@@ -89,8 +88,6 @@ public:
void LoadUISettings(obs_data_t *obj);
bool VersionChanged(obs_data_t *obj, std::string currentVersion);
- bool TabOrderValid();
- void ResetTabOrder();
bool PrioFuncsValid();
/* --- End of saving / loading section --- */
@@ -179,7 +176,6 @@ public:
bool disableHints = false;
bool disableFilterComboboxFilter = false;
bool hideLegacyTabs = true;
- std::vector tabOrder = std::vector(tab_count);
bool saveWindowGeo = false;
QPoint windowPos = {};
QSize windowSize = {};
diff --git a/lib/variables/variable-tab.cpp b/lib/variables/variable-tab.cpp
new file mode 100644
index 00000000..169bb301
--- /dev/null
+++ b/lib/variables/variable-tab.cpp
@@ -0,0 +1,296 @@
+#include "advanced-scene-switcher.hpp"
+#include "variable.hpp"
+
+#include
+
+namespace advss {
+
+static void setVariableTabVisible(QTabWidget *tabWidget, bool visible)
+{
+ for (int idx = 0; idx < tabWidget->count(); idx++) {
+ if (tabWidget->tabText(idx) !=
+ obs_module_text("AdvSceneSwitcher.variableTab.title")) {
+ continue;
+ }
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ // TODO: Switch to setTabVisible() once QT 5.15 is more wide spread
+ tabWidget->setTabEnabled(idx, visible);
+ tabWidget->setStyleSheet(
+ "QTabBar::tab::disabled {width: 0; height: 0; margin: 0; padding: 0; border: none;} ");
+#else
+ tabWidget->setTabVisible(idx, visible);
+#endif
+ }
+}
+
+static QString getSaveActionString(Variable *variable)
+{
+ QString saveAction;
+ switch (variable->GetSaveAction()) {
+ case Variable::SaveAction::DONT_SAVE:
+ saveAction = obs_module_text(
+ "AdvSceneSwitcher.variable.save.dontSave");
+ break;
+ case Variable::SaveAction::SAVE:
+ saveAction =
+ obs_module_text("AdvSceneSwitcher.variable.save.save");
+ break;
+ case Variable::SaveAction::SET_DEFAULT:
+ saveAction =
+ QString(obs_module_text(
+ "AdvSceneSwitcher.variable.save.default")) +
+ " \"" +
+ QString::fromStdString(variable->GetDefaultValue()) +
+ "\"";
+ break;
+ default:
+ break;
+ }
+ return saveAction;
+}
+
+static QString getLastUsedString(Variable *variable)
+{
+ auto lastUsed = variable->SecondsSinceLastUse();
+ if (!lastUsed) {
+ return obs_module_text(
+ "AdvSceneSwitcher.variableTab.neverNused");
+ }
+ QString fmt = obs_module_text("AdvSceneSwitcher.variableTab.lastUsed");
+ return fmt.arg(QString::number(*lastUsed));
+}
+
+static void addVariableRow(QTableWidget *table, Variable *variable)
+{
+ if (!variable) {
+ blog(LOG_INFO, "%s called with nullptr", __func__);
+ assert(false);
+ return;
+ }
+
+ int row = table->rowCount();
+ table->setRowCount(row + 1);
+
+ int col = 0;
+ auto *item =
+ new QTableWidgetItem(QString::fromStdString(variable->Name()));
+ table->setItem(row, col, item);
+ col++;
+ item = new QTableWidgetItem(
+ QString::fromStdString(variable->Value(false)));
+ table->setItem(row, col, item);
+ col++;
+ item = new QTableWidgetItem(getSaveActionString(variable));
+ table->setItem(row, col, item);
+ col++;
+ item = new QTableWidgetItem(getLastUsedString(variable));
+ table->setItem(row, col, item);
+ table->sortByColumn(0, Qt::AscendingOrder);
+}
+
+static void removeVariableRow(QTableWidget *table, const QString &name)
+{
+ for (int row = 0; row < table->rowCount(); ++row) {
+ auto item = table->item(row, 0);
+ if (item && item->text() == name) {
+ table->removeRow(row);
+ return;
+ }
+ }
+ table->sortByColumn(0, Qt::AscendingOrder);
+}
+
+static void updateVaribleStatus(QTableWidget *table)
+{
+ auto lock = LockContext();
+ for (int row = 0; row < table->rowCount(); row++) {
+ auto item = table->item(row, 0);
+ if (!item) {
+ continue;
+ }
+ auto weakVariable = GetWeakVariableByQString(item->text());
+ auto variable = weakVariable.lock();
+ if (!variable) {
+ continue;
+ }
+ item = table->item(row, 1);
+ item->setText(QString::fromStdString(variable->Value(false)));
+ item = table->item(row, 2);
+ item->setText(getSaveActionString(variable.get()));
+ item = table->item(row, 3);
+ item->setText(getLastUsedString(variable.get()));
+ }
+}
+
+static void renameVariable(QTableWidget *table, const QString &oldName,
+ const QString &newName)
+{
+ for (int row = 0; row < table->rowCount(); row++) {
+ auto item = table->item(row, 0);
+ if (!item) {
+ continue;
+ }
+ if (item->text() == oldName) {
+ item->setText(newName);
+ table->sortByColumn(0, Qt::AscendingOrder);
+ return;
+ }
+ }
+ blog(LOG_INFO, "%s called but entry \"%s\" not found", __func__,
+ oldName.toStdString().c_str());
+ assert(false);
+}
+
+static void openSettingsDialogAtRow(QTableWidget *table, int row)
+{
+ auto item = table->item(row, 0);
+ if (!item) {
+ return;
+ }
+ auto weakVariable = GetWeakVariableByQString(item->text());
+ auto variable = weakVariable.lock();
+ if (!variable) {
+ return;
+ }
+ auto oldName = variable->Name();
+
+ bool accepted =
+ VariableSettingsDialog::AskForSettings(table, *variable.get());
+ if (accepted && oldName != variable->Name()) {
+ VariableSignalManager::Instance()->Rename(
+ QString::fromStdString(oldName),
+ QString::fromStdString(variable->Name()));
+ }
+}
+
+void AdvSceneSwitcher::SetupVariableTab()
+{
+ if (GetVariables().empty()) {
+ setVariableTabVisible(ui->tabWidget, false);
+ } else {
+ ui->variablesHelp->hide();
+ }
+
+ static const QStringList horizontalHeaders =
+ QStringList()
+ << obs_module_text("AdvSceneSwitcher.variableTab.header.name")
+ << obs_module_text("AdvSceneSwitcher.variableTab.header.value")
+ << obs_module_text(
+ "AdvSceneSwitcher.variableTab.header.saveLoadBehavior")
+ << obs_module_text(
+ "AdvSceneSwitcher.variableTab.header.lastUse");
+
+ auto &variables = GetVariables();
+
+ ui->variables->setColumnCount(horizontalHeaders.size());
+ ui->variables->horizontalHeader()->setSectionResizeMode(
+ QHeaderView::ResizeMode::Stretch);
+ ui->variables->setHorizontalHeaderLabels(horizontalHeaders);
+
+ for (const auto &var : variables) {
+ auto variable = std::static_pointer_cast(var);
+ addVariableRow(ui->variables, variable.get());
+ }
+
+ ui->variables->resizeColumnsToContents();
+ ui->variables->resizeRowsToContents();
+
+ QWidget::connect(
+ VariableSignalManager::Instance(),
+ &VariableSignalManager::Rename,
+ [this](const QString &oldName, const QString &newName) {
+ renameVariable(ui->variables, oldName, newName);
+ });
+ QWidget::connect(VariableSignalManager::Instance(),
+ &VariableSignalManager::Add, this,
+ [this](const QString &name) {
+ addVariableRow(ui->variables,
+ GetVariableByQString(name));
+ ui->variablesHelp->hide();
+ setVariableTabVisible(ui->tabWidget, true);
+ });
+ QWidget::connect(VariableSignalManager::Instance(),
+ &VariableSignalManager::Remove, this,
+ [this](const QString &name) {
+ removeVariableRow(ui->variables, name);
+ if (ui->variables->rowCount() == 0) {
+ ui->variablesHelp->show();
+ }
+ });
+ QWidget::connect(ui->variables, &QTableWidget::cellDoubleClicked,
+ [this](int row, int _) {
+ openSettingsDialogAtRow(ui->variables, row);
+ });
+
+ auto timer = new QTimer(this);
+ timer->setInterval(1000);
+ QWidget::connect(timer, &QTimer::timeout,
+ [this]() { updateVaribleStatus(ui->variables); });
+ timer->start();
+}
+
+void AdvSceneSwitcher::on_variableAdd_clicked()
+{
+ auto newVariable = std::make_shared();
+ auto accepted =
+ VariableSettingsDialog::AskForSettings(this, *newVariable);
+ if (!accepted) {
+ return;
+ }
+ {
+ auto lock = LockContext();
+ auto &variables = GetVariables();
+ variables.emplace_back(newVariable);
+ }
+
+ VariableSignalManager::Instance()->Add(
+ QString::fromStdString(newVariable->Name()));
+}
+
+void AdvSceneSwitcher::on_variableRemove_clicked()
+{
+ auto selectedItems = ui->variables->selectedItems();
+ QList selectedRows;
+ for (auto item : selectedItems) {
+ int row = item->row();
+ if (!selectedRows.contains(row)) {
+ selectedRows.append(row);
+ }
+ }
+
+ if (selectedRows.empty()) {
+ return;
+ }
+
+ QStringList names;
+ for (int row : selectedRows) {
+ auto item = ui->variables->item(row, 0);
+ if (!item) {
+ continue;
+ }
+ names << item->text();
+ }
+
+ for (const auto &name : names) {
+ VariableSignalManager::Instance()->Remove(name);
+ }
+
+ auto lock = LockContext();
+ for (const auto &name : names) {
+ auto variable = GetVariableByQString(name);
+ if (!variable) {
+ continue;
+ }
+
+ auto &variables = GetVariables();
+ variables.erase(
+ std::remove_if(
+ variables.begin(), variables.end(),
+ [variable](const std::shared_ptr- &item) {
+ return item.get() == variable;
+ }),
+ variables.end());
+ }
+}
+
+} // namespace advss