This commit is contained in:
WarmUpTill 2026-03-13 20:29:08 +00:00 committed by GitHub
commit d34e2aea3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 201 additions and 29 deletions

View File

@ -495,7 +495,7 @@ AdvSceneSwitcher.action.file.type.write="Schreiben"
AdvSceneSwitcher.action.file.type.append="Anhängen"
AdvSceneSwitcher.action.file.entry="{{actions}} in {{filePath}}:"
AdvSceneSwitcher.action.studioMode="Studio-Modus"
AdvSceneSwitcher.action.studioMode.type.swap="Vorschau- und Programm-Szene tauschen"
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Vorschau- und Programm-Szene tauschen"
AdvSceneSwitcher.action.studioMode.type.setScene="Vorschau-Szene einstellen auf"
AdvSceneSwitcher.action.studioMode.type.enable="Studio-Modus aktivieren"
AdvSceneSwitcher.action.studioMode.type.disable="Studio-Modus deaktivieren"

View File

@ -1081,7 +1081,17 @@ AdvSceneSwitcher.action.file.type.write="Write"
AdvSceneSwitcher.action.file.type.append="Append"
AdvSceneSwitcher.action.file.entry="{{actions}}to{{filePath}}:"
AdvSceneSwitcher.action.studioMode="Studio mode"
AdvSceneSwitcher.action.studioMode.type.swap="Swap preview and program scene"
AdvSceneSwitcher.action.studioMode.type.transition="Transition"
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Swap preview and program scene"
AdvSceneSwitcher.action.studioMode.type.transitionSwap.enable="Enable preview/program scene swapping after transition"
AdvSceneSwitcher.action.studioMode.type.transitionSwap.disable="Disable preview/program scene swapping after transition"
AdvSceneSwitcher.action.studioMode.type.transitionSwap.toggle="Toggle preview/program scene swapping after transition"
AdvSceneSwitcher.action.studioMode.type.duplicateScene.enable="Enable scene duplication"
AdvSceneSwitcher.action.studioMode.type.duplicateScene.disable="Disable scene duplication"
AdvSceneSwitcher.action.studioMode.type.duplicateScene.toggle="Toggle scene duplication"
AdvSceneSwitcher.action.studioMode.type.duplicateSource.enable="Enable source duplication"
AdvSceneSwitcher.action.studioMode.type.duplicateSource.disable="Disable source duplication"
AdvSceneSwitcher.action.studioMode.type.duplicateSource.toggle="Toggle source duplication"
AdvSceneSwitcher.action.studioMode.type.setScene="Set preview scene to"
AdvSceneSwitcher.action.studioMode.type.enable="Enable studio mode"
AdvSceneSwitcher.action.studioMode.type.disable="Disable studio mode"

View File

@ -413,7 +413,7 @@ AdvSceneSwitcher.action.file.type.write="Escribir"
AdvSceneSwitcher.action.file.type.append="Agregar"
AdvSceneSwitcher.action.file.entry="{{actions}} a {{filePath}}:"
AdvSceneSwitcher.action.studioMode="Modo estudio"
AdvSceneSwitcher.action.studioMode.type.swap="Intercambiar vista previa y escena del programa"
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Intercambiar vista previa y escena del programa"
AdvSceneSwitcher.action.studioMode.type.setScene="Establecer escena de vista previa en"
AdvSceneSwitcher.action.studioMode.type.enable="Activar modo estudio"
AdvSceneSwitcher.action.studioMode.type.disable="Deshabilitar el modo de estudio"

View File

@ -613,7 +613,7 @@ AdvSceneSwitcher.action.file.type.write="Écrire"
AdvSceneSwitcher.action.file.type.append="Ajouter"
AdvSceneSwitcher.action.file.entry="{{actions}}vers{{filePath}}:"
AdvSceneSwitcher.action.studioMode="Mode studio"
AdvSceneSwitcher.action.studioMode.type.swap="Permuter la scène de prévisualisation et la scène du programme"
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Permuter la scène de prévisualisation et la scène du programme"
AdvSceneSwitcher.action.studioMode.type.setScene="Définir la scène de prévisualisation sur"
AdvSceneSwitcher.action.studioMode.type.enable="Activer le mode studio"
AdvSceneSwitcher.action.studioMode.type.disable="Désactiver le mode studio"

View File

@ -1010,7 +1010,7 @@ AdvSceneSwitcher.action.file="ファイル"
; AdvSceneSwitcher.action.file.type.append="Append"
AdvSceneSwitcher.action.file.entry="{{actions}}から{{filePath}}へ:"
AdvSceneSwitcher.action.studioMode="スタジオモード"
AdvSceneSwitcher.action.studioMode.type.swap="プレビューと番組シーンの入れ替え"
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="プレビューと番組シーンの入れ替え"
AdvSceneSwitcher.action.studioMode.type.setScene="プレビューシーンを設定する"
AdvSceneSwitcher.action.studioMode.type.enable="スタジオモードを有効にする"
AdvSceneSwitcher.action.studioMode.type.disable="スタジオモードを無効にする"

View File

@ -923,7 +923,7 @@ AdvSceneSwitcher.action.file.type.write="Escrever"
AdvSceneSwitcher.action.file.type.append="Anexar"
AdvSceneSwitcher.action.file.entry="{{actions}}para{{filePath}}:"
AdvSceneSwitcher.action.studioMode="Modo estúdio"
AdvSceneSwitcher.action.studioMode.type.swap="Trocar cena de visualização e programa"
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Trocar cena de visualização e programa"
AdvSceneSwitcher.action.studioMode.type.setScene="Definir cena de visualização para"
AdvSceneSwitcher.action.studioMode.type.enable="Habilitar modo estúdio"
AdvSceneSwitcher.action.studioMode.type.disable="Desabilitar modo estúdio"

View File

@ -984,7 +984,7 @@ AdvSceneSwitcher.action.file.type.write="覆盖写入"
AdvSceneSwitcher.action.file.type.append="追加写入"
AdvSceneSwitcher.action.file.entry="{{actions}} 到 {{filePath}}:"
AdvSceneSwitcher.action.studioMode="工作室模式"
AdvSceneSwitcher.action.studioMode.type.swap="切换预览和程序场景"
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="切换预览和程序场景"
AdvSceneSwitcher.action.studioMode.type.setScene="将预览场景设置为"
AdvSceneSwitcher.action.studioMode.type.enable="启用工作室模式"
AdvSceneSwitcher.action.studioMode.type.disable="停用工作室模式"

View File

@ -2,6 +2,7 @@
#include "layout-helpers.hpp"
#include <obs-frontend-api.h>
#include <util/config-file.h>
namespace advss {
@ -13,16 +14,64 @@ bool MacroActionSudioMode::_registered = MacroActionFactory::Register(
"AdvSceneSwitcher.action.studioMode"});
const static std::map<MacroActionSudioMode::Action, std::string> actionTypes = {
{MacroActionSudioMode::Action::SWAP_SCENE,
"AdvSceneSwitcher.action.studioMode.type.swap"},
{MacroActionSudioMode::Action::SET_SCENE,
"AdvSceneSwitcher.action.studioMode.type.setScene"},
{MacroActionSudioMode::Action::TRANSITION,
"AdvSceneSwitcher.action.studioMode.type.transition"},
{MacroActionSudioMode::Action::TRANSITION_WITH_SWAP,
"AdvSceneSwitcher.action.studioMode.type.transitionWithSwap"},
{MacroActionSudioMode::Action::ENALBE_TRANSITION_SWAP,
"AdvSceneSwitcher.action.studioMode.type.transitionSwap.enable"},
{MacroActionSudioMode::Action::DISABLE_TRANSITION_SWAP,
"AdvSceneSwitcher.action.studioMode.type.transitionSwap.disable"},
{MacroActionSudioMode::Action::TOGGLE_TRANSITION_SWAP,
"AdvSceneSwitcher.action.studioMode.type.transitionSwap.toggle"},
{MacroActionSudioMode::Action::ENALBE_DUPLICATE_SCENE,
"AdvSceneSwitcher.action.studioMode.type.duplicateScene.enable"},
{MacroActionSudioMode::Action::DISABLE_DUPLICATE_SCENE,
"AdvSceneSwitcher.action.studioMode.type.duplicateScene.disable"},
{MacroActionSudioMode::Action::TOGGLE_DUPLICATE_SCENE,
"AdvSceneSwitcher.action.studioMode.type.duplicateScene.toggle"},
{MacroActionSudioMode::Action::ENALBE_DUPLICATE_SOURCE,
"AdvSceneSwitcher.action.studioMode.type.duplicateSource.enable"},
{MacroActionSudioMode::Action::DISABLE_DUPLICATE_SOURCE,
"AdvSceneSwitcher.action.studioMode.type.duplicateSource.disable"},
{MacroActionSudioMode::Action::TOGGLE_DUPLICATE_SOURCE,
"AdvSceneSwitcher.action.studioMode.type.duplicateSource.toggle"},
{MacroActionSudioMode::Action::ENABLE_STUDIO_MODE,
"AdvSceneSwitcher.action.studioMode.type.enable"},
{MacroActionSudioMode::Action::DISABLE_STUDIO_MODE,
"AdvSceneSwitcher.action.studioMode.type.disable"},
{MacroActionSudioMode::Action::TOGGLE_STUDIO_MODE,
"AdvSceneSwitcher.action.studioMode.type.toggle"},
{MacroActionSudioMode::Action::SET_SCENE,
"AdvSceneSwitcher.action.studioMode.type.setScene"},
};
template<typename Func, typename... Args>
static void setConfigValueHelper(Func func, Args... args)
{
auto config = obs_frontend_get_user_config();
func(config, args...);
if (config_save(config) != CONFIG_SUCCESS) {
blog(LOG_WARNING, "failed to save user config!");
}
}
template<typename Func, typename... Args>
static auto getConfigValueHelper(Func func, Func defaultFunc, Args... args)
-> std::optional<std::invoke_result_t<Func, config_t *, Args...>>
{
using Ret = std::invoke_result_t<Func, config_t *, Args...>;
auto config = obs_frontend_get_user_config();
if (config_has_user_value(config, args...)) {
return func(config, args...);
}
if (config_has_default_value(config, args...)) {
return defaultFunc(config, args...);
}
return std::optional<Ret>{};
}
// Calling obs_frontend_set_preview_program_mode() directly from a thread that
// is not the main OBS UI thread will lead to undefined behaviour, so we have
// to use this helper function instead - copied from obs-websocket plugin
@ -42,14 +91,78 @@ static void enableStudioMode(bool enable)
bool MacroActionSudioMode::PerformAction()
{
obs_frontend_get_user_config();
switch (_action) {
case Action::SWAP_SCENE:
case Action::TRANSITION:
obs_frontend_preview_program_trigger_transition();
break;
case Action::SET_SCENE: {
auto s = obs_weak_source_get_source(_scene.GetScene());
obs_frontend_set_current_preview_scene(s);
obs_source_release(s);
case Action::TRANSITION_WITH_SWAP: {
auto swapEnabled = getConfigValueHelper(config_get_bool,
config_get_default_bool,
"BasicWindow",
"SwapScenesMode");
if (swapEnabled.has_value() && *swapEnabled == true) {
obs_frontend_preview_program_trigger_transition();
break;
}
setConfigValueHelper(config_set_bool, "BasicWindow",
"SwapScenesMode", true);
obs_frontend_preview_program_trigger_transition();
setConfigValueHelper(config_set_bool, "BasicWindow",
"SwapScenesMode", false);
break;
}
case Action::ENALBE_TRANSITION_SWAP:
setConfigValueHelper(config_set_bool, "BasicWindow",
"SwapScenesMode", true);
break;
case Action::DISABLE_TRANSITION_SWAP:
setConfigValueHelper(config_set_bool, "BasicWindow",
"SwapScenesMode", false);
break;
case Action::TOGGLE_TRANSITION_SWAP: {
const auto enabled = getConfigValueHelper(
config_get_bool, config_get_default_bool, "BasicWindow",
"SwapScenesMode");
setConfigValueHelper(config_set_bool, "BasicWindow",
"SwapScenesMode",
enabled.has_value() && !*enabled);
break;
}
case Action::ENALBE_DUPLICATE_SCENE:
setConfigValueHelper(config_set_bool, "BasicWindow",
"SceneDuplicationMode", true);
break;
case Action::DISABLE_DUPLICATE_SCENE:
setConfigValueHelper(config_set_bool, "BasicWindow",
"SceneDuplicationMode", false);
break;
case Action::TOGGLE_DUPLICATE_SCENE: {
const auto enabled = getConfigValueHelper(
config_get_bool, config_get_default_bool, "BasicWindow",
"SceneDuplicationMode");
setConfigValueHelper(config_set_bool, "BasicWindow",
"SceneDuplicationMode",
enabled.has_value() && !*enabled);
break;
}
case Action::ENALBE_DUPLICATE_SOURCE:
setConfigValueHelper(config_set_bool, "BasicWindow",
"EditPropertiesMode", true);
break;
case Action::DISABLE_DUPLICATE_SOURCE:
setConfigValueHelper(config_set_bool, "BasicWindow",
"EditPropertiesMode", false);
break;
case Action::TOGGLE_DUPLICATE_SOURCE: {
const auto enabled = getConfigValueHelper(
config_get_bool, config_get_default_bool, "BasicWindow",
"EditPropertiesMode");
setConfigValueHelper(config_set_bool, "BasicWindow",
"EditPropertiesMode",
enabled.has_value() && !*enabled);
break;
}
case Action::ENABLE_STUDIO_MODE:
@ -58,6 +171,15 @@ bool MacroActionSudioMode::PerformAction()
case Action::DISABLE_STUDIO_MODE:
enableStudioMode(false);
break;
case Action::TOGGLE_STUDIO_MODE:
enableStudioMode(!obs_frontend_preview_program_mode_active());
break;
case Action::SET_SCENE: {
auto s = obs_weak_source_get_source(_scene.GetScene());
obs_frontend_set_current_preview_scene(s);
obs_source_release(s);
break;
}
default:
break;
}
@ -82,6 +204,7 @@ bool MacroActionSudioMode::Save(obs_data_t *obj) const
MacroAction::Save(obj);
obs_data_set_int(obj, "action", static_cast<int>(_action));
_scene.Save(obj);
obs_data_set_int(obj, "version", 1);
return true;
}
@ -90,6 +213,34 @@ bool MacroActionSudioMode::Load(obs_data_t *obj)
MacroAction::Load(obj);
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
_scene.Load(obj);
if (!obs_data_has_user_value(obj, "version")) {
enum class OldAction {
SWAP_SCENE,
SET_SCENE,
ENABLE_STUDIO_MODE,
DISABLE_STUDIO_MODE,
};
switch (static_cast<OldAction>(
obs_data_get_int(obj, "action"))) {
case OldAction::SWAP_SCENE:
_action = Action::TRANSITION_WITH_SWAP;
break;
case OldAction::SET_SCENE:
_action = Action::SET_SCENE;
break;
case OldAction::ENABLE_STUDIO_MODE:
_action = Action::ENABLE_STUDIO_MODE;
break;
case OldAction::DISABLE_STUDIO_MODE:
_action = Action::DISABLE_STUDIO_MODE;
break;
default:
break;
}
}
return true;
}
@ -136,15 +287,11 @@ MacroActionStudioModeEdit::MacroActionStudioModeEdit(
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{actions}}", _actions},
{"{{scenes}}", _scenes},
};
QHBoxLayout *mainLayout = new QHBoxLayout;
auto layout = new QHBoxLayout;
PlaceWidgets(
obs_module_text("AdvSceneSwitcher.action.studioMode.entry"),
mainLayout, widgetPlaceholders);
setLayout(mainLayout);
layout, {{"{{actions}}", _actions}, {"{{scenes}}", _scenes}});
setLayout(layout);
_entryData = entryData;
UpdateEntryData();

View File

@ -18,13 +18,28 @@ public:
void ResolveVariablesToFixedValues();
enum class Action {
SWAP_SCENE,
SET_SCENE, // TODO: Remove in future version as the
// functionality moved to the scene switch action
ENABLE_STUDIO_MODE,
DISABLE_STUDIO_MODE,
TRANSITION = 10,
TRANSITION_WITH_SWAP = 20,
ENALBE_TRANSITION_SWAP = 30,
DISABLE_TRANSITION_SWAP = 40,
TOGGLE_TRANSITION_SWAP = 50,
ENALBE_DUPLICATE_SCENE = 60,
DISABLE_DUPLICATE_SCENE = 70,
TOGGLE_DUPLICATE_SCENE = 80,
ENALBE_DUPLICATE_SOURCE = 90,
DISABLE_DUPLICATE_SOURCE = 100,
TOGGLE_DUPLICATE_SOURCE = 110,
ENABLE_STUDIO_MODE = 120,
DISABLE_STUDIO_MODE = 130,
TOGGLE_STUDIO_MODE = 140,
SET_SCENE = 1000, // Deprecated
};
Action _action = Action::SWAP_SCENE;
Action _action = Action::TRANSITION;
SceneSelection _scene;
private: