mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-07 09:05:57 -05:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8212da80f | ||
|
|
862bc420ad | ||
|
|
f832d6c52e | ||
|
|
790d0095f3 | ||
|
|
81409ba22d | ||
|
|
e687cf139a |
2
.github/workflows/build-project.yaml
vendored
2
.github/workflows/build-project.yaml
vendored
@@ -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-3
|
DEP_DIR: .deps/advss-build-dependencies-2
|
||||||
jobs:
|
jobs:
|
||||||
check-event:
|
check-event:
|
||||||
name: Check GitHub Event Data 🔎
|
name: Check GitHub Event Data 🔎
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ You have the option to ...
|
|||||||
|
|
||||||
Both methods require [CMake](https://cmake.org/download/).
|
Both methods require [CMake](https://cmake.org/download/).
|
||||||
|
|
||||||
The plugin can be compiled for OBS 31 and above, although using the latest version of OBS is recommended to support all features.
|
The plugin can be compiled for OBS 27 and above, although using the latest version of OBS is recommended to support all features.
|
||||||
|
|
||||||
## Compiling in tree (recommended for development)
|
## Compiling in tree (recommended for development)
|
||||||
This section assumes that you have a working [OBS Studio development environment](https://obsproject.com/wiki/Building-OBS-Studio).
|
This section assumes that you have a working [OBS Studio development environment](https://obsproject.com/wiki/Building-OBS-Studio).
|
||||||
|
|
||||||
Add the "SceneSwitcher" source directory to your obs-studio source directory under obs-studio/plugins:
|
Add the "SceneSwitcher" source directory to your obs-studio source directory under obs-studio/UI/frontend-plugins/:
|
||||||
```
|
```
|
||||||
cd obs-studio/plugins
|
cd obs-studio/UI/frontend-plugins/
|
||||||
git clone --recursive https://github.com/WarmUpTill/SceneSwitcher.git
|
git clone --recursive https://github.com/WarmUpTill/SceneSwitcher.git
|
||||||
```
|
```
|
||||||
|
|
||||||
Then modify the obs-studio/plugins/CMakeLists.txt and add an entry for the scene switcher:
|
Then modify the obs-studio/UI/frontend-plugins/CMakeLists.txt Example and add an entry for the scene switcher:
|
||||||
```
|
```
|
||||||
add_subdirectory(SceneSwitcher)
|
add_subdirectory(SceneSwitcher)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -146,8 +146,6 @@ target_sources(
|
|||||||
lib/macro/macro-ref.hpp
|
lib/macro/macro-ref.hpp
|
||||||
lib/macro/macro-run-button.cpp
|
lib/macro/macro-run-button.cpp
|
||||||
lib/macro/macro-run-button.hpp
|
lib/macro/macro-run-button.hpp
|
||||||
lib/macro/macro-search.cpp
|
|
||||||
lib/macro/macro-search.hpp
|
|
||||||
lib/macro/macro-segment-copy-paste.cpp
|
lib/macro/macro-segment-copy-paste.cpp
|
||||||
lib/macro/macro-segment-copy-paste.hpp
|
lib/macro/macro-segment-copy-paste.hpp
|
||||||
lib/macro/macro-segment-list.cpp
|
lib/macro/macro-segment-list.cpp
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"obs-studio": {
|
"obs-studio": {
|
||||||
"version": "31.1.1",
|
"version": "30.1.2",
|
||||||
"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": "39751f067bacc13d44b116c5138491b5f1391f91516d3d590d874edd21292291",
|
"macos": "490bae1c392b3b344b0270afd8cb887da4bc50bd92c0c426e96713c1ccb9701a",
|
||||||
"windows-x64": "2c8427c10b55ac6d68008df2e9a3e82f4647aaad18f105e30d4713c2de678ccf"
|
"windows-x64": "c2dd03fa7fd01fad5beafce8f7156da11f9ed9a588373fd40b44a06f4c03b867"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prebuilt": {
|
"prebuilt": {
|
||||||
"version": "2025-07-11",
|
"version": "2024-03-19",
|
||||||
"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": "495687e63383d1a287684b6e2e9bfe246bb8f156fe265926afb1a325af1edd2a",
|
"macos": "2e9bfb55a5e0e4c1086fa1fda4cf268debfead473089df2aaea80e1c7a3ca7ff",
|
||||||
"windows-x64": "c8c642c1070dc31ce9a0f1e4cef5bb992f4bff4882255788b5da12129e85caa7"
|
"windows-x64": "6e86068371526a967e805f6f9903f9407adb683c21820db5f07da8f30d11e998"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"qt6": {
|
"qt6": {
|
||||||
"version": "2025-07-11",
|
"version": "2024-03-19",
|
||||||
"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": "d3f5f04b6ea486e032530bdf0187cbda9a54e0a49621a4c8ba984c5023998867",
|
"macos": "694f1e639c017e3b1f456f735330dc5afae287cbea85757101af1368de3142c8",
|
||||||
"windows-x64": "0e76bf0555dd5382838850b748d3dcfab44a1e1058441309ab54e1a65b156d0a"
|
"windows-x64": "72d1df34a0ef7413a681d5fcc88cae81da60adc03dcd23ef17862ab170bcc0dd"
|
||||||
},
|
},
|
||||||
"debugSymbols": {
|
"debugSymbols": {
|
||||||
"windows-x64": "11b7be92cf66a273299b8f3515c07a5cfb61614b59a4e67f7fc5ecba5e2bdf21"
|
"windows-x64": "fbddd1f659c360f2291911ac5709b67b6f8182e6bca519d24712e4f6fd3cc865"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -65,16 +65,17 @@ function(_setup_obs_studio)
|
|||||||
|
|
||||||
if(OS_WINDOWS)
|
if(OS_WINDOWS)
|
||||||
set(_cmake_generator "${CMAKE_GENERATOR}")
|
set(_cmake_generator "${CMAKE_GENERATOR}")
|
||||||
set(_cmake_arch
|
set(_cmake_arch "-A ${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})")
|
||||||
@@ -82,42 +83,32 @@ 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}" -DOBS_CMAKE_VERSION:STRING=3.0.0
|
${_cmake_generator} "${_cmake_arch}"
|
||||||
-DENABLE_PLUGINS:BOOL=OFF -DENABLE_FRONTEND:BOOL=OFF
|
-DOBS_CMAKE_VERSION:STRING=${_cmake_version} -DENABLE_PLUGINS:BOOL=OFF
|
||||||
-DOBS_VERSION_OVERRIDE:STRING=${_obs_version}
|
-DENABLE_UI:BOOL=OFF -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} (Debug - ${arch})")
|
message(STATUS "Build ${label} (${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} (Debug - ${arch}) - done")
|
message(STATUS "Build ${label} (${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}"
|
--config Debug --prefix "${dependencies_dir}" ${_cmake_extra}
|
||||||
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)
|
||||||
@@ -180,46 +171,24 @@ function(_check_dependencies)
|
|||||||
set(url ${url}/${version}/${file})
|
set(url ${url}/${version}/${file})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(MAX_DOWNLOAD_RETRIES 3)
|
|
||||||
set(RETRY_DELAY 60) # seconds
|
|
||||||
|
|
||||||
if(NOT EXISTS "${dependencies_dir}/${file}")
|
if(NOT EXISTS "${dependencies_dir}/${file}")
|
||||||
message(STATUS "Downloading ${url}")
|
message(STATUS "Downloading ${url}")
|
||||||
|
file(
|
||||||
|
DOWNLOAD "${url}" "${dependencies_dir}/${file}"
|
||||||
|
STATUS download_status
|
||||||
|
EXPECTED_HASH SHA256=${hash})
|
||||||
|
|
||||||
set(download_success FALSE)
|
list(GET download_status 0 error_code)
|
||||||
|
list(GET download_status 1 error_message)
|
||||||
foreach(i RANGE 1 ${MAX_DOWNLOAD_RETRIES})
|
if(error_code GREATER 0)
|
||||||
message(STATUS "Attempt ${i}/${MAX_DOWNLOAD_RETRIES} for ${url}")
|
message(STATUS "Downloading ${url} - Failure")
|
||||||
|
|
||||||
file(
|
|
||||||
DOWNLOAD "${url}" "${dependencies_dir}/${file}"
|
|
||||||
STATUS download_status
|
|
||||||
EXPECTED_HASH SHA256=${hash})
|
|
||||||
|
|
||||||
list(GET download_status 0 error_code)
|
|
||||||
list(GET download_status 1 error_message)
|
|
||||||
|
|
||||||
if(error_code EQUAL 0)
|
|
||||||
message(STATUS "Downloading ${url} - success on attempt ${i}")
|
|
||||||
set(download_success TRUE)
|
|
||||||
break()
|
|
||||||
else()
|
|
||||||
message(WARNING "Download failed (attempt ${i}): ${error_message}")
|
|
||||||
file(REMOVE "${dependencies_dir}/${file}")
|
|
||||||
|
|
||||||
if(NOT i EQUAL MAX_DOWNLOAD_RETRIES)
|
|
||||||
message(STATUS "Retrying in ${RETRY_DELAY} seconds...")
|
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${RETRY_DELAY})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if(NOT download_success)
|
|
||||||
message(
|
message(
|
||||||
FATAL_ERROR
|
FATAL_ERROR
|
||||||
"Unable to download ${url} after ${MAX_DOWNLOAD_RETRIES} attempts")
|
"Unable to download ${url}, failed with error: ${error_message}")
|
||||||
|
file(REMOVE "${dependencies_dir}/${file}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Downloading ${url} - done")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Downloading ${url} - done")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT EXISTS "${dependencies_dir}/${destination}")
|
if(NOT EXISTS "${dependencies_dir}/${destination}")
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
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")
|
||||||
@@ -47,20 +46,33 @@ 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")
|
CACHE PATH "Path to OpenSSL root" FORCE)
|
||||||
set(OPENSSL_CRYPTO_LIBRARY
|
set(OPENSSL_CRYPTO_LIBRARY
|
||||||
"${_root}/${_suffix}/libcrypto.lib"
|
"${_root}/${_suffix}/libcrypto.lib"
|
||||||
CACHE FILEPATH "OpenSSL crypto lib")
|
CACHE FILEPATH "OpenSSL crypto lib" FORCE)
|
||||||
set(OPENSSL_SSL_LIBRARY
|
set(OPENSSL_SSL_LIBRARY
|
||||||
"${_root}/${_suffix}/libssl.lib"
|
"${_root}/${_suffix}/libssl.lib"
|
||||||
CACHE FILEPATH "OpenSSL ssl lib")
|
CACHE FILEPATH "OpenSSL ssl lib" FORCE)
|
||||||
set(OPENSSL_INCLUDE_DIR
|
set(OPENSSL_INCLUDE_DIR
|
||||||
"${_root}/include"
|
"${_root}/include"
|
||||||
CACHE PATH "OpenSSL include dir")
|
CACHE PATH "OpenSSL include dir" FORCE)
|
||||||
set(OpenSSL_FOUND
|
set(OpenSSL_FOUND
|
||||||
TRUE
|
TRUE
|
||||||
CACHE BOOL "Whether OpenSSL was found")
|
CACHE BOOL "Whether OpenSSL was found" FORCE)
|
||||||
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()
|
||||||
|
|||||||
@@ -43,9 +43,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="Display warni
|
|||||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
|
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="The plugin installation seems to be corrupted and might crash!\nPlease make sure the plugin was installed correctly!"
|
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="The plugin installation seems to be corrupted and might crash!\nPlease make sure the plugin was installed correctly!"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
|
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowMacroSearch="Always show macro search"
|
AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache="Disable macro widget caching"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowFeatureTabs="Always show all feature tabs"
|
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowFeatureTabs.tooltip="Show tabs that are normally hidden until first used in a macro (e.g. Action Queues, Variables, Twitch, Websockets)."
|
|
||||||
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
|
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
|
||||||
AdvSceneSwitcher.generalTab.priority="Priority"
|
AdvSceneSwitcher.generalTab.priority="Priority"
|
||||||
AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)"
|
AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)"
|
||||||
@@ -76,7 +74,6 @@ AdvSceneSwitcher.generalTab.setTransitionBy="When changing transitions:"
|
|||||||
AdvSceneSwitcher.generalTab.transitionOverride="Set transition overrides"
|
AdvSceneSwitcher.generalTab.transitionOverride="Set transition overrides"
|
||||||
AdvSceneSwitcher.generalTab.adjustActiveTransitionType="Change active transition type"
|
AdvSceneSwitcher.generalTab.adjustActiveTransitionType="Change active transition type"
|
||||||
AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="At least one option must be enabled:\n\n - Use transition overrides\n\n - Change active transition type"
|
AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="At least one option must be enabled:\n\n - Use transition overrides\n\n - Change active transition type"
|
||||||
AdvSceneSwitcher.generalTab.uiBehavior="UI settings"
|
|
||||||
|
|
||||||
# Variables Tab
|
# Variables Tab
|
||||||
AdvSceneSwitcher.variableTab.title="Variables"
|
AdvSceneSwitcher.variableTab.title="Variables"
|
||||||
@@ -94,12 +91,6 @@ AdvSceneSwitcher.variableTab.lastUsed.text.never="Never"
|
|||||||
AdvSceneSwitcher.variableTab.lastChanged.header="Last changed"
|
AdvSceneSwitcher.variableTab.lastChanged.header="Last changed"
|
||||||
AdvSceneSwitcher.variableTab.lastChanged.text.none="No change since launch"
|
AdvSceneSwitcher.variableTab.lastChanged.text.none="No change since launch"
|
||||||
AdvSceneSwitcher.variableTab.lastChanged.tooltip="Times changed: %1\n\nPrevious value: %2"
|
AdvSceneSwitcher.variableTab.lastChanged.tooltip="Times changed: %1\n\nPrevious value: %2"
|
||||||
AdvSceneSwitcher.variableTab.search.placeholder="Search ..."
|
|
||||||
AdvSceneSwitcher.variableTab.search.all="All columns"
|
|
||||||
AdvSceneSwitcher.variableTab.search.name="Name column"
|
|
||||||
AdvSceneSwitcher.variableTab.search.value="Value column"
|
|
||||||
AdvSceneSwitcher.variableTab.addDock="Add dock"
|
|
||||||
AdvSceneSwitcher.variableTab.clear="Clear"
|
|
||||||
|
|
||||||
# Action Queue Tab
|
# Action Queue Tab
|
||||||
AdvSceneSwitcher.actionQueueTab.title="Action Queues"
|
AdvSceneSwitcher.actionQueueTab.title="Action Queues"
|
||||||
@@ -279,13 +270,6 @@ AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton="Move selected action up in
|
|||||||
AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton="Move selected action down in the else section"
|
AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton="Move selected action down in the else section"
|
||||||
AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton="Move selected action to the bottom in the else section"
|
AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton="Move selected action to the bottom in the else section"
|
||||||
AdvSceneSwitcher.macroTab.tooltip.openMacroSettingsButton="Open macro settings"
|
AdvSceneSwitcher.macroTab.tooltip.openMacroSettingsButton="Open macro settings"
|
||||||
AdvSceneSwitcher.macroTab.search.placeholder="Search ..."
|
|
||||||
AdvSceneSwitcher.macroTab.search.showSettings="Show search settings"
|
|
||||||
AdvSceneSwitcher.macroTab.search.name="Name"
|
|
||||||
AdvSceneSwitcher.macroTab.search.allSegments="Segment type"
|
|
||||||
AdvSceneSwitcher.macroTab.search.conditions="Condition type"
|
|
||||||
AdvSceneSwitcher.macroTab.search.actions="Action type"
|
|
||||||
AdvSceneSwitcher.macroTab.search.label="Segment label"
|
|
||||||
|
|
||||||
AdvSceneSwitcher.macroDock.pause="Pause"
|
AdvSceneSwitcher.macroDock.pause="Pause"
|
||||||
AdvSceneSwitcher.macroDock.unpause="Unpause"
|
AdvSceneSwitcher.macroDock.unpause="Unpause"
|
||||||
@@ -944,9 +928,6 @@ AdvSceneSwitcher.action.source.type.deinterlaceOrder="Set deinterlace field orde
|
|||||||
AdvSceneSwitcher.action.source.type.openInteractionDialog="Open interaction dialog"
|
AdvSceneSwitcher.action.source.type.openInteractionDialog="Open interaction dialog"
|
||||||
AdvSceneSwitcher.action.source.type.openFilterDialog="Open filter dialog"
|
AdvSceneSwitcher.action.source.type.openFilterDialog="Open filter dialog"
|
||||||
AdvSceneSwitcher.action.source.type.openPropertiesDialog="Open properties dialog"
|
AdvSceneSwitcher.action.source.type.openPropertiesDialog="Open properties dialog"
|
||||||
AdvSceneSwitcher.action.source.type.closeInteractionDialog="Close interaction dialog"
|
|
||||||
AdvSceneSwitcher.action.source.type.closeFilterDialog="Close filter dialog"
|
|
||||||
AdvSceneSwitcher.action.source.type.closePropertiesDialog="Close properties dialog"
|
|
||||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}{{refresh}}"
|
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}{{refresh}}"
|
||||||
AdvSceneSwitcher.action.source.entry.settings="{{settings}}{{settingsInputMethod}}{{settingValue}}{{tempVar}}"
|
AdvSceneSwitcher.action.source.entry.settings="{{settings}}{{settingsInputMethod}}{{settingValue}}{{tempVar}}"
|
||||||
AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI\nYou might be looking for \"Scene item visibility\""
|
AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI\nYou might be looking for \"Scene item visibility\""
|
||||||
@@ -968,7 +949,6 @@ AdvSceneSwitcher.action.source.inputMethod.individualTempvar="Set to macro prope
|
|||||||
AdvSceneSwitcher.action.source.inputMethod.json="Set setting JSON string"
|
AdvSceneSwitcher.action.source.inputMethod.json="Set setting JSON string"
|
||||||
AdvSceneSwitcher.action.source.refresh="Refresh"
|
AdvSceneSwitcher.action.source.refresh="Refresh"
|
||||||
AdvSceneSwitcher.action.source.refresh.tooltip="Repopulate the source settings selection with the settings of the source which's name matches the variable value."
|
AdvSceneSwitcher.action.source.refresh.tooltip="Repopulate the source settings selection with the settings of the source which's name matches the variable value."
|
||||||
AdvSceneSwitcher.action.source.dialog.accept="Accept changes"
|
|
||||||
AdvSceneSwitcher.action.media="Media"
|
AdvSceneSwitcher.action.media="Media"
|
||||||
AdvSceneSwitcher.action.media.type.play="Play"
|
AdvSceneSwitcher.action.media.type.play="Play"
|
||||||
AdvSceneSwitcher.action.media.type.pause="Pause"
|
AdvSceneSwitcher.action.media.type.pause="Pause"
|
||||||
@@ -1165,7 +1145,6 @@ AdvSceneSwitcher.action.http.entry.line2="Timeout:{{timeout}}seconds"
|
|||||||
AdvSceneSwitcher.action.variable="Variable"
|
AdvSceneSwitcher.action.variable="Variable"
|
||||||
AdvSceneSwitcher.action.variable.type.set="Set to value"
|
AdvSceneSwitcher.action.variable.type.set="Set to value"
|
||||||
AdvSceneSwitcher.action.variable.type.append="Append"
|
AdvSceneSwitcher.action.variable.type.append="Append"
|
||||||
AdvSceneSwitcher.action.variable.type.copy="Copy variable"
|
|
||||||
AdvSceneSwitcher.action.variable.type.appendVar="Append variable"
|
AdvSceneSwitcher.action.variable.type.appendVar="Append variable"
|
||||||
AdvSceneSwitcher.action.variable.type.increment="Increment"
|
AdvSceneSwitcher.action.variable.type.increment="Increment"
|
||||||
AdvSceneSwitcher.action.variable.type.decrement="Decrement"
|
AdvSceneSwitcher.action.variable.type.decrement="Decrement"
|
||||||
@@ -1258,14 +1237,12 @@ AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable="Disable chat's emote
|
|||||||
AdvSceneSwitcher.action.twitch.type.chat.sendMessage="Send chat message"
|
AdvSceneSwitcher.action.twitch.type.chat.sendMessage="Send chat message"
|
||||||
AdvSceneSwitcher.action.twitch.type.user.getInfo="Get user information"
|
AdvSceneSwitcher.action.twitch.type.user.getInfo="Get user information"
|
||||||
AdvSceneSwitcher.action.twitch.type.reward.getInfo="Get channel points reward information"
|
AdvSceneSwitcher.action.twitch.type.reward.getInfo="Get channel points reward information"
|
||||||
AdvSceneSwitcher.action.twitch.type.channel.getInfo="Get channel information"
|
|
||||||
AdvSceneSwitcher.action.twitch.reward.toggleControl="Toggle reward name / variable selection control"
|
AdvSceneSwitcher.action.twitch.reward.toggleControl="Toggle reward name / variable selection control"
|
||||||
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!"
|
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!"
|
||||||
AdvSceneSwitcher.action.twitch.layout.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
|
AdvSceneSwitcher.action.twitch.entry.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.chat="Using account{{account}}{{actions}}on{{channel}}"
|
AdvSceneSwitcher.action.twitch.entry.chat="Using account{{account}}{{actions}}on{{channel}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.channel.getInfo="Using account{{account}}{{actions}}of{{channel}}"
|
AdvSceneSwitcher.action.twitch.entry.user.getInfo="Using account{{account}}{{actions}}for{{userInfoQueryType}}{{userLogin}}{{userId}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.user.getInfo="Using account{{account}}{{actions}}for{{userInfoQueryType}}{{userLogin}}{{userId}}"
|
AdvSceneSwitcher.action.twitch.entry.reward.getInfo="Using account{{account}}{{actions}}for channel{{channel}}{{pointsReward}}{{rewardVariable}}{{toggleRewardSelection}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.reward.getInfo="Using account{{account}}{{actions}}for channel{{channel}}{{pointsReward}}{{rewardVariable}}{{toggleRewardSelection}}"
|
|
||||||
AdvSceneSwitcher.action.twitch.title.title="Enter title"
|
AdvSceneSwitcher.action.twitch.title.title="Enter title"
|
||||||
AdvSceneSwitcher.action.twitch.marker.description="Describe marker"
|
AdvSceneSwitcher.action.twitch.marker.description="Describe marker"
|
||||||
AdvSceneSwitcher.action.twitch.clip.hasDelay="Add a slight delay before capturing the clip"
|
AdvSceneSwitcher.action.twitch.clip.hasDelay="Add a slight delay before capturing the clip"
|
||||||
@@ -1619,11 +1596,7 @@ AdvSceneSwitcher.twitchToken.moderator.chat.settings.manage="Manage channel's ch
|
|||||||
AdvSceneSwitcher.twitchToken.user.whispers.manage="Manage user's whispers."
|
AdvSceneSwitcher.twitchToken.user.whispers.manage="Manage user's whispers."
|
||||||
AdvSceneSwitcher.twitchToken.chat.read="View live stream chat messages."
|
AdvSceneSwitcher.twitchToken.chat.read="View live stream chat messages."
|
||||||
AdvSceneSwitcher.twitchToken.chat.edit="Send live stream chat messages."
|
AdvSceneSwitcher.twitchToken.chat.edit="Send live stream chat messages."
|
||||||
AdvSceneSwitcher.twitchToken.validateTimestamps="Validate timestamps of received Twitch event messages."
|
AdvSceneSwitcher.twitchToken.validateTimestamps="Validate timestamps of received Twitch event messages. (Recommended)"
|
||||||
AdvSceneSwitcher.twitchToken.validateTimestamps.tooltip="Verifies that incoming Twitch messages have valid timestamps to prevent replayed or spoofed messages.\nDisabling this won’t affect normal functionality, and you can try turning it off if you experience issues with the Twitch connection."
|
|
||||||
AdvSceneSwitcher.twitchToken.warnIfInvalid="Display warning if the token expired or is invalid."
|
|
||||||
AdvSceneSwitcher.twitchToken.warnIfInvalid.doNotShowAgain="Don't show again for this connection"
|
|
||||||
AdvSceneSwitcher.twitchToken.warnIfInvalid.message="The Twitch connection \"%1\" is invalid.\nOpen connection settings or ignore?"
|
|
||||||
|
|
||||||
AdvSceneSwitcher.twitch.selection.channel.open="Open channel"
|
AdvSceneSwitcher.twitch.selection.channel.open="Open channel"
|
||||||
AdvSceneSwitcher.twitch.selection.channel.open.tooltip.details="Open channel in external application handling the HTTPS protocol."
|
AdvSceneSwitcher.twitch.selection.channel.open.tooltip.details="Open channel in external application handling the HTTPS protocol."
|
||||||
@@ -2190,8 +2163,6 @@ AdvSceneSwitcher.tempVar.run.process.none.description="When not waiting for the
|
|||||||
|
|
||||||
AdvSceneSwitcher.tempVar.recording.durationSeconds="Recording duration"
|
AdvSceneSwitcher.tempVar.recording.durationSeconds="Recording duration"
|
||||||
AdvSceneSwitcher.tempVar.recording.durationSeconds.description="Recording duration in seconds.\nThis value does not change while the recording is paused and will be reset to zero if the recording is stopped."
|
AdvSceneSwitcher.tempVar.recording.durationSeconds.description="Recording duration in seconds.\nThis value does not change while the recording is paused and will be reset to zero if the recording is stopped."
|
||||||
AdvSceneSwitcher.tempVar.recording.lastSavePath="Last save path"
|
|
||||||
AdvSceneSwitcher.tempVar.recording.lastSavePath.description="The file path of the last saved recording."
|
|
||||||
|
|
||||||
AdvSceneSwitcher.tempVar.video.patternCount="Pattern count"
|
AdvSceneSwitcher.tempVar.video.patternCount="Pattern count"
|
||||||
AdvSceneSwitcher.tempVar.video.patternCount.description="The number of times the given pattern has been found in a given video input frame."
|
AdvSceneSwitcher.tempVar.video.patternCount.description="The number of times the given pattern has been found in a given video input frame."
|
||||||
@@ -2341,9 +2312,6 @@ AdvSceneSwitcher.tempVar.mqtt.message="Message"
|
|||||||
AdvSceneSwitcher.tempVar.cursor.x="Cursor position (X)"
|
AdvSceneSwitcher.tempVar.cursor.x="Cursor position (X)"
|
||||||
AdvSceneSwitcher.tempVar.cursor.y="Cursor position (Y)"
|
AdvSceneSwitcher.tempVar.cursor.y="Cursor position (Y)"
|
||||||
|
|
||||||
AdvSceneSwitcher.tempVar.replay.lastSavePath="Last save path"
|
|
||||||
AdvSceneSwitcher.tempVar.replay.lastSavePath.description="The file path of the last replay buffer saved."
|
|
||||||
|
|
||||||
AdvSceneSwitcher.selectScene="--select scene--"
|
AdvSceneSwitcher.selectScene="--select scene--"
|
||||||
AdvSceneSwitcher.selectCanvas="--select canvas--"
|
AdvSceneSwitcher.selectCanvas="--select canvas--"
|
||||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="プラグイ
|
|||||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>次のプラグイン ライブラリの読み込みに失敗したため、一部の高機能シーンスイッチャーが利用できなくなる可能性があります:%1詳細については、OBS ログを確認してください。<br>このメッセージは、[全般] タブで無効にすることができます。 </body></html>"
|
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>次のプラグイン ライブラリの読み込みに失敗したため、一部の高機能シーンスイッチャーが利用できなくなる可能性があります:%1詳細については、OBS ログを確認してください。<br>このメッセージは、[全般] タブで無効にすることができます。 </body></html>"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="プラグインが正しくインストールできておらずクラッシュする可能性があります!\nプラグインが正しくインストールされているか確認してください!"
|
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="プラグインが正しくインストールできておらずクラッシュする可能性があります!\nプラグインが正しくインストールされているか確認してください!"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="旧来型マクロ設定のタブを非表示にする(廃止予定タブ)"
|
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="旧来型マクロ設定のタブを非表示にする(廃止予定タブ)"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache="マクロウィジェットのキャッシングを無効にする"
|
||||||
AdvSceneSwitcher.generalTab.matchBehavior="マッチした場合の動作(廃止予定の設定項目)"
|
AdvSceneSwitcher.generalTab.matchBehavior="マッチした場合の動作(廃止予定の設定項目)"
|
||||||
AdvSceneSwitcher.generalTab.priority="優先順位"
|
AdvSceneSwitcher.generalTab.priority="優先順位"
|
||||||
AdvSceneSwitcher.generalTab.priority.description="切り替え方法の優先順位(優先順位が高いものが上)"
|
AdvSceneSwitcher.generalTab.priority.description="切り替え方法の優先順位(優先順位が高いものが上)"
|
||||||
@@ -1193,10 +1194,10 @@ AdvSceneSwitcher.action.twitch.type.user.getInfo="ユーザー情報を取得"
|
|||||||
AdvSceneSwitcher.action.twitch.type.reward.getInfo="チャンネルポイントリワード情報を取得"
|
AdvSceneSwitcher.action.twitch.type.reward.getInfo="チャンネルポイントリワード情報を取得"
|
||||||
AdvSceneSwitcher.action.twitch.reward.toggleControl="リワード名/変数選択コントロールの切り替え"
|
AdvSceneSwitcher.action.twitch.reward.toggleControl="リワード名/変数選択コントロールの切り替え"
|
||||||
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Twitchアカウントを選択しないとカテゴリを選択できません!"
|
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Twitchアカウントを選択しないとカテゴリを選択できません!"
|
||||||
; AdvSceneSwitcher.action.twitch.layout.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}"
|
; AdvSceneSwitcher.action.twitch.entry.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.chat="{{channel}}でアカウント{{account}}{{actions}}を使用しています"
|
AdvSceneSwitcher.action.twitch.entry.chat="{{channel}}でアカウント{{account}}{{actions}}を使用しています"
|
||||||
AdvSceneSwitcher.action.twitch.layout.user.getInfo="{{userInfoQueryType}}{{userLogin}}{{userId}}でアカウント{{account}}{{actions}}を使用"
|
AdvSceneSwitcher.action.twitch.entry.user.getInfo="{{userInfoQueryType}}{{userLogin}}{{userId}}でアカウント{{account}}{{actions}}を使用"
|
||||||
AdvSceneSwitcher.action.twitch.layout.reward.getInfo="チャンネル{{channel}}{{pointsReward}}{{rewardVariable}}{{toggleRewardSelection}}でアカウント{{account}}{{actions}}を使用"
|
AdvSceneSwitcher.action.twitch.entry.reward.getInfo="チャンネル{{channel}}{{pointsReward}}{{rewardVariable}}{{toggleRewardSelection}}でアカウント{{account}}{{actions}}を使用"
|
||||||
AdvSceneSwitcher.action.twitch.title.title="タイトルを入力"
|
AdvSceneSwitcher.action.twitch.title.title="タイトルを入力"
|
||||||
AdvSceneSwitcher.action.twitch.marker.description="マーカーの説明"
|
AdvSceneSwitcher.action.twitch.marker.description="マーカーの説明"
|
||||||
AdvSceneSwitcher.action.twitch.clip.hasDelay="クリップをキャプチャする前にわずかな遅延を追加します"
|
AdvSceneSwitcher.action.twitch.clip.hasDelay="クリップをキャプチャする前にわずかな遅延を追加します"
|
||||||
|
|||||||
@@ -1065,8 +1065,8 @@ AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.enable="Habilitar modo apenas
|
|||||||
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable="Desabilitar modo apenas emotes no chat"
|
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable="Desabilitar modo apenas emotes no chat"
|
||||||
AdvSceneSwitcher.action.twitch.type.chat.sendMessage="Enviar mensagem de chat"
|
AdvSceneSwitcher.action.twitch.type.chat.sendMessage="Enviar mensagem de chat"
|
||||||
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Não é possível selecionar categoria sem selecionar uma conta Twitch primeiro!"
|
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Não é possível selecionar categoria sem selecionar uma conta Twitch primeiro!"
|
||||||
AdvSceneSwitcher.action.twitch.layout.default="Em{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
|
AdvSceneSwitcher.action.twitch.entry.default="Em{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.chat="Usando conta{{account}}{{actions}}em{{channel}}"
|
AdvSceneSwitcher.action.twitch.entry.chat="Usando conta{{account}}{{actions}}em{{channel}}"
|
||||||
AdvSceneSwitcher.action.twitch.title.title="Digite o título"
|
AdvSceneSwitcher.action.twitch.title.title="Digite o título"
|
||||||
AdvSceneSwitcher.action.twitch.marker.description="Descreva o marcador"
|
AdvSceneSwitcher.action.twitch.marker.description="Descreva o marcador"
|
||||||
AdvSceneSwitcher.action.twitch.clip.hasDelay="Adicionar um leve atraso antes de capturar o clipe"
|
AdvSceneSwitcher.action.twitch.clip.hasDelay="Adicionar um leve atraso antes de capturar o clipe"
|
||||||
|
|||||||
@@ -1139,10 +1139,10 @@ AdvSceneSwitcher.action.twitch.type.user.getInfo="获取用户信息"
|
|||||||
AdvSceneSwitcher.action.twitch.type.reward.getInfo="获取频道积分奖励信息"
|
AdvSceneSwitcher.action.twitch.type.reward.getInfo="获取频道积分奖励信息"
|
||||||
AdvSceneSwitcher.action.twitch.reward.toggleControl="切换奖励名称/变量选择控制"
|
AdvSceneSwitcher.action.twitch.reward.toggleControl="切换奖励名称/变量选择控制"
|
||||||
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="在未选择 Twitch 帐户的情况下无法选择类别!"
|
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="在未选择 Twitch 帐户的情况下无法选择类别!"
|
||||||
AdvSceneSwitcher.action.twitch.layout.default="{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
|
AdvSceneSwitcher.action.twitch.entry.default="{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.chat="使用账户{{account}}{{actions}}{{channel}}"
|
AdvSceneSwitcher.action.twitch.entry.chat="使用账户{{account}}{{actions}}{{channel}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.user.getInfo="使用账户{{account}}{{actions}}{{userInfoQueryType}}{{userLogin}}{{userId}}"
|
AdvSceneSwitcher.action.twitch.entry.user.getInfo="使用账户{{account}}{{actions}}{{userInfoQueryType}}{{userLogin}}{{userId}}"
|
||||||
AdvSceneSwitcher.action.twitch.layout.reward.getInfo="使用账户{{account}}{{actions}} 频道{{channel}}{{pointsReward}}{{rewardVariable}}{{toggleRewardSelection}}"
|
AdvSceneSwitcher.action.twitch.entry.reward.getInfo="使用账户{{account}}{{actions}} 频道{{channel}}{{pointsReward}}{{rewardVariable}}{{toggleRewardSelection}}"
|
||||||
AdvSceneSwitcher.action.twitch.title.title="输入标题"
|
AdvSceneSwitcher.action.twitch.title.title="输入标题"
|
||||||
AdvSceneSwitcher.action.twitch.marker.description="标记描述"
|
AdvSceneSwitcher.action.twitch.marker.description="标记描述"
|
||||||
AdvSceneSwitcher.action.twitch.clip.hasDelay="在捕捉视频片段前稍加延迟"
|
AdvSceneSwitcher.action.twitch.clip.hasDelay="在捕捉视频片段前稍加延迟"
|
||||||
|
|||||||
@@ -68,162 +68,365 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>962</width>
|
<width>962</width>
|
||||||
<height>1160</height>
|
<height>1057</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="statusBox">
|
<layout class="QHBoxLayout" name="horizontalLayout_31">
|
||||||
<property name="title">
|
<item>
|
||||||
<string>AdvSceneSwitcher.generalTab.status</string>
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
</property>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<widget class="QGroupBox" name="statusBox">
|
||||||
<item row="0" column="0">
|
<property name="title">
|
||||||
<layout class="QGridLayout" name="statusLayout">
|
<string>AdvSceneSwitcher.generalTab.status</string>
|
||||||
<item row="4" column="1">
|
</property>
|
||||||
<widget class="QComboBox" name="autoStartEvent"/>
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
</item>
|
<item row="0" column="0">
|
||||||
<item row="4" column="0">
|
<layout class="QGridLayout" name="statusLayout">
|
||||||
<widget class="QLabel" name="label_10">
|
<item row="4" column="1">
|
||||||
<property name="text">
|
<widget class="QComboBox" name="autoStartEvent"/>
|
||||||
<string>AdvSceneSwitcher.generalTab.status.autoStart.startup</string>
|
</item>
|
||||||
</property>
|
<item row="4" column="0">
|
||||||
</widget>
|
<widget class="QLabel" name="label_10">
|
||||||
</item>
|
<property name="text">
|
||||||
<item row="0" column="0">
|
<string>AdvSceneSwitcher.generalTab.status.autoStart.startup</string>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QLabel" name="label_4">
|
</item>
|
||||||
<property name="text">
|
<item row="0" column="0">
|
||||||
<string>AdvSceneSwitcher.generalTab.status.checkInterval</string>
|
<layout class="QVBoxLayout" name="verticalLayout_33">
|
||||||
</property>
|
<item>
|
||||||
</widget>
|
<widget class="QLabel" name="label_4">
|
||||||
</item>
|
<property name="text">
|
||||||
<item>
|
<string>AdvSceneSwitcher.generalTab.status.checkInterval</string>
|
||||||
<widget class="QLabel" name="checkIntervalTooLowWarning">
|
</property>
|
||||||
<property name="text">
|
</widget>
|
||||||
<string/>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</widget>
|
<widget class="QLabel" name="checkIntervalTooLowWarning">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="startupBehavior"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QWidget" name="placeholder3" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QWidget" name="placeholder" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_64">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.status.onStartup</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QWidget" name="placeholder2" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QLabel" name="label_13">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.status.hotkeytips</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="checkInterval">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true">ms</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>20000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>300</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="autoStartSceneEnable">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.status.autoStart.scene</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="autoStartSceneLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="advss::SceneSelectionWidget" name="autoStartScene" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="advss::VariableLineEdit" name="autoStartSceneName"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="advss::RegexConfigWidget" name="autoStartSceneNameRegex" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</widget>
|
||||||
<item row="3" column="1">
|
</item>
|
||||||
<widget class="QComboBox" name="startupBehavior"/>
|
<item>
|
||||||
</item>
|
<widget class="QGroupBox" name="generalSettingsBox">
|
||||||
<item row="1" column="1">
|
<property name="title">
|
||||||
<widget class="QWidget" name="placeholder3" native="true"/>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior</string>
|
||||||
</item>
|
</property>
|
||||||
<item row="1" column="0">
|
<layout class="QVBoxLayout" name="verticalLayout_32">
|
||||||
<widget class="QWidget" name="placeholder" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_64">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.status.onStartup</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QWidget" name="placeholder2" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QLabel" name="label_13">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.status.hotkeytips</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QSpinBox" name="checkInterval">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string notr="true">ms</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>20000</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>300</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QCheckBox" name="autoStartSceneEnable">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.status.autoStart.scene</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="autoStartSceneLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="advss::SceneSelectionWidget" name="autoStartScene" native="true"/>
|
<layout class="QHBoxLayout" name="horizontalLayout_52">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_21">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="logLevel"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_49">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="advss::VariableLineEdit" name="autoStartSceneName"/>
|
<layout class="QHBoxLayout" name="horizontalLayout_50">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="saveWindowGeo">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_55">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="advss::RegexConfigWidget" name="autoStartSceneNameRegex" native="true"/>
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="showTrayNotifications">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_48">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="uiHintsDisable">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_52">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="disableComboBoxFilter">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.comboBoxFilterDisable</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_13">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="disableMacroWidgetCache">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="warnPluginLoadFailure">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_19">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_24">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="hideLegacyTabs">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_16">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</widget>
|
||||||
</layout>
|
</item>
|
||||||
</item>
|
<item>
|
||||||
</layout>
|
<layout class="QVBoxLayout" name="verticalLayout_18">
|
||||||
</widget>
|
<item>
|
||||||
|
<widget class="QGroupBox" name="saveLoadBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="exportSettings">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.export</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="importSettings">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.import</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="saveLoadBox">
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings</string>
|
<string>AdvSceneSwitcher.generalTab.matchBehavior</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_17">
|
<layout class="QVBoxLayout" name="verticalLayout_37">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="exportSettings">
|
<layout class="QHBoxLayout" name="cooldownLayout">
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.export</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="importSettings">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.import</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="generalSettingsBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_32">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_52">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_21">
|
<widget class="QCheckBox" name="enableCooldown">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel</string>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.cooldown</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="logLevel"/>
|
<widget class="advss::DurationSelection" name="cooldownTime" native="true"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_49">
|
<spacer name="horizontalSpacer_21">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
@@ -238,72 +441,80 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="showTrayNotifications">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<property name="text">
|
<item row="0" column="2">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications</string>
|
<layout class="QHBoxLayout" name="horizontalLayout_43">
|
||||||
</property>
|
<item>
|
||||||
</widget>
|
<widget class="QRadioButton" name="noMatchDontSwitch">
|
||||||
</item>
|
<property name="text">
|
||||||
<item>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.dontSwitch</string>
|
||||||
<widget class="QCheckBox" name="warnPluginLoadFailure">
|
</property>
|
||||||
<property name="text">
|
<property name="checked">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure</string>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
<item row="2" column="2">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="horizontalLayout_45">
|
||||||
<widget class="QGroupBox" name="groupBox_6">
|
<item>
|
||||||
<property name="title">
|
<widget class="QRadioButton" name="noMatchRandomSwitch">
|
||||||
<string>AdvSceneSwitcher.generalTab.uiBehavior</string>
|
<property name="text">
|
||||||
</property>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchToRandom</string>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QCheckBox" name="saveWindowGeo">
|
</item>
|
||||||
<property name="text">
|
</layout>
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo</string>
|
</item>
|
||||||
</property>
|
<item row="1" column="2">
|
||||||
</widget>
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
</item>
|
<property name="leftMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<widget class="QCheckBox" name="alwaysShowMacroSearch">
|
</property>
|
||||||
<property name="text">
|
<property name="topMargin">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowMacroSearch</string>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="rightMargin">
|
||||||
</item>
|
<number>0</number>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QCheckBox" name="alwaysShowFeatureTabs">
|
<property name="bottomMargin">
|
||||||
<property name="toolTip">
|
<number>0</number>
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowFeatureTabs.tooltip</string>
|
</property>
|
||||||
</property>
|
<item>
|
||||||
<property name="text">
|
<widget class="QRadioButton" name="noMatchSwitch">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowFeatureTabs</string>
|
<property name="text">
|
||||||
</property>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchTo</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QCheckBox" name="disableComboBoxFilter">
|
<item>
|
||||||
<property name="text">
|
<widget class="advss::SceneSelectionWidget" name="noMatchSwitchScene">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.comboBoxFilterDisable</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="1">
|
||||||
<widget class="QCheckBox" name="uiHintsDisable">
|
<layout class="QHBoxLayout" name="noMatchLayout">
|
||||||
<property name="text">
|
<item>
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints</string>
|
<widget class="QLabel" name="label_2">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
</widget>
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
</item>
|
<horstretch>0</horstretch>
|
||||||
<item>
|
<verstretch>0</verstretch>
|
||||||
<widget class="QCheckBox" name="hideLegacyTabs">
|
</sizepolicy>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs</string>
|
<property name="text">
|
||||||
</property>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch</string>
|
||||||
</widget>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -351,109 +562,6 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="matchBehaviorBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.matchBehavior</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_37">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="cooldownLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="enableCooldown">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.cooldown</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="advss::DurationSelection" name="cooldownTime" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_21">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QRadioButton" name="noMatchDontSwitch">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.dontSwitch</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2">
|
|
||||||
<widget class="QRadioButton" name="noMatchRandomSwitch">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchToRandom</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="noMatchSwitch">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchTo</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="advss::SceneSelectionWidget" name="noMatchSwitchScene" native="true"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="noMatchLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="priorityBox">
|
<widget class="QGroupBox" name="priorityBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -468,7 +576,15 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListWidget" name="priorityList"/>
|
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_41">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="priorityList"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_32">
|
<layout class="QHBoxLayout" name="horizontalLayout_32">
|
||||||
@@ -605,55 +721,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="macroSearchLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="macroSearchText">
|
|
||||||
<property name="placeholderText">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.search.placeholder</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="macroSearchClear">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.variableTab.clear</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="macroSearchType"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="advss::RegexConfigWidget" name="macroSearchRegex" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="macroSearchShowSettings">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.search.showSettings</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="advss::MacroTree" name="macros">
|
<widget class="advss::MacroTree" name="macros">
|
||||||
<property name="showDropIndicator" stdset="0">
|
<property name="showDropIndicator" stdset="0">
|
||||||
@@ -4097,7 +4164,12 @@
|
|||||||
<tabstop>autoStartSceneName</tabstop>
|
<tabstop>autoStartSceneName</tabstop>
|
||||||
<tabstop>autoStartSceneNameRegex</tabstop>
|
<tabstop>autoStartSceneNameRegex</tabstop>
|
||||||
<tabstop>logLevel</tabstop>
|
<tabstop>logLevel</tabstop>
|
||||||
|
<tabstop>saveWindowGeo</tabstop>
|
||||||
|
<tabstop>showTrayNotifications</tabstop>
|
||||||
|
<tabstop>uiHintsDisable</tabstop>
|
||||||
|
<tabstop>disableComboBoxFilter</tabstop>
|
||||||
<tabstop>warnPluginLoadFailure</tabstop>
|
<tabstop>warnPluginLoadFailure</tabstop>
|
||||||
|
<tabstop>hideLegacyTabs</tabstop>
|
||||||
<tabstop>exportSettings</tabstop>
|
<tabstop>exportSettings</tabstop>
|
||||||
<tabstop>importSettings</tabstop>
|
<tabstop>importSettings</tabstop>
|
||||||
<tabstop>noMatchDontSwitch</tabstop>
|
<tabstop>noMatchDontSwitch</tabstop>
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ public slots:
|
|||||||
void on_showTrayNotifications_stateChanged(int state);
|
void on_showTrayNotifications_stateChanged(int state);
|
||||||
void on_uiHintsDisable_stateChanged(int state);
|
void on_uiHintsDisable_stateChanged(int state);
|
||||||
void on_disableComboBoxFilter_stateChanged(int state);
|
void on_disableComboBoxFilter_stateChanged(int state);
|
||||||
|
void on_disableMacroWidgetCache_stateChanged(int state);
|
||||||
void on_warnPluginLoadFailure_stateChanged(int state);
|
void on_warnPluginLoadFailure_stateChanged(int state);
|
||||||
void on_hideLegacyTabs_stateChanged(int state);
|
void on_hideLegacyTabs_stateChanged(int state);
|
||||||
void on_priorityUp_clicked();
|
void on_priorityUp_clicked();
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "filter-combo-box.hpp"
|
#include "filter-combo-box.hpp"
|
||||||
#include "layout-helpers.hpp"
|
#include "layout-helpers.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "macro-search.hpp"
|
|
||||||
#include "macro-settings.hpp"
|
#include "macro-settings.hpp"
|
||||||
#include "path-helpers.hpp"
|
#include "path-helpers.hpp"
|
||||||
#include "selection-helpers.hpp"
|
#include "selection-helpers.hpp"
|
||||||
@@ -186,6 +185,16 @@ void AdvSceneSwitcher::on_disableComboBoxFilter_stateChanged(int state)
|
|||||||
FilterComboBox::SetFilterBehaviourEnabled(!state);
|
FilterComboBox::SetFilterBehaviourEnabled(!state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_disableMacroWidgetCache_stateChanged(int state)
|
||||||
|
{
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switcher->disableMacroWidgetCache = state;
|
||||||
|
MacroSegmentList::SetCachingEnabled(!state);
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -522,6 +531,8 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
|||||||
obs_data_set_bool(obj, "disableHints", disableHints);
|
obs_data_set_bool(obj, "disableHints", disableHints);
|
||||||
obs_data_set_bool(obj, "disableFilterComboboxFilter",
|
obs_data_set_bool(obj, "disableFilterComboboxFilter",
|
||||||
disableFilterComboboxFilter);
|
disableFilterComboboxFilter);
|
||||||
|
obs_data_set_bool(obj, "disableMacroWidgetCache",
|
||||||
|
disableMacroWidgetCache);
|
||||||
obs_data_set_bool(obj, "warnPluginLoadFailure", warnPluginLoadFailure);
|
obs_data_set_bool(obj, "warnPluginLoadFailure", warnPluginLoadFailure);
|
||||||
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
||||||
|
|
||||||
@@ -591,6 +602,8 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
disableHints = obs_data_get_bool(obj, "disableHints");
|
disableHints = obs_data_get_bool(obj, "disableHints");
|
||||||
disableFilterComboboxFilter =
|
disableFilterComboboxFilter =
|
||||||
obs_data_get_bool(obj, "disableFilterComboboxFilter");
|
obs_data_get_bool(obj, "disableFilterComboboxFilter");
|
||||||
|
disableMacroWidgetCache =
|
||||||
|
obs_data_get_bool(obj, "disableMacroWidgetCache");
|
||||||
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
|
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
|
||||||
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
|
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
|
||||||
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
||||||
@@ -914,6 +927,9 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
switcher->disableFilterComboboxFilter);
|
switcher->disableFilterComboboxFilter);
|
||||||
FilterComboBox::SetFilterBehaviourEnabled(
|
FilterComboBox::SetFilterBehaviourEnabled(
|
||||||
!switcher->disableFilterComboboxFilter);
|
!switcher->disableFilterComboboxFilter);
|
||||||
|
ui->disableMacroWidgetCache->setChecked(
|
||||||
|
switcher->disableMacroWidgetCache);
|
||||||
|
MacroSegmentList::SetCachingEnabled(!switcher->disableMacroWidgetCache);
|
||||||
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
||||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||||
|
|
||||||
@@ -997,19 +1013,6 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
switcher->CheckAutoStart();
|
switcher->CheckAutoStart();
|
||||||
});
|
});
|
||||||
|
|
||||||
ui->alwaysShowMacroSearch->setChecked(
|
|
||||||
GetMacroSearchSettings().showAlways);
|
|
||||||
|
|
||||||
connect(ui->alwaysShowMacroSearch, &QCheckBox::stateChanged, this,
|
|
||||||
[this](int enabled) {
|
|
||||||
GetMacroSearchSettings().showAlways = enabled;
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CheckMacroSearchVisibility();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up status control
|
// Set up status control
|
||||||
auto statusControl = new StatusControl(this, true);
|
auto statusControl = new StatusControl(this, true);
|
||||||
ui->statusLayout->addWidget(statusControl->StatusPrefixLabel(), 1, 0);
|
ui->statusLayout->addWidget(statusControl->StatusPrefixLabel(), 1, 0);
|
||||||
@@ -1029,8 +1032,6 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
setTabOrder(ui->importSettings, ui->cooldownTime);
|
setTabOrder(ui->importSettings, ui->cooldownTime);
|
||||||
setTabOrder(ui->cooldownTime, ui->noMatchDontSwitch);
|
setTabOrder(ui->cooldownTime, ui->noMatchDontSwitch);
|
||||||
|
|
||||||
SetupShowAllTabsCheckBox(ui->alwaysShowFeatureTabs, ui->tabWidget);
|
|
||||||
|
|
||||||
MinimizeSizeOfColumn(ui->statusLayout, 0);
|
MinimizeSizeOfColumn(ui->statusLayout, 0);
|
||||||
setWindowTitle(windowTitle() + " - " + g_GIT_TAG);
|
setWindowTitle(windowTitle() + " - " + g_GIT_TAG);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ static inline void populateActionSelection(QComboBox *list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MacroActionEdit::MacroActionEdit(QWidget *parent,
|
MacroActionEdit::MacroActionEdit(QWidget *parent,
|
||||||
std::shared_ptr<MacroAction> *entryData)
|
std::shared_ptr<MacroAction> *entryData,
|
||||||
|
const std::string &id)
|
||||||
: MacroSegmentEdit(parent),
|
: MacroSegmentEdit(parent),
|
||||||
_actionSelection(new FilterComboBox()),
|
_actionSelection(new FilterComboBox()),
|
||||||
_enable(new SwitchButton()),
|
_enable(new SwitchButton()),
|
||||||
|
|||||||
@@ -13,8 +13,10 @@ class MacroActionEdit : public MacroSegmentEdit {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MacroActionEdit(QWidget *parent = nullptr,
|
MacroActionEdit(
|
||||||
std::shared_ptr<MacroAction> * = nullptr);
|
QWidget *parent = nullptr,
|
||||||
|
std::shared_ptr<MacroAction> * = nullptr,
|
||||||
|
const std::string &id = MacroAction::GetDefaultID().data());
|
||||||
void SetupWidgets(bool basicSetup = false);
|
void SetupWidgets(bool basicSetup = false);
|
||||||
void SetEntryData(std::shared_ptr<MacroAction> *);
|
void SetEntryData(std::shared_ptr<MacroAction> *);
|
||||||
|
|
||||||
|
|||||||
@@ -93,46 +93,33 @@ bool MacroActionMacro::PerformAction()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto performActionForMacro = [this](Macro *macro) {
|
switch (_action) {
|
||||||
switch (_action) {
|
case Action::PAUSE:
|
||||||
case Action::PAUSE:
|
macro->SetPaused();
|
||||||
macro->SetPaused();
|
break;
|
||||||
break;
|
case Action::UNPAUSE:
|
||||||
case Action::UNPAUSE:
|
macro->SetPaused(false);
|
||||||
macro->SetPaused(false);
|
break;
|
||||||
break;
|
case Action::TOGGLE_PAUSE:
|
||||||
case Action::TOGGLE_PAUSE:
|
macro->SetPaused(!macro->Paused());
|
||||||
macro->SetPaused(!macro->Paused());
|
break;
|
||||||
break;
|
case Action::RESET_COUNTER:
|
||||||
case Action::RESET_COUNTER:
|
macro->ResetRunCount();
|
||||||
macro->ResetRunCount();
|
break;
|
||||||
break;
|
case Action::RUN_ACTIONS:
|
||||||
case Action::RUN_ACTIONS:
|
RunActions(macro.get());
|
||||||
RunActions(macro);
|
break;
|
||||||
break;
|
case Action::STOP:
|
||||||
case Action::STOP:
|
macro->Stop();
|
||||||
macro->Stop();
|
break;
|
||||||
break;
|
case Action::DISABLE_ACTION:
|
||||||
case Action::DISABLE_ACTION:
|
case Action::ENABLE_ACTION:
|
||||||
case Action::ENABLE_ACTION:
|
case Action::TOGGLE_ACTION:
|
||||||
case Action::TOGGLE_ACTION:
|
AdjustActionState(macro.get());
|
||||||
AdjustActionState(macro);
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!IsGroupMacro(macro.get())) {
|
|
||||||
performActionForMacro(macro.get());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto macros = GetGroupMacroEntries(macro.get());
|
|
||||||
for (const auto ¯o : macros) {
|
|
||||||
performActionForMacro(macro.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,7 +404,6 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
|||||||
populateActionTypes(_actionTypes);
|
populateActionTypes(_actionTypes);
|
||||||
|
|
||||||
_conditionMacros->HideSelectedMacro();
|
_conditionMacros->HideSelectedMacro();
|
||||||
_conditionMacros->HideGroups();
|
|
||||||
|
|
||||||
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
||||||
this, SLOT(MacroChanged(const QString &)));
|
this, SLOT(MacroChanged(const QString &)));
|
||||||
|
|||||||
@@ -286,14 +286,6 @@ bool MacroActionVariable::PerformAction()
|
|||||||
case Action::APPEND:
|
case Action::APPEND:
|
||||||
apppend(*var, _strValue);
|
apppend(*var, _strValue);
|
||||||
break;
|
break;
|
||||||
case Action::COPY_VAR: {
|
|
||||||
auto var2 = _variable2.lock();
|
|
||||||
if (!var2) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
var->SetValue(var2->Value());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Action::APPEND_VAR: {
|
case Action::APPEND_VAR: {
|
||||||
auto var2 = _variable2.lock();
|
auto var2 = _variable2.lock();
|
||||||
if (!var2) {
|
if (!var2) {
|
||||||
@@ -678,8 +670,6 @@ static inline void populateActionSelection(QComboBox *list)
|
|||||||
actions = {
|
actions = {
|
||||||
{MacroActionVariable::Action::SET_VALUE,
|
{MacroActionVariable::Action::SET_VALUE,
|
||||||
"AdvSceneSwitcher.action.variable.type.set"},
|
"AdvSceneSwitcher.action.variable.type.set"},
|
||||||
{MacroActionVariable::Action::COPY_VAR,
|
|
||||||
"AdvSceneSwitcher.action.variable.type.copy"},
|
|
||||||
{MacroActionVariable::Action::APPEND,
|
{MacroActionVariable::Action::APPEND,
|
||||||
"AdvSceneSwitcher.action.variable.type.append"},
|
"AdvSceneSwitcher.action.variable.type.append"},
|
||||||
{MacroActionVariable::Action::PAD,
|
{MacroActionVariable::Action::PAD,
|
||||||
@@ -1531,7 +1521,6 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_variables2->setVisible(
|
_variables2->setVisible(
|
||||||
_entryData->_action == MacroActionVariable::Action::COPY_VAR ||
|
|
||||||
_entryData->_action ==
|
_entryData->_action ==
|
||||||
MacroActionVariable::Action::APPEND_VAR ||
|
MacroActionVariable::Action::APPEND_VAR ||
|
||||||
_entryData->_action ==
|
_entryData->_action ==
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public:
|
|||||||
RANDOM_NUMBER,
|
RANDOM_NUMBER,
|
||||||
QUERY_JSON,
|
QUERY_JSON,
|
||||||
ARRAY_JSON,
|
ARRAY_JSON,
|
||||||
COPY_VAR,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Action _action = Action::SET_VALUE;
|
Action _action = Action::SET_VALUE;
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void DurationModifierEdit::Collapse(bool collapse)
|
|||||||
|
|
||||||
MacroConditionEdit::MacroConditionEdit(
|
MacroConditionEdit::MacroConditionEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroCondition> *entryData,
|
QWidget *parent, std::shared_ptr<MacroCondition> *entryData,
|
||||||
bool isRootCondition)
|
const std::string &id, bool isRootCondition)
|
||||||
: MacroSegmentEdit(parent),
|
: MacroSegmentEdit(parent),
|
||||||
_logicSelection(new QComboBox()),
|
_logicSelection(new QComboBox()),
|
||||||
_conditionSelection(new FilterComboBox()),
|
_conditionSelection(new FilterComboBox()),
|
||||||
|
|||||||
@@ -34,9 +34,11 @@ class MacroConditionEdit : public MacroSegmentEdit {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MacroConditionEdit(QWidget *parent = nullptr,
|
MacroConditionEdit(
|
||||||
std::shared_ptr<MacroCondition> * = nullptr,
|
QWidget *parent = nullptr,
|
||||||
bool root = true);
|
std::shared_ptr<MacroCondition> * = nullptr,
|
||||||
|
const std::string &id = MacroCondition::GetDefaultID().data(),
|
||||||
|
bool root = true);
|
||||||
bool IsRootNode() const;
|
bool IsRootNode() const;
|
||||||
void SetRootNode(bool);
|
void SetRootNode(bool);
|
||||||
void SetupWidgets(bool basicSetup = false);
|
void SetupWidgets(bool basicSetup = false);
|
||||||
|
|||||||
@@ -315,7 +315,6 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
|
|||||||
_actionIndex(new MacroSegmentSelection(
|
_actionIndex(new MacroSegmentSelection(
|
||||||
this, MacroSegmentSelection::Type::ACTION))
|
this, MacroSegmentSelection::Type::ACTION))
|
||||||
{
|
{
|
||||||
_macros->HideGroups();
|
|
||||||
_count->setMaximum(10000000);
|
_count->setMaximum(10000000);
|
||||||
populateTypeSelection(_types);
|
populateTypeSelection(_types);
|
||||||
populateCounterConditionSelection(_counterConditions);
|
populateCounterConditionSelection(_counterConditions);
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ void MacroDock::RunClicked()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret = macro->PerformActions(true, true, true);
|
auto ret = macro->PerformActions(true);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
QString err =
|
QString err =
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
||||||
|
|||||||
@@ -418,7 +418,8 @@ void MacroEdit::PopulateMacroActions(Macro &m, uint32_t afterIdx)
|
|||||||
ui->actionsList->SetVisibilityCheckEnable(false);
|
ui->actionsList->SetVisibilityCheckEnable(false);
|
||||||
|
|
||||||
for (; afterIdx < actions.size(); afterIdx++) {
|
for (; afterIdx < actions.size(); afterIdx++) {
|
||||||
auto newEntry = new MacroActionEdit(this, &actions[afterIdx]);
|
auto newEntry = new MacroActionEdit(this, &actions[afterIdx],
|
||||||
|
actions[afterIdx]->GetId());
|
||||||
ui->actionsList->Add(newEntry);
|
ui->actionsList->Add(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +444,8 @@ void MacroEdit::PopulateMacroElseActions(Macro &m, uint32_t afterIdx)
|
|||||||
ui->elseActionsList->SetVisibilityCheckEnable(false);
|
ui->elseActionsList->SetVisibilityCheckEnable(false);
|
||||||
|
|
||||||
for (; afterIdx < actions.size(); afterIdx++) {
|
for (; afterIdx < actions.size(); afterIdx++) {
|
||||||
auto newEntry = new MacroActionEdit(this, &actions[afterIdx]);
|
auto newEntry = new MacroActionEdit(this, &actions[afterIdx],
|
||||||
|
actions[afterIdx]->GetId());
|
||||||
ui->elseActionsList->Add(newEntry);
|
ui->elseActionsList->Add(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +472,8 @@ void MacroEdit::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
|
|||||||
|
|
||||||
for (; afterIdx < conditions.size(); afterIdx++) {
|
for (; afterIdx < conditions.size(); afterIdx++) {
|
||||||
auto newEntry = new MacroConditionEdit(
|
auto newEntry = new MacroConditionEdit(
|
||||||
this, &conditions[afterIdx], root);
|
this, &conditions[afterIdx],
|
||||||
|
conditions[afterIdx]->GetId(), root);
|
||||||
ui->conditionsList->Add(newEntry);
|
ui->conditionsList->Add(newEntry);
|
||||||
root = false;
|
root = false;
|
||||||
}
|
}
|
||||||
@@ -1080,7 +1083,8 @@ void MacroEdit::AddMacroAction(Macro *macro, int idx, const std::string &id,
|
|||||||
RunAndClearPostLoadSteps();
|
RunAndClearPostLoadSteps();
|
||||||
macro->UpdateActionIndices();
|
macro->UpdateActionIndices();
|
||||||
ui->actionsList->Insert(
|
ui->actionsList->Insert(
|
||||||
idx, new MacroActionEdit(this, ¯o->Actions()[idx]));
|
idx,
|
||||||
|
new MacroActionEdit(this, ¯o->Actions()[idx], id));
|
||||||
SetActionData(*macro);
|
SetActionData(*macro);
|
||||||
}
|
}
|
||||||
HighlightAction(idx);
|
HighlightAction(idx);
|
||||||
@@ -1382,8 +1386,8 @@ void MacroEdit::AddMacroElseAction(Macro *macro, int idx, const std::string &id,
|
|||||||
RunAndClearPostLoadSteps();
|
RunAndClearPostLoadSteps();
|
||||||
macro->UpdateElseActionIndices();
|
macro->UpdateElseActionIndices();
|
||||||
ui->elseActionsList->Insert(
|
ui->elseActionsList->Insert(
|
||||||
idx,
|
idx, new MacroActionEdit(
|
||||||
new MacroActionEdit(this, ¯o->ElseActions()[idx]));
|
this, ¯o->ElseActions()[idx], id));
|
||||||
SetElseActionData(*macro);
|
SetElseActionData(*macro);
|
||||||
}
|
}
|
||||||
HighlightElseAction(idx);
|
HighlightElseAction(idx);
|
||||||
@@ -1585,7 +1589,7 @@ void MacroEdit::AddMacroCondition(Macro *macro, int idx, const std::string &id,
|
|||||||
ui->conditionsList->Insert(
|
ui->conditionsList->Insert(
|
||||||
idx,
|
idx,
|
||||||
new MacroConditionEdit(this, ¯o->Conditions()[idx],
|
new MacroConditionEdit(this, ¯o->Conditions()[idx],
|
||||||
idx == 0));
|
id, idx == 0));
|
||||||
SetConditionData(*macro);
|
SetConditionData(*macro);
|
||||||
}
|
}
|
||||||
HighlightCondition(idx);
|
HighlightCondition(idx);
|
||||||
|
|||||||
@@ -63,33 +63,6 @@ std::deque<std::shared_ptr<Macro>> GetAllMacros()
|
|||||||
return macros;
|
return macros;
|
||||||
}
|
}
|
||||||
|
|
||||||
Macro *GetMacroByName(const char *name)
|
|
||||||
{
|
|
||||||
for (const auto &m : GetTopLevelMacros()) {
|
|
||||||
if (m->Name() == name) {
|
|
||||||
return m.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Macro *GetMacroByQString(const QString &name)
|
|
||||||
{
|
|
||||||
return GetMacroByName(name.toUtf8().constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
|
|
||||||
{
|
|
||||||
for (const auto &m : GetTopLevelMacros()) {
|
|
||||||
if (m->Name() == name) {
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::deque<std::shared_ptr<MacroAction>>>
|
std::optional<std::deque<std::shared_ptr<MacroAction>>>
|
||||||
GetMacroActions(Macro *macro)
|
GetMacroActions(Macro *macro)
|
||||||
{
|
{
|
||||||
@@ -117,32 +90,9 @@ GetMacroConditions(Macro *macro)
|
|||||||
return macro->Conditions();
|
return macro->Conditions();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsGroupMacro(Macro *macro)
|
std::string_view GetSceneSwitchActionId()
|
||||||
{
|
{
|
||||||
return macro && macro->IsGroup();
|
return MacroAction::GetDefaultID();
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Macro>> GetGroupMacroEntries(Macro *macro)
|
|
||||||
{
|
|
||||||
if (!macro || !macro->IsGroup()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Macro>> entries;
|
|
||||||
entries.reserve(macro->GroupSize());
|
|
||||||
|
|
||||||
const auto ¯os = GetTopLevelMacros();
|
|
||||||
for (auto it = macros.begin(); it < macros.end(); it++) {
|
|
||||||
if ((*it)->Name() != macro->Name()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (uint32_t i = 1; i <= macro->GroupSize(); i++) {
|
|
||||||
entries.emplace_back(*std::next(it, i));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return entries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::condition_variable &GetMacroWaitCV()
|
std::condition_variable &GetMacroWaitCV()
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "export-symbol-helper.hpp"
|
#include "export-symbol-helper.hpp"
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -20,16 +18,10 @@ class Macro;
|
|||||||
class MacroAction;
|
class MacroAction;
|
||||||
class MacroCondition;
|
class MacroCondition;
|
||||||
|
|
||||||
static const int macro_func = 10;
|
|
||||||
|
|
||||||
EXPORT std::deque<std::shared_ptr<Macro>> &GetTopLevelMacros();
|
EXPORT std::deque<std::shared_ptr<Macro>> &GetTopLevelMacros();
|
||||||
std::deque<std::shared_ptr<Macro>> &GetTemporaryMacros();
|
std::deque<std::shared_ptr<Macro>> &GetTemporaryMacros();
|
||||||
EXPORT std::deque<std::shared_ptr<Macro>> GetAllMacros();
|
EXPORT std::deque<std::shared_ptr<Macro>> GetAllMacros();
|
||||||
|
|
||||||
Macro *GetMacroByName(const char *name);
|
|
||||||
Macro *GetMacroByQString(const QString &name);
|
|
||||||
std::weak_ptr<Macro> GetWeakMacroByName(const char *name);
|
|
||||||
|
|
||||||
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>>>
|
EXPORT std::optional<std::deque<std::shared_ptr<MacroAction>>>
|
||||||
@@ -37,8 +29,9 @@ GetMacroElseActions(Macro *);
|
|||||||
EXPORT std::optional<std::deque<std::shared_ptr<MacroCondition>>>
|
EXPORT std::optional<std::deque<std::shared_ptr<MacroCondition>>>
|
||||||
GetMacroConditions(Macro *);
|
GetMacroConditions(Macro *);
|
||||||
|
|
||||||
EXPORT bool IsGroupMacro(Macro *);
|
std::string_view GetSceneSwitchActionId();
|
||||||
EXPORT std::vector<std::shared_ptr<Macro>> GetGroupMacroEntries(Macro *);
|
|
||||||
|
constexpr auto macro_func = 10;
|
||||||
|
|
||||||
EXPORT std::condition_variable &GetMacroWaitCV();
|
EXPORT std::condition_variable &GetMacroWaitCV();
|
||||||
EXPORT std::condition_variable &GetMacroTransitionCV();
|
EXPORT std::condition_variable &GetMacroTransitionCV();
|
||||||
|
|||||||
@@ -1,323 +0,0 @@
|
|||||||
#include "macro-search.hpp"
|
|
||||||
#include "layout-helpers.hpp"
|
|
||||||
#include "macro.hpp"
|
|
||||||
#include "macro-action-factory.hpp"
|
|
||||||
#include "macro-condition-factory.hpp"
|
|
||||||
#include "macro-helpers.hpp"
|
|
||||||
#include "macro-signals.hpp"
|
|
||||||
#include "plugin-state-helpers.hpp"
|
|
||||||
#include "ui-helpers.hpp"
|
|
||||||
|
|
||||||
#include <obs.hpp>
|
|
||||||
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <QLayout>
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
static bool searchEnabled = false;
|
|
||||||
static bool setup();
|
|
||||||
static bool setupDone = setup();
|
|
||||||
|
|
||||||
static QLayout *searchLayout = nullptr;
|
|
||||||
static QComboBox *searchType = nullptr;
|
|
||||||
static RegexConfigWidget *searchRegex = nullptr;
|
|
||||||
static QPushButton *showSettings = nullptr;
|
|
||||||
static std::function<void()> refreshFilter;
|
|
||||||
|
|
||||||
static void save(obs_data_t *data)
|
|
||||||
{
|
|
||||||
GetMacroSearchSettings().Save(data, "macroSearchSettings");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void load(obs_data_t *data)
|
|
||||||
{
|
|
||||||
GetMacroSearchSettings().Load(data, "macroSearchSettings");
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool setup()
|
|
||||||
{
|
|
||||||
AddSaveStep(save);
|
|
||||||
AddLoadStep(load);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroSearchSettings::Save(obs_data_t *data, const char *name)
|
|
||||||
{
|
|
||||||
OBSDataAutoRelease settings = obs_data_create();
|
|
||||||
obs_data_set_bool(settings, "showAlways", showAlways);
|
|
||||||
obs_data_set_int(settings, "searchType", static_cast<int>(searchType));
|
|
||||||
obs_data_set_string(settings, "searchString", searchString.c_str());
|
|
||||||
regex.Save(settings);
|
|
||||||
obs_data_set_obj(data, name, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroSearchSettings::Load(obs_data_t *data, const char *name)
|
|
||||||
{
|
|
||||||
OBSDataAutoRelease settings = obs_data_get_obj(data, name);
|
|
||||||
showAlways = obs_data_get_bool(settings, "showAlways");
|
|
||||||
searchType = static_cast<SearchType>(
|
|
||||||
obs_data_get_int(settings, "searchType"));
|
|
||||||
searchString = obs_data_get_string(settings, "searchString");
|
|
||||||
regex.Load(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void showAdvancedSearchSettings(bool show)
|
|
||||||
{
|
|
||||||
assert(searchType);
|
|
||||||
assert(searchRegex);
|
|
||||||
|
|
||||||
searchType->setVisible(show);
|
|
||||||
searchRegex->setVisible(show);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool shouldShowSearch()
|
|
||||||
{
|
|
||||||
static const int showSearchThreshold = 10;
|
|
||||||
return GetMacroSearchSettings().showAlways ||
|
|
||||||
GetTopLevelMacros().size() >= showSearchThreshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckMacroSearchVisibility()
|
|
||||||
{
|
|
||||||
assert(searchLayout);
|
|
||||||
assert(searchType);
|
|
||||||
assert(searchRegex);
|
|
||||||
assert(showSettings);
|
|
||||||
|
|
||||||
searchEnabled = shouldShowSearch();
|
|
||||||
SetLayoutVisible(searchLayout, searchEnabled);
|
|
||||||
showAdvancedSearchSettings(false);
|
|
||||||
showSettings->setChecked(false);
|
|
||||||
refreshFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupMacroSearchWidgets(QLayout *searchLayoutArg, QLineEdit *searchText,
|
|
||||||
QPushButton *searchClear, QComboBox *searchTypeArg,
|
|
||||||
RegexConfigWidget *searchRegexArg,
|
|
||||||
QPushButton *showSettingsArg,
|
|
||||||
const std::function<void()> &refreshArg)
|
|
||||||
{
|
|
||||||
searchLayout = searchLayoutArg;
|
|
||||||
searchType = searchTypeArg;
|
|
||||||
searchRegex = searchRegexArg;
|
|
||||||
refreshFilter = refreshArg;
|
|
||||||
showSettings = showSettingsArg;
|
|
||||||
|
|
||||||
searchClear->setMaximumWidth(22);
|
|
||||||
SetButtonIcon(searchClear, GetThemeTypeName() == "Light"
|
|
||||||
? "theme:Light/close.svg"
|
|
||||||
: "theme:Dark/close.svg");
|
|
||||||
searchClear->setDisabled(GetMacroSearchSettings().searchString.empty());
|
|
||||||
|
|
||||||
QWidget::connect(searchClear, &QPushButton::clicked, searchClear,
|
|
||||||
[=]() {
|
|
||||||
searchText->setText("");
|
|
||||||
searchClear->setDisabled(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto ph = searchText->placeholderText();
|
|
||||||
const QFontMetrics fm(searchText->font());
|
|
||||||
const int width = fm.horizontalAdvance(ph);
|
|
||||||
// Add a little padding so the text isn't cramped
|
|
||||||
searchText->setMinimumWidth(width + 10);
|
|
||||||
|
|
||||||
searchText->setText(
|
|
||||||
QString::fromStdString(GetMacroSearchSettings().searchString));
|
|
||||||
QWidget::connect(searchText, &QLineEdit::textChanged, searchText,
|
|
||||||
[searchClear](const QString &text) {
|
|
||||||
GetMacroSearchSettings().searchString =
|
|
||||||
text.toStdString();
|
|
||||||
searchClear->setDisabled(text.isEmpty());
|
|
||||||
refreshFilter();
|
|
||||||
});
|
|
||||||
|
|
||||||
searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.search.name"),
|
|
||||||
static_cast<int>(MacroSearchSettings::SearchType::NAME));
|
|
||||||
searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.search.allSegments"),
|
|
||||||
static_cast<int>(
|
|
||||||
MacroSearchSettings::SearchType::ALL_SEGMENTS));
|
|
||||||
searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.search.conditions"),
|
|
||||||
static_cast<int>(MacroSearchSettings::SearchType::CONDITIONS));
|
|
||||||
searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.search.actions"),
|
|
||||||
static_cast<int>(MacroSearchSettings::SearchType::ACTIONS));
|
|
||||||
searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.search.label"),
|
|
||||||
static_cast<int>(MacroSearchSettings::SearchType::LABEL));
|
|
||||||
searchType->setCurrentIndex(searchType->findData(
|
|
||||||
static_cast<int>(GetMacroSearchSettings().searchType)));
|
|
||||||
QWidget::connect(
|
|
||||||
searchType, &QComboBox::currentIndexChanged, searchType, []() {
|
|
||||||
GetMacroSearchSettings().searchType =
|
|
||||||
static_cast<MacroSearchSettings::SearchType>(
|
|
||||||
searchType->currentData().toInt());
|
|
||||||
refreshFilter();
|
|
||||||
});
|
|
||||||
|
|
||||||
searchRegex->SetRegexConfig(GetMacroSearchSettings().regex);
|
|
||||||
QWidget::connect(searchRegex, &RegexConfigWidget::RegexConfigChanged,
|
|
||||||
searchRegex, [](const RegexConfig ®ex) {
|
|
||||||
GetMacroSearchSettings().regex = regex;
|
|
||||||
refreshFilter();
|
|
||||||
});
|
|
||||||
|
|
||||||
showSettings->setCheckable(true);
|
|
||||||
showSettings->setMaximumWidth(11);
|
|
||||||
SetButtonIcon(showSettings, GetThemeTypeName() == "Light"
|
|
||||||
? ":/res/images/dots-vert.svg"
|
|
||||||
: "theme:Dark/dots-vert.svg");
|
|
||||||
QWidget::connect(showSettings, &QPushButton::toggled, showSettings,
|
|
||||||
showAdvancedSearchSettings);
|
|
||||||
|
|
||||||
QWidget::connect(MacroSignalManager::Instance(),
|
|
||||||
&MacroSignalManager::Rename, searchText,
|
|
||||||
[]() { refreshFilter(); });
|
|
||||||
|
|
||||||
CheckMacroSearchVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroSearchSettings &GetMacroSearchSettings()
|
|
||||||
{
|
|
||||||
static MacroSearchSettings settings;
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool stringMatches(const std::string &text)
|
|
||||||
{
|
|
||||||
const auto &settings = GetMacroSearchSettings();
|
|
||||||
const auto ®ex = settings.regex;
|
|
||||||
const auto &searchString = settings.searchString;
|
|
||||||
|
|
||||||
if (regex.Enabled()) {
|
|
||||||
return regex.Matches(text, searchString);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QString::fromStdString(text).contains(
|
|
||||||
QString::fromStdString(searchString), Qt::CaseInsensitive);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool segmentTypeMatches(MacroSegment *segment, bool isCondition)
|
|
||||||
{
|
|
||||||
if (!segment) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto getNameFromId =
|
|
||||||
isCondition ? MacroConditionFactory::GetConditionName
|
|
||||||
: MacroActionFactory::GetActionName;
|
|
||||||
const auto name = getNameFromId(segment->GetId());
|
|
||||||
return stringMatches(obs_module_text(name.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool segmentLabelMatches(MacroSegment *segment)
|
|
||||||
{
|
|
||||||
if (!segment) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!segment->GetUseCustomLabel()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto label = segment->GetCustomLabel();
|
|
||||||
return stringMatches(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroMatchesSearchFilter(Macro *macro)
|
|
||||||
{
|
|
||||||
assert(macro);
|
|
||||||
|
|
||||||
if (!searchEnabled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &settings = GetMacroSearchSettings();
|
|
||||||
|
|
||||||
if (settings.searchString.empty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (macro->IsGroup()) {
|
|
||||||
const auto groupEntries = GetGroupMacroEntries(macro);
|
|
||||||
for (const auto &entry : groupEntries) {
|
|
||||||
if (MacroMatchesSearchFilter(entry.get())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (settings.searchType) {
|
|
||||||
case MacroSearchSettings::SearchType::NAME: {
|
|
||||||
const auto name = macro->Name();
|
|
||||||
return stringMatches(name);
|
|
||||||
}
|
|
||||||
case MacroSearchSettings::SearchType::ALL_SEGMENTS:
|
|
||||||
for (const auto &condition : macro->Conditions()) {
|
|
||||||
if (segmentTypeMatches(condition.get(), true)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto &action : macro->Actions()) {
|
|
||||||
if (segmentTypeMatches(action.get(), false)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto &action : macro->ElseActions()) {
|
|
||||||
if (segmentTypeMatches(action.get(), false)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MacroSearchSettings::SearchType::CONDITIONS:
|
|
||||||
for (const auto &condition : macro->Conditions()) {
|
|
||||||
if (segmentTypeMatches(condition.get(), true)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MacroSearchSettings::SearchType::ACTIONS:
|
|
||||||
for (const auto &action : macro->Actions()) {
|
|
||||||
if (segmentTypeMatches(action.get(), false)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto &action : macro->ElseActions()) {
|
|
||||||
if (segmentTypeMatches(action.get(), false)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
case MacroSearchSettings::SearchType::LABEL:
|
|
||||||
for (const auto &condition : macro->Conditions()) {
|
|
||||||
if (segmentLabelMatches(condition.get())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto &action : macro->Actions()) {
|
|
||||||
if (segmentLabelMatches(action.get())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const auto &action : macro->ElseActions()) {
|
|
||||||
if (segmentLabelMatches(action.get())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unhandled search type
|
|
||||||
assert(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "regex-config.hpp"
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class QComboBox;
|
|
||||||
class QLayout;
|
|
||||||
class QLineEdit;
|
|
||||||
class QPushButton;
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
class Macro;
|
|
||||||
|
|
||||||
struct MacroSearchSettings {
|
|
||||||
void Save(obs_data_t *data, const char *name);
|
|
||||||
void Load(obs_data_t *data, const char *name);
|
|
||||||
|
|
||||||
enum class SearchType {
|
|
||||||
NAME = 0,
|
|
||||||
ALL_SEGMENTS = 10,
|
|
||||||
CONDITIONS = 20,
|
|
||||||
ACTIONS = 30,
|
|
||||||
LABEL = 40,
|
|
||||||
};
|
|
||||||
|
|
||||||
SearchType searchType = SearchType::NAME;
|
|
||||||
std::string searchString;
|
|
||||||
RegexConfig regex;
|
|
||||||
bool showAlways = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
void CheckMacroSearchVisibility();
|
|
||||||
void SetupMacroSearchWidgets(QLayout *searchLayout, QLineEdit *searchText,
|
|
||||||
QPushButton *searchClear, QComboBox *searchType,
|
|
||||||
RegexConfigWidget *searchRegex,
|
|
||||||
QPushButton *showSettings,
|
|
||||||
const std::function<void()> &refresh);
|
|
||||||
MacroSearchSettings &GetMacroSearchSettings();
|
|
||||||
bool MacroMatchesSearchFilter(Macro *macro);
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -15,6 +15,9 @@ MacroSelection::MacroSelection(QWidget *parent)
|
|||||||
obs_module_text("AdvSceneSwitcher.selectMacro"))
|
obs_module_text("AdvSceneSwitcher.selectMacro"))
|
||||||
{
|
{
|
||||||
for (const auto &m : GetTopLevelMacros()) {
|
for (const auto &m : GetTopLevelMacros()) {
|
||||||
|
if (m->IsGroup()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
addItem(QString::fromStdString(m->Name()));
|
addItem(QString::fromStdString(m->Name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,22 +66,6 @@ void MacroSelection::HideSelectedMacro()
|
|||||||
qobject_cast<QListView *>(view())->setRowHidden(idx, true);
|
qobject_cast<QListView *>(view())->setRowHidden(idx, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroSelection::HideGroups()
|
|
||||||
{
|
|
||||||
for (const auto ¯o : GetTopLevelMacros()) {
|
|
||||||
if (!macro->IsGroup()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx = findText(QString::fromStdString(macro->Name()));
|
|
||||||
if (idx == -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
qobject_cast<QListView *>(view())->setRowHidden(idx, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroSelection::ShowAllMacros()
|
void MacroSelection::ShowAllMacros()
|
||||||
{
|
{
|
||||||
auto v = qobject_cast<QListView *>(view());
|
auto v = qobject_cast<QListView *>(view());
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ public:
|
|||||||
MacroSelection(QWidget *parent);
|
MacroSelection(QWidget *parent);
|
||||||
void SetCurrentMacro(const MacroRef &);
|
void SetCurrentMacro(const MacroRef &);
|
||||||
void HideSelectedMacro(); // Macro currently being edited
|
void HideSelectedMacro(); // Macro currently being edited
|
||||||
void HideGroups();
|
|
||||||
void ShowAllMacros();
|
void ShowAllMacros();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "macro-condition-edit.hpp"
|
#include "macro-condition-edit.hpp"
|
||||||
#include "macro-export-import-dialog.hpp"
|
#include "macro-export-import-dialog.hpp"
|
||||||
#include "macro-settings.hpp"
|
#include "macro-settings.hpp"
|
||||||
#include "macro-search.hpp"
|
|
||||||
#include "macro-signals.hpp"
|
#include "macro-signals.hpp"
|
||||||
#include "macro-tree.hpp"
|
#include "macro-tree.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
@@ -147,7 +146,20 @@ void AdvSceneSwitcher::on_macroAdd_clicked()
|
|||||||
static void addGroupSubitems(std::vector<std::shared_ptr<Macro>> ¯os,
|
static void addGroupSubitems(std::vector<std::shared_ptr<Macro>> ¯os,
|
||||||
const std::shared_ptr<Macro> &group)
|
const std::shared_ptr<Macro> &group)
|
||||||
{
|
{
|
||||||
auto subitems = GetGroupMacroEntries(group.get());
|
std::vector<std::shared_ptr<Macro>> subitems;
|
||||||
|
subitems.reserve(group->GroupSize());
|
||||||
|
|
||||||
|
// Find all subitems
|
||||||
|
auto allMacros = GetTopLevelMacros();
|
||||||
|
for (auto it = allMacros.begin(); it < allMacros.end(); it++) {
|
||||||
|
if ((*it)->Name() != group->Name()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 1; i <= group->GroupSize(); i++) {
|
||||||
|
subitems.emplace_back(*std::next(it, i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove subitems which were already selected to avoid duplicates
|
// Remove subitems which were already selected to avoid duplicates
|
||||||
for (const auto &subitem : subitems) {
|
for (const auto &subitem : subitems) {
|
||||||
@@ -195,7 +207,7 @@ void AdvSceneSwitcher::RemoveMacro(std::shared_ptr<Macro> ¯o)
|
|||||||
// Don't cache widgets for about to be deleted macros
|
// Don't cache widgets for about to be deleted macros
|
||||||
MacroSegmentList::SetCachingEnabled(false);
|
MacroSegmentList::SetCachingEnabled(false);
|
||||||
ui->macros->Remove(macro);
|
ui->macros->Remove(macro);
|
||||||
MacroSegmentList::SetCachingEnabled(true);
|
MacroSegmentList::SetCachingEnabled(!switcher->disableMacroWidgetCache);
|
||||||
|
|
||||||
MacroSignalManager::Instance()->Remove(name);
|
MacroSignalManager::Instance()->Remove(name);
|
||||||
}
|
}
|
||||||
@@ -603,20 +615,17 @@ setupToolBar(const std::initializer_list<std::initializer_list<QWidget *>>
|
|||||||
auto toolbar = new QToolBar();
|
auto toolbar = new QToolBar();
|
||||||
toolbar->setIconSize({16, 16});
|
toolbar->setIconSize({16, 16});
|
||||||
|
|
||||||
QAction *lastSeparator = nullptr;
|
QAction *lastSeperator = nullptr;
|
||||||
|
|
||||||
for (const auto &widgetGroup : widgetGroups) {
|
for (const auto &widgetGroup : widgetGroups) {
|
||||||
for (const auto &widget : widgetGroup) {
|
for (const auto &widget : widgetGroup) {
|
||||||
if (!widget) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
toolbar->addWidget(widget);
|
toolbar->addWidget(widget);
|
||||||
}
|
}
|
||||||
lastSeparator = toolbar->addSeparator();
|
lastSeperator = toolbar->addSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastSeparator) {
|
if (lastSeperator) {
|
||||||
toolbar->removeAction(lastSeparator);
|
toolbar->removeAction(lastSeperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent "extension" button from showing up
|
// Prevent "extension" button from showing up
|
||||||
@@ -629,9 +638,7 @@ void AdvSceneSwitcher::SetupMacroTab()
|
|||||||
{
|
{
|
||||||
ui->macros->installEventFilter(this);
|
ui->macros->installEventFilter(this);
|
||||||
|
|
||||||
auto ¯os = GetTopLevelMacros();
|
if (GetTopLevelMacros().size() == 0 && !switcher->disableHints) {
|
||||||
|
|
||||||
if (macros.size() == 0 && !switcher->disableHints) {
|
|
||||||
addPulse = HighlightWidget(ui->macroAdd, QColor(Qt::green));
|
addPulse = HighlightWidget(ui->macroAdd, QColor(Qt::green));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,7 +646,8 @@ void AdvSceneSwitcher::SetupMacroTab()
|
|||||||
{ui->macroUp, ui->macroDown}});
|
{ui->macroUp, ui->macroDown}});
|
||||||
ui->macroControlLayout->addWidget(macroControls);
|
ui->macroControlLayout->addWidget(macroControls);
|
||||||
|
|
||||||
ui->macros->Reset(macros, GetGlobalMacroSettings()._highlightExecuted);
|
ui->macros->Reset(GetTopLevelMacros(),
|
||||||
|
GetGlobalMacroSettings()._highlightExecuted);
|
||||||
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
|
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
|
||||||
SLOT(MacroSelectionChanged()));
|
SLOT(MacroSelectionChanged()));
|
||||||
ui->runMacro->SetMacroTree(ui->macros);
|
ui->runMacro->SetMacroTree(ui->macros);
|
||||||
@@ -668,12 +676,6 @@ void AdvSceneSwitcher::SetupMacroTab()
|
|||||||
switcher->macroListMacroEditSplitterPosition);
|
switcher->macroListMacroEditSplitterPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupMacroSearchWidgets(ui->macroSearchLayout, ui->macroSearchText,
|
|
||||||
ui->macroSearchClear, ui->macroSearchType,
|
|
||||||
ui->macroSearchRegex,
|
|
||||||
ui->macroSearchShowSettings,
|
|
||||||
[this]() { ui->macros->RefreshFilter(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos)
|
void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "macro-tree.hpp"
|
#include "macro-tree.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "macro-search.hpp"
|
|
||||||
#include "macro-signals.hpp"
|
#include "macro-signals.hpp"
|
||||||
#include "path-helpers.hpp"
|
#include "path-helpers.hpp"
|
||||||
#include "sync-helpers.hpp"
|
#include "sync-helpers.hpp"
|
||||||
@@ -784,8 +783,7 @@ void MacroTree::Reset(std::deque<std::shared_ptr<Macro>> ¯os,
|
|||||||
bool highlight)
|
bool highlight)
|
||||||
{
|
{
|
||||||
_highlight = highlight;
|
_highlight = highlight;
|
||||||
|
MacroTreeModel *mtm = new MacroTreeModel(this, macros);
|
||||||
auto mtm = new MacroTreeModel(this, macros);
|
|
||||||
setModel(mtm);
|
setModel(mtm);
|
||||||
GetModel()->Reset(macros);
|
GetModel()->Reset(macros);
|
||||||
connect(selectionModel(),
|
connect(selectionModel(),
|
||||||
@@ -871,7 +869,7 @@ void MacroTree::UpdateWidgets(bool force)
|
|||||||
|
|
||||||
for (int i = 0; i < (int)mtm->_macros.size(); i++) {
|
for (int i = 0; i < (int)mtm->_macros.size(); i++) {
|
||||||
std::shared_ptr<Macro> item = mtm->_macros[i];
|
std::shared_ptr<Macro> item = mtm->_macros[i];
|
||||||
auto widget = GetItemWidget(i);
|
MacroTreeItem *widget = GetItemWidget(i);
|
||||||
|
|
||||||
if (!widget) {
|
if (!widget) {
|
||||||
UpdateWidget(mtm->createIndex(i, 0, nullptr), item);
|
UpdateWidget(mtm->createIndex(i, 0, nullptr), item);
|
||||||
@@ -1206,12 +1204,6 @@ void MacroTree::CollapseGroup(std::shared_ptr<Macro> item) const
|
|||||||
mtm->CollapseGroup(item);
|
mtm->CollapseGroup(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroTree::RefreshFilter()
|
|
||||||
{
|
|
||||||
UpdateWidgets();
|
|
||||||
doItemsLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroTree::MoveItemBefore(const std::shared_ptr<Macro> &item,
|
void MacroTree::MoveItemBefore(const std::shared_ptr<Macro> &item,
|
||||||
const std::shared_ptr<Macro> &after) const
|
const std::shared_ptr<Macro> &after) const
|
||||||
{
|
{
|
||||||
@@ -1226,7 +1218,7 @@ void MacroTree::MoveItemAfter(const std::shared_ptr<Macro> &item,
|
|||||||
|
|
||||||
MacroTreeModel *MacroTree::GetModel() const
|
MacroTreeModel *MacroTree::GetModel() const
|
||||||
{
|
{
|
||||||
return qobject_cast<MacroTreeModel *>(model());
|
return reinterpret_cast<MacroTreeModel *>(model());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroTree::Remove(std::shared_ptr<Macro> item) const
|
void MacroTree::Remove(std::shared_ptr<Macro> item) const
|
||||||
@@ -1341,8 +1333,8 @@ void MacroTree::SelectionChangedHelper(const QItemSelection &,
|
|||||||
|
|
||||||
inline MacroTreeItem *MacroTree::GetItemWidget(int idx) const
|
inline MacroTreeItem *MacroTree::GetItemWidget(int idx) const
|
||||||
{
|
{
|
||||||
auto widget = indexWidget(GetModel()->createIndex(idx, 0, nullptr));
|
QWidget *widget = indexWidget(GetModel()->createIndex(idx, 0, nullptr));
|
||||||
return qobject_cast<MacroTreeItem *>(widget);
|
return reinterpret_cast<MacroTreeItem *>(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroTree::paintEvent(QPaintEvent *event)
|
void MacroTree::paintEvent(QPaintEvent *event)
|
||||||
@@ -1369,25 +1361,14 @@ MacroTreeDelegate::MacroTreeDelegate(QObject *parent)
|
|||||||
QSize MacroTreeDelegate::sizeHint(const QStyleOptionViewItem &option,
|
QSize MacroTreeDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const
|
const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
auto tree = qobject_cast<MacroTree *>(parent());
|
MacroTree *tree = qobject_cast<MacroTree *>(parent());
|
||||||
auto widget = tree->indexWidget(index);
|
QWidget *item = tree->indexWidget(index);
|
||||||
|
|
||||||
if (!widget) {
|
if (!item) {
|
||||||
return QStyledItemDelegate::sizeHint(option, index);
|
return QStyledItemDelegate::sizeHint(option, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = index.data(Qt::AccessibleTextRole).toString();
|
return QSize(item->sizeHint());
|
||||||
auto macro = GetMacroByQString(name);
|
|
||||||
|
|
||||||
if (!macro) {
|
|
||||||
return QStyledItemDelegate::sizeHint(option, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MacroMatchesSearchFilter(macro)) {
|
|
||||||
return QSize(widget->sizeHint());
|
|
||||||
}
|
|
||||||
|
|
||||||
return QSize(0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ public:
|
|||||||
bool GroupsExist() const;
|
bool GroupsExist() const;
|
||||||
void ExpandGroup(std::shared_ptr<Macro> item) const;
|
void ExpandGroup(std::shared_ptr<Macro> item) const;
|
||||||
void CollapseGroup(std::shared_ptr<Macro> item) const;
|
void CollapseGroup(std::shared_ptr<Macro> item) const;
|
||||||
void RefreshFilter();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void GroupSelectedItems();
|
void GroupSelectedItems();
|
||||||
|
|||||||
@@ -948,12 +948,12 @@ bool Macro::PostLoad()
|
|||||||
bool Macro::SwitchesScene() const
|
bool Macro::SwitchesScene() const
|
||||||
{
|
{
|
||||||
for (const auto &a : _actions) {
|
for (const auto &a : _actions) {
|
||||||
if (a->GetId() == MacroAction::GetDefaultID()) {
|
if (a->GetId() == GetSceneSwitchActionId()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &a : _elseActions) {
|
for (const auto &a : _elseActions) {
|
||||||
if (a->GetId() == MacroAction::GetDefaultID()) {
|
if (a->GetId() == GetSceneSwitchActionId()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1255,6 +1255,33 @@ void StopAllMacros()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Macro *GetMacroByName(const char *name)
|
||||||
|
{
|
||||||
|
for (const auto &m : GetTopLevelMacros()) {
|
||||||
|
if (m->Name() == name) {
|
||||||
|
return m.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Macro *GetMacroByQString(const QString &name)
|
||||||
|
{
|
||||||
|
return GetMacroByName(name.toUtf8().constData());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
|
||||||
|
{
|
||||||
|
for (const auto &m : GetTopLevelMacros()) {
|
||||||
|
if (m->Name() == name) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void InvalidateMacroTempVarValues()
|
void InvalidateMacroTempVarValues()
|
||||||
{
|
{
|
||||||
for (const auto &m : GetTopLevelMacros()) {
|
for (const auto &m : GetTopLevelMacros()) {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include "temp-variable.hpp"
|
#include "temp-variable.hpp"
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
|
#include <QString>
|
||||||
|
#include <QByteArray>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -218,6 +220,9 @@ void SaveMacros(obs_data_t *obj);
|
|||||||
bool CheckMacros();
|
bool CheckMacros();
|
||||||
bool RunMacros();
|
bool RunMacros();
|
||||||
void StopAllMacros();
|
void StopAllMacros();
|
||||||
|
Macro *GetMacroByName(const char *name);
|
||||||
|
Macro *GetMacroByQString(const QString &name);
|
||||||
|
std::weak_ptr<Macro> GetWeakMacroByName(const char *name);
|
||||||
void InvalidateMacroTempVarValues();
|
void InvalidateMacroTempVarValues();
|
||||||
std::shared_ptr<Macro> GetMacroWithInvalidConditionInterval();
|
std::shared_ptr<Macro> GetMacroWithInvalidConditionInterval();
|
||||||
|
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ bool IsFullscreen(const std::string &title)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> GetTextInWindow(const std::string &)
|
std::optional<std::string> GetTextInWindow(const std::string &window)
|
||||||
{
|
{
|
||||||
// Not implemented
|
// Not implemented
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ void ImportQueues(obs_data_t *data)
|
|||||||
importedQueues->emplace_back(queue);
|
importedQueues->emplace_back(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueUITask(signalImportedQueues, importedQueues);
|
QeueUITask(signalImportedQueues, importedQueues);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::weak_ptr<ActionQueue> GetWeakActionQueueByName(const std::string &name)
|
std::weak_ptr<ActionQueue> GetWeakActionQueueByName(const std::string &name)
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ public:
|
|||||||
bool warnPluginLoadFailure = true;
|
bool warnPluginLoadFailure = true;
|
||||||
bool disableHints = false;
|
bool disableHints = false;
|
||||||
bool disableFilterComboboxFilter = false;
|
bool disableFilterComboboxFilter = false;
|
||||||
|
bool disableMacroWidgetCache = false;
|
||||||
bool hideLegacyTabs = true;
|
bool hideLegacyTabs = true;
|
||||||
bool saveWindowGeo = false;
|
bool saveWindowGeo = false;
|
||||||
QPoint windowPos = {};
|
QPoint windowPos = {};
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ int GetCanvasCount()
|
|||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
static const auto enumCanvases = [](void *countPtr,
|
static const auto enumCanvases = [](void *countPtr,
|
||||||
obs_canvas_t *) -> bool {
|
obs_canvas_t *canvas) -> bool {
|
||||||
auto count = static_cast<int *>(countPtr);
|
auto count = static_cast<int *>(countPtr);
|
||||||
(*count)++;
|
(*count)++;
|
||||||
return true;
|
return true;
|
||||||
@@ -145,15 +145,6 @@ OBSWeakSource GetActiveCanvasScene(const OBSWeakCanvas &weakCanvas)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
|
||||||
|
|
||||||
// The frontend scene order does not necessarily match the order of the
|
|
||||||
// scenes in the canvas.
|
|
||||||
if (canvas == mainCanvas) {
|
|
||||||
OBSSourceAutoRelease scene = obs_frontend_get_current_scene();
|
|
||||||
return OBSGetWeakRef(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const auto enumCanvasScenes = [](void *scenePtr,
|
static const auto enumCanvasScenes = [](void *scenePtr,
|
||||||
obs_source_t *source) -> bool {
|
obs_source_t *source) -> bool {
|
||||||
auto scene = static_cast<OBSWeakSource *>(scenePtr);
|
auto scene = static_cast<OBSWeakSource *>(scenePtr);
|
||||||
@@ -190,25 +181,6 @@ OBSWeakSource GetSceneAtIndex(const OBSWeakCanvas &weakCanvas, int idx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
|
||||||
|
|
||||||
// The frontend scene order does not necessarily match the order of the
|
|
||||||
// scenes in the canvas.
|
|
||||||
// So, rely on obs_frontend_get_scenes() in case of the main canvas
|
|
||||||
// instead.
|
|
||||||
if (canvas == mainCanvas) {
|
|
||||||
struct obs_frontend_source_list scenes = {0};
|
|
||||||
obs_frontend_get_scenes(&scenes);
|
|
||||||
if (idx >= (int)scenes.sources.num) {
|
|
||||||
obs_frontend_source_list_free(&scenes);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto scene = OBSGetWeakRef(scenes.sources.array[idx]);
|
|
||||||
obs_frontend_source_list_free(&scenes);
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
const int idx;
|
const int idx;
|
||||||
int currentIdx;
|
int currentIdx;
|
||||||
@@ -251,29 +223,6 @@ int GetIndexOfScene(const OBSWeakCanvas &weakCanvas, const OBSWeakSource &scene)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
|
||||||
|
|
||||||
// The frontend scene order does not necessarily match the order of the
|
|
||||||
// scenes in the canvas.
|
|
||||||
// So, rely on obs_frontend_get_scenes() in case of the main canvas
|
|
||||||
// instead.
|
|
||||||
if (canvas == mainCanvas) {
|
|
||||||
struct obs_frontend_source_list scenes = {0};
|
|
||||||
obs_frontend_get_scenes(&scenes);
|
|
||||||
|
|
||||||
OBSSourceAutoRelease sceneSource = OBSGetStrongRef(scene);
|
|
||||||
int idx = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < scenes.sources.num; i++) {
|
|
||||||
if (scenes.sources.array[i] == sceneSource) {
|
|
||||||
idx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_frontend_source_list_free(&scenes);
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
int idx;
|
int idx;
|
||||||
@@ -297,12 +246,6 @@ int GetIndexOfScene(const OBSWeakCanvas &weakCanvas, const OBSWeakSource &scene)
|
|||||||
return data.idx;
|
return data.idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSWeakCanvas GetMainCanvas()
|
|
||||||
{
|
|
||||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
|
||||||
return OBSGetWeakRef(mainCanvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||||
|
|
||||||
obs_canvas_t *obs_canvas_get_ref(obs_canvas_t *)
|
obs_canvas_t *obs_canvas_get_ref(obs_canvas_t *)
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ EXPORT OBSWeakSource GetActiveCanvasScene(const OBSWeakCanvas &canvas);
|
|||||||
EXPORT OBSWeakSource GetSceneAtIndex(const OBSWeakCanvas &weakCanvas, int idx);
|
EXPORT OBSWeakSource GetSceneAtIndex(const OBSWeakCanvas &weakCanvas, int idx);
|
||||||
EXPORT int GetIndexOfScene(const OBSWeakCanvas &weakCanvas,
|
EXPORT int GetIndexOfScene(const OBSWeakCanvas &weakCanvas,
|
||||||
const OBSWeakSource &scene);
|
const OBSWeakSource &scene);
|
||||||
EXPORT OBSWeakCanvas GetMainCanvas();
|
|
||||||
|
|
||||||
class CanvasSelection : public FilterComboBox {
|
class CanvasSelection : public FilterComboBox {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ std::optional<double> GetDouble(const std::string &str)
|
|||||||
std::optional<int> GetInt(const std::string &str)
|
std::optional<int> GetInt(const std::string &str)
|
||||||
{
|
{
|
||||||
char *end = nullptr;
|
char *end = nullptr;
|
||||||
int value = (int)std::strtol(str.c_str(), &end, 10);
|
int value = std::strtol(str.c_str(), &end, 10);
|
||||||
|
|
||||||
if (end != str.c_str() && *end == '\0' && value != INT_MAX &&
|
if (end != str.c_str() && *end == '\0' && value != INT_MAX &&
|
||||||
value != INT_MIN) {
|
value != INT_MIN) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
ResourceTable::ResourceTable(QWidget *parent, const QString &help,
|
ResourceTable::ResourceTable(QTabWidget *parent, const QString &help,
|
||||||
const QString &addToolTip,
|
const QString &addToolTip,
|
||||||
const QString &removeToolTip,
|
const QString &removeToolTip,
|
||||||
const QStringList &headers,
|
const QStringList &headers,
|
||||||
@@ -65,16 +65,13 @@ ResourceTable::ResourceTable(QWidget *parent, const QString &help,
|
|||||||
[openSettings]() { openSettings(); });
|
[openSettings]() { openSettings(); });
|
||||||
|
|
||||||
auto settingsShortcut = new QShortcut(QKeySequence("F2"), this);
|
auto settingsShortcut = new QShortcut(QKeySequence("F2"), this);
|
||||||
settingsShortcut->setContext(Qt::WidgetWithChildrenShortcut);
|
|
||||||
QWidget::connect(settingsShortcut, &QShortcut::activated, this,
|
QWidget::connect(settingsShortcut, &QShortcut::activated, this,
|
||||||
openSettings);
|
openSettings);
|
||||||
auto removeShortcut = new QShortcut(QKeySequence("Del"), this);
|
auto removeShortcut = new QShortcut(QKeySequence("Del"), this);
|
||||||
removeShortcut->setContext(Qt::WidgetWithChildrenShortcut);
|
|
||||||
QWidget::connect(removeShortcut, &QShortcut::activated, this,
|
QWidget::connect(removeShortcut, &QShortcut::activated, this,
|
||||||
[this]() { Remove(); });
|
[this]() { Remove(); });
|
||||||
|
|
||||||
auto newShortcut = new QShortcut(QKeySequence("Ctrl+N"), this);
|
auto newShortcut = new QShortcut(QKeySequence("Ctrl+N"), this);
|
||||||
newShortcut->setContext(Qt::WidgetWithChildrenShortcut);
|
|
||||||
QWidget::connect(newShortcut, &QShortcut::activated, this,
|
QWidget::connect(newShortcut, &QShortcut::activated, this,
|
||||||
[this]() { Add(); });
|
[this]() { Add(); });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class ADVSS_EXPORT ResourceTable : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResourceTable(QWidget *parent, const QString &help,
|
ResourceTable(QTabWidget *parent, const QString &help,
|
||||||
const QString &addToolTip, const QString &removeToolTip,
|
const QString &addToolTip, const QString &removeToolTip,
|
||||||
const QStringList &headers,
|
const QStringList &headers,
|
||||||
const std::function<void()> &openSettings);
|
const std::function<void()> &openSettings);
|
||||||
|
|||||||
@@ -103,11 +103,10 @@ void SceneSelection::Load(obs_data_t *obj, const char *name,
|
|||||||
OBSDataAutoRelease data =
|
OBSDataAutoRelease data =
|
||||||
obs_data_get_obj(obj, selectionSaveName.data());
|
obs_data_get_obj(obj, selectionSaveName.data());
|
||||||
|
|
||||||
const char *canvasName =
|
if (obs_data_has_user_value(data, canvasSaveName.data())) {
|
||||||
obs_data_get_string(data, canvasSaveName.data());
|
_canvas = GetWeakCanvasByName(
|
||||||
_canvas = GetWeakCanvasByName(
|
obs_data_get_string(data, canvasSaveName.data()));
|
||||||
obs_data_get_string(data, canvasSaveName.data()));
|
} else {
|
||||||
if (strcmp(canvasName, "") == 0) {
|
|
||||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
||||||
_canvas = obs_canvas_get_weak_canvas(mainCanvas);
|
_canvas = obs_canvas_get_weak_canvas(mainCanvas);
|
||||||
obs_weak_canvas_release(_canvas);
|
obs_weak_canvas_release(_canvas);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
OBSWeakSource _scene;
|
OBSWeakSource _scene;
|
||||||
OBSWeakCanvas _canvas = GetMainCanvas();
|
OBSWeakCanvas _canvas;
|
||||||
SceneGroup *_group = nullptr;
|
SceneGroup *_group = nullptr;
|
||||||
std::weak_ptr<Variable> _variable;
|
std::weak_ptr<Variable> _variable;
|
||||||
Type _type = Type::SCENE;
|
Type _type = Type::SCENE;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#include "source-helpers.hpp"
|
#include "source-helpers.hpp"
|
||||||
#include "canvas-helpers.hpp"
|
|
||||||
|
|
||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
|
|
||||||
@@ -29,43 +28,15 @@ std::string GetWeakSourceName(obs_weak_source_t *weak_source)
|
|||||||
|
|
||||||
OBSWeakSource GetWeakSourceByName(const char *name)
|
OBSWeakSource GetWeakSourceByName(const char *name)
|
||||||
{
|
{
|
||||||
OBSSourceAutoRelease source = obs_get_source_by_name(name);
|
OBSWeakSource weak;
|
||||||
|
obs_source_t *source = obs_get_source_by_name(name);
|
||||||
if (source) {
|
if (source) {
|
||||||
return OBSGetWeakRef(source);
|
weak = obs_source_get_weak_source(source);
|
||||||
|
obs_weak_source_release(weak);
|
||||||
|
obs_source_release(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LIBOBS_API_VER > MAKE_SEMANTIC_VERSION(31, 1, 0)
|
return weak;
|
||||||
struct SearchData {
|
|
||||||
const char *name;
|
|
||||||
OBSWeakSource &scene;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const auto enumCanvasScenes = [](void *dataPtr,
|
|
||||||
obs_source_t *source) -> bool {
|
|
||||||
auto data = static_cast<SearchData *>(dataPtr);
|
|
||||||
if (strcmp(data->name, obs_source_get_name(source)) == 0) {
|
|
||||||
data->scene = OBSGetWeakRef(source);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const auto enumCanvases = [](void *dataPtr,
|
|
||||||
obs_canvas_t *canvas) -> bool {
|
|
||||||
obs_canvas_enum_scenes(canvas, enumCanvasScenes, dataPtr);
|
|
||||||
|
|
||||||
auto data = static_cast<SearchData *>(dataPtr);
|
|
||||||
return data->scene == nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
OBSWeakSource weakScene;
|
|
||||||
SearchData searchData{name, weakScene};
|
|
||||||
obs_enum_canvases(enumCanvases, &searchData);
|
|
||||||
return weakScene;
|
|
||||||
#else
|
|
||||||
return nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSWeakSource GetWeakSourceByQString(const QString &name)
|
OBSWeakSource GetWeakSourceByQString(const QString &name)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "tab-helpers.hpp"
|
#include "tab-helpers.hpp"
|
||||||
#include "log-helper.hpp"
|
#include "log-helper.hpp"
|
||||||
#include "obs-module-helper.hpp"
|
#include "obs-module-helper.hpp"
|
||||||
#include "plugin-state-helpers.hpp"
|
|
||||||
|
|
||||||
#include <obs.hpp>
|
#include <obs.hpp>
|
||||||
#include <QTabBar>
|
#include <QTabBar>
|
||||||
@@ -34,21 +33,6 @@ struct TabCallbacks {
|
|||||||
static std::unordered_map<const char *, TabCallbacks> createTabCallbacks;
|
static std::unordered_map<const char *, TabCallbacks> createTabCallbacks;
|
||||||
|
|
||||||
static int lastOpenedTab = -1;
|
static int lastOpenedTab = -1;
|
||||||
static bool alwaysShowTabs = false;
|
|
||||||
|
|
||||||
[[maybe_unused]] static bool _ = []() {
|
|
||||||
AddPluginInitStep([]() {
|
|
||||||
AddSaveStep([](obs_data_t *data) {
|
|
||||||
obs_data_set_bool(data, "alwaysShowTabs",
|
|
||||||
alwaysShowTabs);
|
|
||||||
});
|
|
||||||
AddLoadStep([](obs_data_t *data) {
|
|
||||||
alwaysShowTabs =
|
|
||||||
obs_data_get_bool(data, "alwaysShowTabs");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}();
|
|
||||||
|
|
||||||
void SetTabVisibleByName(QTabWidget *tabWidget, bool visible,
|
void SetTabVisibleByName(QTabWidget *tabWidget, bool visible,
|
||||||
const QString &name)
|
const QString &name)
|
||||||
@@ -213,41 +197,7 @@ void SetupOtherTabs(QTabWidget *tabWidget)
|
|||||||
.c_str());
|
.c_str());
|
||||||
tabWidget->insertTab(0, widget, tabText);
|
tabWidget->insertTab(0, widget, tabText);
|
||||||
callbacks.setupTab(tabWidget);
|
callbacks.setupTab(tabWidget);
|
||||||
|
|
||||||
if (alwaysShowTabs) {
|
|
||||||
tabWidget->setTabVisible(0, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupShowAllTabsCheckBox(QCheckBox *checkBox, QTabWidget *tabWidget)
|
|
||||||
{
|
|
||||||
const auto stateChanged = [tabWidget](int state) {
|
|
||||||
const bool newState = (state != 0);
|
|
||||||
if (newState == alwaysShowTabs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
alwaysShowTabs = newState;
|
|
||||||
|
|
||||||
// Only show currently hidden tabs, but don't hide tabs which
|
|
||||||
// are already visible
|
|
||||||
if (!alwaysShowTabs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &[name, _] : createTabCallbacks) {
|
|
||||||
const auto localeKey =
|
|
||||||
std::string("AdvSceneSwitcher.") + name +
|
|
||||||
".title";
|
|
||||||
auto tabText = obs_module_text(localeKey.c_str());
|
|
||||||
SetTabVisibleByName(tabWidget, true, tabText);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
checkBox->setChecked(alwaysShowTabs);
|
|
||||||
QWidget::connect(checkBox, &QCheckBox::stateChanged, checkBox,
|
|
||||||
stateChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
#include "export-symbol-helper.hpp"
|
#include "export-symbol-helper.hpp"
|
||||||
|
|
||||||
#include <obs-data.h>
|
#include <obs-data.h>
|
||||||
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
@@ -21,6 +19,5 @@ void SetupOtherTabs(QTabWidget *tabWidget);
|
|||||||
void SaveTabOrder(obs_data_t *obj);
|
void SaveTabOrder(obs_data_t *obj);
|
||||||
void LoadTabOrder(obs_data_t *obj);
|
void LoadTabOrder(obs_data_t *obj);
|
||||||
bool MacroTabIsInFocus();
|
bool MacroTabIsInFocus();
|
||||||
void SetupShowAllTabsCheckBox(QCheckBox *checkBox, QTabWidget *tabWidget);
|
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ std::string GetThemeTypeName()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueUITask(void (*task)(void *param), void *param)
|
void QeueUITask(void (*task)(void *param), void *param)
|
||||||
{
|
{
|
||||||
obs_queue_task(OBS_TASK_UI, task, param, false);
|
obs_queue_task(OBS_TASK_UI, task, param, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ EXPORT void DisplayTrayMessage(const QString &title, const QString &msg,
|
|||||||
EXPORT std::string GetThemeTypeName();
|
EXPORT std::string GetThemeTypeName();
|
||||||
EXPORT QWidget *GetSettingsWindow();
|
EXPORT QWidget *GetSettingsWindow();
|
||||||
|
|
||||||
EXPORT void QueueUITask(void (*task)(void *param), void *param);
|
void QeueUITask(void (*task)(void *param), void *param);
|
||||||
|
|
||||||
bool IsCursorInWidgetArea(QWidget *widget);
|
bool IsCursorInWidgetArea(QWidget *widget);
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
#include "variable.hpp"
|
#include "variable.hpp"
|
||||||
|
|
||||||
#include <obs-frontend-api.h>
|
|
||||||
|
|
||||||
#include <QLayout>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
@@ -19,62 +16,14 @@ static bool registerTab();
|
|||||||
static void setupTab(QTabWidget *);
|
static void setupTab(QTabWidget *);
|
||||||
static bool registerTabDone = registerTab();
|
static bool registerTabDone = registerTab();
|
||||||
|
|
||||||
static VariableTable *dockWidget = nullptr;
|
static VariableTable *tabWidget = nullptr;
|
||||||
static bool addDock = false;
|
|
||||||
|
|
||||||
static VariableTable::Settings tabSettings;
|
|
||||||
static VariableTable::Settings dockSettings;
|
|
||||||
|
|
||||||
static void save(obs_data_t *data)
|
|
||||||
{
|
|
||||||
tabSettings.Save(data, "tabSettings");
|
|
||||||
dockSettings.Save(data, "dockSettings");
|
|
||||||
obs_data_set_bool(data, "addVariablesDock", addDock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enableDock(bool enable)
|
|
||||||
{
|
|
||||||
if (OBSIsShuttingDown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_frontend_remove_dock("advss-variable-dock");
|
|
||||||
|
|
||||||
addDock = enable;
|
|
||||||
if (!addDock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dockWidget = new VariableTable(dockSettings);
|
|
||||||
dockWidget->HideDockOptions();
|
|
||||||
if (obs_frontend_add_dock_by_id(
|
|
||||||
"advss-variable-dock",
|
|
||||||
obs_module_text("AdvSceneSwitcher.variableTab.title"),
|
|
||||||
dockWidget)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
blog(LOG_INFO, "failed to register variable dock!");
|
|
||||||
dockWidget->deleteLater();
|
|
||||||
dockWidget = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void load(obs_data_t *data)
|
|
||||||
{
|
|
||||||
tabSettings.Load(data, "tabSettings");
|
|
||||||
dockSettings.Load(data, "dockSettings");
|
|
||||||
|
|
||||||
enableDock(obs_data_get_bool(data, "addVariablesDock"));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool registerTab()
|
static bool registerTab()
|
||||||
{
|
{
|
||||||
AddPluginInitStep([]() {
|
AddPluginInitStep([]() {
|
||||||
AddSetupTabCallback("variableTab",
|
AddSetupTabCallback("variableTab", VariableTable::Create,
|
||||||
VariableTable::CreateTabTable, setupTab);
|
setupTab);
|
||||||
});
|
});
|
||||||
AddSaveStep(save);
|
|
||||||
AddLoadStep(load);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,14 +34,10 @@ static void setTabVisible(QTabWidget *tabWidget, bool visible)
|
|||||||
obs_module_text("AdvSceneSwitcher.variableTab.title"));
|
obs_module_text("AdvSceneSwitcher.variableTab.title"));
|
||||||
}
|
}
|
||||||
|
|
||||||
VariableTable *VariableTable::CreateTabTable()
|
VariableTable *VariableTable::Create()
|
||||||
{
|
{
|
||||||
return new VariableTable(tabSettings);
|
tabWidget = new VariableTable();
|
||||||
}
|
return tabWidget;
|
||||||
|
|
||||||
void VariableTable::HideDockOptions() const
|
|
||||||
{
|
|
||||||
_addDock->hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableTable::Add()
|
void VariableTable::Add()
|
||||||
@@ -218,14 +163,15 @@ static void updateVariableStatus(QTableWidget *table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openSettingsDialog(VariableTable *table)
|
static void openSettingsDialog()
|
||||||
{
|
{
|
||||||
auto selectedRows = table->Table()->selectionModel()->selectedRows();
|
auto selectedRows =
|
||||||
|
tabWidget->Table()->selectionModel()->selectedRows();
|
||||||
if (selectedRows.empty()) {
|
if (selectedRows.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cell = table->Table()->item(selectedRows.last().row(), 0);
|
auto cell = tabWidget->Table()->item(selectedRows.last().row(), 0);
|
||||||
if (!cell) {
|
if (!cell) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -248,14 +194,15 @@ static void openSettingsDialog(VariableTable *table)
|
|||||||
|
|
||||||
void VariableTable::Remove()
|
void VariableTable::Remove()
|
||||||
{
|
{
|
||||||
auto selectedRows = Table()->selectionModel()->selectedRows();
|
auto selectedRows =
|
||||||
|
tabWidget->Table()->selectionModel()->selectedRows();
|
||||||
if (selectedRows.empty()) {
|
if (selectedRows.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList varNames;
|
QStringList varNames;
|
||||||
for (const auto &row : selectedRows) {
|
for (const auto &row : selectedRows) {
|
||||||
auto cell = Table()->item(row.row(), 0);
|
auto cell = tabWidget->Table()->item(row.row(), 0);
|
||||||
if (!cell) {
|
if (!cell) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -288,52 +235,7 @@ void VariableTable::Remove()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VariableTable::Filter()
|
VariableTable::VariableTable(QTabWidget *parent)
|
||||||
{
|
|
||||||
const auto itemMatches = [&](const QTableWidgetItem *item) {
|
|
||||||
if (!item) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_settings.searchString.empty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto text = item->text();
|
|
||||||
|
|
||||||
if (_settings.regex.Enabled()) {
|
|
||||||
return _settings.regex.Matches(text.toStdString(),
|
|
||||||
_settings.searchString);
|
|
||||||
}
|
|
||||||
|
|
||||||
return text.contains(
|
|
||||||
QString::fromStdString(_settings.searchString),
|
|
||||||
Qt::CaseInsensitive);
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int row = 0; row < Table()->rowCount(); ++row) {
|
|
||||||
bool match = false;
|
|
||||||
|
|
||||||
if (_settings.searchType == Settings::SearchType::ALL) {
|
|
||||||
for (int col = 0; col < Table()->columnCount(); ++col) {
|
|
||||||
if (itemMatches(Table()->item(row, col))) {
|
|
||||||
match = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (itemMatches(Table()->item(
|
|
||||||
row,
|
|
||||||
static_cast<int>(_settings.searchType)))) {
|
|
||||||
match = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Table()->setRowHidden(row, !match);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableTable::VariableTable(Settings &settings, QWidget *parent)
|
|
||||||
: ResourceTable(
|
: ResourceTable(
|
||||||
parent, obs_module_text("AdvSceneSwitcher.variableTab.help"),
|
parent, obs_module_text("AdvSceneSwitcher.variableTab.help"),
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
@@ -351,113 +253,13 @@ VariableTable::VariableTable(Settings &settings, QWidget *parent)
|
|||||||
"AdvSceneSwitcher.variableTab.lastUsed.header")
|
"AdvSceneSwitcher.variableTab.lastUsed.header")
|
||||||
<< obs_module_text(
|
<< obs_module_text(
|
||||||
"AdvSceneSwitcher.variableTab.lastChanged.header"),
|
"AdvSceneSwitcher.variableTab.lastChanged.header"),
|
||||||
[this]() { openSettingsDialog(this); }),
|
openSettingsDialog)
|
||||||
_searchField(new QLineEdit(this)),
|
|
||||||
_clear(new QPushButton(this)),
|
|
||||||
_searchType(new QComboBox(this)),
|
|
||||||
_regexWidget(new RegexConfigWidget(this)),
|
|
||||||
_addDock(new QCheckBox(
|
|
||||||
obs_module_text("AdvSceneSwitcher.variableTab.addDock"))),
|
|
||||||
_settings(settings)
|
|
||||||
{
|
{
|
||||||
_clear->setMaximumWidth(22);
|
|
||||||
SetButtonIcon(_clear, GetThemeTypeName() == "Light"
|
|
||||||
? "theme:Light/close.svg"
|
|
||||||
: "theme:Dark/close.svg");
|
|
||||||
_clear->setToolTip(
|
|
||||||
obs_module_text("AdvSceneSwitcher.variableTab.clear"));
|
|
||||||
_clear->setDisabled(_settings.searchString.empty());
|
|
||||||
|
|
||||||
connect(_clear, &QPushButton::clicked, this, [this]() {
|
|
||||||
_searchField->setText("");
|
|
||||||
_clear->setDisabled(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const auto &variable : GetVariables()) {
|
for (const auto &variable : GetVariables()) {
|
||||||
auto v = std::static_pointer_cast<Variable>(variable);
|
auto v = std::static_pointer_cast<Variable>(variable);
|
||||||
AddItemTableRow(Table(), getCellLabels(v.get()));
|
AddItemTableRow(Table(), getCellLabels(v.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(Table(), &QTableWidget::itemChanged, this,
|
|
||||||
[this]() { Filter(); });
|
|
||||||
|
|
||||||
_searchField->setPlaceholderText(obs_module_text(
|
|
||||||
("AdvSceneSwitcher.variableTab.search.placeholder")));
|
|
||||||
_searchField->setText(QString::fromStdString(_settings.searchString));
|
|
||||||
connect(_searchField, &QLineEdit::textChanged, this,
|
|
||||||
[this](const QString &text) {
|
|
||||||
_settings.searchString = text.toStdString();
|
|
||||||
_clear->setDisabled(text.isEmpty());
|
|
||||||
Filter();
|
|
||||||
});
|
|
||||||
|
|
||||||
_searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.variableTab.search.all"),
|
|
||||||
Settings::SearchType::ALL);
|
|
||||||
_searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.variableTab.search.name"),
|
|
||||||
Settings::SearchType::NAME);
|
|
||||||
_searchType->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.variableTab.search.value"),
|
|
||||||
Settings::SearchType::VALUE);
|
|
||||||
_searchType->setCurrentIndex(
|
|
||||||
_searchType->findData(_settings.searchType));
|
|
||||||
|
|
||||||
connect(_searchType, &QComboBox::currentIndexChanged, this, [this]() {
|
|
||||||
_settings.searchType = static_cast<Settings::SearchType>(
|
|
||||||
_searchType->currentData().toInt());
|
|
||||||
});
|
|
||||||
|
|
||||||
_regexWidget->SetRegexConfig(_settings.regex);
|
|
||||||
connect(_regexWidget, &RegexConfigWidget::RegexConfigChanged, this,
|
|
||||||
[this](const RegexConfig ®ex) {
|
|
||||||
_settings.regex = regex;
|
|
||||||
Filter();
|
|
||||||
});
|
|
||||||
|
|
||||||
_addDock->setChecked(addDock);
|
|
||||||
connect(_addDock, &QCheckBox::stateChanged, this,
|
|
||||||
[this](int checked) { enableDock(checked); });
|
|
||||||
|
|
||||||
QWidget::connect(VariableSignalManager::Instance(),
|
|
||||||
&VariableSignalManager::Rename, this,
|
|
||||||
[this](const QString &oldName,
|
|
||||||
const QString &newName) {
|
|
||||||
RenameItemTableRow(Table(), oldName, newName);
|
|
||||||
});
|
|
||||||
QWidget::connect(
|
|
||||||
VariableSignalManager::Instance(), &VariableSignalManager::Add,
|
|
||||||
this, [this](const QString &name) {
|
|
||||||
AddItemTableRow(
|
|
||||||
Table(),
|
|
||||||
getCellLabels(GetVariableByQString(name)));
|
|
||||||
SetHelpVisible(false);
|
|
||||||
HighlightAddButton(false);
|
|
||||||
});
|
|
||||||
QWidget::connect(VariableSignalManager::Instance(),
|
|
||||||
&VariableSignalManager::Remove, this,
|
|
||||||
[this](const QString &name) {
|
|
||||||
RemoveItemTableRow(Table(), name);
|
|
||||||
if (Table()->rowCount() == 0) {
|
|
||||||
SetHelpVisible(true);
|
|
||||||
HighlightAddButton(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
auto timer = new QTimer(this);
|
|
||||||
timer->setInterval(1000);
|
|
||||||
QWidget::connect(timer, &QTimer::timeout,
|
|
||||||
[this]() { updateVariableStatus(Table()); });
|
|
||||||
timer->start();
|
|
||||||
|
|
||||||
auto searchLayout = new QHBoxLayout();
|
|
||||||
searchLayout->addWidget(_searchField);
|
|
||||||
searchLayout->addWidget(_clear);
|
|
||||||
searchLayout->addWidget(_searchType);
|
|
||||||
searchLayout->addWidget(_regexWidget);
|
|
||||||
searchLayout->addWidget(_addDock);
|
|
||||||
qobject_cast<QVBoxLayout *>(layout())->insertLayout(0, searchLayout);
|
|
||||||
|
|
||||||
SetHelpVisible(GetVariables().empty());
|
SetHelpVisible(GetVariables().empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,26 +270,36 @@ static void setupTab(QTabWidget *tab)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QWidget::connect(VariableSignalManager::Instance(),
|
QWidget::connect(VariableSignalManager::Instance(),
|
||||||
&VariableSignalManager::Add, tab,
|
&VariableSignalManager::Rename, tab,
|
||||||
[tab](const QString &) { setTabVisible(tab, true); });
|
[](const QString &oldName, const QString &newName) {
|
||||||
}
|
RenameItemTableRow(tabWidget->Table(), oldName,
|
||||||
|
newName);
|
||||||
|
});
|
||||||
|
QWidget::connect(
|
||||||
|
VariableSignalManager::Instance(), &VariableSignalManager::Add,
|
||||||
|
tab, [tab](const QString &name) {
|
||||||
|
AddItemTableRow(
|
||||||
|
tabWidget->Table(),
|
||||||
|
getCellLabels(GetVariableByQString(name)));
|
||||||
|
tabWidget->SetHelpVisible(false);
|
||||||
|
tabWidget->HighlightAddButton(false);
|
||||||
|
setTabVisible(tab, true);
|
||||||
|
});
|
||||||
|
QWidget::connect(VariableSignalManager::Instance(),
|
||||||
|
&VariableSignalManager::Remove, tab,
|
||||||
|
[](const QString &name) {
|
||||||
|
RemoveItemTableRow(tabWidget->Table(), name);
|
||||||
|
if (tabWidget->Table()->rowCount() == 0) {
|
||||||
|
tabWidget->SetHelpVisible(true);
|
||||||
|
tabWidget->HighlightAddButton(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
void VariableTable::Settings::Save(obs_data_t *data, const char *name)
|
auto timer = new QTimer(tabWidget);
|
||||||
{
|
timer->setInterval(1000);
|
||||||
OBSDataAutoRelease settings = obs_data_create();
|
QWidget::connect(timer, &QTimer::timeout,
|
||||||
obs_data_set_int(settings, "searchType", static_cast<int>(searchType));
|
[]() { updateVariableStatus(tabWidget->Table()); });
|
||||||
obs_data_set_string(settings, "searchString", searchString.c_str());
|
timer->start();
|
||||||
regex.Save(settings);
|
|
||||||
obs_data_set_obj(data, name, settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VariableTable::Settings::Load(obs_data_t *data, const char *name)
|
|
||||||
{
|
|
||||||
OBSDataAutoRelease settings = obs_data_get_obj(data, name);
|
|
||||||
searchType = static_cast<SearchType>(
|
|
||||||
obs_data_get_int(settings, "searchType"));
|
|
||||||
searchString = obs_data_get_string(settings, "searchString");
|
|
||||||
regex.Load(settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "resource-table.hpp"
|
#include "resource-table.hpp"
|
||||||
#include "regex-config.hpp"
|
|
||||||
|
|
||||||
#include <QComboBox>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -10,34 +7,14 @@ class VariableTable final : public ResourceTable {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Settings {
|
static VariableTable *Create();
|
||||||
void Save(obs_data_t *data, const char *name);
|
|
||||||
void Load(obs_data_t *data, const char *name);
|
|
||||||
|
|
||||||
enum SearchType { ALL = -1, NAME = 0, VALUE = 1 };
|
|
||||||
|
|
||||||
SearchType searchType = SearchType::ALL;
|
|
||||||
std::string searchString;
|
|
||||||
RegexConfig regex;
|
|
||||||
};
|
|
||||||
|
|
||||||
VariableTable(Settings &settings, QWidget *parent = nullptr);
|
|
||||||
static VariableTable *CreateTabTable();
|
|
||||||
void HideDockOptions() const;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void Add();
|
void Add();
|
||||||
void Remove();
|
void Remove();
|
||||||
void Filter();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLineEdit *_searchField;
|
VariableTable(QTabWidget *parent = nullptr);
|
||||||
QPushButton *_clear;
|
|
||||||
QComboBox *_searchType;
|
|
||||||
RegexConfigWidget *_regexWidget;
|
|
||||||
QCheckBox *_addDock;
|
|
||||||
|
|
||||||
Settings &_settings;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -456,7 +456,7 @@ void ImportVariables(obs_data_t *data)
|
|||||||
|
|
||||||
obs_data_array_release(array);
|
obs_data_array_release(array);
|
||||||
|
|
||||||
QueueUITask(signalImportedVariables, importedVars);
|
QeueUITask(signalImportedVariables, importedVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::high_resolution_clock::time_point GetLastVariableChangeTime()
|
std::chrono::high_resolution_clock::time_point GetLastVariableChangeTime()
|
||||||
|
|||||||
@@ -601,10 +601,10 @@ static void populateHotkeyNames(QComboBox *list,
|
|||||||
MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
_actionType(new FilterComboBox()),
|
_actionType(new QComboBox()),
|
||||||
_hotkeyType(new FilterComboBox()),
|
_hotkeyType(new QComboBox()),
|
||||||
_obsHotkeys(new FilterComboBox()),
|
_obsHotkeys(new QComboBox()),
|
||||||
_keys(new FilterComboBox()),
|
_keys(new QComboBox()),
|
||||||
_leftShift(new QCheckBox(
|
_leftShift(new QCheckBox(
|
||||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"))),
|
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"))),
|
||||||
_rightShift(new QCheckBox(obs_module_text(
|
_rightShift(new QCheckBox(obs_module_text(
|
||||||
|
|||||||
@@ -85,14 +85,11 @@ private slots:
|
|||||||
void DurationChanged(const Duration &);
|
void DurationChanged(const Duration &);
|
||||||
void OnlySendToOBSChanged(int state);
|
void OnlySendToOBSChanged(int state);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void RepopulateOBSHotkeySelection();
|
QComboBox *_actionType;
|
||||||
void SetWidgetVisibility();
|
QComboBox *_hotkeyType;
|
||||||
|
QComboBox *_obsHotkeys;
|
||||||
FilterComboBox *_actionType;
|
QComboBox *_keys;
|
||||||
FilterComboBox *_hotkeyType;
|
|
||||||
FilterComboBox *_obsHotkeys;
|
|
||||||
FilterComboBox *_keys;
|
|
||||||
QCheckBox *_leftShift;
|
QCheckBox *_leftShift;
|
||||||
QCheckBox *_rightShift;
|
QCheckBox *_rightShift;
|
||||||
QCheckBox *_leftCtrl;
|
QCheckBox *_leftCtrl;
|
||||||
@@ -104,10 +101,15 @@ private:
|
|||||||
DurationSelection *_duration;
|
DurationSelection *_duration;
|
||||||
QCheckBox *_onlySendToOBS;
|
QCheckBox *_onlySendToOBS;
|
||||||
QLabel *_noKeyPressSimulationWarning;
|
QLabel *_noKeyPressSimulationWarning;
|
||||||
QHBoxLayout *_entryLayout;
|
|
||||||
QHBoxLayout *_keyConfigLayout;
|
|
||||||
|
|
||||||
std::shared_ptr<MacroActionHotkey> _entryData;
|
std::shared_ptr<MacroActionHotkey> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RepopulateOBSHotkeySelection();
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
|
||||||
|
QHBoxLayout *_entryLayout;
|
||||||
|
QHBoxLayout *_keyConfigLayout;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -137,51 +137,31 @@ bool MacroActionSwitchScene::WaitForTransition(OBSWeakSource &scene,
|
|||||||
bool MacroActionSwitchScene::PerformAction()
|
bool MacroActionSwitchScene::PerformAction()
|
||||||
{
|
{
|
||||||
OBSWeakSource sceneToSwitchTo;
|
OBSWeakSource sceneToSwitchTo;
|
||||||
OBSWeakCanvas canvasToSwitchFor;
|
OBSWeakCanvas canvas;
|
||||||
|
|
||||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
|
||||||
OBSWeakCanvas mainCanvasWeak = OBSGetWeakRef(mainCanvas);
|
|
||||||
|
|
||||||
const auto getActiveSceneHelper = [this](const OBSWeakCanvas &canvas) {
|
|
||||||
OBSWeakSource activeScene;
|
|
||||||
if (IsMainCanvas(canvas) && _sceneType == SceneType::PREVIEW) {
|
|
||||||
OBSSourceAutoRelease previewSource =
|
|
||||||
obs_frontend_get_current_preview_scene();
|
|
||||||
return OBSGetWeakRef(previewSource);
|
|
||||||
} else {
|
|
||||||
return GetActiveCanvasScene(canvas);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case Action::SCENE_NAME:
|
case Action::SCENE_NAME:
|
||||||
sceneToSwitchTo = _scene.GetScene();
|
sceneToSwitchTo = _scene.GetScene();
|
||||||
canvasToSwitchFor = _scene.GetCanvas();
|
canvas = _scene.GetCanvas();
|
||||||
break;
|
break;
|
||||||
case Action::SCENE_LIST_NEXT: {
|
case Action::SCENE_LIST_NEXT: {
|
||||||
canvasToSwitchFor = _canvas ? _canvas : mainCanvasWeak;
|
const auto activeScene = GetActiveCanvasScene(_canvas);
|
||||||
const auto activeScene =
|
const int currentIndex = GetIndexOfScene(_canvas, activeScene);
|
||||||
getActiveSceneHelper(canvasToSwitchFor);
|
sceneToSwitchTo = GetSceneAtIndex(_canvas, currentIndex + 1);
|
||||||
const int currentIndex =
|
canvas = _canvas;
|
||||||
GetIndexOfScene(canvasToSwitchFor, activeScene);
|
|
||||||
sceneToSwitchTo =
|
|
||||||
GetSceneAtIndex(canvasToSwitchFor, currentIndex + 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Action::SCENE_LIST_PREVIOUS: {
|
case Action::SCENE_LIST_PREVIOUS: {
|
||||||
canvasToSwitchFor = _canvas ? _canvas : mainCanvasWeak;
|
const auto activeScene = GetActiveCanvasScene(_canvas);
|
||||||
const auto activeScene =
|
const int currentIndex = GetIndexOfScene(_canvas, activeScene);
|
||||||
getActiveSceneHelper(canvasToSwitchFor);
|
sceneToSwitchTo = GetSceneAtIndex(_canvas, currentIndex - 1);
|
||||||
const int currentIndex =
|
canvas = _canvas;
|
||||||
GetIndexOfScene(canvasToSwitchFor, activeScene);
|
|
||||||
sceneToSwitchTo =
|
|
||||||
GetSceneAtIndex(canvasToSwitchFor, currentIndex - 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Action::SCENE_LIST_INDEX: {
|
case Action::SCENE_LIST_INDEX: {
|
||||||
canvasToSwitchFor = _canvas ? _canvas : mainCanvasWeak;
|
sceneToSwitchTo =
|
||||||
sceneToSwitchTo = GetSceneAtIndex(canvasToSwitchFor,
|
GetSceneAtIndex(_canvas, _index.GetValue() - 1);
|
||||||
_index.GetValue() - 1);
|
canvas = _canvas;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -196,12 +176,11 @@ bool MacroActionSwitchScene::PerformAction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto transition = _transition.GetTransition();
|
auto transition = _transition.GetTransition();
|
||||||
SwitchScene(
|
SwitchScene({sceneToSwitchTo, transition,
|
||||||
{sceneToSwitchTo, transition, (int)(_duration.Milliseconds())},
|
(int)(_duration.Milliseconds())},
|
||||||
obs_frontend_preview_program_mode_active(), canvasToSwitchFor);
|
obs_frontend_preview_program_mode_active(), canvas);
|
||||||
if (_blockUntilTransitionDone && sceneToSwitchTo &&
|
if (_blockUntilTransitionDone && sceneToSwitchTo &&
|
||||||
sceneToSwitchTo != GetCurrentScene() &&
|
sceneToSwitchTo != GetCurrentScene() && IsMainCanvas(canvas)) {
|
||||||
IsMainCanvas(canvasToSwitchFor)) {
|
|
||||||
return WaitForTransition(sceneToSwitchTo, transition);
|
return WaitForTransition(sceneToSwitchTo, transition);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -413,7 +392,6 @@ void MacroActionSwitchSceneEdit::SetWidgetData() const
|
|||||||
_sceneTypes->setCurrentIndex(_sceneTypes->findData(
|
_sceneTypes->setCurrentIndex(_sceneTypes->findData(
|
||||||
static_cast<int>(_entryData->_sceneType)));
|
static_cast<int>(_entryData->_sceneType)));
|
||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_canvas->SetCanvas(_entryData->_canvas);
|
|
||||||
_transitions->SetTransition(_entryData->_transition);
|
_transitions->SetTransition(_entryData->_transition);
|
||||||
_duration->SetDuration(_entryData->_duration);
|
_duration->SetDuration(_entryData->_duration);
|
||||||
_blockUntilTransitionDone->setChecked(
|
_blockUntilTransitionDone->setChecked(
|
||||||
@@ -453,7 +431,7 @@ void MacroActionSwitchSceneEdit::SceneSelectionCanvasChanged(
|
|||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSwitchSceneEdit::ActionChanged(int)
|
void MacroActionSwitchSceneEdit::ActionChanged(int value)
|
||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
_entryData->_action = static_cast<MacroActionSwitchScene::Action>(
|
_entryData->_action = static_cast<MacroActionSwitchScene::Action>(
|
||||||
@@ -583,17 +561,9 @@ void MacroActionSwitchSceneEdit::SetWidgetVisibility()
|
|||||||
{{"{{transitions}}", _transitions},
|
{{"{{transitions}}", _transitions},
|
||||||
{"{{duration}}", _duration}});
|
{"{{duration}}", _duration}});
|
||||||
|
|
||||||
OBSWeakCanvas canvas;
|
const auto canvas = action == MacroActionSwitchScene::Action::SCENE_NAME
|
||||||
if (action == MacroActionSwitchScene::Action::SCENE_NAME) {
|
? _entryData->_scene.GetCanvas()
|
||||||
canvas = _entryData->_scene.GetCanvas();
|
: _entryData->_canvas;
|
||||||
} else {
|
|
||||||
if (_entryData->_canvas) {
|
|
||||||
canvas = _entryData->_canvas;
|
|
||||||
} else {
|
|
||||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
|
||||||
canvas = OBSGetWeakRef(mainCanvas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const bool isMainCanvas = IsMainCanvas(canvas);
|
const bool isMainCanvas = IsMainCanvas(canvas);
|
||||||
SetLayoutVisible(_transitionLayout, isMainCanvas);
|
SetLayoutVisible(_transitionLayout, isMainCanvas);
|
||||||
_blockUntilTransitionDone->setVisible(isMainCanvas);
|
_blockUntilTransitionDone->setVisible(isMainCanvas);
|
||||||
@@ -610,7 +580,7 @@ void MacroActionSwitchSceneEdit::SetWidgetVisibility()
|
|||||||
_notSupportedWarning->setText(
|
_notSupportedWarning->setText(
|
||||||
fmt.arg(QString::fromStdString(GetWeakCanvasName(canvas))));
|
fmt.arg(QString::fromStdString(GetWeakCanvasName(canvas))));
|
||||||
_notSupportedWarning->setVisible(
|
_notSupportedWarning->setVisible(
|
||||||
!isMainCanvas &&
|
!IsMainCanvas(canvas) &&
|
||||||
_entryData->_sceneType ==
|
_entryData->_sceneType ==
|
||||||
MacroActionSwitchScene::SceneType::PREVIEW);
|
MacroActionSwitchScene::SceneType::PREVIEW);
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,6 @@ MacroActionSequenceEdit::MacroActionSequenceEdit(
|
|||||||
_resetIndex(new VariableSpinBox()),
|
_resetIndex(new VariableSpinBox()),
|
||||||
_layout(new QHBoxLayout())
|
_layout(new QHBoxLayout())
|
||||||
{
|
{
|
||||||
_macros->HideGroups();
|
|
||||||
populateActionSelection(_actions);
|
populateActionSelection(_actions);
|
||||||
|
|
||||||
_resetIndex->setMinimum(1);
|
_resetIndex->setMinimum(1);
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
const std::string MacroActionSource::id = "source";
|
const std::string MacroActionSource::id = "source";
|
||||||
@@ -39,12 +37,6 @@ const static std::map<MacroActionSource::Action, std::string> actionTypes = {
|
|||||||
"AdvSceneSwitcher.action.source.type.openFilterDialog"},
|
"AdvSceneSwitcher.action.source.type.openFilterDialog"},
|
||||||
{MacroActionSource::Action::OPEN_PROPERTIES_DIALOG,
|
{MacroActionSource::Action::OPEN_PROPERTIES_DIALOG,
|
||||||
"AdvSceneSwitcher.action.source.type.openPropertiesDialog"},
|
"AdvSceneSwitcher.action.source.type.openPropertiesDialog"},
|
||||||
{MacroActionSource::Action::CLOSE_INTERACTION_DIALOG,
|
|
||||||
"AdvSceneSwitcher.action.source.type.closeInteractionDialog"},
|
|
||||||
{MacroActionSource::Action::CLOSE_FILTER_DIALOG,
|
|
||||||
"AdvSceneSwitcher.action.source.type.closeFilterDialog"},
|
|
||||||
{MacroActionSource::Action::CLOSE_PROPERTIES_DIALOG,
|
|
||||||
"AdvSceneSwitcher.action.source.type.closePropertiesDialog"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const static std::map<obs_deinterlace_mode, std::string> deinterlaceModes = {
|
const static std::map<obs_deinterlace_mode, std::string> deinterlaceModes = {
|
||||||
@@ -116,81 +108,9 @@ static bool isInteractable(obs_source_t *source)
|
|||||||
return (flags & OBS_SOURCE_INTERACTION) != 0;
|
return (flags & OBS_SOURCE_INTERACTION) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void closeSourceDialog(obs_source_t *source, bool accept,
|
|
||||||
const char *className)
|
|
||||||
{
|
|
||||||
if (!source) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto mainWindow =
|
|
||||||
reinterpret_cast<QMainWindow *>(obs_frontend_get_main_window());
|
|
||||||
if (!mainWindow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto widget : mainWindow->children()) {
|
|
||||||
auto dialog = qobject_cast<QDialog *>(widget);
|
|
||||||
if (!dialog) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dialog->metaObject()->className() != QString(className)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *name = obs_source_get_name(source);
|
|
||||||
if (!name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dialog->windowTitle().contains(QString(name))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accept) {
|
|
||||||
dialog->accept();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// dialog->reject() will ask for confirmation
|
|
||||||
// Try to avoid this by finding and pressing the cancel button
|
|
||||||
for (const auto widget : dialog->children()) {
|
|
||||||
auto buttons = qobject_cast<QDialogButtonBox *>(widget);
|
|
||||||
if (!buttons) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto *button : buttons->buttons()) {
|
|
||||||
if (buttons->buttonRole(button) ==
|
|
||||||
QDialogButtonBox::RejectRole) {
|
|
||||||
button->click();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename F> void QueueUITaskLambda(F &&func)
|
|
||||||
{
|
|
||||||
using FnType = std::decay_t<F>;
|
|
||||||
auto *heapFunc = new FnType(std::forward<F>(func));
|
|
||||||
|
|
||||||
QueueUITask(
|
|
||||||
[](void *param) {
|
|
||||||
std::unique_ptr<FnType> fn(
|
|
||||||
static_cast<FnType *>(param));
|
|
||||||
(*fn)();
|
|
||||||
},
|
|
||||||
heapFunc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionSource::PerformAction()
|
bool MacroActionSource::PerformAction()
|
||||||
{
|
{
|
||||||
OBSSource s = obs_weak_source_get_source(_source.GetSource());
|
auto s = obs_weak_source_get_source(_source.GetSource());
|
||||||
obs_source_release(s);
|
|
||||||
|
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case Action::ENABLE:
|
case Action::ENABLE:
|
||||||
obs_source_set_enabled(s, true);
|
obs_source_set_enabled(s, true);
|
||||||
@@ -252,31 +172,10 @@ bool MacroActionSource::PerformAction()
|
|||||||
case Action::OPEN_PROPERTIES_DIALOG:
|
case Action::OPEN_PROPERTIES_DIALOG:
|
||||||
obs_frontend_open_source_properties(s);
|
obs_frontend_open_source_properties(s);
|
||||||
break;
|
break;
|
||||||
case Action::CLOSE_INTERACTION_DIALOG:
|
|
||||||
if (!isInteractable(s)) {
|
|
||||||
// Nothing to do
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueueUITaskLambda([&]() {
|
|
||||||
closeSourceDialog(s, true, "OBSBasicInteraction");
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case Action::CLOSE_FILTER_DIALOG:
|
|
||||||
QueueUITaskLambda([&]() {
|
|
||||||
closeSourceDialog(s, _acceptDialog, "OBSBasicFilters");
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case Action::CLOSE_PROPERTIES_DIALOG:
|
|
||||||
QueueUITaskLambda([&]() {
|
|
||||||
closeSourceDialog(s, _acceptDialog,
|
|
||||||
"OBSBasicProperties");
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
obs_source_release(s);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +207,6 @@ bool MacroActionSource::Save(obs_data_t *obj) const
|
|||||||
static_cast<int>(_deinterlaceMode));
|
static_cast<int>(_deinterlaceMode));
|
||||||
obs_data_set_int(obj, "deinterlaceOrder",
|
obs_data_set_int(obj, "deinterlaceOrder",
|
||||||
static_cast<int>(_deinterlaceOrder));
|
static_cast<int>(_deinterlaceOrder));
|
||||||
obs_data_set_bool(obj, "acceptDialog", _acceptDialog);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +231,6 @@ bool MacroActionSource::Load(obs_data_t *obj)
|
|||||||
obs_data_get_int(obj, "deinterlaceMode"));
|
obs_data_get_int(obj, "deinterlaceMode"));
|
||||||
_deinterlaceOrder = static_cast<obs_deinterlace_field_order>(
|
_deinterlaceOrder = static_cast<obs_deinterlace_field_order>(
|
||||||
obs_data_get_int(obj, "deinterlaceOrder"));
|
obs_data_get_int(obj, "deinterlaceOrder"));
|
||||||
_acceptDialog = obs_data_get_bool(obj, "acceptDialog");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,9 +307,7 @@ MacroActionSourceEdit::MacroActionSourceEdit(
|
|||||||
_warning(new QLabel(
|
_warning(new QLabel(
|
||||||
obs_module_text("AdvSceneSwitcher.action.source.warning"))),
|
obs_module_text("AdvSceneSwitcher.action.source.warning"))),
|
||||||
_refreshSettingSelection(new QPushButton(
|
_refreshSettingSelection(new QPushButton(
|
||||||
obs_module_text("AdvSceneSwitcher.action.source.refresh"))),
|
obs_module_text("AdvSceneSwitcher.action.source.refresh")))
|
||||||
_acceptDialog(new QCheckBox(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.source.dialog.accept")))
|
|
||||||
{
|
{
|
||||||
populateActionSelection(_actions);
|
populateActionSelection(_actions);
|
||||||
|
|
||||||
@@ -452,8 +347,6 @@ MacroActionSourceEdit::MacroActionSourceEdit(
|
|||||||
SLOT(SelectionChanged(const SourceSetting &)));
|
SLOT(SelectionChanged(const SourceSetting &)));
|
||||||
QWidget::connect(_refreshSettingSelection, SIGNAL(clicked()), this,
|
QWidget::connect(_refreshSettingSelection, SIGNAL(clicked()), this,
|
||||||
SLOT(RefreshVariableSourceSelectionValue()));
|
SLOT(RefreshVariableSourceSelectionValue()));
|
||||||
QWidget::connect(_acceptDialog, SIGNAL(stateChanged(int)), this,
|
|
||||||
SLOT(AcceptDialogChanged(int)));
|
|
||||||
|
|
||||||
auto entryLayout = new QHBoxLayout;
|
auto entryLayout = new QHBoxLayout;
|
||||||
entryLayout->setContentsMargins(0, 0, 0, 0);
|
entryLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
@@ -481,7 +374,6 @@ MacroActionSourceEdit::MacroActionSourceEdit(
|
|||||||
mainLayout->addLayout(_settingsLayout);
|
mainLayout->addLayout(_settingsLayout);
|
||||||
mainLayout->addWidget(_warning);
|
mainLayout->addWidget(_warning);
|
||||||
mainLayout->addWidget(_settingsString);
|
mainLayout->addWidget(_settingsString);
|
||||||
mainLayout->addWidget(_acceptDialog);
|
|
||||||
auto buttonLayout = new QHBoxLayout;
|
auto buttonLayout = new QHBoxLayout;
|
||||||
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
buttonLayout->addWidget(_getSettings);
|
buttonLayout->addWidget(_getSettings);
|
||||||
@@ -514,7 +406,6 @@ void MacroActionSourceEdit::UpdateEntryData()
|
|||||||
static_cast<int>(_entryData->_settingsInputMethod)));
|
static_cast<int>(_entryData->_settingsInputMethod)));
|
||||||
_tempVars->SetVariable(_entryData->_tempVar);
|
_tempVars->SetVariable(_entryData->_tempVar);
|
||||||
_manualSettingValue->setPlainText(_entryData->_manualSettingValue);
|
_manualSettingValue->setPlainText(_entryData->_manualSettingValue);
|
||||||
_acceptDialog->setChecked(_entryData->_acceptDialog);
|
|
||||||
|
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
@@ -640,12 +531,6 @@ void MacroActionSourceEdit::RefreshVariableSourceSelectionValue()
|
|||||||
_sourceSettings->SetSource(_entryData->_source.GetSource());
|
_sourceSettings->SetSource(_entryData->_source.GetSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSourceEdit::AcceptDialogChanged(int state)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_acceptDialog = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString GetIndividualListEntryName()
|
static QString GetIndividualListEntryName()
|
||||||
{
|
{
|
||||||
static const auto matchesInput =
|
static const auto matchesInput =
|
||||||
@@ -728,12 +613,6 @@ void MacroActionSourceEdit::SetWidgetVisibility()
|
|||||||
_entryData->_source.GetType() ==
|
_entryData->_source.GetType() ==
|
||||||
SourceSelection::Type::VARIABLE);
|
SourceSelection::Type::VARIABLE);
|
||||||
|
|
||||||
_acceptDialog->setVisible(
|
|
||||||
_entryData->_action ==
|
|
||||||
MacroActionSource::Action::CLOSE_FILTER_DIALOG ||
|
|
||||||
_entryData->_action ==
|
|
||||||
MacroActionSource::Action::CLOSE_PROPERTIES_DIALOG);
|
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,9 @@
|
|||||||
#include "source-selection.hpp"
|
#include "source-selection.hpp"
|
||||||
#include "source-setting.hpp"
|
#include "source-setting.hpp"
|
||||||
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -34,7 +33,6 @@ public:
|
|||||||
OBS_DEINTERLACE_FIELD_ORDER_TOP;
|
OBS_DEINTERLACE_FIELD_ORDER_TOP;
|
||||||
TempVariableRef _tempVar;
|
TempVariableRef _tempVar;
|
||||||
SourceSetting _setting;
|
SourceSetting _setting;
|
||||||
bool _acceptDialog = false;
|
|
||||||
|
|
||||||
enum class Action {
|
enum class Action {
|
||||||
ENABLE,
|
ENABLE,
|
||||||
@@ -47,9 +45,6 @@ public:
|
|||||||
OPEN_INTERACTION_DIALOG,
|
OPEN_INTERACTION_DIALOG,
|
||||||
OPEN_FILTER_DIALOG,
|
OPEN_FILTER_DIALOG,
|
||||||
OPEN_PROPERTIES_DIALOG,
|
OPEN_PROPERTIES_DIALOG,
|
||||||
CLOSE_INTERACTION_DIALOG,
|
|
||||||
CLOSE_FILTER_DIALOG,
|
|
||||||
CLOSE_PROPERTIES_DIALOG,
|
|
||||||
};
|
};
|
||||||
Action _action = Action::SETTINGS;
|
Action _action = Action::SETTINGS;
|
||||||
|
|
||||||
@@ -96,7 +91,6 @@ private slots:
|
|||||||
void SelectionChanged(const SourceSetting &);
|
void SelectionChanged(const SourceSetting &);
|
||||||
void ManualSettingsValueChanged();
|
void ManualSettingsValueChanged();
|
||||||
void RefreshVariableSourceSelectionValue();
|
void RefreshVariableSourceSelectionValue();
|
||||||
void AcceptDialogChanged(int);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
@@ -118,7 +112,6 @@ private:
|
|||||||
QComboBox *_deinterlaceOrder;
|
QComboBox *_deinterlaceOrder;
|
||||||
QLabel *_warning;
|
QLabel *_warning;
|
||||||
QPushButton *_refreshSettingSelection;
|
QPushButton *_refreshSettingSelection;
|
||||||
QCheckBox *_acceptDialog;
|
|
||||||
|
|
||||||
std::shared_ptr<MacroActionSource> _entryData;
|
std::shared_ptr<MacroActionSource> _entryData;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
|
|||||||
@@ -31,16 +31,15 @@ bool MacroActionTimer::PerformAction()
|
|||||||
if (!macro) {
|
if (!macro) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
auto conditions = *GetMacroConditions(macro.get());
|
||||||
const auto updateCondition = [this](MacroCondition *condition) {
|
for (auto condition : conditions) {
|
||||||
if (condition->GetId() != id) {
|
if (condition->GetId() != id) {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto timerCondition =
|
auto timerCondition =
|
||||||
dynamic_cast<MacroConditionTimer *>(condition);
|
dynamic_cast<MacroConditionTimer *>(condition.get());
|
||||||
if (!timerCondition) {
|
if (!timerCondition) {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (_actionType) {
|
switch (_actionType) {
|
||||||
@@ -60,23 +59,6 @@ bool MacroActionTimer::PerformAction()
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const auto updateMacro = [&](Macro *macro) {
|
|
||||||
auto conditions = *GetMacroConditions(macro);
|
|
||||||
for (auto condition : conditions) {
|
|
||||||
updateCondition(condition.get());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!IsGroupMacro(macro.get())) {
|
|
||||||
updateMacro(macro.get());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto macros = GetGroupMacroEntries(macro.get());
|
|
||||||
for (const auto ¯o : macros) {
|
|
||||||
updateMacro(macro.get());
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -149,7 +131,7 @@ void MacroActionTimer::ResolveVariablesToFixedValues()
|
|||||||
_duration.ResolveVariables();
|
_duration.ResolveVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void populateTypeSelection(QComboBox *list)
|
static inline void populateTypeSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (const auto &[_, name] : timerActions) {
|
for (const auto &[_, name] : timerActions) {
|
||||||
list->addItem(obs_module_text(name.c_str()));
|
list->addItem(obs_module_text(name.c_str()));
|
||||||
@@ -158,11 +140,12 @@ static void populateTypeSelection(QComboBox *list)
|
|||||||
|
|
||||||
MacroActionTimerEdit::MacroActionTimerEdit(
|
MacroActionTimerEdit::MacroActionTimerEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionTimer> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionTimer> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent)
|
||||||
_macros(new MacroSelection(parent)),
|
|
||||||
_duration(new DurationSelection(this)),
|
|
||||||
_timerAction(new QComboBox(this))
|
|
||||||
{
|
{
|
||||||
|
_macros = new MacroSelection(parent);
|
||||||
|
_duration = new DurationSelection();
|
||||||
|
_timerAction = new QComboBox();
|
||||||
|
|
||||||
populateTypeSelection(_timerAction);
|
populateTypeSelection(_timerAction);
|
||||||
|
|
||||||
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
||||||
@@ -172,13 +155,15 @@ MacroActionTimerEdit::MacroActionTimerEdit(
|
|||||||
QWidget::connect(_timerAction, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_timerAction, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(ActionTypeChanged(int)));
|
SLOT(ActionTypeChanged(int)));
|
||||||
|
|
||||||
auto layout = new QHBoxLayout;
|
_mainLayout = new QHBoxLayout;
|
||||||
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
|
{"{{macros}}", _macros},
|
||||||
|
{"{{duration}}", _duration},
|
||||||
|
{"{{timerAction}}", _timerAction},
|
||||||
|
};
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.timer.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.timer.entry"),
|
||||||
layout,
|
_mainLayout, widgetPlaceholders);
|
||||||
{{"{{macros}}", _macros},
|
setLayout(_mainLayout);
|
||||||
{"{{duration}}", _duration},
|
|
||||||
{"{{timerAction}}", _timerAction}});
|
|
||||||
setLayout(layout);
|
|
||||||
|
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
UpdateEntryData();
|
UpdateEntryData();
|
||||||
|
|||||||
@@ -58,14 +58,16 @@ private slots:
|
|||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void SetWidgetVisibility();
|
void SetWidgetVisibility();
|
||||||
|
|
||||||
MacroSelection *_macros;
|
MacroSelection *_macros;
|
||||||
DurationSelection *_duration;
|
DurationSelection *_duration;
|
||||||
QComboBox *_timerAction;
|
QComboBox *_timerAction;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionTimer> _entryData;
|
std::shared_ptr<MacroActionTimer> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ void MacroConditionProcessEdit::ProcessChanged(const QString &text)
|
|||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionProcessEdit::showEvent(QShowEvent *)
|
void MacroConditionProcessEdit::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
const QSignalBlocker b(_processSelection);
|
const QSignalBlocker b(_processSelection);
|
||||||
const auto text = _processSelection->currentText();
|
const auto text = _processSelection->currentText();
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ static int currentRecordingDurationInSeconds = 0;
|
|||||||
|
|
||||||
bool MacroConditionRecord::CheckCondition()
|
bool MacroConditionRecord::CheckCondition()
|
||||||
{
|
{
|
||||||
char *lastSavePath = obs_frontend_get_last_recording();
|
|
||||||
SetTempVarValue("lastSavePath", lastSavePath ? lastSavePath : "");
|
|
||||||
bfree(lastSavePath);
|
|
||||||
|
|
||||||
switch (_condition) {
|
switch (_condition) {
|
||||||
case Condition::STOP:
|
case Condition::STOP:
|
||||||
return !obs_frontend_recording_active();
|
return !obs_frontend_recording_active();
|
||||||
@@ -78,14 +74,6 @@ void MacroConditionRecord::SetCondition(Condition condition)
|
|||||||
void MacroConditionRecord::SetupTempVars()
|
void MacroConditionRecord::SetupTempVars()
|
||||||
{
|
{
|
||||||
MacroCondition::SetupTempVars();
|
MacroCondition::SetupTempVars();
|
||||||
|
|
||||||
AddTempvar(
|
|
||||||
"lastSavePath",
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.recording.lastSavePath"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.recording.lastSavePath.description"));
|
|
||||||
|
|
||||||
switch (_condition) {
|
switch (_condition) {
|
||||||
case Condition::DURATION:
|
case Condition::DURATION:
|
||||||
AddTempvar(
|
AddTempvar(
|
||||||
|
|||||||
@@ -58,10 +58,6 @@ bool MacroConditionReplayBuffer::ReplayBufferWasSaved()
|
|||||||
|
|
||||||
bool MacroConditionReplayBuffer::CheckCondition()
|
bool MacroConditionReplayBuffer::CheckCondition()
|
||||||
{
|
{
|
||||||
char *lastSavePath = obs_frontend_get_last_replay();
|
|
||||||
SetTempVarValue("lastSavePath", lastSavePath ? lastSavePath : "");
|
|
||||||
bfree(lastSavePath);
|
|
||||||
|
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case Condition::STOP:
|
case Condition::STOP:
|
||||||
return !obs_frontend_replay_buffer_active();
|
return !obs_frontend_replay_buffer_active();
|
||||||
@@ -89,16 +85,6 @@ bool MacroConditionReplayBuffer::Load(obs_data_t *obj)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionReplayBuffer::SetupTempVars()
|
|
||||||
{
|
|
||||||
MacroCondition::SetupTempVars();
|
|
||||||
AddTempvar(
|
|
||||||
"lastSavePath",
|
|
||||||
obs_module_text("AdvSceneSwitcher.tempVar.replay.lastSavePath"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.replay.lastSavePath.description"));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void populateStateSelection(QComboBox *list)
|
static inline void populateStateSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (const auto &entry : conditions) {
|
for (const auto &entry : conditions) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
class MacroConditionReplayBuffer final : public MacroCondition {
|
class MacroConditionReplayBuffer : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
MacroConditionReplayBuffer(Macro *m) : MacroCondition(m) {}
|
MacroConditionReplayBuffer(Macro *m) : MacroCondition(m) {}
|
||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
@@ -27,7 +27,6 @@ public:
|
|||||||
Condition _state = Condition::STOP;
|
Condition _state = Condition::STOP;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupTempVars();
|
|
||||||
bool ReplayBufferWasSaved();
|
bool ReplayBufferWasSaved();
|
||||||
|
|
||||||
bool _saveTimeInitialized = false;
|
bool _saveTimeInitialized = false;
|
||||||
@@ -36,7 +35,7 @@ private:
|
|||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionReplayBufferEdit final : public QWidget {
|
class MacroConditionReplayBufferEdit : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -56,10 +55,11 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void StateChanged(int value);
|
void StateChanged(int value);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
QComboBox *_state;
|
QComboBox *_state;
|
||||||
|
|
||||||
std::shared_ptr<MacroConditionReplayBuffer> _entryData;
|
std::shared_ptr<MacroConditionReplayBuffer> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace advss {
|
|||||||
enum class HotkeyType;
|
enum class HotkeyType;
|
||||||
|
|
||||||
bool CanSimulateKeyPresses();
|
bool CanSimulateKeyPresses();
|
||||||
void PressKeys(const std::vector<HotkeyType> &keys, int duration);
|
void PressKeys(const std::vector<HotkeyType> keys, int duration);
|
||||||
|
|
||||||
class Hotkey {
|
class Hotkey {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ static const std::unordered_map<HotkeyType, long> keyTable = {
|
|||||||
{HotkeyType::Key_NumpadEnter, XK_KP_Enter},
|
{HotkeyType::Key_NumpadEnter, XK_KP_Enter},
|
||||||
};
|
};
|
||||||
|
|
||||||
void PressKeys(const std::vector<HotkeyType> &keys, int duration)
|
void PressKeys(const std::vector<HotkeyType> keys, int duration)
|
||||||
{
|
{
|
||||||
if (!canSimulateKeyPresses) {
|
if (!canSimulateKeyPresses) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ bool CanSimulateKeyPresses()
|
|||||||
return canSimulateKeyPresses;
|
return canSimulateKeyPresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PressKeys(const std::vector<HotkeyType> &, int)
|
void PressKeys(const std::vector<HotkeyType> keys, int duration)
|
||||||
{
|
{
|
||||||
// Not supported on MacOS
|
// Not supported on MacOS
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ findListPropertyById(const obs_source_t *source, const std::string &id)
|
|||||||
}
|
}
|
||||||
auto property = obs_properties_first(properties);
|
auto property = obs_properties_first(properties);
|
||||||
return {findListPropertyByIdHelper(property, id),
|
return {findListPropertyByIdHelper(property, id),
|
||||||
properties_t(properties, obs_properties_destroy)};
|
properties_t(nullptr, obs_properties_destroy)};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::pair<obs_property_t *, properties_t>
|
static std::pair<obs_property_t *, properties_t>
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ static const std::unordered_map<HotkeyType, long> keyTable = {
|
|||||||
{HotkeyType::Key_NumpadEnter, VK_RETURN},
|
{HotkeyType::Key_NumpadEnter, VK_RETURN},
|
||||||
};
|
};
|
||||||
|
|
||||||
void PressKeys(const std::vector<HotkeyType> &keys, int duration)
|
void PressKeys(const std::vector<HotkeyType> keys, int duration)
|
||||||
{
|
{
|
||||||
const int repeatInterval = 100;
|
const int repeatInterval = 100;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ 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"
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ void ScriptHandler::SetVariableValue(void *, calldata_t *data)
|
|||||||
RETURN_SUCCESS();
|
RETURN_SUCCESS();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptHandler::GetRunningStatus(void *, calldata_t *data)
|
void ScriptHandler::GetRunningStatus(void *ctx, calldata_t *data)
|
||||||
{
|
{
|
||||||
calldata_set_bool(data, "is_running", PluginIsRunning());
|
calldata_set_bool(data, "is_running", PluginIsRunning());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,16 +58,14 @@ std::string TwitchChannel::GetUserID(const TwitchToken &token) const
|
|||||||
}
|
}
|
||||||
OBSDataArrayAutoRelease array = obs_data_get_array(res.data, "data");
|
OBSDataArrayAutoRelease array = obs_data_get_array(res.data, "data");
|
||||||
size_t count = obs_data_array_count(array);
|
size_t count = obs_data_array_count(array);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
if (count == 0) {
|
OBSDataAutoRelease arrayObj = obs_data_array_item(array, i);
|
||||||
userIDCache[_name] = "invalid";
|
std::string id = obs_data_get_string(arrayObj, "id");
|
||||||
return "invalid";
|
userIDCache[_name] = id;
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
userIDCache[_name] = "invalid";
|
||||||
OBSDataAutoRelease arrayObj = obs_data_array_item(array, 0);
|
return "invalid";
|
||||||
const std::string id = obs_data_get_string(arrayObj, "id");
|
|
||||||
userIDCache[_name] = id;
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QDate parseRFC3339Date(const std::string &rfc3339Date)
|
static QDate parseRFC3339Date(const std::string &rfc3339Date)
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ void EventSub::UnregisterInstance()
|
|||||||
void EventSub::ConnectThread()
|
void EventSub::ConnectThread()
|
||||||
{
|
{
|
||||||
_client->reset();
|
_client->reset();
|
||||||
|
_connected = true;
|
||||||
websocketpp::lib::error_code ec;
|
websocketpp::lib::error_code ec;
|
||||||
EventSubWSClient::connection_ptr con =
|
EventSubWSClient::connection_ptr con =
|
||||||
_client->get_connection(_url, ec);
|
_client->get_connection(_url, ec);
|
||||||
@@ -112,7 +113,6 @@ void EventSub::Connect()
|
|||||||
_thread.join();
|
_thread.join();
|
||||||
}
|
}
|
||||||
_disconnect = false;
|
_disconnect = false;
|
||||||
_connected = true;
|
|
||||||
_thread = std::thread(&EventSub::ConnectThread, this);
|
_thread = std::thread(&EventSub::ConnectThread, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +448,7 @@ void EventSub::StartServerMigrationClient(const std::string &url)
|
|||||||
auto client = std::make_unique<EventSubWSClient>();
|
auto client = std::make_unique<EventSubWSClient>();
|
||||||
SetupClient(*client);
|
SetupClient(*client);
|
||||||
|
|
||||||
client->set_open_handler([this](connection_hdl) {
|
client->set_open_handler([this](connection_hdl hdl) {
|
||||||
vblog(LOG_INFO, "Twitch EventSub migration client opened");
|
vblog(LOG_INFO, "Twitch EventSub migration client opened");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ const static std::map<MacroActionTwitch::Action, std::string> actionTypes = {
|
|||||||
"AdvSceneSwitcher.action.twitch.type.user.getInfo"},
|
"AdvSceneSwitcher.action.twitch.type.user.getInfo"},
|
||||||
{MacroActionTwitch::Action::POINTS_REWARD_GET_INFO,
|
{MacroActionTwitch::Action::POINTS_REWARD_GET_INFO,
|
||||||
"AdvSceneSwitcher.action.twitch.type.reward.getInfo"},
|
"AdvSceneSwitcher.action.twitch.type.reward.getInfo"},
|
||||||
{MacroActionTwitch::Action::CHANNEL_GET_INFO,
|
|
||||||
"AdvSceneSwitcher.action.twitch.type.channel.getInfo"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const static std::map<MacroActionTwitch::AnnouncementColor, std::string>
|
const static std::map<MacroActionTwitch::AnnouncementColor, std::string>
|
||||||
@@ -324,41 +322,6 @@ void MacroActionTwitch::GetUserInfo(const std::shared_ptr<TwitchToken> &token)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionTwitch::GetChannelInfo(const std::shared_ptr<TwitchToken> &token)
|
|
||||||
{
|
|
||||||
auto info = _channel.GetInfo(*token);
|
|
||||||
if (!info) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetTempVarValue("broadcaster_user_id", info->broadcaster_id);
|
|
||||||
SetTempVarValue("broadcaster_user_login", info->broadcaster_login);
|
|
||||||
SetTempVarValue("broadcaster_user_name", info->broadcaster_name);
|
|
||||||
SetTempVarValue("language", info->broadcaster_language);
|
|
||||||
SetTempVarValue("game_id", info->game_id);
|
|
||||||
SetTempVarValue("game_name", info->game_name);
|
|
||||||
SetTempVarValue("title", info->title);
|
|
||||||
SetTempVarValue("delay", std::to_string(info->delay));
|
|
||||||
std::string tags;
|
|
||||||
for (const auto &tag : info->tags) {
|
|
||||||
tags += tag + " ";
|
|
||||||
}
|
|
||||||
if (!tags.empty()) {
|
|
||||||
tags.pop_back();
|
|
||||||
}
|
|
||||||
SetTempVarValue("tags", tags);
|
|
||||||
std::string classificationLabels;
|
|
||||||
for (const auto &label : info->content_classification_labels) {
|
|
||||||
classificationLabels += label + " ";
|
|
||||||
}
|
|
||||||
if (!classificationLabels.empty()) {
|
|
||||||
classificationLabels.pop_back();
|
|
||||||
}
|
|
||||||
SetTempVarValue("content_classification_labels", classificationLabels);
|
|
||||||
SetTempVarValue("is_branded_content",
|
|
||||||
info->is_branded_content ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionTwitch::ResolveVariableSelectionToRewardId(
|
bool MacroActionTwitch::ResolveVariableSelectionToRewardId(
|
||||||
const std::shared_ptr<TwitchToken> &token)
|
const std::shared_ptr<TwitchToken> &token)
|
||||||
{
|
{
|
||||||
@@ -542,16 +505,6 @@ void MacroActionTwitch::SetupTempVars()
|
|||||||
setupTempVarHelper("offline_image_url", ".user.getInfo");
|
setupTempVarHelper("offline_image_url", ".user.getInfo");
|
||||||
setupTempVarHelper("created_at", ".user.getInfo");
|
setupTempVarHelper("created_at", ".user.getInfo");
|
||||||
break;
|
break;
|
||||||
case Action::CHANNEL_GET_INFO:
|
|
||||||
setupTempVarHelper("language");
|
|
||||||
setupTempVarHelper("game_id");
|
|
||||||
setupTempVarHelper("game_name");
|
|
||||||
setupTempVarHelper("title");
|
|
||||||
setupTempVarHelper("delay");
|
|
||||||
setupTempVarHelper("tags");
|
|
||||||
setupTempVarHelper("content_classification_labels");
|
|
||||||
setupTempVarHelper("is_branded_content");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -610,9 +563,6 @@ bool MacroActionTwitch::PerformAction()
|
|||||||
case MacroActionTwitch::Action::POINTS_REWARD_GET_INFO:
|
case MacroActionTwitch::Action::POINTS_REWARD_GET_INFO:
|
||||||
GetRewardInfo(token);
|
GetRewardInfo(token);
|
||||||
break;
|
break;
|
||||||
case MacroActionTwitch::Action::CHANNEL_GET_INFO:
|
|
||||||
GetChannelInfo(token);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -822,7 +772,6 @@ bool MacroActionTwitch::ActionIsSupportedByToken()
|
|||||||
{Action::WHISPER_SEND, {{"user:manage:whispers"}}},
|
{Action::WHISPER_SEND, {{"user:manage:whispers"}}},
|
||||||
{Action::SEND_CHAT_MESSAGE, {{"chat:edit"}}},
|
{Action::SEND_CHAT_MESSAGE, {{"chat:edit"}}},
|
||||||
{Action::USER_GET_INFO, {}},
|
{Action::USER_GET_INFO, {}},
|
||||||
{Action::CHANNEL_GET_INFO, {}},
|
|
||||||
{Action::POINTS_REWARD_GET_INFO,
|
{Action::POINTS_REWARD_GET_INFO,
|
||||||
{{"channel:read:redemptions"},
|
{{"channel:read:redemptions"},
|
||||||
{"channel:manage:redemptions"}}}};
|
{"channel:manage:redemptions"}}}};
|
||||||
@@ -1178,8 +1127,6 @@ void MacroActionTwitchEdit::SetWidgetVisibility()
|
|||||||
_entryData->GetAction() ==
|
_entryData->GetAction() ==
|
||||||
MacroActionTwitch::Action::CHANNEL_INFO_CONTENT_LABELS_SET);
|
MacroActionTwitch::Action::CHANNEL_INFO_CONTENT_LABELS_SET);
|
||||||
_channel->setVisible(
|
_channel->setVisible(
|
||||||
_entryData->GetAction() ==
|
|
||||||
MacroActionTwitch::Action::CHANNEL_GET_INFO ||
|
|
||||||
_entryData->GetAction() ==
|
_entryData->GetAction() ==
|
||||||
MacroActionTwitch::Action::RAID_START ||
|
MacroActionTwitch::Action::RAID_START ||
|
||||||
_entryData->GetAction() ==
|
_entryData->GetAction() ==
|
||||||
@@ -1326,23 +1273,19 @@ void MacroActionTwitchEdit::SetWidgetLayout()
|
|||||||
switch (_entryData->GetAction()) {
|
switch (_entryData->GetAction()) {
|
||||||
case MacroActionTwitch::Action::SEND_CHAT_MESSAGE:
|
case MacroActionTwitch::Action::SEND_CHAT_MESSAGE:
|
||||||
layoutText = obs_module_text(
|
layoutText = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.twitch.layout.chat");
|
"AdvSceneSwitcher.action.twitch.entry.chat");
|
||||||
break;
|
break;
|
||||||
case MacroActionTwitch::Action::USER_GET_INFO:
|
case MacroActionTwitch::Action::USER_GET_INFO:
|
||||||
layoutText = obs_module_text(
|
layoutText = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.twitch.layout.user.getInfo");
|
"AdvSceneSwitcher.action.twitch.entry.user.getInfo");
|
||||||
break;
|
break;
|
||||||
case MacroActionTwitch::Action::POINTS_REWARD_GET_INFO:
|
case MacroActionTwitch::Action::POINTS_REWARD_GET_INFO:
|
||||||
layoutText = obs_module_text(
|
layoutText = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.twitch.layout.reward.getInfo");
|
"AdvSceneSwitcher.action.twitch.entry.reward.getInfo");
|
||||||
break;
|
|
||||||
case MacroActionTwitch::Action::CHANNEL_GET_INFO:
|
|
||||||
layoutText = obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.twitch.layout.channel.getInfo");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
layoutText = obs_module_text(
|
layoutText = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.twitch.layout.default");
|
"AdvSceneSwitcher.action.twitch.entry.default");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,8 +142,7 @@ public:
|
|||||||
SEND_CHAT_MESSAGE = 5000,
|
SEND_CHAT_MESSAGE = 5000,
|
||||||
|
|
||||||
// Get user info
|
// Get user info
|
||||||
USER_GET_INFO = 6000,
|
USER_GET_INFO = 6000
|
||||||
CHANNEL_GET_INFO = 6100,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class AnnouncementColor {
|
enum class AnnouncementColor {
|
||||||
@@ -204,7 +203,6 @@ private:
|
|||||||
void SendChatMessage(const std::shared_ptr<TwitchToken> &);
|
void SendChatMessage(const std::shared_ptr<TwitchToken> &);
|
||||||
void GetUserInfo(const std::shared_ptr<TwitchToken> &);
|
void GetUserInfo(const std::shared_ptr<TwitchToken> &);
|
||||||
void GetRewardInfo(const std::shared_ptr<TwitchToken> &);
|
void GetRewardInfo(const std::shared_ptr<TwitchToken> &);
|
||||||
void GetChannelInfo(const std::shared_ptr<TwitchToken> &token);
|
|
||||||
|
|
||||||
bool ResolveVariableSelectionToRewardId(
|
bool ResolveVariableSelectionToRewardId(
|
||||||
const std::shared_ptr<TwitchToken> &);
|
const std::shared_ptr<TwitchToken> &);
|
||||||
|
|||||||
@@ -629,7 +629,7 @@ void MacroConditionTwitch::SetTempVarValues(const ChannelInfo &info)
|
|||||||
if (!classificationLabels.empty()) {
|
if (!classificationLabels.empty()) {
|
||||||
classificationLabels.pop_back();
|
classificationLabels.pop_back();
|
||||||
}
|
}
|
||||||
SetTempVarValue("content_classification_labels", classificationLabels);
|
SetTempVarValue("content_classification_labels", tags);
|
||||||
SetTempVarValue("is_branded_content",
|
SetTempVarValue("is_branded_content",
|
||||||
info.is_branded_content ? "true" : "false");
|
info.is_branded_content ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "token.hpp"
|
#include "token.hpp"
|
||||||
#include "twitch-helpers.hpp"
|
#include "twitch-helpers.hpp"
|
||||||
|
|
||||||
#include <help-icon.hpp>
|
|
||||||
#include <layout-helpers.hpp>
|
#include <layout-helpers.hpp>
|
||||||
#include <log-helper.hpp>
|
#include <log-helper.hpp>
|
||||||
#include <obs-module-helper.hpp>
|
#include <obs-module-helper.hpp>
|
||||||
@@ -164,8 +163,7 @@ TwitchToken::TwitchToken(const TwitchToken &other)
|
|||||||
_userID(other._userID),
|
_userID(other._userID),
|
||||||
_tokenOptions(other._tokenOptions),
|
_tokenOptions(other._tokenOptions),
|
||||||
_eventSub(),
|
_eventSub(),
|
||||||
_validateEventSubTimestamps(other._validateEventSubTimestamps),
|
_validateEventSubTimestamps(other._validateEventSubTimestamps)
|
||||||
_warnIfInvalid(other._warnIfInvalid)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +174,6 @@ TwitchToken &TwitchToken::operator=(const TwitchToken &other)
|
|||||||
_userID = other._userID;
|
_userID = other._userID;
|
||||||
_tokenOptions = other._tokenOptions;
|
_tokenOptions = other._tokenOptions;
|
||||||
_validateEventSubTimestamps = other._validateEventSubTimestamps;
|
_validateEventSubTimestamps = other._validateEventSubTimestamps;
|
||||||
_warnIfInvalid = other._warnIfInvalid;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,9 +185,6 @@ void TwitchToken::Load(obs_data_t *obj)
|
|||||||
obs_data_set_default_bool(obj, "validateEventSubTimestamps", true);
|
obs_data_set_default_bool(obj, "validateEventSubTimestamps", true);
|
||||||
_validateEventSubTimestamps =
|
_validateEventSubTimestamps =
|
||||||
obs_data_get_bool(obj, "validateEventSubTimestamps");
|
obs_data_get_bool(obj, "validateEventSubTimestamps");
|
||||||
_warnIfInvalid = obs_data_has_user_value(obj, "warnIfInvalid")
|
|
||||||
? obs_data_get_bool(obj, "warnIfInvalid")
|
|
||||||
: true;
|
|
||||||
_tokenOptions.clear();
|
_tokenOptions.clear();
|
||||||
OBSDataArrayAutoRelease options = obs_data_get_array(obj, "options");
|
OBSDataArrayAutoRelease options = obs_data_get_array(obj, "options");
|
||||||
size_t count = obs_data_array_count(options);
|
size_t count = obs_data_array_count(options);
|
||||||
@@ -209,7 +203,6 @@ void TwitchToken::Save(obs_data_t *obj) const
|
|||||||
obs_data_set_string(obj, "userID", _userID.c_str());
|
obs_data_set_string(obj, "userID", _userID.c_str());
|
||||||
obs_data_set_bool(obj, "validateEventSubTimestamps",
|
obs_data_set_bool(obj, "validateEventSubTimestamps",
|
||||||
_validateEventSubTimestamps);
|
_validateEventSubTimestamps);
|
||||||
obs_data_set_bool(obj, "warnIfInvalid", _warnIfInvalid);
|
|
||||||
OBSDataArrayAutoRelease options = obs_data_array_create();
|
OBSDataArrayAutoRelease options = obs_data_array_create();
|
||||||
for (auto &option : _tokenOptions) {
|
for (auto &option : _tokenOptions) {
|
||||||
OBSDataAutoRelease arrayObj = obs_data_create();
|
OBSDataAutoRelease arrayObj = obs_data_create();
|
||||||
@@ -484,9 +477,7 @@ TwitchTokenSettingsDialog::TwitchTokenSettingsDialog(
|
|||||||
_tokenStatus(new QLabel()),
|
_tokenStatus(new QLabel()),
|
||||||
_generalSettingsGrid(new QGridLayout()),
|
_generalSettingsGrid(new QGridLayout()),
|
||||||
_validateTimestamps(new QCheckBox(obs_module_text(
|
_validateTimestamps(new QCheckBox(obs_module_text(
|
||||||
"AdvSceneSwitcher.twitchToken.validateTimestamps"))),
|
"AdvSceneSwitcher.twitchToken.validateTimestamps")))
|
||||||
_warnIfInvalid(new QCheckBox(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.twitchToken.warnIfInvalid")))
|
|
||||||
{
|
{
|
||||||
_showToken->setMaximumWidth(22);
|
_showToken->setMaximumWidth(22);
|
||||||
_showToken->setFlat(true);
|
_showToken->setFlat(true);
|
||||||
@@ -548,18 +539,11 @@ TwitchTokenSettingsDialog::TwitchTokenSettingsDialog(
|
|||||||
scrollArea->setWidgetResizable(true);
|
scrollArea->setWidgetResizable(true);
|
||||||
scrollArea->setFrameShape(QFrame::NoFrame);
|
scrollArea->setFrameShape(QFrame::NoFrame);
|
||||||
|
|
||||||
auto timestampsLayout = new QHBoxLayout();
|
|
||||||
timestampsLayout->addWidget(_validateTimestamps);
|
|
||||||
auto timestampHelp = new HelpIcon(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.twitchToken.validateTimestamps.tooltip"));
|
|
||||||
timestampsLayout->addWidget(timestampHelp);
|
|
||||||
|
|
||||||
auto contentWidget = new QWidget(scrollArea);
|
auto contentWidget = new QWidget(scrollArea);
|
||||||
auto layout = new QVBoxLayout(contentWidget);
|
auto layout = new QVBoxLayout(contentWidget);
|
||||||
layout->addLayout(_generalSettingsGrid);
|
layout->addLayout(_generalSettingsGrid);
|
||||||
layout->addWidget(optionsBox);
|
layout->addWidget(optionsBox);
|
||||||
layout->addLayout(timestampsLayout);
|
layout->addWidget(_validateTimestamps);
|
||||||
layout->addWidget(_warnIfInvalid);
|
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
scrollArea->setWidget(contentWidget);
|
scrollArea->setWidget(contentWidget);
|
||||||
|
|
||||||
@@ -585,7 +569,6 @@ TwitchTokenSettingsDialog::TwitchTokenSettingsDialog(
|
|||||||
#ifndef VERIFY_TIMESTAMPS
|
#ifndef VERIFY_TIMESTAMPS
|
||||||
_validateTimestamps->hide();
|
_validateTimestamps->hide();
|
||||||
#endif
|
#endif
|
||||||
_warnIfInvalid->setChecked(settings._warnIfInvalid);
|
|
||||||
|
|
||||||
_currentToken = settings;
|
_currentToken = settings;
|
||||||
|
|
||||||
@@ -794,8 +777,6 @@ bool TwitchTokenSettingsDialog::AskForSettings(QWidget *parent,
|
|||||||
settings._tokenOptions = dialog.GetEnabledOptions();
|
settings._tokenOptions = dialog.GetEnabledOptions();
|
||||||
settings._validateEventSubTimestamps =
|
settings._validateEventSubTimestamps =
|
||||||
dialog._validateTimestamps->isChecked();
|
dialog._validateTimestamps->isChecked();
|
||||||
settings._warnIfInvalid = dialog._warnIfInvalid->isChecked();
|
|
||||||
|
|
||||||
if (settings._eventSub) {
|
if (settings._eventSub) {
|
||||||
settings._eventSub->EnableTimestampValidation(
|
settings._eventSub->EnableTimestampValidation(
|
||||||
settings._validateEventSubTimestamps);
|
settings._validateEventSubTimestamps);
|
||||||
@@ -829,7 +810,7 @@ void TokenGrabberThread::run()
|
|||||||
if (_serverThread.joinable()) {
|
if (_serverThread.joinable()) {
|
||||||
_serverThread.join();
|
_serverThread.join();
|
||||||
}
|
}
|
||||||
_stopWaiting = false;
|
_stopWaiting = {false};
|
||||||
|
|
||||||
// Generate URI to request token
|
// Generate URI to request token
|
||||||
auto state = generateStateString();
|
auto state = generateStateString();
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ public:
|
|||||||
std::shared_ptr<EventSub> GetEventSub();
|
std::shared_ptr<EventSub> GetEventSub();
|
||||||
bool ValidateTimestamps() const { return _validateEventSubTimestamps; }
|
bool ValidateTimestamps() const { return _validateEventSubTimestamps; }
|
||||||
bool IsValid(bool forceUpdate = false) const;
|
bool IsValid(bool forceUpdate = false) const;
|
||||||
bool WarnIfInvalid() const { return _warnIfInvalid; }
|
|
||||||
void SetWarnIfInvalid(bool value) { _warnIfInvalid = value; }
|
|
||||||
size_t PermissionCount() const { return _tokenOptions.size(); }
|
size_t PermissionCount() const { return _tokenOptions.size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -69,7 +67,6 @@ private:
|
|||||||
std::set<TokenOption> _tokenOptions = TokenOption::GetAllTokenOptions();
|
std::set<TokenOption> _tokenOptions = TokenOption::GetAllTokenOptions();
|
||||||
std::shared_ptr<EventSub> _eventSub;
|
std::shared_ptr<EventSub> _eventSub;
|
||||||
bool _validateEventSubTimestamps = false;
|
bool _validateEventSubTimestamps = false;
|
||||||
bool _warnIfInvalid = true;
|
|
||||||
|
|
||||||
static bool _setup;
|
static bool _setup;
|
||||||
|
|
||||||
@@ -134,7 +131,6 @@ private:
|
|||||||
TwitchToken _currentToken;
|
TwitchToken _currentToken;
|
||||||
std::unordered_map<std::string, QCheckBox *> _optionWidgets;
|
std::unordered_map<std::string, QCheckBox *> _optionWidgets;
|
||||||
QCheckBox *_validateTimestamps;
|
QCheckBox *_validateTimestamps;
|
||||||
QCheckBox *_warnIfInvalid;
|
|
||||||
QTimer _validationTimer;
|
QTimer _validationTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -144,14 +144,9 @@ static void handleThrottling(const httplib::Result &response)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sleepDuration < std::chrono::seconds(1)) {
|
blog(LOG_WARNING, "Twitch API access is throttled for %lld seconds!",
|
||||||
sleepDuration = std::chrono::seconds(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
blog(LOG_WARNING,
|
|
||||||
"Twitch API access is throttled for %lld milliseconds!",
|
|
||||||
static_cast<long long int>(
|
static_cast<long long int>(
|
||||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
sleepDuration)
|
sleepDuration)
|
||||||
.count()));
|
.count()));
|
||||||
apiIsThrottling = true;
|
apiIsThrottling = true;
|
||||||
|
|||||||
@@ -1,47 +1,24 @@
|
|||||||
#include "twitch-tab.hpp"
|
#include "twitch-tab.hpp"
|
||||||
#include "obs-module-helper.hpp"
|
#include "obs-module-helper.hpp"
|
||||||
#include "plugin-state-helpers.hpp"
|
|
||||||
#include "sync-helpers.hpp"
|
#include "sync-helpers.hpp"
|
||||||
#include "tab-helpers.hpp"
|
#include "tab-helpers.hpp"
|
||||||
#include "token.hpp"
|
#include "token.hpp"
|
||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
static bool setup();
|
static bool registerTab();
|
||||||
static void setupTab(QTabWidget *);
|
static void setupTab(QTabWidget *);
|
||||||
static bool setupDone = setup();
|
static bool registerTabDone = registerTab();
|
||||||
|
|
||||||
static TwitchConnectionsTable *tabWidget = nullptr;
|
static TwitchConnectionsTable *tabWidget = nullptr;
|
||||||
|
|
||||||
static QStringList getInvalidTokens();
|
static bool registerTab()
|
||||||
|
|
||||||
static bool setup()
|
|
||||||
{
|
{
|
||||||
AddSetupTabCallback("twitchConnectionTab",
|
AddSetupTabCallback("twitchConnectionTab",
|
||||||
TwitchConnectionsTable::Create, setupTab);
|
TwitchConnectionsTable::Create, setupTab);
|
||||||
|
|
||||||
static const auto showInvalidWarnings = []() {
|
|
||||||
const auto invalidTokens = getInvalidTokens();
|
|
||||||
for (const auto &token : invalidTokens) {
|
|
||||||
QueueUITask(
|
|
||||||
[](void *tokenPtr) {
|
|
||||||
auto tokenName = static_cast<QString *>(
|
|
||||||
tokenPtr);
|
|
||||||
InvalidTokenDialog::ShowWarning(
|
|
||||||
*tokenName);
|
|
||||||
},
|
|
||||||
(void *)&token);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AddLoadStep([](obs_data_t *) {
|
|
||||||
AddPostLoadStep([]() { showInvalidWarnings(); });
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,25 +188,6 @@ static void updateConnectionStatus(QTableWidget *table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QStringList getInvalidTokens()
|
|
||||||
{
|
|
||||||
QStringList tokens;
|
|
||||||
for (const auto &t : GetTwitchTokens()) {
|
|
||||||
if (!t) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto token = std::static_pointer_cast<TwitchToken>(t);
|
|
||||||
if (!token->WarnIfInvalid() || token->IsValid(true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens << QString::fromStdString(token->GetName());
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setupTab(QTabWidget *tab)
|
static void setupTab(QTabWidget *tab)
|
||||||
{
|
{
|
||||||
if (GetTwitchTokens().empty()) {
|
if (GetTwitchTokens().empty()) {
|
||||||
@@ -264,63 +222,6 @@ static void setupTab(QTabWidget *tab)
|
|||||||
updateConnectionStatus(tabWidget->Table());
|
updateConnectionStatus(tabWidget->Table());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto invalidTokens = getInvalidTokens();
|
|
||||||
for (const auto &token : invalidTokens) {
|
|
||||||
// Constructing the warning dialog in the constructor of the settings
|
|
||||||
// window might lead to a crash, so wait for the settings window
|
|
||||||
// constructor to complete
|
|
||||||
QTimer::singleShot(0, tab, [token]() {
|
|
||||||
InvalidTokenDialog::ShowWarning(token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InvalidTokenDialog::ShowWarning(const QString &tokenName)
|
|
||||||
{
|
|
||||||
auto weakToken = GetWeakTwitchTokenByQString(tokenName);
|
|
||||||
auto token = weakToken.lock();
|
|
||||||
if (!token) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto dialog = new InvalidTokenDialog(tokenName);
|
|
||||||
dialog->setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
|
||||||
const bool ignore = dialog->exec() != DialogCode::Accepted;
|
|
||||||
token->SetWarnIfInvalid(!dialog->_doNotShowAgain->isChecked());
|
|
||||||
dialog->deleteLater();
|
|
||||||
|
|
||||||
if (ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TwitchTokenSettingsDialog::AskForSettings(GetSettingsWindow(),
|
|
||||||
*token.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidTokenDialog::InvalidTokenDialog(const QString &name)
|
|
||||||
: QDialog(GetSettingsWindow()),
|
|
||||||
_doNotShowAgain(new QCheckBox(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.twitchToken.warnIfInvalid.doNotShowAgain")))
|
|
||||||
{
|
|
||||||
auto buttons = new QDialogButtonBox(QDialogButtonBox::Ignore |
|
|
||||||
QDialogButtonBox::Open);
|
|
||||||
|
|
||||||
connect(buttons->button(QDialogButtonBox::Ignore),
|
|
||||||
&QPushButton::clicked, this, &QDialog::reject);
|
|
||||||
connect(buttons->button(QDialogButtonBox::Open), &QPushButton::clicked,
|
|
||||||
this, &QDialog::accept);
|
|
||||||
buttons->setCenterButtons(true);
|
|
||||||
|
|
||||||
const QString format(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.twitchToken.warnIfInvalid.message"));
|
|
||||||
const QString message = format.arg(name);
|
|
||||||
|
|
||||||
auto layout = new QVBoxLayout;
|
|
||||||
layout->addWidget(new QLabel(message));
|
|
||||||
layout->addWidget(_doNotShowAgain);
|
|
||||||
layout->addWidget(buttons);
|
|
||||||
setLayout(layout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "resource-table.hpp"
|
#include "resource-table.hpp"
|
||||||
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
class TwitchConnectionsTable final : public ResourceTable {
|
class TwitchConnectionsTable final : public ResourceTable {
|
||||||
@@ -20,14 +17,4 @@ private:
|
|||||||
TwitchConnectionsTable(QTabWidget *parent = nullptr);
|
TwitchConnectionsTable(QTabWidget *parent = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class InvalidTokenDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
static void ShowWarning(const QString &name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
InvalidTokenDialog(const QString &name);
|
|
||||||
QCheckBox *_doNotShowAgain;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -106,11 +106,8 @@ target_sources(
|
|||||||
|
|
||||||
# --- variable --- #
|
# --- variable --- #
|
||||||
|
|
||||||
if(OS_WINDOWS)
|
if(NOT OS_WINDOWS)
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE /wd4100)
|
target_compile_options(${PROJECT_NAME} PUBLIC -Wno-error=shadow)
|
||||||
else()
|
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-error=shadow
|
|
||||||
-Wno-unused-parameter)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_sources(
|
target_sources(
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ std::string GetThemeTypeName()
|
|||||||
return "Dark";
|
return "Dark";
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueUITask(void (*task)(void *param), void *) {}
|
void QeueUITask(void (*task)(void *param), void *) {}
|
||||||
|
|
||||||
QWidget *GetSettingsWindow()
|
QWidget *GetSettingsWindow()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user