Add undo / redo support for macros

This commit is contained in:
WarmUpTill
2026-08-12 11:48:53 +02:00
parent 71e1e395df
commit 151f69305b
9 changed files with 1142 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
#include "macro-edit.hpp"
#include "condition-logic.hpp"
#include "macro-undo-redo.hpp"
#include "cursor-shape-changer.hpp"
#include "macro-action-edit.hpp"
#include "macro-action-macro.hpp"
@@ -257,6 +258,92 @@ std::shared_ptr<Macro> MacroEdit::GetMacro() const
return _currentMacro;
}
void MacroEdit::InsertSegmentWidget(SegmentType type, int idx)
{
auto macro = _currentMacro;
if (!macro) {
return;
}
switch (type) {
case SegmentType::ACTION: {
if (idx < 0 || idx > (int)macro->Actions().size()) {
break;
}
ui->actionsList->Insert(
idx, new MacroActionEdit(this, &macro->Actions()[idx]));
SetActionData(*macro);
ui->actionsList->SetHelpMsgVisible(false);
break;
}
case SegmentType::ELSE_ACTION: {
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
break;
}
ui->elseActionsList->Insert(
idx,
new MacroActionEdit(this, &macro->ElseActions()[idx]));
SetElseActionData(*macro);
ui->elseActionsList->SetHelpMsgVisible(false);
break;
}
case SegmentType::CONDITION: {
if (idx < 0 || idx > (int)macro->Conditions().size()) {
break;
}
ui->conditionsList->Insert(
idx,
new MacroConditionEdit(this, &macro->Conditions()[idx],
idx == 0));
if (idx == 0 && macro->Conditions().size() > 1) {
static_cast<MacroConditionEdit *>(
ui->conditionsList->WidgetAt(1))
->SetRootNode(false);
}
SetConditionData(*macro);
ui->conditionsList->SetHelpMsgVisible(false);
break;
}
}
}
void MacroEdit::RemoveSegmentWidget(SegmentType type, int idx)
{
auto macro = _currentMacro;
if (!macro) {
return;
}
switch (type) {
case SegmentType::ACTION:
if (idx >= 0 &&
idx < ui->actionsList->ContentLayout()->count()) {
ui->actionsList->Remove(idx);
SetActionData(*macro);
}
break;
case SegmentType::ELSE_ACTION:
if (idx >= 0 &&
idx < ui->elseActionsList->ContentLayout()->count()) {
ui->elseActionsList->Remove(idx);
SetElseActionData(*macro);
}
break;
case SegmentType::CONDITION:
if (idx >= 0 &&
idx < ui->conditionsList->ContentLayout()->count()) {
ui->conditionsList->Remove(idx);
if (idx == 0 && !macro->Conditions().empty()) {
static_cast<MacroConditionEdit *>(
ui->conditionsList->WidgetAt(0))
->SetRootNode(true);
}
SetConditionData(*macro);
}
break;
}
}
void MacroEdit::ClearSegmentWidgetCacheFor(Macro *macro) const
{
ui->conditionsList->ClearWidgetsFromCacheFor(macro);
@@ -295,7 +382,7 @@ isValidMacroSegmentIdx(const std::deque<std::shared_ptr<MacroSegment>> &list,
return (idx > 0 || (unsigned)idx < list.size());
}
void MacroEdit::SetupMacroSegmentSelection(MacroSection type, int idx)
void MacroEdit::SetupMacroSegmentSelection(SegmentType type, int idx)
{
auto macro = _currentMacro;
if (!macro) {
@@ -308,7 +395,7 @@ void MacroEdit::SetupMacroSegmentSelection(MacroSection type, int idx)
std::deque<std::shared_ptr<MacroSegment>> segments;
switch (type) {
case MacroEdit::MacroSection::CONDITIONS:
case MacroEdit::SegmentType::CONDITION:
setList = ui->conditionsList;
setIdx = &currentConditionIdx;
segments = {macro->Conditions().begin(),
@@ -319,7 +406,7 @@ void MacroEdit::SetupMacroSegmentSelection(MacroSection type, int idx)
resetIdx1 = &currentActionIdx;
resetIdx2 = &currentElseActionIdx;
break;
case MacroEdit::MacroSection::ACTIONS:
case MacroEdit::SegmentType::ACTION:
setList = ui->actionsList;
setIdx = &currentActionIdx;
segments = {macro->Actions().begin(), macro->Actions().end()};
@@ -329,7 +416,7 @@ void MacroEdit::SetupMacroSegmentSelection(MacroSection type, int idx)
resetIdx1 = &currentConditionIdx;
resetIdx2 = &currentElseActionIdx;
break;
case MacroEdit::MacroSection::ELSE_ACTIONS:
case MacroEdit::SegmentType::ELSE_ACTION:
setList = ui->elseActionsList;
setIdx = &currentElseActionIdx;
segments = {macro->ElseActions().begin(),
@@ -965,7 +1052,7 @@ void MacroEdit::UpMacroSegmentHotkey()
int conditionSize = macro->Conditions().size();
if (currentActionIdx == -1 && currentConditionIdx == -1) {
if (lastInteracted == MacroSection::CONDITIONS) {
if (lastInteracted == SegmentType::CONDITION) {
if (conditionSize == 0) {
MacroActionSelectionChanged(0);
} else {
@@ -1021,7 +1108,7 @@ void MacroEdit::DownMacroSegmentHotkey()
int conditionSize = macro->Conditions().size();
if (currentActionIdx == -1 && currentConditionIdx == -1) {
if (lastInteracted == MacroSection::CONDITIONS) {
if (lastInteracted == SegmentType::CONDITION) {
if (conditionSize == 0) {
MacroActionSelectionChanged(0);
} else {
@@ -1098,6 +1185,7 @@ void MacroEdit::AddMacroAction(Macro *macro, int idx, const std::string &id,
idx, new MacroActionEdit(this, &macro->Actions()[idx]));
SetActionData(*macro);
}
RegisterSegmentAddUndoRedo(macro, SegmentType::ACTION, idx);
HighlightAction(idx);
ui->actionsList->SetHelpMsgVisible(false);
emit(MacroSegmentOrderChanged());
@@ -1163,6 +1251,19 @@ void MacroEdit::RemoveMacroAction(int idx)
return;
}
{
OBSDataAutoRelease segData = obs_data_create();
std::string segId;
{
auto lock = LockContext();
macro->Actions().at(idx)->Save(segData);
segId = macro->Actions().at(idx)->GetId();
}
RegisterSegmentRemoveUndoRedo(macro.get(), SegmentType::ACTION,
idx, segId, segData,
(int)Logic::Type::ROOT_NONE);
}
{
auto lock = LockContext();
ui->actionsList->Remove(idx);
@@ -1173,7 +1274,7 @@ void MacroEdit::RemoveMacroAction(int idx)
SetActionData(*macro);
}
MacroActionSelectionChanged(-1);
lastInteracted = MacroSection::ACTIONS;
lastInteracted = SegmentType::ACTION;
emit(MacroSegmentOrderChanged());
}
@@ -1353,7 +1454,7 @@ void MacroEdit::MoveMacroActionDown(int idx)
void MacroEdit::MacroElseActionSelectionChanged(int idx)
{
SetupMacroSegmentSelection(MacroSection::ELSE_ACTIONS, idx);
SetupMacroSegmentSelection(SegmentType::ELSE_ACTION, idx);
}
void MacroEdit::MacroElseActionReorder(int to, int from)
@@ -1406,6 +1507,7 @@ void MacroEdit::AddMacroElseAction(Macro *macro, int idx, const std::string &id,
new MacroActionEdit(this, &macro->ElseActions()[idx]));
SetElseActionData(*macro);
}
RegisterSegmentAddUndoRedo(macro, SegmentType::ELSE_ACTION, idx);
HighlightElseAction(idx);
ui->elseActionsList->SetHelpMsgVisible(false);
emit(MacroSegmentOrderChanged());
@@ -1455,6 +1557,20 @@ void MacroEdit::RemoveMacroElseAction(int idx)
return;
}
{
OBSDataAutoRelease segData = obs_data_create();
std::string segId;
{
auto lock = LockContext();
macro->ElseActions().at(idx)->Save(segData);
segId = macro->ElseActions().at(idx)->GetId();
}
RegisterSegmentRemoveUndoRedo(macro.get(),
SegmentType::ELSE_ACTION, idx,
segId, segData,
(int)Logic::Type::ROOT_NONE);
}
{
auto lock = LockContext();
ui->elseActionsList->Remove(idx);
@@ -1465,7 +1581,7 @@ void MacroEdit::RemoveMacroElseAction(int idx)
SetElseActionData(*macro);
}
MacroElseActionSelectionChanged(-1);
lastInteracted = MacroSection::ELSE_ACTIONS;
lastInteracted = SegmentType::ELSE_ACTION;
emit(MacroSegmentOrderChanged());
}
@@ -1526,7 +1642,7 @@ void MacroEdit::MoveMacroElseActionDown(int idx)
void MacroEdit::MacroActionSelectionChanged(int idx)
{
SetupMacroSegmentSelection(MacroSection::ACTIONS, idx);
SetupMacroSegmentSelection(SegmentType::ACTION, idx);
}
void MacroEdit::MacroActionReorder(int to, int from)
@@ -1617,6 +1733,7 @@ void MacroEdit::AddMacroCondition(Macro *macro, int idx, const std::string &id,
idx == 0));
SetConditionData(*macro);
}
RegisterSegmentAddUndoRedo(macro, SegmentType::CONDITION, idx);
HighlightCondition(idx);
ui->conditionsList->SetHelpMsgVisible(false);
emit(MacroSegmentOrderChanged());
@@ -1652,6 +1769,21 @@ void MacroEdit::RemoveMacroCondition(int idx)
return;
}
{
OBSDataAutoRelease segData = obs_data_create();
std::string segId;
int logic;
{
auto lock = LockContext();
macro->Conditions().at(idx)->Save(segData);
segId = macro->Conditions().at(idx)->GetId();
logic = (int)macro->Conditions().at(idx)->GetLogicType();
}
RegisterSegmentRemoveUndoRedo(macro.get(),
SegmentType::CONDITION, idx,
segId, segData, logic);
}
{
auto lock = LockContext();
ui->conditionsList->Remove(idx);
@@ -1667,7 +1799,7 @@ void MacroEdit::RemoveMacroCondition(int idx)
SetConditionData(*macro);
}
MacroConditionSelectionChanged(-1);
lastInteracted = MacroSection::CONDITIONS;
lastInteracted = SegmentType::CONDITION;
emit(MacroSegmentOrderChanged());
}
@@ -1792,7 +1924,7 @@ void MacroEdit::MoveMacroConditionDown(int idx)
void MacroEdit::MacroConditionSelectionChanged(int idx)
{
SetupMacroSegmentSelection(MacroSection::CONDITIONS, idx);
SetupMacroSegmentSelection(SegmentType::CONDITION, idx);
}
void MacroEdit::MacroConditionReorder(int to, int from)