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" description: "Project name detected by parsing build spec file"
value: ${{ jobs.check-event.outputs.pluginName }} value: ${{ jobs.check-event.outputs.pluginName }}
env: env:
DEP_DIR: .deps/advss-build-dependencies-2 DEP_DIR: .deps/advss-build-dependencies-3
jobs: jobs:
check-event: check-event:
name: Check GitHub Event Data 🔎 name: Check GitHub Event Data 🔎

View File

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

View File

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

View File

@@ -4,6 +4,7 @@
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
if(WIN32 AND (NOT OpenSSL_FOUND)) if(WIN32 AND (NOT OpenSSL_FOUND))
set(_openssl_roots set(_openssl_roots
"$ENV{ProgramFiles}/OpenSSL-Win64" "$ENV{ProgramFiles}/OpenSSL" "$ENV{ProgramFiles}/OpenSSL-Win64" "$ENV{ProgramFiles}/OpenSSL"
"$ENV{ProgramW6432}/OpenSSL-Win64") "$ENV{ProgramW6432}/OpenSSL-Win64")
@@ -46,33 +47,20 @@ if(WIN32 AND (NOT OpenSSL_FOUND))
AND EXISTS "${_root}/${_suffix}/libcrypto.lib") AND EXISTS "${_root}/${_suffix}/libcrypto.lib")
set(OPENSSL_ROOT_DIR set(OPENSSL_ROOT_DIR
"${_root}" "${_root}"
CACHE PATH "Path to OpenSSL root" FORCE) CACHE PATH "Path to OpenSSL root")
set(OPENSSL_CRYPTO_LIBRARY set(OPENSSL_CRYPTO_LIBRARY
"${_root}/${_suffix}/libcrypto.lib" "${_root}/${_suffix}/libcrypto.lib"
CACHE FILEPATH "OpenSSL crypto lib" FORCE) CACHE FILEPATH "OpenSSL crypto lib")
set(OPENSSL_SSL_LIBRARY set(OPENSSL_SSL_LIBRARY
"${_root}/${_suffix}/libssl.lib" "${_root}/${_suffix}/libssl.lib"
CACHE FILEPATH "OpenSSL ssl lib" FORCE) CACHE FILEPATH "OpenSSL ssl lib")
set(OPENSSL_INCLUDE_DIR set(OPENSSL_INCLUDE_DIR
"${_root}/include" "${_root}/include"
CACHE PATH "OpenSSL include dir" FORCE) CACHE PATH "OpenSSL include dir")
set(OpenSSL_FOUND set(OpenSSL_FOUND
TRUE TRUE
CACHE BOOL "Whether OpenSSL was found" FORCE) CACHE BOOL "Whether OpenSSL was found")
message(STATUS "Found OpenSSL at: ${_root}/${_suffix}") 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() return()
endif() endif()
endforeach() endforeach()

View File

@@ -495,7 +495,7 @@ AdvSceneSwitcher.action.file.type.write="Schreiben"
AdvSceneSwitcher.action.file.type.append="Anhängen" AdvSceneSwitcher.action.file.type.append="Anhängen"
AdvSceneSwitcher.action.file.entry="{{actions}} in {{filePath}}:" AdvSceneSwitcher.action.file.entry="{{actions}} in {{filePath}}:"
AdvSceneSwitcher.action.studioMode="Studio-Modus" 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.setScene="Vorschau-Szene einstellen auf"
AdvSceneSwitcher.action.studioMode.type.enable="Studio-Modus aktivieren" AdvSceneSwitcher.action.studioMode.type.enable="Studio-Modus aktivieren"
AdvSceneSwitcher.action.studioMode.type.disable="Studio-Modus deaktivieren" 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.enableAction="Enable action"
AdvSceneSwitcher.action.macro.type.toggleAction="Toggle action" AdvSceneSwitcher.action.macro.type.toggleAction="Toggle action"
AdvSceneSwitcher.action.macro.type.nestedMacro="Nested macro" 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.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.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.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.entry.run="{{actions}}{{actionTypes}}of{{macros}}"
AdvSceneSwitcher.action.macro.layout.run.condition="{{conditionBehaviors}}of{{conditionMacros}}" AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}of{{conditionMacros}}"
AdvSceneSwitcher.action.macro.layout.actionState="{{actions}}{{actionSelectionType}}{{actionIndex}}{{label}}{{regex}}{{actionTypes}}in{{actionSections}}section of{{macros}}" AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.macro.layout.other="{{actions}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Plugin state" AdvSceneSwitcher.action.pluginState="Plugin state"
AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin" AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin"
AdvSceneSwitcher.action.pluginState.type.noMatch="Change the no-match behaviour:" 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.type.append="Append"
AdvSceneSwitcher.action.file.entry="{{actions}}to{{filePath}}:" AdvSceneSwitcher.action.file.entry="{{actions}}to{{filePath}}:"
AdvSceneSwitcher.action.studioMode="Studio mode" 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.setScene="Set preview scene to"
AdvSceneSwitcher.action.studioMode.type.enable="Enable studio mode" AdvSceneSwitcher.action.studioMode.type.enable="Enable studio mode"
AdvSceneSwitcher.action.studioMode.type.disable="Disable 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.type.append="Agregar"
AdvSceneSwitcher.action.file.entry="{{actions}} a {{filePath}}:" AdvSceneSwitcher.action.file.entry="{{actions}} a {{filePath}}:"
AdvSceneSwitcher.action.studioMode="Modo estudio" 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.setScene="Establecer escena de vista previa en"
AdvSceneSwitcher.action.studioMode.type.enable="Activar modo estudio" AdvSceneSwitcher.action.studioMode.type.enable="Activar modo estudio"
AdvSceneSwitcher.action.studioMode.type.disable="Deshabilitar el modo de 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.type.append="Ajouter"
AdvSceneSwitcher.action.file.entry="{{actions}}vers{{filePath}}:" AdvSceneSwitcher.action.file.entry="{{actions}}vers{{filePath}}:"
AdvSceneSwitcher.action.studioMode="Mode studio" 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.setScene="Définir la scène de prévisualisation sur"
AdvSceneSwitcher.action.studioMode.type.enable="Activer le mode studio" AdvSceneSwitcher.action.studioMode.type.enable="Activer le mode studio"
AdvSceneSwitcher.action.studioMode.type.disable="Désactiver 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.type.append="Append"
AdvSceneSwitcher.action.file.entry="{{actions}}から{{filePath}}へ:" AdvSceneSwitcher.action.file.entry="{{actions}}から{{filePath}}へ:"
AdvSceneSwitcher.action.studioMode="スタジオモード" AdvSceneSwitcher.action.studioMode="スタジオモード"
AdvSceneSwitcher.action.studioMode.type.swap="プレビューと番組シーンの入れ替え" AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="プレビューと番組シーンの入れ替え"
AdvSceneSwitcher.action.studioMode.type.setScene="プレビューシーンを設定する" AdvSceneSwitcher.action.studioMode.type.setScene="プレビューシーンを設定する"
AdvSceneSwitcher.action.studioMode.type.enable="スタジオモードを有効にする" AdvSceneSwitcher.action.studioMode.type.enable="スタジオモードを有効にする"
AdvSceneSwitcher.action.studioMode.type.disable="スタジオモードを無効にする" 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.disableAction="Desabilitar ação"
AdvSceneSwitcher.action.macro.type.enableAction="Habilitar ação" AdvSceneSwitcher.action.macro.type.enableAction="Habilitar ação"
AdvSceneSwitcher.action.macro.type.toggleAction="Alternar ação" AdvSceneSwitcher.action.macro.type.toggleAction="Alternar ação"
AdvSceneSwitcher.action.macro.layout.run="{{actions}}{{actionSections}}de{{macros}}" AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}de{{macros}}"
AdvSceneSwitcher.action.macro.layout.run.condition="{{conditionBehaviors}}de{{conditionMacros}}" AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}de{{conditionMacros}}"
AdvSceneSwitcher.action.macro.layout.other="{{actions}}{{macros}}" AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="Estado do plugin" AdvSceneSwitcher.action.pluginState="Estado do plugin"
AdvSceneSwitcher.action.pluginState.type.stop="Parar o plugin Advanced Scene Switcher" 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:" 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.type.append="Anexar"
AdvSceneSwitcher.action.file.entry="{{actions}}para{{filePath}}:" AdvSceneSwitcher.action.file.entry="{{actions}}para{{filePath}}:"
AdvSceneSwitcher.action.studioMode="Modo estúdio" 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.setScene="Definir cena de visualização para"
AdvSceneSwitcher.action.studioMode.type.enable="Habilitar modo estúdio" AdvSceneSwitcher.action.studioMode.type.enable="Habilitar modo estúdio"
AdvSceneSwitcher.action.studioMode.type.disable="Desabilitar 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.disableAction="停用操作"
AdvSceneSwitcher.action.macro.type.enableAction="启用操作" AdvSceneSwitcher.action.macro.type.enableAction="启用操作"
AdvSceneSwitcher.action.macro.type.toggleAction="切换操作开关" AdvSceneSwitcher.action.macro.type.toggleAction="切换操作开关"
AdvSceneSwitcher.action.macro.layout.run="{{actions}}{{actionSections}}{{macros}}" AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}{{macros}}"
AdvSceneSwitcher.action.macro.layout.run.condition="{{conditionBehaviors}}{{conditionMacros}}" AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}{{conditionMacros}}"
AdvSceneSwitcher.action.macro.layout.other="{{actions}}{{macros}}" AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
AdvSceneSwitcher.action.pluginState="插件状态" AdvSceneSwitcher.action.pluginState="插件状态"
AdvSceneSwitcher.action.pluginState.type.stop="停止高级场景切换插件" AdvSceneSwitcher.action.pluginState.type.stop="停止高级场景切换插件"
AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项时:" AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项时:"
@@ -984,7 +984,7 @@ AdvSceneSwitcher.action.file.type.write="覆盖写入"
AdvSceneSwitcher.action.file.type.append="追加写入" AdvSceneSwitcher.action.file.type.append="追加写入"
AdvSceneSwitcher.action.file.entry="{{actions}} 到 {{filePath}}:" AdvSceneSwitcher.action.file.entry="{{actions}} 到 {{filePath}}:"
AdvSceneSwitcher.action.studioMode="工作室模式" AdvSceneSwitcher.action.studioMode="工作室模式"
AdvSceneSwitcher.action.studioMode.type.swap="切换预览和程序场景" AdvSceneSwitcher.action.studioMode.type.transitionWithSwap="切换预览和程序场景"
AdvSceneSwitcher.action.studioMode.type.setScene="将预览场景设置为" AdvSceneSwitcher.action.studioMode.type.setScene="将预览场景设置为"
AdvSceneSwitcher.action.studioMode.type.enable="启用工作室模式" AdvSceneSwitcher.action.studioMode.type.enable="启用工作室模式"
AdvSceneSwitcher.action.studioMode.type.disable="停用工作室模式" AdvSceneSwitcher.action.studioMode.type.disable="停用工作室模式"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -102,7 +102,7 @@ bool MacroConditionMacro::CheckActionStateCondition()
if (!macro) { if (!macro) {
return false; return false;
} }
if (!IsValidActionIndex(macro.get(), _actionIndex - 1)) { if (!IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1, false)) {
return false; return false;
} }
if (_type == Type::ACTION_DISABLED) { 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)->Load(data);
} }
macro->Actions().at(idx)->PostLoad(); macro->Actions().at(idx)->PostLoad();
RunAndClearPostLoadSteps(); RunPostLoadSteps();
macro->UpdateActionIndices(); macro->UpdateActionIndices();
ui->actionsList->Insert( ui->actionsList->Insert(
idx, 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)->Load(data);
} }
macro->ElseActions().at(idx)->PostLoad(); macro->ElseActions().at(idx)->PostLoad();
RunAndClearPostLoadSteps(); RunPostLoadSteps();
macro->UpdateElseActionIndices(); macro->UpdateElseActionIndices();
ui->elseActionsList->Insert( ui->elseActionsList->Insert(
idx, new MacroActionEdit( 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)->Load(data);
} }
macro->Conditions().at(idx)->PostLoad(); macro->Conditions().at(idx)->PostLoad();
RunAndClearPostLoadSteps(); RunPostLoadSteps();
(*cond)->SetLogicType(logic); (*cond)->SetLogicType(logic);
macro->UpdateConditionIndices(); macro->UpdateConditionIndices();
ui->conditionsList->Insert( ui->conditionsList->Insert(

View File

@@ -1,6 +1,5 @@
#include "macro-helpers.hpp" #include "macro-helpers.hpp"
#include "macro.hpp" #include "macro.hpp"
#include "macro-action-macro.hpp"
#include "plugin-state-helpers.hpp" #include "plugin-state-helpers.hpp"
namespace advss { namespace advss {
@@ -9,60 +8,6 @@ static std::atomic_bool abortMacroWait = {false};
static std::atomic_bool macroSceneSwitched = {false}; static std::atomic_bool macroSceneSwitched = {false};
static std::atomic_int shutdownConditionCount = {0}; 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>>> std::optional<std::deque<std::shared_ptr<MacroAction>>>
GetMacroActions(Macro *macro) GetMacroActions(Macro *macro)
{ {
@@ -72,15 +17,6 @@ GetMacroActions(Macro *macro)
return macro->Actions(); 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>>> std::optional<std::deque<std::shared_ptr<MacroCondition>>>
GetMacroConditions(Macro *macro) GetMacroConditions(Macro *macro)
{ {
@@ -208,42 +144,20 @@ void ResetMacroRunCount(Macro *macro)
macro->ResetRunCount(); macro->ResetRunCount();
} }
bool IsValidActionIndex(const Macro *m, const int idx) bool IsValidMacroSegmentIndex(const Macro *m, const int idx, bool isCondition)
{ {
if (!m || idx < 0) { if (!m || idx < 0) {
return false; return false;
} }
if (isCondition) {
if (idx >= (int)m->Actions().size()) { if (idx >= (int)m->Conditions().size()) {
return false; 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; return true;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -239,26 +239,22 @@ void SceneSelection::ResolveVariables()
_type = Type::SCENE; _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 SceneSelectionWidget::CurrentSelection()
{ {
SceneSelection s; 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(); : _canvas->GetCanvas();
const int idx = _scenes->currentIndex(); const int idx = _scenes->currentIndex();
@@ -334,7 +330,6 @@ static QStringList getCanvasScenesList(obs_weak_canvas_t *weakCanvas)
QStringList list; QStringList list;
obs_canvas_enum_scenes(canvas, enumCanvasScenes, &list); obs_canvas_enum_scenes(canvas, enumCanvasScenes, &list);
list.sort();
return list; return list;
} }
@@ -347,10 +342,6 @@ void SceneSelectionWidget::Reset()
void SceneSelectionWidget::PopulateSceneSelection(obs_weak_canvas_t *canvas) void SceneSelectionWidget::PopulateSceneSelection(obs_weak_canvas_t *canvas)
{ {
if (_forceMainCanvas) {
canvas = getWeakRefToMainCanvas();
}
_scenes->clear(); _scenes->clear();
if ((_current || _previous)) { if ((_current || _previous)) {
const bool isMain = IsMainCanvas(canvas); const bool isMain = IsMainCanvas(canvas);
@@ -427,7 +418,7 @@ SceneSelectionWidget::SceneSelectionWidget(QWidget *parent, bool variables,
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
if (GetCanvasCount() <= 1) { if (GetCanvasCount() <= 1) {
LockToMainCanvas(); _canvas->hide();
} }
Resize(); Resize();

View File

@@ -199,17 +199,7 @@ std::chrono::high_resolution_clock::time_point GetLastSceneChangeTime()
OBSWeakSource GetCurrentScene() OBSWeakSource GetCurrentScene()
{ {
if (switcher->currentScene) { return 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();
} }
OBSWeakSource GetPreviousScene() OBSWeakSource GetPreviousScene()

View File

@@ -190,6 +190,29 @@ static bool isMatchingNestedMacroAction(MacroAction *action, const Macro *macro)
return nestedMacroAction->_nestedMacro.get() == 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, static Macro *getParentMacro(const Macro *targetMacro,
const std::vector<Macro *> &macros) const std::vector<Macro *> &macros)
{ {
@@ -240,10 +263,8 @@ static Macro *getParentMacro(const Macro *targetMacro,
static Macro *getParentMacro(const Macro *macro) static Macro *getParentMacro(const Macro *macro)
{ {
const auto &topLevelMacros = GetTopLevelMacros();
std::vector<Macro *> macros; std::vector<Macro *> macros;
macros.reserve(topLevelMacros.size()); for (const auto &macro : GetMacros()) {
for (const auto &macro : topLevelMacros) {
macros.emplace_back(macro.get()); macros.emplace_back(macro.get());
} }
return getParentMacro(macro, macros); 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) void TempVariableRef::Load(obs_data_t *obj, Macro *macroPtr, const char *name)
{ {
const auto macros = GetAllMacros();
std::weak_ptr<Macro> macro; std::weak_ptr<Macro> macro;
for (const auto &macroShared : macros) { for (const auto &macroShared : GetMacros()) {
if (macroShared.get() == macroPtr) { if (macroShared.get() == macroPtr) {
macro = macroShared; macro = macroShared;
break; break;
@@ -320,9 +340,9 @@ void TempVariableRef::PostLoad(int idx, SegmentType type,
return; return;
} }
auto macro = childMacro.get(); Macro *macro = nullptr;
for (int i = 0; i < _depth; i++) { for (int i = 0; i < _depth; i++) {
macro = getParentMacro(macro); macro = getParentMacro(childMacro.get());
} }
if (!macro) { if (!macro) {
@@ -466,9 +486,15 @@ void TempVariableSelection::MacroSegmentsChanged()
SetVariable(currentSelection); 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) void TempVariableSelection::HighlightChanged(int idx)

View File

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

View File

@@ -2,6 +2,7 @@
#include "layout-helpers.hpp" #include "layout-helpers.hpp"
#include <obs-frontend-api.h> #include <obs-frontend-api.h>
#include <util/config-file.h>
namespace advss { namespace advss {
@@ -13,16 +14,64 @@ bool MacroActionSudioMode::_registered = MacroActionFactory::Register(
"AdvSceneSwitcher.action.studioMode"}); "AdvSceneSwitcher.action.studioMode"});
const static std::map<MacroActionSudioMode::Action, std::string> actionTypes = { const static std::map<MacroActionSudioMode::Action, std::string> actionTypes = {
{MacroActionSudioMode::Action::SWAP_SCENE, {MacroActionSudioMode::Action::TRANSITION,
"AdvSceneSwitcher.action.studioMode.type.swap"}, "AdvSceneSwitcher.action.studioMode.type.transition"},
{MacroActionSudioMode::Action::SET_SCENE, {MacroActionSudioMode::Action::TRANSITION_WITH_SWAP,
"AdvSceneSwitcher.action.studioMode.type.setScene"}, "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, {MacroActionSudioMode::Action::ENABLE_STUDIO_MODE,
"AdvSceneSwitcher.action.studioMode.type.enable"}, "AdvSceneSwitcher.action.studioMode.type.enable"},
{MacroActionSudioMode::Action::DISABLE_STUDIO_MODE, {MacroActionSudioMode::Action::DISABLE_STUDIO_MODE,
"AdvSceneSwitcher.action.studioMode.type.disable"}, "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 // 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 // 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 // to use this helper function instead - copied from obs-websocket plugin
@@ -42,14 +91,78 @@ static void enableStudioMode(bool enable)
bool MacroActionSudioMode::PerformAction() bool MacroActionSudioMode::PerformAction()
{ {
obs_frontend_get_user_config();
switch (_action) { switch (_action) {
case Action::SWAP_SCENE: case Action::TRANSITION:
obs_frontend_preview_program_trigger_transition(); obs_frontend_preview_program_trigger_transition();
break; break;
case Action::SET_SCENE: { case Action::TRANSITION_WITH_SWAP: {
auto s = obs_weak_source_get_source(_scene.GetScene()); auto swapEnabled = getConfigValueHelper(config_get_bool,
obs_frontend_set_current_preview_scene(s); config_get_default_bool,
obs_source_release(s); "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; break;
} }
case Action::ENABLE_STUDIO_MODE: case Action::ENABLE_STUDIO_MODE:
@@ -58,6 +171,15 @@ bool MacroActionSudioMode::PerformAction()
case Action::DISABLE_STUDIO_MODE: case Action::DISABLE_STUDIO_MODE:
enableStudioMode(false); enableStudioMode(false);
break; 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: default:
break; break;
} }
@@ -82,6 +204,7 @@ bool MacroActionSudioMode::Save(obs_data_t *obj) const
MacroAction::Save(obj); MacroAction::Save(obj);
obs_data_set_int(obj, "action", static_cast<int>(_action)); obs_data_set_int(obj, "action", static_cast<int>(_action));
_scene.Save(obj); _scene.Save(obj);
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -90,6 +213,34 @@ bool MacroActionSudioMode::Load(obs_data_t *obj)
MacroAction::Load(obj); MacroAction::Load(obj);
_action = static_cast<Action>(obs_data_get_int(obj, "action")); _action = static_cast<Action>(obs_data_get_int(obj, "action"));
_scene.Load(obj); _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; return true;
} }
@@ -136,15 +287,11 @@ MacroActionStudioModeEdit::MacroActionStudioModeEdit(
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &))); this, SLOT(SceneChanged(const SceneSelection &)));
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { auto layout = new QHBoxLayout;
{"{{actions}}", _actions},
{"{{scenes}}", _scenes},
};
QHBoxLayout *mainLayout = new QHBoxLayout;
PlaceWidgets( PlaceWidgets(
obs_module_text("AdvSceneSwitcher.action.studioMode.entry"), obs_module_text("AdvSceneSwitcher.action.studioMode.entry"),
mainLayout, widgetPlaceholders); layout, {{"{{actions}}", _actions}, {"{{scenes}}", _scenes}});
setLayout(mainLayout); setLayout(layout);
_entryData = entryData; _entryData = entryData;
UpdateEntryData(); UpdateEntryData();

View File

@@ -18,13 +18,28 @@ public:
void ResolveVariablesToFixedValues(); void ResolveVariablesToFixedValues();
enum class Action { enum class Action {
SWAP_SCENE, TRANSITION = 10,
SET_SCENE, // TODO: Remove in future version as the TRANSITION_WITH_SWAP = 20,
// functionality moved to the scene switch action
ENABLE_STUDIO_MODE, ENALBE_TRANSITION_SWAP = 30,
DISABLE_STUDIO_MODE, 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; SceneSelection _scene;
private: private:

View File

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

View File

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