Skip to content

Commit 3f2eb40

Browse files
committed
Improve "Studio mode" action
1 parent 6932de8 commit 3f2eb40

9 files changed

Lines changed: 201 additions & 29 deletions

File tree

data/locale/de-DE.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ AdvSceneSwitcher.action.file.type.write="Schreiben"
495495
AdvSceneSwitcher.action.file.type.append="Anhängen"
496496
AdvSceneSwitcher.action.file.entry="{{actions}} in {{filePath}}:"
497497
AdvSceneSwitcher.action.studioMode="Studio-Modus"
498-
AdvSceneSwitcher.action.studioMode.type.swap="Vorschau- und Programm-Szene tauschen"
498+
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Vorschau- und Programm-Szene tauschen"
499499
AdvSceneSwitcher.action.studioMode.type.setScene="Vorschau-Szene einstellen auf"
500500
AdvSceneSwitcher.action.studioMode.type.enable="Studio-Modus aktivieren"
501501
AdvSceneSwitcher.action.studioMode.type.disable="Studio-Modus deaktivieren"

data/locale/en-US.ini

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,17 @@ AdvSceneSwitcher.action.file.type.write="Write"
10551055
AdvSceneSwitcher.action.file.type.append="Append"
10561056
AdvSceneSwitcher.action.file.entry="{{actions}}to{{filePath}}:"
10571057
AdvSceneSwitcher.action.studioMode="Studio mode"
1058-
AdvSceneSwitcher.action.studioMode.type.swap="Swap preview and program scene"
1058+
AdvSceneSwitcher.action.studioMode.type.transition="Transition"
1059+
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Swap preview and program scene"
1060+
AdvSceneSwitcher.action.studioMode.type.transitionSwap.enable="Enable preview/program scene swapping after transition"
1061+
AdvSceneSwitcher.action.studioMode.type.transitionSwap.disable="Disable preview/program scene swapping after transition"
1062+
AdvSceneSwitcher.action.studioMode.type.transitionSwap.toggle="Toggle preview/program scene swapping after transition"
1063+
AdvSceneSwitcher.action.studioMode.type.duplicateScene.enable="Enable scene duplication"
1064+
AdvSceneSwitcher.action.studioMode.type.duplicateScene.disable="Disable scene duplication"
1065+
AdvSceneSwitcher.action.studioMode.type.duplicateScene.toggle="Toggle scene duplication"
1066+
AdvSceneSwitcher.action.studioMode.type.duplicateSource.enable="Enable source duplication"
1067+
AdvSceneSwitcher.action.studioMode.type.duplicateSource.disable="Disable source duplication"
1068+
AdvSceneSwitcher.action.studioMode.type.duplicateSource.toggle="Toggle source duplication"
10591069
AdvSceneSwitcher.action.studioMode.type.setScene="Set preview scene to"
10601070
AdvSceneSwitcher.action.studioMode.type.enable="Enable studio mode"
10611071
AdvSceneSwitcher.action.studioMode.type.disable="Disable studio mode"

data/locale/es-ES.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ AdvSceneSwitcher.action.file.type.write="Escribir"
413413
AdvSceneSwitcher.action.file.type.append="Agregar"
414414
AdvSceneSwitcher.action.file.entry="{{actions}} a {{filePath}}:"
415415
AdvSceneSwitcher.action.studioMode="Modo estudio"
416-
AdvSceneSwitcher.action.studioMode.type.swap="Intercambiar vista previa y escena del programa"
416+
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Intercambiar vista previa y escena del programa"
417417
AdvSceneSwitcher.action.studioMode.type.setScene="Establecer escena de vista previa en"
418418
AdvSceneSwitcher.action.studioMode.type.enable="Activar modo estudio"
419419
AdvSceneSwitcher.action.studioMode.type.disable="Deshabilitar el modo de estudio"

data/locale/fr-FR.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ AdvSceneSwitcher.action.file.type.write="Écrire"
613613
AdvSceneSwitcher.action.file.type.append="Ajouter"
614614
AdvSceneSwitcher.action.file.entry="{{actions}}vers{{filePath}}:"
615615
AdvSceneSwitcher.action.studioMode="Mode studio"
616-
AdvSceneSwitcher.action.studioMode.type.swap="Permuter la scène de prévisualisation et la scène du programme"
616+
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Permuter la scène de prévisualisation et la scène du programme"
617617
AdvSceneSwitcher.action.studioMode.type.setScene="Définir la scène de prévisualisation sur"
618618
AdvSceneSwitcher.action.studioMode.type.enable="Activer le mode studio"
619619
AdvSceneSwitcher.action.studioMode.type.disable="Désactiver le mode studio"

data/locale/ja-JP.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ AdvSceneSwitcher.action.file="ファイル"
10161016
; AdvSceneSwitcher.action.file.type.append="Append"
10171017
AdvSceneSwitcher.action.file.entry="{{actions}}から{{filePath}}へ:"
10181018
AdvSceneSwitcher.action.studioMode="スタジオモード"
1019-
AdvSceneSwitcher.action.studioMode.type.swap="プレビューと番組シーンの入れ替え"
1019+
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="プレビューと番組シーンの入れ替え"
10201020
AdvSceneSwitcher.action.studioMode.type.setScene="プレビューシーンを設定する"
10211021
AdvSceneSwitcher.action.studioMode.type.enable="スタジオモードを有効にする"
10221022
AdvSceneSwitcher.action.studioMode.type.disable="スタジオモードを無効にする"

data/locale/pt-BR.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ AdvSceneSwitcher.action.file.type.write="Escrever"
923923
AdvSceneSwitcher.action.file.type.append="Anexar"
924924
AdvSceneSwitcher.action.file.entry="{{actions}}para{{filePath}}:"
925925
AdvSceneSwitcher.action.studioMode="Modo estúdio"
926-
AdvSceneSwitcher.action.studioMode.type.swap="Trocar cena de visualização e programa"
926+
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="Trocar cena de visualização e programa"
927927
AdvSceneSwitcher.action.studioMode.type.setScene="Definir cena de visualização para"
928928
AdvSceneSwitcher.action.studioMode.type.enable="Habilitar modo estúdio"
929929
AdvSceneSwitcher.action.studioMode.type.disable="Desabilitar modo estúdio"

data/locale/zh-CN.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ AdvSceneSwitcher.action.file.type.write="覆盖写入"
984984
AdvSceneSwitcher.action.file.type.append="追加写入"
985985
AdvSceneSwitcher.action.file.entry="{{actions}} 到 {{filePath}}:"
986986
AdvSceneSwitcher.action.studioMode="工作室模式"
987-
AdvSceneSwitcher.action.studioMode.type.swap="切换预览和程序场景"
987+
AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="切换预览和程序场景"
988988
AdvSceneSwitcher.action.studioMode.type.setScene="将预览场景设置为"
989989
AdvSceneSwitcher.action.studioMode.type.enable="启用工作室模式"
990990
AdvSceneSwitcher.action.studioMode.type.disable="停用工作室模式"

plugins/base/macro-action-studio-mode.cpp

Lines changed: 163 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "layout-helpers.hpp"
33

44
#include <obs-frontend-api.h>
5+
#include <util/config-file.h>
56

67
namespace advss {
78

@@ -13,16 +14,64 @@ bool MacroActionSudioMode::_registered = MacroActionFactory::Register(
1314
"AdvSceneSwitcher.action.studioMode"});
1415

1516
const static std::map<MacroActionSudioMode::Action, std::string> actionTypes = {
16-
{MacroActionSudioMode::Action::SWAP_SCENE,
17-
"AdvSceneSwitcher.action.studioMode.type.swap"},
18-
{MacroActionSudioMode::Action::SET_SCENE,
19-
"AdvSceneSwitcher.action.studioMode.type.setScene"},
17+
{MacroActionSudioMode::Action::TRANSITION,
18+
"AdvSceneSwitcher.action.studioMode.type.transition"},
19+
{MacroActionSudioMode::Action::TRANSITION_WITH_SWAP,
20+
"AdvSceneSwitcher.action.studioMode.type.transitionWithSwap"},
21+
{MacroActionSudioMode::Action::ENALBE_TRANSITION_SWAP,
22+
"AdvSceneSwitcher.action.studioMode.type.transitionSwap.enable"},
23+
{MacroActionSudioMode::Action::DISABLE_TRANSITION_SWAP,
24+
"AdvSceneSwitcher.action.studioMode.type.transitionSwap.disable"},
25+
{MacroActionSudioMode::Action::TOGGLE_TRANSITION_SWAP,
26+
"AdvSceneSwitcher.action.studioMode.type.transitionSwap.toggle"},
27+
{MacroActionSudioMode::Action::ENALBE_DUPLICATE_SCENE,
28+
"AdvSceneSwitcher.action.studioMode.type.duplicateScene.enable"},
29+
{MacroActionSudioMode::Action::DISABLE_DUPLICATE_SCENE,
30+
"AdvSceneSwitcher.action.studioMode.type.duplicateScene.disable"},
31+
{MacroActionSudioMode::Action::TOGGLE_DUPLICATE_SCENE,
32+
"AdvSceneSwitcher.action.studioMode.type.duplicateScene.toggle"},
33+
{MacroActionSudioMode::Action::ENALBE_DUPLICATE_SOURCE,
34+
"AdvSceneSwitcher.action.studioMode.type.duplicateSource.enable"},
35+
{MacroActionSudioMode::Action::DISABLE_DUPLICATE_SOURCE,
36+
"AdvSceneSwitcher.action.studioMode.type.duplicateSource.disable"},
37+
{MacroActionSudioMode::Action::TOGGLE_DUPLICATE_SOURCE,
38+
"AdvSceneSwitcher.action.studioMode.type.duplicateSource.toggle"},
2039
{MacroActionSudioMode::Action::ENABLE_STUDIO_MODE,
2140
"AdvSceneSwitcher.action.studioMode.type.enable"},
2241
{MacroActionSudioMode::Action::DISABLE_STUDIO_MODE,
2342
"AdvSceneSwitcher.action.studioMode.type.disable"},
43+
{MacroActionSudioMode::Action::TOGGLE_STUDIO_MODE,
44+
"AdvSceneSwitcher.action.studioMode.type.toggle"},
45+
{MacroActionSudioMode::Action::SET_SCENE,
46+
"AdvSceneSwitcher.action.studioMode.type.setScene"},
2447
};
2548

49+
template<typename Func, typename... Args>
50+
static void setConfigValueHelper(Func func, Args... args)
51+
{
52+
auto config = obs_frontend_get_user_config();
53+
func(config, args...);
54+
if (config_save(config) != CONFIG_SUCCESS) {
55+
blog(LOG_WARNING, "failed to save user config!");
56+
}
57+
}
58+
59+
template<typename Func, typename... Args>
60+
static auto getConfigValueHelper(Func func, Func defaultFunc, Args... args)
61+
-> std::optional<std::invoke_result_t<Func, config_t *, Args...>>
62+
{
63+
using Ret = std::invoke_result_t<Func, config_t *, Args...>;
64+
65+
auto config = obs_frontend_get_user_config();
66+
if (config_has_user_value(config, args...)) {
67+
return func(config, args...);
68+
}
69+
if (config_has_default_value(config, args...)) {
70+
return defaultFunc(config, args...);
71+
}
72+
return std::optional<Ret>{};
73+
}
74+
2675
// Calling obs_frontend_set_preview_program_mode() directly from a thread that
2776
// is not the main OBS UI thread will lead to undefined behaviour, so we have
2877
// to use this helper function instead - copied from obs-websocket plugin
@@ -42,14 +91,78 @@ static void enableStudioMode(bool enable)
4291

4392
bool MacroActionSudioMode::PerformAction()
4493
{
94+
obs_frontend_get_user_config();
4595
switch (_action) {
46-
case Action::SWAP_SCENE:
96+
case Action::TRANSITION:
4797
obs_frontend_preview_program_trigger_transition();
4898
break;
49-
case Action::SET_SCENE: {
50-
auto s = obs_weak_source_get_source(_scene.GetScene());
51-
obs_frontend_set_current_preview_scene(s);
52-
obs_source_release(s);
99+
case Action::TRANSITION_WITH_SWAP: {
100+
auto swapEnabled = getConfigValueHelper(config_get_bool,
101+
config_get_default_bool,
102+
"BasicWindow",
103+
"SwapScenesMode");
104+
105+
if (swapEnabled.has_value() && *swapEnabled == true) {
106+
obs_frontend_preview_program_trigger_transition();
107+
break;
108+
}
109+
110+
setConfigValueHelper(config_set_bool, "BasicWindow",
111+
"SwapScenesMode", true);
112+
obs_frontend_preview_program_trigger_transition();
113+
setConfigValueHelper(config_set_bool, "BasicWindow",
114+
"SwapScenesMode", false);
115+
break;
116+
}
117+
case Action::ENALBE_TRANSITION_SWAP:
118+
setConfigValueHelper(config_set_bool, "BasicWindow",
119+
"SwapScenesMode", true);
120+
break;
121+
case Action::DISABLE_TRANSITION_SWAP:
122+
setConfigValueHelper(config_set_bool, "BasicWindow",
123+
"SwapScenesMode", false);
124+
break;
125+
case Action::TOGGLE_TRANSITION_SWAP: {
126+
const auto enabled = getConfigValueHelper(
127+
config_get_bool, config_get_default_bool, "BasicWindow",
128+
"SwapScenesMode");
129+
setConfigValueHelper(config_set_bool, "BasicWindow",
130+
"SwapScenesMode",
131+
enabled.has_value() && !*enabled);
132+
break;
133+
}
134+
case Action::ENALBE_DUPLICATE_SCENE:
135+
setConfigValueHelper(config_set_bool, "BasicWindow",
136+
"SceneDuplicationMode", true);
137+
break;
138+
case Action::DISABLE_DUPLICATE_SCENE:
139+
setConfigValueHelper(config_set_bool, "BasicWindow",
140+
"SceneDuplicationMode", false);
141+
break;
142+
case Action::TOGGLE_DUPLICATE_SCENE: {
143+
const auto enabled = getConfigValueHelper(
144+
config_get_bool, config_get_default_bool, "BasicWindow",
145+
"SceneDuplicationMode");
146+
setConfigValueHelper(config_set_bool, "BasicWindow",
147+
"SceneDuplicationMode",
148+
enabled.has_value() && !*enabled);
149+
break;
150+
}
151+
case Action::ENALBE_DUPLICATE_SOURCE:
152+
setConfigValueHelper(config_set_bool, "BasicWindow",
153+
"EditPropertiesMode", true);
154+
break;
155+
case Action::DISABLE_DUPLICATE_SOURCE:
156+
setConfigValueHelper(config_set_bool, "BasicWindow",
157+
"EditPropertiesMode", false);
158+
break;
159+
case Action::TOGGLE_DUPLICATE_SOURCE: {
160+
const auto enabled = getConfigValueHelper(
161+
config_get_bool, config_get_default_bool, "BasicWindow",
162+
"EditPropertiesMode");
163+
setConfigValueHelper(config_set_bool, "BasicWindow",
164+
"EditPropertiesMode",
165+
enabled.has_value() && !*enabled);
53166
break;
54167
}
55168
case Action::ENABLE_STUDIO_MODE:
@@ -58,6 +171,15 @@ bool MacroActionSudioMode::PerformAction()
58171
case Action::DISABLE_STUDIO_MODE:
59172
enableStudioMode(false);
60173
break;
174+
case Action::TOGGLE_STUDIO_MODE:
175+
enableStudioMode(!obs_frontend_preview_program_mode_active());
176+
break;
177+
case Action::SET_SCENE: {
178+
auto s = obs_weak_source_get_source(_scene.GetScene());
179+
obs_frontend_set_current_preview_scene(s);
180+
obs_source_release(s);
181+
break;
182+
}
61183
default:
62184
break;
63185
}
@@ -82,6 +204,7 @@ bool MacroActionSudioMode::Save(obs_data_t *obj) const
82204
MacroAction::Save(obj);
83205
obs_data_set_int(obj, "action", static_cast<int>(_action));
84206
_scene.Save(obj);
207+
obs_data_set_int(obj, "version", 1);
85208
return true;
86209
}
87210

@@ -90,6 +213,34 @@ bool MacroActionSudioMode::Load(obs_data_t *obj)
90213
MacroAction::Load(obj);
91214
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
92215
_scene.Load(obj);
216+
217+
if (!obs_data_has_user_value(obj, "version")) {
218+
enum class OldAction {
219+
SWAP_SCENE,
220+
SET_SCENE,
221+
ENABLE_STUDIO_MODE,
222+
DISABLE_STUDIO_MODE,
223+
};
224+
225+
switch (static_cast<OldAction>(
226+
obs_data_get_int(obj, "action"))) {
227+
case OldAction::SWAP_SCENE:
228+
_action = Action::TRANSITION_WITH_SWAP;
229+
break;
230+
case OldAction::SET_SCENE:
231+
_action = Action::SET_SCENE;
232+
break;
233+
case OldAction::ENABLE_STUDIO_MODE:
234+
_action = Action::ENABLE_STUDIO_MODE;
235+
break;
236+
case OldAction::DISABLE_STUDIO_MODE:
237+
_action = Action::DISABLE_STUDIO_MODE;
238+
break;
239+
default:
240+
break;
241+
}
242+
}
243+
93244
return true;
94245
}
95246

@@ -136,15 +287,11 @@ MacroActionStudioModeEdit::MacroActionStudioModeEdit(
136287
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
137288
this, SLOT(SceneChanged(const SceneSelection &)));
138289

139-
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
140-
{"{{actions}}", _actions},
141-
{"{{scenes}}", _scenes},
142-
};
143-
QHBoxLayout *mainLayout = new QHBoxLayout;
290+
auto layout = new QHBoxLayout;
144291
PlaceWidgets(
145292
obs_module_text("AdvSceneSwitcher.action.studioMode.entry"),
146-
mainLayout, widgetPlaceholders);
147-
setLayout(mainLayout);
293+
layout, {{"{{actions}}", _actions}, {"{{scenes}}", _scenes}});
294+
setLayout(layout);
148295

149296
_entryData = entryData;
150297
UpdateEntryData();

plugins/base/macro-action-studio-mode.hpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,28 @@ class MacroActionSudioMode : public MacroAction {
1818
void ResolveVariablesToFixedValues();
1919

2020
enum class Action {
21-
SWAP_SCENE,
22-
SET_SCENE, // TODO: Remove in future version as the
23-
// functionality moved to the scene switch action
24-
ENABLE_STUDIO_MODE,
25-
DISABLE_STUDIO_MODE,
21+
TRANSITION = 10,
22+
TRANSITION_WITH_SWAP = 20,
23+
24+
ENALBE_TRANSITION_SWAP = 30,
25+
DISABLE_TRANSITION_SWAP = 40,
26+
TOGGLE_TRANSITION_SWAP = 50,
27+
28+
ENALBE_DUPLICATE_SCENE = 60,
29+
DISABLE_DUPLICATE_SCENE = 70,
30+
TOGGLE_DUPLICATE_SCENE = 80,
31+
32+
ENALBE_DUPLICATE_SOURCE = 90,
33+
DISABLE_DUPLICATE_SOURCE = 100,
34+
TOGGLE_DUPLICATE_SOURCE = 110,
35+
36+
ENABLE_STUDIO_MODE = 120,
37+
DISABLE_STUDIO_MODE = 130,
38+
TOGGLE_STUDIO_MODE = 140,
39+
40+
SET_SCENE = 1000, // Deprecated
2641
};
27-
Action _action = Action::SWAP_SCENE;
42+
Action _action = Action::TRANSITION;
2843
SceneSelection _scene;
2944

3045
private:

0 commit comments

Comments
 (0)