From 3fc82df278477a8c68eabaff625fd05c7ce2eef4 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Sat, 17 Jul 2021 17:28:10 +0200 Subject: [PATCH] Handle macro control signals --- src/headers/advanced-scene-switcher.hpp | 14 ++ src/headers/macro-action-edit.hpp | 17 +- src/headers/macro-condition-edit.hpp | 14 ++ src/headers/macro.hpp | 15 +- src/headers/utility.hpp | 1 + src/macro-action-edit.cpp | 172 ++++++++++++++++--- src/macro-condition-edit.cpp | 213 ++++++++++++++++++++---- src/macro-tab.cpp | 26 +++ src/macro.cpp | 20 +++ src/utility.cpp | 11 ++ 10 files changed, 450 insertions(+), 53 deletions(-) diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 43124e8e..167d4be9 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -14,6 +14,8 @@ } class QCloseEvent; +class MacroActionEdit; +class MacroConditionEdit; /******************************************************************************* * Advanced Scene Switcher window @@ -47,6 +49,10 @@ public: bool addNewMacro(std::string &name); Macro *getSelectedMacro(); void SetEditMacro(Macro &m); + void ConnectControlSignals(MacroActionEdit *); + void ConnectControlSignals(MacroConditionEdit *); + void SwapActions(Macro *m, int pos1, int pos2); + void SwapConditions(Macro *m, int pos1, int pos2); void loadUI(); void setupGeneralTab(); @@ -111,6 +117,14 @@ public slots: void on_actionRemove_clicked(); void showMacroContextMenu(const QPoint &); void copyMacro(); + void AddMacroAction(int idx); + void RemoveMacroAction(int idx); + void MoveMacroActionUp(int idx); + void MoveMacroActionDown(int idx); + void AddMacroCondition(int idx); + void RemoveMacroCondition(int idx); + void MoveMacroConditionUp(int idx); + void MoveMacroConditionDown(int idx); void on_screenRegionSwitches_currentRowChanged(int idx); void on_showFrame_clicked(); diff --git a/src/headers/macro-action-edit.hpp b/src/headers/macro-action-edit.hpp index 5b095f3c..9b857d8c 100644 --- a/src/headers/macro-action-edit.hpp +++ b/src/headers/macro-action-edit.hpp @@ -1,4 +1,7 @@ #pragma once +#include "macro.hpp" +#include "section.hpp" +#include "macro-entry-controls.hpp" #include #include @@ -6,8 +9,6 @@ #include #include #include -#include "macro.hpp" -#include "section.hpp" struct MacroActionInfo { using TCreateMethod = std::shared_ptr (*)(); @@ -46,6 +47,10 @@ public: private slots: void ActionSelectionChanged(const QString &text); void HeaderInfoChanged(const QString &); + void Add(); + void Remove(); + void Up(); + void Down(); signals: void MacroAdded(const QString &name); void MacroRemoved(const QString &name); @@ -53,11 +58,19 @@ signals: void SceneGroupAdded(const QString &name); void SceneGroupRemoved(const QString &name); void SceneGroupRenamed(const QString &oldName, const QString newName); + void AddAt(int idx); + void RemoveAt(int idx); + void UpAt(int idx); + void DownAt(int idx); protected: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + QComboBox *_actionSelection; Section *_section; QLabel *_headerInfo; + MacroEntryControls *_controls; std::shared_ptr *_entryData; diff --git a/src/headers/macro-condition-edit.hpp b/src/headers/macro-condition-edit.hpp index 75e00f2c..6ea52dad 100644 --- a/src/headers/macro-condition-edit.hpp +++ b/src/headers/macro-condition-edit.hpp @@ -4,6 +4,7 @@ #include "macro.hpp" #include "macro-condition-scene.hpp" #include "section.hpp" +#include "macro-entry-controls.hpp" #include "utility.hpp" #include @@ -43,6 +44,7 @@ public: const std::string &id = "scene", bool root = true, bool startCollapsed = false); bool IsRootNode(); + void SetRootNode(bool); void UpdateEntryData(const std::string &id, bool collapse); private slots: @@ -52,6 +54,10 @@ private slots: void DurationConditionChanged(DurationCondition cond); void DurationUnitChanged(DurationUnit unit); void HeaderInfoChanged(const QString &); + void Add(); + void Remove(); + void Up(); + void Down(); signals: void MacroAdded(const QString &name); void MacroRemoved(const QString &name); @@ -59,13 +65,21 @@ signals: void SceneGroupAdded(const QString &name); void SceneGroupRemoved(const QString &name); void SceneGroupRenamed(const QString &oldName, const QString newName); + void AddAt(int idx); + void RemoveAt(int idx); + void UpAt(int idx); + void DownAt(int idx); protected: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + QComboBox *_logicSelection; QComboBox *_conditionSelection; Section *_section; QLabel *_headerInfo; DurationConstraintEdit *_dur; + MacroEntryControls *_controls; std::shared_ptr *_entryData; diff --git a/src/headers/macro.hpp b/src/headers/macro.hpp index 3947f1c6..b7d69a00 100644 --- a/src/headers/macro.hpp +++ b/src/headers/macro.hpp @@ -36,7 +36,16 @@ struct LogicTypeInfo { std::string _name; }; -class MacroCondition { +class MacroSegment { +public: + void SetIndex(int idx) { _idx = idx; } + int GetIndex() { return _idx; } + +protected: + int _idx; +}; + +class MacroCondition : public MacroSegment { public: virtual bool CheckCondition() = 0; virtual bool Save(obs_data_t *obj) = 0; @@ -61,7 +70,7 @@ private: DurationConstraint _duration; }; -class MacroAction { +class MacroAction : public MacroSegment { public: virtual bool PerformAction() = 0; virtual bool Save(obs_data_t *obj) = 0; @@ -89,6 +98,8 @@ public: { return _conditions; } + void UpdateActionIndices(); + void UpdateConditionIndices(); std::deque> &Actions() { return _actions; } bool Save(obs_data_t *obj); diff --git a/src/headers/utility.hpp b/src/headers/utility.hpp index 48696f40..39a03117 100644 --- a/src/headers/utility.hpp +++ b/src/headers/utility.hpp @@ -44,6 +44,7 @@ QString fromatJsonString(const char *); void placeWidgets(std::string text, QBoxLayout *layout, std::unordered_map placeholders, bool addStretch = true); +void deleteLayoutItem(QLayoutItem *item); void clearLayout(QLayout *layout); QMetaObject::Connection PulseWidget(QWidget *widget, QColor endColor, QColor = QColor(0, 0, 0, 0), diff --git a/src/macro-action-edit.cpp b/src/macro-action-edit.cpp index 7016aea3..709056bd 100644 --- a/src/macro-action-edit.cpp +++ b/src/macro-action-edit.cpp @@ -65,10 +65,12 @@ MacroActionEdit::MacroActionEdit(QWidget *parent, _actionSelection = new QComboBox(); _section = new Section(300); _headerInfo = new QLabel(); + _controls = new MacroEntryControls(); QWidget::connect(_actionSelection, SIGNAL(currentTextChanged(const QString &)), this, SLOT(ActionSelectionChanged(const QString &))); + // Macro signals QWidget::connect(parent, SIGNAL(MacroAdded(const QString &)), this, SIGNAL(MacroAdded(const QString &))); QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this, @@ -77,6 +79,8 @@ MacroActionEdit::MacroActionEdit(QWidget *parent, SIGNAL(MacroRenamed(const QString &, const QString)), this, SIGNAL(MacroRenamed(const QString &, const QString))); + + // Scene group signals QWidget::connect(parent, SIGNAL(SceneGroupAdded(const QString &)), this, SIGNAL(SceneGroupAdded(const QString &))); QWidget::connect(parent, SIGNAL(SceneGroupRemoved(const QString &)), @@ -86,6 +90,12 @@ MacroActionEdit::MacroActionEdit(QWidget *parent, SIGNAL(SceneGroupRenamed(const QString &, const QString)), this, SIGNAL(SceneGroupRenamed(const QString &, const QString))); + // Control signals + QWidget::connect(_controls, SIGNAL(Add()), this, SLOT(Add())); + QWidget::connect(_controls, SIGNAL(Remove()), this, SLOT(Remove())); + QWidget::connect(_controls, SIGNAL(Up()), this, SLOT(Up())); + QWidget::connect(_controls, SIGNAL(Down()), this, SLOT(Down())); + populateActionSelection(_actionSelection); _section->AddHeaderWidget(_actionSelection); @@ -93,6 +103,7 @@ MacroActionEdit::MacroActionEdit(QWidget *parent, QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(_section); + mainLayout->addWidget(_controls); setLayout(mainLayout); _entryData = entryData; @@ -101,6 +112,16 @@ MacroActionEdit::MacroActionEdit(QWidget *parent, _loading = false; } +void MacroActionEdit::enterEvent(QEvent *) +{ + _controls->Show(true); +} + +void MacroActionEdit::leaveEvent(QEvent *) +{ + _controls->Show(false); +} + void MacroActionEdit::ActionSelectionChanged(const QString &text) { if (_loading || !_entryData) { @@ -137,48 +158,157 @@ void MacroActionEdit::HeaderInfoChanged(const QString &text) _headerInfo->setText(text); } -void AdvSceneSwitcher::on_actionAdd_clicked() +void MacroActionEdit::Add() +{ + if (_entryData) { + // Insert after current entry + emit AddAt((*_entryData)->GetIndex() + 1); + } +} + +void MacroActionEdit::Remove() +{ + if (_entryData) { + emit RemoveAt((*_entryData)->GetIndex()); + } +} + +void MacroActionEdit::Up() +{ + if (_entryData) { + emit UpAt((*_entryData)->GetIndex()); + } +} + +void MacroActionEdit::Down() +{ + if (_entryData) { + emit DownAt((*_entryData)->GetIndex()); + } +} + +void AdvSceneSwitcher::AddMacroAction(int idx) { auto macro = getSelectedMacro(); if (!macro) { return; } + if (idx < 0 || idx > macro->Actions().size()) { + return; + } + MacroActionSwitchScene temp; std::string id = temp.GetId(); std::lock_guard lock(switcher->m); - macro->Actions().emplace_back(MacroActionFactory::Create(id)); - auto newEntry = - new MacroActionEdit(this, ¯o->Actions().back(), id, false); - ui->macroEditActionLayout->addWidget(newEntry); + auto action = macro->Actions().emplace(macro->Actions().begin() + idx, + MacroActionFactory::Create(id)); + macro->UpdateActionIndices(); + + // All entry pointers in existing edit widgets after the new entry will + // be invalidated by adding the new entry so we have to recreate them + // and because I am lazy I am recreating every widget. + // + // If performance should become a concern this has to be revisited. + SetEditMacro(*macro); +} + +void AdvSceneSwitcher::on_actionAdd_clicked() +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + AddMacroAction((int)macro->Actions().size()); ui->macroEditActionHelp->setVisible(false); } +void AdvSceneSwitcher::RemoveMacroAction(int idx) +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + if (idx < 0 || idx >= macro->Actions().size()) { + return; + } + + std::lock_guard lock(switcher->m); + macro->Actions().erase(macro->Actions().begin() + idx); + macro->UpdateActionIndices(); + + // All entry pointers in existing edit widgets after the new entry will + // be invalidated by adding the new entry so we have to recreate them + // and because I am lazy I am recreating every widget. + // + // If performance should become a concern this has to be revisited. + SetEditMacro(*macro); +} + void AdvSceneSwitcher::on_actionRemove_clicked() { auto macro = getSelectedMacro(); if (!macro) { return; } - std::lock_guard lock(switcher->m); - if (macro->Actions().empty()) { + RemoveMacroAction((int)macro->Actions().size() - 1); +} + +void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2) +{ + if (pos1 == pos2) { return; } - macro->Actions().pop_back(); - - int count = ui->macroEditActionLayout->count(); - auto item = ui->macroEditActionLayout->takeAt(count - 1); - - if (item) { - auto widget = item->widget(); - if (widget) { - widget->setVisible(false); - } - delete item; + if (pos1 > pos2) { + std::swap(pos1, pos2); } - if (count == 1) { - ui->macroEditActionHelp->setVisible(true); - } + std::lock_guard lock(switcher->m); + iter_swap(m->Actions().begin() + pos1, m->Actions().begin() + pos2); + m->UpdateActionIndices(); + + auto a1 = m->Actions().begin() + pos1; + auto a2 = m->Actions().begin() + pos2; + + auto item1 = ui->macroEditActionLayout->takeAt(pos1); + auto item2 = ui->macroEditActionLayout->takeAt(pos2 - 1); + deleteLayoutItem(item1); + deleteLayoutItem(item2); + auto widget1 = new MacroActionEdit(this, &(*a1), (*a1)->GetId(), false); + auto widget2 = new MacroActionEdit(this, &(*a2), (*a2)->GetId(), false); + ConnectControlSignals(widget1); + ConnectControlSignals(widget2); + ui->macroEditActionLayout->insertWidget(pos1, widget1); + ui->macroEditActionLayout->insertWidget(pos2, widget2); +} + +void AdvSceneSwitcher::MoveMacroActionUp(int idx) +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + if (idx < 1 || idx >= macro->Actions().size()) { + return; + } + + SwapActions(macro, idx, idx - 1); +} + +void AdvSceneSwitcher::MoveMacroActionDown(int idx) +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + if (idx < 0 || idx >= macro->Actions().size() - 1) { + return; + } + + SwapActions(macro, idx, idx + 1); } diff --git a/src/macro-condition-edit.cpp b/src/macro-condition-edit.cpp index cea78ae6..4e577387 100644 --- a/src/macro-condition-edit.cpp +++ b/src/macro-condition-edit.cpp @@ -88,13 +88,14 @@ static inline void populateConditionSelection(QComboBox *list) MacroConditionEdit::MacroConditionEdit( QWidget *parent, std::shared_ptr *entryData, const std::string &id, bool root, bool startCollapsed) - : QWidget(parent) + : QWidget(parent), _isRoot(root), _entryData(entryData) { _logicSelection = new QComboBox(); _conditionSelection = new QComboBox(); _section = new Section(300); _headerInfo = new QLabel(); _dur = new DurationConstraintEdit(); + _controls = new MacroEntryControls(); QWidget::connect(_logicSelection, SIGNAL(currentIndexChanged(int)), this, SLOT(LogicSelectionChanged(int))); @@ -108,6 +109,8 @@ MacroConditionEdit::MacroConditionEdit( QWidget::connect(_dur, SIGNAL(ConditionChanged(DurationCondition)), this, SLOT(DurationConditionChanged(DurationCondition))); + + // Macro signals QWidget::connect(parent, SIGNAL(MacroAdded(const QString &)), this, SIGNAL(MacroAdded(const QString &))); QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this, @@ -116,6 +119,8 @@ MacroConditionEdit::MacroConditionEdit( SIGNAL(MacroRenamed(const QString &, const QString)), this, SIGNAL(MacroRenamed(const QString &, const QString))); + + // Scene group signals QWidget::connect(parent, SIGNAL(SceneGroupAdded(const QString &)), this, SIGNAL(SceneGroupAdded(const QString &))); QWidget::connect(parent, SIGNAL(SceneGroupRemoved(const QString &)), @@ -125,6 +130,12 @@ MacroConditionEdit::MacroConditionEdit( SIGNAL(SceneGroupRenamed(const QString &, const QString)), this, SIGNAL(SceneGroupRenamed(const QString &, const QString))); + // Control signals + QWidget::connect(_controls, SIGNAL(Add()), this, SLOT(Add())); + QWidget::connect(_controls, SIGNAL(Remove()), this, SLOT(Remove())); + QWidget::connect(_controls, SIGNAL(Up()), this, SLOT(Up())); + QWidget::connect(_controls, SIGNAL(Down()), this, SLOT(Down())); + populateLogicSelection(_logicSelection, root); populateConditionSelection(_conditionSelection); @@ -135,14 +146,23 @@ MacroConditionEdit::MacroConditionEdit( QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(_section); + mainLayout->addWidget(_controls); setLayout(mainLayout); - _entryData = entryData; - _isRoot = root; UpdateEntryData(id, startCollapsed); _loading = false; } +void MacroConditionEdit::enterEvent(QEvent *) +{ + _controls->Show(true); +} + +void MacroConditionEdit::leaveEvent(QEvent *) +{ + _controls->Show(false); +} + void MacroConditionEdit::LogicSelectionChanged(int idx) { if (_loading || !_entryData) { @@ -165,6 +185,13 @@ bool MacroConditionEdit::IsRootNode() return _isRoot; } +void MacroConditionEdit::SetRootNode(bool root) +{ + const QSignalBlocker blocker(_logicSelection); + _logicSelection->clear(); + populateLogicSelection(_logicSelection, root); +} + void MacroConditionEdit::UpdateEntryData(const std::string &id, bool collapse) { _conditionSelection->setCurrentText(obs_module_text( @@ -250,24 +277,107 @@ void MacroConditionEdit::HeaderInfoChanged(const QString &text) _headerInfo->setText(text); } +void MacroConditionEdit::Add() +{ + if (_entryData) { + // Insert after current entry + emit AddAt((*_entryData)->GetIndex() + 1); + } +} + +void MacroConditionEdit::Remove() +{ + if (_entryData) { + emit RemoveAt((*_entryData)->GetIndex()); + } +} + +void MacroConditionEdit::Up() +{ + if (_entryData) { + emit UpAt((*_entryData)->GetIndex()); + } +} + +void MacroConditionEdit::Down() +{ + if (_entryData) { + emit DownAt((*_entryData)->GetIndex()); + } +} + +void AdvSceneSwitcher::AddMacroCondition(int idx) +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + if (idx < 0 || idx > macro->Conditions().size()) { + return; + } + + MacroConditionScene temp; + std::string id = temp.GetId(); + + std::lock_guard lock(switcher->m); + bool root = idx == 0; + auto cond = + macro->Conditions().emplace(macro->Conditions().begin() + idx, + MacroConditionFactory::Create(id)); + auto logic = root ? LogicType::ROOT_NONE : LogicType::NONE; + (*cond)->SetLogicType(logic); + macro->UpdateConditionIndices(); + + // All entry pointers in existing edit widgets after the new entry will + // be invalidated by adding the new entry so we have to recreate them + // and because I am lazy I am recreating every widget. + // + // If performance should become a concern this has to be revisited. + SetEditMacro(*macro); +} + void AdvSceneSwitcher::on_conditionAdd_clicked() { auto macro = getSelectedMacro(); if (!macro) { return; } - MacroConditionScene temp; - std::string id = temp.GetId(); + + AddMacroCondition((int)macro->Conditions().size()); + ui->macroEditConditionHelp->setVisible(false); +} + +void AdvSceneSwitcher::RemoveMacroCondition(int idx) +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + if (idx < 0 || idx >= macro->Conditions().size()) { + return; + } std::lock_guard lock(switcher->m); - bool root = macro->Conditions().size() == 0; - macro->Conditions().emplace_back(MacroConditionFactory::Create(id)); - auto logic = root ? LogicType::ROOT_NONE : LogicType::NONE; - macro->Conditions().back()->SetLogicType(logic); - auto newEntry = new MacroConditionEdit( - this, ¯o->Conditions().back(), id, root, false); - ui->macroEditConditionLayout->addWidget(newEntry); - ui->macroEditConditionHelp->setVisible(false); + macro->Conditions().erase(macro->Conditions().begin() + idx); + macro->UpdateConditionIndices(); + + if (macro->Conditions().size() == 0) { + ui->macroEditConditionHelp->setVisible(true); + } + + if (idx == 0 && macro->Conditions().size() > 0) { + auto newRoot = macro->Conditions().at(0); + newRoot->SetLogicType(LogicType::ROOT_NONE); + } + + // All entry pointers in existing edit widgets after the new entry will + // be invalidated by adding the new entry so we have to recreate them + // and because I am lazy I am recreating every widget. + // + // If performance should become a concern this has to be revisited. + SetEditMacro(*macro); } void AdvSceneSwitcher::on_conditionRemove_clicked() @@ -276,24 +386,71 @@ void AdvSceneSwitcher::on_conditionRemove_clicked() if (!macro) { return; } - std::lock_guard lock(switcher->m); - if (macro->Conditions().empty()) { + RemoveMacroCondition((int)macro->Conditions().size() - 1); +} + +void AdvSceneSwitcher::SwapConditions(Macro *m, int pos1, int pos2) +{ + if (pos1 == pos2) { return; } - macro->Conditions().pop_back(); - - int count = ui->macroEditConditionLayout->count(); - auto item = ui->macroEditConditionLayout->takeAt(count - 1); - - if (item) { - auto widget = item->widget(); - if (widget) { - widget->setVisible(false); - } - delete item; + if (pos1 > pos2) { + std::swap(pos1, pos2); } - if (count == 1) { - ui->macroEditConditionHelp->setVisible(true); + bool root = pos1 == 0; + std::lock_guard lock(switcher->m); + iter_swap(m->Conditions().begin() + pos1, + m->Conditions().begin() + pos2); + m->UpdateConditionIndices(); + + auto c1 = m->Conditions().begin() + pos1; + auto c2 = m->Conditions().begin() + pos2; + if (root) { + auto logic1 = (*c1)->GetLogicType(); + auto logic2 = (*c2)->GetLogicType(); + (*c1)->SetLogicType(logic2); + (*c2)->SetLogicType(logic1); } + + auto item1 = ui->macroEditConditionLayout->takeAt(pos1); + auto item2 = ui->macroEditConditionLayout->takeAt(pos2 - 1); + deleteLayoutItem(item1); + deleteLayoutItem(item2); + auto widget1 = new MacroConditionEdit(this, &(*c1), (*c1)->GetId(), + root, false); + auto widget2 = new MacroConditionEdit(this, &(*c2), (*c2)->GetId(), + false, false); + ConnectControlSignals(widget1); + ConnectControlSignals(widget2); + ui->macroEditConditionLayout->insertWidget(pos1, widget1); + ui->macroEditConditionLayout->insertWidget(pos2, widget2); +} + +void AdvSceneSwitcher::MoveMacroConditionUp(int idx) +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + if (idx < 1 || idx >= macro->Conditions().size()) { + return; + } + + SwapConditions(macro, idx, idx - 1); +} + +void AdvSceneSwitcher::MoveMacroConditionDown(int idx) +{ + auto macro = getSelectedMacro(); + if (!macro) { + return; + } + + if (idx < 0 || idx >= macro->Conditions().size() - 1) { + return; + } + + SwapConditions(macro, idx, idx + 1); } diff --git a/src/macro-tab.cpp b/src/macro-tab.cpp index 27f4c78a..8e16cd26 100644 --- a/src/macro-tab.cpp +++ b/src/macro-tab.cpp @@ -180,6 +180,7 @@ void AdvSceneSwitcher::SetEditMacro(Macro &m) for (auto &c : m.Conditions()) { auto newEntry = new MacroConditionEdit(this, &c, c->GetId(), root, collapse); + ConnectControlSignals(newEntry); ui->macroEditConditionLayout->addWidget(newEntry); ui->macroEditConditionHelp->setVisible(false); root = false; @@ -189,6 +190,7 @@ void AdvSceneSwitcher::SetEditMacro(Macro &m) for (auto &a : m.Actions()) { auto newEntry = new MacroActionEdit(this, &a, a->GetId(), collapse); + ConnectControlSignals(newEntry); ui->macroEditActionLayout->addWidget(newEntry); ui->macroEditActionHelp->setVisible(false); } @@ -208,6 +210,30 @@ void AdvSceneSwitcher::SetEditMacro(Macro &m) } } +void AdvSceneSwitcher::ConnectControlSignals(MacroActionEdit *c) +{ + connect(c, &MacroActionEdit::AddAt, this, + &AdvSceneSwitcher::AddMacroAction); + connect(c, &MacroActionEdit::RemoveAt, this, + &AdvSceneSwitcher::RemoveMacroAction); + connect(c, &MacroActionEdit::UpAt, this, + &AdvSceneSwitcher::MoveMacroActionUp); + connect(c, &MacroActionEdit::DownAt, this, + &AdvSceneSwitcher::MoveMacroActionDown); +} + +void AdvSceneSwitcher::ConnectControlSignals(MacroConditionEdit *c) +{ + connect(c, &MacroConditionEdit::AddAt, this, + &AdvSceneSwitcher::AddMacroCondition); + connect(c, &MacroConditionEdit::RemoveAt, this, + &AdvSceneSwitcher::RemoveMacroCondition); + connect(c, &MacroConditionEdit::UpAt, this, + &AdvSceneSwitcher::MoveMacroConditionUp); + connect(c, &MacroConditionEdit::DownAt, this, + &AdvSceneSwitcher::MoveMacroConditionDown); +} + Macro *AdvSceneSwitcher::getSelectedMacro() { QListWidgetItem *item = ui->macros->currentItem(); diff --git a/src/macro.cpp b/src/macro.cpp index 52e3d97f..c9bafcec 100644 --- a/src/macro.cpp +++ b/src/macro.cpp @@ -124,6 +124,24 @@ void Macro::SetName(const std::string &name) SetHotkeysDesc(); } +void Macro::UpdateActionIndices() +{ + int idx = 0; + for (auto a : _actions) { + a->SetIndex(idx); + idx++; + } +} + +void Macro::UpdateConditionIndices() +{ + int idx = 0; + for (auto c : _conditions) { + c->SetIndex(idx); + idx++; + } +} + bool Macro::Save(obs_data_t *obj) { obs_data_set_string(obj, "name", _name.c_str()); @@ -238,6 +256,7 @@ bool Macro::Load(obs_data_t *obj) root = false; } obs_data_array_release(conditions); + UpdateConditionIndices(); obs_data_array_t *actions = obs_data_get_array(obj, "actions"); count = obs_data_array_count(actions); @@ -260,6 +279,7 @@ bool Macro::Load(obs_data_t *obj) obs_data_release(array_obj); } obs_data_array_release(actions); + UpdateActionIndices(); return true; } diff --git a/src/utility.cpp b/src/utility.cpp index a5862bf7..f68d000c 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -174,6 +174,17 @@ void placeWidgets(std::string text, QBoxLayout *layout, } } +void deleteLayoutItem(QLayoutItem *item) +{ + if (item) { + auto widget = item->widget(); + if (widget) { + widget->setVisible(false); + } + delete item; + } +} + void clearLayout(QLayout *layout) { QLayoutItem *item;