diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3833e83a..969abb2b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -268,6 +268,8 @@ target_sources(
src/utils/macro-export-import-dialog.hpp
src/utils/macro-list.cpp
src/utils/macro-list.hpp
+ src/utils/macro-run-button.cpp
+ src/utils/macro-run-button.hpp
src/utils/macro-segment-selection.cpp
src/utils/macro-segment-selection.hpp
src/utils/math-helpers.cpp
diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini
index 81179a02..1cae4792 100644
--- a/data/locale/en-US.ini
+++ b/data/locale/en-US.ini
@@ -79,6 +79,7 @@ AdvSceneSwitcher.macroTab.edit.action="Action type:"
AdvSceneSwitcher.macroTab.add="Add new macro"
AdvSceneSwitcher.macroTab.name="Name:"
AdvSceneSwitcher.macroTab.run="Run macro"
+AdvSceneSwitcher.macroTab.runElse="Run macro (else)"
AdvSceneSwitcher.macroTab.runFail="Running \"%1\" failed!\nEither one of the actions failed or the macro is running already."
AdvSceneSwitcher.macroTab.runInParallel="Run macro in parallel to other macros"
AdvSceneSwitcher.macroTab.onChange="Perform actions only on condition change"
diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui
index 3e418ba9..9a37330c 100644
--- a/forms/advanced-scene-switcher.ui
+++ b/forms/advanced-scene-switcher.ui
@@ -843,7 +843,7 @@
-
-
+
AdvSceneSwitcher.macroTab.run
@@ -4849,6 +4849,11 @@
1
+
+ advss::MacroRunButton
+ QPushButton
+
+
diff --git a/src/advanced-scene-switcher.hpp b/src/advanced-scene-switcher.hpp
index 967fb9ef..161d330c 100644
--- a/src/advanced-scene-switcher.hpp
+++ b/src/advanced-scene-switcher.hpp
@@ -101,7 +101,6 @@ public slots:
void on_macroUp_clicked();
void on_macroDown_clicked();
void on_macroName_editingFinished();
- void on_runMacro_clicked();
void on_runMacroInParallel_stateChanged(int value);
void on_runMacroOnChange_stateChanged(int value);
void on_conditionAdd_clicked();
diff --git a/src/macro-core/macro-tab.cpp b/src/macro-core/macro-tab.cpp
index 3f6e8d46..4bb78bd8 100644
--- a/src/macro-core/macro-tab.cpp
+++ b/src/macro-core/macro-tab.cpp
@@ -451,21 +451,6 @@ void AdvSceneSwitcher::on_macroName_editingFinished()
RenameMacro(macro, newName);
}
-void AdvSceneSwitcher::on_runMacro_clicked()
-{
- auto macro = GetSelectedMacro();
- if (!macro) {
- return;
- }
-
- bool ret = macro->PerformActions(true, true, true);
- if (!ret) {
- QString err =
- obs_module_text("AdvSceneSwitcher.macroTab.runFail");
- DisplayMessage(err.arg(QString::fromStdString(macro->Name())));
- }
-}
-
void AdvSceneSwitcher::on_runMacroInParallel_stateChanged(int value)
{
auto macro = GetSelectedMacro();
@@ -792,6 +777,7 @@ void AdvSceneSwitcher::SetupMacroTab()
SLOT(MacroSelectionAboutToChange()));
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
SLOT(MacroSelectionChanged()));
+ ui->runMacro->SetMacroTree(ui->macros);
ui->conditionsList->SetHelpMsg(
obs_module_text("AdvSceneSwitcher.macroTab.editConditionHelp"));
diff --git a/src/utils/macro-run-button.cpp b/src/utils/macro-run-button.cpp
new file mode 100644
index 00000000..88ad59eb
--- /dev/null
+++ b/src/utils/macro-run-button.cpp
@@ -0,0 +1,82 @@
+#include "macro-run-button.hpp"
+#include "macro-tree.hpp"
+#include "macro.hpp"
+#include "obs-module-helper.hpp"
+#include "utility.hpp"
+
+#include
+
+namespace advss {
+
+MacroRunButton::MacroRunButton(QWidget *parent) : QPushButton(parent)
+{
+ if (window()) {
+ window()->installEventFilter(this);
+ }
+ QWidget::connect(this, SIGNAL(pressed()), this, SLOT(Pressed()));
+}
+
+void MacroRunButton::SetMacroTree(MacroTree *macros)
+{
+ _macros = macros;
+ QWidget::connect(macros, SIGNAL(MacroSelectionChanged()), this,
+ SLOT(MacroSelectionChanged()));
+ QWidget::connect(&_timer, &QTimer::timeout, this,
+ [this]() { MacroSelectionChanged(); });
+ _timer.start(1000);
+}
+
+void MacroRunButton::MacroSelectionChanged()
+{
+ auto macro = _macros->GetCurrentMacro();
+ if (!macro) {
+ _macroHasElseActions = false;
+ return;
+ }
+ _macroHasElseActions = macro->ElseActions().size() > 0;
+}
+
+bool MacroRunButton::eventFilter(QObject *obj, QEvent *event)
+{
+ if (!_macroHasElseActions) {
+ setText(obs_module_text("AdvSceneSwitcher.macroTab.run"));
+ _runElseActionsKeyHeld = false;
+ return QPushButton::eventFilter(obj, event);
+ }
+
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast(event);
+ if (keyEvent->key() == Qt::Key_Control) {
+ setText(obs_module_text(
+ "AdvSceneSwitcher.macroTab.runElse"));
+ _runElseActionsKeyHeld = true;
+ }
+ } else if (event->type() == QEvent::KeyRelease) {
+ QKeyEvent *keyEvent = static_cast(event);
+ if (keyEvent->key() == Qt::Key_Control) {
+ setText(obs_module_text(
+ "AdvSceneSwitcher.macroTab.run"));
+ _runElseActionsKeyHeld = false;
+ }
+ }
+ return QPushButton::eventFilter(obj, event);
+}
+
+void MacroRunButton::Pressed()
+{
+ auto macro = _macros->GetCurrentMacro();
+ if (!macro) {
+ return;
+ }
+
+ bool ret = _runElseActionsKeyHeld
+ ? macro->PerformActions(false, true, true)
+ : macro->PerformActions(true, true, true);
+ if (!ret) {
+ QString err =
+ obs_module_text("AdvSceneSwitcher.macroTab.runFail");
+ DisplayMessage(err.arg(QString::fromStdString(macro->Name())));
+ }
+}
+
+} // namespace advss
diff --git a/src/utils/macro-run-button.hpp b/src/utils/macro-run-button.hpp
new file mode 100644
index 00000000..c68bd2bc
--- /dev/null
+++ b/src/utils/macro-run-button.hpp
@@ -0,0 +1,29 @@
+#pragma once
+#include
+#include
+
+namespace advss {
+
+class MacroTree;
+
+class MacroRunButton : public QPushButton {
+ Q_OBJECT
+public:
+ MacroRunButton(QWidget *parent = nullptr);
+ void SetMacroTree(MacroTree *);
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event) override;
+
+private slots:
+ void MacroSelectionChanged();
+ void Pressed();
+
+private:
+ MacroTree *_macros = nullptr;
+ bool _macroHasElseActions = false;
+ bool _runElseActionsKeyHeld = false;
+ QTimer _timer;
+};
+
+} // namespace advss