Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/locale/de-DE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
12 changes: 11 additions & 1 deletion data/locale/en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,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"
Expand Down
2 changes: 1 addition & 1 deletion data/locale/es-ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion data/locale/fr-FR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion data/locale/ja-JP.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,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="スタジオモードを無効にする"
Expand Down
2 changes: 1 addition & 1 deletion data/locale/pt-BR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion data/locale/zh-CN.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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="停用工作室模式"
Expand Down
179 changes: 163 additions & 16 deletions plugins/base/macro-action-studio-mode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "layout-helpers.hpp"

#include <obs-frontend-api.h>
#include <util/config-file.h>

namespace advss {

Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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;
}
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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();
Expand Down
27 changes: 21 additions & 6 deletions plugins/base/macro-action-studio-mode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,28 @@ class MacroActionSudioMode : public MacroAction {
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:
Expand Down
Loading