Add canvas and position variable support to scene condition

This commit is contained in:
WarmUpTill 2025-10-12 18:19:30 +02:00 committed by WarmUpTill
parent 16136b8741
commit 8f54e71e61
3 changed files with 130 additions and 35 deletions

View File

@ -325,6 +325,7 @@ AdvSceneSwitcher.condition.scene.type.previousPattern="Previous scene matches"
AdvSceneSwitcher.condition.scene.type.previewPattern="Preview scene matches"
AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="During transition check for transition target scene"
AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="During transition check for transition source scene"
AdvSceneSwitcher.condition.scene.canvasNotSupported="This check is not supported for the currently selected canvas \"%1\""
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}{{regex}}"
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
AdvSceneSwitcher.condition.window="Window"
@ -2103,6 +2104,7 @@ AdvSceneSwitcher.tempVar.clipboard.mimeType.all.description="All MIME types of t
AdvSceneSwitcher.tempVar.scene.current="Current scene"
AdvSceneSwitcher.tempVar.scene.previous="Previous scene"
AdvSceneSwitcher.tempVar.scene.preview="Preview scene"
AdvSceneSwitcher.tempVar.scene.position="Position in scenes list"
AdvSceneSwitcher.tempVar.window.window="Window title"
AdvSceneSwitcher.tempVar.window.window.description="The window title of the matching window."

View File

@ -41,8 +41,17 @@ static bool sceneNameMatchesRegex(const OBSWeakSource &scene,
return regex.Matches(GetWeakSourceName(scene), pattern);
}
static OBSWeakSource getCurrentSceneHelper(bool useTransitionTargetScene)
static OBSWeakSource getCurrentSceneHelper(bool useTransitionTargetScene,
obs_weak_canvas_t *canvas)
{
if (!IsMainCanvas(canvas)) {
// An "active" scene doesn't necessarily have to be the current
// scene, but this is still the best guess for now without
// having more information about each canvas' specific frontend
// implementation
return GetActiveCanvasScene(canvas);
}
if (useTransitionTargetScene) {
auto current = obs_frontend_get_current_scene();
auto weak = obs_source_get_weak_source(current);
@ -68,62 +77,119 @@ bool MacroConditionScene::CheckCondition()
_lastSceneChangeTime = GetLastSceneChangeTime();
}
const auto canvas = _scene.GetCanvas();
switch (_type) {
case Type::CURRENT: {
auto scene = getCurrentSceneHelper(_useTransitionTargetScene);
auto scene = getCurrentSceneHelper(_useTransitionTargetScene,
canvas);
SetVariableValue(GetWeakSourceName(scene));
SetTempVarValue("current", GetWeakSourceName(scene));
return scene == _scene.GetScene(false);
SetTempVarValue("position",
std::to_string(GetIndexOfScene(canvas, scene)));
return scene && scene == _scene.GetScene(false);
}
case Type::PREVIOUS: {
if (!IsMainCanvas(canvas)) {
return false;
}
auto scene = getPreviousSceneHelper(_useTransitionTargetScene);
if (!scene) {
// Scene was never switched
return false;
}
SetVariableValue(GetWeakSourceName(scene));
SetTempVarValue("position",
std::to_string(GetIndexOfScene(canvas, scene)));
SetTempVarValue("previous", GetWeakSourceName(scene));
return scene == _scene.GetScene(false);
}
case Type::PREVIEW: {
if (!IsMainCanvas(canvas)) {
return false;
}
OBSSourceAutoRelease source =
obs_frontend_get_current_preview_scene();
OBSWeakSourceAutoRelease scene =
obs_source_get_weak_source(source);
SetVariableValue(GetWeakSourceName(scene));
SetTempVarValue("preview", GetWeakSourceName(scene));
return scene == _scene.GetScene(false);
SetTempVarValue("position", std::to_string(GetIndexOfScene(
canvas, scene.Get())));
return scene && scene == _scene.GetScene(false);
}
case Type::CHANGED:
if (!IsMainCanvas(canvas)) {
return false;
}
SetVariableValue(GetWeakSourceName(GetCurrentScene()));
SetTempVarValue("current",
GetWeakSourceName(GetCurrentScene()));
SetTempVarValue("previous",
GetWeakSourceName(GetPreviousScene()));
SetTempVarValue("position",
std::to_string(GetIndexOfScene(
canvas, GetCurrentScene())));
return sceneChanged;
case Type::NOT_CHANGED:
if (!IsMainCanvas(canvas)) {
return false;
}
SetVariableValue(GetWeakSourceName(GetCurrentScene()));
SetTempVarValue("current",
GetWeakSourceName(GetCurrentScene()));
SetTempVarValue("previous",
GetWeakSourceName(GetPreviousScene()));
SetTempVarValue("position",
std::to_string(GetIndexOfScene(
canvas, GetCurrentScene())));
return !sceneChanged;
case Type::CURRENT_PATTERN: {
auto scene = getCurrentSceneHelper(_useTransitionTargetScene);
auto scene = getCurrentSceneHelper(_useTransitionTargetScene,
canvas);
SetVariableValue(GetWeakSourceName(scene));
SetTempVarValue("current", GetWeakSourceName(scene));
return sceneNameMatchesRegex(scene, _regex, _pattern);
SetTempVarValue("position",
std::to_string(GetIndexOfScene(canvas, scene)));
return scene && sceneNameMatchesRegex(scene, _regex, _pattern);
}
case Type::PREVIOUS_PATTERN: {
if (!IsMainCanvas(canvas)) {
return false;
}
auto scene = getPreviousSceneHelper(_useTransitionTargetScene);
if (!scene) {
// Scene was never switched
return false;
}
SetVariableValue(GetWeakSourceName(scene));
SetTempVarValue("previous", GetWeakSourceName(scene));
SetTempVarValue("position",
std::to_string(GetIndexOfScene(canvas, scene)));
return sceneNameMatchesRegex(scene, _regex, _pattern);
}
case Type::PREVIEW_PATTERN: {
if (!IsMainCanvas(canvas)) {
return false;
}
OBSSourceAutoRelease source =
obs_frontend_get_current_preview_scene();
OBSWeakSourceAutoRelease scene =
obs_source_get_weak_source(source);
SetVariableValue(GetWeakSourceName(scene));
SetTempVarValue("preview", GetWeakSourceName(scene));
return sceneNameMatchesRegex(scene.Get(), _regex, _pattern);
SetTempVarValue("position", std::to_string(GetIndexOfScene(
canvas, scene.Get())));
return scene &&
sceneNameMatchesRegex(scene.Get(), _regex, _pattern);
}
}
@ -214,6 +280,7 @@ std::string MacroConditionScene::GetShortDesc() const
void MacroConditionScene::SetupTempVars()
{
MacroCondition::SetupTempVars();
switch (_type) {
case Type::CURRENT:
case Type::CURRENT_PATTERN:
@ -245,6 +312,9 @@ void MacroConditionScene::SetupTempVars()
default:
break;
}
AddTempvar("position",
obs_module_text("AdvSceneSwitcher.tempVar.scene.position"));
}
void MacroConditionScene::SetType(const Type &type)
@ -269,10 +339,13 @@ MacroConditionSceneEdit::MacroConditionSceneEdit(
_pattern(new QLineEdit()),
_useTransitionTargetScene(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour"))),
_regex(new RegexConfigWidget(this, false))
_regex(new RegexConfigWidget(this, false)),
_canvasWarning(new QLabel(this))
{
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_scenes, SIGNAL(CanvasChanged(const OBSWeakCanvas &)),
this, SLOT(CanvasChanged(const OBSWeakCanvas &)));
QWidget::connect(_sceneType, SIGNAL(currentIndexChanged(int)), this,
SLOT(TypeChanged(int)));
QWidget::connect(_pattern, SIGNAL(editingFinished()), this,
@ -285,7 +358,7 @@ MacroConditionSceneEdit::MacroConditionSceneEdit(
populateTypeSelection(_sceneType);
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{scenes}}", _scenes},
{"{{sceneType}}", _sceneType},
{"{{pattern}}", _pattern},
@ -303,6 +376,7 @@ MacroConditionSceneEdit::MacroConditionSceneEdit(
auto mainLayout = new QVBoxLayout;
mainLayout->addLayout(line1Layout);
mainLayout->addLayout(line2Layout);
mainLayout->addWidget(_canvasWarning);
setLayout(mainLayout);
_entryData = entryData;
@ -344,41 +418,58 @@ void MacroConditionSceneEdit::RegexChanged(const RegexConfig &regex)
_entryData->_regex = regex;
}
void MacroConditionSceneEdit::CanvasChanged(const OBSWeakCanvas &)
{
SetWidgetVisibility();
}
void MacroConditionSceneEdit::SetWidgetVisibility()
{
_scenes->setVisible(
_entryData->GetType() == MacroConditionScene::Type::CURRENT ||
_entryData->GetType() == MacroConditionScene::Type::PREVIOUS ||
_entryData->GetType() == MacroConditionScene::Type::PREVIEW);
const auto type = _entryData->GetType();
_scenes->setVisible(type == MacroConditionScene::Type::CURRENT ||
type == MacroConditionScene::Type::PREVIOUS ||
type == MacroConditionScene::Type::PREVIEW);
_useTransitionTargetScene->setVisible(
_entryData->GetType() == MacroConditionScene::Type::CURRENT ||
_entryData->GetType() == MacroConditionScene::Type::PREVIOUS ||
_entryData->GetType() ==
MacroConditionScene::Type::CURRENT_PATTERN ||
_entryData->GetType() ==
MacroConditionScene::Type::PREVIOUS_PATTERN);
type == MacroConditionScene::Type::CURRENT ||
type == MacroConditionScene::Type::PREVIOUS ||
type == MacroConditionScene::Type::CURRENT_PATTERN ||
type == MacroConditionScene::Type::PREVIOUS_PATTERN);
const bool isUsingPattern =
_entryData->GetType() ==
MacroConditionScene::Type::CURRENT_PATTERN ||
_entryData->GetType() ==
MacroConditionScene::Type::PREVIOUS_PATTERN ||
_entryData->GetType() ==
MacroConditionScene::Type::PREVIEW_PATTERN;
type == MacroConditionScene::Type::CURRENT_PATTERN ||
type == MacroConditionScene::Type::PREVIOUS_PATTERN ||
type == MacroConditionScene::Type::PREVIEW_PATTERN;
_pattern->setVisible(isUsingPattern);
_regex->setVisible(isUsingPattern);
if (_entryData->GetType() == MacroConditionScene::Type::PREVIOUS ||
_entryData->GetType() ==
MacroConditionScene::Type::PREVIOUS_PATTERN) {
if (type == MacroConditionScene::Type::PREVIOUS ||
type == MacroConditionScene::Type::PREVIOUS_PATTERN) {
_useTransitionTargetScene->setText(obs_module_text(
"AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour"));
}
if (_entryData->GetType() == MacroConditionScene::Type::CURRENT ||
_entryData->GetType() ==
MacroConditionScene::Type::CURRENT_PATTERN) {
if (type == MacroConditionScene::Type::CURRENT ||
type == MacroConditionScene::Type::CURRENT_PATTERN) {
_useTransitionTargetScene->setText(obs_module_text(
"AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour"));
}
const auto canvas = _entryData->_scene.GetCanvas();
const bool isUsingMainCanvas = IsMainCanvas(canvas);
_useTransitionTargetScene->setVisible(isUsingMainCanvas);
const QString fmt = obs_module_text(
"AdvSceneSwitcher.condition.scene.canvasNotSupported");
_canvasWarning->setText(
fmt.arg(QString::fromStdString(GetWeakCanvasName(canvas))));
_canvasWarning->setVisible(
canvas && !isUsingMainCanvas &&
(type == MacroConditionScene::Type::PREVIOUS ||
type == MacroConditionScene::Type::PREVIEW ||
type == MacroConditionScene::Type::CHANGED ||
type == MacroConditionScene::Type::NOT_CHANGED ||
type == MacroConditionScene::Type::PREVIOUS_PATTERN ||
type == MacroConditionScene::Type::PREVIEW_PATTERN));
adjustSize();
updateGeometry();
}

View File

@ -75,19 +75,21 @@ private slots:
void PatternChanged();
void UseTransitionTargetSceneChanged(int state);
void RegexChanged(const RegexConfig &);
void CanvasChanged(const OBSWeakCanvas &);
signals:
void HeaderInfoChanged(const QString &);
protected:
private:
void SetWidgetVisibility();
SceneSelectionWidget *_scenes;
QComboBox *_sceneType;
QLineEdit *_pattern;
QCheckBox *_useTransitionTargetScene;
RegexConfigWidget *_regex;
std::shared_ptr<MacroConditionScene> _entryData;
QLabel *_canvasWarning;
private:
void SetWidgetVisibility();
std::shared_ptr<MacroConditionScene> _entryData;
bool _loading = true;
};