Compare commits

..

1 Commits

Author SHA1 Message Date
WarmUpTill
3f2eb40c06 Improve "Studio mode" action 2025-10-28 19:21:29 +01:00
39 changed files with 440 additions and 605 deletions

View File

@@ -6,7 +6,7 @@ on:
description: "Project name detected by parsing build spec file"
value: ${{ jobs.check-event.outputs.pluginName }}
env:
DEP_DIR: .deps/advss-build-dependencies-2
DEP_DIR: .deps/advss-build-dependencies-3
jobs:
check-event:
name: Check GitHub Event Data 🔎

View File

@@ -1,33 +1,33 @@
{
"dependencies": {
"obs-studio": {
"version": "30.1.2",
"version": "31.1.1",
"baseUrl": "https://github.com/obsproject/obs-studio/archive/refs/tags",
"label": "OBS sources",
"hashes": {
"macos": "490bae1c392b3b344b0270afd8cb887da4bc50bd92c0c426e96713c1ccb9701a",
"windows-x64": "c2dd03fa7fd01fad5beafce8f7156da11f9ed9a588373fd40b44a06f4c03b867"
"macos": "39751f067bacc13d44b116c5138491b5f1391f91516d3d590d874edd21292291",
"windows-x64": "2c8427c10b55ac6d68008df2e9a3e82f4647aaad18f105e30d4713c2de678ccf"
}
},
"prebuilt": {
"version": "2024-03-19",
"version": "2025-07-11",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built obs-deps",
"hashes": {
"macos": "2e9bfb55a5e0e4c1086fa1fda4cf268debfead473089df2aaea80e1c7a3ca7ff",
"windows-x64": "6e86068371526a967e805f6f9903f9407adb683c21820db5f07da8f30d11e998"
"macos": "495687e63383d1a287684b6e2e9bfe246bb8f156fe265926afb1a325af1edd2a",
"windows-x64": "c8c642c1070dc31ce9a0f1e4cef5bb992f4bff4882255788b5da12129e85caa7"
}
},
"qt6": {
"version": "2024-03-19",
"version": "2025-07-11",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built Qt6",
"hashes": {
"macos": "694f1e639c017e3b1f456f735330dc5afae287cbea85757101af1368de3142c8",
"windows-x64": "72d1df34a0ef7413a681d5fcc88cae81da60adc03dcd23ef17862ab170bcc0dd"
"macos": "d3f5f04b6ea486e032530bdf0187cbda9a54e0a49621a4c8ba984c5023998867",
"windows-x64": "0e76bf0555dd5382838850b748d3dcfab44a1e1058441309ab54e1a65b156d0a"
},
"debugSymbols": {
"windows-x64": "fbddd1f659c360f2291911ac5709b67b6f8182e6bca519d24712e4f6fd3cc865"
"windows-x64": "11b7be92cf66a273299b8f3515c07a5cfb61614b59a4e67f7fc5ecba5e2bdf21"
}
}
},

View File

@@ -65,17 +65,16 @@ function(_setup_obs_studio)
if(OS_WINDOWS)
set(_cmake_generator "${CMAKE_GENERATOR}")
set(_cmake_arch "-A ${arch}")
set(_cmake_arch
"-A ${arch},version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
set(_cmake_extra
"-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} -DCMAKE_ENABLE_SCRIPTING=OFF"
)
set(_cmake_version "2.0.0")
elseif(OS_MACOS)
set(_cmake_generator "Xcode")
set(_cmake_arch "-DCMAKE_OSX_ARCHITECTURES:STRING='arm64;x86_64'")
set(_cmake_extra
"-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
set(_cmake_version "3.0.0")
endif()
message(STATUS "Configure ${label} (${arch})")
@@ -83,32 +82,42 @@ function(_setup_obs_studio)
COMMAND
"${CMAKE_COMMAND}" -S "${dependencies_dir}/${_obs_destination}" -B
"${dependencies_dir}/${_obs_destination}/build_${arch}" -G
${_cmake_generator} "${_cmake_arch}"
-DOBS_CMAKE_VERSION:STRING=${_cmake_version} -DENABLE_PLUGINS:BOOL=OFF
-DENABLE_UI:BOOL=OFF -DOBS_VERSION_OVERRIDE:STRING=${_obs_version}
${_cmake_generator} "${_cmake_arch}" -DOBS_CMAKE_VERSION:STRING=3.0.0
-DENABLE_PLUGINS:BOOL=OFF -DENABLE_FRONTEND:BOOL=OFF
-DOBS_VERSION_OVERRIDE:STRING=${_obs_version}
"-DCMAKE_PREFIX_PATH='${CMAKE_PREFIX_PATH}'" ${_is_fresh} ${_cmake_extra}
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
message(STATUS "Configure ${label} (${arch}) - done")
message(STATUS "Build ${label} (${arch})")
message(STATUS "Build ${label} (Debug - ${arch})")
execute_process(
COMMAND "${CMAKE_COMMAND}" --build build_${arch} --target obs-frontend-api
--config Debug --parallel
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
message(STATUS "Build ${label} (${arch}) - done")
message(STATUS "Build ${label} (Debug - ${arch}) - done")
message(STATUS "Build ${label} (Release - ${arch})")
execute_process(
COMMAND "${CMAKE_COMMAND}" --build build_${arch} --target obs-frontend-api
--config Release --parallel
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
message(STATUS "Build ${label} (Reelase - ${arch}) - done")
message(STATUS "Install ${label} (${arch})")
if(OS_WINDOWS)
set(_cmake_extra "--component obs_libraries")
else()
set(_cmake_extra "")
endif()
execute_process(
COMMAND "${CMAKE_COMMAND}" --install build_${arch} --component Development
--config Debug --prefix "${dependencies_dir}" ${_cmake_extra}
--config Debug --prefix "${dependencies_dir}"
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
execute_process(
COMMAND "${CMAKE_COMMAND}" --install build_${arch} --component Development
--config Release --prefix "${dependencies_dir}"
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)

View File

@@ -4,6 +4,7 @@
# ---------------------------------------------------------------------------
if(WIN32 AND (NOT OpenSSL_FOUND))
set(_openssl_roots
"$ENV{ProgramFiles}/OpenSSL-Win64" "$ENV{ProgramFiles}/OpenSSL"
"$ENV{ProgramW6432}/OpenSSL-Win64")
@@ -46,33 +47,20 @@ if(WIN32 AND (NOT OpenSSL_FOUND))
AND EXISTS "${_root}/${_suffix}/libcrypto.lib")
set(OPENSSL_ROOT_DIR
"${_root}"
CACHE PATH "Path to OpenSSL root" FORCE)
CACHE PATH "Path to OpenSSL root")
set(OPENSSL_CRYPTO_LIBRARY
"${_root}/${_suffix}/libcrypto.lib"
CACHE FILEPATH "OpenSSL crypto lib" FORCE)
CACHE FILEPATH "OpenSSL crypto lib")
set(OPENSSL_SSL_LIBRARY
"${_root}/${_suffix}/libssl.lib"
CACHE FILEPATH "OpenSSL ssl lib" FORCE)
CACHE FILEPATH "OpenSSL ssl lib")
set(OPENSSL_INCLUDE_DIR
"${_root}/include"
CACHE PATH "OpenSSL include dir" FORCE)
CACHE PATH "OpenSSL include dir")
set(OpenSSL_FOUND
TRUE
CACHE BOOL "Whether OpenSSL was found" FORCE)
CACHE BOOL "Whether OpenSSL was found")
message(STATUS "Found OpenSSL at: ${_root}/${_suffix}")
# Recursively list all files under OPENSSL_ROOT_DIR
file(GLOB_RECURSE OPENSSL_FILES "${OPENSSL_ROOT_DIR}/*")
message(STATUS "Listing contents of OPENSSL_ROOT_DIR:")
foreach(file ${OPENSSL_FILES})
message(STATUS " ${file}")
endforeach()
get_cmake_property(_variableNames VARIABLES)
list(SORT _variableNames)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
return()
endif()
endforeach()

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

@@ -984,16 +984,12 @@ AdvSceneSwitcher.action.macro.type.disableAction="Disable action"
AdvSceneSwitcher.action.macro.type.enableAction="Enable action"
AdvSceneSwitcher.action.macro.type.toggleAction="Toggle action"
AdvSceneSwitcher.action.macro.type.nestedMacro="Nested macro"
AdvSceneSwitcher.action.macro.actionSelectionType.index="at index"
AdvSceneSwitcher.action.macro.actionSelectionType.label="with label"
AdvSceneSwitcher.action.macro.actionSelectionType.id="of action type"
AdvSceneSwitcher.action.macro.type.nestedMacro.conditionHelp="This section allows you to define macro conditions.\n\nClick the plus button below to add a new condition."
AdvSceneSwitcher.action.macro.type.nestedMacro.actionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are met.\n\nClick the plus button below to add a new action."
AdvSceneSwitcher.action.macro.type.nestedMacro.elseActionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are *not* met.\n\nClick the plus button below to add a new action."
AdvSceneSwitcher.action.macro.layout.run="{{actions}}{{actionSections}}of{{macros}}"
AdvSceneSwitcher.action.macro.layout.run.condition="{{conditionBehaviors}}of{{conditionMacros}}"
AdvSceneSwitcher.action.macro.layout.actionState="{{actions}}{{actionSelectionType}}{{actionIndex}}{{label}}{{regex}}{{actionTypes}}in{{actionSections}}section of{{macros}}"
AdvSceneSwitcher.action.macro.layout.other="{{actions}}{{macros}}"
AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}of{{macros}}"
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}of{{conditionMacros}}"
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Plugin state"
AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin"
AdvSceneSwitcher.action.pluginState.type.noMatch="Change the no-match behaviour:"
@@ -1059,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"

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

@@ -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="スタジオモードを無効にする"

View File

@@ -861,9 +861,9 @@ AdvSceneSwitcher.action.macro.type.stop="Parar ações"
AdvSceneSwitcher.action.macro.type.disableAction="Desabilitar ação"
AdvSceneSwitcher.action.macro.type.enableAction="Habilitar ação"
AdvSceneSwitcher.action.macro.type.toggleAction="Alternar ação"
AdvSceneSwitcher.action.macro.layout.run="{{actions}}{{actionSections}}de{{macros}}"
AdvSceneSwitcher.action.macro.layout.run.condition="{{conditionBehaviors}}de{{conditionMacros}}"
AdvSceneSwitcher.action.macro.layout.other="{{actions}}{{macros}}"
AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}de{{macros}}"
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}de{{conditionMacros}}"
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Estado do plugin"
AdvSceneSwitcher.action.pluginState.type.stop="Parar o plugin Advanced Scene Switcher"
AdvSceneSwitcher.action.pluginState.type.noMatch="Alterar o comportamento em caso de não correspondência:"
@@ -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

@@ -920,9 +920,9 @@ AdvSceneSwitcher.action.macro.type.stop="停止操作"
AdvSceneSwitcher.action.macro.type.disableAction="停用操作"
AdvSceneSwitcher.action.macro.type.enableAction="启用操作"
AdvSceneSwitcher.action.macro.type.toggleAction="切换操作开关"
AdvSceneSwitcher.action.macro.layout.run="{{actions}}{{actionSections}}{{macros}}"
AdvSceneSwitcher.action.macro.layout.run.condition="{{conditionBehaviors}}{{conditionMacros}}"
AdvSceneSwitcher.action.macro.layout.other="{{actions}}{{macros}}"
AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}{{macros}}"
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}{{conditionMacros}}"
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="插件状态"
AdvSceneSwitcher.action.pluginState.type.stop="停止高级场景切换插件"
AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项时:"
@@ -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

@@ -421,7 +421,7 @@ bool SwitcherData::CheckForMatch(OBSWeakSource &scene,
static void ResetMacros()
{
for (auto &m : GetTopLevelMacros()) {
for (auto &m : GetMacros()) {
ResetMacroRunCount(m.get());
ResetMacroConditionTimers(m.get());
}

View File

@@ -459,7 +459,7 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
LoadHotkeys(obj);
LoadUISettings(obj);
RunAndClearPostLoadSteps();
RunPostLoadSteps();
// Reset on startup and scene collection change
ResetLastOpenedTab();

View File

@@ -117,7 +117,7 @@ void MacroActionEdit::ActionSelectionChanged(const QString &text)
*_entryData = MacroActionFactory::Create(id, macro);
(*_entryData)->SetIndex(idx);
(*_entryData)->PostLoad();
RunAndClearPostLoadSteps();
RunPostLoadSteps();
}
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),

View File

@@ -2,7 +2,6 @@
#include "help-icon.hpp"
#include "layout-helpers.hpp"
#include "macro.hpp"
#include "macro-action-factory.hpp"
namespace advss {
@@ -13,74 +12,6 @@ bool MacroActionMacro::_registered = MacroActionFactory::Register(
{MacroActionMacro::Create, MacroActionMacroEdit::Create,
"AdvSceneSwitcher.action.macro"});
void MacroActionMacro::AdjustActionState(Macro *macro) const
{
const auto &macroActions = _useElseSection ? macro->ElseActions()
: macro->Actions();
std::vector<std::shared_ptr<MacroAction>> actionsToModify;
switch (_actionSelectionType) {
case SelectionType::INDEX: {
const bool isValidAction =
(_useElseSection &&
IsValidElseActionIndex(macro, _actionIndex - 1)) ||
(!_useElseSection &&
IsValidActionIndex(macro, _actionIndex - 1));
if (isValidAction) {
actionsToModify.emplace_back(
macroActions.at(_actionIndex - 1));
}
break;
}
case SelectionType::LABEL:
for (const auto &action : macroActions) {
if (!action->GetUseCustomLabel()) {
continue;
}
const auto label = action->GetCustomLabel();
if (_regex.Enabled()) {
if (_regex.Matches(label, _label)) {
actionsToModify.emplace_back(action);
}
continue;
}
if (label == std::string(_label)) {
actionsToModify.emplace_back(action);
}
}
break;
case SelectionType::ID:
for (const auto &action : macroActions) {
if (action->GetId() == _actionId) {
actionsToModify.emplace_back(action);
}
}
break;
default:
break;
}
for (const auto &action : actionsToModify) {
switch (_action) {
case Action::DISABLE_ACTION:
action->SetEnabled(false);
break;
case Action::ENABLE_ACTION:
action->SetEnabled(true);
break;
case Action::TOGGLE_ACTION:
action->SetEnabled(!action->Enabled());
break;
default:
break;
}
}
}
bool MacroActionMacro::PerformAction()
{
if (_action == Action::NESTED_MACRO) {
@@ -113,9 +44,23 @@ bool MacroActionMacro::PerformAction()
macro->Stop();
break;
case Action::DISABLE_ACTION:
if (IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1,
false)) {
macro->Actions().at(_actionIndex - 1)->SetEnabled(false);
}
break;
case Action::ENABLE_ACTION:
if (IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1,
false)) {
macro->Actions().at(_actionIndex - 1)->SetEnabled(true);
}
break;
case Action::TOGGLE_ACTION:
AdjustActionState(macro.get());
if (IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1,
false)) {
auto action = macro->Actions().at(_actionIndex - 1);
action->SetEnabled(!action->Enabled());
}
break;
default:
break;
@@ -170,14 +115,9 @@ void MacroActionMacro::LogAction() const
bool MacroActionMacro::Save(obs_data_t *obj) const
{
MacroAction::Save(obj);
obs_data_set_int(obj, "action", static_cast<int>(_action));
_macro.Save(obj);
obs_data_set_int(obj, "actionSelectionType",
static_cast<int>(_actionSelectionType));
_actionIndex.Save(obj, "actionIndex");
_label.Save(obj, "label");
obs_data_set_string(obj, "actionId", _actionId.c_str());
_regex.Save(obj);
obs_data_set_int(obj, "action", static_cast<int>(_action));
_runOptions.Save(obj);
OBSDataAutoRelease nestedMacroData = obs_data_create();
_nestedMacro->Save(nestedMacroData);
@@ -189,15 +129,10 @@ bool MacroActionMacro::Save(obs_data_t *obj) const
bool MacroActionMacro::Load(obs_data_t *obj)
{
MacroAction::Load(obj);
_macro.Load(obj);
_actionIndex.Load(obj, "actionIndex");
_action = static_cast<MacroActionMacro::Action>(
obs_data_get_int(obj, "action"));
_macro.Load(obj);
_actionSelectionType = static_cast<SelectionType>(
obs_data_get_int(obj, "actionSelectionType"));
_actionIndex.Load(obj, "actionIndex");
_label.Load(obj, "label");
_actionId = obs_data_get_string(obj, "actionId");
_regex.Load(obj);
_runOptions.Load(obj);
if (obs_data_has_user_value(obj, "nestedMacro")) {
@@ -248,7 +183,6 @@ std::shared_ptr<MacroAction> MacroActionMacro::Copy() const
void MacroActionMacro::ResolveVariablesToFixedValues()
{
_actionIndex.ResolveVariables();
_label.ResolveVariables();
}
static void runActionsHelper(Macro *macro, bool runElseActions, bool setInputs,
@@ -332,7 +266,7 @@ static void populateConditionBehaviorSelection(QComboBox *list)
"AdvSceneSwitcher.action.macro.type.run.conditions.false"));
}
static void populateActionSectionSelection(QComboBox *list)
static void populateActionTypeSelection(QComboBox *list)
{
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.actionType.regular"));
@@ -340,47 +274,19 @@ static void populateActionSectionSelection(QComboBox *list)
"AdvSceneSwitcher.action.macro.type.run.actionType.else"));
}
static void populateActionTypes(QComboBox *list)
{
for (const auto &[id, info] : MacroActionFactory::GetActionTypes()) {
list->addItem(obs_module_text(info._name.c_str()),
QString::fromStdString(id));
}
}
static void populateActionSelectionTypes(QComboBox *list)
{
list->addItem(
obs_module_text(
"AdvSceneSwitcher.action.macro.actionSelectionType.index"),
static_cast<int>(MacroActionMacro::SelectionType::INDEX));
list->addItem(
obs_module_text(
"AdvSceneSwitcher.action.macro.actionSelectionType.label"),
static_cast<int>(MacroActionMacro::SelectionType::LABEL));
list->addItem(
obs_module_text(
"AdvSceneSwitcher.action.macro.actionSelectionType.id"),
static_cast<int>(MacroActionMacro::SelectionType::ID));
}
MacroActionMacroEdit::MacroActionMacroEdit(
QWidget *parent, std::shared_ptr<MacroActionMacro> entryData)
: ResizableWidget(parent),
_actions(new QComboBox()),
_macros(new MacroSelection(parent)),
_actionSelectionType(new QComboBox(this)),
_actionIndex(new MacroSegmentSelection(
this, MacroSegmentSelection::Type::ACTION)),
_label(new VariableLineEdit(this)),
_actionTypes(new FilterComboBox(this)),
_regex(new RegexConfigWidget(this)),
_actions(new QComboBox()),
_conditionMacros(new MacroSelection(parent)),
_conditionBehaviors(new QComboBox()),
_reevaluateConditionState(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.macro.type.run."
"updateConditionMatchState"))),
_actionSections(new QComboBox(this)),
_actionTypes(new QComboBox()),
_skipWhenPaused(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.action.macro.type.run.skipWhenPaused"))),
_setInputs(new QCheckBox(obs_module_text(
@@ -399,9 +305,7 @@ MacroActionMacroEdit::MacroActionMacroEdit(
{
populateActionSelection(_actions);
populateConditionBehaviorSelection(_conditionBehaviors);
populateActionSectionSelection(_actionSections);
populateActionSelectionTypes(_actionSelectionType);
populateActionTypes(_actionTypes);
populateActionTypeSelection(_actionTypes);
_conditionMacros->HideSelectedMacro();
@@ -409,25 +313,16 @@ MacroActionMacroEdit::MacroActionMacroEdit(
this, SLOT(MacroChanged(const QString &)));
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));
QWidget::connect(_actionSelectionType, SIGNAL(currentIndexChanged(int)),
this, SLOT(ActionSelectionTypeChanged(int)));
QWidget::connect(_actionIndex,
SIGNAL(SelectionChanged(const IntVariable &)), this,
SLOT(ActionIndexChanged(const IntVariable &)));
QWidget::connect(_label, SIGNAL(editingFinished()), this,
SLOT(LabelChanged()));
QWidget::connect(_actionTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionTypeChanged(int)));
QWidget::connect(_regex,
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
SLOT(RegexChanged(const RegexConfig &)));
QWidget::connect(_conditionMacros,
SIGNAL(currentTextChanged(const QString &)), this,
SLOT(ConditionMacroChanged(const QString &)));
QWidget::connect(_conditionBehaviors, SIGNAL(currentIndexChanged(int)),
this, SLOT(ConditionBehaviorChanged(int)));
QWidget::connect(_actionSections, SIGNAL(currentIndexChanged(int)),
this, SLOT(ActionSectionChanged(int)));
QWidget::connect(_actionTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionTypeChanged(int)));
QWidget::connect(_skipWhenPaused, SIGNAL(stateChanged(int)), this,
SLOT(SkipWhenPausedChanged(int)));
QWidget::connect(_setInputs, SIGNAL(stateChanged(int)), this,
@@ -480,24 +375,17 @@ void MacroActionMacroEdit::UpdateEntryData()
if (!_entryData) {
return;
}
_actions->setCurrentIndex(
_actions->findData(static_cast<int>(_entryData->_action)));
_actionSelectionType->setCurrentIndex(_actionSelectionType->findData(
static_cast<int>(_entryData->_actionSelectionType)));
_actionIndex->SetValue(_entryData->_actionIndex);
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
_label->setText(_entryData->_label);
_actionTypes->setCurrentIndex(_actionTypes->findData(
QString::fromStdString(_entryData->_actionId)));
_regex->SetRegexConfig(_entryData->_regex);
_macros->SetCurrentMacro(_entryData->_macro);
_conditionMacros->SetCurrentMacro(_entryData->_runOptions.macro);
_conditionBehaviors->setCurrentIndex(
static_cast<int>(_entryData->_runOptions.logic));
_reevaluateConditionState->setChecked(
_entryData->_runOptions.reevaluateConditionState);
_actionSections->setCurrentIndex(
_actionTypes->setCurrentIndex(
_entryData->_runOptions.runElseActions ? 1 : 0);
_skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused);
_setInputs->setChecked(_entryData->_runOptions.setInputs);
@@ -536,40 +424,12 @@ void MacroActionMacroEdit::ActionChanged(int idx)
SetWidgetVisibility();
}
void MacroActionMacroEdit::ActionSelectionTypeChanged(int idx)
{
GUARD_LOADING_AND_LOCK();
_entryData->_actionSelectionType =
static_cast<MacroActionMacro::SelectionType>(
_actionSelectionType->itemData(idx).toInt());
SetWidgetVisibility();
}
void MacroActionMacroEdit::ActionIndexChanged(const IntVariable &value)
{
GUARD_LOADING_AND_LOCK();
_entryData->_actionIndex = value;
}
void MacroActionMacroEdit::LabelChanged()
{
GUARD_LOADING_AND_LOCK();
_entryData->_label = _label->text().toStdString();
}
void MacroActionMacroEdit::ActionTypeChanged(int idx)
{
GUARD_LOADING_AND_LOCK();
_entryData->_actionId =
_actionTypes->itemData(idx).toString().toStdString();
}
void MacroActionMacroEdit::RegexChanged(const RegexConfig &regex)
{
GUARD_LOADING_AND_LOCK();
_entryData->_regex = regex;
}
void MacroActionMacroEdit::ConditionMacroChanged(const QString &text)
{
GUARD_LOADING_AND_LOCK();
@@ -591,13 +451,10 @@ void MacroActionMacroEdit::ReevaluateConditionStateChanged(int value)
SetWidgetVisibility();
}
void MacroActionMacroEdit::ActionSectionChanged(int useElse)
void MacroActionMacroEdit::ActionTypeChanged(int value)
{
GUARD_LOADING_AND_LOCK();
_entryData->_runOptions.runElseActions = useElse;
_entryData->_useElseSection = useElse;
_actionIndex->SetType(useElse ? MacroSegmentSelection::Type::ELSE_ACTION
: MacroSegmentSelection::Type::ACTION);
_entryData->_runOptions.runElseActions = value;
}
void MacroActionMacroEdit::SkipWhenPausedChanged(int value)
@@ -626,11 +483,7 @@ void MacroActionMacroEdit::SetWidgetVisibility()
_entryLayout->removeWidget(_actions);
_entryLayout->removeWidget(_actionIndex);
_entryLayout->removeWidget(_macros);
_entryLayout->removeWidget(_actionSections);
_entryLayout->removeWidget(_label);
_entryLayout->removeWidget(_regex);
_entryLayout->removeWidget(_actionTypes);
_entryLayout->removeWidget(_actionSelectionType);
_conditionLayout->removeWidget(_conditionBehaviors);
_conditionLayout->removeWidget(_conditionMacros);
@@ -641,40 +494,19 @@ void MacroActionMacroEdit::SetWidgetVisibility()
{"{{actions}}", _actions},
{"{{actionIndex}}", _actionIndex},
{"{{macros}}", _macros},
{"{{actionSections}}", _actionSections},
{"{{actionTypes}}", _actionTypes},
{"{{conditionBehaviors}}", _conditionBehaviors},
{"{{conditionMacros}}", _conditionMacros},
{"{{actionSelectionType}}", _actionSelectionType},
{"{{label}}", _label},
{"{{regex}}", _regex},
{"{{actionTypes}}", _actionTypes},
};
const auto action = _entryData->_action;
const char *layoutText = "";
switch (action) {
case MacroActionMacro::Action::PAUSE:
case MacroActionMacro::Action::UNPAUSE:
case MacroActionMacro::Action::TOGGLE_PAUSE:
case MacroActionMacro::Action::RESET_COUNTER:
case MacroActionMacro::Action::STOP:
case MacroActionMacro::Action::NESTED_MACRO:
layoutText = "AdvSceneSwitcher.action.macro.layout.other";
break;
case MacroActionMacro::Action::RUN_ACTIONS:
layoutText = "AdvSceneSwitcher.action.macro.layout.run";
break;
case MacroActionMacro::Action::DISABLE_ACTION:
case MacroActionMacro::Action::ENABLE_ACTION:
case MacroActionMacro::Action::TOGGLE_ACTION:
layoutText = "AdvSceneSwitcher.action.macro.layout.actionState";
break;
default:
break;
}
PlaceWidgets(obs_module_text(layoutText), _entryLayout, placeholders);
PlaceWidgets(
obs_module_text(
_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS
? "AdvSceneSwitcher.action.macro.entry.run"
: "AdvSceneSwitcher.action.macro.entry.other"),
_entryLayout, placeholders);
if (_entryData->_runOptions.logic ==
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS) {
@@ -683,63 +515,56 @@ void MacroActionMacroEdit::SetWidgetVisibility()
} else {
PlaceWidgets(
obs_module_text(
"AdvSceneSwitcher.action.macro.layout.run.condition"),
"AdvSceneSwitcher.action.macro.entry.run.condition"),
_conditionLayout, placeholders);
}
if (action == MacroActionMacro::Action::RUN_ACTIONS ||
action == MacroActionMacro::Action::STOP) {
if (_entryData->_action == MacroActionMacro::Action::RUN_ACTIONS ||
_entryData->_action == MacroActionMacro::Action::STOP) {
_macros->HideSelectedMacro();
} else {
_macros->ShowAllMacros();
}
const auto actionSelectionType = _entryData->_actionSelectionType;
const bool isModifyingActionState =
action == MacroActionMacro::Action::DISABLE_ACTION ||
action == MacroActionMacro::Action::ENABLE_ACTION ||
action == MacroActionMacro::Action::TOGGLE_ACTION;
_actionSelectionType->setVisible(isModifyingActionState);
_actionIndex->setVisible(
isModifyingActionState &&
actionSelectionType == MacroActionMacro::SelectionType::INDEX);
_label->setVisible(isModifyingActionState &&
actionSelectionType ==
MacroActionMacro::SelectionType::LABEL);
_regex->setVisible(isModifyingActionState &&
actionSelectionType ==
MacroActionMacro::SelectionType::LABEL);
_actionTypes->setVisible(isModifyingActionState &&
actionSelectionType ==
MacroActionMacro::SelectionType::ID);
_entryData->_action ==
MacroActionMacro::Action::DISABLE_ACTION ||
_entryData->_action ==
MacroActionMacro::Action::ENABLE_ACTION ||
_entryData->_action == MacroActionMacro::Action::TOGGLE_ACTION;
_actionIndex->setVisible(isModifyingActionState);
SetLayoutVisible(_conditionLayout,
action == MacroActionMacro::Action::RUN_ACTIONS);
_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS);
const bool needsAdditionalConditionWidgets =
action == MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_action == MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_runOptions.logic !=
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS;
_conditionMacros->setVisible(needsAdditionalConditionWidgets);
SetLayoutVisible(_reevaluateConditionStateLayout,
needsAdditionalConditionWidgets);
SetLayoutVisible(_setInputsLayout,
action == MacroActionMacro::Action::RUN_ACTIONS);
_inputs->setVisible(action == MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS);
_inputs->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_runOptions.setInputs);
HighlightMacroSettingsButton(
action == MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_action == MacroActionMacro::Action::RUN_ACTIONS &&
_entryData->_runOptions.setInputs &&
!_inputs->HasInputsToSet());
_actionSections->setVisible(
action == MacroActionMacro::Action::RUN_ACTIONS ||
isModifyingActionState);
_skipWhenPaused->setVisible(action ==
_actionTypes->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS);
_skipWhenPaused->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN_ACTIONS);
_nestedMacro->setVisible(action ==
_nestedMacro->setVisible(_entryData->_action ==
MacroActionMacro::Action::NESTED_MACRO);
_macros->setVisible(action != MacroActionMacro::Action::NESTED_MACRO);
SetResizingEnabled(action == MacroActionMacro::Action::NESTED_MACRO);
_macros->setVisible(_entryData->_action !=
MacroActionMacro::Action::NESTED_MACRO);
SetResizingEnabled(_entryData->_action ==
MacroActionMacro::Action::NESTED_MACRO);
if (_nestedMacro->IsEmpty()) {
_nestedMacro->ShowAllMacroSections();

View File

@@ -5,9 +5,7 @@
#include "macro-input.hpp"
#include "macro-selection.hpp"
#include "macro-segment-selection.hpp"
#include "regex-config.hpp"
#include "resizable-widget.hpp"
#include "variable-line-edit.hpp"
#include <QCheckBox>
#include <QHBoxLayout>
@@ -57,23 +55,14 @@ public:
TOGGLE_PAUSE,
NESTED_MACRO,
};
enum class SelectionType { INDEX, LABEL, ID };
Action _action = Action::NESTED_MACRO;
SelectionType _actionSelectionType = SelectionType::INDEX;
bool _useElseSection = false;
IntVariable _actionIndex = 1;
StringVariable _label = "Custom label";
std::string _actionId;
RegexConfig _regex;
RunOptions _runOptions = {};
std::shared_ptr<Macro> _nestedMacro = std::make_shared<Macro>();
int _customWidgetHeight = 0;
private:
void RunActions(Macro *actionMacro) const;
void AdjustActionState(Macro *) const;
static bool _registered;
static const std::string id;
@@ -93,15 +82,11 @@ public:
private slots:
void MacroChanged(const QString &text);
void ActionChanged(int value);
void ActionSelectionTypeChanged(int value);
void ActionIndexChanged(const IntVariable &value);
void LabelChanged();
void ActionTypeChanged(int value);
void RegexChanged(const RegexConfig &);
void ConditionMacroChanged(const QString &text);
void ConditionBehaviorChanged(int value);
void ReevaluateConditionStateChanged(int value);
void ActionSectionChanged(int value);
void ActionTypeChanged(int value);
void SkipWhenPausedChanged(int value);
void SetInputsChanged(int value);
void InputsChanged(const StringList &);
@@ -113,17 +98,13 @@ private:
void SetWidgetVisibility();
void SetupMacroInput(Macro *) const;
QComboBox *_actions;
MacroSelection *_macros;
QComboBox *_actionSelectionType;
MacroSegmentSelection *_actionIndex;
VariableLineEdit *_label;
FilterComboBox *_actionTypes;
RegexConfigWidget *_regex;
QComboBox *_actions;
MacroSelection *_conditionMacros;
QComboBox *_conditionBehaviors;
QCheckBox *_reevaluateConditionState;
QComboBox *_actionSections;
QComboBox *_actionTypes;
QCheckBox *_skipWhenPaused;
QCheckBox *_setInputs;
MacroInputEdit *_inputs;

View File

@@ -239,7 +239,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
(*_entryData)->SetIndex(idx);
(*_entryData)->SetLogicType(logic);
(*_entryData)->PostLoad();
RunAndClearPostLoadSteps();
RunPostLoadSteps();
}
auto widget =
MacroConditionFactory::CreateWidget(id, this, *_entryData);

View File

@@ -102,7 +102,7 @@ bool MacroConditionMacro::CheckActionStateCondition()
if (!macro) {
return false;
}
if (!IsValidActionIndex(macro.get(), _actionIndex - 1)) {
if (!IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1, false)) {
return false;
}
if (_type == Type::ACTION_DISABLED) {

View File

@@ -1080,7 +1080,7 @@ void MacroEdit::AddMacroAction(Macro *macro, int idx, const std::string &id,
macro->Actions().at(idx)->Load(data);
}
macro->Actions().at(idx)->PostLoad();
RunAndClearPostLoadSteps();
RunPostLoadSteps();
macro->UpdateActionIndices();
ui->actionsList->Insert(
idx,
@@ -1383,7 +1383,7 @@ void MacroEdit::AddMacroElseAction(Macro *macro, int idx, const std::string &id,
macro->ElseActions().at(idx)->Load(data);
}
macro->ElseActions().at(idx)->PostLoad();
RunAndClearPostLoadSteps();
RunPostLoadSteps();
macro->UpdateElseActionIndices();
ui->elseActionsList->Insert(
idx, new MacroActionEdit(
@@ -1583,7 +1583,7 @@ void MacroEdit::AddMacroCondition(Macro *macro, int idx, const std::string &id,
macro->Conditions().at(idx)->Load(data);
}
macro->Conditions().at(idx)->PostLoad();
RunAndClearPostLoadSteps();
RunPostLoadSteps();
(*cond)->SetLogicType(logic);
macro->UpdateConditionIndices();
ui->conditionsList->Insert(

View File

@@ -1,6 +1,5 @@
#include "macro-helpers.hpp"
#include "macro.hpp"
#include "macro-action-macro.hpp"
#include "plugin-state-helpers.hpp"
namespace advss {
@@ -9,60 +8,6 @@ static std::atomic_bool abortMacroWait = {false};
static std::atomic_bool macroSceneSwitched = {false};
static std::atomic_int shutdownConditionCount = {0};
static void appendNestedMacros(std::deque<std::shared_ptr<Macro>> &macros,
Macro *macro)
{
if (!macro) {
return;
}
const auto iterate = [&macros](const std::deque<
std::shared_ptr<MacroAction>> &actions) {
for (const auto &action : actions) {
const auto nestedMacroAction =
dynamic_cast<MacroActionMacro *>(action.get());
if (!nestedMacroAction) {
continue;
}
macros.push_back(nestedMacroAction->_nestedMacro);
appendNestedMacros(
macros, nestedMacroAction->_nestedMacro.get());
}
};
iterate(macro->Actions());
iterate(macro->ElseActions());
}
std::deque<std::shared_ptr<Macro>> &GetTopLevelMacros()
{
static std::deque<std::shared_ptr<Macro>> macros;
return macros;
}
std::deque<std::shared_ptr<Macro>> &GetTemporaryMacros()
{
static std::deque<std::shared_ptr<Macro>> tempMacros;
return tempMacros;
}
std::deque<std::shared_ptr<Macro>> GetAllMacros()
{
auto macros = GetTopLevelMacros();
for (const auto &topLevelMacro : macros) {
appendNestedMacros(macros, topLevelMacro.get());
}
const auto &tempMacros = GetTemporaryMacros();
macros.insert(macros.end(), tempMacros.begin(), tempMacros.end());
for (const auto &tempMacro : tempMacros) {
appendNestedMacros(macros, tempMacro.get());
}
return macros;
}
std::optional<std::deque<std::shared_ptr<MacroAction>>>
GetMacroActions(Macro *macro)
{
@@ -72,15 +17,6 @@ GetMacroActions(Macro *macro)
return macro->Actions();
}
std::optional<std::deque<std::shared_ptr<MacroAction>>>
GetMacroElseActions(Macro *macro)
{
if (!macro) {
return {};
}
return macro->ElseActions();
}
std::optional<std::deque<std::shared_ptr<MacroCondition>>>
GetMacroConditions(Macro *macro)
{
@@ -208,42 +144,20 @@ void ResetMacroRunCount(Macro *macro)
macro->ResetRunCount();
}
bool IsValidActionIndex(const Macro *m, const int idx)
bool IsValidMacroSegmentIndex(const Macro *m, const int idx, bool isCondition)
{
if (!m || idx < 0) {
return false;
}
if (idx >= (int)m->Actions().size()) {
return false;
if (isCondition) {
if (idx >= (int)m->Conditions().size()) {
return false;
}
} else {
if (idx >= (int)m->Actions().size()) {
return false;
}
}
return true;
}
bool IsValidElseActionIndex(const Macro *m, const int idx)
{
if (!m || idx < 0) {
return false;
}
if (idx >= (int)m->ElseActions().size()) {
return false;
}
return true;
}
bool IsValidConditionIndex(const Macro *m, const int idx)
{
if (!m || idx < 0) {
return false;
}
if (idx >= (int)m->Conditions().size()) {
return false;
}
return true;
}

View File

@@ -18,14 +18,10 @@ class Macro;
class MacroAction;
class MacroCondition;
EXPORT std::deque<std::shared_ptr<Macro>> &GetTopLevelMacros();
std::deque<std::shared_ptr<Macro>> &GetTemporaryMacros();
EXPORT std::deque<std::shared_ptr<Macro>> GetAllMacros();
EXPORT std::deque<std::shared_ptr<Macro>> &GetMacros();
EXPORT std::optional<std::deque<std::shared_ptr<MacroAction>>>
GetMacroActions(Macro *);
EXPORT std::optional<std::deque<std::shared_ptr<MacroAction>>>
GetMacroElseActions(Macro *);
EXPORT std::optional<std::deque<std::shared_ptr<MacroCondition>>>
GetMacroConditions(Macro *);
@@ -72,8 +68,6 @@ EXPORT void InvalidateMacroTempVarValues();
EXPORT void ResetMacroConditionTimers(Macro *);
EXPORT void ResetMacroRunCount(Macro *);
bool IsValidActionIndex(const Macro *m, const int idx);
bool IsValidElseActionIndex(const Macro *m, const int idx);
bool IsValidConditionIndex(const Macro *m, const int idx);
bool IsValidMacroSegmentIndex(const Macro *m, const int idx, bool isCondition);
} // namespace advss

View File

@@ -73,46 +73,35 @@ void MacroSegmentSelection::MacroSegmentOrderChanged()
}
static QString GetMacroSegmentDescription(Macro *macro, int idx,
MacroSegmentSelection::Type type)
bool isCondition)
{
if (!macro) {
return "";
}
MacroSegment *segment;
switch (type) {
case MacroSegmentSelection::Type::CONDITION:
if (!IsValidConditionIndex(macro, idx)) {
return "";
}
segment = GetMacroConditions(macro)->at(idx).get();
break;
case MacroSegmentSelection::Type::ACTION:
if (!IsValidActionIndex(macro, idx)) {
return "";
}
segment = GetMacroActions(macro)->at(idx).get();
break;
case MacroSegmentSelection::Type::ELSE_ACTION:
if (!IsValidElseActionIndex(macro, idx)) {
return "";
}
segment = GetMacroElseActions(macro)->at(idx).get();
break;
default:
if (!IsValidMacroSegmentIndex(macro, idx, isCondition)) {
return "";
}
const auto idToName = type == MacroSegmentSelection::Type::CONDITION
? MacroConditionFactory::GetConditionName
: MacroActionFactory::GetActionName;
const QString typeStr =
obs_module_text(idToName(segment->GetId()).c_str());
const QString description =
QString::fromStdString(segment->GetShortDesc());
MacroSegment *segment;
if (isCondition) {
segment = GetMacroConditions(macro)->at(idx).get();
} else {
segment = GetMacroActions(macro)->at(idx).get();
}
QString result = typeStr;
QString description = QString::fromStdString(segment->GetShortDesc());
QString type;
if (isCondition) {
type = obs_module_text(MacroConditionFactory::GetConditionName(
segment->GetId())
.c_str());
} else {
type = obs_module_text(
MacroActionFactory::GetActionName(segment->GetId())
.c_str());
}
QString result = type;
if (!description.isEmpty()) {
result += ": " + description;
}
@@ -134,25 +123,11 @@ void MacroSegmentSelection::SetupDescription() const
return;
}
bool validIndex = false;
switch (_type) {
case Type::CONDITION:
validIndex = IsValidConditionIndex(_macro, index - 1);
break;
case Type::ACTION:
validIndex = IsValidActionIndex(_macro, index - 1);
break;
case Type::ELSE_ACTION:
validIndex = IsValidElseActionIndex(_macro, index - 1);
break;
default:
break;
}
QString description;
if (validIndex) {
description =
GetMacroSegmentDescription(_macro, index - 1, _type);
if (IsValidMacroSegmentIndex(_macro, index - 1,
_type == Type::CONDITION)) {
description = GetMacroSegmentDescription(
_macro, index - 1, _type == Type::CONDITION);
} else {
description = obs_module_text(
"AdvSceneSwitcher.macroSegmentSelection.invalid");
@@ -190,23 +165,8 @@ void MacroSegmentSelection::MarkSelectedSegment()
if (index.GetType() == IntVariable::Type::VARIABLE) {
return;
}
bool validIndex = false;
switch (_type) {
case Type::CONDITION:
validIndex = IsValidConditionIndex(_macro, index - 1);
break;
case Type::ACTION:
validIndex = IsValidActionIndex(_macro, index - 1);
break;
case Type::ELSE_ACTION:
validIndex = IsValidElseActionIndex(_macro, index - 1);
break;
default:
break;
}
if (!validIndex) {
if (!IsValidMacroSegmentIndex(_macro, index - 1,
_type == Type::CONDITION)) {
return;
}

View File

@@ -8,7 +8,7 @@ class Macro;
class MacroSegmentSelection : public QWidget {
Q_OBJECT
public:
enum class Type { CONDITION, ACTION, ELSE_ACTION };
enum class Type { CONDITION, ACTION };
MacroSegmentSelection(QWidget *parent, Type type,
bool allowVariables = true);

View File

@@ -14,7 +14,7 @@ MacroSelection::MacroSelection(QWidget *parent)
: FilterComboBox(parent,
obs_module_text("AdvSceneSwitcher.selectMacro"))
{
for (const auto &m : GetTopLevelMacros()) {
for (const auto &m : GetMacros()) {
if (m->IsGroup()) {
continue;
}

View File

@@ -150,7 +150,7 @@ static void addGroupSubitems(std::vector<std::shared_ptr<Macro>> &macros,
subitems.reserve(group->GroupSize());
// Find all subitems
auto allMacros = GetTopLevelMacros();
auto allMacros = GetMacros();
for (auto it = allMacros.begin(); it < allMacros.end(); it++) {
if ((*it)->Name() != group->Name()) {
continue;
@@ -410,17 +410,13 @@ void AdvSceneSwitcher::ImportMacros()
int groupSize = 0;
std::shared_ptr<Macro> group;
std::vector<std::shared_ptr<Macro>> importedMacros;
auto &tempMacros = GetTemporaryMacros();
auto lock = LockContext();
for (size_t i = 0; i < count; i++) {
tempMacros.clear();
OBSDataAutoRelease array_obj = obs_data_array_item(array, i);
auto macro = std::make_shared<Macro>();
tempMacros.emplace_back(macro);
macro->Load(array_obj);
RunAndClearPostLoadSteps();
RunPostLoadSteps();
if (macroNameExists(macro->Name()) &&
!ResolveMacroImportNameConflict(macro)) {
@@ -429,7 +425,7 @@ void AdvSceneSwitcher::ImportMacros()
}
importedMacros.emplace_back(macro);
GetTopLevelMacros().emplace_back(macro);
GetMacros().emplace_back(macro);
if (groupSize > 0 && !macro->IsGroup()) {
Macro::PrepareMoveToGroup(group, macro);
groupSize--;
@@ -448,10 +444,9 @@ void AdvSceneSwitcher::ImportMacros()
for (const auto &macro : importedMacros) {
macro->PostLoad();
}
RunAndClearPostLoadSteps();
tempMacros.clear();
RunPostLoadSteps();
ui->macros->Reset(GetTopLevelMacros(),
ui->macros->Reset(GetMacros(),
GetGlobalMacroSettings()._highlightExecuted);
disableAddButtonHighlight();
}
@@ -638,7 +633,7 @@ void AdvSceneSwitcher::SetupMacroTab()
{
ui->macros->installEventFilter(this);
if (GetTopLevelMacros().size() == 0 && !switcher->disableHints) {
if (GetMacros().size() == 0 && !switcher->disableHints) {
addPulse = HighlightWidget(ui->macroAdd, QColor(Qt::green));
}
@@ -646,7 +641,7 @@ void AdvSceneSwitcher::SetupMacroTab()
{ui->macroUp, ui->macroDown}});
ui->macroControlLayout->addWidget(macroControls);
ui->macros->Reset(GetTopLevelMacros(),
ui->macros->Reset(GetMacros(),
GetGlobalMacroSettings()._highlightExecuted);
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
SLOT(MacroSelectionChanged()));
@@ -757,7 +752,7 @@ void AdvSceneSwitcher::CopyMacro()
newMacro->Load(data);
newMacro->PostLoad();
newMacro->SetName(name);
RunAndClearPostLoadSteps();
RunPostLoadSteps();
Macro::PrepareMoveToGroup(macro->Parent(), newMacro);
ui->macros->Add(newMacro, macro);

View File

@@ -1184,7 +1184,7 @@ bool MacroTree::SelectionEmpty() const
bool MacroTree::GroupsExist() const
{
for (const auto &macro : GetTopLevelMacros()) {
for (const auto &macro : GetMacros()) {
if (macro->IsGroup()) {
return true;
}
@@ -1306,7 +1306,7 @@ void MacroTree::UngroupSelectedGroups()
void MacroTree::ExpandAll()
{
for (const auto &macro : GetTopLevelMacros()) {
for (const auto &macro : GetMacros()) {
if (!macro->IsGroup()) {
continue;
}
@@ -1316,7 +1316,7 @@ void MacroTree::ExpandAll()
void MacroTree::CollapseAll()
{
for (const auto &macro : GetTopLevelMacros()) {
for (const auto &macro : GetMacros()) {
if (!macro->IsGroup()) {
continue;
}

View File

@@ -17,6 +17,8 @@
namespace advss {
static std::deque<std::shared_ptr<Macro>> macros;
Macro::Macro(const std::string &name) : _dockSettings(this)
{
SetName(name);
@@ -57,7 +59,6 @@ Macro::CreateGroup(const std::string &name,
void Macro::RemoveGroup(std::shared_ptr<Macro> group)
{
auto &macros = GetTopLevelMacros();
auto it = std::find(macros.begin(), macros.end(), group);
if (it == macros.end()) {
return;
@@ -74,7 +75,6 @@ void Macro::RemoveGroup(std::shared_ptr<Macro> group)
void Macro::PrepareMoveToGroup(Macro *group, std::shared_ptr<Macro> item)
{
auto &macros = GetTopLevelMacros();
for (const auto &m : macros) {
if (m.get() == group) {
PrepareMoveToGroup(m, item);
@@ -1114,7 +1114,7 @@ void Macro::SetHotkeysDesc() const
void SaveMacros(obs_data_t *obj)
{
obs_data_array_t *macroArray = obs_data_array_create();
for (const auto &m : GetTopLevelMacros()) {
for (const auto &m : macros) {
obs_data_t *array_obj = obs_data_create();
m->Save(array_obj);
@@ -1128,9 +1128,7 @@ void SaveMacros(obs_data_t *obj)
void LoadMacros(obs_data_t *obj)
{
auto &macros = GetTopLevelMacros();
macros.clear();
obs_data_array_t *macroArray = obs_data_get_array(obj, "macros");
size_t count = obs_data_array_count(macroArray);
@@ -1180,10 +1178,15 @@ void LoadMacros(obs_data_t *obj)
}
}
std::deque<std::shared_ptr<Macro>> &GetMacros()
{
return macros;
}
bool CheckMacros()
{
bool matchFound = false;
for (const auto &m : GetTopLevelMacros()) {
for (const auto &m : macros) {
if (!m->ConditionsShouldBeChecked()) {
vblog(LOG_INFO,
"skipping condition check for macro \"%s\" "
@@ -1210,7 +1213,7 @@ bool RunMacros()
// reordered while macros are currently being executed.
// For example, this can happen if a macro is performing a wait action,
// as the main lock will be unlocked during this time.
auto runPhaseMacros = GetTopLevelMacros();
auto runPhaseMacros = macros;
// Avoid deadlocks when opening settings window and calling frontend
// API functions at the same time.
@@ -1250,14 +1253,14 @@ bool RunMacros()
void StopAllMacros()
{
for (const auto &m : GetAllMacros()) {
for (const auto &m : macros) {
m->Stop();
}
}
Macro *GetMacroByName(const char *name)
{
for (const auto &m : GetTopLevelMacros()) {
for (const auto &m : macros) {
if (m->Name() == name) {
return m.get();
}
@@ -1273,7 +1276,7 @@ Macro *GetMacroByQString(const QString &name)
std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
{
for (const auto &m : GetTopLevelMacros()) {
for (const auto &m : macros) {
if (m->Name() == name) {
return m;
}
@@ -1284,7 +1287,7 @@ std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
void InvalidateMacroTempVarValues()
{
for (const auto &m : GetTopLevelMacros()) {
for (const auto &m : macros) {
// Do not invalidate the temp vars set during condition checks
// or action executions running in parallel to the "main" macro
// loop, as otherwise access to the information stored in those
@@ -1299,8 +1302,6 @@ void InvalidateMacroTempVarValues()
std::shared_ptr<Macro> GetMacroWithInvalidConditionInterval()
{
auto &macros = GetTopLevelMacros();
if (macros.empty()) {
return {};
}

View File

@@ -217,6 +217,7 @@ private:
void LoadMacros(obs_data_t *obj);
void SaveMacros(obs_data_t *obj);
std::deque<std::shared_ptr<Macro>> &GetMacros();
bool CheckMacros();
bool RunMacros();
void StopAllMacros();

View File

@@ -113,7 +113,7 @@ void ActionQueue::Add(const std::shared_ptr<MacroAction> &action)
action->Save(data);
copy->Load(data);
copy->PostLoad();
RunAndClearPostLoadSteps();
RunPostLoadSteps();
copy->ResolveVariablesToFixedValues();
_actions.emplace_back(copy);
} else {

View File

@@ -113,13 +113,12 @@ void RunLoadSteps(obs_data_t *obj)
}
}
void RunAndClearPostLoadSteps()
void RunPostLoadSteps()
{
std::lock_guard<std::mutex> lock(postLoadMutex);
for (const auto &func : getPostLoadSteps()) {
func();
}
getPostLoadSteps().clear();
}
void ClearPostLoadSteps()

View File

@@ -14,7 +14,7 @@ EXPORT void AddPostLoadStep(std::function<void()>);
EXPORT void AddIntervalResetStep(std::function<void()>);
void RunSaveSteps(obs_data_t *);
void RunLoadSteps(obs_data_t *);
EXPORT void RunAndClearPostLoadSteps();
EXPORT void RunPostLoadSteps();
void ClearPostLoadSteps();
EXPORT void AddPluginInitStep(std::function<void()>);

View File

@@ -239,26 +239,22 @@ void SceneSelection::ResolveVariables()
_type = Type::SCENE;
}
static obs_weak_canvas_t *getWeakRefToMainCanvas()
{
static auto canvas = obs_get_main_canvas();
static auto weakCanvas = obs_canvas_get_weak_canvas(canvas);
[[maybe_unused]] static const bool _ = []() {
// Let's just hope we don't have to deal with selecting scenes
// when the OBS main canvas gets deleted and release the
// references here already to avoid reporting leaks on shutdown
obs_canvas_release(canvas);
obs_weak_canvas_release(weakCanvas);
return true;
}();
return weakCanvas;
}
SceneSelection SceneSelectionWidget::CurrentSelection()
{
SceneSelection s;
s._canvas = _forceMainCanvas ? OBSWeakCanvas(getWeakRefToMainCanvas())
static auto mainCanvas = obs_get_main_canvas();
static auto mainCanvasWeak = obs_canvas_get_weak_canvas(mainCanvas);
[[maybe_unused]] static const bool _ = []() {
// Let's just hope we don't have to deal with selecting scenes
// when the OBS main canvas gets deleted and release the
// references here already to avoid reporting leaks on shutdown
obs_canvas_release(mainCanvas);
obs_weak_canvas_release(mainCanvasWeak);
return true;
}();
s._canvas = _forceMainCanvas ? OBSWeakCanvas(mainCanvasWeak)
: _canvas->GetCanvas();
const int idx = _scenes->currentIndex();
@@ -334,7 +330,6 @@ static QStringList getCanvasScenesList(obs_weak_canvas_t *weakCanvas)
QStringList list;
obs_canvas_enum_scenes(canvas, enumCanvasScenes, &list);
list.sort();
return list;
}
@@ -347,10 +342,6 @@ void SceneSelectionWidget::Reset()
void SceneSelectionWidget::PopulateSceneSelection(obs_weak_canvas_t *canvas)
{
if (_forceMainCanvas) {
canvas = getWeakRefToMainCanvas();
}
_scenes->clear();
if ((_current || _previous)) {
const bool isMain = IsMainCanvas(canvas);
@@ -427,7 +418,7 @@ SceneSelectionWidget::SceneSelectionWidget(QWidget *parent, bool variables,
layout->setContentsMargins(0, 0, 0, 0);
if (GetCanvasCount() <= 1) {
LockToMainCanvas();
_canvas->hide();
}
Resize();

View File

@@ -199,17 +199,7 @@ std::chrono::high_resolution_clock::time_point GetLastSceneChangeTime()
OBSWeakSource GetCurrentScene()
{
if (switcher->currentScene) {
return switcher->currentScene;
}
// If there wasn't any scene switch yet switcher->currentScene will be
// null and we must use obs_frontend_get_current_scene() instead
OBSSourceAutoRelease currentSceneSource =
obs_frontend_get_current_scene();
OBSWeakSourceAutoRelease currentSceneWeakSource =
obs_source_get_weak_source(currentSceneSource);
return currentSceneWeakSource.Get();
return switcher->currentScene;
}
OBSWeakSource GetPreviousScene()

View File

@@ -190,6 +190,29 @@ static bool isMatchingNestedMacroAction(MacroAction *action, const Macro *macro)
return nestedMacroAction->_nestedMacro.get() == macro;
}
static void appendNestedMacros(std::deque<std::shared_ptr<Macro>> &macros,
Macro *macro)
{
if (!macro) {
return;
}
for (const auto &action : macro->Actions()) {
const auto nestedMacroAction =
dynamic_cast<MacroActionMacro *>(action.get());
if (nestedMacroAction) {
macros.push_back(nestedMacroAction->_nestedMacro);
}
}
for (const auto &action : macro->ElseActions()) {
const auto nestedMacroAction =
dynamic_cast<MacroActionMacro *>(action.get());
if (nestedMacroAction) {
macros.push_back(nestedMacroAction->_nestedMacro);
}
}
}
static Macro *getParentMacro(const Macro *targetMacro,
const std::vector<Macro *> &macros)
{
@@ -240,10 +263,8 @@ static Macro *getParentMacro(const Macro *targetMacro,
static Macro *getParentMacro(const Macro *macro)
{
const auto &topLevelMacros = GetTopLevelMacros();
std::vector<Macro *> macros;
macros.reserve(topLevelMacros.size());
for (const auto &macro : topLevelMacros) {
for (const auto &macro : GetMacros()) {
macros.emplace_back(macro.get());
}
return getParentMacro(macro, macros);
@@ -280,9 +301,8 @@ void TempVariableRef::Save(obs_data_t *obj, Macro *macro,
void TempVariableRef::Load(obs_data_t *obj, Macro *macroPtr, const char *name)
{
const auto macros = GetAllMacros();
std::weak_ptr<Macro> macro;
for (const auto &macroShared : macros) {
for (const auto &macroShared : GetMacros()) {
if (macroShared.get() == macroPtr) {
macro = macroShared;
break;
@@ -320,9 +340,9 @@ void TempVariableRef::PostLoad(int idx, SegmentType type,
return;
}
auto macro = childMacro.get();
Macro *macro = nullptr;
for (int i = 0; i < _depth; i++) {
macro = getParentMacro(macro);
macro = getParentMacro(childMacro.get());
}
if (!macro) {
@@ -466,9 +486,15 @@ void TempVariableSelection::MacroSegmentsChanged()
SetVariable(currentSelection);
}
void TempVariableSelection::SegmentTempVarsChanged(MacroSegment *)
void TempVariableSelection::SegmentTempVarsChanged(MacroSegment *segment)
{
MacroSegmentsChanged();
const auto currentSegment = GetSegment();
const auto currentMacro = currentSegment ? currentSegment->GetMacro()
: nullptr;
const auto changeMacro = segment ? segment->GetMacro() : nullptr;
if (currentMacro == changeMacro) {
MacroSegmentsChanged();
}
}
void TempVariableSelection::HighlightChanged(int idx)

View File

@@ -75,7 +75,7 @@ private:
void PostLoad(int idx, SegmentType, const std::weak_ptr<Macro> &);
std::string _id = "";
std::weak_ptr<MacroSegment> _segment = {};
std::weak_ptr<MacroSegment> _segment;
int _depth = 0;
friend TempVariable;

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:

View File

@@ -252,7 +252,6 @@ MacroConditionSlideshowEdit::MacroConditionSlideshowEdit(
setToolTip(obs_module_text(
"AdvSceneSwitcher.condition.slideshow.updateInterval.tooltip"));
_index->setMinimum(1);
_index->setMaximum(9999);
populateConditionSelection(_conditions);
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,

View File

@@ -10,12 +10,6 @@ if(OS_MACOS)
endif()
find_package(OpenSSL)
get_cmake_property(_variableNames VARIABLES)
list(SORT _variableNames)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
find_package(PahoMqttCpp)
if(NOT PahoMqttCpp_FOUND)
message(WARNING "PahoMqttCpp not found!\n"