From be44577967dbce2d9227f014b3a12685cfdd2633 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Sun, 2 Jun 2024 00:01:47 +0200 Subject: [PATCH] Add option to set input variable values to Macro action --- data/locale/en-US.ini | 4 +- lib/macro/macro-action-macro.cpp | 131 ++++++++++++++++++++++--------- lib/macro/macro-action-macro.hpp | 14 +++- 3 files changed, 109 insertions(+), 40 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 77a9f53c..cee7eb84 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -185,7 +185,7 @@ AdvSceneSwitcher.macroTab.generalSettings="General settings" AdvSceneSwitcher.macroTab.inputSettings="Input settings" AdvSceneSwitcher.macroTab.inputSettings.description="This section will allow you to specify variables, which will be treated as input parameters for the selected macro.\nWhen executing the macro using the \"Macro\" action type, you will have the option to set the values for those variables." AdvSceneSwitcher.macroTab.inputSettings.invalid="" -AdvSceneSwitcher.macroTab.inputSettings.noInputs="No inputs defined!\nOpen macro settings to define inputs." +AdvSceneSwitcher.macroTab.inputSettings.noInputs="No inputs are defined for the selected macro!\nOpen the settings of the macro to define inputs.\nThe settings button is highlighted above." AdvSceneSwitcher.macroTab.dockSettings="Dock settings" AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros" AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently" @@ -841,6 +841,8 @@ AdvSceneSwitcher.action.macro.type.run.conditions.false="Only if conditions eval AdvSceneSwitcher.action.macro.type.run.actionType.regular="actions" AdvSceneSwitcher.action.macro.type.run.actionType.else="else-actions" AdvSceneSwitcher.action.macro.type.run.skipWhenPaused="Skip execution when macro is paused" +AdvSceneSwitcher.action.macro.type.run.setInputs="Set inputs" +AdvSceneSwitcher.action.macro.type.run.setInputs.description="Input variables can be defined in the macro settings.\nDefining input variables will allow you to modify the values of variables before an action is executed." AdvSceneSwitcher.action.macro.type.stop="Stop actions" AdvSceneSwitcher.action.macro.type.disableAction="Disable action" AdvSceneSwitcher.action.macro.type.enableAction="Enable action" diff --git a/lib/macro/macro-action-macro.cpp b/lib/macro/macro-action-macro.cpp index b456712b..57392d21 100644 --- a/lib/macro/macro-action-macro.cpp +++ b/lib/macro/macro-action-macro.cpp @@ -1,6 +1,7 @@ #include "macro-action-macro.hpp" #include "layout-helpers.hpp" #include "macro.hpp" +#include "ui-helpers.hpp" namespace advss { @@ -175,6 +176,10 @@ void MacroActionMacro::RunActions(Macro *actionMacro) const } if (_runOptions.logic == RunOptions::Logic::IGNORE_CONDITIONS) { + if (_runOptions.setInputs) { + actionMacro->GetInputVariables().SetValues( + _runOptions.inputs); + } actionMacro->PerformActions(!_runOptions.runElseActions, false, true); return; @@ -189,6 +194,10 @@ void MacroActionMacro::RunActions(Macro *actionMacro) const conditionMacro->Matched()) || (_runOptions.logic == RunOptions::Logic::INVERT_CONDITIONS && !conditionMacro->Matched())) { + if (_runOptions.setInputs) { + actionMacro->GetInputVariables().SetValues( + _runOptions.inputs); + } actionMacro->PerformActions(!_runOptions.runElseActions, false, true); } @@ -231,8 +240,12 @@ MacroActionMacroEdit::MacroActionMacroEdit( _actionTypes(new QComboBox()), _skipWhenPaused(new QCheckBox(obs_module_text( "AdvSceneSwitcher.action.macro.type.run.skipWhenPaused"))), + _setInputs(new QCheckBox(obs_module_text( + "AdvSceneSwitcher.action.macro.type.run.setInputs"))), + _inputs(new MacroInputEdit()), _entryLayout(new QHBoxLayout()), - _conditionLayout(new QHBoxLayout()) + _conditionLayout(new QHBoxLayout()), + _setInputsLayout(new QHBoxLayout()) { populateActionSelection(_actions); populateConditionBehaviorSelection(_conditionBehaviors); @@ -256,10 +269,31 @@ MacroActionMacroEdit::MacroActionMacroEdit( SLOT(ActionTypeChanged(int))); QWidget::connect(_skipWhenPaused, SIGNAL(stateChanged(int)), this, SLOT(SkipWhenPausedChanged(int))); + QWidget::connect(_setInputs, SIGNAL(stateChanged(int)), this, + SLOT(SetInputsChanged(int))); + QWidget::connect(_inputs, + SIGNAL(MacroInputValuesChanged(const StringList &)), + this, SLOT(InputsChanged(const StringList &))); + + auto inputsDescription = new QLabel(); + QString path = GetThemeTypeName() == "Light" + ? ":/res/images/help.svg" + : ":/res/images/help_light.svg"; + QIcon icon(path); + QPixmap pixmap = icon.pixmap(QSize(16, 16)); + inputsDescription->setPixmap(pixmap); + inputsDescription->setToolTip(obs_module_text( + "AdvSceneSwitcher.action.macro.type.run.setInputs.description")); + + _setInputsLayout->addWidget(_setInputs); + _setInputsLayout->addWidget(inputsDescription); + _setInputsLayout->addStretch(); auto layout = new QVBoxLayout(); layout->addLayout(_entryLayout); layout->addLayout(_conditionLayout); + layout->addLayout(_setInputsLayout); + layout->addWidget(_inputs); layout->addWidget(_skipWhenPaused); setLayout(layout); _entryData = entryData; @@ -267,6 +301,13 @@ MacroActionMacroEdit::MacroActionMacroEdit( _loading = false; } +void HighligthMacroSettingsButton(bool enable); + +MacroActionMacroEdit::~MacroActionMacroEdit() +{ + HighligthMacroSettingsButton(false); +} + void MacroActionMacroEdit::UpdateEntryData() { if (!_entryData) { @@ -282,60 +323,45 @@ void MacroActionMacroEdit::UpdateEntryData() _actionTypes->setCurrentIndex( _entryData->_runOptions.runElseActions ? 1 : 0); _skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused); + _setInputs->setChecked(_entryData->_runOptions.setInputs); + SetupMacroInput(_entryData->_macro.GetMacro().get()); SetWidgetVisibility(); } void MacroActionMacroEdit::MacroChanged(const QString &text) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_macro = text; - _actionIndex->SetMacro(_entryData->_macro.GetMacro()); + const auto ¯o = _entryData->_macro.GetMacro(); + _actionIndex->SetMacro(macro); + SetupMacroInput(macro.get()); emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); + SetWidgetVisibility(); } void MacroActionMacroEdit::ActionChanged(int value) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_action = static_cast(value); SetWidgetVisibility(); } void MacroActionMacroEdit::ActionIndexChanged(const IntVariable &value) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_actionIndex = value; } void MacroActionMacroEdit::ConditionMacroChanged(const QString &text) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_runOptions.macro = text; } void MacroActionMacroEdit::ConditionBehaviorChanged(int value) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_runOptions.logic = static_cast(value); SetWidgetVisibility(); @@ -343,24 +369,31 @@ void MacroActionMacroEdit::ConditionBehaviorChanged(int value) void MacroActionMacroEdit::ActionTypeChanged(int value) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_runOptions.runElseActions = value; } void MacroActionMacroEdit::SkipWhenPausedChanged(int value) { - if (_loading || !_entryData) { - return; - } - - auto lock = LockContext(); + GUARD_LOADING_AND_LOCK(); _entryData->_runOptions.skipWhenPaused = value; } +void MacroActionMacroEdit::SetInputsChanged(int value) +{ + GUARD_LOADING_AND_LOCK(); + _entryData->_runOptions.setInputs = value; + SetWidgetVisibility(); +} + +void MacroActionMacroEdit::InputsChanged(const StringList &inputs) +{ + GUARD_LOADING_AND_LOCK(); + _entryData->_runOptions.inputs = inputs; + adjustSize(); + updateGeometry(); +} + void MacroActionMacroEdit::SetWidgetVisibility() { _entryLayout->removeWidget(_actions); @@ -422,6 +455,15 @@ void MacroActionMacroEdit::SetWidgetVisibility() _entryData->_action == MacroActionMacro::Action::RUN && _entryData->_runOptions.logic != MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS); + SetLayoutVisible(_setInputsLayout, + _entryData->_action == MacroActionMacro::Action::RUN); + _inputs->setVisible(_entryData->_action == + MacroActionMacro::Action::RUN && + _entryData->_runOptions.setInputs); + HighligthMacroSettingsButton(_entryData->_action == + MacroActionMacro::Action::RUN && + _entryData->_runOptions.setInputs && + !_inputs->HasInputsToSet()); _actionTypes->setVisible(_entryData->_action == MacroActionMacro::Action::RUN); _skipWhenPaused->setVisible(_entryData->_action == @@ -431,12 +473,25 @@ void MacroActionMacroEdit::SetWidgetVisibility() updateGeometry(); } +void MacroActionMacroEdit::SetupMacroInput(Macro *macro) const +{ + if (macro) { + _inputs->SetInputVariablesAndValues( + macro->GetInputVariables(), + _entryData->_runOptions.inputs); + } else { + _inputs->SetInputVariablesAndValues({}, {}); + } +} + void MacroActionMacro::RunOptions::Save(obs_data_t *obj) const { OBSDataAutoRelease data = obs_data_create(); obs_data_set_int(data, "logic", static_cast(logic)); obs_data_set_bool(data, "runElseActions", runElseActions); obs_data_set_bool(data, "skipWhenPaused", skipWhenPaused); + obs_data_set_bool(data, "setInputs", setInputs); + inputs.Save(data, "inputs"); macro.Save(data); obs_data_set_obj(obj, "runOptions", data); } @@ -450,6 +505,8 @@ void MacroActionMacro::RunOptions::Load(obs_data_t *obj) logic = static_cast(obs_data_get_int(data, "logic")); runElseActions = obs_data_get_bool(data, "runElseActions"); skipWhenPaused = obs_data_get_bool(data, "skipWhenPaused"); + setInputs = obs_data_get_bool(data, "setInputs"); + inputs.Load(data, "inputs"); macro.Load(data); } diff --git a/lib/macro/macro-action-macro.hpp b/lib/macro/macro-action-macro.hpp index 07e2c2dc..bf63ae9e 100644 --- a/lib/macro/macro-action-macro.hpp +++ b/lib/macro/macro-action-macro.hpp @@ -1,5 +1,6 @@ #pragma once #include "macro-action-edit.hpp" +#include "macro-input.hpp" #include "macro-selection.hpp" #include "macro-segment-selection.hpp" @@ -8,7 +9,7 @@ namespace advss { -class MacroActionMacro : public MacroRefAction { +class MacroActionMacro final : public MacroRefAction { public: MacroActionMacro(Macro *m) : MacroAction(m), MacroRefAction(m) {} bool PerformAction(); @@ -33,6 +34,8 @@ public: Logic logic; bool runElseActions = false; bool skipWhenPaused = true; + bool setInputs = false; + StringList inputs; MacroRef macro; }; @@ -57,13 +60,14 @@ private: static const std::string id; }; -class MacroActionMacroEdit : public QWidget { +class MacroActionMacroEdit final : public QWidget { Q_OBJECT public: MacroActionMacroEdit( QWidget *parent, std::shared_ptr entryData = nullptr); + ~MacroActionMacroEdit(); void UpdateEntryData(); static QWidget *Create(QWidget *parent, std::shared_ptr action) @@ -81,12 +85,15 @@ private slots: void ConditionBehaviorChanged(int value); void ActionTypeChanged(int value); void SkipWhenPausedChanged(int value); + void SetInputsChanged(int value); + void InputsChanged(const StringList &); signals: void HeaderInfoChanged(const QString &); private: void SetWidgetVisibility(); + void SetupMacroInput(Macro *) const; MacroSelection *_macros; MacroSegmentSelection *_actionIndex; @@ -95,8 +102,11 @@ private: QComboBox *_conditionBehaviors; QComboBox *_actionTypes; QCheckBox *_skipWhenPaused; + QCheckBox *_setInputs; + MacroInputEdit *_inputs; QHBoxLayout *_entryLayout; QHBoxLayout *_conditionLayout; + QHBoxLayout *_setInputsLayout; std::shared_ptr _entryData; bool _loading = true;