Compare commits

...

5 Commits

Author SHA1 Message Date
WarmUpTill
4c977a2e2f Add "None" support for scene items to Transition action 2026-06-25 21:25:48 +02:00
WarmUpTill
0f1273ab4c Add support for "None" transition type to scene item visibility action 2026-06-25 21:18:57 +02:00
WarmUpTill
67f6b1b459 Add "current transition" support to scene item visibility action 2026-06-25 20:59:36 +02:00
WarmUpTill
a04c51397d Fix variables of nested macros' actions not being resolved
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2026-06-17 21:12:48 +02:00
WarmUpTill
2073ef6ce9 Fix nested macro actions being executed twice when added to a queue 2026-06-17 21:12:48 +02:00
8 changed files with 86 additions and 17 deletions

View File

@@ -2546,6 +2546,7 @@ AdvSceneSwitcher.selectCurrentScene="Current Scene"
AdvSceneSwitcher.selectPreviewScene="Preview Scene" AdvSceneSwitcher.selectPreviewScene="Preview Scene"
AdvSceneSwitcher.selectAnyScene="Any Scene" AdvSceneSwitcher.selectAnyScene="Any Scene"
AdvSceneSwitcher.currentTransition="Current Transition" AdvSceneSwitcher.currentTransition="Current Transition"
AdvSceneSwitcher.noneTransition="None"
AdvSceneSwitcher.anyTransition="Any Transition" AdvSceneSwitcher.anyTransition="Any Transition"
AdvSceneSwitcher.selectTransition="--select transition--" AdvSceneSwitcher.selectTransition="--select transition--"
AdvSceneSwitcher.selectWindow="--select window--" AdvSceneSwitcher.selectWindow="--select window--"

View File

@@ -263,6 +263,7 @@ bool MacroActionMacro::Load(obs_data_t *obj)
if (obs_data_has_user_value(obj, "nestedMacro")) { if (obs_data_has_user_value(obj, "nestedMacro")) {
OBSDataAutoRelease nestedMacroData = OBSDataAutoRelease nestedMacroData =
obs_data_get_obj(obj, "nestedMacro"); obs_data_get_obj(obj, "nestedMacro");
_nestedMacro = std::make_shared<Macro>();
_nestedMacro->Load(nestedMacroData); _nestedMacro->Load(nestedMacroData);
} }
@@ -309,6 +310,15 @@ void MacroActionMacro::ResolveVariablesToFixedValues()
{ {
_actionIndex.ResolveVariables(); _actionIndex.ResolveVariables();
_label.ResolveVariables(); _label.ResolveVariables();
if (_action == Action::NESTED_MACRO) {
for (auto &action : _nestedMacro->Actions()) {
action->ResolveVariablesToFixedValues();
}
for (auto &action : _nestedMacro->ElseActions()) {
action->ResolveVariablesToFixedValues();
}
}
} }
static void runActionsHelper(Macro *macro, bool runElseActions, bool setInputs, static void runActionsHelper(Macro *macro, bool runElseActions, bool setInputs,

View File

@@ -135,7 +135,7 @@ QStringList GetSourceNames()
} }
void PopulateTransitionSelection(QComboBox *sel, bool addCurrent, bool addAny, void PopulateTransitionSelection(QComboBox *sel, bool addCurrent, bool addAny,
bool addSelect) bool addSelect, bool addNone)
{ {
obs_frontend_source_list *transitions = new obs_frontend_source_list(); obs_frontend_source_list *transitions = new obs_frontend_source_list();
@@ -168,6 +168,11 @@ void PopulateTransitionSelection(QComboBox *sel, bool addCurrent, bool addAny,
addSelect ? 1 : 0, addSelect ? 1 : 0,
obs_module_text("AdvSceneSwitcher.anyTransition")); obs_module_text("AdvSceneSwitcher.anyTransition"));
} }
if (addNone) {
sel->insertItem(
addSelect ? 1 : 0,
obs_module_text("AdvSceneSwitcher.noneTransition"));
}
} }
void PopulateWindowSelection(QComboBox *sel, bool addSelect) void PopulateWindowSelection(QComboBox *sel, bool addSelect)

View File

@@ -19,7 +19,8 @@ EXPORT QStringList GetSourceNames();
EXPORT void PopulateTransitionSelection(QComboBox *sel, bool addCurrent = true, EXPORT void PopulateTransitionSelection(QComboBox *sel, bool addCurrent = true,
bool addAny = false, bool addAny = false,
bool addSelect = true); bool addSelect = true,
bool addNone = false);
EXPORT void PopulateWindowSelection(QComboBox *sel, bool addSelect = true); EXPORT void PopulateWindowSelection(QComboBox *sel, bool addSelect = true);
void PopulateAudioSelection(QComboBox *sel, bool addSelect = true); void PopulateAudioSelection(QComboBox *sel, bool addSelect = true);
void PopulateVideoSelection(QComboBox *sel, bool addMainOutput = false, void PopulateVideoSelection(QComboBox *sel, bool addMainOutput = false,

View File

@@ -160,12 +160,11 @@ static void attachRestoreContext(obs_sceneitem_t *item,
static void setSceneItemVisibility(obs_sceneitem_t *item, static void setSceneItemVisibility(obs_sceneitem_t *item,
const bool setTransition, const bool setTransition,
const OBSWeakSource &transitionWeak, const TransitionSelection &transitionSel,
const bool setDuration, const bool setDuration,
const Duration &duration, const Duration &duration,
MacroActionSceneVisibility::Action action) MacroActionSceneVisibility::Action action)
{ {
const OBSSourceAutoRelease transition = OBSGetStrongRef(transitionWeak);
const bool itemIsVisible = obs_sceneitem_visible(item); const bool itemIsVisible = obs_sceneitem_visible(item);
const OBSSource currentTransition = const OBSSource currentTransition =
@@ -175,6 +174,16 @@ static void setSceneItemVisibility(obs_sceneitem_t *item,
OBSSource privateTransitionSource = nullptr; OBSSource privateTransitionSource = nullptr;
if (setTransition) { if (setTransition) {
OBSSourceAutoRelease transition;
if (transitionSel.GetType() ==
TransitionSelection::Type::CURRENT) {
transition = obs_source_get_ref(
obs_sceneitem_get_transition(item,
!itemIsVisible));
} else {
transition =
OBSGetStrongRef(transitionSel.GetTransition());
}
privateTransitionSource = SetSceneItemTransition( privateTransitionSource = SetSceneItemTransition(
item, transition, !itemIsVisible); item, transition, !itemIsVisible);
} else { } else {
@@ -229,8 +238,7 @@ bool MacroActionSceneVisibility::PerformAction()
{ {
auto items = _source.GetSceneItems(_scene); auto items = _source.GetSceneItems(_scene);
for (const auto &item : items) { for (const auto &item : items) {
setSceneItemVisibility(item, _updateTransition, setSceneItemVisibility(item, _updateTransition, _transition,
_transition.GetTransition(),
_updateDuration, _duration, _action); _updateDuration, _duration, _action);
} }
return true; return true;
@@ -340,7 +348,7 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
}, },
SceneItemSelectionWidget::NameClashMode::ALL)), SceneItemSelectionWidget::NameClashMode::ALL)),
_updateTransition(new QCheckBox(this)), _updateTransition(new QCheckBox(this)),
_transitions(new TransitionSelectionWidget(this, false, false)), _transitions(new TransitionSelectionWidget(this, true, false, true)),
_updateDuration(new QCheckBox(this)), _updateDuration(new QCheckBox(this)),
_duration(new DurationSelection(this, false)), _duration(new DurationSelection(this, false)),
_durationLayout(new QHBoxLayout), _durationLayout(new QHBoxLayout),
@@ -474,8 +482,11 @@ void MacroActionSceneVisibilityEdit::ActionChanged(int value)
void MacroActionSceneVisibilityEdit::SetWidgetVisibility() void MacroActionSceneVisibilityEdit::SetWidgetVisibility()
{ {
const auto transitionType = _entryData->_transition.GetType();
const bool hideDurationSelection = const bool hideDurationSelection =
_entryData->_updateTransition && _entryData->_updateTransition &&
transitionType != TransitionSelection::Type::CURRENT &&
transitionType != TransitionSelection::Type::NONE &&
IsFixedLengthTransition( IsFixedLengthTransition(
_entryData->_transition.GetTransition()); _entryData->_transition.GetTransition());

View File

@@ -406,15 +406,17 @@ void MacroActionTransitionEdit::SetWidgetVisibility()
MacroActionTransition::Type::TBAR; MacroActionTransition::Type::TBAR;
const bool isReleaseTbar = _entryData->_type == const bool isReleaseTbar = _entryData->_type ==
MacroActionTransition::Type::RELEASE_TBAR; MacroActionTransition::Type::RELEASE_TBAR;
_sources->setVisible( const bool isSourceTransition =
_entryData->_type == MacroActionTransition::Type::SOURCE_HIDE || _entryData->_type == MacroActionTransition::Type::SOURCE_SHOW ||
_entryData->_type == MacroActionTransition::Type::SOURCE_SHOW); _entryData->_type == MacroActionTransition::Type::SOURCE_HIDE;
_sources->setVisible(isSourceTransition);
_scenes->setVisible(_entryData->_type != _scenes->setVisible(_entryData->_type !=
MacroActionTransition::Type::SCENE && MacroActionTransition::Type::SCENE &&
!isTbar && !isReleaseTbar); !isTbar && !isReleaseTbar);
SetLayoutVisible(_transitionLayout, !isTbar && !isReleaseTbar); SetLayoutVisible(_transitionLayout, !isTbar && !isReleaseTbar);
SetLayoutVisible(_durationLayout, !isTbar && !isReleaseTbar); SetLayoutVisible(_durationLayout, !isTbar && !isReleaseTbar);
SetLayoutVisible(_tbarLayout, isTbar); SetLayoutVisible(_tbarLayout, isTbar);
_transitions->EnableNoneEntry(isSourceTransition);
adjustSize(); adjustSize();
} }

View File

@@ -48,6 +48,8 @@ OBSWeakSource TransitionSelection::GetTransition() const
obs_source_release(source); obs_source_release(source);
return weakSource; return weakSource;
} }
case Type::NONE:
return nullptr;
default: default:
break; break;
} }
@@ -63,6 +65,8 @@ std::string TransitionSelection::ToString() const
return obs_module_text("AdvSceneSwitcher.currentTransition"); return obs_module_text("AdvSceneSwitcher.currentTransition");
case Type::ANY: case Type::ANY:
return obs_module_text("AdvSceneSwitcher.anyTransition"); return obs_module_text("AdvSceneSwitcher.anyTransition");
case Type::NONE:
return obs_module_text("AdvSceneSwitcher.noneTransition");
default: default:
break; break;
} }
@@ -70,14 +74,16 @@ std::string TransitionSelection::ToString() const
} }
TransitionSelectionWidget::TransitionSelectionWidget(QWidget *parent, TransitionSelectionWidget::TransitionSelectionWidget(QWidget *parent,
bool current, bool any) bool current, bool any,
bool none)
: FilterComboBox(parent, : FilterComboBox(parent,
obs_module_text("AdvSceneSwitcher.selectTransition")), obs_module_text("AdvSceneSwitcher.selectTransition")),
_addCurrent(current), _addCurrent(current),
_addAny(any) _addAny(any),
_addNone(none)
{ {
setDuplicatesEnabled(true); setDuplicatesEnabled(true);
PopulateTransitionSelection(this, current, any, false); PopulateTransitionSelection(this, current, any, false, none);
QWidget::connect(this, SIGNAL(currentTextChanged(const QString &)), QWidget::connect(this, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SelectionChanged(const QString &))); this, SLOT(SelectionChanged(const QString &)));
@@ -86,8 +92,9 @@ TransitionSelectionWidget::TransitionSelectionWidget(QWidget *parent,
void TransitionSelectionWidget::SetTransition(const TransitionSelection &t) void TransitionSelectionWidget::SetTransition(const TransitionSelection &t)
{ {
// Order of entries // Order of entries
// 1. Any transition // 1. None transition
// 2. Current transition // 2. Any transition
// 3. Current transition
// 4. Transitions // 4. Transitions
switch (t.GetType()) { switch (t.GetType()) {
@@ -102,6 +109,10 @@ void TransitionSelectionWidget::SetTransition(const TransitionSelection &t)
setCurrentIndex(findText(QString::fromStdString( setCurrentIndex(findText(QString::fromStdString(
obs_module_text("AdvSceneSwitcher.anyTransition")))); obs_module_text("AdvSceneSwitcher.anyTransition"))));
break; break;
case TransitionSelection::Type::NONE:
setCurrentIndex(findText(QString::fromStdString(
obs_module_text("AdvSceneSwitcher.noneTransition"))));
break;
default: default:
setCurrentIndex(-1); setCurrentIndex(-1);
break; break;
@@ -120,6 +131,17 @@ void TransitionSelectionWidget::EnableAnyEntry(bool enable)
Populate(); Populate();
} }
void TransitionSelectionWidget::EnableNoneEntry(bool enable)
{
if (_addNone == enable) {
return;
}
const auto selection = GetCurrentSelection();
_addNone = enable;
Populate();
SetTransition(selection);
}
void TransitionSelectionWidget::showEvent(QShowEvent *event) void TransitionSelectionWidget::showEvent(QShowEvent *event)
{ {
FilterComboBox::showEvent(event); FilterComboBox::showEvent(event);
@@ -133,7 +155,7 @@ void TransitionSelectionWidget::Populate()
{ {
const QSignalBlocker blocker(this); const QSignalBlocker blocker(this);
clear(); clear();
PopulateTransitionSelection(this, _addCurrent, _addAny); PopulateTransitionSelection(this, _addCurrent, _addAny, true, _addNone);
} }
static bool isFirstEntry(const QComboBox *l, QString name, int idx) static bool isFirstEntry(const QComboBox *l, QString name, int idx)
@@ -163,6 +185,9 @@ TransitionSelection TransitionSelectionWidget::GetCurrentSelection() const
if (IsAnyTransitionSelected(text)) { if (IsAnyTransitionSelected(text)) {
result._type = TransitionSelection::Type::ANY; result._type = TransitionSelection::Type::ANY;
} }
if (IsNoneTransitionSelected(text)) {
result._type = TransitionSelection::Type::NONE;
}
} }
return result; return result;
} }
@@ -187,6 +212,16 @@ bool TransitionSelectionWidget::IsAnyTransitionSelected(
return false; return false;
} }
bool TransitionSelectionWidget::IsNoneTransitionSelected(
const QString &name) const
{
if (name == QString::fromStdString((obs_module_text(
"AdvSceneSwitcher.noneTransition")))) {
return isFirstEntry(this, name, currentIndex());
}
return false;
}
void TransitionSelectionWidget::SelectionChanged(const QString &) void TransitionSelectionWidget::SelectionChanged(const QString &)
{ {
emit TransitionChanged(GetCurrentSelection()); emit TransitionChanged(GetCurrentSelection());

View File

@@ -16,6 +16,7 @@ public:
TRANSITION, TRANSITION,
CURRENT, CURRENT,
ANY, ANY,
NONE,
}; };
Type GetType() const { return _type; } Type GetType() const { return _type; }
@@ -33,10 +34,11 @@ class TransitionSelectionWidget : public FilterComboBox {
public: public:
TransitionSelectionWidget(QWidget *parent, bool current = true, TransitionSelectionWidget(QWidget *parent, bool current = true,
bool any = false); bool any = false, bool none = false);
void SetTransition(const TransitionSelection &); void SetTransition(const TransitionSelection &);
void EnableCurrentEntry(bool enable); void EnableCurrentEntry(bool enable);
void EnableAnyEntry(bool enable); void EnableAnyEntry(bool enable);
void EnableNoneEntry(bool enable);
protected: protected:
void showEvent(QShowEvent *event) override; void showEvent(QShowEvent *event) override;
@@ -52,9 +54,11 @@ private:
TransitionSelection GetCurrentSelection() const; TransitionSelection GetCurrentSelection() const;
bool IsCurrentTransitionSelected(const QString &name) const; bool IsCurrentTransitionSelected(const QString &name) const;
bool IsAnyTransitionSelected(const QString &name) const; bool IsAnyTransitionSelected(const QString &name) const;
bool IsNoneTransitionSelected(const QString &name) const;
bool _addCurrent; bool _addCurrent;
bool _addAny; bool _addAny;
bool _addNone;
}; };
} // namespace advss } // namespace advss