mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-30 21:25:32 -05:00
Compare commits
2 Commits
master
...
websocket-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d568683f7 | ||
|
|
a26c37021d |
@@ -19,9 +19,14 @@ inputs:
|
|||||||
runs:
|
runs:
|
||||||
using: 'composite'
|
using: 'composite'
|
||||||
steps:
|
steps:
|
||||||
|
- name: Setup cmake
|
||||||
|
uses: jwlawson/actions-setup-cmake@v1.13
|
||||||
|
with:
|
||||||
|
cmake-version: '3.24.x'
|
||||||
|
|
||||||
- name: Restore cached dependencies
|
- name: Restore cached dependencies
|
||||||
id: restore-cache
|
id: restore-cache
|
||||||
uses: actions/cache@v5
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ env.DEP_DIR }}
|
path: ${{ env.DEP_DIR }}
|
||||||
key: ${{ env.DEP_DIR }}-${{ runner.os }}-${{ inputs.target }}
|
key: ${{ env.DEP_DIR }}-${{ runner.os }}-${{ inputs.target }}
|
||||||
|
|||||||
2
.github/actions/run-clang-format/action.yaml
vendored
2
.github/actions/run-clang-format/action.yaml
vendored
@@ -29,7 +29,6 @@ runs:
|
|||||||
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
|
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
|
||||||
echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
|
echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH
|
||||||
echo "/home/linuxbrew/.linuxbrew/opt/clang-format@16/bin" >> $GITHUB_PATH
|
echo "/home/linuxbrew/.linuxbrew/opt/clang-format@16/bin" >> $GITHUB_PATH
|
||||||
brew update
|
|
||||||
brew install --quiet zsh
|
brew install --quiet zsh
|
||||||
echo ::endgroup::
|
echo ::endgroup::
|
||||||
|
|
||||||
@@ -53,7 +52,6 @@ runs:
|
|||||||
|
|
||||||
if (( ${changes[(I)(*.c|*.h|*.cpp|*.hpp|*.m|*.mm)]} )) {
|
if (( ${changes[(I)(*.c|*.h|*.cpp|*.hpp|*.m|*.mm)]} )) {
|
||||||
echo ::group::Install clang-format-16
|
echo ::group::Install clang-format-16
|
||||||
brew update
|
|
||||||
brew install --quiet obsproject/tools/clang-format@16
|
brew install --quiet obsproject/tools/clang-format@16
|
||||||
echo ::endgroup::
|
echo ::endgroup::
|
||||||
|
|
||||||
|
|||||||
1
.github/scripts/.Aptfile
vendored
1
.github/scripts/.Aptfile
vendored
@@ -8,7 +8,6 @@ package 'libcurl4-openssl-dev'
|
|||||||
package 'libxtst-dev'
|
package 'libxtst-dev'
|
||||||
package 'libxss-dev'
|
package 'libxss-dev'
|
||||||
package 'libopencv-dev'
|
package 'libopencv-dev'
|
||||||
package 'libopencv-contrib-dev'
|
|
||||||
package 'libtesseract-dev'
|
package 'libtesseract-dev'
|
||||||
package 'libproc2-dev'
|
package 'libproc2-dev'
|
||||||
package 'libusb-1.0-0-dev'
|
package 'libusb-1.0-0-dev'
|
||||||
|
|||||||
2
.github/scripts/.Wingetfile
vendored
2
.github/scripts/.Wingetfile
vendored
@@ -1,4 +1,4 @@
|
|||||||
package 'cmake', path: 'Cmake\bin', bin: 'cmake'
|
package 'cmake', path: 'Cmake\bin', bin: 'cmake'
|
||||||
package 'innosetup', path: 'Inno Setup 6', bin: 'iscc'
|
package 'innosetup', path: 'Inno Setup 6', bin: 'iscc'
|
||||||
package 'OpenSSL', path: 'OpenSSL', bin: 'openssl', version: '3.6.2'
|
package 'OpenSSL', path: 'OpenSSL', bin: 'openssl'
|
||||||
package 'Microsoft.VisualStudio.Locator', path: 'vswhere', bin: 'vswhere'
|
package 'Microsoft.VisualStudio.Locator', path: 'vswhere', bin: 'vswhere'
|
||||||
102
.github/scripts/.build-deps.zsh
vendored
102
.github/scripts/.build-deps.zsh
vendored
@@ -284,56 +284,30 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
case ${host_os} {
|
case ${host_os} {
|
||||||
macos)
|
macos)
|
||||||
local opencv_dir="${project_root}/deps/opencv"
|
local opencv_dir="${project_root}/deps/opencv"
|
||||||
local opencv_contrib_dir="${project_root}/deps/opencv_contrib"
|
local opencv_build_dir="${opencv_dir}/build_${target##*-}"
|
||||||
local opencv_install_x86="${opencv_dir}/install_x86_64"
|
|
||||||
local opencv_install_arm="${opencv_dir}/install_arm64"
|
|
||||||
|
|
||||||
local -a opencv_cmake_args_common=(
|
local -a opencv_cmake_args=(
|
||||||
-DCMAKE_BUILD_TYPE=Release
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
-DBUILD_LIST=core,imgproc,objdetect,xobjdetect,dnn
|
-DBUILD_LIST=core,imgproc,objdetect
|
||||||
-DOPENCV_EXTRA_MODULES_PATH="${opencv_contrib_dir}/modules"
|
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||||
-DCMAKE_PREFIX_PATH="${advss_dep_path};${_plugin_deps}"
|
-DCMAKE_PREFIX_PATH="${advss_dep_path};${_plugin_deps}"
|
||||||
-DWITH_KLEIDICV=OFF
|
-DCMAKE_INSTALL_PREFIX="${advss_dep_path}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if [ "${target}" != "macos-x86_64" ]; then
|
||||||
|
opencv_cmake_args+=(-DWITH_IPP=OFF)
|
||||||
|
fi
|
||||||
|
|
||||||
pushd ${opencv_dir}
|
pushd ${opencv_dir}
|
||||||
|
log_info "Configure OpenCV ..."
|
||||||
|
cmake -S . -B ${opencv_build_dir} ${opencv_cmake_args}
|
||||||
|
|
||||||
log_info "Configure OpenCV (x86_64) ..."
|
log_info "Building OpenCV ..."
|
||||||
cmake -S . -B build_x86_64 ${opencv_cmake_args_common} \
|
cmake --build ${opencv_build_dir} --config Release
|
||||||
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
|
||||||
-DCMAKE_PROJECT_INCLUDE="${SCRIPT_HOME}/opencv-force-processor-x86_64.cmake" \
|
|
||||||
-DCMAKE_INSTALL_PREFIX="${opencv_install_x86}" \
|
|
||||||
-DWITH_IPP=OFF
|
|
||||||
|
|
||||||
log_info "Building OpenCV (x86_64) ..."
|
log_info "Installing OpenCV ..."
|
||||||
cmake --build build_x86_64 --config Release
|
cmake --install ${opencv_build_dir} --prefix "${advss_dep_path}" --config Release || true
|
||||||
|
|
||||||
log_info "Installing OpenCV (x86_64) ..."
|
|
||||||
cmake --install build_x86_64 --prefix "${opencv_install_x86}" --config Release || true
|
|
||||||
|
|
||||||
log_info "Configure OpenCV (arm64) ..."
|
|
||||||
cmake -S . -B build_arm64 ${opencv_cmake_args_common} \
|
|
||||||
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
|
||||||
-DCMAKE_INSTALL_PREFIX="${opencv_install_arm}"
|
|
||||||
|
|
||||||
log_info "Building OpenCV (arm64) ..."
|
|
||||||
cmake --build build_arm64 --config Release
|
|
||||||
|
|
||||||
log_info "Installing OpenCV (arm64) ..."
|
|
||||||
cmake --install build_arm64 --prefix "${opencv_install_arm}" --config Release || true
|
|
||||||
|
|
||||||
log_info "Merging OpenCV into universal binaries ..."
|
|
||||||
cp -R "${opencv_install_arm}/." "${advss_dep_path}"
|
|
||||||
for arm_lib in ${opencv_install_arm}/lib/**/*.(dylib|a)(.); do
|
|
||||||
local rel="${arm_lib#${opencv_install_arm}/}"
|
|
||||||
local x86_lib="${opencv_install_x86}/${rel}"
|
|
||||||
if [[ -f "${x86_lib}" ]]; then
|
|
||||||
lipo -create "${x86_lib}" "${arm_lib}" -output "${advss_dep_path}/${rel}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
rm -rf "${opencv_install_x86}" "${opencv_install_arm}"
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
local leptonica_dir="${project_root}/deps/leptonica"
|
local leptonica_dir="${project_root}/deps/leptonica"
|
||||||
@@ -345,7 +319,7 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||||
-DSW_BUILD=OFF
|
-DSW_BUILD=OFF
|
||||||
-DOPENJPEG_SUPPORT=OFF
|
-DOPENJPEG_SUPPORT=OFF
|
||||||
-DENABLE_WEBP=OFF
|
-DLIBWEBP_SUPPORT=OFF
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_GIF=TRUE
|
-DCMAKE_DISABLE_FIND_PACKAGE_GIF=TRUE
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_JPEG=TRUE
|
-DCMAKE_DISABLE_FIND_PACKAGE_JPEG=TRUE
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_TIFF=TRUE
|
-DCMAKE_DISABLE_FIND_PACKAGE_TIFF=TRUE
|
||||||
@@ -420,11 +394,8 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
pushd ${advss_dep_path}
|
||||||
log_info "Prepare openssl ..."
|
log_info "Prepare openssl ..."
|
||||||
rm -rf ${advss_dep_path}/openssl ${advss_dep_path}/openssl_build
|
|
||||||
mkdir ${advss_dep_path}/openssl_build
|
|
||||||
pushd ${advss_dep_path}/openssl_build
|
|
||||||
|
|
||||||
rm -rf openssl
|
rm -rf openssl
|
||||||
git clone https://github.com/openssl/openssl.git --branch openssl-3.1.2 --depth 1
|
git clone https://github.com/openssl/openssl.git --branch openssl-3.1.2 --depth 1
|
||||||
mv openssl openssl_x86
|
mv openssl openssl_x86
|
||||||
@@ -432,27 +403,25 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
|
|
||||||
log_info "Building openssl x86 ..."
|
log_info "Building openssl x86 ..."
|
||||||
export MACOSX_DEPLOYMENT_TARGET=10.9
|
export MACOSX_DEPLOYMENT_TARGET=10.9
|
||||||
pushd openssl_x86
|
cd openssl_x86
|
||||||
./Configure darwin64-x86_64-cc no-shared no-module no-zlib --prefix=${advss_dep_path}
|
./Configure darwin64-x86_64-cc shared
|
||||||
make -j$(nproc)
|
make
|
||||||
popd
|
|
||||||
|
|
||||||
log_info "Building openssl arm ..."
|
log_info "Building openssl arm ..."
|
||||||
export MACOSX_DEPLOYMENT_TARGET=10.15
|
export MACOSX_DEPLOYMENT_TARGET=10.15
|
||||||
pushd openssl_arm
|
cd ../openssl_arm
|
||||||
./Configure enable-rc5 darwin64-arm64-cc no-shared no-module no-asm no-zlib --prefix=${advss_dep_path}
|
./Configure enable-rc5 zlib darwin64-arm64-cc no-asm
|
||||||
make -j$(nproc)
|
make
|
||||||
|
|
||||||
log_info "Install openssl ..."
|
|
||||||
make install
|
|
||||||
popd
|
|
||||||
|
|
||||||
log_info "Combine arm and x86 openssl binaries ..."
|
log_info "Combine arm and x86 openssl binaries ..."
|
||||||
lipo -create openssl_x86/libcrypto.a openssl_arm/libcrypto.a -output ${advss_dep_path}/lib/libcrypto.a
|
cd ..
|
||||||
lipo -create openssl_x86/libssl.a openssl_arm/libssl.a -output ${advss_dep_path}/lib/libssl.a
|
mkdir openssl-combined
|
||||||
|
lipo -create openssl_x86/libcrypto.a openssl_arm/libcrypto.a -output openssl-combined/libcrypto.a
|
||||||
|
lipo -create openssl_x86/libssl.a openssl_arm/libssl.a -output openssl-combined/libssl.a
|
||||||
|
|
||||||
log_info "Clean up openssl dir ..."
|
log_info "Clean up openssl dir ..."
|
||||||
rm -rf openssl_x86 openssl_arm
|
mv openssl_x86 openssl
|
||||||
|
rm -rf openssl_arm
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd ${project_root}/deps/libusb
|
pushd ${project_root}/deps/libusb
|
||||||
@@ -470,16 +439,14 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
mkdir ${project_root}/deps/libusb/out_x86
|
mkdir ${project_root}/deps/libusb/out_x86
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure --host=x86_64-apple-darwin --prefix=${advss_dep_path}
|
./configure --host=x86_64-apple-darwin --prefix=${advss_dep_path}
|
||||||
make -j$(nproc)
|
make && make install
|
||||||
make install
|
|
||||||
|
|
||||||
log_info "Configure libusb arm ..."
|
log_info "Configure libusb arm ..."
|
||||||
make clean
|
make clean
|
||||||
rm -r ${project_root}/deps/libusb/out_x86
|
rm -r ${project_root}/deps/libusb/out_x86
|
||||||
mkdir ${project_root}/deps/libusb/out_x86
|
mkdir ${project_root}/deps/libusb/out_x86
|
||||||
./configure --host=aarch64-apple-darwin --prefix=${project_root}/deps/libusb/out_x86
|
./configure --host=aarch64-apple-darwin --prefix=${project_root}/deps/libusb/out_x86
|
||||||
make -j$(nproc)
|
make && make install
|
||||||
make install
|
|
||||||
|
|
||||||
log_info "Building libusb arm ..."
|
log_info "Building libusb arm ..."
|
||||||
make clean
|
make clean
|
||||||
@@ -492,8 +459,7 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
export MACOSX_DEPLOYMENT_TARGET=10.15
|
export MACOSX_DEPLOYMENT_TARGET=10.15
|
||||||
mkdir ${project_root}/deps/libusb/out_arm
|
mkdir ${project_root}/deps/libusb/out_arm
|
||||||
./configure --host=aarch64-apple-darwin --prefix=${project_root}/deps/libusb/out_arm
|
./configure --host=aarch64-apple-darwin --prefix=${project_root}/deps/libusb/out_arm
|
||||||
make -j$(nproc)
|
make && make install
|
||||||
make install
|
|
||||||
|
|
||||||
log_info "Combine arm and x86 libusb binaries ..."
|
log_info "Combine arm and x86 libusb binaries ..."
|
||||||
lipo -create ${project_root}/deps/libusb/out_x86/lib/libusb-1.0.0.dylib \
|
lipo -create ${project_root}/deps/libusb/out_x86/lib/libusb-1.0.0.dylib \
|
||||||
@@ -525,8 +491,8 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
-DPAHO_BUILD_SHARED=OFF
|
-DPAHO_BUILD_SHARED=OFF
|
||||||
-DPAHO_BUILD_STATIC=ON
|
-DPAHO_BUILD_STATIC=ON
|
||||||
-DPAHO_WITH_MQTT_C=ON
|
-DPAHO_WITH_MQTT_C=ON
|
||||||
-DPAHO_WITH_SSL=ON
|
-DOPENSSL_ROOT_DIR="${advss_dep_path}"
|
||||||
-DOPENSSL_USE_STATIC_LIBS=ON
|
-DPAHO_WITH_SSL=OFF # TODO: figure out linking issues with openssl
|
||||||
)
|
)
|
||||||
|
|
||||||
pushd ${mqtt_dir}
|
pushd ${mqtt_dir}
|
||||||
|
|||||||
10
.github/scripts/.build.zsh
vendored
10
.github/scripts/.build.zsh
vendored
@@ -253,12 +253,12 @@ ${_usage_host:-}"
|
|||||||
macos-*)
|
macos-*)
|
||||||
if (( ${+CI} )) typeset -gx NSUnbufferedIO=YES
|
if (( ${+CI} )) typeset -gx NSUnbufferedIO=YES
|
||||||
|
|
||||||
|
local openssl_lib_dir="${advss_deps_path}/openssl-combined/"
|
||||||
|
local openssl_include_dir="${advss_deps_path}/openssl/include"
|
||||||
|
|
||||||
cmake_args+=(
|
cmake_args+=(
|
||||||
-DCMAKE_PREFIX_PATH="${advss_deps_path}"
|
-DOPENSSL_INCLUDE_DIR="${openssl_include_dir}"
|
||||||
-DOPENSSL_ROOT_DIR="${advss_deps_path}"
|
-DOPENSSL_LIBRARIES="${openssl_lib_dir}/libcrypto.a;${openssl_lib_dir}/libssl.a"
|
||||||
-DOPENSSL_INCLUDE_DIR="${advss_deps_path}/include"
|
|
||||||
-DOPENSSL_CRYPTO_LIBRARY="${advss_deps_path}/lib/libcrypto.a"
|
|
||||||
-DOPENSSL_SSL_LIBRARY="${advss_deps_path}/lib/libssl.a"
|
|
||||||
--preset ${_preset}
|
--preset ${_preset}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
3
.github/scripts/.package.zsh
vendored
3
.github/scripts/.package.zsh
vendored
@@ -258,9 +258,6 @@ ${_usage_host:-}"
|
|||||||
pushd ${project_root}
|
pushd ${project_root}
|
||||||
cmake --build build_${target##*-} --config ${config} -t package ${cmake_args}
|
cmake --build build_${target##*-} --config ${config} -t package ${cmake_args}
|
||||||
|
|
||||||
# Mark certain deps as optional
|
|
||||||
build-aux/CI/linux/demote-deps.sh ${project_root}/release/*.deb Recommends '(mqtt)|(opencv)|(tesseract)|(usb)|(x11)|(libobs)'
|
|
||||||
|
|
||||||
if [ ! -e ${project_root}/release/${output_name}.deb ]; then
|
if [ ! -e ${project_root}/release/${output_name}.deb ]; then
|
||||||
mv ${project_root}/release/*.deb ${project_root}/release/${output_name}.deb
|
mv ${project_root}/release/*.deb ${project_root}/release/${output_name}.deb
|
||||||
mv ${project_root}/release/*.ddeb ${project_root}/release/${output_name}.ddeb
|
mv ${project_root}/release/*.ddeb ${project_root}/release/${output_name}.ddeb
|
||||||
|
|||||||
22
.github/scripts/Build-Deps-Windows.ps1
vendored
22
.github/scripts/Build-Deps-Windows.ps1
vendored
@@ -106,7 +106,6 @@ function Build {
|
|||||||
$ADVSSDepPath = "$(Resolve-Path -Path ${ProjectRoot}/${OutDirName})"
|
$ADVSSDepPath = "$(Resolve-Path -Path ${ProjectRoot}/${OutDirName})"
|
||||||
|
|
||||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
||||||
$OpenCVContribPath = "${ProjectRoot}/deps/opencv_contrib"
|
|
||||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
$OpenCVBuildPath = "${OpenCVPath}/build"
|
||||||
|
|
||||||
Push-Location -Stack BuildOpenCVTemp
|
Push-Location -Stack BuildOpenCVTemp
|
||||||
@@ -116,8 +115,7 @@ function Build {
|
|||||||
"-DCMAKE_BUILD_TYPE=Release"
|
"-DCMAKE_BUILD_TYPE=Release"
|
||||||
"-DCMAKE_PREFIX_PATH:PATH=${OBSDepPath}"
|
"-DCMAKE_PREFIX_PATH:PATH=${OBSDepPath}"
|
||||||
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
||||||
"-DBUILD_LIST=core,imgproc,objdetect,xobjdetect"
|
"-DBUILD_LIST=core,imgproc,objdetect"
|
||||||
"-DOPENCV_EXTRA_MODULES_PATH:PATH=${OpenCVContribPath}/modules"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Log-Information "Configuring OpenCV..."
|
Log-Information "Configuring OpenCV..."
|
||||||
@@ -211,9 +209,7 @@ function Build {
|
|||||||
$msbuildExe = vswhere -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe | select-object -first 1
|
$msbuildExe = vswhere -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe | select-object -first 1
|
||||||
|
|
||||||
if ($msbuildExe) {
|
if ($msbuildExe) {
|
||||||
$env:CL="/wd5287"
|
|
||||||
Invoke-External $msbuildExe "${LibusbPath}/msvc/libusb.sln" /property:Configuration=Release /property:Platform=x64
|
Invoke-External $msbuildExe "${LibusbPath}/msvc/libusb.sln" /property:Configuration=Release /property:Platform=x64
|
||||||
Remove-Item Env:CL
|
|
||||||
|
|
||||||
$libusbBuildResultDirectory = "${LibusbPath}/build/v143/x64/Release"
|
$libusbBuildResultDirectory = "${LibusbPath}/build/v143/x64/Release"
|
||||||
if (-not (Test-Path -Path $libusbBuildResultDirectory)) {
|
if (-not (Test-Path -Path $libusbBuildResultDirectory)) {
|
||||||
@@ -236,24 +232,8 @@ function Build {
|
|||||||
"-DCMAKE_PREFIX_PATH:PATH=${OBSDepPath}"
|
"-DCMAKE_PREFIX_PATH:PATH=${OBSDepPath}"
|
||||||
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
||||||
"-DPAHO_WITH_MQTT_C=ON"
|
"-DPAHO_WITH_MQTT_C=ON"
|
||||||
"-DPAHO_WITH_SSL=ON"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Try to find OpenSSL installed via winget
|
|
||||||
$pf64 = Join-Path $Env:ProgramFiles "OpenSSL-Win64"
|
|
||||||
$pf = Join-Path $Env:ProgramFiles "OpenSSL"
|
|
||||||
$possibleDirs = @($pf64, $pf)
|
|
||||||
$opensslDir = $possibleDirs | Where-Object { Test-Path (Join-Path $_ "include\openssl\ssl.h") } | Select-Object -First 1
|
|
||||||
|
|
||||||
if ($opensslDir) {
|
|
||||||
Write-Host "Detected OpenSSL at: $opensslDir"
|
|
||||||
$MqttCmakeArgs += "-DOPENSSL_ROOT_DIR=$opensslDir"
|
|
||||||
$MqttCmakeArgs += "-DOPENSSL_CRYPTO_LIBRARY=$opensslDir\lib\VC\x64\MD\libcrypto.lib"
|
|
||||||
$MqttCmakeArgs += "-DOPENSSL_SSL_LIBRARY=$opensslDir\lib\VC\x64\MD\libssl.lib"
|
|
||||||
} else {
|
|
||||||
Write-Warning "OpenSSL not found - maybe cmake will find it ..."
|
|
||||||
}
|
|
||||||
|
|
||||||
Log-Information "Configuring paho.mqtt.cpp..."
|
Log-Information "Configuring paho.mqtt.cpp..."
|
||||||
Invoke-External cmake -S ${MqttPath} -B ${MqttBuildPath} @MqttCmakeArgs
|
Invoke-External cmake -S ${MqttPath} -B ${MqttBuildPath} @MqttCmakeArgs
|
||||||
|
|
||||||
|
|||||||
73
.github/scripts/Package-Windows.ps1
vendored
73
.github/scripts/Package-Windows.ps1
vendored
@@ -68,53 +68,14 @@ function Package {
|
|||||||
|
|
||||||
Remove-Item @RemoveArgs
|
Remove-Item @RemoveArgs
|
||||||
|
|
||||||
$ReleasePath = "${ProjectRoot}/release/${Configuration}"
|
Log-Group "Archiving ${ProductName}..."
|
||||||
$NewBinPath = "${ReleasePath}/${ProductName}/bin/64bit"
|
$CompressArgs = @{
|
||||||
$NewDataPath = "${ReleasePath}/${ProductName}/data"
|
Path = (Get-ChildItem -Path "${ProjectRoot}/release/${Configuration}" -Exclude "${OutputName}*.*")
|
||||||
$CIWindowsDir = "${ProjectRoot}/build-aux/CI/windows"
|
CompressionLevel = 'Optimal'
|
||||||
|
DestinationPath = "${ProjectRoot}/release/${OutputName}.zip"
|
||||||
# --- Recommended zip (new layout, extract to %ProgramData%\obs-studio\) ---
|
Verbose = ($Env:CI -ne $null)
|
||||||
Log-Group "Archiving ${ProductName} (recommended)..."
|
|
||||||
$RecStaging = "${ProjectRoot}/release/zip-staging-rec"
|
|
||||||
Remove-Item -Path $RecStaging -Recurse -Force -ErrorAction SilentlyContinue
|
|
||||||
New-Item -ItemType Directory -Force -Path $RecStaging | Out-Null
|
|
||||||
Copy-Item -Path "${CIWindowsDir}/README.txt" -Destination "${RecStaging}/README.txt"
|
|
||||||
if ( Test-Path -Path $NewBinPath ) {
|
|
||||||
$RecBinPath = "${RecStaging}/${ProductName}/bin/64bit"
|
|
||||||
New-Item -ItemType Directory -Force -Path $RecBinPath | Out-Null
|
|
||||||
Copy-Item -Path "${NewBinPath}/*" -Destination $RecBinPath -Recurse -Force
|
|
||||||
}
|
}
|
||||||
if ( Test-Path -Path $NewDataPath ) {
|
Compress-Archive -Force @CompressArgs
|
||||||
$RecDataPath = "${RecStaging}/${ProductName}/data"
|
|
||||||
New-Item -ItemType Directory -Force -Path $RecDataPath | Out-Null
|
|
||||||
Copy-Item -Path "${NewDataPath}/*" -Destination $RecDataPath -Recurse -Force
|
|
||||||
}
|
|
||||||
Compress-Archive -Force -Path (Get-ChildItem -Path $RecStaging) `
|
|
||||||
-CompressionLevel Optimal `
|
|
||||||
-DestinationPath "${ProjectRoot}/release/${OutputName}.zip"
|
|
||||||
Remove-Item -Path $RecStaging -Recurse -Force
|
|
||||||
Log-Group
|
|
||||||
|
|
||||||
# --- Legacy zip (old layout, extract to OBS install directory) ---
|
|
||||||
Log-Group "Archiving ${ProductName} (portable)..."
|
|
||||||
$PortableStaging = "${ProjectRoot}/release/zip-staging-portable"
|
|
||||||
Remove-Item -Path $PortableStaging -Recurse -Force -ErrorAction SilentlyContinue
|
|
||||||
New-Item -ItemType Directory -Force -Path $PortableStaging | Out-Null
|
|
||||||
Copy-Item -Path "${CIWindowsDir}/README-portable.txt" -Destination "${PortableStaging}/README.txt"
|
|
||||||
if ( Test-Path -Path $NewBinPath ) {
|
|
||||||
$PortableBinPath = "${PortableStaging}/obs-plugins/64bit"
|
|
||||||
New-Item -ItemType Directory -Force -Path $PortableBinPath | Out-Null
|
|
||||||
Copy-Item -Path "${NewBinPath}/*" -Destination $PortableBinPath -Recurse -Force
|
|
||||||
}
|
|
||||||
if ( Test-Path -Path $NewDataPath ) {
|
|
||||||
$PortableDataPath = "${PortableStaging}/data/obs-plugins/${ProductName}"
|
|
||||||
New-Item -ItemType Directory -Force -Path $PortableDataPath | Out-Null
|
|
||||||
Copy-Item -Path "${NewDataPath}/*" -Destination $PortableDataPath -Recurse -Force
|
|
||||||
}
|
|
||||||
Compress-Archive -Force -Path (Get-ChildItem -Path $PortableStaging) `
|
|
||||||
-CompressionLevel Optimal `
|
|
||||||
-DestinationPath "${ProjectRoot}/release/${OutputName}-portable.zip"
|
|
||||||
Remove-Item -Path $PortableStaging -Recurse -Force
|
|
||||||
Log-Group
|
Log-Group
|
||||||
|
|
||||||
if ( ( $BuildInstaller ) ) {
|
if ( ( $BuildInstaller ) ) {
|
||||||
@@ -128,25 +89,7 @@ function Package {
|
|||||||
Log-Information 'Creating InnoSetup installer...'
|
Log-Information 'Creating InnoSetup installer...'
|
||||||
Push-Location -Stack BuildTemp
|
Push-Location -Stack BuildTemp
|
||||||
Ensure-Location -Path "${ProjectRoot}/release"
|
Ensure-Location -Path "${ProjectRoot}/release"
|
||||||
Remove-Item -Path Package -Recurse -Force -ErrorAction SilentlyContinue
|
Copy-Item -Path ${Configuration} -Destination Package -Recurse
|
||||||
|
|
||||||
# Recommended layout (for %ProgramData%\obs-studio\plugins\)
|
|
||||||
$PkgRec = "Package/recommended"
|
|
||||||
New-Item -ItemType Directory -Force -Path $PkgRec | Out-Null
|
|
||||||
Copy-Item -Path "${Configuration}/*" -Destination $PkgRec -Recurse -Force
|
|
||||||
|
|
||||||
# Legacy layout (for OBS installation directory)
|
|
||||||
if ( Test-Path "${Configuration}/${ProductName}/bin/64bit" ) {
|
|
||||||
$PkgLegBin = "Package/portable/obs-plugins/64bit"
|
|
||||||
New-Item -ItemType Directory -Force -Path $PkgLegBin | Out-Null
|
|
||||||
Copy-Item -Path "${Configuration}/${ProductName}/bin/64bit/*" -Destination $PkgLegBin -Recurse -Force
|
|
||||||
}
|
|
||||||
if ( Test-Path "${Configuration}/${ProductName}/data" ) {
|
|
||||||
$PkgLegData = "Package/portable/data/obs-plugins/${ProductName}"
|
|
||||||
New-Item -ItemType Directory -Force -Path $PkgLegData | Out-Null
|
|
||||||
Copy-Item -Path "${Configuration}/${ProductName}/data/*" -Destination $PkgLegData -Recurse -Force
|
|
||||||
}
|
|
||||||
|
|
||||||
Invoke-External iscc ${IsccFile} /O"${ProjectRoot}/release" /F"${OutputName}-Installer"
|
Invoke-External iscc ${IsccFile} /O"${ProjectRoot}/release" /F"${OutputName}-Installer"
|
||||||
Remove-Item -Path Package -Recurse
|
Remove-Item -Path Package -Recurse
|
||||||
Pop-Location -Stack BuildTemp
|
Pop-Location -Stack BuildTemp
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
# Injected via CMAKE_PROJECT_INCLUDE after opencv's project() call. Forces
|
|
||||||
# CMAKE_SYSTEM_PROCESSOR into the cache so that third-party subdirectories
|
|
||||||
# (mlas) that read the cache directly see x86_64 instead of the arm64 host
|
|
||||||
# processor on Apple Silicon CI runners.
|
|
||||||
set(CMAKE_SYSTEM_PROCESSOR
|
|
||||||
x86_64
|
|
||||||
CACHE INTERNAL "" FORCE)
|
|
||||||
1
.github/scripts/utils.zsh/setup_ccache
vendored
1
.github/scripts/utils.zsh/setup_ccache
vendored
@@ -10,6 +10,7 @@ if (( ${+commands[ccache]} )) {
|
|||||||
|
|
||||||
typeset -gx CCACHE_CONFIGPATH="${project_root}/.ccache.conf"
|
typeset -gx CCACHE_CONFIGPATH="${project_root}/.ccache.conf"
|
||||||
|
|
||||||
|
ccache --set-config=run_second_cpp=true
|
||||||
ccache --set-config=direct_mode=true
|
ccache --set-config=direct_mode=true
|
||||||
ccache --set-config=inode_cache=true
|
ccache --set-config=inode_cache=true
|
||||||
ccache --set-config=compiler_check=content
|
ccache --set-config=compiler_check=content
|
||||||
|
|||||||
20
.github/scripts/utils.zsh/setup_linux
vendored
20
.github/scripts/utils.zsh/setup_linux
vendored
@@ -35,21 +35,13 @@ if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) {
|
|||||||
sudo apt-get install ${apt_args} gcc-${${target##*-}//_/-}-linux-gnu g++-${${target##*-}//_/-}-linux-gnu
|
sudo apt-get install ${apt_args} gcc-${${target##*-}//_/-}-linux-gnu g++-${${target##*-}//_/-}-linux-gnu
|
||||||
}
|
}
|
||||||
|
|
||||||
local dist_version
|
sudo add-apt-repository --yes ppa:obsproject/obs-studio
|
||||||
read -r dist_version <<< "$(source /etc/os-release; print "${VERSION_ID}")"
|
sudo apt update
|
||||||
|
|
||||||
# The OBS PPA may not yet support newer Ubuntu versions.
|
sudo apt-get install ${apt_args} \
|
||||||
# On those, use the native obs-studio packages and install libobs-dev separately,
|
build-essential \
|
||||||
# as it is not bundled in obs-studio itself on newer Ubuntu releases.
|
libgles2-mesa-dev \
|
||||||
local -a obs_packages=(build-essential libgles2-mesa-dev libsimde-dev obs-studio)
|
obs-studio
|
||||||
if is-at-least 26.04 ${dist_version}; then
|
|
||||||
obs_packages+=(libobs-dev)
|
|
||||||
else
|
|
||||||
sudo add-apt-repository --yes ppa:obsproject/obs-studio
|
|
||||||
sudo apt update
|
|
||||||
fi
|
|
||||||
|
|
||||||
sudo apt-get install ${apt_args} ${obs_packages}
|
|
||||||
|
|
||||||
local -a _qt_packages=()
|
local -a _qt_packages=()
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/build-debian.yml
vendored
4
.github/workflows/build-debian.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
- name: check_libobs_revision
|
- name: check_libobs_revision
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
mv ../*.deb .
|
mv ../*.deb .
|
||||||
- name: Publish
|
- name: Publish
|
||||||
if: success()
|
if: success()
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: "obs-scene-switcher.deb"
|
name: "obs-scene-switcher.deb"
|
||||||
path: ${{ github.workspace }}/*.deb
|
path: ${{ github.workspace }}/*.deb
|
||||||
|
|||||||
144
.github/workflows/build-project.yaml
vendored
144
.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-6
|
DEP_DIR: .deps/advss-build-dependencies
|
||||||
jobs:
|
jobs:
|
||||||
check-event:
|
check-event:
|
||||||
name: Check GitHub Event Data 🔎
|
name: Check GitHub Event Data 🔎
|
||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
commitHash: ${{ steps.setup.outputs.commitHash }}
|
commitHash: ${{ steps.setup.outputs.commitHash }}
|
||||||
pluginName: ${{ steps.setup.outputs.pluginName }}
|
pluginName: ${{ steps.setup.outputs.pluginName }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Check Event Data ☑️
|
- name: Check Event Data ☑️
|
||||||
@@ -75,13 +75,13 @@ jobs:
|
|||||||
|
|
||||||
macos-build:
|
macos-build:
|
||||||
name: Build for macOS 🍏
|
name: Build for macOS 🍏
|
||||||
runs-on: macos-15
|
runs-on: macos-14
|
||||||
needs: check-event
|
needs: check-event
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: zsh --no-rcs --errexit --pipefail {0}
|
shell: zsh --no-rcs --errexit --pipefail {0}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -107,11 +107,11 @@ jobs:
|
|||||||
print "pluginName=${product_name}" >> $GITHUB_OUTPUT
|
print "pluginName=${product_name}" >> $GITHUB_OUTPUT
|
||||||
print "pluginVersion=${git_tag}" >> $GITHUB_OUTPUT
|
print "pluginVersion=${git_tag}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
print '::group::Enable Xcode 16.1'
|
print '::group::Enable Xcode 15.2'
|
||||||
sudo xcode-select --switch /Applications/Xcode_16.1.0.app/Contents/Developer
|
sudo xcode-select --switch /Applications/Xcode_15.2.app/Contents/Developer
|
||||||
print '::endgroup::'
|
print '::endgroup::'
|
||||||
|
|
||||||
- uses: actions/cache@v5
|
- uses: actions/cache@v4
|
||||||
id: ccache-cache
|
id: ccache-cache
|
||||||
with:
|
with:
|
||||||
path: ${{ github.workspace }}/.ccache
|
path: ${{ github.workspace }}/.ccache
|
||||||
@@ -163,13 +163,13 @@ jobs:
|
|||||||
codesignPass: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
|
codesignPass: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
|
||||||
|
|
||||||
- name: Upload Artifacts 📡
|
- name: Upload Artifacts 📡
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-macos-universal-${{ needs.check-event.outputs.commitHash }}
|
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-macos-universal-${{ needs.check-event.outputs.commitHash }}
|
||||||
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-macos-universal.*
|
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-macos-universal.*
|
||||||
|
|
||||||
- name: Upload Debug Symbol Artifacts 🪲
|
- name: Upload Debug Symbol Artifacts 🪲
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ needs.check-event.outputs.config == 'Release' }}
|
if: ${{ needs.check-event.outputs.config == 'Release' }}
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-macos-universal-${{ needs.check-event.outputs.commitHash }}-dSYMs
|
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-macos-universal-${{ needs.check-event.outputs.commitHash }}-dSYMs
|
||||||
@@ -183,7 +183,7 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
shell: bash
|
shell: bash
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -202,7 +202,7 @@ jobs:
|
|||||||
echo "pluginName=${product_name}" >> $GITHUB_OUTPUT
|
echo "pluginName=${product_name}" >> $GITHUB_OUTPUT
|
||||||
echo "pluginVersion=${git_tag}" >> $GITHUB_OUTPUT
|
echo "pluginVersion=${git_tag}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/cache@v5
|
- uses: actions/cache@v4
|
||||||
id: ccache-cache
|
id: ccache-cache
|
||||||
with:
|
with:
|
||||||
path: ${{ github.workspace }}/.ccache
|
path: ${{ github.workspace }}/.ccache
|
||||||
@@ -210,19 +210,13 @@ jobs:
|
|||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-ccache-x86_64-
|
${{ runner.os }}-ccache-x86_64-
|
||||||
|
|
||||||
- name: Set up Homebrew 🍺
|
- name: Set up CMake 🏗️
|
||||||
uses: Homebrew/actions/setup-homebrew@main
|
uses: jwlawson/actions-setup-cmake@v1.13
|
||||||
|
with:
|
||||||
|
cmake-version: '3.24.x'
|
||||||
|
|
||||||
- name: Install Vulkan SDK 🌋
|
- name: Set up Homebrew 🍺
|
||||||
shell: bash
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
run: |
|
|
||||||
wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc \
|
|
||||||
| sudo tee /etc/apt/trusted.gpg.d/lunarg.asc
|
|
||||||
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-noble.list \
|
|
||||||
https://packages.lunarg.com/vulkan/lunarg-vulkan-noble.list
|
|
||||||
sudo apt-get update -qq
|
|
||||||
sudo apt-get install -y vulkan-sdk
|
|
||||||
echo "VULKAN_SDK=/usr" >> "$GITHUB_ENV"
|
|
||||||
|
|
||||||
- name: Build Plugin 🧱
|
- name: Build Plugin 🧱
|
||||||
uses: ./.github/actions/build-plugin
|
uses: ./.github/actions/build-plugin
|
||||||
@@ -244,111 +238,23 @@ jobs:
|
|||||||
config: ${{ needs.check-event.outputs.config }}
|
config: ${{ needs.check-event.outputs.config }}
|
||||||
|
|
||||||
- name: Upload Source Tarball 🗜️
|
- name: Upload Source Tarball 🗜️
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-sources-${{ needs.check-event.outputs.commitHash }}
|
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-sources-${{ needs.check-event.outputs.commitHash }}
|
||||||
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-source.*
|
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-source.*
|
||||||
|
|
||||||
- name: Rename artifacts for Ubuntu 24 🏷️
|
|
||||||
run: |
|
|
||||||
: Rename artifacts for Ubuntu 24 🏷️
|
|
||||||
for f in ${{ github.workspace }}/release/*-x86_64-linux-gnu.*; do
|
|
||||||
[ -e "${f}" ] || continue
|
|
||||||
mv "${f}" "${f/x86_64-linux-gnu/x86_64-ubuntu24.04-linux-gnu}"
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Upload Artifacts 📡
|
- name: Upload Artifacts 📡
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-24.04-x86_64-${{ needs.check-event.outputs.commitHash }}
|
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-24.04-x86_64-${{ needs.check-event.outputs.commitHash }}
|
||||||
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*.*
|
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*.*
|
||||||
|
|
||||||
- name: Upload debug symbol artifacts 🪲
|
- name: Upload debug symbol artifacts 🪲
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ fromJSON(needs.check-event.outputs.package) }}
|
if: ${{ fromJSON(needs.check-event.outputs.package) }}
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-24.04-x86_64-${{ needs.check-event.outputs.commitHash }}-dbgsym
|
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-24.04-x86_64-${{ needs.check-event.outputs.commitHash }}-dbgsym
|
||||||
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*-dbgsym.ddeb
|
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*-dbgsym.ddeb
|
||||||
if-no-files-found: ignore
|
|
||||||
|
|
||||||
ubuntu-26-build:
|
|
||||||
name: Build for Ubuntu 26 🐧
|
|
||||||
runs-on: ubuntu-26.04
|
|
||||||
needs: check-event
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set Up Environment 🔧
|
|
||||||
id: setup
|
|
||||||
run: |
|
|
||||||
: Set Up Environment 🔧
|
|
||||||
if [[ "${RUNNER_DEBUG}" ]]; then set -x; fi
|
|
||||||
|
|
||||||
git_tag="$(git describe --tags)"
|
|
||||||
|
|
||||||
read -r product_name product_version <<< \
|
|
||||||
"$(jq -r '. | {name, version} | join(" ")' buildspec.json)"
|
|
||||||
|
|
||||||
echo "pluginName=${product_name}" >> $GITHUB_OUTPUT
|
|
||||||
echo "pluginVersion=${git_tag}" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- uses: actions/cache@v5
|
|
||||||
id: ccache-cache
|
|
||||||
with:
|
|
||||||
path: ${{ github.workspace }}/.ccache
|
|
||||||
key: ${{ runner.os }}-ccache-x86_64-${{ needs.check-event.outputs.config }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-ccache-x86_64-
|
|
||||||
|
|
||||||
- name: Set up Homebrew 🍺
|
|
||||||
uses: Homebrew/actions/setup-homebrew@main
|
|
||||||
|
|
||||||
- name: Build Plugin 🧱
|
|
||||||
uses: ./.github/actions/build-plugin
|
|
||||||
with:
|
|
||||||
target: x86_64
|
|
||||||
config: ${{ needs.check-event.outputs.config }}
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
uses: ./.github/actions/run-tests
|
|
||||||
with:
|
|
||||||
target: x86_64
|
|
||||||
config: ${{ needs.check-event.outputs.config }}
|
|
||||||
|
|
||||||
- name: Package Plugin 📀
|
|
||||||
uses: ./.github/actions/package-plugin
|
|
||||||
with:
|
|
||||||
package: ${{ fromJSON(needs.check-event.outputs.package) }}
|
|
||||||
target: x86_64
|
|
||||||
config: ${{ needs.check-event.outputs.config }}
|
|
||||||
|
|
||||||
- name: Rename artifacts for Ubuntu 26 🏷️
|
|
||||||
run: |
|
|
||||||
: Rename artifacts for Ubuntu 26 🏷️
|
|
||||||
for f in ${{ github.workspace }}/release/*-x86_64-linux-gnu.*; do
|
|
||||||
[ -e "${f}" ] || continue
|
|
||||||
mv "${f}" "${f/x86_64-linux-gnu/x86_64-ubuntu26.04-linux-gnu}"
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Upload Artifacts 📡
|
|
||||||
uses: actions/upload-artifact@v7
|
|
||||||
with:
|
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-26.04-x86_64-${{ needs.check-event.outputs.commitHash }}
|
|
||||||
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*.*
|
|
||||||
|
|
||||||
- name: Upload debug symbol artifacts 🪲
|
|
||||||
uses: actions/upload-artifact@v7
|
|
||||||
if: ${{ fromJSON(needs.check-event.outputs.package) }}
|
|
||||||
with:
|
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-26.04-x86_64-${{ needs.check-event.outputs.commitHash }}-dbgsym
|
|
||||||
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*-dbgsym.ddeb
|
|
||||||
if-no-files-found: ignore
|
|
||||||
|
|
||||||
windows-build:
|
windows-build:
|
||||||
name: Build for Windows 🪟
|
name: Build for Windows 🪟
|
||||||
@@ -358,7 +264,7 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -385,12 +291,6 @@ jobs:
|
|||||||
target: x64
|
target: x64
|
||||||
config: ${{ needs.check-event.outputs.config }}
|
config: ${{ needs.check-event.outputs.config }}
|
||||||
|
|
||||||
- name: Install Vulkan SDK 🌋
|
|
||||||
uses: jakoch/install-vulkan-sdk-action@v1
|
|
||||||
with:
|
|
||||||
install_runtime: false
|
|
||||||
cache: true
|
|
||||||
|
|
||||||
- name: Build Plugin 🧱
|
- name: Build Plugin 🧱
|
||||||
uses: ./.github/actions/build-plugin
|
uses: ./.github/actions/build-plugin
|
||||||
with:
|
with:
|
||||||
@@ -411,7 +311,7 @@ jobs:
|
|||||||
package: ${{ fromJSON(needs.check-event.outputs.package) }}
|
package: ${{ fromJSON(needs.check-event.outputs.package) }}
|
||||||
|
|
||||||
- name: Upload Artifacts 📡
|
- name: Upload Artifacts 📡
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-windows-x64-${{ needs.check-event.outputs.commitHash }}
|
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-windows-x64-${{ needs.check-event.outputs.commitHash }}
|
||||||
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-windows-x64*.*
|
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-windows-x64*.*
|
||||||
|
|||||||
4
.github/workflows/check-format.yaml
vendored
4
.github/workflows/check-format.yaml
vendored
@@ -5,7 +5,7 @@ jobs:
|
|||||||
clang-format:
|
clang-format:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: clang-format check 🐉
|
- name: clang-format check 🐉
|
||||||
@@ -17,7 +17,7 @@ jobs:
|
|||||||
cmake-format:
|
cmake-format:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: cmake-format check 🎛️
|
- name: cmake-format check 🎛️
|
||||||
|
|||||||
2
.github/workflows/locale-check.yml
vendored
2
.github/workflows/locale-check.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Check locale files
|
- name: Check locale files
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
5
.github/workflows/push.yaml
vendored
5
.github/workflows/push.yaml
vendored
@@ -59,7 +59,7 @@ jobs:
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
- name: Download Build Artifacts 📥
|
- name: Download Build Artifacts 📥
|
||||||
uses: actions/download-artifact@v8
|
uses: actions/download-artifact@v4
|
||||||
if: fromJSON(steps.check.outputs.validTag)
|
if: fromJSON(steps.check.outputs.validTag)
|
||||||
id: download
|
id: download
|
||||||
|
|
||||||
@@ -78,7 +78,6 @@ jobs:
|
|||||||
'windows-x64;zip|exe'
|
'windows-x64;zip|exe'
|
||||||
'macos-universal;tar.xz|pkg'
|
'macos-universal;tar.xz|pkg'
|
||||||
'ubuntu-24.04-x86_64;tar.xz|deb|ddeb'
|
'ubuntu-24.04-x86_64;tar.xz|deb|ddeb'
|
||||||
'ubuntu-26.04-x86_64;tar.xz|deb|ddeb'
|
|
||||||
'sources;tar.xz'
|
'sources;tar.xz'
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -107,7 +106,7 @@ jobs:
|
|||||||
- name: Create Release 🛫
|
- name: Create Release 🛫
|
||||||
if: fromJSON(steps.check.outputs.validTag)
|
if: fromJSON(steps.check.outputs.validTag)
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda
|
uses: softprops/action-gh-release@d4e8205d7e959a9107da6396278b2f1f07af0f9b
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: ${{ fromJSON(steps.check.outputs.prerelease) }}
|
prerelease: ${{ fromJSON(steps.check.outputs.prerelease) }}
|
||||||
|
|||||||
9
.gitmodules
vendored
9
.gitmodules
vendored
@@ -28,15 +28,12 @@
|
|||||||
[submodule "deps/libusb"]
|
[submodule "deps/libusb"]
|
||||||
path = deps/libusb
|
path = deps/libusb
|
||||||
url = https://github.com/libusb/libusb.git
|
url = https://github.com/libusb/libusb.git
|
||||||
|
[submodule "deps/date"]
|
||||||
|
path = deps/date
|
||||||
|
url = https://github.com/HowardHinnant/date.git
|
||||||
[submodule "deps/jsoncons"]
|
[submodule "deps/jsoncons"]
|
||||||
path = deps/jsoncons
|
path = deps/jsoncons
|
||||||
url = https://github.com/danielaparker/jsoncons.git
|
url = https://github.com/danielaparker/jsoncons.git
|
||||||
[submodule "deps/paho.mqtt.cpp"]
|
[submodule "deps/paho.mqtt.cpp"]
|
||||||
path = deps/paho.mqtt.cpp
|
path = deps/paho.mqtt.cpp
|
||||||
url = https://github.com/eclipse-paho/paho.mqtt.cpp.git
|
url = https://github.com/eclipse-paho/paho.mqtt.cpp.git
|
||||||
[submodule "deps/opencv_contrib"]
|
|
||||||
path = deps/opencv_contrib
|
|
||||||
url = https://github.com/opencv/opencv_contrib.git
|
|
||||||
[submodule "deps/whisper.cpp"]
|
|
||||||
path = deps/whisper.cpp
|
|
||||||
url = https://github.com/ggml-org/whisper.cpp.git
|
|
||||||
|
|||||||
@@ -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)
|
||||||
```
|
```
|
||||||
|
|||||||
132
CMakeLists.txt
132
CMakeLists.txt
@@ -16,14 +16,6 @@ if(BUILD_OUT_OF_TREE)
|
|||||||
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake"
|
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake"
|
||||||
NO_POLICY_SCOPE)
|
NO_POLICY_SCOPE)
|
||||||
include(compilerconfig)
|
include(compilerconfig)
|
||||||
# OPENSSL_USE_STATIC_LIBS here ensures FindOpenSSL picks up the static libs
|
|
||||||
# preventing DLL name collisions with other plugins (e.g.NVIDIA AR SDK).
|
|
||||||
if(OS_WINDOWS)
|
|
||||||
set(OPENSSL_USE_STATIC_LIBS
|
|
||||||
ON
|
|
||||||
CACHE BOOL "Use static OpenSSL" FORCE)
|
|
||||||
include(cmake/windows/wingetssl.cmake)
|
|
||||||
endif()
|
|
||||||
include(defaults)
|
include(defaults)
|
||||||
include(helpers)
|
include(helpers)
|
||||||
endif()
|
endif()
|
||||||
@@ -107,8 +99,6 @@ target_sources(
|
|||||||
lib/macro/macro-action-edit.hpp
|
lib/macro/macro-action-edit.hpp
|
||||||
lib/macro/macro-action-factory.cpp
|
lib/macro/macro-action-factory.cpp
|
||||||
lib/macro/macro-action-factory.hpp
|
lib/macro/macro-action-factory.hpp
|
||||||
lib/macro/macro-action-loop.cpp
|
|
||||||
lib/macro/macro-action-loop.hpp
|
|
||||||
lib/macro/macro-action-macro.cpp
|
lib/macro/macro-action-macro.cpp
|
||||||
lib/macro/macro-action-macro.hpp
|
lib/macro/macro-action-macro.hpp
|
||||||
lib/macro/macro-action-queue.cpp
|
lib/macro/macro-action-queue.cpp
|
||||||
@@ -133,15 +123,6 @@ target_sources(
|
|||||||
lib/macro/macro-condition.hpp
|
lib/macro/macro-condition.hpp
|
||||||
lib/macro/macro-dock.cpp
|
lib/macro/macro-dock.cpp
|
||||||
lib/macro/macro-dock.hpp
|
lib/macro/macro-dock.hpp
|
||||||
lib/macro/macro-dock-settings.hpp
|
|
||||||
lib/macro/macro-dock-settings.cpp
|
|
||||||
lib/macro/macro-dock-window.cpp
|
|
||||||
lib/macro/macro-dock-window.hpp
|
|
||||||
lib/macro/macro-edit.cpp
|
|
||||||
lib/macro/macro-edit.hpp
|
|
||||||
lib/macro/macro-export-builtin-extensions.cpp
|
|
||||||
lib/macro/macro-export-extensions.cpp
|
|
||||||
lib/macro/macro-export-extensions.hpp
|
|
||||||
lib/macro/macro-export-import-dialog.cpp
|
lib/macro/macro-export-import-dialog.cpp
|
||||||
lib/macro/macro-export-import-dialog.hpp
|
lib/macro/macro-export-import-dialog.hpp
|
||||||
lib/macro/macro-helpers.cpp
|
lib/macro/macro-helpers.cpp
|
||||||
@@ -154,27 +135,21 @@ 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
|
||||||
lib/macro/macro-segment-list.hpp
|
lib/macro/macro-segment-list.hpp
|
||||||
lib/macro/macro-segment-selection.cpp
|
lib/macro/macro-segment-selection.cpp
|
||||||
lib/macro/macro-segment-selection.hpp
|
lib/macro/macro-segment-selection.hpp
|
||||||
lib/macro/macro-segment-unknown.hpp
|
|
||||||
lib/macro/macro-segment.cpp
|
lib/macro/macro-segment.cpp
|
||||||
lib/macro/macro-segment.hpp
|
lib/macro/macro-segment.hpp
|
||||||
lib/macro/macro-selection.cpp
|
lib/macro/macro-selection.cpp
|
||||||
lib/macro/macro-selection.hpp
|
lib/macro/macro-selection.hpp
|
||||||
lib/macro/macro-settings.cpp
|
lib/macro/macro-settings.cpp
|
||||||
lib/macro/macro-settings.hpp
|
lib/macro/macro-settings.hpp
|
||||||
lib/macro/macro-signals.cpp
|
|
||||||
lib/macro/macro-signals.hpp
|
|
||||||
lib/macro/macro-tab.cpp
|
lib/macro/macro-tab.cpp
|
||||||
lib/macro/macro-tree.cpp
|
lib/macro/macro-tree.cpp
|
||||||
lib/macro/macro-tree.hpp
|
lib/macro/macro-tree.hpp
|
||||||
lib/macro/macro-websocket-trigger.cpp
|
|
||||||
lib/macro/macro.cpp
|
lib/macro/macro.cpp
|
||||||
lib/macro/macro.hpp)
|
lib/macro/macro.hpp)
|
||||||
|
|
||||||
@@ -189,12 +164,8 @@ target_sources(
|
|||||||
lib/utils/auto-update-tooltip-label.hpp
|
lib/utils/auto-update-tooltip-label.hpp
|
||||||
lib/utils/backup.cpp
|
lib/utils/backup.cpp
|
||||||
lib/utils/backup.hpp
|
lib/utils/backup.hpp
|
||||||
lib/utils/canvas-helpers.cpp
|
|
||||||
lib/utils/canvas-helpers.hpp
|
|
||||||
lib/utils/condition-logic.cpp
|
lib/utils/condition-logic.cpp
|
||||||
lib/utils/condition-logic.hpp
|
lib/utils/condition-logic.hpp
|
||||||
lib/utils/crash-handler.cpp
|
|
||||||
lib/utils/crash-handler.hpp
|
|
||||||
lib/utils/curl-helper.cpp
|
lib/utils/curl-helper.cpp
|
||||||
lib/utils/curl-helper.hpp
|
lib/utils/curl-helper.hpp
|
||||||
lib/utils/cursor-shape-changer.cpp
|
lib/utils/cursor-shape-changer.cpp
|
||||||
@@ -212,15 +183,6 @@ target_sources(
|
|||||||
lib/utils/file-selection.hpp
|
lib/utils/file-selection.hpp
|
||||||
lib/utils/filter-combo-box.cpp
|
lib/utils/filter-combo-box.cpp
|
||||||
lib/utils/filter-combo-box.hpp
|
lib/utils/filter-combo-box.hpp
|
||||||
lib/utils/first-run-wizard.cpp
|
|
||||||
lib/utils/first-run-wizard.hpp
|
|
||||||
lib/utils/first-run-wizard-audio.cpp
|
|
||||||
lib/utils/first-run-wizard-audio.hpp
|
|
||||||
lib/utils/first-run-wizard-helpers.hpp
|
|
||||||
lib/utils/first-run-wizard-sequence.cpp
|
|
||||||
lib/utils/first-run-wizard-sequence.hpp
|
|
||||||
lib/utils/first-run-wizard-window.cpp
|
|
||||||
lib/utils/first-run-wizard-window.hpp
|
|
||||||
lib/utils/help-icon.hpp
|
lib/utils/help-icon.hpp
|
||||||
lib/utils/help-icon.cpp
|
lib/utils/help-icon.cpp
|
||||||
lib/utils/item-selection-helpers.cpp
|
lib/utils/item-selection-helpers.cpp
|
||||||
@@ -255,8 +217,6 @@ target_sources(
|
|||||||
lib/utils/priority-helper.hpp
|
lib/utils/priority-helper.hpp
|
||||||
lib/utils/regex-config.cpp
|
lib/utils/regex-config.cpp
|
||||||
lib/utils/regex-config.hpp
|
lib/utils/regex-config.hpp
|
||||||
lib/utils/resizable-widget.cpp
|
|
||||||
lib/utils/resizable-widget.hpp
|
|
||||||
lib/utils/resizing-text-edit.cpp
|
lib/utils/resizing-text-edit.cpp
|
||||||
lib/utils/resizing-text-edit.hpp
|
lib/utils/resizing-text-edit.hpp
|
||||||
lib/utils/resource-table.cpp
|
lib/utils/resource-table.cpp
|
||||||
@@ -303,10 +263,6 @@ target_sources(
|
|||||||
lib/utils/volume-control.hpp
|
lib/utils/volume-control.hpp
|
||||||
lib/utils/websocket-api.cpp
|
lib/utils/websocket-api.cpp
|
||||||
lib/utils/websocket-api.hpp
|
lib/utils/websocket-api.hpp
|
||||||
lib/variables/variable-color-button.cpp
|
|
||||||
lib/variables/variable-color-button.hpp
|
|
||||||
lib/variables/variable-color.cpp
|
|
||||||
lib/variables/variable-color.hpp
|
|
||||||
lib/variables/variable-line-edit.cpp
|
lib/variables/variable-line-edit.cpp
|
||||||
lib/variables/variable-line-edit.hpp
|
lib/variables/variable-line-edit.hpp
|
||||||
lib/variables/variable-number.hpp
|
lib/variables/variable-number.hpp
|
||||||
@@ -379,9 +335,6 @@ set_target_properties(${LIB_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
|||||||
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
|
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)
|
||||||
target_compile_features(${LIB_NAME} PUBLIC cxx_std_17)
|
target_compile_features(${LIB_NAME} PUBLIC cxx_std_17)
|
||||||
|
|
||||||
target_precompile_headers(${LIB_NAME} PRIVATE
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/pch.hpp")
|
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
${LIB_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib"
|
${LIB_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/exprtk")
|
"${CMAKE_CURRENT_SOURCE_DIR}/deps/exprtk")
|
||||||
@@ -478,29 +431,14 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
if(PROCPS2_INCLUDE_DIR)
|
if(PROCPS2_INCLUDE_DIR)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(libproc2 IMPORTED_TARGET libproc2<4.0.5 QUIET)
|
||||||
|
if(libproc2_FOUND)
|
||||||
|
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS2_USE_INFO)
|
||||||
|
endif()
|
||||||
pkg_check_modules(libproc2 REQUIRED IMPORTED_TARGET libproc2)
|
pkg_check_modules(libproc2 REQUIRED IMPORTED_TARGET libproc2)
|
||||||
set(PROC_INCLUDE_DIR "${PROCPS2_INCLUDE_DIR}")
|
set(PROC_INCLUDE_DIR "${PROCPS2_INCLUDE_DIR}")
|
||||||
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS2_AVAILABLE)
|
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS2_AVAILABLE)
|
||||||
set(PROCESS_CONDITION_SUPPORTED 1)
|
set(PROCESS_CONDITION_SUPPORTED 1)
|
||||||
|
|
||||||
# Check if PIDS_VAL takes 4 arguments (old API, pre-4.0.5) or 3 (new API)
|
|
||||||
include(CheckCSourceCompiles)
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES "${PROCPS2_INCLUDE_DIR}")
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES proc2)
|
|
||||||
check_c_source_compiles(
|
|
||||||
"
|
|
||||||
#include <libproc2/pids.h>
|
|
||||||
int main(void) {
|
|
||||||
struct pids_stack *s = 0;
|
|
||||||
struct pids_info *i = 0;
|
|
||||||
(void)PIDS_VAL(0, str, s, i);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
PROCPS2_PIDS_VAL_TAKES_INFO)
|
|
||||||
if(PROCPS2_PIDS_VAL_TAKES_INFO)
|
|
||||||
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS2_USE_INFO)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
if(NOT DEFINED PROCESS_CONDITION_SUPPORTED)
|
if(NOT DEFINED PROCESS_CONDITION_SUPPORTED)
|
||||||
message(
|
message(
|
||||||
@@ -526,11 +464,7 @@ endif()
|
|||||||
# --- End of section ---
|
# --- End of section ---
|
||||||
|
|
||||||
add_subdirectory(plugins)
|
add_subdirectory(plugins)
|
||||||
|
add_subdirectory(tests)
|
||||||
option(ADVSS_ENABLE_TESTS "Build advanced-scene-switcher unit tests" OFF)
|
|
||||||
if(ADVSS_ENABLE_TESTS)
|
|
||||||
add_subdirectory(tests)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# --- Install ---
|
# --- Install ---
|
||||||
|
|
||||||
@@ -559,59 +493,3 @@ else()
|
|||||||
set_target_properties_obs(${PROJECT_NAME} PROPERTIES PREFIX "")
|
set_target_properties_obs(${PROJECT_NAME} PROPERTIES PREFIX "")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# --- Install third-party dependency licenses ---
|
|
||||||
#
|
|
||||||
# Each entry is "display-name:path/to/license/file" relative to deps/. Files are
|
|
||||||
# silently skipped when a submodule is not checked out.
|
|
||||||
set(_dep_license_files
|
|
||||||
"asio:asio/asio/LICENSE_1_0.txt"
|
|
||||||
"cpp-httplib:cpp-httplib/LICENSE"
|
|
||||||
"json:json/LICENSE.MIT"
|
|
||||||
"jsoncons:jsoncons/LICENSE"
|
|
||||||
"leptonica:leptonica/leptonica-license.txt"
|
|
||||||
"libremidi:libremidi/LICENSE.md"
|
|
||||||
"libusb:libusb/COPYING"
|
|
||||||
"opencv:opencv/LICENSE"
|
|
||||||
"openvr:openvr/LICENSE"
|
|
||||||
"paho-mqtt:paho.mqtt.cpp/LICENSE"
|
|
||||||
"tesseract:tesseract/LICENSE"
|
|
||||||
"websocketpp:websocketpp/COPYING"
|
|
||||||
"whisper:whisper.cpp/LICENSE")
|
|
||||||
|
|
||||||
if(DEB_INSTALL)
|
|
||||||
if(NOT DATA_OUT_DIR)
|
|
||||||
set(DATA_OUT_DIR "/share/obs/obs-plugins/${PROJECT_NAME}")
|
|
||||||
endif()
|
|
||||||
set(_license_dest "${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR}/licenses")
|
|
||||||
elseif(OS_MACOS)
|
|
||||||
# macOS: license files become bundle Resources/licenses/* entries
|
|
||||||
set(_license_dest "")
|
|
||||||
else()
|
|
||||||
# Windows and non-DEB Linux: alongside the plugin's data directory
|
|
||||||
set(_license_dest "${CMAKE_PROJECT_NAME}/data/licenses")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
foreach(_entry IN LISTS _dep_license_files)
|
|
||||||
string(REGEX MATCH "^([^:]+):(.+)$" _m "${_entry}")
|
|
||||||
set(_dep_name "${CMAKE_MATCH_1}")
|
|
||||||
set(_dep_file "${CMAKE_CURRENT_SOURCE_DIR}/deps/${CMAKE_MATCH_2}")
|
|
||||||
|
|
||||||
if(NOT EXISTS "${_dep_file}")
|
|
||||||
continue()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(OS_MACOS)
|
|
||||||
# Copy to binary dir so we can give the file a clean name
|
|
||||||
set(_staged "${CMAKE_CURRENT_BINARY_DIR}/licenses/LICENSE-${_dep_name}")
|
|
||||||
configure_file("${_dep_file}" "${_staged}" COPYONLY)
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE "${_staged}")
|
|
||||||
set_source_files_properties("${_staged}" PROPERTIES MACOSX_PACKAGE_LOCATION
|
|
||||||
"Resources/licenses")
|
|
||||||
else()
|
|
||||||
install(
|
|
||||||
FILES "${_dep_file}"
|
|
||||||
DESTINATION "${_license_dest}"
|
|
||||||
RENAME "LICENSE-${_dep_name}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|||||||
@@ -41,8 +41,7 @@
|
|||||||
"description": "Build for macOS 11.0+ (Universal binary) for CI",
|
"description": "Build for macOS 11.0+ (Universal binary) for CI",
|
||||||
"generator": "Xcode",
|
"generator": "Xcode",
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_COMPILE_WARNING_AS_ERROR": true,
|
"CMAKE_COMPILE_WARNING_AS_ERROR": true
|
||||||
"ADVSS_ENABLE_TESTS": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -70,8 +69,7 @@
|
|||||||
"displayName": "Windows x64 CI build",
|
"displayName": "Windows x64 CI build",
|
||||||
"description": "Build for Windows x64 on CI",
|
"description": "Build for Windows x64 on CI",
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_COMPILE_WARNING_AS_ERROR": true,
|
"CMAKE_COMPILE_WARNING_AS_ERROR": true
|
||||||
"ADVSS_ENABLE_TESTS": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -99,8 +97,7 @@
|
|||||||
"description": "Build for Linux x86_64 on CI",
|
"description": "Build for Linux x86_64 on CI",
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||||
"CMAKE_COMPILE_WARNING_AS_ERROR": true,
|
"CMAKE_COMPILE_WARNING_AS_ERROR": true
|
||||||
"ADVSS_ENABLE_TESTS": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -128,8 +125,7 @@
|
|||||||
"description": "Build for Linux aarch64 on CI",
|
"description": "Build for Linux aarch64 on CI",
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||||
"CMAKE_COMPILE_WARNING_AS_ERROR": true,
|
"CMAKE_COMPILE_WARNING_AS_ERROR": true
|
||||||
"ADVSS_ENABLE_TESTS": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ On Linux the plugin is available via the **Flatpak** package manager for users w
|
|||||||
flatpak install com.obsproject.Studio.Plugin.SceneSwitcher
|
flatpak install com.obsproject.Studio.Plugin.SceneSwitcher
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The **Snap** package manager offers an OBS Studio installation which is bundled with the plugin:
|
||||||
|
```
|
||||||
|
sudo snap install obs-studio
|
||||||
|
```
|
||||||
|
|
||||||
More information can be found [here](https://github.com/WarmUpTill/SceneSwitcher/wiki/Installation).
|
More information can be found [here](https://github.com/WarmUpTill/SceneSwitcher/wiki/Installation).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Usage: demote_deps.sh <in.deb> [Recommends|Suggests] [regex]
|
|
||||||
# Example: demote_deps.sh build/advanced-scene-switcher_1.31.0_amd64.deb Recommends 'opencv'
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
if [[ $# -lt 1 ]]; then
|
|
||||||
echo "Usage: $0 <in.deb> [Recommends|Suggests] [regex]" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
IN_DEB="$1"
|
|
||||||
DEST_FIELD="${2:-Recommends}" # Recommends or Suggests
|
|
||||||
MATCH_REGEX="${3:-opencv}" # regex to match packages to demote
|
|
||||||
|
|
||||||
echo "Demoting dependencies matching '${MATCH_REGEX}' to ${DEST_FIELD}"
|
|
||||||
|
|
||||||
TMPDIR="$(mktemp -d)"
|
|
||||||
trap 'rm -rf "$TMPDIR"' EXIT
|
|
||||||
|
|
||||||
dpkg-deb -R "$IN_DEB" "$TMPDIR"
|
|
||||||
CONTROL="$TMPDIR/DEBIAN/control"
|
|
||||||
|
|
||||||
# Read a field (single line value), handling continuation lines starting with a space.
|
|
||||||
get_field() {
|
|
||||||
local key="$1"
|
|
||||||
awk -v key="$key" '
|
|
||||||
BEGIN { val=""; collecting=0 }
|
|
||||||
$0 ~ "^" key ":" {
|
|
||||||
collecting=1
|
|
||||||
sub("^" key ":[[:space:]]*", "", $0)
|
|
||||||
val=$0
|
|
||||||
next
|
|
||||||
}
|
|
||||||
collecting==1 {
|
|
||||||
if ($0 ~ "^[[:space:]]") {
|
|
||||||
sub("^[[:space:]]+", "", $0)
|
|
||||||
val = val " " $0
|
|
||||||
next
|
|
||||||
} else {
|
|
||||||
collecting=0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END { print val }
|
|
||||||
' "$CONTROL"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Split a comma-separated list into lines, trimming whitespace
|
|
||||||
split_csv() {
|
|
||||||
tr ',' '\n' | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//' | sed '/^$/d'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Join with ", "
|
|
||||||
join_csv() {
|
|
||||||
awk 'BEGIN{first=1}{ if(!first) printf(", "); printf("%s",$0); first=0 } END{print ""}'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Deduplicate while preserving order
|
|
||||||
dedup() {
|
|
||||||
awk '!seen[$0]++'
|
|
||||||
}
|
|
||||||
|
|
||||||
DEPENDS_VAL="$(get_field Depends)"
|
|
||||||
EXIST_DEST_VAL="$(get_field "$DEST_FIELD")"
|
|
||||||
|
|
||||||
# Separate opencv-matching vs the rest (preserve tokens exactly)
|
|
||||||
mapfile -t DEPENDS_ARR < <(printf "%s\n" "$DEPENDS_VAL" | split_csv)
|
|
||||||
declare -a MOVED=()
|
|
||||||
declare -a KEPT=()
|
|
||||||
for item in "${DEPENDS_ARR[@]}"; do
|
|
||||||
# Skip empty just in case
|
|
||||||
[[ -z "$item" ]] && continue
|
|
||||||
if [[ "$item" =~ $MATCH_REGEX ]]; then
|
|
||||||
MOVED+=("$item")
|
|
||||||
else
|
|
||||||
KEPT+=("$item")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Merge with existing dest field
|
|
||||||
if [[ -n "$EXIST_DEST_VAL" ]]; then
|
|
||||||
mapfile -t EXIST_DEST_ARR < <(printf "%s\n" "$EXIST_DEST_VAL" | split_csv)
|
|
||||||
MOVED+=("${EXIST_DEST_ARR[@]}")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# De-duplicate
|
|
||||||
mapfile -t MOVED < <(printf "%s\n" "${MOVED[@]:-}" | sed '/^$/d' | dedup)
|
|
||||||
mapfile -t KEPT < <(printf "%s\n" "${KEPT[@]:-}" | sed '/^$/d' | dedup)
|
|
||||||
|
|
||||||
# Rebuild values
|
|
||||||
NEW_DEPENDS="$(printf "%s\n" "${KEPT[@]:-}" | join_csv || true)"
|
|
||||||
NEW_DEST="$(printf "%s\n" "${MOVED[@]:-}" | join_csv || true)"
|
|
||||||
|
|
||||||
# Write a cleaned control (remove existing Depends/Recommends/Suggests incl. continuations)
|
|
||||||
awk '
|
|
||||||
BEGIN { skip=0 }
|
|
||||||
{
|
|
||||||
if ($0 ~ "^(Depends|Recommends|Suggests):") { skip=1; next }
|
|
||||||
if (skip==1) {
|
|
||||||
if ($0 ~ "^[[:space:]]") { next } else { skip=0 }
|
|
||||||
}
|
|
||||||
print
|
|
||||||
}
|
|
||||||
' "$CONTROL" > "$CONTROL.clean"
|
|
||||||
|
|
||||||
# Append the rebuilt fields
|
|
||||||
{
|
|
||||||
cat "$CONTROL.clean"
|
|
||||||
if [[ -n "$NEW_DEPENDS" ]]; then
|
|
||||||
echo "Depends: $NEW_DEPENDS"
|
|
||||||
fi
|
|
||||||
if [[ -n "$NEW_DEST" ]]; then
|
|
||||||
echo "$DEST_FIELD: $NEW_DEST"
|
|
||||||
fi
|
|
||||||
} > "$CONTROL.new"
|
|
||||||
|
|
||||||
# Clean up empty lines
|
|
||||||
sed -i '/^[[:space:]]*$/d' "$CONTROL.new"
|
|
||||||
|
|
||||||
mv "$CONTROL.new" "$CONTROL"
|
|
||||||
rm -f "$CONTROL.clean"
|
|
||||||
|
|
||||||
# Repack
|
|
||||||
rm -f "${IN_DEB}"
|
|
||||||
OUT_DEB="${IN_DEB}"
|
|
||||||
dpkg-deb -b "$TMPDIR" "$OUT_DEB" >/dev/null
|
|
||||||
echo "$OUT_DEB"
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
Advanced Scene Switcher - Windows Installation (Portable)
|
|
||||||
==========================================================
|
|
||||||
|
|
||||||
For full installation instructions visit:
|
|
||||||
https://github.com/WarmUpTill/SceneSwitcher/wiki/Installation
|
|
||||||
|
|
||||||
|
|
||||||
This archive uses the portable plugin layout for older OBS versions,
|
|
||||||
portable OBS installs, and Steam.
|
|
||||||
|
|
||||||
Extract the CONTENTS of this archive into your OBS installation directory,
|
|
||||||
typically:
|
|
||||||
|
|
||||||
C:\Program Files\obs-studio\
|
|
||||||
|
|
||||||
Merge the data\ and obs-plugins\ folders with the existing ones when prompted.
|
|
||||||
|
|
||||||
Steam users: right-click OBS in your library -> Manage -> Browse local files,
|
|
||||||
then extract the contents of this archive into that directory.
|
|
||||||
|
|
||||||
|
|
||||||
For OBS 28 and newer the recommended archive is preferred:
|
|
||||||
advanced-scene-switcher-<version>-windows-x64.zip
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
Advanced Scene Switcher - Windows Installation
|
|
||||||
===============================================
|
|
||||||
|
|
||||||
For full installation instructions visit:
|
|
||||||
https://github.com/WarmUpTill/SceneSwitcher/wiki/Installation
|
|
||||||
|
|
||||||
|
|
||||||
This archive uses the recommended plugin layout for OBS 28 and newer.
|
|
||||||
|
|
||||||
Extract the CONTENTS of this archive into:
|
|
||||||
|
|
||||||
C:\ProgramData\obs-studio\plugins\
|
|
||||||
|
|
||||||
Tip: press Win+R and type %ProgramData%\obs-studio\plugins to open that folder.
|
|
||||||
|
|
||||||
After extracting, the path should look like:
|
|
||||||
C:\ProgramData\obs-studio\plugins\advanced-scene-switcher\bin\64bit\advanced-scene-switcher.dll
|
|
||||||
|
|
||||||
|
|
||||||
If the plugin does not appear in OBS, try the portable archive instead:
|
|
||||||
advanced-scene-switcher-<version>-windows-x64-portable.zip
|
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
if(BUILD_OUT_OF_TREE)
|
if(BUILD_OUT_OF_TREE)
|
||||||
if(OS_WINDOWS)
|
if(OS_WINDOWS)
|
||||||
set(OBS_PLUGIN_DESTINATION "${CMAKE_PROJECT_NAME}/bin/64bit")
|
set(OBS_PLUGIN_DESTINATION "obs-plugins/64bit")
|
||||||
else()
|
else()
|
||||||
set(OBS_PLUGIN_DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-plugins")
|
set(OBS_PLUGIN_DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-plugins")
|
||||||
endif()
|
endif()
|
||||||
@@ -157,9 +157,7 @@ else()
|
|||||||
set_target_properties(${target} PROPERTIES INSTALL_RPATH
|
set_target_properties(${target} PROPERTIES INSTALL_RPATH
|
||||||
"$ORIGIN:$ORIGIN/..")
|
"$ORIGIN:$ORIGIN/..")
|
||||||
endif()
|
endif()
|
||||||
get_filename_component(_plugin_dir_name "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
|
message(STATUS "ADVSS: ENABLED PLUGIN ${target}")
|
||||||
set_property(GLOBAL APPEND PROPERTY ADVSS_PLUGINS_ENABLED
|
|
||||||
${_plugin_dir_name})
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(install_advss_plugin_dependency_target target dep)
|
function(install_advss_plugin_dependency_target target dep)
|
||||||
@@ -333,8 +331,6 @@ function(setup_advss_plugin target)
|
|||||||
PRIVATE "${ADVSS_SOURCE_DIR}/lib" "${ADVSS_SOURCE_DIR}/lib/legacy"
|
PRIVATE "${ADVSS_SOURCE_DIR}/lib" "${ADVSS_SOURCE_DIR}/lib/legacy"
|
||||||
"${ADVSS_SOURCE_DIR}/lib/macro" "${ADVSS_SOURCE_DIR}/lib/utils"
|
"${ADVSS_SOURCE_DIR}/lib/macro" "${ADVSS_SOURCE_DIR}/lib/utils"
|
||||||
"${ADVSS_SOURCE_DIR}/lib/variables" "${ADVSS_SOURCE_DIR}/forms")
|
"${ADVSS_SOURCE_DIR}/lib/variables" "${ADVSS_SOURCE_DIR}/forms")
|
||||||
|
|
||||||
target_precompile_headers(${target} PRIVATE "${ADVSS_SOURCE_DIR}/lib/pch.hpp")
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(install_advss_plugin_dependency)
|
function(install_advss_plugin_dependency)
|
||||||
|
|||||||
@@ -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,53 +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)
|
|
||||||
|
|
||||||
list(GET download_status 0 error_code)
|
|
||||||
list(GET download_status 1 error_message)
|
|
||||||
|
|
||||||
if(error_code EQUAL 0)
|
|
||||||
file(SHA256 "${dependencies_dir}/${file}" actual_hash)
|
|
||||||
if(NOT actual_hash STREQUAL hash)
|
|
||||||
set(error_code 1)
|
|
||||||
set(error_message
|
|
||||||
"hash mismatch (expected ${hash}, got ${actual_hash})")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
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}")
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ function(_git_find_closest_git_dir _start_dir _git_dir_var)
|
|||||||
while(NOT EXISTS "${git_dir}")
|
while(NOT EXISTS "${git_dir}")
|
||||||
# .git dir not found, search parent directories
|
# .git dir not found, search parent directories
|
||||||
set(git_previous_parent "${cur_dir}")
|
set(git_previous_parent "${cur_dir}")
|
||||||
get_filename_component(cur_dir "${cur_dir}" DIRECTORY)
|
get_filename_component(cur_dir ${cur_dir} DIRECTORY)
|
||||||
if(cur_dir STREQUAL git_previous_parent)
|
if(cur_dir STREQUAL git_previous_parent)
|
||||||
# We have reached the root directory, we are not in git
|
# We have reached the root directory, we are not in git
|
||||||
set(${_git_dir_var}
|
set(${_git_dir_var}
|
||||||
|
|||||||
@@ -18,11 +18,8 @@ set(CPACK_PACKAGE_FILE_NAME
|
|||||||
"${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_C_LIBRARY_ARCHITECTURE}"
|
"${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_C_LIBRARY_ARCHITECTURE}"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CPACK_GENERATOR
|
set(CPACK_GENERATOR "DEB")
|
||||||
"DEB"
|
|
||||||
CACHE STRING "CPack generator to use")
|
|
||||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "obs-studio")
|
|
||||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PLUGIN_EMAIL}")
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PLUGIN_EMAIL}")
|
||||||
set(CPACK_SET_DESTDIR ON)
|
set(CPACK_SET_DESTDIR ON)
|
||||||
|
|
||||||
@@ -49,19 +46,6 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME
|
|||||||
set(CPACK_ARCHIVE_THREADS 0)
|
set(CPACK_ARCHIVE_THREADS 0)
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
# CPack.cmake has a side effect that leaves binary packaging variables in the
|
|
||||||
# state intended for source packaging when it finishes. Specifically it sets
|
|
||||||
# CPACK_GENERATOR to CPACK_SOURCE_GENERATOR ("TXZ"), sets
|
|
||||||
# CPACK_INSTALLED_DIRECTORIES to the source root (which would cause CPackDeb to
|
|
||||||
# scan the entire source tree, including ccache object files that lack a Build
|
|
||||||
# ID), and clears CPACK_INSTALL_CMAKE_PROJECTS (preventing the cmake install
|
|
||||||
# mechanism from being used). In some cmake versions these overrides happen
|
|
||||||
# before CPackConfig.cmake is written. Reset all three so that binary DEB
|
|
||||||
# packaging works correctly regardless of cmake version.
|
|
||||||
set(CPACK_GENERATOR "DEB")
|
|
||||||
set(CPACK_INSTALLED_DIRECTORIES "")
|
|
||||||
set(CPACK_INSTALL_CMAKE_PROJECTS
|
|
||||||
"${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/")
|
|
||||||
|
|
||||||
find_package(libobs QUIET)
|
find_package(libobs QUIET)
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,7 @@ include(buildspec_common)
|
|||||||
|
|
||||||
# _check_dependencies_windows: Set up Windows slice for _check_dependencies
|
# _check_dependencies_windows: Set up Windows slice for _check_dependencies
|
||||||
function(_check_dependencies_windows)
|
function(_check_dependencies_windows)
|
||||||
if(CMAKE_GENERATOR_PLATFORM)
|
set(arch ${CMAKE_GENERATOR_PLATFORM})
|
||||||
set(arch ${CMAKE_GENERATOR_PLATFORM})
|
|
||||||
else()
|
|
||||||
set(arch x64)
|
|
||||||
endif()
|
|
||||||
set(platform windows-${arch})
|
set(platform windows-${arch})
|
||||||
|
|
||||||
set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps")
|
set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps")
|
||||||
|
|||||||
@@ -6,9 +6,3 @@ include_guard(GLOBAL)
|
|||||||
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE)
|
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE)
|
||||||
|
|
||||||
include(buildspec)
|
include(buildspec)
|
||||||
|
|
||||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
|
||||||
set(CMAKE_INSTALL_PREFIX
|
|
||||||
"$ENV{ALLUSERSPROFILE}/obs-studio/plugins"
|
|
||||||
CACHE STRING "Default plugin installation directory" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ function(set_target_properties_plugin target)
|
|||||||
|
|
||||||
install(
|
install(
|
||||||
TARGETS ${target}
|
TARGETS ${target}
|
||||||
RUNTIME DESTINATION "${target}/bin/64bit"
|
RUNTIME DESTINATION bin/64bit
|
||||||
LIBRARY DESTINATION "${target}/bin/64bit")
|
LIBRARY DESTINATION obs-plugins/64bit)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
FILES "$<TARGET_PDB_FILE:${target}>"
|
FILES "$<TARGET_PDB_FILE:${target}>"
|
||||||
CONFIGURATIONS RelWithDebInfo Debug Release
|
CONFIGURATIONS RelWithDebInfo Debug Release
|
||||||
DESTINATION "${target}/bin/64bit"
|
DESTINATION obs-plugins/64bit
|
||||||
OPTIONAL)
|
OPTIONAL)
|
||||||
|
|
||||||
if(OBS_BUILD_DIR)
|
if(OBS_BUILD_DIR)
|
||||||
@@ -44,11 +44,11 @@ function(set_target_properties_plugin target)
|
|||||||
TARGET ${target}
|
TARGET ${target}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND "${CMAKE_COMMAND}" -E make_directory
|
COMMAND "${CMAKE_COMMAND}" -E make_directory
|
||||||
"${OBS_BUILD_DIR}/plugins/${target}/bin/64bit"
|
"${OBS_BUILD_DIR}/obs-plugins/64bit"
|
||||||
COMMAND
|
COMMAND
|
||||||
"${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${target}>"
|
"${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${target}>"
|
||||||
"$<$<CONFIG:Debug,RelWithDebInfo,Release>:$<TARGET_PDB_FILE:${target}>>"
|
"$<$<CONFIG:Debug,RelWithDebInfo,Release>:$<TARGET_PDB_FILE:${target}>>"
|
||||||
"${OBS_BUILD_DIR}/plugins/${target}/bin/64bit"
|
"${OBS_BUILD_DIR}/obs-plugins/64bit"
|
||||||
COMMENT "Copy ${target} to obs-studio directory ${OBS_BUILD_DIR}"
|
COMMENT "Copy ${target} to obs-studio directory ${OBS_BUILD_DIR}"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
endif()
|
endif()
|
||||||
@@ -105,7 +105,7 @@ function(target_install_resources target)
|
|||||||
|
|
||||||
install(
|
install(
|
||||||
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/"
|
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/"
|
||||||
DESTINATION "${target}/data"
|
DESTINATION data/obs-plugins/${target}
|
||||||
USE_SOURCE_PERMISSIONS)
|
USE_SOURCE_PERMISSIONS)
|
||||||
|
|
||||||
if(OBS_BUILD_DIR)
|
if(OBS_BUILD_DIR)
|
||||||
@@ -113,11 +113,11 @@ function(target_install_resources target)
|
|||||||
TARGET ${target}
|
TARGET ${target}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND "${CMAKE_COMMAND}" -E make_directory
|
COMMAND "${CMAKE_COMMAND}" -E make_directory
|
||||||
"${OBS_BUILD_DIR}/plugins/${target}/data"
|
"${OBS_BUILD_DIR}/data/obs-plugins/${target}"
|
||||||
COMMAND
|
COMMAND
|
||||||
"${CMAKE_COMMAND}" -E copy_directory
|
"${CMAKE_COMMAND}" -E copy_directory
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/data"
|
"${CMAKE_CURRENT_SOURCE_DIR}/data"
|
||||||
"${OBS_BUILD_DIR}/plugins/${target}/data"
|
"${OBS_BUILD_DIR}/data/obs-plugins/${target}"
|
||||||
COMMENT "Copy ${target} resources to data directory"
|
COMMENT "Copy ${target} resources to data directory"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
endif()
|
endif()
|
||||||
@@ -133,7 +133,7 @@ function(target_add_resource target resource)
|
|||||||
|
|
||||||
install(
|
install(
|
||||||
FILES "${resource}"
|
FILES "${resource}"
|
||||||
DESTINATION "${target}/data"
|
DESTINATION data/obs-plugins/${target}
|
||||||
COMPONENT Runtime)
|
COMPONENT Runtime)
|
||||||
|
|
||||||
if(OBS_BUILD_DIR)
|
if(OBS_BUILD_DIR)
|
||||||
@@ -141,9 +141,9 @@ function(target_add_resource target resource)
|
|||||||
TARGET ${target}
|
TARGET ${target}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND "${CMAKE_COMMAND}" -E make_directory
|
COMMAND "${CMAKE_COMMAND}" -E make_directory
|
||||||
"${OBS_BUILD_DIR}/plugins/${target}/data"
|
"${OBS_BUILD_DIR}/data/obs-plugins/${target}"
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy "${resource}"
|
COMMAND "${CMAKE_COMMAND}" -E copy "${resource}"
|
||||||
"${OBS_BUILD_DIR}/plugins/${target}/data"
|
"${OBS_BUILD_DIR}/data/obs-plugins/${target}"
|
||||||
COMMENT "Copy ${target} resource ${resource} to library directory"
|
COMMENT "Copy ${target} resource ${resource} to library directory"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -2,13 +2,12 @@
|
|||||||
#define MyAppVersion "@CMAKE_PROJECT_VERSION@"
|
#define MyAppVersion "@CMAKE_PROJECT_VERSION@"
|
||||||
#define MyAppPublisher "@PLUGIN_AUTHOR@"
|
#define MyAppPublisher "@PLUGIN_AUTHOR@"
|
||||||
#define MyAppURL "@PLUGIN_WEBSITE@"
|
#define MyAppURL "@PLUGIN_WEBSITE@"
|
||||||
#define MyAppId "@UUID_APP@"
|
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
; NOTE: The value of AppId uniquely identifies this application.
|
; NOTE: The value of AppId uniquely identifies this application.
|
||||||
; Do not use the same AppId value in installers for other applications.
|
; Do not use the same AppId value in installers for other applications.
|
||||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||||
AppId={{{#MyAppId}}
|
AppId={{@UUID_APP@}
|
||||||
AppName={#MyAppName}
|
AppName={#MyAppName}
|
||||||
AppVersion={#MyAppVersion}
|
AppVersion={#MyAppVersion}
|
||||||
AppPublisher={#MyAppPublisher}
|
AppPublisher={#MyAppPublisher}
|
||||||
@@ -21,19 +20,14 @@ OutputBaseFilename={#MyAppName}-{#MyAppVersion}-Windows-Installer
|
|||||||
Compression=lzma
|
Compression=lzma
|
||||||
SolidCompression=yes
|
SolidCompression=yes
|
||||||
DirExistsWarning=no
|
DirExistsWarning=no
|
||||||
UsePreviousAppDir=no
|
|
||||||
SetupIconFile=installer.ico
|
SetupIconFile=installer.ico
|
||||||
UninstallDisplayIcon={code:GetUninstallIconPath}
|
UninstallDisplayIcon={app}\data\obs-plugins\advanced-scene-switcher\res\images\logo.ico
|
||||||
DisableDirPage=no
|
|
||||||
|
|
||||||
[Languages]
|
[Languages]
|
||||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
; Recommended layout - used when installing to %ProgramData%\obs-studio\plugins\
|
Source: "..\release\Package\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
Source: "..\release\Package\recommended\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: IsRecommendedLayout
|
|
||||||
; Legacy layout - used when installing to the OBS installation directory
|
|
||||||
Source: "..\release\Package\portable\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Check: IsLegacyLayout
|
|
||||||
Source: "..\LICENSE"; Flags: dontcopy
|
Source: "..\LICENSE"; Flags: dontcopy
|
||||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
|
||||||
@@ -56,64 +50,17 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Returns true when the selected install directory is under %ProgramData%,
|
// credit where it's due :
|
||||||
// meaning the recommended plugin layout should be used.
|
// following function come from https://github.com/Xaymar/obs-studio_amf-encoder-plugin/blob/master/%23Resources/Installer.in.iss#L45
|
||||||
function IsRecommendedLayout(): Boolean;
|
|
||||||
begin
|
|
||||||
Result := Pos(LowerCase(ExpandConstant('{commonappdata}')),
|
|
||||||
LowerCase(WizardDirValue())) = 1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function IsLegacyLayout(): Boolean;
|
|
||||||
begin
|
|
||||||
Result := not IsRecommendedLayout();
|
|
||||||
end;
|
|
||||||
|
|
||||||
function GetUninstallIconPath(Param: string): string;
|
|
||||||
begin
|
|
||||||
if IsRecommendedLayout() then
|
|
||||||
Result := ExpandConstant('{app}\advanced-scene-switcher\data\res\images\logo.ico')
|
|
||||||
else
|
|
||||||
Result := ExpandConstant('{app}\data\obs-plugins\advanced-scene-switcher\res\images\logo.ico');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function GetDirName(Value: string): string;
|
function GetDirName(Value: string): string;
|
||||||
var
|
var
|
||||||
PrevPath: string;
|
InstallPath: string;
|
||||||
UninstallKey: string;
|
|
||||||
begin
|
begin
|
||||||
Result := ExpandConstant('{commonappdata}\obs-studio\plugins');
|
// initialize default path, which will be returned when the following registry
|
||||||
UninstallKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + '{' + '{#MyAppId}' + '}_is1';
|
// key queries fail due to missing keys or for some different reason
|
||||||
if RegQueryStringValue(HKLM, UninstallKey, 'InstallLocation', PrevPath) and (PrevPath <> '') then
|
Result := '{autopf}\obs-studio';
|
||||||
Result := PrevPath;
|
// query the first registry value; if this succeeds, return the obtained value
|
||||||
|
if RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', InstallPath) then
|
||||||
|
Result := InstallPath
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Remove files placed by the portable installer (obs-plugins/64bit and
|
|
||||||
// data/obs-plugins layout) so the plugin is not loaded twice by OBS.
|
|
||||||
// Only runs when upgrading from a portable location to the recommended one.
|
|
||||||
procedure RemoveLegacyFiles();
|
|
||||||
var
|
|
||||||
OldInstallPath: string;
|
|
||||||
UninstallKey: string;
|
|
||||||
begin
|
|
||||||
if not IsRecommendedLayout() then
|
|
||||||
Exit;
|
|
||||||
UninstallKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + '{' + '{#MyAppId}' + '}_is1';
|
|
||||||
if not RegQueryStringValue(HKLM, UninstallKey, 'InstallLocation', OldInstallPath) then
|
|
||||||
Exit;
|
|
||||||
// Skip if the previous install was already in the recommended location
|
|
||||||
if Pos(LowerCase(ExpandConstant('{commonappdata}')), LowerCase(OldInstallPath)) = 1 then
|
|
||||||
Exit;
|
|
||||||
DeleteFile(OldInstallPath + '\obs-plugins\64bit\advanced-scene-switcher.dll');
|
|
||||||
DeleteFile(OldInstallPath + '\obs-plugins\64bit\advanced-scene-switcher.pdb');
|
|
||||||
DeleteFile(OldInstallPath + '\obs-plugins\64bit\advanced-scene-switcher-lib.dll');
|
|
||||||
DeleteFile(OldInstallPath + '\obs-plugins\64bit\advanced-scene-switcher-lib.pdb');
|
|
||||||
DelTree(OldInstallPath + '\obs-plugins\64bit\advanced-scene-switcher-plugins', True, True, True);
|
|
||||||
DelTree(OldInstallPath + '\data\obs-plugins\advanced-scene-switcher', True, True, True);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure CurStepChanged(CurStep: TSetupStep);
|
|
||||||
begin
|
|
||||||
if CurStep = ssInstall then
|
|
||||||
RemoveLegacyFiles();
|
|
||||||
end;
|
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Detects OpenSSL installed via winget or other common Windows locations,
|
|
||||||
# without requiring the user to manually set OPENSSL_ROOT_DIR.
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if(WIN32 AND (NOT OpenSSL_FOUND))
|
|
||||||
|
|
||||||
set(_openssl_roots
|
|
||||||
"$ENV{ProgramFiles}/OpenSSL-Win64" "$ENV{ProgramFiles}/OpenSSL"
|
|
||||||
"$ENV{ProgramW6432}/OpenSSL-Win64")
|
|
||||||
|
|
||||||
set(_openssl_lib_suffixes "lib/VC/x64/MD" "lib/VC/x64/MDd" "lib/VC/x64/MT"
|
|
||||||
"lib/VC/x64/MTd" "lib")
|
|
||||||
|
|
||||||
# Determine which configuration we're building
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
|
||||||
set(_is_debug TRUE)
|
|
||||||
else()
|
|
||||||
set(_is_debug FALSE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Determine which runtime we use Default to /MD (shared CRT)
|
|
||||||
set(_crt_kind "MD")
|
|
||||||
if(MSVC)
|
|
||||||
if(CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "MultiThreaded")
|
|
||||||
if(CMAKE_MSVC_RUNTIME_LIBRARY MATCHES "Debug")
|
|
||||||
set(_crt_kind "MTd")
|
|
||||||
else()
|
|
||||||
set(_crt_kind "MT")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
if(_is_debug)
|
|
||||||
set(_crt_kind "MDd")
|
|
||||||
else()
|
|
||||||
set(_crt_kind "MD")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Looking for OpenSSL built with CRT variant: ${_crt_kind}")
|
|
||||||
|
|
||||||
# Try to find the root and corresponding lib path
|
|
||||||
if(OPENSSL_USE_STATIC_LIBS)
|
|
||||||
set(_crypto_lib_name "libcrypto_static.lib")
|
|
||||||
set(_ssl_lib_name "libssl_static.lib")
|
|
||||||
else()
|
|
||||||
set(_crypto_lib_name "libcrypto.lib")
|
|
||||||
set(_ssl_lib_name "libssl.lib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
foreach(_root ${_openssl_roots})
|
|
||||||
if(EXISTS "${_root}/include/openssl/ssl.h")
|
|
||||||
foreach(_suffix ${_openssl_lib_suffixes})
|
|
||||||
if(_suffix MATCHES "${_crt_kind}$"
|
|
||||||
AND EXISTS "${_root}/${_suffix}/${_crypto_lib_name}")
|
|
||||||
set(OPENSSL_ROOT_DIR
|
|
||||||
"${_root}"
|
|
||||||
CACHE PATH "Path to OpenSSL root")
|
|
||||||
set(OPENSSL_CRYPTO_LIBRARY
|
|
||||||
"${_root}/${_suffix}/${_crypto_lib_name}"
|
|
||||||
CACHE FILEPATH "OpenSSL crypto lib")
|
|
||||||
set(OPENSSL_SSL_LIBRARY
|
|
||||||
"${_root}/${_suffix}/${_ssl_lib_name}"
|
|
||||||
CACHE FILEPATH "OpenSSL ssl lib")
|
|
||||||
set(OPENSSL_INCLUDE_DIR
|
|
||||||
"${_root}/include"
|
|
||||||
CACHE PATH "OpenSSL include dir")
|
|
||||||
set(OpenSSL_FOUND
|
|
||||||
TRUE
|
|
||||||
CACHE BOOL "Whether OpenSSL was found")
|
|
||||||
message(STATUS "Found OpenSSL at: ${_root}/${_suffix}")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
if(OpenSSL_FOUND)
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if(NOT OpenSSL_FOUND)
|
|
||||||
message(WARNING "Could not auto-detect OpenSSL under Program Files. "
|
|
||||||
"Might have to set OPENSSL_ROOT_DIR manually.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif()
|
|
||||||
@@ -12,7 +12,7 @@ AdvSceneSwitcher.generalTab.status.onStartup.alwaysStart="Aktiviere den Szenenwe
|
|||||||
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Aktiviere den Szenenwechsler nicht"
|
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Aktiviere den Szenenwechsler nicht"
|
||||||
AdvSceneSwitcher.generalTab.status.start="Start"
|
AdvSceneSwitcher.generalTab.status.start="Start"
|
||||||
AdvSceneSwitcher.generalTab.status.stop="Stop"
|
AdvSceneSwitcher.generalTab.status.stop="Stop"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.startup="Starte auotmatischen den Szenenwechsler beim:"
|
AdvSceneSwitcher.generalTab.status.autoStart="Starte auotmatischen den Szenenwechsler beim:"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.never="Niemals"
|
AdvSceneSwitcher.generalTab.status.autoStart.never="Niemals"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.recording="Aufnehmen"
|
AdvSceneSwitcher.generalTab.status.autoStart.recording="Aufnehmen"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Streamen"
|
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Streamen"
|
||||||
@@ -76,6 +76,7 @@ AdvSceneSwitcher.macroTab.name="Name:"
|
|||||||
AdvSceneSwitcher.macroTab.run="Makro ausführen"
|
AdvSceneSwitcher.macroTab.run="Makro ausführen"
|
||||||
AdvSceneSwitcher.macroTab.runFail="Ausführen von \"%1\" fehlgeschlagen!\nEntweder ist eine der Aktionen fehlgeschlagen oder das Makro wird bereits ausgeführt.\nSoll die aktuelle Ausführung gestoppt werden?"
|
AdvSceneSwitcher.macroTab.runFail="Ausführen von \"%1\" fehlgeschlagen!\nEntweder ist eine der Aktionen fehlgeschlagen oder das Makro wird bereits ausgeführt.\nSoll die aktuelle Ausführung gestoppt werden?"
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Parallel zu anderen Makros ausführen"
|
AdvSceneSwitcher.macroTab.runInParallel="Parallel zu anderen Makros ausführen"
|
||||||
|
AdvSceneSwitcher.macroTab.onChange="Nur bei Änderung ausführen"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
||||||
AdvSceneSwitcher.macroTab.defaultGroupName="Gruppe %1"
|
AdvSceneSwitcher.macroTab.defaultGroupName="Gruppe %1"
|
||||||
AdvSceneSwitcher.macroTab.removeGroupPopup.text="Sicher, dass \"%1\" und alle zugehörigen Elemente gelöscht werden?"
|
AdvSceneSwitcher.macroTab.removeGroupPopup.text="Sicher, dass \"%1\" und alle zugehörigen Elemente gelöscht werden?"
|
||||||
@@ -99,6 +100,7 @@ AdvSceneSwitcher.macroList.deleted="gelöscht"
|
|||||||
AdvSceneSwitcher.macroList.duplicate="\"%1\" ist bereits ausgewählt!"
|
AdvSceneSwitcher.macroList.duplicate="\"%1\" ist bereits ausgewählt!"
|
||||||
|
|
||||||
; Macro Logic
|
; Macro Logic
|
||||||
|
AdvSceneSwitcher.logic.none="Eintrag ignorieren"
|
||||||
AdvSceneSwitcher.logic.and="Und"
|
AdvSceneSwitcher.logic.and="Und"
|
||||||
AdvSceneSwitcher.logic.or="Oder"
|
AdvSceneSwitcher.logic.or="Oder"
|
||||||
AdvSceneSwitcher.logic.andNot="Und nicht"
|
AdvSceneSwitcher.logic.andNot="Und nicht"
|
||||||
@@ -144,7 +146,11 @@ AdvSceneSwitcher.condition.file="Datei"
|
|||||||
AdvSceneSwitcher.condition.file.type.match="entspricht"
|
AdvSceneSwitcher.condition.file.type.match="entspricht"
|
||||||
AdvSceneSwitcher.condition.file.type.contentChange="Inhalt geändert"
|
AdvSceneSwitcher.condition.file.type.contentChange="Inhalt geändert"
|
||||||
AdvSceneSwitcher.condition.file.type.dateChange="Änderungsdatum geändert"
|
AdvSceneSwitcher.condition.file.type.dateChange="Änderungsdatum geändert"
|
||||||
AdvSceneSwitcher.condition.file.layout="{{filePath}}{{conditions}}{{regex}}"
|
AdvSceneSwitcher.condition.file.remote="Entfernte Datei"
|
||||||
|
AdvSceneSwitcher.condition.file.local="Lokale Datei"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Medien"
|
AdvSceneSwitcher.condition.media="Medien"
|
||||||
AdvSceneSwitcher.condition.media.source="Quelle"
|
AdvSceneSwitcher.condition.media.source="Quelle"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Beliebige Medienquelle in"
|
AdvSceneSwitcher.condition.media.anyOnScene="Beliebige Medienquelle in"
|
||||||
@@ -210,8 +216,8 @@ AdvSceneSwitcher.condition.record.state.start="Aufnahme läuft"
|
|||||||
AdvSceneSwitcher.condition.record.state.pause="Aufnahme pausiert"
|
AdvSceneSwitcher.condition.record.state.pause="Aufnahme pausiert"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Aufnahme gestoppt"
|
AdvSceneSwitcher.condition.record.state.stop="Aufnahme gestoppt"
|
||||||
AdvSceneSwitcher.condition.process="Prozess"
|
AdvSceneSwitcher.condition.process="Prozess"
|
||||||
AdvSceneSwitcher.condition.process.layout="{{processes}}{{regex}}läuft{{focused}}und ist fokusiert"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}läuft{{focused}}und ist fokusiert"
|
||||||
AdvSceneSwitcher.condition.process.layout.focus="Aktueller Vordergrundprozess: {{focusProcess}}"
|
AdvSceneSwitcher.condition.process.entry.focus="Aktueller Vordergrundprozess: {{focusProcess}}"
|
||||||
AdvSceneSwitcher.condition.idle="Leerlauf"
|
AdvSceneSwitcher.condition.idle="Leerlauf"
|
||||||
AdvSceneSwitcher.condition.idle.entry="Keine Tastatur- oder Mauseingaben für {{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="Keine Tastatur- oder Mauseingaben für {{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Plugin-Status"
|
AdvSceneSwitcher.condition.pluginState="Plugin-Status"
|
||||||
@@ -285,14 +291,14 @@ AdvSceneSwitcher.condition.replay.state.started="Replay Buffer gestartet"
|
|||||||
AdvSceneSwitcher.condition.replay.state.saved="Replay Buffer gespeichert"
|
AdvSceneSwitcher.condition.replay.state.saved="Replay Buffer gespeichert"
|
||||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||||
AdvSceneSwitcher.condition.date="Datum"
|
AdvSceneSwitcher.condition.date="Datum"
|
||||||
AdvSceneSwitcher.day.any="Beliebiger Tag"
|
AdvSceneSwitcher.condition.date.anyDay="Beliebiger Tag"
|
||||||
AdvSceneSwitcher.day.monday="Montag"
|
AdvSceneSwitcher.condition.date.monday="Montag"
|
||||||
AdvSceneSwitcher.day.tuesday="Dienstag"
|
AdvSceneSwitcher.condition.date.tuesday="Dienstag"
|
||||||
AdvSceneSwitcher.day.wednesday="Mittwoch"
|
AdvSceneSwitcher.condition.date.wednesday="Mittwoch"
|
||||||
AdvSceneSwitcher.day.thursday="Donnerstag"
|
AdvSceneSwitcher.condition.date.thursday="Donnerstag"
|
||||||
AdvSceneSwitcher.day.friday="Freitag"
|
AdvSceneSwitcher.condition.date.friday="Freitag"
|
||||||
AdvSceneSwitcher.day.saturday="Samstag"
|
AdvSceneSwitcher.condition.date.saturday="Samstag"
|
||||||
AdvSceneSwitcher.day.sunday="Sonntag"
|
AdvSceneSwitcher.condition.date.sunday="Sonntag"
|
||||||
AdvSceneSwitcher.condition.date.state.at="Am"
|
AdvSceneSwitcher.condition.date.state.at="Am"
|
||||||
AdvSceneSwitcher.condition.date.state.after="Nach"
|
AdvSceneSwitcher.condition.date.state.after="Nach"
|
||||||
AdvSceneSwitcher.condition.date.state.before="Vor"
|
AdvSceneSwitcher.condition.date.state.before="Vor"
|
||||||
@@ -303,13 +309,12 @@ AdvSceneSwitcher.condition.date.ignoreDate="Wenn diese Option nicht aktiviert is
|
|||||||
AdvSceneSwitcher.condition.date.ignoreTime="Wenn diese Option nicht aktiviert ist, wird die Zeitkomponente ignoriert"
|
AdvSceneSwitcher.condition.date.ignoreTime="Wenn diese Option nicht aktiviert ist, wird die Zeitkomponente ignoriert"
|
||||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Erweiterte Einstellungen anzeigen"
|
AdvSceneSwitcher.condition.date.showAdvancedSettings="Erweiterte Einstellungen anzeigen"
|
||||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Einfache Einstellungen anzeigen"
|
AdvSceneSwitcher.condition.date.showSimpleSettings="Einfache Einstellungen anzeigen"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.day="Am{{dayOfWeek}}"
|
AdvSceneSwitcher.condition.date.entry.simple="Am {{dayOfWeek}} {{weekCondition}} {{ignoreWeekTime}}{{weekTime}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} Wiederholen alle {{duration}} bei Datumsübereinstimmung"
|
||||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}} Wiederholen alle {{duration}} bei Datumsübereinstimmung"
|
AdvSceneSwitcher.condition.date.entry.pattern="Aktuelles Datum \"{{currentDate}}\" entspricht dem Muster {{pattern}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.pattern="Aktuelles Datum \"{{currentDate}}\" entspricht dem Muster {{pattern}}"
|
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Nächster Treffer bei: %1"
|
||||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Nächster Treffer bei: %1"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Bei Wiederholung ausgewähltes Datum auf Wiederholungsdatum aktualisieren"
|
||||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}} Bei Wiederholung ausgewähltes Datum auf Wiederholungsdatum aktualisieren"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Szenenelement transformieren"
|
AdvSceneSwitcher.condition.sceneTransform="Szenenelement transformieren"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Transformation erhalten"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Transformation erhalten"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.condition.match="entspricht Transformation"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="entspricht Transformation"
|
||||||
@@ -378,12 +383,14 @@ AdvSceneSwitcher.condition.variable.type.greaterThanVariable="ist größer als d
|
|||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.scene="Szene wechseln"
|
AdvSceneSwitcher.action.scene="Szene wechseln"
|
||||||
|
AdvSceneSwitcher.action.scene.entry="Wechsle{{sceneTypes}}Szene zu{{scenes}}mittels{{transitions}}mit einer Dauer von{{duration}}Sekunden"
|
||||||
|
AdvSceneSwitcher.action.scene.entry.noDuration="Wechsle{{sceneTypes}}Szene zu{{scenes}}mittels{{transitions}}"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Warten, bis der Übergang zur Zielszene abgeschlossen ist"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Warten, bis der Übergang zur Zielszene abgeschlossen ist"
|
||||||
AdvSceneSwitcher.action.wait="Warten"
|
AdvSceneSwitcher.action.wait="Warten"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="fixe"
|
AdvSceneSwitcher.action.wait.type.fixed="fixe"
|
||||||
AdvSceneSwitcher.action.wait.type.random="zufällig"
|
AdvSceneSwitcher.action.wait.type.random="zufällig"
|
||||||
AdvSceneSwitcher.action.wait.layout.fixed="Warte für {{waitType}} Dauer von {{duration}}"
|
AdvSceneSwitcher.action.wait.entry.fixed="Warte für {{waitType}} Dauer von {{duration}}"
|
||||||
AdvSceneSwitcher.action.wait.layout.random="Warte für {{waitType}} Dauer von {{duration}} bis {{duration2}}"
|
AdvSceneSwitcher.action.wait.entry.random="Warte für {{waitType}} Dauer von {{duration}} bis {{duration2}}"
|
||||||
AdvSceneSwitcher.action.audio="Audio"
|
AdvSceneSwitcher.action.audio="Audio"
|
||||||
AdvSceneSwitcher.action.audio.type.mute="Stummgeschaltet"
|
AdvSceneSwitcher.action.audio.type.mute="Stummgeschaltet"
|
||||||
AdvSceneSwitcher.action.audio.type.unmute="Nicht stummgeschaltet"
|
AdvSceneSwitcher.action.audio.type.unmute="Nicht stummgeschaltet"
|
||||||
@@ -407,6 +414,7 @@ AdvSceneSwitcher.action.recording.type.unpause="Aufnahme nicht mehr pausieren"
|
|||||||
AdvSceneSwitcher.action.recording.type.split="Aufnahme-Datei teilen"
|
AdvSceneSwitcher.action.recording.type.split="Aufnahme-Datei teilen"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Bitte beachten, dass je nach Aufnahmeeinstellung die Aufnahme möglicherweise nicht unterbrochen werden kann"
|
AdvSceneSwitcher.action.recording.pause.hint="Bitte beachten, dass je nach Aufnahmeeinstellung die Aufnahme möglicherweise nicht unterbrochen werden kann"
|
||||||
AdvSceneSwitcher.action.recording.split.hint="Vergewissern, dass die automatische Dateiaufteilung in den OBS-Einstellungen aktiviert ist!"
|
AdvSceneSwitcher.action.recording.split.hint="Vergewissern, dass die automatische Dateiaufteilung in den OBS-Einstellungen aktiviert ist!"
|
||||||
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Replay Buffer"
|
AdvSceneSwitcher.action.replay="Replay Buffer"
|
||||||
AdvSceneSwitcher.action.replay.saveWarn="Warnung: Ein zu häufiges Speichern kann dazu führen, dass der Replay Buffer nicht gespeichert wird!"
|
AdvSceneSwitcher.action.replay.saveWarn="Warnung: Ein zu häufiges Speichern kann dazu führen, dass der Replay Buffer nicht gespeichert wird!"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Replay Buffer stoppen"
|
AdvSceneSwitcher.action.replay.type.stop="Replay Buffer stoppen"
|
||||||
@@ -415,6 +423,7 @@ AdvSceneSwitcher.action.replay.type.save="Replay Buffer speichern"
|
|||||||
AdvSceneSwitcher.action.streaming="Stream"
|
AdvSceneSwitcher.action.streaming="Stream"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Stream stoppen"
|
AdvSceneSwitcher.action.streaming.type.stop="Stream stoppen"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Stream starten"
|
AdvSceneSwitcher.action.streaming.type.start="Stream starten"
|
||||||
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Ausführen"
|
AdvSceneSwitcher.action.run="Ausführen"
|
||||||
AdvSceneSwitcher.action.sceneVisibility="Sichtbarkeit von Szenenelementen"
|
AdvSceneSwitcher.action.sceneVisibility="Sichtbarkeit von Szenenelementen"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Anzeigen"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Anzeigen"
|
||||||
@@ -422,7 +431,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="Verstecken"
|
|||||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Umschalten"
|
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Umschalten"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Quelle"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Quelle"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Beliebig"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Beliebig"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.layout="Auf{{scenes}}{{actions}}{{sources}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="Auf{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filter"
|
AdvSceneSwitcher.action.filter="Filter"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Aktivieren"
|
AdvSceneSwitcher.action.filter.type.enable="Aktivieren"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Deaktivieren"
|
AdvSceneSwitcher.action.filter.type.disable="Deaktivieren"
|
||||||
@@ -450,14 +459,14 @@ AdvSceneSwitcher.action.macro="Makro"
|
|||||||
AdvSceneSwitcher.action.macro.type.pause="Pausieren"
|
AdvSceneSwitcher.action.macro.type.pause="Pausieren"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Nicht mehr pausieren"
|
AdvSceneSwitcher.action.macro.type.unpause="Nicht mehr pausieren"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Zähler zurücksetzen"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Zähler zurücksetzen"
|
||||||
AdvSceneSwitcher.action.macro.type.runActions="Aktionen ausführen"
|
AdvSceneSwitcher.action.macro.type.run="Aktionen ausführen"
|
||||||
AdvSceneSwitcher.action.macro.type.stop="Aktionen stoppen"
|
AdvSceneSwitcher.action.macro.type.stop="Aktionen stoppen"
|
||||||
AdvSceneSwitcher.action.pluginState="Plugin-Status"
|
AdvSceneSwitcher.action.pluginState="Plugin-Status"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Erweiterten Automatischen Szenenwechsler stoppen"
|
AdvSceneSwitcher.action.pluginState.type.stop="Erweiterten Automatischen Szenenwechsler stoppen"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Ändern des Nichtübereinstimmungsverhaltens:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Ändern des Nichtübereinstimmungsverhaltens:"
|
||||||
AdvSceneSwitcher.action.pluginState.type.import="Einstellungen importieren aus"
|
AdvSceneSwitcher.action.pluginState.type.import="Einstellungen importieren aus"
|
||||||
AdvSceneSwitcher.action.pluginState.importWarning="Hinweis: Die Aktion wird ignoriert, solange das Einstellungsfenster geöffnet ist."
|
AdvSceneSwitcher.action.pluginState.importWarning="Hinweis: Die Aktion wird ignoriert, solange das Einstellungsfenster geöffnet ist."
|
||||||
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}"
|
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}{{settingsWarning}}"
|
||||||
AdvSceneSwitcher.action.virtualCamera="Virtuelle Kamera"
|
AdvSceneSwitcher.action.virtualCamera="Virtuelle Kamera"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.stop="Virtuelle Kamera stoppen"
|
AdvSceneSwitcher.action.virtualCamera.type.stop="Virtuelle Kamera stoppen"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.start="Virtuelle Kamera starten"
|
AdvSceneSwitcher.action.virtualCamera.type.start="Virtuelle Kamera starten"
|
||||||
@@ -498,9 +507,9 @@ AdvSceneSwitcher.action.transition.type.scene="Szenenübergang"
|
|||||||
AdvSceneSwitcher.action.transition.type.sceneOverride="Szenenübergang überschreiben"
|
AdvSceneSwitcher.action.transition.type.sceneOverride="Szenenübergang überschreiben"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceShow="Übergang der Quelle anzeigen"
|
AdvSceneSwitcher.action.transition.type.sourceShow="Übergang der Quelle anzeigen"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceHide="Übergang der Quelle verstecken"
|
AdvSceneSwitcher.action.transition.type.sourceHide="Übergang der Quelle verstecken"
|
||||||
AdvSceneSwitcher.action.transition.layout.type="Anpassen {{type}}{{scenes}}{{sources}}"
|
AdvSceneSwitcher.action.transition.entry.line1="Anpassen {{type}}{{scenes}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.transition="{{setTransition}}Übergangstyp festlegen auf {{transitions}}"
|
AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}}Übergangstyp festlegen auf {{transitions}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.duration="{{setDuration}}Übergangsdauer festlegen auf {{duration}}Sekunden"
|
AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}}Übergangsdauer festlegen auf {{duration}}Sekunden"
|
||||||
AdvSceneSwitcher.action.timer="Timer"
|
AdvSceneSwitcher.action.timer="Timer"
|
||||||
AdvSceneSwitcher.action.timer.type.pause="Pausieren"
|
AdvSceneSwitcher.action.timer.type.pause="Pausieren"
|
||||||
AdvSceneSwitcher.action.timer.type.continue="Fortsetzen"
|
AdvSceneSwitcher.action.timer.type.continue="Fortsetzen"
|
||||||
@@ -827,6 +836,8 @@ AdvSceneSwitcher.status.inactive="Inaktiv"
|
|||||||
AdvSceneSwitcher.running="Plugin läuft"
|
AdvSceneSwitcher.running="Plugin läuft"
|
||||||
AdvSceneSwitcher.stopped="Plugin gestoppt"
|
AdvSceneSwitcher.stopped="Plugin gestoppt"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>Dies scheint das erste Mal zu sein, dass der Erweiterte Szenenwechsler gestartet wurde.<br>Bitte schaue ins <a href=\"https://github.com/WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> für eine Liste von Anleitungen und Beispielen.<br>Nicht zögern und Fragen im <a href=\"https://obsproject.com/forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:#268bd2;\">Thread</span></a> des Plugins im OBS-Forum stellen!!</p></body></html>"
|
||||||
|
|
||||||
AdvSceneSwitcher.deprecatedTabWarning="Die Entwicklung für dieses Tab wurde gestoppt!\nBitte stattdessen zur Verwendung des Makros-Tab übergehen.\nDieser Hinweis kann im Allgemein-Tab deaktiviert werden."
|
AdvSceneSwitcher.deprecatedTabWarning="Die Entwicklung für dieses Tab wurde gestoppt!\nBitte stattdessen zur Verwendung des Makros-Tab übergehen.\nDieser Hinweis kann im Allgemein-Tab deaktiviert werden."
|
||||||
|
|
||||||
AdvSceneSwitcher.unit.milliseconds="Millisekunden"
|
AdvSceneSwitcher.unit.milliseconds="Millisekunden"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ AdvSceneSwitcher.generalTab.status.onStartup.alwaysStart="Siempre iniciar el sel
|
|||||||
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="No iniciar el selector de escenas"
|
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="No iniciar el selector de escenas"
|
||||||
AdvSceneSwitcher.generalTab.status.start="Iniciar"
|
AdvSceneSwitcher.generalTab.status.start="Iniciar"
|
||||||
AdvSceneSwitcher.generalTab.status.stop="Detener"
|
AdvSceneSwitcher.generalTab.status.stop="Detener"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.startup="Iniciar automáticamente el selector de escenas cuando:"
|
AdvSceneSwitcher.generalTab.status.autoStart="Iniciar automáticamente el selector de escenas cuando:"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.never="Nunca"
|
AdvSceneSwitcher.generalTab.status.autoStart.never="Nunca"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.recording="Grabando"
|
AdvSceneSwitcher.generalTab.status.autoStart.recording="Grabando"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Emitiendo"
|
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Emitiendo"
|
||||||
@@ -72,6 +72,7 @@ AdvSceneSwitcher.macroTab.add="Agregar nueva macro"
|
|||||||
AdvSceneSwitcher.macroTab.name="Nombre:"
|
AdvSceneSwitcher.macroTab.name="Nombre:"
|
||||||
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
||||||
|
AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
||||||
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
||||||
@@ -83,6 +84,7 @@ AdvSceneSwitcher.macroTab.highlightTrueConditions="Resaltar condiciones de la ma
|
|||||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
|
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
|
||||||
|
|
||||||
; Lógica de macros
|
; Lógica de macros
|
||||||
|
AdvSceneSwitcher.logic.none="Omitir entrada"
|
||||||
AdvSceneSwitcher.logic.and="Y"
|
AdvSceneSwitcher.logic.and="Y"
|
||||||
AdvSceneSwitcher.logic.or="O"
|
AdvSceneSwitcher.logic.or="O"
|
||||||
AdvSceneSwitcher.logic.andNot="Y no"
|
AdvSceneSwitcher.logic.andNot="Y no"
|
||||||
@@ -116,7 +118,9 @@ AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Durante la tra
|
|||||||
AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Durante la transición, verifique la escena de origen de la transición"
|
AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Durante la transición, verifique la escena de origen de la transición"
|
||||||
AdvSceneSwitcher.condition.window="Ventana"
|
AdvSceneSwitcher.condition.window="Ventana"
|
||||||
AdvSceneSwitcher.condition.file="Archivo"
|
AdvSceneSwitcher.condition.file="Archivo"
|
||||||
AdvSceneSwitcher.condition.file.layout="Contenido de{{filePath}}{{conditions}}{{regex}}"
|
AdvSceneSwitcher.condition.file.entry.line1="Contenido de{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Medios"
|
AdvSceneSwitcher.condition.media="Medios"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Cualquier fuente multimedia activada"
|
AdvSceneSwitcher.condition.media.anyOnScene="Cualquier fuente multimedia activada"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="Todas las fuentes de medios activadas"
|
AdvSceneSwitcher.condition.media.allOnScene="Todas las fuentes de medios activadas"
|
||||||
@@ -172,7 +176,7 @@ AdvSceneSwitcher.condition.record.state.start="Grabación en ejecución"
|
|||||||
AdvSceneSwitcher.condition.record.state.pause="Grabación en pausa"
|
AdvSceneSwitcher.condition.record.state.pause="Grabación en pausa"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Grabación detenida"
|
AdvSceneSwitcher.condition.record.state.stop="Grabación detenida"
|
||||||
AdvSceneSwitcher.condition.process="Proceso"
|
AdvSceneSwitcher.condition.process="Proceso"
|
||||||
AdvSceneSwitcher.condition.process.layout="{{processes}}{{regex}}se está ejecutando{{focused}}y está enfocado"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}se está ejecutando{{focused}}y está enfocado"
|
||||||
AdvSceneSwitcher.condition.idle="Inactivo"
|
AdvSceneSwitcher.condition.idle="Inactivo"
|
||||||
AdvSceneSwitcher.condition.idle.entry="No hay entradas de teclado o ratón durante {{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="No hay entradas de teclado o ratón durante {{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Estado del complemento"
|
AdvSceneSwitcher.condition.pluginState="Estado del complemento"
|
||||||
@@ -237,14 +241,14 @@ AdvSceneSwitcher.condition.replay.state.started="Búfer de reproducción iniciad
|
|||||||
AdvSceneSwitcher.condition.replay.state.saved="Búfer de reproducción guardado"
|
AdvSceneSwitcher.condition.replay.state.saved="Búfer de reproducción guardado"
|
||||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||||
AdvSceneSwitcher.condition.date="Fecha"
|
AdvSceneSwitcher.condition.date="Fecha"
|
||||||
AdvSceneSwitcher.day.any="Cualquier día"
|
AdvSceneSwitcher.condition.date.anyDay="Cualquier día"
|
||||||
AdvSceneSwitcher.day.monday="Lunes"
|
AdvSceneSwitcher.condition.date.monday="Lunes"
|
||||||
AdvSceneSwitcher.day.tuesday="Martes"
|
AdvSceneSwitcher.condition.date.tuesday="Martes"
|
||||||
AdvSceneSwitcher.day.wednesday="Miércoles"
|
AdvSceneSwitcher.condition.date.wednesday="Miércoles"
|
||||||
AdvSceneSwitcher.day.thursday="Jueves"
|
AdvSceneSwitcher.condition.date.thursday="Jueves"
|
||||||
AdvSceneSwitcher.day.friday="Viernes"
|
AdvSceneSwitcher.condition.date.friday="Viernes"
|
||||||
AdvSceneSwitcher.day.saturday="Sábado"
|
AdvSceneSwitcher.condition.date.saturday="Sábado"
|
||||||
AdvSceneSwitcher.day.sunday="Domingo"
|
AdvSceneSwitcher.condition.date.sunday="Domingo"
|
||||||
AdvSceneSwitcher.condition.date.state.at="A las"
|
AdvSceneSwitcher.condition.date.state.at="A las"
|
||||||
AdvSceneSwitcher.condition.date.state.after="Después"
|
AdvSceneSwitcher.condition.date.state.after="Después"
|
||||||
AdvSceneSwitcher.condition.date.state.before="Antes"
|
AdvSceneSwitcher.condition.date.state.before="Antes"
|
||||||
@@ -254,12 +258,11 @@ AdvSceneSwitcher.condition.date.ignoreDate="Si no se marca, se ignorará el comp
|
|||||||
AdvSceneSwitcher.condition.date.ignoreTime="Si no se marca, se ignorará el componente de tiempo"
|
AdvSceneSwitcher.condition.date.ignoreTime="Si no se marca, se ignorará el componente de tiempo"
|
||||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Mostrar configuración avanzada"
|
AdvSceneSwitcher.condition.date.showAdvancedSettings="Mostrar configuración avanzada"
|
||||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Mostrar configuración simple"
|
AdvSceneSwitcher.condition.date.showSimpleSettings="Mostrar configuración simple"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.day="El{{dayOfWeek}}"
|
AdvSceneSwitcher.condition.date.entry.simple="El {{dayOfWeek}} {{weekCondition}} {{ignoreWeekTime}}{{weekTime}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} Repetir cada {{duration}} en la coincidencia de fechas"
|
||||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}} Repetir cada {{duration}} en la coincidencia de fechas"
|
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Próxima coincidencia en: %1"
|
||||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Próxima coincidencia en: %1"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha"
|
||||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Transformar elemento de escena"
|
AdvSceneSwitcher.condition.sceneTransform="Transformar elemento de escena"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtener transformación"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtener transformación"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.condition.match="coincide con la transformación"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="coincide con la transformación"
|
||||||
@@ -308,12 +311,13 @@ AdvSceneSwitcher.condition.stats.entry="{{stats}} esta {{condition}} {{value}}"
|
|||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.scene="Cambiar escena"
|
AdvSceneSwitcher.action.scene="Cambiar escena"
|
||||||
|
AdvSceneSwitcher.action.scene.entry="Cambiar a la{{sceneTypes}}escena{{scenes}}usando{{transitions}}con una duración de{{duration}} segundos"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Espere hasta que se complete la transición a la escena de destino"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Espere hasta que se complete la transición a la escena de destino"
|
||||||
AdvSceneSwitcher.action.wait="Esperar"
|
AdvSceneSwitcher.action.wait="Esperar"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="fijo"
|
AdvSceneSwitcher.action.wait.type.fixed="fijo"
|
||||||
AdvSceneSwitcher.action.wait.type.random="aleatorio"
|
AdvSceneSwitcher.action.wait.type.random="aleatorio"
|
||||||
AdvSceneSwitcher.action.wait.layout.fixed="Espere {{waitType}} de {{duration}}"
|
AdvSceneSwitcher.action.wait.entry.fixed="Espere {{waitType}} de {{duration}}"
|
||||||
AdvSceneSwitcher.action.wait.layout.random="Espere {{waitType}} de {{duration}} a {{duration2}}"
|
AdvSceneSwitcher.action.wait.entry.random="Espere {{waitType}} de {{duration}} a {{duration2}}"
|
||||||
AdvSceneSwitcher.action.audio="Audio"
|
AdvSceneSwitcher.action.audio="Audio"
|
||||||
AdvSceneSwitcher.action.audio.type.mute="Silencio"
|
AdvSceneSwitcher.action.audio.type.mute="Silencio"
|
||||||
AdvSceneSwitcher.action.audio.type.unmute="Activar silencio"
|
AdvSceneSwitcher.action.audio.type.unmute="Activar silencio"
|
||||||
@@ -331,6 +335,7 @@ AdvSceneSwitcher.action.recording.type.start="Iniciar grabación"
|
|||||||
AdvSceneSwitcher.action.recording.type.pause="Pausar grabación"
|
AdvSceneSwitcher.action.recording.type.pause="Pausar grabación"
|
||||||
AdvSceneSwitcher.action.recording.type.unpause="Reanudar grabación"
|
AdvSceneSwitcher.action.recording.type.unpause="Reanudar grabación"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Tenga en cuenta que, dependiendo de la configuración de grabación, es posible que no pueda pausar la grabación"
|
AdvSceneSwitcher.action.recording.pause.hint="Tenga en cuenta que, dependiendo de la configuración de grabación, es posible que no pueda pausar la grabación"
|
||||||
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Búfer de reproducción"
|
AdvSceneSwitcher.action.replay="Búfer de reproducción"
|
||||||
AdvSceneSwitcher.action.replay.saveWarn="Advertencia: ¡Guardar con demasiada frecuencia puede hacer que el búfer de reproducción no se guarde realmente!"
|
AdvSceneSwitcher.action.replay.saveWarn="Advertencia: ¡Guardar con demasiada frecuencia puede hacer que el búfer de reproducción no se guarde realmente!"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
|
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
|
||||||
@@ -339,13 +344,14 @@ AdvSceneSwitcher.action.replay.type.save="Guardar búfer de reproducción"
|
|||||||
AdvSceneSwitcher.action.streaming="Transmisión"
|
AdvSceneSwitcher.action.streaming="Transmisión"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Detener transmisión"
|
AdvSceneSwitcher.action.streaming.type.stop="Detener transmisión"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión"
|
AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión"
|
||||||
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Ejecutar"
|
AdvSceneSwitcher.action.run="Ejecutar"
|
||||||
AdvSceneSwitcher.action.sceneVisibility="Visibilidad del elemento de escena"
|
AdvSceneSwitcher.action.sceneVisibility="Visibilidad del elemento de escena"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Mostrar"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Mostrar"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Fuente"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Fuente"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Cualquiera"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Cualquiera"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.layout="En{{scenes}}{{actions}}{{sources}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="En{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filtro"
|
AdvSceneSwitcher.action.filter="Filtro"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Deshabilitar"
|
AdvSceneSwitcher.action.filter.type.disable="Deshabilitar"
|
||||||
@@ -370,14 +376,14 @@ AdvSceneSwitcher.action.macro="Macro"
|
|||||||
AdvSceneSwitcher.action.macro.type.pause="Pausa"
|
AdvSceneSwitcher.action.macro.type.pause="Pausa"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Reanudar"
|
AdvSceneSwitcher.action.macro.type.unpause="Reanudar"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
|
||||||
AdvSceneSwitcher.action.macro.type.runActions="Ejecutar"
|
AdvSceneSwitcher.action.macro.type.run="Ejecutar"
|
||||||
AdvSceneSwitcher.action.macro.type.stop="Detener"
|
AdvSceneSwitcher.action.macro.type.stop="Detener"
|
||||||
AdvSceneSwitcher.action.pluginState="Estado del complemento"
|
AdvSceneSwitcher.action.pluginState="Estado del complemento"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Detener el complemento Advanced Scene Switcher"
|
AdvSceneSwitcher.action.pluginState.type.stop="Detener el complemento Advanced Scene Switcher"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Cambiar el comportamiento de no coincidencia:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Cambiar el comportamiento de no coincidencia:"
|
||||||
AdvSceneSwitcher.action.pluginState.type.import="Importar configuración desde"
|
AdvSceneSwitcher.action.pluginState.type.import="Importar configuración desde"
|
||||||
AdvSceneSwitcher.action.pluginState.importWarning="Nota: la acción se ignorará mientras se abra la ventana de configuración."
|
AdvSceneSwitcher.action.pluginState.importWarning="Nota: la acción se ignorará mientras se abra la ventana de configuración."
|
||||||
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}"
|
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}{{settingsWarning}}"
|
||||||
AdvSceneSwitcher.action.virtualCamera="Cámara virtual"
|
AdvSceneSwitcher.action.virtualCamera="Cámara virtual"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.stop="Detener cámara virtual"
|
AdvSceneSwitcher.action.virtualCamera.type.stop="Detener cámara virtual"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.start="Iniciar cámara virtual"
|
AdvSceneSwitcher.action.virtualCamera.type.start="Iniciar cámara virtual"
|
||||||
@@ -418,9 +424,9 @@ AdvSceneSwitcher.action.transition.type.scene="transición de escena"
|
|||||||
AdvSceneSwitcher.action.transition.type.sceneOverride="anulación de transición de escena"
|
AdvSceneSwitcher.action.transition.type.sceneOverride="anulación de transición de escena"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceShow="transición del programa de origen"
|
AdvSceneSwitcher.action.transition.type.sourceShow="transición del programa de origen"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceHide="fuente ocultar transición"
|
AdvSceneSwitcher.action.transition.type.sourceHide="fuente ocultar transición"
|
||||||
AdvSceneSwitcher.action.transition.layout.type="Modificar {{type}}{{scenes}}{{sources}}"
|
AdvSceneSwitcher.action.transition.entry.line1="Modificar {{type}}{{scenes}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.transition="{{setTransition}}Establecer el tipo de transición en {{transitions}}"
|
AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}}Establecer el tipo de transición en {{transitions}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.duration="{{setDuration}}Establecer la duración de la transición en {{duration}}segundos"
|
AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}}Establecer la duración de la transición en {{duration}}segundos"
|
||||||
AdvSceneSwitcher.action.timer="Temporizador"
|
AdvSceneSwitcher.action.timer="Temporizador"
|
||||||
AdvSceneSwitcher.action.timer.type.pause="Pausa"
|
AdvSceneSwitcher.action.timer.type.pause="Pausa"
|
||||||
AdvSceneSwitcher.action.timer.type.continue="Continuar"
|
AdvSceneSwitcher.action.timer.type.continue="Continuar"
|
||||||
@@ -675,6 +681,8 @@ AdvSceneSwitcher.status.inactive="Inactivo"
|
|||||||
AdvSceneSwitcher.running="Iniciar complemento"
|
AdvSceneSwitcher.running="Iniciar complemento"
|
||||||
AdvSceneSwitcher.stopped="Complemento de detención"
|
AdvSceneSwitcher.stopped="Complemento de detención"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>Esta parece ser la primera vez que se inicia el conmutador de escena avanzado.<br>Por favor, eche un vistazo a <a href=\"https:/ /github.com/WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> para obtener una lista de guías y ejemplos.<br>No dude en hacer preguntas en el complemento <a href=\"https://obsproject.com /forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:#268bd2;\">hilo</span></a> en los foros de OBS!</p></body></html>"
|
||||||
|
|
||||||
AdvSceneSwitcher.deprecatedTabWarning="¡Se detuvo el desarrollo de esta pestaña!\nConsidere cambiar a macros en su lugar.\nEsta sugerencia se puede desactivar en la pestaña General".
|
AdvSceneSwitcher.deprecatedTabWarning="¡Se detuvo el desarrollo de esta pestaña!\nConsidere cambiar a macros en su lugar.\nEsta sugerencia se puede desactivar en la pestaña General".
|
||||||
|
|
||||||
AdvSceneSwitcher.unit.milliseconds="milisegundos"
|
AdvSceneSwitcher.unit.milliseconds="milisegundos"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ AdvSceneSwitcher.generalTab.status.onStartup.alwaysStart="Toujours démarrer le
|
|||||||
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Ne pas démarrer le sélecteur de scène"
|
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Ne pas démarrer le sélecteur de scène"
|
||||||
AdvSceneSwitcher.generalTab.status.start="Démarrer"
|
AdvSceneSwitcher.generalTab.status.start="Démarrer"
|
||||||
AdvSceneSwitcher.generalTab.status.stop="Arrêter"
|
AdvSceneSwitcher.generalTab.status.stop="Arrêter"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.startup="Démarrer automatiquement le sélecteur de scène lorsque :"
|
AdvSceneSwitcher.generalTab.status.autoStart="Démarrer automatiquement le sélecteur de scène lorsque :"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.never="Jamais"
|
AdvSceneSwitcher.generalTab.status.autoStart.never="Jamais"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.recording="Enregistrement"
|
AdvSceneSwitcher.generalTab.status.autoStart.recording="Enregistrement"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Diffusion en continu"
|
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Diffusion en continu"
|
||||||
@@ -78,6 +78,7 @@ AdvSceneSwitcher.macroTab.add="Ajouter une nouvelle macro"
|
|||||||
AdvSceneSwitcher.macroTab.name="Nom :"
|
AdvSceneSwitcher.macroTab.name="Nom :"
|
||||||
AdvSceneSwitcher.macroTab.run="Exécuter la macro"
|
AdvSceneSwitcher.macroTab.run="Exécuter la macro"
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Exécuter la macro en parallèle avec d'autres macros"
|
AdvSceneSwitcher.macroTab.runInParallel="Exécuter la macro en parallèle avec d'autres macros"
|
||||||
|
AdvSceneSwitcher.macroTab.onChange="Exécuter des actions uniquement en cas de changement de condition"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.defaultGroupName="Groupe %1"
|
AdvSceneSwitcher.macroTab.defaultGroupName="Groupe %1"
|
||||||
AdvSceneSwitcher.macroTab.removeSingleMacroPopup.text="Êtes-vous sûr de vouloir supprimer \"%1\" ?"
|
AdvSceneSwitcher.macroTab.removeSingleMacroPopup.text="Êtes-vous sûr de vouloir supprimer \"%1\" ?"
|
||||||
@@ -131,6 +132,7 @@ AdvSceneSwitcher.macroList.deleted="supprimé"
|
|||||||
AdvSceneSwitcher.macroList.duplicate="\"%1\" est déjà sélectionné !"
|
AdvSceneSwitcher.macroList.duplicate="\"%1\" est déjà sélectionné !"
|
||||||
|
|
||||||
; Macro Logic
|
; Macro Logic
|
||||||
|
AdvSceneSwitcher.logic.none="Ignorer l'entrée"
|
||||||
AdvSceneSwitcher.logic.and="Et"
|
AdvSceneSwitcher.logic.and="Et"
|
||||||
AdvSceneSwitcher.logic.or="Ou"
|
AdvSceneSwitcher.logic.or="Ou"
|
||||||
AdvSceneSwitcher.logic.andNot="Et pas"
|
AdvSceneSwitcher.logic.andNot="Et pas"
|
||||||
@@ -186,6 +188,8 @@ AdvSceneSwitcher.condition.file="Fichier"
|
|||||||
AdvSceneSwitcher.condition.file.type.match="correspond à"
|
AdvSceneSwitcher.condition.file.type.match="correspond à"
|
||||||
AdvSceneSwitcher.condition.file.type.contentChange="a changé de contenu"
|
AdvSceneSwitcher.condition.file.type.contentChange="a changé de contenu"
|
||||||
AdvSceneSwitcher.condition.file.type.dateChange="a changé de date de modification"
|
AdvSceneSwitcher.condition.file.type.dateChange="a changé de date de modification"
|
||||||
|
AdvSceneSwitcher.condition.file.remote="Fichier distant"
|
||||||
|
AdvSceneSwitcher.condition.file.local="Fichier local"
|
||||||
AdvSceneSwitcher.condition.media="Média"
|
AdvSceneSwitcher.condition.media="Média"
|
||||||
AdvSceneSwitcher.condition.media.source="Source"
|
AdvSceneSwitcher.condition.media.source="Source"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Toute source média sur la scène"
|
AdvSceneSwitcher.condition.media.anyOnScene="Toute source média sur la scène"
|
||||||
@@ -257,10 +261,10 @@ AdvSceneSwitcher.condition.video.layout.modelPath="Données du modèle (classifi
|
|||||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Nombre minimum de voisins :{{minNeighbors}}"
|
AdvSceneSwitcher.condition.video.layout.minNeighbor="Nombre minimum de voisins :{{minNeighbors}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Réduire la charge CPU en effectuant la vérification uniquement toutes les{{throttleCount}}millisecondes"
|
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Réduire la charge CPU en effectuant la vérification uniquement toutes les{{throttleCount}}millisecondes"
|
||||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Effectuer la vérification uniquement dans la zone"
|
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Effectuer la vérification uniquement dans la zone"
|
||||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Vérifier la couleur du texte :{{color}}"
|
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Vérifier la couleur du texte :{{textColor}}{{selectColor}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Vérifier le type de texte :{{textType}}"
|
AdvSceneSwitcher.condition.video.layout.ocrTextType="Vérifier le type de texte :{{textType}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Vérifier la langue :{{languageCode}}"
|
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Vérifier la langue :{{languageCode}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.color="Vérifier la couleur :{{color}}"
|
AdvSceneSwitcher.condition.video.layout.color="Vérifier la couleur :{{color}}{{selectColor}}"
|
||||||
AdvSceneSwitcher.condition.video.minSize="Taille minimale :"
|
AdvSceneSwitcher.condition.video.minSize="Taille minimale :"
|
||||||
AdvSceneSwitcher.condition.video.maxSize="Taille maximale :"
|
AdvSceneSwitcher.condition.video.maxSize="Taille maximale :"
|
||||||
AdvSceneSwitcher.condition.video.selectArea="Sélectionner la zone"
|
AdvSceneSwitcher.condition.video.selectArea="Sélectionner la zone"
|
||||||
@@ -278,8 +282,8 @@ AdvSceneSwitcher.condition.record.state.start="Enregistrement en cours"
|
|||||||
AdvSceneSwitcher.condition.record.state.pause="Enregistrement en pause"
|
AdvSceneSwitcher.condition.record.state.pause="Enregistrement en pause"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Arrêt de l'enregistrement"
|
AdvSceneSwitcher.condition.record.state.stop="Arrêt de l'enregistrement"
|
||||||
AdvSceneSwitcher.condition.process="Processus"
|
AdvSceneSwitcher.condition.process="Processus"
|
||||||
AdvSceneSwitcher.condition.process.layout="{{processes}}{{regex}}en cours d'exécution{{focused}}et est au premier plan"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}en cours d'exécution{{focused}}et est au premier plan"
|
||||||
AdvSceneSwitcher.condition.process.layout.focus="Processus au premier plan actuel :{{focusProcess}}"
|
AdvSceneSwitcher.condition.process.entry.focus="Processus au premier plan actuel :{{focusProcess}}"
|
||||||
AdvSceneSwitcher.condition.idle="Inactif"
|
AdvSceneSwitcher.condition.idle="Inactif"
|
||||||
AdvSceneSwitcher.condition.idle.entry="Aucune entrée de clavier ou de souris pendant{{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="Aucune entrée de clavier ou de souris pendant{{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="État du plugin"
|
AdvSceneSwitcher.condition.pluginState="État du plugin"
|
||||||
@@ -352,14 +356,14 @@ AdvSceneSwitcher.condition.replay.state.stopped="Tampon de répétition arrêté
|
|||||||
AdvSceneSwitcher.condition.replay.state.started="Tampon de répétition démarré"
|
AdvSceneSwitcher.condition.replay.state.started="Tampon de répétition démarré"
|
||||||
AdvSceneSwitcher.condition.replay.state.saved="Tampon de répétition enregistré"
|
AdvSceneSwitcher.condition.replay.state.saved="Tampon de répétition enregistré"
|
||||||
AdvSceneSwitcher.condition.date="Date"
|
AdvSceneSwitcher.condition.date="Date"
|
||||||
AdvSceneSwitcher.day.any="N'importe quel jour"
|
AdvSceneSwitcher.condition.date.anyDay="N'importe quel jour"
|
||||||
AdvSceneSwitcher.day.monday="Lundi"
|
AdvSceneSwitcher.condition.date.monday="Lundi"
|
||||||
AdvSceneSwitcher.day.tuesday="Mardi"
|
AdvSceneSwitcher.condition.date.tuesday="Mardi"
|
||||||
AdvSceneSwitcher.day.wednesday="Mercredi"
|
AdvSceneSwitcher.condition.date.wednesday="Mercredi"
|
||||||
AdvSceneSwitcher.day.thursday="Jeudi"
|
AdvSceneSwitcher.condition.date.thursday="Jeudi"
|
||||||
AdvSceneSwitcher.day.friday="Vendredi"
|
AdvSceneSwitcher.condition.date.friday="Vendredi"
|
||||||
AdvSceneSwitcher.day.saturday="Samedi"
|
AdvSceneSwitcher.condition.date.saturday="Samedi"
|
||||||
AdvSceneSwitcher.day.sunday="Dimanche"
|
AdvSceneSwitcher.condition.date.sunday="Dimanche"
|
||||||
AdvSceneSwitcher.condition.date.state.at="À"
|
AdvSceneSwitcher.condition.date.state.at="À"
|
||||||
AdvSceneSwitcher.condition.date.state.after="Après"
|
AdvSceneSwitcher.condition.date.state.after="Après"
|
||||||
AdvSceneSwitcher.condition.date.state.before="Avant"
|
AdvSceneSwitcher.condition.date.state.before="Avant"
|
||||||
@@ -370,12 +374,11 @@ AdvSceneSwitcher.condition.date.ignoreDate="Si non cochée, la composante date s
|
|||||||
AdvSceneSwitcher.condition.date.ignoreTime="Si non cochée, la composante heure sera ignorée"
|
AdvSceneSwitcher.condition.date.ignoreTime="Si non cochée, la composante heure sera ignorée"
|
||||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Afficher les paramètres avancés"
|
AdvSceneSwitcher.condition.date.showAdvancedSettings="Afficher les paramètres avancés"
|
||||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Afficher les paramètres simples"
|
AdvSceneSwitcher.condition.date.showSimpleSettings="Afficher les paramètres simples"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.day="Le{{dayOfWeek}}"
|
AdvSceneSwitcher.condition.date.entry.simple="Le{{dayOfWeek}}{{weekCondition}}{{ignoreWeekTime}}{{weekTime}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}}Répéter toutes les{{duration}}lorsque la date correspond"
|
||||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}}Répéter toutes les{{duration}}lorsque la date correspond"
|
AdvSceneSwitcher.condition.date.entry.pattern="La date actuelle \"{{currentDate}}\" correspond au motif{{pattern}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.pattern="La date actuelle \"{{currentDate}}\" correspond au motif{{pattern}}"
|
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Prochaine correspondance à : %1"
|
||||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Prochaine correspondance à : %1"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}À la répétition, mettre à jour la date sélectionnée pour la date de répétition"
|
||||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}}À la répétition, mettre à jour la date sélectionnée pour la date de répétition"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Transformation de l'élément de la scène"
|
AdvSceneSwitcher.condition.sceneTransform="Transformation de l'élément de la scène"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtenir la transformation"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtenir la transformation"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.condition.match="correspond à la transformation"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="correspond à la transformation"
|
||||||
@@ -456,12 +459,14 @@ AdvSceneSwitcher.condition.slideshow.updateInterval.tooltip="Les informations su
|
|||||||
AdvSceneSwitcher.action.scene="Changer de scène"
|
AdvSceneSwitcher.action.scene="Changer de scène"
|
||||||
AdvSceneSwitcher.action.scene.type.program="Programme"
|
AdvSceneSwitcher.action.scene.type.program="Programme"
|
||||||
AdvSceneSwitcher.action.scene.type.preview="Aperçu"
|
AdvSceneSwitcher.action.scene.type.preview="Aperçu"
|
||||||
|
AdvSceneSwitcher.action.scene.entry="Changer la scène{{sceneTypes}}{{scenes}}en utilisant{{transitions}}avec une durée de{{duration}}secondes"
|
||||||
|
AdvSceneSwitcher.action.scene.entry.noDuration="Changer la scène{{sceneTypes}}{{scenes}}en utilisant{{transitions}}"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Attendre que la transition vers la scène cible soit terminée"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Attendre que la transition vers la scène cible soit terminée"
|
||||||
AdvSceneSwitcher.action.wait="Attendre"
|
AdvSceneSwitcher.action.wait="Attendre"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="fixe"
|
AdvSceneSwitcher.action.wait.type.fixed="fixe"
|
||||||
AdvSceneSwitcher.action.wait.type.random="aléatoire"
|
AdvSceneSwitcher.action.wait.type.random="aléatoire"
|
||||||
AdvSceneSwitcher.action.wait.layout.fixed="Attendre pour{{waitType}}une durée de{{duration}}"
|
AdvSceneSwitcher.action.wait.entry.fixed="Attendre pour{{waitType}}une durée de{{duration}}"
|
||||||
AdvSceneSwitcher.action.wait.layout.random="Attendre pour{{waitType}}une durée de{{duration}}à{{duration2}}"
|
AdvSceneSwitcher.action.wait.entry.random="Attendre pour{{waitType}}une durée de{{duration}}à{{duration2}}"
|
||||||
AdvSceneSwitcher.action.audio="Audio"
|
AdvSceneSwitcher.action.audio="Audio"
|
||||||
AdvSceneSwitcher.action.audio.type.mute="Muet"
|
AdvSceneSwitcher.action.audio.type.mute="Muet"
|
||||||
AdvSceneSwitcher.action.audio.type.unmute="Activer le son"
|
AdvSceneSwitcher.action.audio.type.unmute="Activer le son"
|
||||||
@@ -507,7 +512,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="Masquer"
|
|||||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Basculer"
|
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Basculer"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Source"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Source"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="N'importe"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="N'importe"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.layout="Sur{{scenes}}{{actions}}{{sources}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="Sur{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filtre"
|
AdvSceneSwitcher.action.filter="Filtre"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Activer"
|
AdvSceneSwitcher.action.filter.type.enable="Activer"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Désactiver"
|
AdvSceneSwitcher.action.filter.type.disable="Désactiver"
|
||||||
@@ -550,7 +555,7 @@ AdvSceneSwitcher.action.macro="Macro"
|
|||||||
AdvSceneSwitcher.action.macro.type.pause="Pause"
|
AdvSceneSwitcher.action.macro.type.pause="Pause"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Reprendre"
|
AdvSceneSwitcher.action.macro.type.unpause="Reprendre"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Réinitialiser le compteur"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Réinitialiser le compteur"
|
||||||
AdvSceneSwitcher.action.macro.type.runActions="Exécuter les actions"
|
AdvSceneSwitcher.action.macro.type.run="Exécuter les actions"
|
||||||
AdvSceneSwitcher.action.macro.type.stop="Arrêter les actions"
|
AdvSceneSwitcher.action.macro.type.stop="Arrêter les actions"
|
||||||
AdvSceneSwitcher.action.macro.type.disableAction="Désactiver l'action"
|
AdvSceneSwitcher.action.macro.type.disableAction="Désactiver l'action"
|
||||||
AdvSceneSwitcher.action.macro.type.enableAction="Activer l'action"
|
AdvSceneSwitcher.action.macro.type.enableAction="Activer l'action"
|
||||||
@@ -619,9 +624,9 @@ AdvSceneSwitcher.action.transition.type.scene="Transition de scène"
|
|||||||
AdvSceneSwitcher.action.transition.type.sceneOverride="Remplacement de la transition de scène"
|
AdvSceneSwitcher.action.transition.type.sceneOverride="Remplacement de la transition de scène"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceShow="Transition d'affichage de la source"
|
AdvSceneSwitcher.action.transition.type.sourceShow="Transition d'affichage de la source"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceHide="Transition de masquage de la source"
|
AdvSceneSwitcher.action.transition.type.sourceHide="Transition de masquage de la source"
|
||||||
AdvSceneSwitcher.action.transition.layout.type="Modifier{{type}}{{scenes}}{{sources}}"
|
AdvSceneSwitcher.action.transition.entry.line1="Modifier{{type}}{{scenes}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.transition="{{setTransition}}Définir le type de transition sur{{transitions}}"
|
AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}}Définir le type de transition sur{{transitions}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.duration="{{setDuration}}Définir la durée de la transition à{{duration}}secondes"
|
AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}}Définir la durée de la transition à{{duration}}secondes"
|
||||||
AdvSceneSwitcher.action.timer="Minuterie"
|
AdvSceneSwitcher.action.timer="Minuterie"
|
||||||
AdvSceneSwitcher.action.timer.type.pause="Mettre en pause"
|
AdvSceneSwitcher.action.timer.type.pause="Mettre en pause"
|
||||||
AdvSceneSwitcher.action.timer.type.continue="Continuer"
|
AdvSceneSwitcher.action.timer.type.continue="Continuer"
|
||||||
@@ -698,8 +703,8 @@ AdvSceneSwitcher.action.variable.invalidSelection="Sélection invalide !"
|
|||||||
AdvSceneSwitcher.action.variable.actionNoVariableSupport="La récupération de valeurs de variables à partir d'actions %1 n'est pas prise en charge !"
|
AdvSceneSwitcher.action.variable.actionNoVariableSupport="La récupération de valeurs de variables à partir d'actions %1 n'est pas prise en charge !"
|
||||||
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="La récupération de valeurs de variables à partir de conditions %1 n'est pas prise en charge !"
|
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="La récupération de valeurs de variables à partir de conditions %1 n'est pas prise en charge !"
|
||||||
AdvSceneSwitcher.action.variable.currentSegmentValue="Valeur actuelle :"
|
AdvSceneSwitcher.action.variable.currentSegmentValue="Valeur actuelle :"
|
||||||
AdvSceneSwitcher.action.variable.layout.substringIndex="Début de la sous-chaîne :{{subStringStart}}Taille de la sous-chaîne :{{subStringSize}}{{subStringRegex}}"
|
AdvSceneSwitcher.action.variable.layout.substringIndex="Début de la sous-chaîne :{{subStringStart}}Taille de la sous-chaîne :{{subStringSize}}"
|
||||||
AdvSceneSwitcher.action.variable.layout.substringRegex="Attribuer la valeur du match{{regexMatchIdx}}en utilisant une expression régulière:{{subStringRegex}}"
|
AdvSceneSwitcher.action.variable.layout.substringRegex="Attribuer la valeur du match{{regexMatchIdx}}en utilisant une expression régulière :"
|
||||||
AdvSceneSwitcher.action.variable.layout.userInput.customPrompt="{{useCustomPrompt}}Utiliser un message personnalisé{{inputPrompt}}"
|
AdvSceneSwitcher.action.variable.layout.userInput.customPrompt="{{useCustomPrompt}}Utiliser un message personnalisé{{inputPrompt}}"
|
||||||
AdvSceneSwitcher.action.variable.layout.userInput.placeholder="{{useInputPlaceholder}}Remplir avec un indicateur de position{{inputPlaceholder}}"
|
AdvSceneSwitcher.action.variable.layout.userInput.placeholder="{{useInputPlaceholder}}Remplir avec un indicateur de position{{inputPlaceholder}}"
|
||||||
AdvSceneSwitcher.action.projector="Projecteur"
|
AdvSceneSwitcher.action.projector="Projecteur"
|
||||||
@@ -1102,15 +1107,15 @@ AdvSceneSwitcher.sceneItemSelection.configure="Configurer le type de sélection
|
|||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceName="Nom de la source"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceName="Nom de la source"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceVariable="Nom de la variable"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceVariable="Nom de la variable"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern="Le nom de la source correspond au motif"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern="Le nom de la source correspond au motif"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern.layout="{{nameConflictIndex}}correspondant à{{pattern}}{{regex}}"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern.entry="{{nameConflictIndex}}correspondant à{{pattern}}{{regex}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceType="Sources de type"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceType="Sources de type"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceType.layout="{{nameConflictIndex}}Type de source{{sourceTypes}}"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceType.entry="{{nameConflictIndex}}Type de source{{sourceTypes}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.index="Source avec index"
|
AdvSceneSwitcher.sceneItemSelection.type.index="Source avec index"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.index.layout="{{index}}source"
|
AdvSceneSwitcher.sceneItemSelection.type.index.entry="{{index}}source"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.indexRange="Sources dans la plage d'index"
|
AdvSceneSwitcher.sceneItemSelection.type.indexRange="Sources dans la plage d'index"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.indexRange.layout="Sources de{{index}}à{{indexEnd}}"
|
AdvSceneSwitcher.sceneItemSelection.type.indexRange.entry="Sources de{{index}}à{{indexEnd}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.all="Toutes les sources"
|
AdvSceneSwitcher.sceneItemSelection.type.all="Toutes les sources"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.all.layout="Toutes les sources"
|
AdvSceneSwitcher.sceneItemSelection.type.all.entry="Toutes les sources"
|
||||||
AdvSceneSwitcher.sceneItemSelection.all="Tout"
|
AdvSceneSwitcher.sceneItemSelection.all="Tout"
|
||||||
AdvSceneSwitcher.sceneItemSelection.any="N'importe lequel"
|
AdvSceneSwitcher.sceneItemSelection.any="N'importe lequel"
|
||||||
|
|
||||||
@@ -1119,6 +1124,8 @@ AdvSceneSwitcher.status.inactive="Inactif"
|
|||||||
AdvSceneSwitcher.running="Plugin en cours d'exécution"
|
AdvSceneSwitcher.running="Plugin en cours d'exécution"
|
||||||
AdvSceneSwitcher.stopped="Plugin arrêté"
|
AdvSceneSwitcher.stopped="Plugin arrêté"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>Il semble que ce soit la première fois que l'Advanced Scene Switcher est démarré.<br>Veuillez consulter le <a href=\"https://github.com/WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> pour obtenir une liste de guides et d'exemples.<br>N'hésitez pas à poser des questions dans le <a href=\"https://obsproject.com/forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:#268bd2;\">fil de discussion</span></a> du plugin sur les forums OBS !</p></body></html>"
|
||||||
|
|
||||||
AdvSceneSwitcher.deprecatedTabWarning="Le développement de cet onglet est terminé !\nVeuillez envisager de passer à l'utilisation des Macros à la place.\nCette astuce peut être désactivée dans l'onglet Général."
|
AdvSceneSwitcher.deprecatedTabWarning="Le développement de cet onglet est terminé !\nVeuillez envisager de passer à l'utilisation des Macros à la place.\nCette astuce peut être désactivée dans l'onglet Général."
|
||||||
|
|
||||||
AdvSceneSwitcher.unit.milliseconds="millisecondes"
|
AdvSceneSwitcher.unit.milliseconds="millisecondes"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ AdvSceneSwitcher.generalTab.status.onStartup.alwaysStart="Sempre iniciar o switc
|
|||||||
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Não iniciar o switcher de cenas"
|
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Não iniciar o switcher de cenas"
|
||||||
AdvSceneSwitcher.generalTab.status.start="Iniciar"
|
AdvSceneSwitcher.generalTab.status.start="Iniciar"
|
||||||
AdvSceneSwitcher.generalTab.status.stop="Parar"
|
AdvSceneSwitcher.generalTab.status.stop="Parar"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.startup="Iniciar automaticamente o switcher de cenas quando:"
|
AdvSceneSwitcher.generalTab.status.autoStart="Iniciar automaticamente o switcher de cenas quando:"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.never="Nunca"
|
AdvSceneSwitcher.generalTab.status.autoStart.never="Nunca"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.recording="Gravando"
|
AdvSceneSwitcher.generalTab.status.autoStart.recording="Gravando"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Transmitindo"
|
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Transmitindo"
|
||||||
@@ -147,6 +147,7 @@ AdvSceneSwitcher.macroTab.run.tooltip="Execute todas as ações da macro indepen
|
|||||||
AdvSceneSwitcher.macroTab.runElse="Executar macro (alternativa)"
|
AdvSceneSwitcher.macroTab.runElse="Executar macro (alternativa)"
|
||||||
AdvSceneSwitcher.macroTab.runFail="Falha ao executar \"%1\"!\nUma das ações falhou ou a macro já está em execução.\nDeseja interrompê-la?"
|
AdvSceneSwitcher.macroTab.runFail="Falha ao executar \"%1\"!\nUma das ações falhou ou a macro já está em execução.\nDeseja interrompê-la?"
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Executar macro em paralelo com outras macros"
|
AdvSceneSwitcher.macroTab.runInParallel="Executar macro em paralelo com outras macros"
|
||||||
|
AdvSceneSwitcher.macroTab.onChange="Executar ações apenas quando houver mudança na condição"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.defaultGroupName="Grupo %1"
|
AdvSceneSwitcher.macroTab.defaultGroupName="Grupo %1"
|
||||||
AdvSceneSwitcher.macroTab.macroNameExists="O nome \"%1\" já está em uso por uma macro."
|
AdvSceneSwitcher.macroTab.macroNameExists="O nome \"%1\" já está em uso por uma macro."
|
||||||
@@ -239,6 +240,7 @@ AdvSceneSwitcher.macroList.deleted="excluída"
|
|||||||
AdvSceneSwitcher.macroList.duplicate="\"%1\" já está selecionada!"
|
AdvSceneSwitcher.macroList.duplicate="\"%1\" já está selecionada!"
|
||||||
|
|
||||||
; Macro Logic
|
; Macro Logic
|
||||||
|
AdvSceneSwitcher.logic.none="Ignorar entrada"
|
||||||
AdvSceneSwitcher.logic.and="E"
|
AdvSceneSwitcher.logic.and="E"
|
||||||
AdvSceneSwitcher.logic.or="Ou"
|
AdvSceneSwitcher.logic.or="Ou"
|
||||||
AdvSceneSwitcher.logic.andNot="E não"
|
AdvSceneSwitcher.logic.andNot="E não"
|
||||||
@@ -294,6 +296,11 @@ AdvSceneSwitcher.condition.file="Arquivo"
|
|||||||
AdvSceneSwitcher.condition.file.type.match="corresponde"
|
AdvSceneSwitcher.condition.file.type.match="corresponde"
|
||||||
AdvSceneSwitcher.condition.file.type.contentChange="conteúdo mudou"
|
AdvSceneSwitcher.condition.file.type.contentChange="conteúdo mudou"
|
||||||
AdvSceneSwitcher.condition.file.type.dateChange="data de modificação mudou"
|
AdvSceneSwitcher.condition.file.type.dateChange="data de modificação mudou"
|
||||||
|
AdvSceneSwitcher.condition.file.remote="Arquivo remoto"
|
||||||
|
AdvSceneSwitcher.condition.file.local="Arquivo local"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Mídia"
|
AdvSceneSwitcher.condition.media="Mídia"
|
||||||
AdvSceneSwitcher.condition.media.checkType.state="Estado corresponde"
|
AdvSceneSwitcher.condition.media.checkType.state="Estado corresponde"
|
||||||
AdvSceneSwitcher.condition.media.checkType.time="Restrição de tempo corresponde"
|
AdvSceneSwitcher.condition.media.checkType.time="Restrição de tempo corresponde"
|
||||||
@@ -371,10 +378,10 @@ AdvSceneSwitcher.condition.video.layout.minNeighbor="Vizinhos mínimos:{{minNeig
|
|||||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzir carga de CPU realizando a verificação apenas a cada {{throttleCount}} milissegundos"
|
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzir carga de CPU realizando a verificação apenas a cada {{throttleCount}} milissegundos"
|
||||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Realizar verificação apenas na área"
|
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Realizar verificação apenas na área"
|
||||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Verificar cor do texto:{{color}}"
|
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Verificar cor do texto:{{textColor}}{{selectColor}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Verificar tipo de texto:{{textType}}"
|
AdvSceneSwitcher.condition.video.layout.ocrTextType="Verificar tipo de texto:{{textType}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Verificar idioma:{{languageCode}}"
|
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Verificar idioma:{{languageCode}}"
|
||||||
AdvSceneSwitcher.condition.video.layout.color="Verificar cor:{{color}}"
|
AdvSceneSwitcher.condition.video.layout.color="Verificar cor:{{color}}{{selectColor}}"
|
||||||
AdvSceneSwitcher.condition.video.minSize="Tamanho mínimo:"
|
AdvSceneSwitcher.condition.video.minSize="Tamanho mínimo:"
|
||||||
AdvSceneSwitcher.condition.video.maxSize="Tamanho máximo:"
|
AdvSceneSwitcher.condition.video.maxSize="Tamanho máximo:"
|
||||||
AdvSceneSwitcher.condition.video.selectArea="Selecionar área"
|
AdvSceneSwitcher.condition.video.selectArea="Selecionar área"
|
||||||
@@ -394,8 +401,8 @@ AdvSceneSwitcher.condition.record.state.stop="Gravação parada"
|
|||||||
AdvSceneSwitcher.condition.record.state.duration="Duração da gravação é maior que"
|
AdvSceneSwitcher.condition.record.state.duration="Duração da gravação é maior que"
|
||||||
AdvSceneSwitcher.condition.record.entry="{{condition}}{{duration}}"
|
AdvSceneSwitcher.condition.record.entry="{{condition}}{{duration}}"
|
||||||
AdvSceneSwitcher.condition.process="Processo"
|
AdvSceneSwitcher.condition.process="Processo"
|
||||||
AdvSceneSwitcher.condition.process.layout="{{processes}}{{regex}}está em execução{{focused}}e está em foco"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}está em execução{{focused}}e está em foco"
|
||||||
AdvSceneSwitcher.condition.process.layout.focus="Processo atual em primeiro plano:{{focusProcess}}"
|
AdvSceneSwitcher.condition.process.entry.focus="Processo atual em primeiro plano:{{focusProcess}}"
|
||||||
AdvSceneSwitcher.condition.idle="Inativo"
|
AdvSceneSwitcher.condition.idle="Inativo"
|
||||||
AdvSceneSwitcher.condition.idle.entry="Sem entradas de teclado ou mouse por {{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="Sem entradas de teclado ou mouse por {{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Estado do plugin"
|
AdvSceneSwitcher.condition.pluginState="Estado do plugin"
|
||||||
@@ -495,14 +502,14 @@ AdvSceneSwitcher.condition.replay.state.started="Buffer de replay iniciado"
|
|||||||
AdvSceneSwitcher.condition.replay.state.saved="Buffer de replay salvo"
|
AdvSceneSwitcher.condition.replay.state.saved="Buffer de replay salvo"
|
||||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||||
AdvSceneSwitcher.condition.date="Data"
|
AdvSceneSwitcher.condition.date="Data"
|
||||||
AdvSceneSwitcher.day.any="Qualquer dia"
|
AdvSceneSwitcher.condition.date.anyDay="Qualquer dia"
|
||||||
AdvSceneSwitcher.day.monday="Segunda-feira"
|
AdvSceneSwitcher.condition.date.monday="Segunda-feira"
|
||||||
AdvSceneSwitcher.day.tuesday="Terça-feira"
|
AdvSceneSwitcher.condition.date.tuesday="Terça-feira"
|
||||||
AdvSceneSwitcher.day.wednesday="Quarta-feira"
|
AdvSceneSwitcher.condition.date.wednesday="Quarta-feira"
|
||||||
AdvSceneSwitcher.day.thursday="Quinta-feira"
|
AdvSceneSwitcher.condition.date.thursday="Quinta-feira"
|
||||||
AdvSceneSwitcher.day.friday="Sexta-feira"
|
AdvSceneSwitcher.condition.date.friday="Sexta-feira"
|
||||||
AdvSceneSwitcher.day.saturday="Sábado"
|
AdvSceneSwitcher.condition.date.saturday="Sábado"
|
||||||
AdvSceneSwitcher.day.sunday="Domingo"
|
AdvSceneSwitcher.condition.date.sunday="Domingo"
|
||||||
AdvSceneSwitcher.condition.date.state.at="Às"
|
AdvSceneSwitcher.condition.date.state.at="Às"
|
||||||
AdvSceneSwitcher.condition.date.state.after="Após"
|
AdvSceneSwitcher.condition.date.state.after="Após"
|
||||||
AdvSceneSwitcher.condition.date.state.before="Antes"
|
AdvSceneSwitcher.condition.date.state.before="Antes"
|
||||||
@@ -513,13 +520,12 @@ AdvSceneSwitcher.condition.date.ignoreDate="Se desmarcado, o componente de data
|
|||||||
AdvSceneSwitcher.condition.date.ignoreTime="Se desmarcado, o componente de tempo será ignorado"
|
AdvSceneSwitcher.condition.date.ignoreTime="Se desmarcado, o componente de tempo será ignorado"
|
||||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Mostrar configurações avançadas"
|
AdvSceneSwitcher.condition.date.showAdvancedSettings="Mostrar configurações avançadas"
|
||||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Mostrar configurações simples"
|
AdvSceneSwitcher.condition.date.showSimpleSettings="Mostrar configurações simples"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.day="Em{{dayOfWeek}}"
|
AdvSceneSwitcher.condition.date.entry.simple="Em{{dayOfWeek}}{{weekCondition}}{{ignoreWeekTime}}{{weekTime}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}}Repetir a cada{{duration}}em correspondência de data"
|
||||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}}Repetir a cada{{duration}}em correspondência de data"
|
AdvSceneSwitcher.condition.date.entry.pattern="Data atual \"{{currentDate}}\" corresponde ao padrão{{pattern}}"
|
||||||
AdvSceneSwitcher.condition.date.layout.pattern="Data atual \"{{currentDate}}\" corresponde ao padrão{{pattern}}"
|
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Próxima correspondência em: %1"
|
||||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Próxima correspondência em: %1"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}Ao repetir, atualize a data selecionada para a data de repetição"
|
||||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}}Ao repetir, atualize a data selecionada para a data de repetição"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Transformação do item de cena"
|
AdvSceneSwitcher.condition.sceneTransform="Transformação do item de cena"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obter transformação"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obter transformação"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getCurrentValue="Obter valor atual"
|
AdvSceneSwitcher.condition.sceneTransform.getCurrentValue="Obter valor atual"
|
||||||
@@ -714,12 +720,15 @@ AdvSceneSwitcher.condition.noDevicesFoundWarning="Nenhum dispositivo USB detecta
|
|||||||
AdvSceneSwitcher.action.scene="Trocar cena"
|
AdvSceneSwitcher.action.scene="Trocar cena"
|
||||||
AdvSceneSwitcher.action.scene.type.program="Programa"
|
AdvSceneSwitcher.action.scene.type.program="Programa"
|
||||||
AdvSceneSwitcher.action.scene.type.preview="Pré-visualização"
|
AdvSceneSwitcher.action.scene.type.preview="Pré-visualização"
|
||||||
|
AdvSceneSwitcher.action.scene.entry="Trocar{{sceneTypes}}cena para{{scenes}}usando{{transitions}}com duração de{{duration}}segundos"
|
||||||
|
AdvSceneSwitcher.action.scene.entry.noDuration="Trocar{{sceneTypes}}cena para{{scenes}}usando{{transitions}}"
|
||||||
|
AdvSceneSwitcher.action.scene.entry.preview="Trocar{{sceneTypes}}cena para{{scenes}}"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Aguardar até que a transição para a cena de destino seja concluída"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Aguardar até que a transição para a cena de destino seja concluída"
|
||||||
AdvSceneSwitcher.action.wait="Aguardar"
|
AdvSceneSwitcher.action.wait="Aguardar"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="fixo"
|
AdvSceneSwitcher.action.wait.type.fixed="fixo"
|
||||||
AdvSceneSwitcher.action.wait.type.random="aleatório"
|
AdvSceneSwitcher.action.wait.type.random="aleatório"
|
||||||
AdvSceneSwitcher.action.wait.layout.fixed="Aguardando por{{waitType}}duração de{{duration}}"
|
AdvSceneSwitcher.action.wait.entry.fixed="Aguardando por{{waitType}}duração de{{duration}}"
|
||||||
AdvSceneSwitcher.action.wait.layout.random="Aguardando por{{waitType}}duração de{{duration}}para{{duration2}}"
|
AdvSceneSwitcher.action.wait.entry.random="Aguardando por{{waitType}}duração de{{duration}}para{{duration2}}"
|
||||||
AdvSceneSwitcher.action.audio="Áudio"
|
AdvSceneSwitcher.action.audio="Áudio"
|
||||||
AdvSceneSwitcher.action.audio.type.mute="Silenciar"
|
AdvSceneSwitcher.action.audio.type.mute="Silenciar"
|
||||||
AdvSceneSwitcher.action.audio.type.unmute="Ativar som"
|
AdvSceneSwitcher.action.audio.type.unmute="Ativar som"
|
||||||
@@ -748,6 +757,7 @@ AdvSceneSwitcher.action.recording.type.changeOutputFolder="Alterar pasta de saí
|
|||||||
AdvSceneSwitcher.action.recording.type.changeOutputFileFormat="Alterar formatação do nome do arquivo"
|
AdvSceneSwitcher.action.recording.type.changeOutputFileFormat="Alterar formatação do nome do arquivo"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Observe que dependendo das suas configurações de gravação, você pode não conseguir pausar a gravação"
|
AdvSceneSwitcher.action.recording.pause.hint="Observe que dependendo das suas configurações de gravação, você pode não conseguir pausar a gravação"
|
||||||
AdvSceneSwitcher.action.recording.split.hint="Certifique-se de habilitar a divisão automática de arquivos nas configurações do OBS primeiro!"
|
AdvSceneSwitcher.action.recording.split.hint="Certifique-se de habilitar a divisão automática de arquivos nas configurações do OBS primeiro!"
|
||||||
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Buffer de replay"
|
AdvSceneSwitcher.action.replay="Buffer de replay"
|
||||||
AdvSceneSwitcher.action.replay.saveWarn="Aviso: Salvar com muita frequência pode resultar em o buffer de replay não ser realmente salvo!"
|
AdvSceneSwitcher.action.replay.saveWarn="Aviso: Salvar com muita frequência pode resultar em o buffer de replay não ser realmente salvo!"
|
||||||
AdvSceneSwitcher.action.replay.durationWarn="Aviso: Alterar o tempo máximo de replay só se aplicará na próxima vez que o buffer de replay for iniciado!"
|
AdvSceneSwitcher.action.replay.durationWarn="Aviso: Alterar o tempo máximo de replay só se aplicará na próxima vez que o buffer de replay for iniciado!"
|
||||||
@@ -764,6 +774,7 @@ AdvSceneSwitcher.action.streaming.type.server="Definir URL do servidor"
|
|||||||
AdvSceneSwitcher.action.streaming.type.streamKey="Definir chave de transmissão"
|
AdvSceneSwitcher.action.streaming.type.streamKey="Definir chave de transmissão"
|
||||||
AdvSceneSwitcher.action.streaming.type.username="Definir nome de usuário"
|
AdvSceneSwitcher.action.streaming.type.username="Definir nome de usuário"
|
||||||
AdvSceneSwitcher.action.streaming.type.password="Definir senha"
|
AdvSceneSwitcher.action.streaming.type.password="Definir senha"
|
||||||
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Executar"
|
AdvSceneSwitcher.action.run="Executar"
|
||||||
AdvSceneSwitcher.action.run.wait.entry="{{wait}}Aguardar a saída do processo ou no máximo {{timeout}}{{waitHelp}}"
|
AdvSceneSwitcher.action.run.wait.entry="{{wait}}Aguardar a saída do processo ou no máximo {{timeout}}{{waitHelp}}"
|
||||||
AdvSceneSwitcher.action.run.wait.help.tooltip="Observe que as propriedades da macro não funcionarão se você deixar isso desmarcado, pois o processo é iniciado de forma independente do restante da lógica e não há controle sobre ele."
|
AdvSceneSwitcher.action.run.wait.help.tooltip="Observe que as propriedades da macro não funcionarão se você deixar isso desmarcado, pois o processo é iniciado de forma independente do restante da lógica e não há controle sobre ele."
|
||||||
@@ -773,7 +784,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
|||||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Alternar"
|
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Alternar"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Fonte"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Fonte"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Qualquer"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Qualquer"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.layout="Em{{scenes}}{{actions}}{{sources}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="Em{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filtro"
|
AdvSceneSwitcher.action.filter="Filtro"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Desabilitar"
|
AdvSceneSwitcher.action.filter.type.disable="Desabilitar"
|
||||||
@@ -838,7 +849,7 @@ AdvSceneSwitcher.action.macro="Macro"
|
|||||||
AdvSceneSwitcher.action.macro.type.pause="Pausar"
|
AdvSceneSwitcher.action.macro.type.pause="Pausar"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Retomar"
|
AdvSceneSwitcher.action.macro.type.unpause="Retomar"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
|
||||||
AdvSceneSwitcher.action.macro.type.runActions="Executar macro"
|
AdvSceneSwitcher.action.macro.type.run="Executar macro"
|
||||||
AdvSceneSwitcher.action.macro.type.run.conditions.ignore="Não considerar o estado da condição"
|
AdvSceneSwitcher.action.macro.type.run.conditions.ignore="Não considerar o estado da condição"
|
||||||
AdvSceneSwitcher.action.macro.type.run.conditions.true="Apenas se as condições forem verdadeiras"
|
AdvSceneSwitcher.action.macro.type.run.conditions.true="Apenas se as condições forem verdadeiras"
|
||||||
AdvSceneSwitcher.action.macro.type.run.conditions.false="Apenas se as condições forem falsas"
|
AdvSceneSwitcher.action.macro.type.run.conditions.false="Apenas se as condições forem falsas"
|
||||||
@@ -853,9 +864,9 @@ AdvSceneSwitcher.action.macro.type.stop="Parar ações"
|
|||||||
AdvSceneSwitcher.action.macro.type.disableAction="Desabilitar ação"
|
AdvSceneSwitcher.action.macro.type.disableAction="Desabilitar ação"
|
||||||
AdvSceneSwitcher.action.macro.type.enableAction="Habilitar ação"
|
AdvSceneSwitcher.action.macro.type.enableAction="Habilitar ação"
|
||||||
AdvSceneSwitcher.action.macro.type.toggleAction="Alternar ação"
|
AdvSceneSwitcher.action.macro.type.toggleAction="Alternar ação"
|
||||||
AdvSceneSwitcher.action.macro.layout.run="{{actions}}{{actionSections}}de{{macros}}"
|
AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}de{{macros}}"
|
||||||
AdvSceneSwitcher.action.macro.layout.run.condition="{{conditionBehaviors}}de{{conditionMacros}}"
|
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}de{{conditionMacros}}"
|
||||||
AdvSceneSwitcher.action.macro.layout.other="{{actions}}{{macros}}"
|
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
|
||||||
AdvSceneSwitcher.action.pluginState="Estado do plugin"
|
AdvSceneSwitcher.action.pluginState="Estado do plugin"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Parar o plugin Advanced Scene Switcher"
|
AdvSceneSwitcher.action.pluginState.type.stop="Parar o plugin Advanced Scene Switcher"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Alterar o comportamento em caso de não correspondência:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Alterar o comportamento em caso de não correspondência:"
|
||||||
@@ -863,7 +874,7 @@ AdvSceneSwitcher.action.pluginState.type.import="Importar configurações de"
|
|||||||
AdvSceneSwitcher.action.pluginState.importWarning="Nota: Ação será ignorada enquanto a janela de configurações estiver aberta."
|
AdvSceneSwitcher.action.pluginState.importWarning="Nota: Ação será ignorada enquanto a janela de configurações estiver aberta."
|
||||||
AdvSceneSwitcher.action.pluginState.type.terminate="Desligar OBS"
|
AdvSceneSwitcher.action.pluginState.type.terminate="Desligar OBS"
|
||||||
AdvSceneSwitcher.action.pluginState.terminateConfirm="O OBS será desligado automaticamente em 10 segundos!\nDeseja continuar com o desligamento do OBS?"
|
AdvSceneSwitcher.action.pluginState.terminateConfirm="O OBS será desligado automaticamente em 10 segundos!\nDeseja continuar com o desligamento do OBS?"
|
||||||
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}"
|
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}{{settingsWarning}}"
|
||||||
AdvSceneSwitcher.action.virtualCamera="Câmera virtual"
|
AdvSceneSwitcher.action.virtualCamera="Câmera virtual"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.stop="Parar câmera virtual"
|
AdvSceneSwitcher.action.virtualCamera.type.stop="Parar câmera virtual"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.start="Iniciar câmera virtual"
|
AdvSceneSwitcher.action.virtualCamera.type.start="Iniciar câmera virtual"
|
||||||
@@ -925,9 +936,9 @@ AdvSceneSwitcher.action.transition.type.scene="transição de cena"
|
|||||||
AdvSceneSwitcher.action.transition.type.sceneOverride="substituição de transição de cena"
|
AdvSceneSwitcher.action.transition.type.sceneOverride="substituição de transição de cena"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceShow="transição de exibição de fonte"
|
AdvSceneSwitcher.action.transition.type.sourceShow="transição de exibição de fonte"
|
||||||
AdvSceneSwitcher.action.transition.type.sourceHide="transição de ocultação de fonte"
|
AdvSceneSwitcher.action.transition.type.sourceHide="transição de ocultação de fonte"
|
||||||
AdvSceneSwitcher.action.transition.layout.type="Modificar{{type}}{{scenes}}{{sources}}"
|
AdvSceneSwitcher.action.transition.entry.line1="Modificar{{type}}{{scenes}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.transition="{{setTransition}}Definir tipo de transição para{{transitions}}"
|
AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}}Definir tipo de transição para{{transitions}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.duration="{{setDuration}}Definir duração da transição para{{duration}}segundos"
|
AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}}Definir duração da transição para{{duration}}segundos"
|
||||||
AdvSceneSwitcher.action.timer="Temporizador"
|
AdvSceneSwitcher.action.timer="Temporizador"
|
||||||
AdvSceneSwitcher.action.timer.type.pause="Pausar"
|
AdvSceneSwitcher.action.timer.type.pause="Pausar"
|
||||||
AdvSceneSwitcher.action.timer.type.continue="Continuar"
|
AdvSceneSwitcher.action.timer.type.continue="Continuar"
|
||||||
@@ -1022,8 +1033,8 @@ AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Obter valores de va
|
|||||||
AdvSceneSwitcher.action.variable.currentSegmentValue="Valor atual:"
|
AdvSceneSwitcher.action.variable.currentSegmentValue="Valor atual:"
|
||||||
AdvSceneSwitcher.action.variable.layout.pad="{{actions}}de{{variables}}para comprimento{{stringLength}}adicionando{{paddingCharSelection}}ao{{direction}}"
|
AdvSceneSwitcher.action.variable.layout.pad="{{actions}}de{{variables}}para comprimento{{stringLength}}adicionando{{paddingCharSelection}}ao{{direction}}"
|
||||||
AdvSceneSwitcher.action.variable.layout.truncate="{{actions}}de{{variables}}para comprimento{{stringLength}}removendo caracteres da{{direction}}"
|
AdvSceneSwitcher.action.variable.layout.truncate="{{actions}}de{{variables}}para comprimento{{stringLength}}removendo caracteres da{{direction}}"
|
||||||
AdvSceneSwitcher.action.variable.layout.substringIndex="Início da substring:{{subStringStart}}Tamanho da substring:{{subStringSize}}{{subStringRegex}}"
|
AdvSceneSwitcher.action.variable.layout.substringIndex="Início da substring:{{subStringStart}}Tamanho da substring:{{subStringSize}}"
|
||||||
AdvSceneSwitcher.action.variable.layout.substringRegex="Atribuir valor do{{regexMatchIdx}}correspondência usando expressão regular:{{subStringRegex}}"
|
AdvSceneSwitcher.action.variable.layout.substringRegex="Atribuir valor do{{regexMatchIdx}}correspondência usando expressão regular:"
|
||||||
AdvSceneSwitcher.action.variable.layout.findAndReplace="{{findStr}}{{findRegex}}{{replaceStr}}"
|
AdvSceneSwitcher.action.variable.layout.findAndReplace="{{findStr}}{{findRegex}}{{replaceStr}}"
|
||||||
AdvSceneSwitcher.action.variable.layout.userInput.customPrompt="{{useCustomPrompt}}Usar prompt personalizado{{inputPrompt}}"
|
AdvSceneSwitcher.action.variable.layout.userInput.customPrompt="{{useCustomPrompt}}Usar prompt personalizado{{inputPrompt}}"
|
||||||
AdvSceneSwitcher.action.variable.layout.userInput.placeholder="{{useInputPlaceholder}}Preencher com placeholder{{inputPlaceholder}}"
|
AdvSceneSwitcher.action.variable.layout.userInput.placeholder="{{useInputPlaceholder}}Preencher com placeholder{{inputPlaceholder}}"
|
||||||
@@ -1057,8 +1068,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}}{{nonModDelayDuration}}"
|
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"
|
||||||
@@ -1840,19 +1851,19 @@ AdvSceneSwitcher.setting.transform.width="Largura"
|
|||||||
|
|
||||||
AdvSceneSwitcher.sceneItemSelection.configure="Configurar tipo de seleção de item de cena"
|
AdvSceneSwitcher.sceneItemSelection.configure="Configurar tipo de seleção de item de cena"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceName="Nome da fonte"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceName="Nome da fonte"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceName.layout="{{nameConflictIndex}}{{sourceName}}"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceName.entry="{{nameConflictIndex}}{{sourceName}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceVariable="Nome da variável"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceVariable="Nome da variável"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceVariable.layout="{{nameConflictIndex}}{{variable}}"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceVariable.entry="{{nameConflictIndex}}{{variable}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern="Nome da fonte corresponde ao padrão"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern="Nome da fonte corresponde ao padrão"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern.layout="{{nameConflictIndex}}correspondendo{{pattern}}{{regex}}"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceNamePattern.entry="{{nameConflictIndex}}correspondendo{{pattern}}{{regex}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceType="Fontes do tipo"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceType="Fontes do tipo"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceType.layout="Tipo de fonte{{nameConflictIndex}}{{sourceTypes}}"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceType.entry="Tipo de fonte{{nameConflictIndex}}{{sourceTypes}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.index="Fonte com índice"
|
AdvSceneSwitcher.sceneItemSelection.type.index="Fonte com índice"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.index.layout="{{index}}fonte"
|
AdvSceneSwitcher.sceneItemSelection.type.index.entry="{{index}}fonte"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.indexRange="Fontes no intervalo de índices"
|
AdvSceneSwitcher.sceneItemSelection.type.indexRange="Fontes no intervalo de índices"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.indexRange.layout="Fontes de{{index}}para{{indexEnd}}"
|
AdvSceneSwitcher.sceneItemSelection.type.indexRange.entry="Fontes de{{index}}para{{indexEnd}}"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.all="Todas as fontes"
|
AdvSceneSwitcher.sceneItemSelection.type.all="Todas as fontes"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.all.layout="Todas as fontes"
|
AdvSceneSwitcher.sceneItemSelection.type.all.entry="Todas as fontes"
|
||||||
AdvSceneSwitcher.sceneItemSelection.all="Todas"
|
AdvSceneSwitcher.sceneItemSelection.all="Todas"
|
||||||
AdvSceneSwitcher.sceneItemSelection.any="Qualquer"
|
AdvSceneSwitcher.sceneItemSelection.any="Qualquer"
|
||||||
|
|
||||||
@@ -1863,6 +1874,8 @@ AdvSceneSwitcher.status.inactive="Inativo"
|
|||||||
AdvSceneSwitcher.running="Plugin em execução"
|
AdvSceneSwitcher.running="Plugin em execução"
|
||||||
AdvSceneSwitcher.stopped="Plugin parado"
|
AdvSceneSwitcher.stopped="Plugin parado"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>Parece que esta é a primeira vez que o Advanced Scene Switcher está sendo iniciado.<br>Por favor, consulte o <a href=\"https://github.com/WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> para uma lista de guias e exemplos.<br>Não hesite em fazer perguntas no <a href=\"https://obsproject.com/forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:#268bd2;\">tópico</span></a> do plugin nos fóruns do OBS!</p></body></html>"
|
||||||
|
|
||||||
AdvSceneSwitcher.deprecatedTabWarning="Desenvolvimento para esta aba interrompido!\nPor favor, considere a transição para o uso de Macros em vez disso.\nEsta dica pode ser desativada na aba Geral."
|
AdvSceneSwitcher.deprecatedTabWarning="Desenvolvimento para esta aba interrompido!\nPor favor, considere a transição para o uso de Macros em vez disso.\nEsta dica pode ser desativada na aba Geral."
|
||||||
|
|
||||||
AdvSceneSwitcher.unit.milliseconds="milissegundos"
|
AdvSceneSwitcher.unit.milliseconds="milissegundos"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ AdvSceneSwitcher.generalTab.status.onStartup.alwaysStart="Всегда запу
|
|||||||
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Не запускать переключатель сцен"
|
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Не запускать переключатель сцен"
|
||||||
AdvSceneSwitcher.generalTab.status.start="Старт"
|
AdvSceneSwitcher.generalTab.status.start="Старт"
|
||||||
AdvSceneSwitcher.generalTab.status.stop="Стоп"
|
AdvSceneSwitcher.generalTab.status.stop="Стоп"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.startup="Автоматически запускать переключатель сцен, когда:"
|
AdvSceneSwitcher.generalTab.status.autoStart="Автоматически запускать переключатель сцен, когда:"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.never="Никогда"
|
AdvSceneSwitcher.generalTab.status.autoStart.never="Никогда"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.recording="Запись"
|
AdvSceneSwitcher.generalTab.status.autoStart.recording="Запись"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Вещание"
|
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Вещание"
|
||||||
@@ -70,6 +70,7 @@ AdvSceneSwitcher.macroTab.name="Имя:"
|
|||||||
AdvSceneSwitcher.macroTab.defaultname="Макрос %1"
|
AdvSceneSwitcher.macroTab.defaultname="Макрос %1"
|
||||||
AdvSceneSwitcher.macroTab.copy="Создать копию"
|
AdvSceneSwitcher.macroTab.copy="Создать копию"
|
||||||
; Macro Logic
|
; Macro Logic
|
||||||
|
AdvSceneSwitcher.logic.none="Игнорировать вход"
|
||||||
AdvSceneSwitcher.logic.and="И"
|
AdvSceneSwitcher.logic.and="И"
|
||||||
AdvSceneSwitcher.logic.or="Или"
|
AdvSceneSwitcher.logic.or="Или"
|
||||||
AdvSceneSwitcher.logic.andNot="И не"
|
AdvSceneSwitcher.logic.andNot="И не"
|
||||||
@@ -84,6 +85,8 @@ AdvSceneSwitcher.condition.scene.type.current="Текущий"
|
|||||||
AdvSceneSwitcher.condition.scene.type.previous="Предыдущий"
|
AdvSceneSwitcher.condition.scene.type.previous="Предыдущий"
|
||||||
AdvSceneSwitcher.condition.window="Окно"
|
AdvSceneSwitcher.condition.window="Окно"
|
||||||
AdvSceneSwitcher.condition.file="Файл"
|
AdvSceneSwitcher.condition.file="Файл"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Медиа"
|
AdvSceneSwitcher.condition.media="Медиа"
|
||||||
AdvSceneSwitcher.condition.video="Видео"
|
AdvSceneSwitcher.condition.video="Видео"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
||||||
@@ -102,7 +105,7 @@ AdvSceneSwitcher.condition.record.state.start="Запись запущена"
|
|||||||
AdvSceneSwitcher.condition.record.state.pause="Запись приостановлена"
|
AdvSceneSwitcher.condition.record.state.pause="Запись приостановлена"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Запись остановлена"
|
AdvSceneSwitcher.condition.record.state.stop="Запись остановлена"
|
||||||
AdvSceneSwitcher.condition.process="Процесс"
|
AdvSceneSwitcher.condition.process="Процесс"
|
||||||
AdvSceneSwitcher.condition.process.layout="{{processes}}{{regex}}запущен{{focused}}и сфокусирован"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}запущен{{focused}}и сфокусирован"
|
||||||
AdvSceneSwitcher.condition.idle="Простой"
|
AdvSceneSwitcher.condition.idle="Простой"
|
||||||
AdvSceneSwitcher.condition.idle.entry="Не было ни клавиатуры, ни мыши в течении{{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="Не было ни клавиатуры, ни мыши в течении{{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Состояние плагина"
|
AdvSceneSwitcher.condition.pluginState="Состояние плагина"
|
||||||
@@ -111,11 +114,12 @@ AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
|||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.scene="Переключить сцену"
|
AdvSceneSwitcher.action.scene="Переключить сцену"
|
||||||
|
AdvSceneSwitcher.action.scene.entry="Перейти к сцене{{sceneTypes}}{{scenes}}используя{{transitions}}с продолжительностью{{duration}}секунд"
|
||||||
AdvSceneSwitcher.action.wait="Подождать"
|
AdvSceneSwitcher.action.wait="Подождать"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="фиксированный"
|
AdvSceneSwitcher.action.wait.type.fixed="фиксированный"
|
||||||
AdvSceneSwitcher.action.wait.type.random="случайный"
|
AdvSceneSwitcher.action.wait.type.random="случайный"
|
||||||
AdvSceneSwitcher.action.wait.layout.fixed="Ожидать {{waitType}} в течении {{duration}}"
|
AdvSceneSwitcher.action.wait.entry.fixed="Ожидать {{waitType}} в течении {{duration}}"
|
||||||
AdvSceneSwitcher.action.wait.layout.random="Ожидание {{waitType}} длительностью от {{duration}} до {{duration2}}"
|
AdvSceneSwitcher.action.wait.entry.random="Ожидание {{waitType}} длительностью от {{duration}} до {{duration2}}"
|
||||||
AdvSceneSwitcher.action.audio="Аудио"
|
AdvSceneSwitcher.action.audio="Аудио"
|
||||||
AdvSceneSwitcher.action.audio.type.mute="Замьютить"
|
AdvSceneSwitcher.action.audio.type.mute="Замьютить"
|
||||||
AdvSceneSwitcher.action.audio.type.unmute="Размьютить"
|
AdvSceneSwitcher.action.audio.type.unmute="Размьютить"
|
||||||
@@ -127,6 +131,7 @@ AdvSceneSwitcher.action.recording.type.start="Начать запись"
|
|||||||
AdvSceneSwitcher.action.recording.type.pause="Пауза записи"
|
AdvSceneSwitcher.action.recording.type.pause="Пауза записи"
|
||||||
AdvSceneSwitcher.action.recording.type.unpause="Снять запись с паузы"
|
AdvSceneSwitcher.action.recording.type.unpause="Снять запись с паузы"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Обратите внимание, что в зависимости от настроек записи вы можете не иметь возможности приостановить запись"
|
AdvSceneSwitcher.action.recording.pause.hint="Обратите внимание, что в зависимости от настроек записи вы можете не иметь возможности приостановить запись"
|
||||||
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Буфер воспроизведения"
|
AdvSceneSwitcher.action.replay="Буфер воспроизведения"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Остановить буфер воспроизведения"
|
AdvSceneSwitcher.action.replay.type.stop="Остановить буфер воспроизведения"
|
||||||
AdvSceneSwitcher.action.replay.type.start="Начать воспроизведение буфера"
|
AdvSceneSwitcher.action.replay.type.start="Начать воспроизведение буфера"
|
||||||
@@ -134,6 +139,7 @@ AdvSceneSwitcher.action.replay.type.save="Сохранить буфер восп
|
|||||||
AdvSceneSwitcher.action.streaming="Потоковое вещание"
|
AdvSceneSwitcher.action.streaming="Потоковое вещание"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
||||||
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Запустить"
|
AdvSceneSwitcher.action.run="Запустить"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ AdvSceneSwitcher.generalTab.status.onStartup.alwaysStart="Her zaman sahne deği
|
|||||||
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Sahne değiştiriciyi başlatma"
|
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Sahne değiştiriciyi başlatma"
|
||||||
AdvSceneSwitcher.generalTab.status.start="Başlat"
|
AdvSceneSwitcher.generalTab.status.start="Başlat"
|
||||||
AdvSceneSwitcher.generalTab.status.stop="Durdur"
|
AdvSceneSwitcher.generalTab.status.stop="Durdur"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.startup="Aşağıdaki durumlarda sahne değiştiriciyi otomatik olarak başlatın:"
|
AdvSceneSwitcher.generalTab.status.autoStart="Aşağıdaki durumlarda sahne değiştiriciyi otomatik olarak başlatın:"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.never="Asla"
|
AdvSceneSwitcher.generalTab.status.autoStart.never="Asla"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.recording="Kayıt"
|
AdvSceneSwitcher.generalTab.status.autoStart.recording="Kayıt"
|
||||||
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Yayın"
|
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Yayın"
|
||||||
@@ -72,12 +72,14 @@ AdvSceneSwitcher.macroTab.add="Yeni Makro ekle"
|
|||||||
AdvSceneSwitcher.macroTab.name="İsim:"
|
AdvSceneSwitcher.macroTab.name="İsim:"
|
||||||
AdvSceneSwitcher.macroTab.run="Makro Çalıştırma"
|
AdvSceneSwitcher.macroTab.run="Makro Çalıştırma"
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Makroyu diğer makrolara paralel olarak çalıştırın"
|
AdvSceneSwitcher.macroTab.runInParallel="Makroyu diğer makrolara paralel olarak çalıştırın"
|
||||||
|
AdvSceneSwitcher.macroTab.onChange="Eylemleri yalnızca koşul değişikliğinde gerçekleştirin"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
||||||
AdvSceneSwitcher.macroTab.copy="Kopya oluştur"
|
AdvSceneSwitcher.macroTab.copy="Kopya oluştur"
|
||||||
AdvSceneSwitcher.macroTab.expandAll="Hepsini Genişlet"
|
AdvSceneSwitcher.macroTab.expandAll="Hepsini Genişlet"
|
||||||
AdvSceneSwitcher.macroTab.collapseAll="Hepsini Küçült"
|
AdvSceneSwitcher.macroTab.collapseAll="Hepsini Küçült"
|
||||||
|
|
||||||
; Macro Logic
|
; Macro Logic
|
||||||
|
AdvSceneSwitcher.logic.none="Girişi yoksay"
|
||||||
AdvSceneSwitcher.logic.and="Ve"
|
AdvSceneSwitcher.logic.and="Ve"
|
||||||
AdvSceneSwitcher.logic.or="Ya da"
|
AdvSceneSwitcher.logic.or="Ya da"
|
||||||
AdvSceneSwitcher.logic.andNot="ve değil"
|
AdvSceneSwitcher.logic.andNot="ve değil"
|
||||||
@@ -106,7 +108,9 @@ AdvSceneSwitcher.condition.scene.type.notChanged="Sahne değişmedi"
|
|||||||
AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Geçiş hedefi sahnesi için geçiş kontrolü sırasında"
|
AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Geçiş hedefi sahnesi için geçiş kontrolü sırasında"
|
||||||
AdvSceneSwitcher.condition.window="Pencere"
|
AdvSceneSwitcher.condition.window="Pencere"
|
||||||
AdvSceneSwitcher.condition.file="Dosya"
|
AdvSceneSwitcher.condition.file="Dosya"
|
||||||
AdvSceneSwitcher.condition.file.layout="İçerik{{filePath}}{{conditions}}{{regex}}"
|
AdvSceneSwitcher.condition.file.entry.line1="İçerik{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Medya"
|
AdvSceneSwitcher.condition.media="Medya"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Herhangi bir medya kaynağı"
|
AdvSceneSwitcher.condition.media.anyOnScene="Herhangi bir medya kaynağı"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="Tüm medya kaynakları "
|
AdvSceneSwitcher.condition.media.allOnScene="Tüm medya kaynakları "
|
||||||
@@ -149,7 +153,7 @@ AdvSceneSwitcher.condition.record.state.start="Kayıt Çalışıyor"
|
|||||||
AdvSceneSwitcher.condition.record.state.pause="Kayıt durakladı"
|
AdvSceneSwitcher.condition.record.state.pause="Kayıt durakladı"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Kayıt durdu"
|
AdvSceneSwitcher.condition.record.state.stop="Kayıt durdu"
|
||||||
AdvSceneSwitcher.condition.process="İşlem"
|
AdvSceneSwitcher.condition.process="İşlem"
|
||||||
AdvSceneSwitcher.condition.process.layout="{{processes}}{{regex}}çalışıyor{{focused}}ve odaklandı"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}çalışıyor{{focused}}ve odaklandı"
|
||||||
AdvSceneSwitcher.condition.idle="Boşta"
|
AdvSceneSwitcher.condition.idle="Boşta"
|
||||||
AdvSceneSwitcher.condition.idle.entry="...için klavye veya fare girişi yok {{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="...için klavye veya fare girişi yok {{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Eklenti durumu"
|
AdvSceneSwitcher.condition.pluginState="Eklenti durumu"
|
||||||
@@ -245,12 +249,13 @@ AdvSceneSwitcher.condition.openvr.entry.line3="HMD mevcut {{xPos}} x {{yPos}} x
|
|||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.scene="Sahne Degistirici"
|
AdvSceneSwitcher.action.scene="Sahne Degistirici"
|
||||||
|
AdvSceneSwitcher.action.scene.entry="Sahneyi{{sceneTypes}}{{scenes}}kullanarak{{transitions}}süresi olan{{duration}}saniye"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Hedef sahneye geçiş tamamlanana kadar bekleyin"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Hedef sahneye geçiş tamamlanana kadar bekleyin"
|
||||||
AdvSceneSwitcher.action.wait="Bekle"
|
AdvSceneSwitcher.action.wait="Bekle"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="sabit"
|
AdvSceneSwitcher.action.wait.type.fixed="sabit"
|
||||||
AdvSceneSwitcher.action.wait.type.random="rastgele"
|
AdvSceneSwitcher.action.wait.type.random="rastgele"
|
||||||
AdvSceneSwitcher.action.wait.layout.fixed="Şunu bekle {{waitType}} süre {{duration}}"
|
AdvSceneSwitcher.action.wait.entry.fixed="Şunu bekle {{waitType}} süre {{duration}}"
|
||||||
AdvSceneSwitcher.action.wait.layout.random="Şunu bekle {{waitType}} bu aralıktan {{duration}} buna {{duration2}}"
|
AdvSceneSwitcher.action.wait.entry.random="Şunu bekle {{waitType}} bu aralıktan {{duration}} buna {{duration2}}"
|
||||||
AdvSceneSwitcher.action.audio="Ses"
|
AdvSceneSwitcher.action.audio="Ses"
|
||||||
AdvSceneSwitcher.action.audio.type.mute="Sessiz"
|
AdvSceneSwitcher.action.audio.type.mute="Sessiz"
|
||||||
AdvSceneSwitcher.action.audio.type.unmute="Ses açmak"
|
AdvSceneSwitcher.action.audio.type.unmute="Ses açmak"
|
||||||
@@ -262,6 +267,7 @@ AdvSceneSwitcher.action.recording.type.start="Kayıt Başlat"
|
|||||||
AdvSceneSwitcher.action.recording.type.pause="Kayıt Duraklat"
|
AdvSceneSwitcher.action.recording.type.pause="Kayıt Duraklat"
|
||||||
AdvSceneSwitcher.action.recording.type.unpause="Kayıt Duraklatma"
|
AdvSceneSwitcher.action.recording.type.unpause="Kayıt Duraklatma"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Kayıt ayarlarınıza bağlı olarak kaydı duraklatamayabileceğinizi unutmayın."
|
AdvSceneSwitcher.action.recording.pause.hint="Kayıt ayarlarınıza bağlı olarak kaydı duraklatamayabileceğinizi unutmayın."
|
||||||
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Tekrar arabelleği"
|
AdvSceneSwitcher.action.replay="Tekrar arabelleği"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Tekrar arabelleğini durdur"
|
AdvSceneSwitcher.action.replay.type.stop="Tekrar arabelleğini durdur"
|
||||||
AdvSceneSwitcher.action.replay.type.start="Tekrar arabelleğini başlat"
|
AdvSceneSwitcher.action.replay.type.start="Tekrar arabelleğini başlat"
|
||||||
@@ -269,13 +275,14 @@ AdvSceneSwitcher.action.replay.type.save="Tekrar arabelleğini kaydet"
|
|||||||
AdvSceneSwitcher.action.streaming="Yayın"
|
AdvSceneSwitcher.action.streaming="Yayın"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Yayın durdur"
|
AdvSceneSwitcher.action.streaming.type.stop="Yayın durdur"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Yayın başlat"
|
AdvSceneSwitcher.action.streaming.type.start="Yayın başlat"
|
||||||
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Çalıştır"
|
AdvSceneSwitcher.action.run="Çalıştır"
|
||||||
AdvSceneSwitcher.action.sceneVisibility="Sahne öğesi görünürlüğü"
|
AdvSceneSwitcher.action.sceneVisibility="Sahne öğesi görünürlüğü"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Göster"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Göster"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Gizle"
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="Gizle"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Kayıt"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Kayıt"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Herhangi"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Herhangi"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.layout="Açık{{scenes}}{{actions}}{{sources}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="Açık{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filtrele"
|
AdvSceneSwitcher.action.filter="Filtrele"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Etkin"
|
AdvSceneSwitcher.action.filter.type.enable="Etkin"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Etkisiz"
|
AdvSceneSwitcher.action.filter.type.disable="Etkisiz"
|
||||||
@@ -299,13 +306,13 @@ AdvSceneSwitcher.action.macro="Makro"
|
|||||||
AdvSceneSwitcher.action.macro.type.pause="Duraklat"
|
AdvSceneSwitcher.action.macro.type.pause="Duraklat"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Duraklatma"
|
AdvSceneSwitcher.action.macro.type.unpause="Duraklatma"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Sayacı sıfırla"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Sayacı sıfırla"
|
||||||
AdvSceneSwitcher.action.macro.type.runActions="Çalıştır"
|
AdvSceneSwitcher.action.macro.type.run="Çalıştır"
|
||||||
AdvSceneSwitcher.action.pluginState="Eklenti durumu"
|
AdvSceneSwitcher.action.pluginState="Eklenti durumu"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Advanced Scene Switcher eklentisini durdurun"
|
AdvSceneSwitcher.action.pluginState.type.stop="Advanced Scene Switcher eklentisini durdurun"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Eşleşmeme davranışını değiştirin:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Eşleşmeme davranışını değiştirin:"
|
||||||
AdvSceneSwitcher.action.pluginState.type.import="Ayarları şuradan içe aktar:"
|
AdvSceneSwitcher.action.pluginState.type.import="Ayarları şuradan içe aktar:"
|
||||||
AdvSceneSwitcher.action.pluginState.importWarning="Not: Ayarlar penceresi açılırken eylem göz ardı edilecektir."
|
AdvSceneSwitcher.action.pluginState.importWarning="Not: Ayarlar penceresi açılırken eylem göz ardı edilecektir."
|
||||||
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}"
|
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}{{settingsWarning}}"
|
||||||
AdvSceneSwitcher.action.virtualCamera="Sanal Kamera"
|
AdvSceneSwitcher.action.virtualCamera="Sanal Kamera"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.stop="Sanal Kamerayı Durdur"
|
AdvSceneSwitcher.action.virtualCamera.type.stop="Sanal Kamerayı Durdur"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.start="Sanal Kamerayı Başlat"
|
AdvSceneSwitcher.action.virtualCamera.type.start="Sanal Kamerayı Başlat"
|
||||||
@@ -336,8 +343,8 @@ AdvSceneSwitcher.action.file.type.write="Yaz"
|
|||||||
AdvSceneSwitcher.action.file.type.append="Ekle"
|
AdvSceneSwitcher.action.file.type.append="Ekle"
|
||||||
AdvSceneSwitcher.action.file.entry="{{actions}} {{filePath}}:"
|
AdvSceneSwitcher.action.file.entry="{{actions}} {{filePath}}:"
|
||||||
AdvSceneSwitcher.action.transition="Geçiş"
|
AdvSceneSwitcher.action.transition="Geçiş"
|
||||||
AdvSceneSwitcher.action.transition.layout.transition="{{setTransition}}Geçiş türünü ayarla {{transitions}}"
|
AdvSceneSwitcher.action.transition.entry.line2="{{setTransition}}Geçiş türünü ayarla {{transitions}}"
|
||||||
AdvSceneSwitcher.action.transition.layout.duration="{{setDuration}}Geçiş süresini şuna ayarla: {{duration}}saniyeler"
|
AdvSceneSwitcher.action.transition.entry.line3="{{setDuration}}Geçiş süresini şuna ayarla: {{duration}}saniyeler"
|
||||||
AdvSceneSwitcher.action.timer="Zamanlayıcı"
|
AdvSceneSwitcher.action.timer="Zamanlayıcı"
|
||||||
AdvSceneSwitcher.action.timer.type.pause="Duraklat"
|
AdvSceneSwitcher.action.timer.type.pause="Duraklat"
|
||||||
AdvSceneSwitcher.action.timer.type.continue="Devam et"
|
AdvSceneSwitcher.action.timer.type.continue="Devam et"
|
||||||
@@ -581,6 +588,8 @@ AdvSceneSwitcher.status.inactive="İnaktif"
|
|||||||
AdvSceneSwitcher.running="Eklenti çalışıyor"
|
AdvSceneSwitcher.running="Eklenti çalışıyor"
|
||||||
AdvSceneSwitcher.stopped="Eklenti durdu"
|
AdvSceneSwitcher.stopped="Eklenti durdu"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>Gelişmiş Sahne Değiştirici ilk kez başlatılıyor gibi görünüyor.<br>Lütfen <a href=\"https://github.com/ adresine bir göz atın. WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> için kılavuzlar ve örnekler listesi.<br>Yapmayın. eklentinin <a href=\"https://obsproject.com/forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:# sayfasında soru sormaktan çekinmeyin OBS forumlarında 268bd2;\">konu</span></a>!</p></body></html>"
|
||||||
|
|
||||||
AdvSceneSwitcher.unit.milliseconds="millisaniye"
|
AdvSceneSwitcher.unit.milliseconds="millisaniye"
|
||||||
AdvSceneSwitcher.unit.seconds="saniye"
|
AdvSceneSwitcher.unit.seconds="saniye"
|
||||||
AdvSceneSwitcher.unit.minutes="dakika"
|
AdvSceneSwitcher.unit.minutes="dakika"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#fefefe" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="800px" height="800px" viewBox="0 0 52 52" enable-background="new 0 0 52 52" xml:space="preserve">
|
|
||||||
<path d="M42.6,17.8c2.4,0,7.2-2,7.2-8.4c0-6.4-4.6-6.8-6.1-6.8c-2.8,0-5.6,2-8.1,6.3c-2.5,4.4-5.3,9.1-5.3,9.1
|
|
||||||
l-0.1,0c-0.6-3.1-1.1-5.6-1.3-6.7c-0.5-2.7-3.6-8.4-9.9-8.4c-6.4,0-12.2,3.7-12.2,3.7l0,0C5.8,7.3,5.1,8.5,5.1,9.9
|
|
||||||
c0,2.1,1.7,3.9,3.9,3.9c0.6,0,1.2-0.2,1.7-0.4l0,0c0,0,4.8-2.7,5.9,0c0.3,0.8,0.6,1.7,0.9,2.7c1.2,4.2,2.4,9.1,3.3,13.5l-4.2,6
|
|
||||||
c0,0-4.7-1.7-7.1-1.7s-7.2,2-7.2,8.4s4.6,6.8,6.1,6.8c2.8,0,5.6-2,8.1-6.3c2.5-4.4,5.3-9.1,5.3-9.1c0.8,4,1.5,7.1,1.9,8.5
|
|
||||||
c1.6,4.5,5.3,7.2,10.1,7.2c0,0,5,0,10.9-3.3c1.4-0.6,2.4-2,2.4-3.6c0-2.1-1.7-3.9-3.9-3.9c-0.6,0-1.2,0.2-1.7,0.4l0,0
|
|
||||||
c0,0-4.2,2.4-5.6,0.5c-1-2-1.9-4.6-2.6-7.8c-0.6-2.8-1.3-6.2-2-9.5l4.3-6.2C35.5,16.1,40.2,17.8,42.6,17.8z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 973 B |
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#202020" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="800px" height="800px" viewBox="0 0 52 52" enable-background="new 0 0 52 52" xml:space="preserve">
|
|
||||||
<path d="M42.6,17.8c2.4,0,7.2-2,7.2-8.4c0-6.4-4.6-6.8-6.1-6.8c-2.8,0-5.6,2-8.1,6.3c-2.5,4.4-5.3,9.1-5.3,9.1
|
|
||||||
l-0.1,0c-0.6-3.1-1.1-5.6-1.3-6.7c-0.5-2.7-3.6-8.4-9.9-8.4c-6.4,0-12.2,3.7-12.2,3.7l0,0C5.8,7.3,5.1,8.5,5.1,9.9
|
|
||||||
c0,2.1,1.7,3.9,3.9,3.9c0.6,0,1.2-0.2,1.7-0.4l0,0c0,0,4.8-2.7,5.9,0c0.3,0.8,0.6,1.7,0.9,2.7c1.2,4.2,2.4,9.1,3.3,13.5l-4.2,6
|
|
||||||
c0,0-4.7-1.7-7.1-1.7s-7.2,2-7.2,8.4s4.6,6.8,6.1,6.8c2.8,0,5.6-2,8.1-6.3c2.5-4.4,5.3-9.1,5.3-9.1c0.8,4,1.5,7.1,1.9,8.5
|
|
||||||
c1.6,4.5,5.3,7.2,10.1,7.2c0,0,5,0,10.9-3.3c1.4-0.6,2.4-2,2.4-3.6c0-2.1-1.7-3.9-3.9-3.9c-0.6,0-1.2,0.2-1.7,0.4l0,0
|
|
||||||
c0,0-4.2,2.4-5.6,0.5c-1-2-1.9-4.6-2.6-7.8c-0.6-2.8-1.3-6.2-2-9.5l4.3-6.2C35.5,16.1,40.2,17.8,42.6,17.8z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 973 B |
Binary file not shown.
2
deps/cpp-httplib
vendored
2
deps/cpp-httplib
vendored
Submodule deps/cpp-httplib updated: 008e107d0f...c7ed1796a7
1
deps/date
vendored
Submodule
1
deps/date
vendored
Submodule
Submodule deps/date added at 5bdb7e6f31
2
deps/json
vendored
2
deps/json
vendored
Submodule deps/json updated: 55f93686c0...bc889afb4c
2
deps/leptonica
vendored
2
deps/leptonica
vendored
Submodule deps/leptonica updated: 13275a278e...b667978e86
2
deps/libusb
vendored
2
deps/libusb
vendored
Submodule deps/libusb updated: bc368fb133...d52e355daa
58
deps/obs-websocket/lib/obs-websocket-api.h
vendored
58
deps/obs-websocket/lib/obs-websocket-api.h
vendored
@@ -22,7 +22,7 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
#include <obs.h>
|
#include <obs.h>
|
||||||
|
|
||||||
#define OBS_WEBSOCKET_API_VERSION 2
|
#define OBS_WEBSOCKET_API_VERSION 3
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -31,6 +31,8 @@ extern "C" {
|
|||||||
typedef void *obs_websocket_vendor;
|
typedef void *obs_websocket_vendor;
|
||||||
typedef void (*obs_websocket_request_callback_function)(obs_data_t *,
|
typedef void (*obs_websocket_request_callback_function)(obs_data_t *,
|
||||||
obs_data_t *, void *);
|
obs_data_t *, void *);
|
||||||
|
typedef void (*obs_websocket_event_callback_function)(uint64_t, const char *,
|
||||||
|
const char *, void *);
|
||||||
|
|
||||||
struct obs_websocket_request_response {
|
struct obs_websocket_request_response {
|
||||||
unsigned int status_code;
|
unsigned int status_code;
|
||||||
@@ -45,6 +47,11 @@ struct obs_websocket_request_callback {
|
|||||||
void *priv_data;
|
void *priv_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct obs_websocket_event_callback {
|
||||||
|
obs_websocket_event_callback_function callback;
|
||||||
|
void *priv_data;
|
||||||
|
};
|
||||||
|
|
||||||
static proc_handler_t *_ph;
|
static proc_handler_t *_ph;
|
||||||
|
|
||||||
/* ==================== INTERNAL API FUNCTIONS ==================== */
|
/* ==================== INTERNAL API FUNCTIONS ==================== */
|
||||||
@@ -123,7 +130,6 @@ obs_websocket_call_request(const char *request_type, obs_data_t *request_data
|
|||||||
request_data_string = obs_data_get_json(request_data);
|
request_data_string = obs_data_get_json(request_data);
|
||||||
|
|
||||||
calldata_t cd = {0, 0, 0, 0};
|
calldata_t cd = {0, 0, 0, 0};
|
||||||
|
|
||||||
calldata_set_string(&cd, "request_type", request_type);
|
calldata_set_string(&cd, "request_type", request_type);
|
||||||
calldata_set_string(&cd, "request_data", request_data_string);
|
calldata_set_string(&cd, "request_data", request_data_string);
|
||||||
|
|
||||||
@@ -152,6 +158,48 @@ static inline void obs_websocket_request_response_free(
|
|||||||
bfree(response);
|
bfree(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register an event handler to receive obs-websocket events
|
||||||
|
static inline bool obs_websocket_register_event_callback(
|
||||||
|
obs_websocket_event_callback_function event_callback, void *priv_data)
|
||||||
|
{
|
||||||
|
if (!obs_websocket_ensure_ph())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct obs_websocket_event_callback cb = {event_callback, priv_data};
|
||||||
|
|
||||||
|
calldata_t cd = {0, 0, 0, 0};
|
||||||
|
calldata_set_ptr(&cd, "callback", &cb);
|
||||||
|
|
||||||
|
proc_handler_call(_ph, "register_event_callback", &cd);
|
||||||
|
|
||||||
|
bool ret = calldata_bool(&cd, "success");
|
||||||
|
|
||||||
|
calldata_free(&cd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregister an existing event handler
|
||||||
|
static inline bool obs_websocket_unregister_event_callback(
|
||||||
|
obs_websocket_event_callback_function event_callback, void *priv_data)
|
||||||
|
{
|
||||||
|
if (!obs_websocket_ensure_ph())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct obs_websocket_event_callback cb = {event_callback, priv_data};
|
||||||
|
|
||||||
|
calldata_t cd = {0, 0, 0, 0};
|
||||||
|
calldata_set_ptr(&cd, "callback", &cb);
|
||||||
|
|
||||||
|
proc_handler_call(_ph, "unregister_event_callback", &cd);
|
||||||
|
|
||||||
|
bool ret = calldata_bool(&cd, "success");
|
||||||
|
|
||||||
|
calldata_free(&cd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* ==================== VENDOR API FUNCTIONS ==================== */
|
/* ==================== VENDOR API FUNCTIONS ==================== */
|
||||||
|
|
||||||
// ALWAYS CALL ONLY VIA `obs_module_post_load()` CALLBACK!
|
// ALWAYS CALL ONLY VIA `obs_module_post_load()` CALLBACK!
|
||||||
@@ -163,7 +211,6 @@ obs_websocket_register_vendor(const char *vendor_name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
calldata_t cd = {0, 0, 0, 0};
|
calldata_t cd = {0, 0, 0, 0};
|
||||||
|
|
||||||
calldata_set_string(&cd, "name", vendor_name);
|
calldata_set_string(&cd, "name", vendor_name);
|
||||||
|
|
||||||
proc_handler_call(_ph, "vendor_register", &cd);
|
proc_handler_call(_ph, "vendor_register", &cd);
|
||||||
@@ -179,11 +226,10 @@ static inline bool obs_websocket_vendor_register_request(
|
|||||||
obs_websocket_request_callback_function request_callback,
|
obs_websocket_request_callback_function request_callback,
|
||||||
void *priv_data)
|
void *priv_data)
|
||||||
{
|
{
|
||||||
calldata_t cd = {0, 0, 0, 0};
|
|
||||||
|
|
||||||
struct obs_websocket_request_callback cb = {request_callback,
|
struct obs_websocket_request_callback cb = {request_callback,
|
||||||
priv_data};
|
priv_data};
|
||||||
|
|
||||||
|
calldata_t cd = {0, 0, 0, 0};
|
||||||
calldata_set_string(&cd, "type", request_type);
|
calldata_set_string(&cd, "type", request_type);
|
||||||
calldata_set_ptr(&cd, "callback", &cb);
|
calldata_set_ptr(&cd, "callback", &cb);
|
||||||
|
|
||||||
@@ -200,7 +246,6 @@ obs_websocket_vendor_unregister_request(obs_websocket_vendor vendor,
|
|||||||
const char *request_type)
|
const char *request_type)
|
||||||
{
|
{
|
||||||
calldata_t cd = {0, 0, 0, 0};
|
calldata_t cd = {0, 0, 0, 0};
|
||||||
|
|
||||||
calldata_set_string(&cd, "type", request_type);
|
calldata_set_string(&cd, "type", request_type);
|
||||||
|
|
||||||
bool success = obs_websocket_vendor_run_simple_proc(
|
bool success = obs_websocket_vendor_run_simple_proc(
|
||||||
@@ -217,7 +262,6 @@ static inline bool obs_websocket_vendor_emit_event(obs_websocket_vendor vendor,
|
|||||||
obs_data_t *event_data)
|
obs_data_t *event_data)
|
||||||
{
|
{
|
||||||
calldata_t cd = {0, 0, 0, 0};
|
calldata_t cd = {0, 0, 0, 0};
|
||||||
|
|
||||||
calldata_set_string(&cd, "type", event_name);
|
calldata_set_string(&cd, "type", event_name);
|
||||||
calldata_set_ptr(&cd, "data", (void *)event_data);
|
calldata_set_ptr(&cd, "data", (void *)event_data);
|
||||||
|
|
||||||
|
|||||||
2
deps/opencv
vendored
2
deps/opencv
vendored
Submodule deps/opencv updated: 40738fb16c...71d3237a09
1
deps/opencv_contrib
vendored
1
deps/opencv_contrib
vendored
Submodule deps/opencv_contrib deleted from 755e50675d
1
deps/whisper.cpp
vendored
1
deps/whisper.cpp
vendored
Submodule deps/whisper.cpp deleted from 306c88f4d1
File diff suppressed because it is too large
Load Diff
@@ -1,388 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>MacroEdit</class>
|
|
||||||
<widget class="QWidget" name="MacroEdit">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>300</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QSplitter" name="macroActionConditionSplitter">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="macroConditions" native="true">
|
|
||||||
<layout class="QVBoxLayout" name="macroConditionsLayout">
|
|
||||||
<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="advss::MacroSegmentList" name="conditionsList">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>1</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="conditionControlsLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="conditionAdd">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionAddButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">addIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-plus</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="conditionRemove">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionRemoveButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">removeIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-trash</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="conditionTop">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionTopButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="conditionUp">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionUpButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">upArrowIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-up</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="conditionDown">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionDownButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">downArrowIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-down</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="conditionBottom">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionBottomButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QSplitter" name="macroElseActionSplitter">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="macroActions" native="true">
|
|
||||||
<layout class="QVBoxLayout" name="macroActionsLayout">
|
|
||||||
<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="advss::MacroSegmentList" name="actionsList">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>1</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="actionControlsLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="actionAdd">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionAddButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">addIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-plus</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="actionRemove">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionRemoveButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">removeIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-trash</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="actionTop">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionTopButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="actionUp">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionUpButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">upArrowIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-up</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="actionDown">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionDownButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">downArrowIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-down</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="actionBottom">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionBottomButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_14">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="toggleElseActions">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.toggleShowElseSection</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="macroElseActions" native="true">
|
|
||||||
<layout class="QVBoxLayout" name="macroElseActionsLayout">
|
|
||||||
<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="advss::MacroSegmentList" name="elseActionsList">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>1</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="elseActionControlsLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>9</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="elseActionAdd">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionAddButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">addIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-plus</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="elseActionRemove">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionRemoveButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">removeIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-trash</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="elseActionTop">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionTopButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="elseActionUp">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">upArrowIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-up</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="elseActionDown">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton</string>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
|
||||||
<string notr="true">downArrowIconSmall</string>
|
|
||||||
</property>
|
|
||||||
<property name="class" stdset="0">
|
|
||||||
<string notr="true">icon-down</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="elseActionBottom">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>advss::MacroSegmentList</class>
|
|
||||||
<extends>QScrollArea</extends>
|
|
||||||
<header>macro-segment-list.hpp</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<tabstops>
|
|
||||||
<tabstop>conditionsList</tabstop>
|
|
||||||
<tabstop>conditionAdd</tabstop>
|
|
||||||
<tabstop>conditionRemove</tabstop>
|
|
||||||
<tabstop>conditionTop</tabstop>
|
|
||||||
<tabstop>conditionUp</tabstop>
|
|
||||||
<tabstop>conditionDown</tabstop>
|
|
||||||
<tabstop>conditionBottom</tabstop>
|
|
||||||
<tabstop>actionsList</tabstop>
|
|
||||||
<tabstop>actionAdd</tabstop>
|
|
||||||
<tabstop>actionRemove</tabstop>
|
|
||||||
<tabstop>actionTop</tabstop>
|
|
||||||
<tabstop>actionUp</tabstop>
|
|
||||||
<tabstop>actionDown</tabstop>
|
|
||||||
<tabstop>actionBottom</tabstop>
|
|
||||||
<tabstop>toggleElseActions</tabstop>
|
|
||||||
<tabstop>elseActionsList</tabstop>
|
|
||||||
<tabstop>elseActionAdd</tabstop>
|
|
||||||
<tabstop>elseActionRemove</tabstop>
|
|
||||||
<tabstop>elseActionTop</tabstop>
|
|
||||||
<tabstop>elseActionUp</tabstop>
|
|
||||||
<tabstop>elseActionDown</tabstop>
|
|
||||||
<tabstop>elseActionBottom</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
#include "backup.hpp"
|
#include "backup.hpp"
|
||||||
#include "crash-handler.hpp"
|
|
||||||
#include "log-helper.hpp"
|
#include "log-helper.hpp"
|
||||||
#include "macro-helpers.hpp"
|
#include "macro-helpers.hpp"
|
||||||
#include "obs-module-helper.hpp"
|
#include "obs-module-helper.hpp"
|
||||||
@@ -19,10 +18,8 @@
|
|||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
@@ -43,12 +40,9 @@ AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent)
|
|||||||
{
|
{
|
||||||
switcher->settingsWindowOpened = true;
|
switcher->settingsWindowOpened = true;
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
{
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
switcher->Prune();
|
||||||
switcher->Prune();
|
LoadUI();
|
||||||
LoadUI();
|
|
||||||
}
|
|
||||||
CheckFirstTimeSetup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvSceneSwitcher::~AdvSceneSwitcher()
|
AdvSceneSwitcher::~AdvSceneSwitcher()
|
||||||
@@ -144,6 +138,7 @@ void AdvSceneSwitcher::LoadUI()
|
|||||||
SetTabOrder(ui->tabWidget);
|
SetTabOrder(ui->tabWidget);
|
||||||
SetCurrentTab(ui->tabWidget);
|
SetCurrentTab(ui->tabWidget);
|
||||||
RestoreWindowGeo();
|
RestoreWindowGeo();
|
||||||
|
CheckFirstTimeSetup();
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
@@ -151,7 +146,16 @@ void AdvSceneSwitcher::LoadUI()
|
|||||||
bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
|
bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
|
||||||
{
|
{
|
||||||
auto eventType = event->type();
|
auto eventType = event->type();
|
||||||
if (eventType == QEvent::KeyPress) {
|
if (obj == ui->macroElseActions && eventType == QEvent::Resize) {
|
||||||
|
QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
|
||||||
|
|
||||||
|
if (resizeEvent->size().height() == 0) {
|
||||||
|
SetElseActionsStateToHidden();
|
||||||
|
return QDialog::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetElseActionsStateToVisible();
|
||||||
|
} else if (eventType == QEvent::KeyPress) {
|
||||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
auto pressedKey = keyEvent->key();
|
auto pressedKey = keyEvent->key();
|
||||||
|
|
||||||
@@ -196,21 +200,25 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||||||
|
|
||||||
switcher->m.lock();
|
switcher->m.lock();
|
||||||
if (switcher->VersionChanged(data, g_GIT_SHA1)) {
|
if (switcher->VersionChanged(data, g_GIT_SHA1)) {
|
||||||
AskForBackup(data);
|
auto json = obs_data_get_json(data);
|
||||||
|
static QString jsonQString = json ? json : "";
|
||||||
|
std::thread t([]() {
|
||||||
|
obs_queue_task(
|
||||||
|
OBS_TASK_UI,
|
||||||
|
[](void *) {
|
||||||
|
AskForBackup(jsonQString);
|
||||||
|
},
|
||||||
|
nullptr, false);
|
||||||
|
});
|
||||||
|
t.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
switcher->LoadSettings(data);
|
switcher->LoadSettings(data);
|
||||||
switcher->m.unlock();
|
switcher->m.unlock();
|
||||||
|
|
||||||
if (switcher->stop) {
|
if (!switcher->stop) {
|
||||||
return;
|
switcher->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShouldSkipPluginStartOnUncleanShutdown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switcher->Start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +334,8 @@ void SwitcherData::SetPreconditions()
|
|||||||
{
|
{
|
||||||
// Window title
|
// Window title
|
||||||
lastTitle = currentTitle;
|
lastTitle = currentTitle;
|
||||||
auto title = GetCurrentWindowTitle();
|
std::string title;
|
||||||
|
GetCurrentWindowTitle(title);
|
||||||
for (auto &window : ignoreWindowsSwitches) {
|
for (auto &window : ignoreWindowsSwitches) {
|
||||||
bool equals = (title == window);
|
bool equals = (title == window);
|
||||||
bool matches = false;
|
bool matches = false;
|
||||||
@@ -346,7 +355,7 @@ void SwitcherData::SetPreconditions()
|
|||||||
currentTitle = title;
|
currentTitle = title;
|
||||||
|
|
||||||
// Process name
|
// Process name
|
||||||
currentForegroundProcess = GetForegroundProcessName();
|
GetForegroundProcessName(currentForegroundProcess);
|
||||||
|
|
||||||
// Macro
|
// Macro
|
||||||
InvalidateMacroTempVarValues();
|
InvalidateMacroTempVarValues();
|
||||||
@@ -421,7 +430,7 @@ bool SwitcherData::CheckForMatch(OBSWeakSource &scene,
|
|||||||
|
|
||||||
static void ResetMacros()
|
static void ResetMacros()
|
||||||
{
|
{
|
||||||
for (auto &m : GetTopLevelMacros()) {
|
for (auto &m : GetMacros()) {
|
||||||
ResetMacroRunCount(m.get());
|
ResetMacroRunCount(m.get());
|
||||||
ResetMacroConditionTimers(m.get());
|
ResetMacroConditionTimers(m.get());
|
||||||
}
|
}
|
||||||
@@ -461,13 +470,12 @@ void SwitcherData::Stop()
|
|||||||
SetMacroAbortWait(true);
|
SetMacroAbortWait(true);
|
||||||
GetMacroWaitCV().notify_all();
|
GetMacroWaitCV().notify_all();
|
||||||
GetMacroTransitionCV().notify_all();
|
GetMacroTransitionCV().notify_all();
|
||||||
SignalStopAllMacros();
|
StopAllMacros();
|
||||||
StopAndClearAllActionQueues();
|
StopAndClearAllActionQueues();
|
||||||
CloseAllInputDialogs();
|
CloseAllInputDialogs();
|
||||||
th->wait();
|
th->wait();
|
||||||
delete th;
|
delete th;
|
||||||
th = nullptr;
|
th = nullptr;
|
||||||
WaitForAllMacros();
|
|
||||||
RunStopSteps();
|
RunStopSteps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,8 +519,6 @@ bool SwitcherData::AnySceneTransitionStarted()
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
extern "C" EXPORT void FreeSceneSwitcher()
|
extern "C" EXPORT void FreeSceneSwitcher()
|
||||||
{
|
{
|
||||||
switcher->Stop();
|
|
||||||
|
|
||||||
PlatformCleanup();
|
PlatformCleanup();
|
||||||
RunPluginCleanupSteps();
|
RunPluginCleanupSteps();
|
||||||
|
|
||||||
@@ -541,7 +547,6 @@ static void handleSceneChange()
|
|||||||
}
|
}
|
||||||
|
|
||||||
switcher->checkDefaultSceneTransitions();
|
switcher->checkDefaultSceneTransitions();
|
||||||
switcher->CheckAutoStart();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setLiveTime()
|
static void setLiveTime()
|
||||||
@@ -556,28 +561,18 @@ static void resetLiveTime()
|
|||||||
|
|
||||||
static void checkAutoStartRecording()
|
static void checkAutoStartRecording()
|
||||||
{
|
{
|
||||||
if (switcher->obsIsShuttingDown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switcher->autoStartEvent == SwitcherData::AutoStart::RECORDING ||
|
if (switcher->autoStartEvent == SwitcherData::AutoStart::RECORDING ||
|
||||||
switcher->autoStartEvent ==
|
switcher->autoStartEvent ==
|
||||||
SwitcherData::AutoStart::RECORINDG_OR_STREAMING) {
|
SwitcherData::AutoStart::RECORINDG_OR_STREAMING)
|
||||||
switcher->Start();
|
switcher->Start();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkAutoStartStreaming()
|
static void checkAutoStartStreaming()
|
||||||
{
|
{
|
||||||
if (switcher->obsIsShuttingDown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switcher->autoStartEvent == SwitcherData::AutoStart::STREAMING ||
|
if (switcher->autoStartEvent == SwitcherData::AutoStart::STREAMING ||
|
||||||
switcher->autoStartEvent ==
|
switcher->autoStartEvent ==
|
||||||
SwitcherData::AutoStart::RECORINDG_OR_STREAMING) {
|
SwitcherData::AutoStart::RECORINDG_OR_STREAMING)
|
||||||
switcher->Start();
|
switcher->Start();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleTransitionEnd()
|
static void handleTransitionEnd()
|
||||||
@@ -613,7 +608,7 @@ static void handleSceneCollectionChanging()
|
|||||||
AdvSceneSwitcher::window->close();
|
AdvSceneSwitcher::window->close();
|
||||||
}
|
}
|
||||||
if (!switcher->stop) {
|
if (!switcher->stop) {
|
||||||
switcher->sceneCollectionStop = true;
|
switcher->sceneColletionStop = true;
|
||||||
switcher->Stop();
|
switcher->Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -634,20 +629,13 @@ static void handleSceneCollectionCleanup()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP is also called on
|
|
||||||
// shutdown.
|
|
||||||
// Here we also don't want to clear the settings.
|
|
||||||
if (switcher->obsIsShuttingDown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveSceneSwitcher(nullptr, false, nullptr);
|
SaveSceneSwitcher(nullptr, false, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note to future self:
|
// Note to future self:
|
||||||
// be careful using switcher->m here as there is potential for deadlocks when using
|
// be careful using switcher->m here as there is potential for deadlocks when using
|
||||||
// frontend functions such as obs_frontend_set_current_scene()
|
// frontend functions such as obs_frontend_set_current_scene()
|
||||||
static void OBSEvent(enum obs_frontend_event event, void *)
|
static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
||||||
{
|
{
|
||||||
if (!switcher) {
|
if (!switcher) {
|
||||||
return;
|
return;
|
||||||
@@ -721,54 +709,19 @@ static void LoadPlugins()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool settingsPasswordIsCorrect(QWidget *parent)
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
QString input = QInputDialog::getText(
|
|
||||||
parent,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.title"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.passwordLabel"),
|
|
||||||
QLineEdit::Password, QString(), &ok);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.toStdString() == switcher->settingsLockPassword) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMessageBox::warning(
|
|
||||||
parent,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.title"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.wrongPassword"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenSettingsWindow()
|
void OpenSettingsWindow()
|
||||||
{
|
{
|
||||||
if (switcher->settingsWindowOpened) {
|
if (switcher->settingsWindowOpened) {
|
||||||
AdvSceneSwitcher::window->show();
|
AdvSceneSwitcher::window->show();
|
||||||
AdvSceneSwitcher::window->raise();
|
AdvSceneSwitcher::window->raise();
|
||||||
AdvSceneSwitcher::window->activateWindow();
|
AdvSceneSwitcher::window->activateWindow();
|
||||||
return;
|
} else {
|
||||||
|
AdvSceneSwitcher::window =
|
||||||
|
new AdvSceneSwitcher(static_cast<QMainWindow *>(
|
||||||
|
obs_frontend_get_main_window()));
|
||||||
|
AdvSceneSwitcher::window->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
AdvSceneSwitcher::window->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parent =
|
|
||||||
static_cast<QMainWindow *>(obs_frontend_get_main_window());
|
|
||||||
if (switcher->settingsLockEnabled &&
|
|
||||||
!switcher->settingsLockPassword.empty() &&
|
|
||||||
!settingsPasswordIsCorrect(parent)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdvSceneSwitcher::window = new AdvSceneSwitcher(parent);
|
|
||||||
AdvSceneSwitcher::window->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
AdvSceneSwitcher::window->show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::HighlightMacroSettingsButton(bool enable)
|
void AdvSceneSwitcher::HighlightMacroSettingsButton(bool enable)
|
||||||
@@ -791,21 +744,6 @@ void AdvSceneSwitcher::HighlightMacroSettingsButton(bool enable)
|
|||||||
highlight = HighlightWidget(ui->macroSettings, Qt::green);
|
highlight = HighlightWidget(ui->macroSettings, Qt::green);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::HighlightAction(int idx, QColor color) const
|
|
||||||
{
|
|
||||||
ui->macroEdit->HighlightAction(idx, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::HighlightElseAction(int idx, QColor color) const
|
|
||||||
{
|
|
||||||
ui->macroEdit->HighlightElseAction(idx, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::HighlightCondition(int idx, QColor color) const
|
|
||||||
{
|
|
||||||
ui->macroEdit->HighlightCondition(idx, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HighlightMacroSettingsButton(bool enable)
|
void HighlightMacroSettingsButton(bool enable)
|
||||||
{
|
{
|
||||||
auto window = GetSettingsWindow();
|
auto window = GetSettingsWindow();
|
||||||
@@ -816,6 +754,8 @@ void HighlightMacroSettingsButton(bool enable)
|
|||||||
enable);
|
enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupActionQueues();
|
||||||
|
|
||||||
extern "C" EXPORT void InitSceneSwitcher(obs_module_t *module,
|
extern "C" EXPORT void InitSceneSwitcher(obs_module_t *module,
|
||||||
translateFunc translate)
|
translateFunc translate)
|
||||||
{
|
{
|
||||||
@@ -827,11 +767,12 @@ extern "C" EXPORT void InitSceneSwitcher(obs_module_t *module,
|
|||||||
PlatformInit();
|
PlatformInit();
|
||||||
LoadPlugins();
|
LoadPlugins();
|
||||||
SetupDock();
|
SetupDock();
|
||||||
|
SetupActionQueues();
|
||||||
|
|
||||||
RunPluginInitSteps();
|
RunPluginInitSteps();
|
||||||
|
|
||||||
obs_frontend_add_save_callback(SaveSceneSwitcher, nullptr);
|
obs_frontend_add_save_callback(SaveSceneSwitcher, nullptr);
|
||||||
obs_frontend_add_event_callback(OBSEvent, nullptr);
|
obs_frontend_add_event_callback(OBSEvent, switcher);
|
||||||
|
|
||||||
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
|
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
|
||||||
obs_module_text("AdvSceneSwitcher.pluginName"));
|
obs_module_text("AdvSceneSwitcher.pluginName"));
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "macro-segment-list.hpp"
|
||||||
|
#include "condition-logic.hpp"
|
||||||
|
#include "log-helper.hpp"
|
||||||
|
|
||||||
#include <ui_advanced-scene-switcher.h>
|
#include <ui_advanced-scene-switcher.h>
|
||||||
|
|
||||||
@@ -42,6 +45,7 @@ protected:
|
|||||||
/* --- Begin of general tab section --- */
|
/* --- Begin of general tab section --- */
|
||||||
public:
|
public:
|
||||||
void SetupGeneralTab();
|
void SetupGeneralTab();
|
||||||
|
void UpdateNonMatchingScene(const QString &name);
|
||||||
void SetDeprecationWarnings();
|
void SetDeprecationWarnings();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -54,6 +58,7 @@ public slots:
|
|||||||
void on_startupBehavior_currentIndexChanged(int index);
|
void on_startupBehavior_currentIndexChanged(int index);
|
||||||
void on_logLevel_currentIndexChanged(int index);
|
void on_logLevel_currentIndexChanged(int index);
|
||||||
void on_autoStartEvent_currentIndexChanged(int index);
|
void on_autoStartEvent_currentIndexChanged(int index);
|
||||||
|
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
|
||||||
void on_checkInterval_valueChanged(int value);
|
void on_checkInterval_valueChanged(int value);
|
||||||
void on_tabWidget_currentChanged(int index);
|
void on_tabWidget_currentChanged(int index);
|
||||||
void on_exportSettings_clicked();
|
void on_exportSettings_clicked();
|
||||||
@@ -62,21 +67,18 @@ 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_suppressCrashRecoveryDialog_stateChanged(int state);
|
|
||||||
void on_hideLegacyTabs_stateChanged(int state);
|
void on_hideLegacyTabs_stateChanged(int state);
|
||||||
void on_settingsLock_stateChanged(int state);
|
|
||||||
void on_priorityUp_clicked();
|
void on_priorityUp_clicked();
|
||||||
void on_priorityDown_clicked();
|
void on_priorityDown_clicked();
|
||||||
void on_threadPriority_currentTextChanged(const QString &text);
|
void on_threadPriority_currentTextChanged(const QString &text);
|
||||||
void on_openSetupWizard_clicked();
|
|
||||||
|
|
||||||
/* --- End of legacy tab section --- */
|
/* --- End of legacy tab section --- */
|
||||||
|
|
||||||
/* --- Begin of macro tab section --- */
|
/* --- Begin of macro tab section --- */
|
||||||
public:
|
public:
|
||||||
void SetupMacroTab();
|
void SetupMacroTab();
|
||||||
bool MacroTabIsInFocus();
|
|
||||||
bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name,
|
bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name,
|
||||||
std::string format = "");
|
std::string format = "");
|
||||||
void RemoveMacro(std::shared_ptr<Macro> &);
|
void RemoveMacro(std::shared_ptr<Macro> &);
|
||||||
@@ -84,6 +86,7 @@ public:
|
|||||||
void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
|
void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
|
||||||
std::shared_ptr<Macro> GetSelectedMacro() const;
|
std::shared_ptr<Macro> GetSelectedMacro() const;
|
||||||
std::vector<std::shared_ptr<Macro>> GetSelectedMacros() const;
|
std::vector<std::shared_ptr<Macro>> GetSelectedMacros() const;
|
||||||
|
void SetEditMacro(Macro &m);
|
||||||
void SetMacroEditAreaDisabled(bool) const;
|
void SetMacroEditAreaDisabled(bool) const;
|
||||||
void HighlightAction(int idx, QColor color = QColor(Qt::green)) const;
|
void HighlightAction(int idx, QColor color = QColor(Qt::green)) const;
|
||||||
void HighlightElseAction(int idx,
|
void HighlightElseAction(int idx,
|
||||||
@@ -107,20 +110,107 @@ public slots:
|
|||||||
void on_macroDown_clicked() const;
|
void on_macroDown_clicked() const;
|
||||||
void on_macroName_editingFinished();
|
void on_macroName_editingFinished();
|
||||||
void on_runMacroInParallel_stateChanged(int value) const;
|
void on_runMacroInParallel_stateChanged(int value) const;
|
||||||
void on_actionTriggerMode_currentIndexChanged(int index) const;
|
void on_runMacroOnChange_stateChanged(int value) const;
|
||||||
|
void on_conditionAdd_clicked();
|
||||||
|
void on_conditionRemove_clicked();
|
||||||
|
void on_conditionTop_clicked();
|
||||||
|
void on_conditionUp_clicked();
|
||||||
|
void on_conditionDown_clicked();
|
||||||
|
void on_conditionBottom_clicked();
|
||||||
|
void on_actionAdd_clicked();
|
||||||
|
void on_actionRemove_clicked();
|
||||||
|
void on_actionTop_clicked();
|
||||||
|
void on_actionUp_clicked();
|
||||||
|
void on_actionDown_clicked();
|
||||||
|
void on_actionBottom_clicked();
|
||||||
|
void on_toggleElseActions_clicked() const;
|
||||||
|
void on_elseActionAdd_clicked();
|
||||||
|
void on_elseActionRemove_clicked();
|
||||||
|
void on_elseActionTop_clicked();
|
||||||
|
void on_elseActionUp_clicked();
|
||||||
|
void on_elseActionDown_clicked();
|
||||||
|
void on_elseActionBottom_clicked();
|
||||||
|
void MacroSelectionAboutToChange() const;
|
||||||
void MacroSelectionChanged();
|
void MacroSelectionChanged();
|
||||||
|
void UpMacroSegementHotkey();
|
||||||
|
void DownMacroSegementHotkey();
|
||||||
|
void DeleteMacroSegementHotkey();
|
||||||
void ShowMacroContextMenu(const QPoint &);
|
void ShowMacroContextMenu(const QPoint &);
|
||||||
|
void ShowMacroActionsContextMenu(const QPoint &);
|
||||||
|
void ShowMacroElseActionsContextMenu(const QPoint &);
|
||||||
|
void ShowMacroConditionsContextMenu(const QPoint &);
|
||||||
void CopyMacro();
|
void CopyMacro();
|
||||||
void RenameSelectedMacro();
|
void RenameSelectedMacro();
|
||||||
void ExportMacros() const;
|
void ExportMacros() const;
|
||||||
void ImportMacros();
|
void ImportMacros();
|
||||||
void PauseSelectedMacros();
|
void ExpandAllActions() const;
|
||||||
void UnpauseSelectedMacros();
|
void ExpandAllElseActions() const;
|
||||||
|
void ExpandAllConditions() const;
|
||||||
|
void CollapseAllActions() const;
|
||||||
|
void CollapseAllElseActions() const;
|
||||||
|
void CollapseAllConditions() const;
|
||||||
|
void MinimizeActions() const;
|
||||||
|
void MaximizeActions() const;
|
||||||
|
void MinimizeElseActions() const;
|
||||||
|
void MaximizeElseActions() const;
|
||||||
|
void MinimizeConditions() const;
|
||||||
|
void MaximizeConditions() const;
|
||||||
|
void SetElseActionsStateToHidden() const;
|
||||||
|
void SetElseActionsStateToVisible() const;
|
||||||
|
void MacroActionSelectionChanged(int idx);
|
||||||
|
void MacroActionReorder(int to, int target);
|
||||||
|
void AddMacroAction(Macro *macro, int idx, const std::string &id,
|
||||||
|
obs_data_t *data);
|
||||||
|
void AddMacroAction(int idx);
|
||||||
|
void RemoveMacroAction(int idx);
|
||||||
|
void MoveMacroActionUp(int idx);
|
||||||
|
void MoveMacroActionDown(int idx);
|
||||||
|
void MacroElseActionSelectionChanged(int idx);
|
||||||
|
void MacroElseActionReorder(int to, int target);
|
||||||
|
void AddMacroElseAction(Macro *macro, int idx, const std::string &id,
|
||||||
|
obs_data_t *data);
|
||||||
|
void AddMacroElseAction(int idx);
|
||||||
|
void RemoveMacroElseAction(int idx);
|
||||||
|
void SwapElseActions(Macro *m, int pos1, int pos2);
|
||||||
|
void MoveMacroElseActionUp(int idx);
|
||||||
|
void MoveMacroElseActionDown(int idx);
|
||||||
|
void MacroConditionSelectionChanged(int idx);
|
||||||
|
void MacroConditionReorder(int to, int target);
|
||||||
|
void AddMacroCondition(int idx);
|
||||||
|
void AddMacroCondition(Macro *macro, int idx, const std::string &id,
|
||||||
|
obs_data_t *data, Logic::Type logic);
|
||||||
|
void RemoveMacroCondition(int idx);
|
||||||
|
void MoveMacroConditionUp(int idx);
|
||||||
|
void MoveMacroConditionDown(int idx);
|
||||||
|
void HighlightControls() const;
|
||||||
void HighlightOnChange() const;
|
void HighlightOnChange() const;
|
||||||
void on_macroSettings_clicked();
|
void on_macroSettings_clicked();
|
||||||
|
void CopyMacroSegment();
|
||||||
|
void PasteMacroSegment();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void MacroAdded(const QString &name);
|
||||||
|
void MacroRemoved(const QString &name);
|
||||||
|
void MacroRenamed(const QString &oldName, const QString &newName);
|
||||||
|
void MacroSegmentOrderChanged();
|
||||||
|
void SegmentTempVarsChanged(MacroSegment *);
|
||||||
|
void HighlightMacrosChanged(bool value);
|
||||||
|
|
||||||
|
void ConnectionAdded(const QString &);
|
||||||
|
void ConnectionRenamed(const QString &oldName, const QString &newName);
|
||||||
|
void ConnectionRemoved(const QString &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
|
||||||
|
|
||||||
|
void SetupMacroSegmentSelection(MacroSection type, int idx);
|
||||||
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &);
|
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &);
|
||||||
|
bool MacroTabIsInFocus();
|
||||||
|
|
||||||
|
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
||||||
|
int currentConditionIdx = -1;
|
||||||
|
int currentActionIdx = -1;
|
||||||
|
int currentElseActionIdx = -1;
|
||||||
|
|
||||||
/* --- End of macro tab section --- */
|
/* --- End of macro tab section --- */
|
||||||
|
|
||||||
|
|||||||
353
lib/general.cpp
353
lib/general.cpp
@@ -1,28 +1,22 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
#include "crash-handler.hpp"
|
|
||||||
#include "file-selection.hpp"
|
#include "file-selection.hpp"
|
||||||
#include "filter-combo-box.hpp"
|
#include "filter-combo-box.hpp"
|
||||||
#include "first-run-wizard.hpp"
|
|
||||||
#include "layout-helpers.hpp"
|
#include "layout-helpers.hpp"
|
||||||
#include "macro-helpers.hpp"
|
|
||||||
#include "macro-search.hpp"
|
|
||||||
#include "macro-settings.hpp"
|
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "path-helpers.hpp"
|
#include "path-helpers.hpp"
|
||||||
|
#include "selection-helpers.hpp"
|
||||||
#include "source-helpers.hpp"
|
#include "source-helpers.hpp"
|
||||||
#include "splitter-helpers.hpp"
|
#include "splitter-helpers.hpp"
|
||||||
#include "status-control.hpp"
|
#include "status-control.hpp"
|
||||||
#include "switcher-data.hpp"
|
#include "switcher-data.hpp"
|
||||||
#include "tab-helpers.hpp"
|
#include "tab-helpers.hpp"
|
||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
#include "variable.hpp"
|
#include "variable.hpp"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -31,6 +25,15 @@ void AdvSceneSwitcher::reject()
|
|||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::UpdateNonMatchingScene(const QString &name)
|
||||||
|
{
|
||||||
|
OBSSourceAutoRelease scene =
|
||||||
|
obs_get_source_by_name(name.toUtf8().constData());
|
||||||
|
OBSWeakSourceAutoRelease ws = obs_source_get_weak_source(scene);
|
||||||
|
|
||||||
|
switcher->nonMatchingScene = ws;
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_noMatchDontSwitch_clicked()
|
void AdvSceneSwitcher::on_noMatchDontSwitch_clicked()
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -52,6 +55,7 @@ void AdvSceneSwitcher::on_noMatchSwitch_clicked()
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->switchIfNotMatching = NoMatchBehavior::SWITCH;
|
switcher->switchIfNotMatching = NoMatchBehavior::SWITCH;
|
||||||
ui->noMatchSwitchScene->setEnabled(true);
|
ui->noMatchSwitchScene->setEnabled(true);
|
||||||
|
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
|
||||||
ui->randomDisabledWarning->setVisible(true);
|
ui->randomDisabledWarning->setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +131,17 @@ void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
|||||||
switcher->autoStartEvent = static_cast<SwitcherData::AutoStart>(index);
|
switcher->autoStartEvent = static_cast<SwitcherData::AutoStart>(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
|
||||||
|
const QString &text)
|
||||||
|
{
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
|
UpdateNonMatchingScene(text);
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_checkInterval_valueChanged(int value)
|
void AdvSceneSwitcher::on_checkInterval_valueChanged(int value)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -148,7 +163,7 @@ void AdvSceneSwitcher::closeEvent(QCloseEvent *)
|
|||||||
switcher->windowSize = this->size();
|
switcher->windowSize = this->size();
|
||||||
switcher->macroListMacroEditSplitterPosition =
|
switcher->macroListMacroEditSplitterPosition =
|
||||||
ui->macroListMacroEditSplitter->sizes();
|
ui->macroListMacroEditSplitter->sizes();
|
||||||
ui->macroEdit->SetMacro(nullptr); // Trigger saving of splitter states
|
MacroSelectionAboutToChange(); // Trigger saving of splitter states
|
||||||
|
|
||||||
obs_frontend_save();
|
obs_frontend_save();
|
||||||
}
|
}
|
||||||
@@ -190,6 +205,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) {
|
||||||
@@ -199,15 +224,6 @@ void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
|||||||
switcher->warnPluginLoadFailure = state;
|
switcher->warnPluginLoadFailure = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_suppressCrashRecoveryDialog_stateChanged(int state)
|
|
||||||
{
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSuppressCrashDialog(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isLegacyTab(const QString &name)
|
static bool isLegacyTab(const QString &name)
|
||||||
{
|
{
|
||||||
return name == obs_module_text(
|
return name == obs_module_text(
|
||||||
@@ -247,64 +263,6 @@ void AdvSceneSwitcher::on_hideLegacyTabs_stateChanged(int state)
|
|||||||
ui->priorityBox->setVisible(!switcher->hideLegacyTabs);
|
ui->priorityBox->setVisible(!switcher->hideLegacyTabs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_settingsLock_stateChanged(int state)
|
|
||||||
{
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!state) {
|
|
||||||
switcher->settingsLockEnabled = false;
|
|
||||||
switcher->settingsLockPassword = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok;
|
|
||||||
QString newPassword = QInputDialog::getText(
|
|
||||||
this,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.title"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.newPasswordLabel"),
|
|
||||||
QLineEdit::Password, QString(), &ok);
|
|
||||||
|
|
||||||
const auto disablePassword = [this]() {
|
|
||||||
QSignalBlocker blocker(ui->settingsLock);
|
|
||||||
ui->settingsLock->setChecked(false);
|
|
||||||
ui->settingsLock->setCheckState(Qt::Unchecked);
|
|
||||||
switcher->settingsLockEnabled = false;
|
|
||||||
switcher->settingsLockPassword = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!ok || newPassword.isEmpty()) {
|
|
||||||
disablePassword();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString confirm = QInputDialog::getText(
|
|
||||||
this,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.title"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.confirmPasswordLabel"),
|
|
||||||
QLineEdit::Password, QString(), &ok);
|
|
||||||
if (!ok || newPassword != confirm) {
|
|
||||||
if (ok) {
|
|
||||||
QMessageBox::warning(
|
|
||||||
this,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.title"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.settingsLock.passwordMismatch"));
|
|
||||||
}
|
|
||||||
disablePassword();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switcher->settingsLockEnabled = true;
|
|
||||||
switcher->settingsLockPassword = newPassword.toStdString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::SetDeprecationWarnings()
|
void AdvSceneSwitcher::SetDeprecationWarnings()
|
||||||
{
|
{
|
||||||
QString toolTip =
|
QString toolTip =
|
||||||
@@ -432,50 +390,14 @@ void AdvSceneSwitcher::RestoreWindowGeo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void renameMacroIfNecessary(const std::shared_ptr<Macro> ¯o)
|
|
||||||
{
|
|
||||||
if (!GetMacroByName(macro->Name().c_str())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto name = macro->Name();
|
|
||||||
int i = 2;
|
|
||||||
while (GetMacroByName((name + " " + std::to_string(i)).c_str())) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
macro->SetName(name + " " + std::to_string(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::CheckFirstTimeSetup()
|
void AdvSceneSwitcher::CheckFirstTimeSetup()
|
||||||
{
|
{
|
||||||
if (!IsFirstRun() || !GetTopLevelMacros().empty()) {
|
if (switcher->firstBoot && !switcher->disableHints) {
|
||||||
return;
|
switcher->firstBoot = false;
|
||||||
|
DisplayMessage(
|
||||||
|
obs_module_text("AdvSceneSwitcher.firstBootMessage"));
|
||||||
|
switcher->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wasSkipped = false;
|
|
||||||
auto macro = wiz::FirstRunWizard::ShowWizard(this, &wasSkipped);
|
|
||||||
if (macro) {
|
|
||||||
renameMacroIfNecessary(macro);
|
|
||||||
QTimer::singleShot(0, this,
|
|
||||||
[this, macro]() { ui->macros->Add(macro); });
|
|
||||||
}
|
|
||||||
if (wasSkipped) {
|
|
||||||
ui->alwaysShowFeatureTabs->setChecked(true);
|
|
||||||
}
|
|
||||||
switcher->Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_openSetupWizard_clicked()
|
|
||||||
{
|
|
||||||
auto macro = wiz::FirstRunWizard::ShowWizard(this);
|
|
||||||
if (!macro) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
renameMacroIfNecessary(macro);
|
|
||||||
ui->macros->Add(macro);
|
|
||||||
ui->tabWidget->setCurrentWidget(ui->macroTab);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
|
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
|
||||||
@@ -529,13 +451,16 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New post load steps to be declared during load
|
// New post load steps to be declared during load
|
||||||
ClearPostLoadSteps();
|
postLoadSteps.clear();
|
||||||
|
|
||||||
// Needs to be loaded before any entries which might rely on scene group
|
// Needs to be loaded before any entries which might rely on scene group
|
||||||
// selections to be available.
|
// selections to be available.
|
||||||
loadSceneGroups(obj);
|
loadSceneGroups(obj);
|
||||||
|
LoadVariables(obj);
|
||||||
|
|
||||||
RunLoadSteps(obj);
|
for (const auto &func : loadSteps) {
|
||||||
|
func(obj);
|
||||||
|
}
|
||||||
|
|
||||||
LoadMacros(obj);
|
LoadMacros(obj);
|
||||||
LoadGlobalMacroSettings(obj);
|
LoadGlobalMacroSettings(obj);
|
||||||
@@ -556,7 +481,7 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
|||||||
LoadHotkeys(obj);
|
LoadHotkeys(obj);
|
||||||
LoadUISettings(obj);
|
LoadUISettings(obj);
|
||||||
|
|
||||||
RunAndClearPostLoadSteps();
|
RunPostLoadSteps();
|
||||||
|
|
||||||
// Reset on startup and scene collection change
|
// Reset on startup and scene collection change
|
||||||
ResetLastOpenedTab();
|
ResetLastOpenedTab();
|
||||||
@@ -572,6 +497,7 @@ void SwitcherData::SaveSettings(obs_data_t *obj)
|
|||||||
saveSceneGroups(obj);
|
saveSceneGroups(obj);
|
||||||
SaveMacros(obj);
|
SaveMacros(obj);
|
||||||
SaveGlobalMacroSettings(obj);
|
SaveGlobalMacroSettings(obj);
|
||||||
|
SaveVariables(obj);
|
||||||
saveWindowTitleSwitches(obj);
|
saveWindowTitleSwitches(obj);
|
||||||
saveScreenRegionSwitches(obj);
|
saveScreenRegionSwitches(obj);
|
||||||
savePauseSwitches(obj);
|
savePauseSwitches(obj);
|
||||||
@@ -590,16 +516,18 @@ void SwitcherData::SaveSettings(obs_data_t *obj)
|
|||||||
SaveUISettings(obj);
|
SaveUISettings(obj);
|
||||||
SaveVersion(obj, g_GIT_SHA1);
|
SaveVersion(obj, g_GIT_SHA1);
|
||||||
|
|
||||||
RunSaveSteps(obj);
|
for (const auto &func : saveSteps) {
|
||||||
|
func(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
obs_data_set_int(obj, "interval", interval);
|
obs_data_set_int(obj, "interval", interval);
|
||||||
|
|
||||||
OBSDataAutoRelease noMatchScene = obs_data_create();
|
std::string nonMatchingSceneName = GetWeakSourceName(nonMatchingScene);
|
||||||
nonMatchingScene.Save(noMatchScene);
|
obs_data_set_string(obj, "non_matching_scene",
|
||||||
obs_data_set_obj(obj, "noMatchScene", noMatchScene);
|
nonMatchingSceneName.c_str());
|
||||||
obs_data_set_int(obj, "switch_if_not_matching",
|
obs_data_set_int(obj, "switch_if_not_matching",
|
||||||
static_cast<int>(switchIfNotMatching));
|
static_cast<int>(switchIfNotMatching));
|
||||||
noMatchDelay.Save(obj, "noMatchDelay");
|
noMatchDelay.Save(obj, "noMatchDelay");
|
||||||
@@ -607,18 +535,13 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
|||||||
cooldown.Save(obj, "cooldown");
|
cooldown.Save(obj, "cooldown");
|
||||||
obs_data_set_bool(obj, "enableCooldown", enableCooldown);
|
obs_data_set_bool(obj, "enableCooldown", enableCooldown);
|
||||||
|
|
||||||
obs_data_set_bool(obj, "active", sceneCollectionStop ? true : !stop);
|
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
|
||||||
sceneCollectionStop = false;
|
sceneColletionStop = false;
|
||||||
obs_data_set_int(obj, "startup_behavior",
|
obs_data_set_int(obj, "startup_behavior",
|
||||||
static_cast<int>(startupBehavior));
|
static_cast<int>(startupBehavior));
|
||||||
|
|
||||||
OBSDataAutoRelease autoStart = obs_data_create();
|
obs_data_set_int(obj, "autoStartEvent",
|
||||||
obs_data_set_int(autoStart, "event", static_cast<int>(autoStartEvent));
|
static_cast<int>(autoStartEvent));
|
||||||
obs_data_set_bool(autoStart, "useAutoStartScene", useAutoStartScene);
|
|
||||||
autoStartScene.Save(autoStart);
|
|
||||||
autoStartSceneName.Save(autoStart, "name");
|
|
||||||
autoStartSceneRegex.Save(autoStart);
|
|
||||||
obs_data_set_obj(obj, "autoStart", autoStart);
|
|
||||||
|
|
||||||
SaveLogLevel(obj);
|
SaveLogLevel(obj);
|
||||||
|
|
||||||
@@ -627,11 +550,10 @@ 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);
|
||||||
obs_data_set_bool(obj, "settingsLockEnabled", settingsLockEnabled);
|
|
||||||
obs_data_set_string(obj, "settingsLockPassword",
|
|
||||||
settingsLockPassword.c_str());
|
|
||||||
|
|
||||||
SaveFunctionPriorities(obj, functionNamesByPriority);
|
SaveFunctionPriorities(obj, functionNamesByPriority);
|
||||||
|
|
||||||
@@ -654,14 +576,9 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
static_cast<int>(NoMatchBehavior::NO_SWITCH));
|
static_cast<int>(NoMatchBehavior::NO_SWITCH));
|
||||||
switchIfNotMatching = static_cast<NoMatchBehavior>(
|
switchIfNotMatching = static_cast<NoMatchBehavior>(
|
||||||
obs_data_get_int(obj, "switch_if_not_matching"));
|
obs_data_get_int(obj, "switch_if_not_matching"));
|
||||||
|
std::string nonMatchingSceneName =
|
||||||
if (obs_data_has_user_value(obj, "noMatchScene")) {
|
obs_data_get_string(obj, "non_matching_scene");
|
||||||
OBSDataAutoRelease noMatchScene =
|
nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str());
|
||||||
obs_data_get_obj(obj, "noMatchScene");
|
|
||||||
nonMatchingScene.Load(noMatchScene);
|
|
||||||
} else {
|
|
||||||
nonMatchingScene.Load(obj, "non_matching_scene");
|
|
||||||
}
|
|
||||||
noMatchDelay.Load(obj, "noMatchDelay");
|
noMatchDelay.Load(obj, "noMatchDelay");
|
||||||
|
|
||||||
cooldown.Load(obj, "cooldown");
|
cooldown.Load(obj, "cooldown");
|
||||||
@@ -682,15 +599,8 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSDataAutoRelease autoStart = obs_data_get_obj(obj, "autoStart");
|
autoStartEvent =
|
||||||
autoStartEvent = static_cast<AutoStart>(
|
static_cast<AutoStart>(obs_data_get_int(obj, "autoStartEvent"));
|
||||||
obs_data_has_user_value(obj, "autoStart")
|
|
||||||
? obs_data_get_int(autoStart, "event")
|
|
||||||
: obs_data_get_int(obj, "autoStartEvent"));
|
|
||||||
useAutoStartScene = obs_data_get_bool(autoStart, "useAutoStartScene");
|
|
||||||
autoStartScene.Load(autoStart);
|
|
||||||
autoStartSceneName.Load(autoStart, "name");
|
|
||||||
autoStartSceneRegex.Load(autoStart);
|
|
||||||
|
|
||||||
LoadLogLevel(obj);
|
LoadLogLevel(obj);
|
||||||
|
|
||||||
@@ -699,12 +609,12 @@ 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);
|
||||||
hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs");
|
hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs");
|
||||||
settingsLockEnabled = obs_data_get_bool(obj, "settingsLockEnabled");
|
|
||||||
settingsLockPassword = obs_data_get_string(obj, "settingsLockPassword");
|
|
||||||
|
|
||||||
SetDefaultFunctionPriorities(obj);
|
SetDefaultFunctionPriorities(obj);
|
||||||
LoadFunctionPriorities(obj, functionNamesByPriority);
|
LoadFunctionPriorities(obj, functionNamesByPriority);
|
||||||
@@ -770,10 +680,10 @@ void SwitcherData::CheckNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto noMatchScene = nonMatchingScene.GetScene(false);
|
if (switchIfNotMatching == NoMatchBehavior::SWITCH &&
|
||||||
if (switchIfNotMatching == NoMatchBehavior::SWITCH && noMatchScene) {
|
nonMatchingScene) {
|
||||||
match = true;
|
match = true;
|
||||||
scene = noMatchScene;
|
scene = nonMatchingScene;
|
||||||
transition = nullptr;
|
transition = nullptr;
|
||||||
}
|
}
|
||||||
if (switchIfNotMatching == NoMatchBehavior::RANDOM_SWITCH) {
|
if (switchIfNotMatching == NoMatchBehavior::RANDOM_SWITCH) {
|
||||||
@@ -781,27 +691,6 @@ void SwitcherData::CheckNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::CheckAutoStart()
|
|
||||||
{
|
|
||||||
if (!useAutoStartScene) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool shouldStartPlugin = false;
|
|
||||||
if (autoStartSceneRegex.Enabled()) {
|
|
||||||
const auto currentSceneName = GetWeakSourceName(currentScene);
|
|
||||||
shouldStartPlugin = autoStartSceneRegex.Matches(
|
|
||||||
currentSceneName, autoStartSceneName);
|
|
||||||
} else {
|
|
||||||
shouldStartPlugin = autoStartScene.GetScene(false) ==
|
|
||||||
currentScene;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldStartPlugin) {
|
|
||||||
Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SwitcherData::checkSwitchCooldown(bool &match)
|
void SwitcherData::checkSwitchCooldown(bool &match)
|
||||||
{
|
{
|
||||||
if (!match || !enableCooldown) {
|
if (!match || !enableCooldown) {
|
||||||
@@ -944,7 +833,7 @@ static void setupGeneralTabInactiveWarning(QTabWidget *tabs)
|
|||||||
inactiveTimer->start();
|
inactiveTimer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::SetCheckIntervalTooLowVisibility() const
|
void advss::AdvSceneSwitcher::SetCheckIntervalTooLowVisibility() const
|
||||||
{
|
{
|
||||||
auto macro = GetMacroWithInvalidConditionInterval();
|
auto macro = GetMacroWithInvalidConditionInterval();
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
@@ -968,6 +857,8 @@ void AdvSceneSwitcher::SetCheckIntervalTooLowVisibility() const
|
|||||||
|
|
||||||
void AdvSceneSwitcher::SetupGeneralTab()
|
void AdvSceneSwitcher::SetupGeneralTab()
|
||||||
{
|
{
|
||||||
|
PopulateSceneSelection(ui->noMatchSwitchScene, false);
|
||||||
|
|
||||||
if (switcher->switchIfNotMatching == NoMatchBehavior::SWITCH) {
|
if (switcher->switchIfNotMatching == NoMatchBehavior::SWITCH) {
|
||||||
ui->noMatchSwitch->setChecked(true);
|
ui->noMatchSwitch->setChecked(true);
|
||||||
ui->noMatchSwitchScene->setEnabled(true);
|
ui->noMatchSwitchScene->setEnabled(true);
|
||||||
@@ -979,17 +870,8 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
ui->noMatchRandomSwitch->setChecked(true);
|
ui->noMatchRandomSwitch->setChecked(true);
|
||||||
ui->noMatchSwitchScene->setEnabled(false);
|
ui->noMatchSwitchScene->setEnabled(false);
|
||||||
}
|
}
|
||||||
ui->noMatchSwitchScene->SetScene(switcher->nonMatchingScene);
|
ui->noMatchSwitchScene->setCurrentText(
|
||||||
ui->noMatchSwitchScene->LockToMainCanvas();
|
GetWeakSourceName(switcher->nonMatchingScene).c_str());
|
||||||
|
|
||||||
connect(ui->noMatchSwitchScene, &SceneSelectionWidget::SceneChanged,
|
|
||||||
this, [this](const SceneSelection &scene) {
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switcher->nonMatchingScene = scene;
|
|
||||||
});
|
|
||||||
|
|
||||||
DurationSelection *noMatchDelay = new DurationSelection();
|
DurationSelection *noMatchDelay = new DurationSelection();
|
||||||
noMatchDelay->SetDuration(switcher->noMatchDelay);
|
noMatchDelay->SetDuration(switcher->noMatchDelay);
|
||||||
@@ -1024,10 +906,11 @@ 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->suppressCrashRecoveryDialog->setChecked(GetSuppressCrashDialog());
|
|
||||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||||
ui->settingsLock->setChecked(switcher->settingsLockEnabled);
|
|
||||||
|
|
||||||
populatePriorityFunctionList(ui->priorityList);
|
populatePriorityFunctionList(ui->priorityList);
|
||||||
populateThreadPriorityList(ui->threadPriority);
|
populateThreadPriorityList(ui->threadPriority);
|
||||||
@@ -1039,88 +922,6 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
populateAutoStartEventSelection(ui->autoStartEvent);
|
populateAutoStartEventSelection(ui->autoStartEvent);
|
||||||
ui->autoStartEvent->setCurrentIndex(
|
ui->autoStartEvent->setCurrentIndex(
|
||||||
static_cast<int>(switcher->autoStartEvent));
|
static_cast<int>(switcher->autoStartEvent));
|
||||||
ui->autoStartSceneEnable->setChecked(switcher->useAutoStartScene);
|
|
||||||
ui->autoStartScene->SetScene(switcher->autoStartScene);
|
|
||||||
ui->autoStartScene->LockToMainCanvas();
|
|
||||||
ui->autoStartSceneName->setText(switcher->autoStartSceneName);
|
|
||||||
ui->autoStartSceneNameRegex->SetRegexConfig(
|
|
||||||
switcher->autoStartSceneRegex);
|
|
||||||
|
|
||||||
const auto setupAutoStartSceneLayoutVisibility = [this](bool useRegex) {
|
|
||||||
ui->autoStartSceneName->setVisible(useRegex);
|
|
||||||
ui->autoStartScene->setVisible(!useRegex);
|
|
||||||
if (useRegex) {
|
|
||||||
RemoveStretchIfPresent(ui->autoStartSceneLayout);
|
|
||||||
} else {
|
|
||||||
AddStretchIfNecessary(ui->autoStartSceneLayout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
setupAutoStartSceneLayoutVisibility(
|
|
||||||
switcher->autoStartSceneRegex.Enabled());
|
|
||||||
|
|
||||||
const auto setupAutoStartSceneWidgetState =
|
|
||||||
[this](bool useAutoStartScene) {
|
|
||||||
ui->autoStartScene->setEnabled(useAutoStartScene);
|
|
||||||
ui->autoStartSceneName->setEnabled(useAutoStartScene);
|
|
||||||
ui->autoStartSceneNameRegex->setEnabled(
|
|
||||||
useAutoStartScene);
|
|
||||||
};
|
|
||||||
setupAutoStartSceneWidgetState(switcher->useAutoStartScene);
|
|
||||||
|
|
||||||
connect(ui->autoStartSceneEnable, &QCheckBox::stateChanged, this,
|
|
||||||
[this, setupAutoStartSceneWidgetState](int enabled) {
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switcher->useAutoStartScene = enabled;
|
|
||||||
setupAutoStartSceneWidgetState(enabled);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(ui->autoStartScene, &SceneSelectionWidget::SceneChanged, this,
|
|
||||||
[this](const SceneSelection &scene) {
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switcher->autoStartScene = scene;
|
|
||||||
switcher->CheckAutoStart();
|
|
||||||
});
|
|
||||||
connect(ui->autoStartSceneName, &VariableLineEdit::editingFinished,
|
|
||||||
this, [this]() {
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switcher->autoStartSceneName =
|
|
||||||
ui->autoStartSceneName->text().toStdString();
|
|
||||||
switcher->CheckAutoStart();
|
|
||||||
});
|
|
||||||
connect(ui->autoStartSceneNameRegex,
|
|
||||||
&RegexConfigWidget::RegexConfigChanged, this,
|
|
||||||
[this, setupAutoStartSceneLayoutVisibility](
|
|
||||||
const RegexConfig ®ex) {
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switcher->autoStartSceneRegex = regex;
|
|
||||||
setupAutoStartSceneLayoutVisibility(regex.Enabled());
|
|
||||||
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);
|
||||||
@@ -1141,8 +942,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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,11 +92,12 @@ bool SwitcherData::checkExeSwitch(OBSWeakSource &scene,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string title = switcher->currentTitle;
|
std::string title = switcher->currentTitle;
|
||||||
|
QStringList runningProcesses;
|
||||||
bool ignored = false;
|
bool ignored = false;
|
||||||
bool match = false;
|
bool match = false;
|
||||||
|
|
||||||
// Check for match
|
// Check for match
|
||||||
const auto runningProcesses = GetProcessList();
|
GetProcessList(runningProcesses);
|
||||||
for (ExecutableSwitch &s : executableSwitches) {
|
for (ExecutableSwitch &s : executableSwitches) {
|
||||||
if (!s.initialized()) {
|
if (!s.initialized()) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -178,19 +178,47 @@ void AdvSceneSwitcher::on_ignoreWindows_currentRowChanged(int idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool windowInfoMatchesSwitch(const WindowInfo &info,
|
void checkWindowTitleSwitchDirect(WindowSwitch &s,
|
||||||
const WindowSwitch &s)
|
std::string ¤tWindowTitle, bool &match,
|
||||||
|
OBSWeakSource &scene,
|
||||||
|
OBSWeakSource &transition)
|
||||||
{
|
{
|
||||||
if (s.focus && !info.focused) {
|
bool focus = (!s.focus || s.window == currentWindowTitle);
|
||||||
return false;
|
bool fullscreen = (!s.fullscreen || IsFullscreen(s.window));
|
||||||
|
bool max = (!s.maximized || IsMaximized(s.window));
|
||||||
|
|
||||||
|
if (focus && fullscreen && max) {
|
||||||
|
match = true;
|
||||||
|
scene = s.getScene();
|
||||||
|
transition = s.transition;
|
||||||
}
|
}
|
||||||
if (s.fullscreen && !info.fullscreen) {
|
}
|
||||||
return false;
|
|
||||||
|
void checkWindowTitleSwitchRegex(WindowSwitch &s,
|
||||||
|
std::string ¤tWindowTitle,
|
||||||
|
std::vector<std::string> windowList,
|
||||||
|
bool &match, OBSWeakSource &scene,
|
||||||
|
OBSWeakSource &transition)
|
||||||
|
{
|
||||||
|
for (auto &window : windowList) {
|
||||||
|
try {
|
||||||
|
std::regex expr(s.window);
|
||||||
|
if (!std::regex_match(window, expr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} catch (const std::regex_error &) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool focus = (!s.focus || window == currentWindowTitle);
|
||||||
|
bool fullscreen = (!s.fullscreen || IsFullscreen(window));
|
||||||
|
bool max = (!s.maximized || IsMaximized(window));
|
||||||
|
|
||||||
|
if (focus && fullscreen && max) {
|
||||||
|
match = true;
|
||||||
|
scene = s.getScene();
|
||||||
|
transition = s.transition;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (s.maximized && !info.maximized) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwitcherData::checkWindowTitleSwitch(OBSWeakSource &scene,
|
bool SwitcherData::checkWindowTitleSwitch(OBSWeakSource &scene,
|
||||||
@@ -200,37 +228,24 @@ bool SwitcherData::checkWindowTitleSwitch(OBSWeakSource &scene,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string currentWindowTitle = switcher->currentTitle;
|
||||||
bool match = false;
|
bool match = false;
|
||||||
|
std::vector<std::string> windowList;
|
||||||
WindowQueryOptions options;
|
GetWindowList(windowList);
|
||||||
options.focus = true;
|
|
||||||
options.fullscreen = true;
|
|
||||||
options.maximized = true;
|
|
||||||
const auto windows = GetWindows(options);
|
|
||||||
|
|
||||||
for (WindowSwitch &s : windowSwitches) {
|
for (WindowSwitch &s : windowSwitches) {
|
||||||
if (!s.initialized()) {
|
if (!s.initialized()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &info : windows) {
|
if (std::find(windowList.begin(), windowList.end(), s.window) !=
|
||||||
bool titleMatch = false;
|
windowList.end()) {
|
||||||
try {
|
checkWindowTitleSwitchDirect(s, currentWindowTitle,
|
||||||
std::regex expr(s.window);
|
match, scene, transition);
|
||||||
titleMatch = info.title == s.window ||
|
} else {
|
||||||
std::regex_match(info.title, expr);
|
checkWindowTitleSwitchRegex(s, currentWindowTitle,
|
||||||
} catch (const std::regex_error &) {
|
windowList, match, scene,
|
||||||
titleMatch = info.title == s.window;
|
transition);
|
||||||
}
|
|
||||||
|
|
||||||
if (!titleMatch || !windowInfoMatchesSwitch(info, s)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
match = true;
|
|
||||||
scene = s.getScene();
|
|
||||||
transition = s.transition;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
|
|||||||
@@ -32,9 +32,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <climits>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "kwin-helpers.h"
|
#include "kwin-helpers.h"
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
@@ -236,89 +233,28 @@ std::string getWindowName(Window window)
|
|||||||
return windowTitle;
|
return windowTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<WindowInfo> GetWindows(const WindowQueryOptions &options)
|
void GetWindowList(std::vector<std::string> &windows)
|
||||||
{
|
{
|
||||||
const std::string foregroundTitle = GetCurrentWindowTitle();
|
windows.resize(0);
|
||||||
const auto topLevel = getTopLevelWindows();
|
for (auto window : getTopLevelWindows()) {
|
||||||
auto display = disp();
|
|
||||||
|
|
||||||
std::vector<WindowInfo> result;
|
|
||||||
result.reserve(topLevel.size());
|
|
||||||
|
|
||||||
for (auto window : topLevel) {
|
|
||||||
auto name = getWindowName(window);
|
auto name = getWindowName(window);
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
windows.emplace_back(name);
|
||||||
WindowInfo info;
|
|
||||||
info.title = name;
|
|
||||||
|
|
||||||
if (options.focus) {
|
|
||||||
info.focused = (name == foregroundTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.fullscreen || options.maximized) {
|
|
||||||
QStringList states = getStates(window);
|
|
||||||
if (options.fullscreen) {
|
|
||||||
info.fullscreen = states.contains(
|
|
||||||
"_NET_WM_STATE_FULLSCREEN");
|
|
||||||
}
|
|
||||||
if (options.maximized) {
|
|
||||||
info.maximized =
|
|
||||||
states.contains(
|
|
||||||
"_NET_WM_STATE_MAXIMIZED_VERT") &&
|
|
||||||
states.contains(
|
|
||||||
"_NET_WM_STATE_MAXIMIZED_HORZ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.geometry && display) {
|
|
||||||
XWindowAttributes attrs;
|
|
||||||
if (XGetWindowAttributes(display, window, &attrs)) {
|
|
||||||
int x = 0;
|
|
||||||
int y = 0;
|
|
||||||
Window child;
|
|
||||||
XTranslateCoordinates(
|
|
||||||
display, window,
|
|
||||||
DefaultRootWindow(display), 0, 0, &x,
|
|
||||||
&y, &child);
|
|
||||||
info.x = x;
|
|
||||||
info.y = y;
|
|
||||||
info.width = attrs.width;
|
|
||||||
info.height = attrs.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// windowClass and text not implemented on Linux
|
|
||||||
result.emplace_back(std::move(info));
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When KWin compat is active, native Wayland windows are not tracked by
|
void GetWindowList(QStringList &windows)
|
||||||
// X11 and therefore do not appear in the list above. Merge in any window
|
{
|
||||||
// reported by KWin that is not already present (matched by title) so that
|
windows.clear();
|
||||||
// title and focus conditions work for native Wayland windows.
|
for (auto window : getTopLevelWindows()) {
|
||||||
if (KWin) {
|
auto name = getWindowName(window);
|
||||||
for (const auto &[pid, title] :
|
if (name.empty()) {
|
||||||
FocusNotifier::getWindowList()) {
|
continue;
|
||||||
bool found = false;
|
|
||||||
for (const auto &info : result) {
|
|
||||||
if (info.title == title) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
WindowInfo waylandWindow;
|
|
||||||
waylandWindow.title = title;
|
|
||||||
waylandWindow.focused =
|
|
||||||
(title == foregroundTitle);
|
|
||||||
result.emplace_back(std::move(waylandWindow));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
windows << QString::fromStdString(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int getActiveWindow(Window *&window)
|
int getActiveWindow(Window *&window)
|
||||||
@@ -342,24 +278,91 @@ int getActiveWindow(Window *&window)
|
|||||||
&bytes, (uint8_t **)&window);
|
&bytes, (uint8_t **)&window);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetCurrentWindowTitle()
|
void GetCurrentWindowTitle(std::string &title)
|
||||||
{
|
{
|
||||||
if (KWin) {
|
if (KWin) {
|
||||||
return FocusNotifier::getActiveWindowTitle();
|
title = FocusNotifier::getActiveWindowTitle();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window *data = 0;
|
Window *data = 0;
|
||||||
if (getActiveWindow(data) != Success || !data) {
|
if (getActiveWindow(data) != Success || !data) {
|
||||||
return {};
|
return;
|
||||||
}
|
}
|
||||||
if (!data[0]) {
|
if (!data[0]) {
|
||||||
XFree(data);
|
XFree(data);
|
||||||
return {};
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto name = getWindowName(data[0]);
|
auto name = getWindowName(data[0]);
|
||||||
XFree(data);
|
XFree(data);
|
||||||
return name;
|
|
||||||
|
if (name.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
title = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool windowStatesAreSet(const std::string &windowTitle,
|
||||||
|
std::vector<QString> &expectedStates)
|
||||||
|
{
|
||||||
|
if (!ewmhIsSupported()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Window> windows = getTopLevelWindows();
|
||||||
|
for (auto &window : windows) {
|
||||||
|
auto name = getWindowName(window);
|
||||||
|
if (name.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equals = windowTitle == name;
|
||||||
|
bool matches = QString::fromStdString(name).contains(
|
||||||
|
QRegularExpression(
|
||||||
|
QString::fromStdString(windowTitle)));
|
||||||
|
|
||||||
|
if (!(equals || matches)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList states = getStates(window);
|
||||||
|
if (states.isEmpty()) {
|
||||||
|
if (expectedStates.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &state : expectedStates) {
|
||||||
|
if (!states.contains(state)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsMaximized(const std::string &title)
|
||||||
|
{
|
||||||
|
std::vector<QString> states;
|
||||||
|
states.emplace_back("_NET_WM_STATE_MAXIMIZED_VERT");
|
||||||
|
states.emplace_back("_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||||
|
return windowStatesAreSet(title, states);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsFullscreen(const std::string &title)
|
||||||
|
{
|
||||||
|
std::vector<QString> states;
|
||||||
|
states.emplace_back("_NET_WM_STATE_FULLSCREEN");
|
||||||
|
return windowStatesAreSet(title, states);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> GetTextInWindow(const std::string &)
|
||||||
|
{
|
||||||
|
// Not implemented
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getProcessListProcps(QStringList &processes)
|
static void getProcessListProcps(QStringList &processes)
|
||||||
@@ -406,17 +409,16 @@ static void getProcessListProcps2(QStringList &processes)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GetProcessList()
|
void GetProcessList(QStringList &processes)
|
||||||
{
|
{
|
||||||
QStringList processes;
|
processes.clear();
|
||||||
if (libprocpsSupported) {
|
if (libprocpsSupported) {
|
||||||
getProcessListProcps(processes);
|
getProcessListProcps(processes);
|
||||||
return processes;
|
return;
|
||||||
}
|
}
|
||||||
if (libprocps2Supported) {
|
if (libprocps2Supported) {
|
||||||
getProcessListProcps2(processes);
|
getProcessListProcps2(processes);
|
||||||
}
|
}
|
||||||
return processes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long getForegroundProcessPid()
|
long getForegroundProcessPid()
|
||||||
@@ -467,83 +469,24 @@ std::string getProcNameFromPid(long pid)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetForegroundProcessName()
|
void GetForegroundProcessName(QString &proc)
|
||||||
{
|
{
|
||||||
|
std::string temp;
|
||||||
|
GetForegroundProcessName(temp);
|
||||||
|
proc = QString::fromStdString(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetForegroundProcessName(std::string &proc)
|
||||||
|
{
|
||||||
|
proc.resize(0);
|
||||||
auto pid = getForegroundProcessPid();
|
auto pid = getForegroundProcessPid();
|
||||||
return getProcNameFromPid(pid);
|
proc = getProcNameFromPid(pid);
|
||||||
}
|
|
||||||
|
|
||||||
static std::string getProcessPathFromPid(long pid)
|
|
||||||
{
|
|
||||||
std::string linkPath = "/proc/" + std::to_string(pid) + "/exe";
|
|
||||||
char buf[PATH_MAX];
|
|
||||||
ssize_t len = readlink(linkPath.c_str(), buf, sizeof(buf) - 1);
|
|
||||||
if (len <= 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
buf[len] = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetForegroundProcessPath()
|
|
||||||
{
|
|
||||||
auto pid = getForegroundProcessPid();
|
|
||||||
if (pid <= 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return getProcessPathFromPid(pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList GetProcessPathsFromName(const QString &name)
|
|
||||||
{
|
|
||||||
QStringList paths;
|
|
||||||
const std::string nameStr = name.toStdString();
|
|
||||||
DIR *procDir = opendir("/proc");
|
|
||||||
if (!procDir) {
|
|
||||||
return paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dirent *entry;
|
|
||||||
while ((entry = readdir(procDir)) != nullptr) {
|
|
||||||
bool isPid = (entry->d_name[0] != '\0');
|
|
||||||
for (const char *c = entry->d_name; *c; c++) {
|
|
||||||
if (!isdigit(*c)) {
|
|
||||||
isPid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isPid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string pid = entry->d_name;
|
|
||||||
std::string commPath = "/proc/" + pid + "/comm";
|
|
||||||
std::ifstream commFile(commPath);
|
|
||||||
if (!commFile) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::string comm;
|
|
||||||
std::getline(commFile, comm);
|
|
||||||
if (comm != nameStr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string path = getProcessPathFromPid(std::stol(pid));
|
|
||||||
if (path.empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
QString qPath = QString::fromStdString(path);
|
|
||||||
if (!paths.contains(qPath)) {
|
|
||||||
paths.append(qPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir(procDir);
|
|
||||||
return paths;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsInFocus(const QString &executable)
|
bool IsInFocus(const QString &executable)
|
||||||
{
|
{
|
||||||
const auto current = GetForegroundProcessName();
|
std::string current;
|
||||||
|
GetForegroundProcessName(current);
|
||||||
|
|
||||||
// True if executable switch equals current window
|
// True if executable switch equals current window
|
||||||
bool equals = (executable.toStdString() == current);
|
bool equals = (executable.toStdString() == current);
|
||||||
|
|||||||
@@ -12,82 +12,35 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
std::mutex FocusNotifier::_mutex;
|
|
||||||
int FocusNotifier::activePID = -1;
|
int FocusNotifier::activePID = -1;
|
||||||
std::string FocusNotifier::activeTitle = {};
|
std::string FocusNotifier::activeTitle = {};
|
||||||
std::map<std::string, std::pair<int, std::string>> FocusNotifier::_windows;
|
|
||||||
|
|
||||||
int FocusNotifier::getActiveWindowPID()
|
int FocusNotifier::getActiveWindowPID()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
return activePID;
|
return activePID;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FocusNotifier::getActiveWindowTitle()
|
std::string FocusNotifier::getActiveWindowTitle()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
return activeTitle;
|
return activeTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<int, std::string>> FocusNotifier::getWindowList()
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
std::vector<std::pair<int, std::string>> result;
|
|
||||||
result.reserve(_windows.size());
|
|
||||||
for (const auto &entry : _windows) {
|
|
||||||
result.emplace_back(entry.second);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FocusNotifier::focusChanged(const int pid)
|
void FocusNotifier::focusChanged(const int pid)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
activePID = pid;
|
activePID = pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FocusNotifier::focusTitle(const QString &title)
|
void FocusNotifier::focusTitle(const QString &title)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
activeTitle = title.toStdString();
|
activeTitle = title.toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FocusNotifier::focusUpdate(const int pid, const QString &title)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
activePID = pid;
|
|
||||||
activeTitle = title.toStdString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FocusNotifier::windowAdded(const QString &id, const int pid,
|
|
||||||
const QString &title)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
_windows[id.toStdString()] = {pid, title.toStdString()};
|
|
||||||
}
|
|
||||||
|
|
||||||
void FocusNotifier::windowRemoved(const QString &id)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
_windows.erase(id.toStdString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FocusNotifier::windowTitleChanged(const QString &id, const QString &title)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(_mutex);
|
|
||||||
auto it = _windows.find(id.toStdString());
|
|
||||||
if (it != _windows.end()) {
|
|
||||||
it->second.second = title.toStdString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isKWinAvailable()
|
bool isKWinAvailable()
|
||||||
{
|
{
|
||||||
const QDBusConnectionInterface *interface =
|
const QDBusConnectionInterface *interface =
|
||||||
QDBusConnection::sessionBus().interface();
|
QDBusConnection::sessionBus().interface();
|
||||||
if (!interface) {
|
if (!interface)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
const QStringList services =
|
const QStringList services =
|
||||||
interface->registeredServiceNames().value();
|
interface->registeredServiceNames().value();
|
||||||
@@ -100,32 +53,25 @@ bool startKWinScript(QString &scriptObjectPath)
|
|||||||
"/tmp/AdvancedSceneSwitcher/KWinFocusNotifier.js";
|
"/tmp/AdvancedSceneSwitcher/KWinFocusNotifier.js";
|
||||||
|
|
||||||
const QString script =
|
const QString script =
|
||||||
R"(var adss = "com.github.AdvancedSceneSwitcher";
|
R"(workspace.windowActivated.connect(function(client) {
|
||||||
var adssPath = "/com/github/AdvancedSceneSwitcher";
|
if (!client) return;
|
||||||
|
if (!client.pid) return;
|
||||||
|
if (!client.caption) return;
|
||||||
|
|
||||||
function trackWindow(window) {
|
callDBus(
|
||||||
var id = window.internalId.toString();
|
"com.github.AdvancedSceneSwitcher",
|
||||||
callDBus(adss, adssPath, adss, "windowAdded", id, window.pid, window.caption);
|
"/com/github/AdvancedSceneSwitcher",
|
||||||
window.captionChanged.connect(function() {
|
"com.github.AdvancedSceneSwitcher",
|
||||||
callDBus(adss, adssPath, adss, "windowTitleChanged", id, window.caption);
|
"focusChanged",
|
||||||
});
|
client.pid
|
||||||
}
|
);
|
||||||
|
callDBus(
|
||||||
var windows = workspace.windowList();
|
"com.github.AdvancedSceneSwitcher",
|
||||||
for (var i = 0; i < windows.length; i++) {
|
"/com/github/AdvancedSceneSwitcher",
|
||||||
trackWindow(windows[i]);
|
"com.github.AdvancedSceneSwitcher",
|
||||||
}
|
"focusTitle",
|
||||||
|
client.caption
|
||||||
workspace.windowAdded.connect(trackWindow);
|
);
|
||||||
|
|
||||||
workspace.windowRemoved.connect(function(window) {
|
|
||||||
callDBus(adss, adssPath, adss, "windowRemoved", window.internalId.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
workspace.windowActivated.connect(function(client) {
|
|
||||||
callDBus(adss, adssPath, adss, "focusUpdate",
|
|
||||||
client ? client.pid : 0,
|
|
||||||
client ? client.caption : "");
|
|
||||||
}))";
|
}))";
|
||||||
|
|
||||||
if (const QDir dir; !dir.mkpath(QFileInfo(scriptPath).absolutePath())) {
|
if (const QDir dir; !dir.mkpath(QFileInfo(scriptPath).absolutePath())) {
|
||||||
|
|||||||
@@ -2,11 +2,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <map>
|
|
||||||
#include <mutex>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -14,27 +10,18 @@ class FocusNotifier final : public QObject {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_CLASSINFO("D-Bus Interface", "com.github.AdvancedSceneSwitcher")
|
Q_CLASSINFO("D-Bus Interface", "com.github.AdvancedSceneSwitcher")
|
||||||
|
|
||||||
static std::mutex _mutex;
|
|
||||||
static int activePID;
|
static int activePID;
|
||||||
static std::string activeTitle;
|
static std::string activeTitle;
|
||||||
// Maps KWin internal window ID to {pid, title}
|
|
||||||
static std::map<std::string, std::pair<int, std::string>> _windows;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using QObject::QObject;
|
using QObject::QObject;
|
||||||
|
|
||||||
static int getActiveWindowPID();
|
static int getActiveWindowPID();
|
||||||
static std::string getActiveWindowTitle();
|
static std::string getActiveWindowTitle();
|
||||||
static std::vector<std::pair<int, std::string>> getWindowList();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void focusChanged(const int pid);
|
void focusChanged(const int pid);
|
||||||
void focusTitle(const QString &title);
|
void focusTitle(const QString &title);
|
||||||
void focusUpdate(const int pid, const QString &title);
|
|
||||||
void windowAdded(const QString &id, const int pid,
|
|
||||||
const QString &title);
|
|
||||||
void windowRemoved(const QString &id);
|
|
||||||
void windowTitleChanged(const QString &id, const QString &title);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isKWinAvailable();
|
bool isKWinAvailable();
|
||||||
|
|||||||
@@ -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()),
|
||||||
@@ -49,12 +50,10 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
|||||||
_section->AddHeaderWidget(_enable);
|
_section->AddHeaderWidget(_enable);
|
||||||
_section->AddHeaderWidget(_actionSelection);
|
_section->AddHeaderWidget(_actionSelection);
|
||||||
_section->AddHeaderWidget(_headerInfo);
|
_section->AddHeaderWidget(_headerInfo);
|
||||||
_section->AddHeaderWidget(_varMappingToggle);
|
|
||||||
|
|
||||||
auto actionLayout = new QVBoxLayout;
|
auto actionLayout = new QVBoxLayout;
|
||||||
actionLayout->setContentsMargins({7, 7, 7, 7});
|
actionLayout->setContentsMargins({7, 7, 7, 7});
|
||||||
actionLayout->addWidget(_section);
|
actionLayout->addWidget(_section);
|
||||||
actionLayout->addWidget(_outputMappings);
|
|
||||||
_contentLayout->addLayout(actionLayout);
|
_contentLayout->addLayout(actionLayout);
|
||||||
|
|
||||||
auto mainLayout = new QHBoxLayout;
|
auto mainLayout = new QHBoxLayout;
|
||||||
@@ -63,6 +62,7 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
|||||||
mainLayout->addWidget(_frame);
|
mainLayout->addWidget(_frame);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
_entryData = entryData;
|
||||||
SetupWidgets(true);
|
SetupWidgets(true);
|
||||||
|
|
||||||
actionStateTimer->start(300);
|
actionStateTimer->start(300);
|
||||||
@@ -91,10 +91,7 @@ void MacroActionEdit::SetupWidgets(bool basicSetup)
|
|||||||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
|
||||||
SLOT(ShowVariableMappings(bool)));
|
|
||||||
_section->SetContent(widget, (*_entryData)->GetCollapsed());
|
_section->SetContent(widget, (*_entryData)->GetCollapsed());
|
||||||
SetupVarMappings((*_entryData).get());
|
|
||||||
SetFocusPolicyOfWidgets();
|
SetFocusPolicyOfWidgets();
|
||||||
|
|
||||||
_allWidgetsAreSetup = true;
|
_allWidgetsAreSetup = true;
|
||||||
@@ -120,15 +117,12 @@ void MacroActionEdit::ActionSelectionChanged(const QString &text)
|
|||||||
*_entryData = MacroActionFactory::Create(id, macro);
|
*_entryData = MacroActionFactory::Create(id, macro);
|
||||||
(*_entryData)->SetIndex(idx);
|
(*_entryData)->SetIndex(idx);
|
||||||
(*_entryData)->PostLoad();
|
(*_entryData)->PostLoad();
|
||||||
RunAndClearPostLoadSteps();
|
RunPostLoadSteps();
|
||||||
}
|
}
|
||||||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
|
||||||
SLOT(ShowVariableMappings(bool)));
|
|
||||||
_section->SetContent(widget);
|
_section->SetContent(widget);
|
||||||
SetupVarMappings((*_entryData).get());
|
|
||||||
SetFocusPolicyOfWidgets();
|
SetFocusPolicyOfWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,9 +158,473 @@ std::shared_ptr<MacroSegment> MacroActionEdit::Data() const
|
|||||||
return *_entryData;
|
return *_entryData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionEdit::FocusTypeSelection()
|
void AdvSceneSwitcher::AddMacroAction(Macro *macro, int idx,
|
||||||
|
const std::string &id, obs_data_t *data)
|
||||||
{
|
{
|
||||||
_actionSelection->setFocus();
|
if (idx < 0 || idx > (int)macro->Actions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
macro->Actions().emplace(macro->Actions().begin() + idx,
|
||||||
|
MacroActionFactory::Create(id, macro));
|
||||||
|
if (data) {
|
||||||
|
macro->Actions().at(idx)->Load(data);
|
||||||
|
}
|
||||||
|
macro->Actions().at(idx)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
|
macro->UpdateActionIndices();
|
||||||
|
ui->actionsList->Insert(
|
||||||
|
idx,
|
||||||
|
new MacroActionEdit(this, ¯o->Actions()[idx], id));
|
||||||
|
SetActionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightAction(idx);
|
||||||
|
ui->actionsList->SetHelpMsgVisible(false);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::AddMacroAction(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx > (int)macro->Actions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string id;
|
||||||
|
if (idx - 1 >= 0) {
|
||||||
|
id = macro->Actions().at(idx - 1)->GetId();
|
||||||
|
} else {
|
||||||
|
id = MacroAction::GetDefaultID();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSDataAutoRelease data;
|
||||||
|
if (idx - 1 >= 0) {
|
||||||
|
data = obs_data_create();
|
||||||
|
macro->Actions().at(idx - 1)->Save(data);
|
||||||
|
}
|
||||||
|
AddMacroAction(macro.get(), idx, id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_actionAdd_clicked()
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentActionIdx == -1) {
|
||||||
|
AddMacroAction((int)macro->Actions().size());
|
||||||
|
} else {
|
||||||
|
AddMacroAction(currentActionIdx + 1);
|
||||||
|
}
|
||||||
|
if (currentActionIdx != -1) {
|
||||||
|
MacroActionSelectionChanged(currentActionIdx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= (int)macro->Actions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
ui->actionsList->Remove(idx);
|
||||||
|
macro->Actions().erase(macro->Actions().begin() + idx);
|
||||||
|
SetMacroAbortWait(true);
|
||||||
|
GetMacroWaitCV().notify_all();
|
||||||
|
macro->UpdateActionIndices();
|
||||||
|
SetActionData(*macro);
|
||||||
|
}
|
||||||
|
MacroActionSelectionChanged(-1);
|
||||||
|
lastInteracted = MacroSection::ACTIONS;
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_actionRemove_clicked()
|
||||||
|
{
|
||||||
|
if (currentActionIdx == -1) {
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RemoveMacroAction((int)macro->Actions().size() - 1);
|
||||||
|
} else {
|
||||||
|
RemoveMacroAction(currentActionIdx);
|
||||||
|
}
|
||||||
|
MacroActionSelectionChanged(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_actionTop_clicked()
|
||||||
|
{
|
||||||
|
if (currentActionIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MacroActionReorder(0, currentActionIdx);
|
||||||
|
MacroActionSelectionChanged(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_actionUp_clicked()
|
||||||
|
{
|
||||||
|
if (currentActionIdx == -1 || currentActionIdx == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MoveMacroActionUp(currentActionIdx);
|
||||||
|
MacroActionSelectionChanged(currentActionIdx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_actionDown_clicked()
|
||||||
|
{
|
||||||
|
if (currentActionIdx == -1 ||
|
||||||
|
currentActionIdx == ui->actionsList->ContentLayout()->count() - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MoveMacroActionDown(currentActionIdx);
|
||||||
|
MacroActionSelectionChanged(currentActionIdx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_actionBottom_clicked()
|
||||||
|
{
|
||||||
|
if (currentActionIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const int newIdx = ui->actionsList->ContentLayout()->count() - 1;
|
||||||
|
MacroActionReorder(newIdx, currentActionIdx);
|
||||||
|
MacroActionSelectionChanged(newIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_elseActionAdd_clicked()
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentElseActionIdx == -1) {
|
||||||
|
AddMacroElseAction((int)macro->ElseActions().size());
|
||||||
|
} else {
|
||||||
|
AddMacroElseAction(currentElseActionIdx + 1);
|
||||||
|
}
|
||||||
|
if (currentElseActionIdx != -1) {
|
||||||
|
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_elseActionRemove_clicked()
|
||||||
|
{
|
||||||
|
if (currentElseActionIdx == -1) {
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RemoveMacroElseAction((int)macro->ElseActions().size() - 1);
|
||||||
|
} else {
|
||||||
|
RemoveMacroElseAction(currentElseActionIdx);
|
||||||
|
}
|
||||||
|
MacroElseActionSelectionChanged(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_elseActionTop_clicked()
|
||||||
|
{
|
||||||
|
if (currentElseActionIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MacroElseActionReorder(0, currentElseActionIdx);
|
||||||
|
MacroElseActionSelectionChanged(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_elseActionUp_clicked()
|
||||||
|
{
|
||||||
|
if (currentElseActionIdx == -1 || currentElseActionIdx == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MoveMacroElseActionUp(currentElseActionIdx);
|
||||||
|
MacroElseActionSelectionChanged(currentElseActionIdx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_elseActionDown_clicked()
|
||||||
|
{
|
||||||
|
if (currentElseActionIdx == -1 ||
|
||||||
|
currentElseActionIdx ==
|
||||||
|
ui->elseActionsList->ContentLayout()->count() - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MoveMacroElseActionDown(currentElseActionIdx);
|
||||||
|
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_elseActionBottom_clicked()
|
||||||
|
{
|
||||||
|
if (currentElseActionIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const int newIdx = ui->elseActionsList->ContentLayout()->count() - 1;
|
||||||
|
MacroElseActionReorder(newIdx, currentElseActionIdx);
|
||||||
|
MacroElseActionSelectionChanged(newIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2)
|
||||||
|
{
|
||||||
|
if (pos1 == pos2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos1 > pos2) {
|
||||||
|
std::swap(pos1, pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
iter_swap(m->Actions().begin() + pos1, m->Actions().begin() + pos2);
|
||||||
|
m->UpdateActionIndices();
|
||||||
|
auto widget1 = static_cast<MacroActionEdit *>(
|
||||||
|
ui->actionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||||
|
auto widget2 = static_cast<MacroActionEdit *>(
|
||||||
|
ui->actionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
||||||
|
ui->actionsList->Insert(pos1, widget2);
|
||||||
|
ui->actionsList->Insert(pos2, widget1);
|
||||||
|
SetActionData(*m);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MoveMacroActionUp(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 1 || idx >= (int)macro->Actions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapActions(macro.get(), idx, idx - 1);
|
||||||
|
HighlightAction(idx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MoveMacroActionDown(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= (int)macro->Actions().size() - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapActions(macro.get(), idx, idx + 1);
|
||||||
|
HighlightAction(idx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroElseActionSelectionChanged(int idx)
|
||||||
|
{
|
||||||
|
SetupMacroSegmentSelection(MacroSection::ELSE_ACTIONS, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroElseActionReorder(int to, int from)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to == from || from < 0 || from > (int)macro->ElseActions().size() ||
|
||||||
|
to < 0 || to > (int)macro->ElseActions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
auto action = macro->ElseActions().at(from);
|
||||||
|
macro->ElseActions().erase(macro->ElseActions().begin() + from);
|
||||||
|
macro->ElseActions().insert(macro->ElseActions().begin() + to,
|
||||||
|
action);
|
||||||
|
macro->UpdateElseActionIndices();
|
||||||
|
ui->elseActionsList->ContentLayout()->insertItem(
|
||||||
|
to, ui->elseActionsList->ContentLayout()->takeAt(from));
|
||||||
|
SetElseActionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightElseAction(to);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::AddMacroElseAction(Macro *macro, int idx,
|
||||||
|
const std::string &id,
|
||||||
|
obs_data_t *data)
|
||||||
|
{
|
||||||
|
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
macro->ElseActions().emplace(macro->ElseActions().begin() + idx,
|
||||||
|
MacroActionFactory::Create(id,
|
||||||
|
macro));
|
||||||
|
if (data) {
|
||||||
|
macro->ElseActions().at(idx)->Load(data);
|
||||||
|
}
|
||||||
|
macro->ElseActions().at(idx)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
|
macro->UpdateElseActionIndices();
|
||||||
|
ui->elseActionsList->Insert(
|
||||||
|
idx, new MacroActionEdit(
|
||||||
|
this, ¯o->ElseActions()[idx], id));
|
||||||
|
SetElseActionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightElseAction(idx);
|
||||||
|
ui->elseActionsList->SetHelpMsgVisible(false);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::AddMacroElseAction(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string id;
|
||||||
|
if (idx - 1 >= 0) {
|
||||||
|
id = macro->ElseActions().at(idx - 1)->GetId();
|
||||||
|
} else {
|
||||||
|
id = MacroAction::GetDefaultID();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSDataAutoRelease data;
|
||||||
|
if (idx - 1 >= 0) {
|
||||||
|
data = obs_data_create();
|
||||||
|
macro->ElseActions().at(idx - 1)->Save(data);
|
||||||
|
}
|
||||||
|
AddMacroElseAction(macro.get(), idx, id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::RemoveMacroElseAction(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= (int)macro->ElseActions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
ui->elseActionsList->Remove(idx);
|
||||||
|
macro->ElseActions().erase(macro->ElseActions().begin() + idx);
|
||||||
|
SetMacroAbortWait(true);
|
||||||
|
GetMacroWaitCV().notify_all();
|
||||||
|
macro->UpdateElseActionIndices();
|
||||||
|
SetElseActionData(*macro);
|
||||||
|
}
|
||||||
|
MacroElseActionSelectionChanged(-1);
|
||||||
|
lastInteracted = MacroSection::ELSE_ACTIONS;
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::SwapElseActions(Macro *m, int pos1, int pos2)
|
||||||
|
{
|
||||||
|
if (pos1 == pos2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos1 > pos2) {
|
||||||
|
std::swap(pos1, pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
iter_swap(m->ElseActions().begin() + pos1,
|
||||||
|
m->ElseActions().begin() + pos2);
|
||||||
|
m->UpdateElseActionIndices();
|
||||||
|
auto widget1 = static_cast<MacroActionEdit *>(
|
||||||
|
ui->elseActionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||||
|
auto widget2 = static_cast<MacroActionEdit *>(
|
||||||
|
ui->elseActionsList->ContentLayout()
|
||||||
|
->takeAt(pos2 - 1)
|
||||||
|
->widget());
|
||||||
|
ui->elseActionsList->Insert(pos1, widget2);
|
||||||
|
ui->elseActionsList->Insert(pos2, widget1);
|
||||||
|
SetElseActionData(*m);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MoveMacroElseActionUp(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 1 || idx >= (int)macro->ElseActions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapElseActions(macro.get(), idx, idx - 1);
|
||||||
|
HighlightElseAction(idx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MoveMacroElseActionDown(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= (int)macro->ElseActions().size() - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapElseActions(macro.get(), idx, idx + 1);
|
||||||
|
HighlightElseAction(idx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroActionSelectionChanged(int idx)
|
||||||
|
{
|
||||||
|
SetupMacroSegmentSelection(MacroSection::ACTIONS, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroActionReorder(int to, int from)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to == from || from < 0 || from > (int)macro->Actions().size() ||
|
||||||
|
to < 0 || to > (int)macro->Actions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
auto action = macro->Actions().at(from);
|
||||||
|
macro->Actions().erase(macro->Actions().begin() + from);
|
||||||
|
macro->Actions().insert(macro->Actions().begin() + to, action);
|
||||||
|
macro->UpdateActionIndices();
|
||||||
|
ui->actionsList->ContentLayout()->insertItem(
|
||||||
|
to, ui->actionsList->ContentLayout()->takeAt(from));
|
||||||
|
SetActionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightAction(to);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ 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> *);
|
||||||
void FocusTypeSelection() override;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void ActionSelectionChanged(const QString &text);
|
void ActionSelectionChanged(const QString &text);
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
#include "macro-action-factory.hpp"
|
#include "macro-action-factory.hpp"
|
||||||
#include "macro-segment-unknown.hpp"
|
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
using MacroActionUnknown = MacroSegmentUnknown<MacroAction>;
|
namespace {
|
||||||
|
|
||||||
|
class MacroActionUnknown : public MacroAction {
|
||||||
|
public:
|
||||||
|
MacroActionUnknown(Macro *m) : MacroAction(m) {}
|
||||||
|
std::shared_ptr<MacroAction> Copy() const
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionUnknown>(GetMacro());
|
||||||
|
}
|
||||||
|
bool PerformAction() { return true; };
|
||||||
|
bool Save(obs_data_t *obj) const { return MacroAction::Save(obj); };
|
||||||
|
bool Load(obs_data_t *obj) { return MacroAction::Load(obj); };
|
||||||
|
std::string GetId() const { return "unknown"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static std::recursive_mutex mutex;
|
static std::recursive_mutex mutex;
|
||||||
|
|
||||||
@@ -35,10 +49,9 @@ bool MacroActionFactory::Deregister(const std::string &id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<MacroAction> createUnknownAction(Macro *m,
|
static std::shared_ptr<MacroAction> createUnknownAction(Macro *m)
|
||||||
const std::string &id)
|
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionUnknown>(m, id);
|
return std::make_shared<MacroActionUnknown>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MacroAction> MacroActionFactory::Create(const std::string &id,
|
std::shared_ptr<MacroAction> MacroActionFactory::Create(const std::string &id,
|
||||||
@@ -49,7 +62,12 @@ std::shared_ptr<MacroAction> MacroActionFactory::Create(const std::string &id,
|
|||||||
return it->second._create(m);
|
return it->second._create(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
return createUnknownAction(m, id);
|
return createUnknownAction(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QWidget *createUnknownActionWidget()
|
||||||
|
{
|
||||||
|
return new QLabel(obs_module_text("AdvSceneSwitcher.action.unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *MacroActionFactory::CreateWidget(const std::string &id,
|
QWidget *MacroActionFactory::CreateWidget(const std::string &id,
|
||||||
@@ -61,7 +79,7 @@ QWidget *MacroActionFactory::CreateWidget(const std::string &id,
|
|||||||
return it->second._createWidget(parent, action);
|
return it->second._createWidget(parent, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateUnknownSegmentWidget(true);
|
return createUnknownActionWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MacroActionFactory::GetActionName(const std::string &id)
|
std::string MacroActionFactory::GetActionName(const std::string &id)
|
||||||
|
|||||||
@@ -1,196 +0,0 @@
|
|||||||
#include "macro-action-loop.hpp"
|
|
||||||
|
|
||||||
#include "layout-helpers.hpp"
|
|
||||||
#include "macro-action-factory.hpp"
|
|
||||||
#include "macro.hpp"
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
const std::string MacroActionLoop::id = "loop";
|
|
||||||
|
|
||||||
bool MacroActionLoop::_registered = MacroActionFactory::Register(
|
|
||||||
MacroActionLoop::id,
|
|
||||||
{MacroActionLoop::Create, MacroActionLoopEdit::Create,
|
|
||||||
"AdvSceneSwitcher.action.loop"});
|
|
||||||
|
|
||||||
bool MacroActionLoop::PerformAction()
|
|
||||||
{
|
|
||||||
int iterations = 0;
|
|
||||||
const int maxIterations = _maxIterations;
|
|
||||||
Macro *parentMacro = GetMacro();
|
|
||||||
|
|
||||||
if (maxIterations <= 0) {
|
|
||||||
blog(LOG_WARNING,
|
|
||||||
"loop action has invalid max iterations value of %d",
|
|
||||||
maxIterations);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (_loopMacro->CheckConditions()) {
|
|
||||||
if (iterations >= maxIterations) {
|
|
||||||
blog(LOG_WARNING,
|
|
||||||
"loop action reached iteration limit of %d",
|
|
||||||
maxIterations);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ablog(LOG_INFO, "loop iteration %d", iterations);
|
|
||||||
if (!_loopMacro->PerformActions(true, false, true)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++iterations;
|
|
||||||
if (parentMacro && parentMacro->GetStop()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ablog(LOG_INFO, "loop completed after %d iteration(s)", iterations);
|
|
||||||
SetTempVarValue("count", std::to_string(iterations));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionLoop::LogAction() const
|
|
||||||
{
|
|
||||||
ablog(LOG_INFO, "running loop (max %d iterations)",
|
|
||||||
_maxIterations.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionLoop::Save(obs_data_t *obj) const
|
|
||||||
{
|
|
||||||
MacroAction::Save(obj);
|
|
||||||
_maxIterations.Save(obj, "maxIterations");
|
|
||||||
OBSDataAutoRelease loopMacroData = obs_data_create();
|
|
||||||
_loopMacro->Save(loopMacroData);
|
|
||||||
obs_data_set_obj(obj, "loopMacro", loopMacroData);
|
|
||||||
obs_data_set_int(obj, "customWidgetHeight", _customWidgetHeight);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionLoop::Load(obs_data_t *obj)
|
|
||||||
{
|
|
||||||
MacroAction::Load(obj);
|
|
||||||
_maxIterations.Load(obj, "maxIterations");
|
|
||||||
if (obs_data_has_user_value(obj, "loopMacro")) {
|
|
||||||
OBSDataAutoRelease loopMacroData =
|
|
||||||
obs_data_get_obj(obj, "loopMacro");
|
|
||||||
_loopMacro = std::make_shared<Macro>();
|
|
||||||
_loopMacro->Load(loopMacroData);
|
|
||||||
}
|
|
||||||
_customWidgetHeight = obs_data_get_int(obj, "customWidgetHeight");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionLoop::PostLoad()
|
|
||||||
{
|
|
||||||
MacroAction::PostLoad();
|
|
||||||
_loopMacro->PostLoad();
|
|
||||||
_loopMacro->SetActionTriggerMode(Macro::ActionTriggerMode::ALWAYS);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<MacroAction> MacroActionLoop::Create(Macro *m)
|
|
||||||
{
|
|
||||||
return std::make_shared<MacroActionLoop>(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<MacroAction> MacroActionLoop::Copy() const
|
|
||||||
{
|
|
||||||
auto copy = std::make_shared<MacroActionLoop>(*this);
|
|
||||||
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
|
||||||
_loopMacro->Save(data);
|
|
||||||
|
|
||||||
copy->_loopMacro = std::make_shared<Macro>();
|
|
||||||
copy->_loopMacro->Load(data);
|
|
||||||
copy->_loopMacro->PostLoad();
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionLoop::ResolveVariablesToFixedValues()
|
|
||||||
{
|
|
||||||
_maxIterations.ResolveVariables();
|
|
||||||
for (auto &action : _loopMacro->Actions()) {
|
|
||||||
action->ResolveVariablesToFixedValues();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionLoop::SetupTempVars()
|
|
||||||
{
|
|
||||||
MacroAction::SetupTempVars();
|
|
||||||
AddTempvar("count",
|
|
||||||
obs_module_text("AdvSceneSwitcher.tempVar.loop.count"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.loop.count.description"));
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroActionLoopEdit::MacroActionLoopEdit(
|
|
||||||
QWidget *parent, std::shared_ptr<MacroActionLoop> entryData)
|
|
||||||
: ResizableWidget(parent),
|
|
||||||
_macroEdit(new MacroEdit(
|
|
||||||
this, QStringList()
|
|
||||||
<< "AdvSceneSwitcher.action.loop.conditionHelp"
|
|
||||||
<< "AdvSceneSwitcher.action.loop.actionHelp"
|
|
||||||
<< "")),
|
|
||||||
_maxIterations(new VariableSpinBox())
|
|
||||||
{
|
|
||||||
_maxIterations->setMinimum(1);
|
|
||||||
_maxIterations->setMaximum(10000000);
|
|
||||||
|
|
||||||
QWidget::connect(
|
|
||||||
_maxIterations,
|
|
||||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
|
||||||
this, SLOT(MaxIterationsChanged(const NumberVariable<int> &)));
|
|
||||||
|
|
||||||
auto controlsLayout = new QHBoxLayout();
|
|
||||||
controlsLayout->addWidget(new QLabel(
|
|
||||||
obs_module_text("AdvSceneSwitcher.action.loop.maxIterations")));
|
|
||||||
controlsLayout->addWidget(_maxIterations);
|
|
||||||
controlsLayout->addStretch();
|
|
||||||
|
|
||||||
auto layout = new QVBoxLayout();
|
|
||||||
layout->addLayout(controlsLayout);
|
|
||||||
layout->addWidget(_macroEdit);
|
|
||||||
setLayout(layout);
|
|
||||||
|
|
||||||
_macroEdit->HideElseSection();
|
|
||||||
|
|
||||||
_entryData = entryData;
|
|
||||||
UpdateEntryData();
|
|
||||||
_loading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroActionLoopEdit::~MacroActionLoopEdit()
|
|
||||||
{
|
|
||||||
if (!_entryData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_entryData->_customWidgetHeight = GetCustomHeight();
|
|
||||||
_macroEdit->SetMacro({});
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionLoopEdit::UpdateEntryData()
|
|
||||||
{
|
|
||||||
if (!_entryData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_maxIterations->SetValue(_entryData->_maxIterations);
|
|
||||||
_macroEdit->SetMacro(_entryData->_loopMacro);
|
|
||||||
|
|
||||||
if (_macroEdit->IsEmpty()) {
|
|
||||||
_macroEdit->ShowAllMacroSections();
|
|
||||||
_entryData->_customWidgetHeight = 600;
|
|
||||||
}
|
|
||||||
SetResizingEnabled(true);
|
|
||||||
SetCustomHeight(_entryData->_customWidgetHeight);
|
|
||||||
|
|
||||||
adjustSize();
|
|
||||||
updateGeometry();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionLoopEdit::MaxIterationsChanged(const NumberVariable<int> &value)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_maxIterations = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "macro-action-edit.hpp"
|
|
||||||
#include "macro-edit.hpp"
|
|
||||||
#include "resizable-widget.hpp"
|
|
||||||
#include "variable-spinbox.hpp"
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
class MacroActionLoop : public MacroAction {
|
|
||||||
public:
|
|
||||||
MacroActionLoop(Macro *m) : MacroAction(m) {}
|
|
||||||
bool PerformAction();
|
|
||||||
void LogAction() const;
|
|
||||||
bool Save(obs_data_t *obj) const;
|
|
||||||
bool Load(obs_data_t *obj);
|
|
||||||
bool PostLoad();
|
|
||||||
std::string GetId() const { return id; }
|
|
||||||
static std::shared_ptr<MacroAction> Create(Macro *m);
|
|
||||||
std::shared_ptr<MacroAction> Copy() const;
|
|
||||||
void ResolveVariablesToFixedValues();
|
|
||||||
|
|
||||||
std::shared_ptr<Macro> _loopMacro = std::make_shared<Macro>();
|
|
||||||
IntVariable _maxIterations = 100;
|
|
||||||
int _customWidgetHeight = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void SetupTempVars();
|
|
||||||
|
|
||||||
static bool _registered;
|
|
||||||
static const std::string id;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacroActionLoopEdit : public ResizableWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MacroActionLoopEdit(
|
|
||||||
QWidget *parent,
|
|
||||||
std::shared_ptr<MacroActionLoop> entryData = nullptr);
|
|
||||||
~MacroActionLoopEdit();
|
|
||||||
void UpdateEntryData();
|
|
||||||
static QWidget *Create(QWidget *parent,
|
|
||||||
std::shared_ptr<MacroAction> action)
|
|
||||||
{
|
|
||||||
return new MacroActionLoopEdit(
|
|
||||||
parent,
|
|
||||||
std::dynamic_pointer_cast<MacroActionLoop>(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void MaxIterationsChanged(const NumberVariable<int> &value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
MacroEdit *_macroEdit;
|
|
||||||
VariableSpinBox *_maxIterations;
|
|
||||||
|
|
||||||
std::shared_ptr<MacroActionLoop> _entryData;
|
|
||||||
bool _loading = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,14 +1,8 @@
|
|||||||
#include "macro-action-macro.hpp"
|
#include "macro-action-macro.hpp"
|
||||||
|
|
||||||
#include "condition-logic.hpp"
|
|
||||||
#include "help-icon.hpp"
|
#include "help-icon.hpp"
|
||||||
#include "layout-helpers.hpp"
|
#include "layout-helpers.hpp"
|
||||||
#include "macro-action-factory.hpp"
|
|
||||||
#include "macro-helpers.hpp"
|
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
const std::string MacroActionMacro::id = "macro";
|
const std::string MacroActionMacro::id = "macro";
|
||||||
@@ -18,165 +12,54 @@ bool MacroActionMacro::_registered = MacroActionFactory::Register(
|
|||||||
{MacroActionMacro::Create, MacroActionMacroEdit::Create,
|
{MacroActionMacro::Create, MacroActionMacroEdit::Create,
|
||||||
"AdvSceneSwitcher.action.macro"});
|
"AdvSceneSwitcher.action.macro"});
|
||||||
|
|
||||||
void MacroActionMacro::AdjustActionState(Macro *macro) const
|
|
||||||
{
|
|
||||||
const auto ¯oActions = _useElseSection ? macro->ElseActions()
|
|
||||||
: macro->Actions();
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<MacroAction>> actionsToModify;
|
|
||||||
switch (_actionSelectionType) {
|
|
||||||
case SelectionType::INDEX: {
|
|
||||||
const bool isValidAction =
|
|
||||||
(_useElseSection &&
|
|
||||||
IsValidElseActionIndex(macro, _actionIndex - 1)) ||
|
|
||||||
(!_useElseSection &&
|
|
||||||
IsValidActionIndex(macro, _actionIndex - 1));
|
|
||||||
|
|
||||||
if (isValidAction) {
|
|
||||||
actionsToModify.emplace_back(
|
|
||||||
macroActions.at(_actionIndex - 1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SelectionType::LABEL:
|
|
||||||
for (const auto &action : macroActions) {
|
|
||||||
if (!action->GetUseCustomLabel()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto label = action->GetCustomLabel();
|
|
||||||
|
|
||||||
if (_regex.Enabled()) {
|
|
||||||
if (_regex.Matches(label, _label)) {
|
|
||||||
actionsToModify.emplace_back(action);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (label == std::string(_label)) {
|
|
||||||
actionsToModify.emplace_back(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SelectionType::ID:
|
|
||||||
for (const auto &action : macroActions) {
|
|
||||||
if (action->GetId() == _actionId) {
|
|
||||||
actionsToModify.emplace_back(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &action : actionsToModify) {
|
|
||||||
switch (_action) {
|
|
||||||
case Action::DISABLE_ACTION:
|
|
||||||
action->SetEnabled(false);
|
|
||||||
break;
|
|
||||||
case Action::ENABLE_ACTION:
|
|
||||||
action->SetEnabled(true);
|
|
||||||
break;
|
|
||||||
case Action::TOGGLE_ACTION:
|
|
||||||
action->SetEnabled(!action->Enabled());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionMacro::PerformAction()
|
bool MacroActionMacro::PerformAction()
|
||||||
{
|
{
|
||||||
if (_action == Action::NESTED_MACRO) {
|
|
||||||
const bool conditionsMatched = _nestedMacro->CheckConditions();
|
|
||||||
return _nestedMacro->PerformActions(conditionsMatched);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto macro = _macro.GetMacro();
|
auto macro = _macro.GetMacro();
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
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:
|
||||||
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:
|
if (IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1,
|
||||||
case Action::ENABLE_ACTION:
|
false)) {
|
||||||
case Action::TOGGLE_ACTION:
|
macro->Actions().at(_actionIndex - 1)->SetEnabled(false);
|
||||||
AdjustActionState(macro);
|
|
||||||
break;
|
|
||||||
case Action::RUN_MACRO: {
|
|
||||||
if (_runOptions.skipWhenPaused && macro->Paused()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const bool conditionsMatched =
|
|
||||||
macro->CheckConditions(true);
|
|
||||||
macro->PerformActions(conditionsMatched, false, true);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case Action::GET_INFO: {
|
break;
|
||||||
SetTempVarValue(
|
case Action::ENABLE_ACTION:
|
||||||
"conditionCount",
|
if (IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1,
|
||||||
std::to_string(macro->Conditions().size()));
|
false)) {
|
||||||
SetTempVarValue(
|
macro->Actions().at(_actionIndex - 1)->SetEnabled(true);
|
||||||
"actionCount",
|
|
||||||
std::to_string(macro->Actions().size()));
|
|
||||||
SetTempVarValue(
|
|
||||||
"elseActionCount",
|
|
||||||
std::to_string(macro->ElseActions().size()));
|
|
||||||
SetTempVarValue("paused",
|
|
||||||
macro->Paused() ? "true" : "false");
|
|
||||||
SetTempVarValue("runCount",
|
|
||||||
std::to_string(macro->RunCount()));
|
|
||||||
const auto lastRun = macro->GetLastExecutionTime();
|
|
||||||
const bool hasRun =
|
|
||||||
lastRun.time_since_epoch().count() != 0;
|
|
||||||
const auto secondsSinceLastRun =
|
|
||||||
hasRun ? std::chrono::duration_cast<
|
|
||||||
std::chrono::seconds>(
|
|
||||||
std::chrono::
|
|
||||||
high_resolution_clock::
|
|
||||||
now() -
|
|
||||||
lastRun)
|
|
||||||
.count()
|
|
||||||
: -1;
|
|
||||||
SetTempVarValue("secondsSinceLastRun",
|
|
||||||
std::to_string(secondsSinceLastRun));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default:
|
break;
|
||||||
break;
|
case Action::TOGGLE_ACTION:
|
||||||
|
if (IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1,
|
||||||
|
false)) {
|
||||||
|
auto action = macro->Actions().at(_actionIndex - 1);
|
||||||
|
action->SetEnabled(!action->Enabled());
|
||||||
}
|
}
|
||||||
};
|
break;
|
||||||
|
default:
|
||||||
if (!IsGroupMacro(macro.get())) {
|
break;
|
||||||
performActionForMacro(macro.get());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto macros = GetGroupMacroEntries(macro.get());
|
|
||||||
for (const auto ¯o : macros) {
|
|
||||||
performActionForMacro(macro.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +80,7 @@ void MacroActionMacro::LogAction() const
|
|||||||
ablog(LOG_INFO, "reset counter for \"%s\"",
|
ablog(LOG_INFO, "reset counter for \"%s\"",
|
||||||
macro->Name().c_str());
|
macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::RUN_ACTIONS:
|
case Action::RUN:
|
||||||
ablog(LOG_INFO, "run nested macro \"%s\"",
|
ablog(LOG_INFO, "run nested macro \"%s\"",
|
||||||
macro->Name().c_str());
|
macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
@@ -216,15 +99,6 @@ void MacroActionMacro::LogAction() const
|
|||||||
ablog(LOG_INFO, "toggled action %d of macro \"%s\"",
|
ablog(LOG_INFO, "toggled action %d of macro \"%s\"",
|
||||||
_actionIndex.GetValue(), macro->Name().c_str());
|
_actionIndex.GetValue(), macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::NESTED_MACRO:
|
|
||||||
ablog(LOG_INFO, "run nested macro");
|
|
||||||
break;
|
|
||||||
case Action::GET_INFO:
|
|
||||||
ablog(LOG_INFO, "get info for \"%s\"", macro->Name().c_str());
|
|
||||||
break;
|
|
||||||
case Action::RUN_MACRO:
|
|
||||||
ablog(LOG_INFO, "run macro \"%s\"", macro->Name().c_str());
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -233,45 +107,21 @@ void MacroActionMacro::LogAction() const
|
|||||||
bool MacroActionMacro::Save(obs_data_t *obj) const
|
bool MacroActionMacro::Save(obs_data_t *obj) const
|
||||||
{
|
{
|
||||||
MacroAction::Save(obj);
|
MacroAction::Save(obj);
|
||||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
|
||||||
_macro.Save(obj);
|
_macro.Save(obj);
|
||||||
obs_data_set_int(obj, "actionSelectionType",
|
|
||||||
static_cast<int>(_actionSelectionType));
|
|
||||||
_actionIndex.Save(obj, "actionIndex");
|
_actionIndex.Save(obj, "actionIndex");
|
||||||
_label.Save(obj, "label");
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||||
obs_data_set_string(obj, "actionId", _actionId.c_str());
|
|
||||||
_regex.Save(obj);
|
|
||||||
_runOptions.Save(obj);
|
_runOptions.Save(obj);
|
||||||
OBSDataAutoRelease nestedMacroData = obs_data_create();
|
|
||||||
_nestedMacro->Save(nestedMacroData);
|
|
||||||
obs_data_set_obj(obj, "nestedMacro", nestedMacroData);
|
|
||||||
obs_data_set_int(obj, "customWidgetHeight", _customWidgetHeight);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroActionMacro::Load(obs_data_t *obj)
|
bool MacroActionMacro::Load(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
MacroAction::Load(obj);
|
MacroAction::Load(obj);
|
||||||
SetAction(static_cast<MacroActionMacro::Action>(
|
|
||||||
obs_data_get_int(obj, "action")));
|
|
||||||
_macro.Load(obj);
|
_macro.Load(obj);
|
||||||
_actionSelectionType = static_cast<SelectionType>(
|
|
||||||
obs_data_get_int(obj, "actionSelectionType"));
|
|
||||||
_actionIndex.Load(obj, "actionIndex");
|
_actionIndex.Load(obj, "actionIndex");
|
||||||
_label.Load(obj, "label");
|
_action = static_cast<MacroActionMacro::Action>(
|
||||||
_actionId = obs_data_get_string(obj, "actionId");
|
obs_data_get_int(obj, "action"));
|
||||||
_regex.Load(obj);
|
|
||||||
_runOptions.Load(obj);
|
_runOptions.Load(obj);
|
||||||
|
|
||||||
if (obs_data_has_user_value(obj, "nestedMacro")) {
|
|
||||||
OBSDataAutoRelease nestedMacroData =
|
|
||||||
obs_data_get_obj(obj, "nestedMacro");
|
|
||||||
_nestedMacro = std::make_shared<Macro>();
|
|
||||||
_nestedMacro->Load(nestedMacroData);
|
|
||||||
}
|
|
||||||
|
|
||||||
_customWidgetHeight = obs_data_get_int(obj, "customWidgetHeight");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +130,6 @@ bool MacroActionMacro::PostLoad()
|
|||||||
MacroRefAction::PostLoad();
|
MacroRefAction::PostLoad();
|
||||||
MacroAction::PostLoad();
|
MacroAction::PostLoad();
|
||||||
_runOptions.macro.PostLoad();
|
_runOptions.macro.PostLoad();
|
||||||
_nestedMacro->PostLoad();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,32 +145,12 @@ std::shared_ptr<MacroAction> MacroActionMacro::Create(Macro *m)
|
|||||||
|
|
||||||
std::shared_ptr<MacroAction> MacroActionMacro::Copy() const
|
std::shared_ptr<MacroAction> MacroActionMacro::Copy() const
|
||||||
{
|
{
|
||||||
auto copy = std::make_shared<MacroActionMacro>(*this);
|
return std::make_shared<MacroActionMacro>(*this);
|
||||||
|
|
||||||
// Create a new nested macro
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
|
||||||
_nestedMacro->Save(data);
|
|
||||||
|
|
||||||
copy->_nestedMacro = std::make_shared<Macro>();
|
|
||||||
copy->_nestedMacro->Load(data);
|
|
||||||
copy->_nestedMacro->PostLoad();
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacro::ResolveVariablesToFixedValues()
|
void MacroActionMacro::ResolveVariablesToFixedValues()
|
||||||
{
|
{
|
||||||
_actionIndex.ResolveVariables();
|
_actionIndex.ResolveVariables();
|
||||||
_label.ResolveVariables();
|
|
||||||
|
|
||||||
if (_action == Action::NESTED_MACRO) {
|
|
||||||
for (auto &action : _nestedMacro->Actions()) {
|
|
||||||
action->ResolveVariablesToFixedValues();
|
|
||||||
}
|
|
||||||
for (auto &action : _nestedMacro->ElseActions()) {
|
|
||||||
action->ResolveVariablesToFixedValues();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void runActionsHelper(Macro *macro, bool runElseActions, bool setInputs,
|
static void runActionsHelper(Macro *macro, bool runElseActions, bool setInputs,
|
||||||
@@ -363,56 +192,6 @@ void MacroActionMacro::RunActions(Macro *actionMacro) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacro::SetAction(Action action)
|
|
||||||
{
|
|
||||||
_action = action;
|
|
||||||
SetupTempVars();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMacro::SetupTempVars()
|
|
||||||
{
|
|
||||||
MacroAction::SetupTempVars();
|
|
||||||
|
|
||||||
if (_action != Action::GET_INFO) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddTempvar(
|
|
||||||
"conditionCount",
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.conditionCount"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.conditionCount.description"));
|
|
||||||
AddTempvar(
|
|
||||||
"actionCount",
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.actionCount"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.actionCount.description"));
|
|
||||||
AddTempvar(
|
|
||||||
"elseActionCount",
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.elseActionCount"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.elseActionCount.description"));
|
|
||||||
AddTempvar(
|
|
||||||
"paused",
|
|
||||||
obs_module_text("AdvSceneSwitcher.tempVar.macro.info.paused"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.paused.description"));
|
|
||||||
AddTempvar(
|
|
||||||
"runCount",
|
|
||||||
obs_module_text("AdvSceneSwitcher.tempVar.macro.info.runCount"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.runCount.description"));
|
|
||||||
AddTempvar(
|
|
||||||
"secondsSinceLastRun",
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.secondsSinceLastRun"),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.macro.info.secondsSinceLastRun.description"));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void populateActionSelection(QComboBox *list)
|
static void populateActionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
static const std::vector<std::pair<MacroActionMacro::Action, std::string>>
|
static const std::vector<std::pair<MacroActionMacro::Action, std::string>>
|
||||||
@@ -425,12 +204,8 @@ static void populateActionSelection(QComboBox *list)
|
|||||||
"AdvSceneSwitcher.action.macro.type.togglePause"},
|
"AdvSceneSwitcher.action.macro.type.togglePause"},
|
||||||
{MacroActionMacro::Action::RESET_COUNTER,
|
{MacroActionMacro::Action::RESET_COUNTER,
|
||||||
"AdvSceneSwitcher.action.macro.type.resetCounter"},
|
"AdvSceneSwitcher.action.macro.type.resetCounter"},
|
||||||
{MacroActionMacro::Action::NESTED_MACRO,
|
{MacroActionMacro::Action::RUN,
|
||||||
"AdvSceneSwitcher.action.macro.type.nestedMacro"},
|
"AdvSceneSwitcher.action.macro.type.run"},
|
||||||
{MacroActionMacro::Action::RUN_ACTIONS,
|
|
||||||
"AdvSceneSwitcher.action.macro.type.runActions"},
|
|
||||||
{MacroActionMacro::Action::RUN_MACRO,
|
|
||||||
"AdvSceneSwitcher.action.macro.type.runMacro"},
|
|
||||||
{MacroActionMacro::Action::STOP,
|
{MacroActionMacro::Action::STOP,
|
||||||
"AdvSceneSwitcher.action.macro.type.stop"},
|
"AdvSceneSwitcher.action.macro.type.stop"},
|
||||||
{MacroActionMacro::Action::DISABLE_ACTION,
|
{MacroActionMacro::Action::DISABLE_ACTION,
|
||||||
@@ -439,8 +214,6 @@ static void populateActionSelection(QComboBox *list)
|
|||||||
"AdvSceneSwitcher.action.macro.type.enableAction"},
|
"AdvSceneSwitcher.action.macro.type.enableAction"},
|
||||||
{MacroActionMacro::Action::TOGGLE_ACTION,
|
{MacroActionMacro::Action::TOGGLE_ACTION,
|
||||||
"AdvSceneSwitcher.action.macro.type.toggleAction"},
|
"AdvSceneSwitcher.action.macro.type.toggleAction"},
|
||||||
{MacroActionMacro::Action::GET_INFO,
|
|
||||||
"AdvSceneSwitcher.action.macro.type.getInfo"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &[value, name] : actions) {
|
for (const auto &[value, name] : actions) {
|
||||||
@@ -459,7 +232,7 @@ static void populateConditionBehaviorSelection(QComboBox *list)
|
|||||||
"AdvSceneSwitcher.action.macro.type.run.conditions.false"));
|
"AdvSceneSwitcher.action.macro.type.run.conditions.false"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void populateActionSectionSelection(QComboBox *list)
|
static void populateActionTypeSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
list->addItem(obs_module_text(
|
list->addItem(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.macro.type.run.actionType.regular"));
|
"AdvSceneSwitcher.action.macro.type.run.actionType.regular"));
|
||||||
@@ -467,99 +240,49 @@ static void populateActionSectionSelection(QComboBox *list)
|
|||||||
"AdvSceneSwitcher.action.macro.type.run.actionType.else"));
|
"AdvSceneSwitcher.action.macro.type.run.actionType.else"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void populateActionTypes(QComboBox *list)
|
|
||||||
{
|
|
||||||
for (const auto &[id, info] : MacroActionFactory::GetActionTypes()) {
|
|
||||||
list->addItem(obs_module_text(info._name.c_str()),
|
|
||||||
QString::fromStdString(id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void populateActionSelectionTypes(QComboBox *list)
|
|
||||||
{
|
|
||||||
list->addItem(
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.macro.actionSelectionType.index"),
|
|
||||||
static_cast<int>(MacroActionMacro::SelectionType::INDEX));
|
|
||||||
list->addItem(
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.macro.actionSelectionType.label"),
|
|
||||||
static_cast<int>(MacroActionMacro::SelectionType::LABEL));
|
|
||||||
list->addItem(
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.macro.actionSelectionType.id"),
|
|
||||||
static_cast<int>(MacroActionMacro::SelectionType::ID));
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroActionMacroEdit::MacroActionMacroEdit(
|
MacroActionMacroEdit::MacroActionMacroEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionMacro> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionMacro> entryData)
|
||||||
: ResizableWidget(parent),
|
: QWidget(parent),
|
||||||
_actions(new QComboBox()),
|
|
||||||
_macros(new MacroSelection(parent)),
|
_macros(new MacroSelection(parent)),
|
||||||
_actionSelectionType(new QComboBox(this)),
|
|
||||||
_actionIndex(new MacroSegmentSelection(
|
_actionIndex(new MacroSegmentSelection(
|
||||||
this, MacroSegmentSelection::Type::ACTION)),
|
this, MacroSegmentSelection::Type::ACTION)),
|
||||||
_label(new VariableLineEdit(this)),
|
_actions(new QComboBox()),
|
||||||
_actionTypes(new FilterComboBox(this)),
|
|
||||||
_regex(new RegexConfigWidget(this)),
|
|
||||||
_conditionMacros(new MacroSelection(parent)),
|
_conditionMacros(new MacroSelection(parent)),
|
||||||
_conditionBehaviors(new QComboBox()),
|
_conditionBehaviors(new QComboBox()),
|
||||||
_reevaluateConditionState(new QCheckBox(
|
_reevaluateConditionState(new QCheckBox(
|
||||||
obs_module_text("AdvSceneSwitcher.action.macro.type.run."
|
obs_module_text("AdvSceneSwitcher.action.macro.type.run."
|
||||||
"updateConditionMatchState"))),
|
"updateConditionMatchState"))),
|
||||||
_actionSections(new QComboBox(this)),
|
_actionTypes(new QComboBox()),
|
||||||
_skipWhenPaused(new QCheckBox(obs_module_text(
|
_skipWhenPaused(new QCheckBox(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.macro.type.run.skipWhenPaused"))),
|
"AdvSceneSwitcher.action.macro.type.run.skipWhenPaused"))),
|
||||||
_noConditionsWarning(new QLabel(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.macro.type.runMacro.noConditionsWarning"))),
|
|
||||||
_runMacroHelp(new HelpIcon(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.macro.type.runMacro.help"))),
|
|
||||||
_setInputs(new QCheckBox(obs_module_text(
|
_setInputs(new QCheckBox(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.macro.type.run.setInputs"))),
|
"AdvSceneSwitcher.action.macro.type.run.setInputs"))),
|
||||||
_inputs(new MacroInputEdit()),
|
_inputs(new MacroInputEdit()),
|
||||||
_entryLayout(new QHBoxLayout()),
|
_entryLayout(new QHBoxLayout()),
|
||||||
_conditionLayout(new QHBoxLayout()),
|
_conditionLayout(new QHBoxLayout()),
|
||||||
_reevaluateConditionStateLayout(new QHBoxLayout()),
|
_reevaluateConditionStateLayout(new QHBoxLayout()),
|
||||||
_setInputsLayout(new QHBoxLayout()),
|
_setInputsLayout(new QHBoxLayout())
|
||||||
_nestedMacro(new MacroEdit(
|
|
||||||
this,
|
|
||||||
QStringList()
|
|
||||||
<< "AdvSceneSwitcher.action.macro.type.nestedMacro.conditionHelp"
|
|
||||||
<< "AdvSceneSwitcher.action.macro.type.nestedMacro.actionHelp"
|
|
||||||
<< "AdvSceneSwitcher.action.macro.type.nestedMacro.elseActionHelp"))
|
|
||||||
{
|
{
|
||||||
populateActionSelection(_actions);
|
populateActionSelection(_actions);
|
||||||
populateConditionBehaviorSelection(_conditionBehaviors);
|
populateConditionBehaviorSelection(_conditionBehaviors);
|
||||||
populateActionSectionSelection(_actionSections);
|
populateActionTypeSelection(_actionTypes);
|
||||||
populateActionSelectionTypes(_actionSelectionType);
|
|
||||||
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 &)));
|
||||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(ActionChanged(int)));
|
SLOT(ActionChanged(int)));
|
||||||
QWidget::connect(_actionSelectionType, SIGNAL(currentIndexChanged(int)),
|
|
||||||
this, SLOT(ActionSelectionTypeChanged(int)));
|
|
||||||
QWidget::connect(_actionIndex,
|
QWidget::connect(_actionIndex,
|
||||||
SIGNAL(SelectionChanged(const IntVariable &)), this,
|
SIGNAL(SelectionChanged(const IntVariable &)), this,
|
||||||
SLOT(ActionIndexChanged(const IntVariable &)));
|
SLOT(ActionIndexChanged(const IntVariable &)));
|
||||||
QWidget::connect(_label, SIGNAL(editingFinished()), this,
|
|
||||||
SLOT(LabelChanged()));
|
|
||||||
QWidget::connect(_actionTypes, SIGNAL(currentIndexChanged(int)), this,
|
|
||||||
SLOT(ActionTypeChanged(int)));
|
|
||||||
QWidget::connect(_regex,
|
|
||||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
|
||||||
SLOT(RegexChanged(const RegexConfig &)));
|
|
||||||
QWidget::connect(_conditionMacros,
|
QWidget::connect(_conditionMacros,
|
||||||
SIGNAL(currentTextChanged(const QString &)), this,
|
SIGNAL(currentTextChanged(const QString &)), this,
|
||||||
SLOT(ConditionMacroChanged(const QString &)));
|
SLOT(ConditionMacroChanged(const QString &)));
|
||||||
QWidget::connect(_conditionBehaviors, SIGNAL(currentIndexChanged(int)),
|
QWidget::connect(_conditionBehaviors, SIGNAL(currentIndexChanged(int)),
|
||||||
this, SLOT(ConditionBehaviorChanged(int)));
|
this, SLOT(ConditionBehaviorChanged(int)));
|
||||||
QWidget::connect(_actionSections, SIGNAL(currentIndexChanged(int)),
|
QWidget::connect(_actionTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||||
this, SLOT(ActionSectionChanged(int)));
|
SLOT(ActionTypeChanged(int)));
|
||||||
QWidget::connect(_skipWhenPaused, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(_skipWhenPaused, SIGNAL(stateChanged(int)), this,
|
||||||
SLOT(SkipWhenPausedChanged(int)));
|
SLOT(SkipWhenPausedChanged(int)));
|
||||||
QWidget::connect(_setInputs, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(_setInputs, SIGNAL(stateChanged(int)), this,
|
||||||
@@ -587,8 +310,6 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
|||||||
layout->addLayout(_setInputsLayout);
|
layout->addLayout(_setInputsLayout);
|
||||||
layout->addWidget(_inputs);
|
layout->addWidget(_inputs);
|
||||||
layout->addWidget(_skipWhenPaused);
|
layout->addWidget(_skipWhenPaused);
|
||||||
layout->addWidget(_noConditionsWarning);
|
|
||||||
layout->addWidget(_nestedMacro);
|
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
UpdateEntryData();
|
UpdateEntryData();
|
||||||
@@ -600,12 +321,6 @@ void HighlightMacroSettingsButton(bool enable);
|
|||||||
MacroActionMacroEdit::~MacroActionMacroEdit()
|
MacroActionMacroEdit::~MacroActionMacroEdit()
|
||||||
{
|
{
|
||||||
HighlightMacroSettingsButton(false);
|
HighlightMacroSettingsButton(false);
|
||||||
|
|
||||||
if (!_entryData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_entryData->_customWidgetHeight = GetCustomHeight();
|
|
||||||
_nestedMacro->SetMacro({}); // Save splitter states
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::UpdateEntryData()
|
void MacroActionMacroEdit::UpdateEntryData()
|
||||||
@@ -613,42 +328,24 @@ void MacroActionMacroEdit::UpdateEntryData()
|
|||||||
if (!_entryData) {
|
if (!_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_actions->setCurrentIndex(
|
_actions->setCurrentIndex(
|
||||||
_actions->findData(static_cast<int>(_entryData->GetAction())));
|
_actions->findData(static_cast<int>(_entryData->_action)));
|
||||||
_actionSelectionType->setCurrentIndex(_actionSelectionType->findData(
|
|
||||||
static_cast<int>(_entryData->_actionSelectionType)));
|
|
||||||
_actionIndex->SetValue(_entryData->_actionIndex);
|
_actionIndex->SetValue(_entryData->_actionIndex);
|
||||||
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
|
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
|
||||||
_label->setText(_entryData->_label);
|
|
||||||
_actionTypes->setCurrentIndex(_actionTypes->findData(
|
|
||||||
QString::fromStdString(_entryData->_actionId)));
|
|
||||||
_regex->SetRegexConfig(_entryData->_regex);
|
|
||||||
_macros->SetCurrentMacro(_entryData->_macro);
|
_macros->SetCurrentMacro(_entryData->_macro);
|
||||||
_conditionMacros->SetCurrentMacro(_entryData->_runOptions.macro);
|
_conditionMacros->SetCurrentMacro(_entryData->_runOptions.macro);
|
||||||
_conditionBehaviors->setCurrentIndex(
|
_conditionBehaviors->setCurrentIndex(
|
||||||
static_cast<int>(_entryData->_runOptions.logic));
|
static_cast<int>(_entryData->_runOptions.logic));
|
||||||
_reevaluateConditionState->setChecked(
|
_reevaluateConditionState->setChecked(
|
||||||
_entryData->_runOptions.reevaluateConditionState);
|
_entryData->_runOptions.reevaluateConditionState);
|
||||||
_actionSections->setCurrentIndex(
|
_actionTypes->setCurrentIndex(
|
||||||
_entryData->_runOptions.runElseActions ? 1 : 0);
|
_entryData->_runOptions.runElseActions ? 1 : 0);
|
||||||
_skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused);
|
_skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused);
|
||||||
_setInputs->setChecked(_entryData->_runOptions.setInputs);
|
_setInputs->setChecked(_entryData->_runOptions.setInputs);
|
||||||
SetupMacroInput(_entryData->_macro.GetMacro().get());
|
SetupMacroInput(_entryData->_macro.GetMacro().get());
|
||||||
|
|
||||||
const auto ¯o = _entryData->_nestedMacro;
|
|
||||||
_nestedMacro->SetMacro(macro);
|
|
||||||
|
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *MacroActionMacroEdit::Create(QWidget *parent,
|
|
||||||
std::shared_ptr<MacroAction> action)
|
|
||||||
{
|
|
||||||
return new MacroActionMacroEdit(
|
|
||||||
parent, std::dynamic_pointer_cast<MacroActionMacro>(action));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMacroEdit::MacroChanged(const QString &text)
|
void MacroActionMacroEdit::MacroChanged(const QString &text)
|
||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
@@ -664,17 +361,8 @@ void MacroActionMacroEdit::MacroChanged(const QString &text)
|
|||||||
void MacroActionMacroEdit::ActionChanged(int idx)
|
void MacroActionMacroEdit::ActionChanged(int idx)
|
||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
_entryData->SetAction(static_cast<MacroActionMacro::Action>(
|
_entryData->_action = static_cast<MacroActionMacro::Action>(
|
||||||
_actions->itemData(idx).toInt()));
|
_actions->itemData(idx).toInt());
|
||||||
SetWidgetVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMacroEdit::ActionSelectionTypeChanged(int idx)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_actionSelectionType =
|
|
||||||
static_cast<MacroActionMacro::SelectionType>(
|
|
||||||
_actionSelectionType->itemData(idx).toInt());
|
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,25 +372,6 @@ void MacroActionMacroEdit::ActionIndexChanged(const IntVariable &value)
|
|||||||
_entryData->_actionIndex = value;
|
_entryData->_actionIndex = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::LabelChanged()
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_label = _label->text().toStdString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMacroEdit::ActionTypeChanged(int idx)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_actionId =
|
|
||||||
_actionTypes->itemData(idx).toString().toStdString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMacroEdit::RegexChanged(const RegexConfig ®ex)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_regex = regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMacroEdit::ConditionMacroChanged(const QString &text)
|
void MacroActionMacroEdit::ConditionMacroChanged(const QString &text)
|
||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
@@ -724,13 +393,10 @@ void MacroActionMacroEdit::ReevaluateConditionStateChanged(int value)
|
|||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::ActionSectionChanged(int useElse)
|
void MacroActionMacroEdit::ActionTypeChanged(int value)
|
||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
_entryData->_runOptions.runElseActions = useElse;
|
_entryData->_runOptions.runElseActions = value;
|
||||||
_entryData->_useElseSection = useElse;
|
|
||||||
_actionIndex->SetType(useElse ? MacroSegmentSelection::Type::ELSE_ACTION
|
|
||||||
: MacroSegmentSelection::Type::ACTION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::SkipWhenPausedChanged(int value)
|
void MacroActionMacroEdit::SkipWhenPausedChanged(int value)
|
||||||
@@ -757,14 +423,9 @@ void MacroActionMacroEdit::InputsChanged(const StringList &inputs)
|
|||||||
void MacroActionMacroEdit::SetWidgetVisibility()
|
void MacroActionMacroEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
_entryLayout->removeWidget(_actions);
|
_entryLayout->removeWidget(_actions);
|
||||||
_entryLayout->removeWidget(_runMacroHelp);
|
|
||||||
_entryLayout->removeWidget(_actionIndex);
|
_entryLayout->removeWidget(_actionIndex);
|
||||||
_entryLayout->removeWidget(_macros);
|
_entryLayout->removeWidget(_macros);
|
||||||
_entryLayout->removeWidget(_actionSections);
|
|
||||||
_entryLayout->removeWidget(_label);
|
|
||||||
_entryLayout->removeWidget(_regex);
|
|
||||||
_entryLayout->removeWidget(_actionTypes);
|
_entryLayout->removeWidget(_actionTypes);
|
||||||
_entryLayout->removeWidget(_actionSelectionType);
|
|
||||||
_conditionLayout->removeWidget(_conditionBehaviors);
|
_conditionLayout->removeWidget(_conditionBehaviors);
|
||||||
_conditionLayout->removeWidget(_conditionMacros);
|
_conditionLayout->removeWidget(_conditionMacros);
|
||||||
|
|
||||||
@@ -773,47 +434,20 @@ void MacroActionMacroEdit::SetWidgetVisibility()
|
|||||||
|
|
||||||
const std::unordered_map<std::string, QWidget *> placeholders = {
|
const std::unordered_map<std::string, QWidget *> placeholders = {
|
||||||
{"{{actions}}", _actions},
|
{"{{actions}}", _actions},
|
||||||
{"{{runMacroHelp}}", _runMacroHelp},
|
|
||||||
{"{{actionIndex}}", _actionIndex},
|
{"{{actionIndex}}", _actionIndex},
|
||||||
{"{{macros}}", _macros},
|
{"{{macros}}", _macros},
|
||||||
{"{{actionSections}}", _actionSections},
|
{"{{actionTypes}}", _actionTypes},
|
||||||
{"{{conditionBehaviors}}", _conditionBehaviors},
|
{"{{conditionBehaviors}}", _conditionBehaviors},
|
||||||
{"{{conditionMacros}}", _conditionMacros},
|
{"{{conditionMacros}}", _conditionMacros},
|
||||||
{"{{actionSelectionType}}", _actionSelectionType},
|
|
||||||
{"{{label}}", _label},
|
|
||||||
{"{{regex}}", _regex},
|
|
||||||
{"{{actionTypes}}", _actionTypes},
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto action = _entryData->GetAction();
|
PlaceWidgets(
|
||||||
const char *layoutText = "";
|
obs_module_text(
|
||||||
switch (action) {
|
_entryData->_action == MacroActionMacro::Action::RUN
|
||||||
case MacroActionMacro::Action::PAUSE:
|
? "AdvSceneSwitcher.action.macro.entry.run"
|
||||||
case MacroActionMacro::Action::UNPAUSE:
|
: "AdvSceneSwitcher.action.macro.entry.other"),
|
||||||
case MacroActionMacro::Action::TOGGLE_PAUSE:
|
_entryLayout, placeholders);
|
||||||
case MacroActionMacro::Action::RESET_COUNTER:
|
|
||||||
case MacroActionMacro::Action::STOP:
|
|
||||||
case MacroActionMacro::Action::NESTED_MACRO:
|
|
||||||
case MacroActionMacro::Action::GET_INFO:
|
|
||||||
layoutText = "AdvSceneSwitcher.action.macro.layout.other";
|
|
||||||
break;
|
|
||||||
case MacroActionMacro::Action::RUN_MACRO:
|
|
||||||
layoutText = "AdvSceneSwitcher.action.macro.layout.runMacro";
|
|
||||||
break;
|
|
||||||
case MacroActionMacro::Action::RUN_ACTIONS:
|
|
||||||
layoutText = "AdvSceneSwitcher.action.macro.layout.run";
|
|
||||||
break;
|
|
||||||
case MacroActionMacro::Action::DISABLE_ACTION:
|
|
||||||
case MacroActionMacro::Action::ENABLE_ACTION:
|
|
||||||
case MacroActionMacro::Action::TOGGLE_ACTION:
|
|
||||||
layoutText = "AdvSceneSwitcher.action.macro.layout.actionState";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaceWidgets(obs_module_text(layoutText), _entryLayout, placeholders);
|
|
||||||
|
|
||||||
if (_entryData->_runOptions.logic ==
|
if (_entryData->_runOptions.logic ==
|
||||||
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS) {
|
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS) {
|
||||||
@@ -822,82 +456,47 @@ void MacroActionMacroEdit::SetWidgetVisibility()
|
|||||||
} else {
|
} else {
|
||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.action.macro.layout.run.condition"),
|
"AdvSceneSwitcher.action.macro.entry.run.condition"),
|
||||||
_conditionLayout, placeholders);
|
_conditionLayout, placeholders);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == MacroActionMacro::Action::RUN_ACTIONS ||
|
if (_entryData->_action == MacroActionMacro::Action::RUN ||
|
||||||
action == MacroActionMacro::Action::STOP ||
|
_entryData->_action == MacroActionMacro::Action::STOP) {
|
||||||
action == MacroActionMacro::Action::RUN_MACRO) {
|
|
||||||
_macros->HideSelectedMacro();
|
_macros->HideSelectedMacro();
|
||||||
} else {
|
} else {
|
||||||
_macros->ShowAllMacros();
|
_macros->ShowAllMacros();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto actionSelectionType = _entryData->_actionSelectionType;
|
|
||||||
const bool isModifyingActionState =
|
const bool isModifyingActionState =
|
||||||
action == MacroActionMacro::Action::DISABLE_ACTION ||
|
_entryData->_action ==
|
||||||
action == MacroActionMacro::Action::ENABLE_ACTION ||
|
MacroActionMacro::Action::DISABLE_ACTION ||
|
||||||
action == MacroActionMacro::Action::TOGGLE_ACTION;
|
_entryData->_action ==
|
||||||
_actionSelectionType->setVisible(isModifyingActionState);
|
MacroActionMacro::Action::ENABLE_ACTION ||
|
||||||
_actionIndex->setVisible(
|
_entryData->_action == MacroActionMacro::Action::TOGGLE_ACTION;
|
||||||
isModifyingActionState &&
|
_actionIndex->setVisible(isModifyingActionState);
|
||||||
actionSelectionType == MacroActionMacro::SelectionType::INDEX);
|
|
||||||
_label->setVisible(isModifyingActionState &&
|
|
||||||
actionSelectionType ==
|
|
||||||
MacroActionMacro::SelectionType::LABEL);
|
|
||||||
_regex->setVisible(isModifyingActionState &&
|
|
||||||
actionSelectionType ==
|
|
||||||
MacroActionMacro::SelectionType::LABEL);
|
|
||||||
_actionTypes->setVisible(isModifyingActionState &&
|
|
||||||
actionSelectionType ==
|
|
||||||
MacroActionMacro::SelectionType::ID);
|
|
||||||
|
|
||||||
SetLayoutVisible(_conditionLayout,
|
SetLayoutVisible(_conditionLayout,
|
||||||
action == MacroActionMacro::Action::RUN_ACTIONS);
|
_entryData->_action == MacroActionMacro::Action::RUN);
|
||||||
const bool needsAdditionalConditionWidgets =
|
const bool needsAdditionalConditionWidgets =
|
||||||
action == MacroActionMacro::Action::RUN_ACTIONS &&
|
_entryData->_action == MacroActionMacro::Action::RUN &&
|
||||||
_entryData->_runOptions.logic !=
|
_entryData->_runOptions.logic !=
|
||||||
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS;
|
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS;
|
||||||
_conditionMacros->setVisible(needsAdditionalConditionWidgets);
|
_conditionMacros->setVisible(needsAdditionalConditionWidgets);
|
||||||
SetLayoutVisible(_reevaluateConditionStateLayout,
|
SetLayoutVisible(_reevaluateConditionStateLayout,
|
||||||
needsAdditionalConditionWidgets);
|
needsAdditionalConditionWidgets);
|
||||||
SetLayoutVisible(_setInputsLayout,
|
SetLayoutVisible(_setInputsLayout,
|
||||||
action == MacroActionMacro::Action::RUN_ACTIONS);
|
_entryData->_action == MacroActionMacro::Action::RUN);
|
||||||
_inputs->setVisible(action == MacroActionMacro::Action::RUN_ACTIONS &&
|
_inputs->setVisible(_entryData->_action ==
|
||||||
|
MacroActionMacro::Action::RUN &&
|
||||||
_entryData->_runOptions.setInputs);
|
_entryData->_runOptions.setInputs);
|
||||||
HighlightMacroSettingsButton(
|
HighlightMacroSettingsButton(_entryData->_action ==
|
||||||
action == MacroActionMacro::Action::RUN_ACTIONS &&
|
MacroActionMacro::Action::RUN &&
|
||||||
_entryData->_runOptions.setInputs &&
|
_entryData->_runOptions.setInputs &&
|
||||||
!_inputs->HasInputsToSet());
|
!_inputs->HasInputsToSet());
|
||||||
_actionSections->setVisible(
|
_actionTypes->setVisible(_entryData->_action ==
|
||||||
action == MacroActionMacro::Action::RUN_ACTIONS ||
|
MacroActionMacro::Action::RUN);
|
||||||
isModifyingActionState);
|
_skipWhenPaused->setVisible(_entryData->_action ==
|
||||||
_skipWhenPaused->setVisible(
|
MacroActionMacro::Action::RUN);
|
||||||
action == MacroActionMacro::Action::RUN_ACTIONS ||
|
|
||||||
action == MacroActionMacro::Action::RUN_MACRO);
|
|
||||||
|
|
||||||
if (action == MacroActionMacro::Action::RUN_MACRO) {
|
|
||||||
auto macro = _entryData->_macro.GetMacro();
|
|
||||||
_noConditionsWarning->setVisible(!macro ||
|
|
||||||
macro->Conditions().empty());
|
|
||||||
} else {
|
|
||||||
_noConditionsWarning->setVisible(false);
|
|
||||||
}
|
|
||||||
_runMacroHelp->setVisible(action ==
|
|
||||||
MacroActionMacro::Action::RUN_MACRO);
|
|
||||||
|
|
||||||
_nestedMacro->setVisible(action ==
|
|
||||||
MacroActionMacro::Action::NESTED_MACRO);
|
|
||||||
_macros->setVisible(action != MacroActionMacro::Action::NESTED_MACRO);
|
|
||||||
SetResizingEnabled(action == MacroActionMacro::Action::NESTED_MACRO);
|
|
||||||
|
|
||||||
if (_nestedMacro->IsEmpty()) {
|
|
||||||
_nestedMacro->ShowAllMacroSections();
|
|
||||||
// TODO: find a better solution than setting a fixed height
|
|
||||||
_entryData->_customWidgetHeight = 600;
|
|
||||||
}
|
|
||||||
SetCustomHeight(_entryData->_customWidgetHeight);
|
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "macro.hpp"
|
|
||||||
#include "macro-edit.hpp"
|
|
||||||
#include "macro-input.hpp"
|
#include "macro-input.hpp"
|
||||||
#include "macro-selection.hpp"
|
#include "macro-selection.hpp"
|
||||||
#include "macro-segment-selection.hpp"
|
#include "macro-segment-selection.hpp"
|
||||||
#include "regex-config.hpp"
|
|
||||||
#include "resizable-widget.hpp"
|
|
||||||
#include "variable-line-edit.hpp"
|
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -50,44 +44,25 @@ public:
|
|||||||
PAUSE,
|
PAUSE,
|
||||||
UNPAUSE,
|
UNPAUSE,
|
||||||
RESET_COUNTER,
|
RESET_COUNTER,
|
||||||
RUN_ACTIONS,
|
RUN,
|
||||||
STOP,
|
STOP,
|
||||||
DISABLE_ACTION,
|
DISABLE_ACTION,
|
||||||
ENABLE_ACTION,
|
ENABLE_ACTION,
|
||||||
TOGGLE_ACTION,
|
TOGGLE_ACTION,
|
||||||
TOGGLE_PAUSE,
|
TOGGLE_PAUSE,
|
||||||
NESTED_MACRO,
|
|
||||||
GET_INFO,
|
|
||||||
RUN_MACRO,
|
|
||||||
};
|
};
|
||||||
|
Action _action = Action::RUN;
|
||||||
void SetAction(Action);
|
|
||||||
Action GetAction() const { return _action; }
|
|
||||||
|
|
||||||
enum class SelectionType { INDEX, LABEL, ID };
|
|
||||||
|
|
||||||
SelectionType _actionSelectionType = SelectionType::INDEX;
|
|
||||||
bool _useElseSection = false;
|
|
||||||
IntVariable _actionIndex = 1;
|
IntVariable _actionIndex = 1;
|
||||||
StringVariable _label = "Custom label";
|
|
||||||
std::string _actionId;
|
|
||||||
RegexConfig _regex;
|
|
||||||
RunOptions _runOptions = {};
|
RunOptions _runOptions = {};
|
||||||
std::shared_ptr<Macro> _nestedMacro = std::make_shared<Macro>();
|
|
||||||
int _customWidgetHeight = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupTempVars();
|
|
||||||
void RunActions(Macro *actionMacro) const;
|
void RunActions(Macro *actionMacro) const;
|
||||||
void AdjustActionState(Macro *) const;
|
|
||||||
|
|
||||||
Action _action = Action::NESTED_MACRO;
|
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionMacroEdit final : public ResizableWidget {
|
class MacroActionMacroEdit final : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -96,20 +71,22 @@ public:
|
|||||||
std::shared_ptr<MacroActionMacro> entryData = nullptr);
|
std::shared_ptr<MacroActionMacro> entryData = nullptr);
|
||||||
~MacroActionMacroEdit();
|
~MacroActionMacroEdit();
|
||||||
void UpdateEntryData();
|
void UpdateEntryData();
|
||||||
static QWidget *Create(QWidget *, std::shared_ptr<MacroAction>);
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionMacroEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionMacro>(action));
|
||||||
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void MacroChanged(const QString &text);
|
void MacroChanged(const QString &text);
|
||||||
void ActionChanged(int value);
|
void ActionChanged(int value);
|
||||||
void ActionSelectionTypeChanged(int value);
|
|
||||||
void ActionIndexChanged(const IntVariable &value);
|
void ActionIndexChanged(const IntVariable &value);
|
||||||
void LabelChanged();
|
|
||||||
void ActionTypeChanged(int value);
|
|
||||||
void RegexChanged(const RegexConfig &);
|
|
||||||
void ConditionMacroChanged(const QString &text);
|
void ConditionMacroChanged(const QString &text);
|
||||||
void ConditionBehaviorChanged(int value);
|
void ConditionBehaviorChanged(int value);
|
||||||
void ReevaluateConditionStateChanged(int value);
|
void ReevaluateConditionStateChanged(int value);
|
||||||
void ActionSectionChanged(int value);
|
void ActionTypeChanged(int value);
|
||||||
void SkipWhenPausedChanged(int value);
|
void SkipWhenPausedChanged(int value);
|
||||||
void SetInputsChanged(int value);
|
void SetInputsChanged(int value);
|
||||||
void InputsChanged(const StringList &);
|
void InputsChanged(const StringList &);
|
||||||
@@ -121,27 +98,20 @@ private:
|
|||||||
void SetWidgetVisibility();
|
void SetWidgetVisibility();
|
||||||
void SetupMacroInput(Macro *) const;
|
void SetupMacroInput(Macro *) const;
|
||||||
|
|
||||||
QComboBox *_actions;
|
|
||||||
MacroSelection *_macros;
|
MacroSelection *_macros;
|
||||||
QComboBox *_actionSelectionType;
|
|
||||||
MacroSegmentSelection *_actionIndex;
|
MacroSegmentSelection *_actionIndex;
|
||||||
VariableLineEdit *_label;
|
QComboBox *_actions;
|
||||||
FilterComboBox *_actionTypes;
|
|
||||||
RegexConfigWidget *_regex;
|
|
||||||
MacroSelection *_conditionMacros;
|
MacroSelection *_conditionMacros;
|
||||||
QComboBox *_conditionBehaviors;
|
QComboBox *_conditionBehaviors;
|
||||||
QCheckBox *_reevaluateConditionState;
|
QCheckBox *_reevaluateConditionState;
|
||||||
QComboBox *_actionSections;
|
QComboBox *_actionTypes;
|
||||||
QCheckBox *_skipWhenPaused;
|
QCheckBox *_skipWhenPaused;
|
||||||
QLabel *_noConditionsWarning;
|
|
||||||
HelpIcon *_runMacroHelp;
|
|
||||||
QCheckBox *_setInputs;
|
QCheckBox *_setInputs;
|
||||||
MacroInputEdit *_inputs;
|
MacroInputEdit *_inputs;
|
||||||
QHBoxLayout *_entryLayout;
|
QHBoxLayout *_entryLayout;
|
||||||
QHBoxLayout *_conditionLayout;
|
QHBoxLayout *_conditionLayout;
|
||||||
QHBoxLayout *_reevaluateConditionStateLayout;
|
QHBoxLayout *_reevaluateConditionStateLayout;
|
||||||
QHBoxLayout *_setInputsLayout;
|
QHBoxLayout *_setInputsLayout;
|
||||||
MacroEdit *_nestedMacro;
|
|
||||||
|
|
||||||
std::shared_ptr<MacroActionMacro> _entryData;
|
std::shared_ptr<MacroActionMacro> _entryData;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
#include "macro-action-variable.hpp"
|
#include "macro-action-variable.hpp"
|
||||||
#include "help-icon.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
#include "json-helpers.hpp"
|
#include "json-helpers.hpp"
|
||||||
#include "layout-helpers.hpp"
|
#include "layout-helpers.hpp"
|
||||||
#include "macro-condition-edit.hpp"
|
|
||||||
#include "macro-signals.hpp"
|
|
||||||
#include "math-helpers.hpp"
|
#include "math-helpers.hpp"
|
||||||
|
#include "macro-condition-edit.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "non-modal-dialog.hpp"
|
#include "non-modal-dialog.hpp"
|
||||||
#include "source-helpers.hpp"
|
#include "source-helpers.hpp"
|
||||||
@@ -17,15 +16,6 @@ namespace advss {
|
|||||||
|
|
||||||
const std::string MacroActionVariable::id = "variable";
|
const std::string MacroActionVariable::id = "variable";
|
||||||
|
|
||||||
std::vector<TempVariableRef> MacroActionVariable::GetTempVarRefs() const
|
|
||||||
{
|
|
||||||
auto refs = MacroSegment::GetTempVarRefs();
|
|
||||||
if (_tempVar.HasValidID()) {
|
|
||||||
refs.push_back(_tempVar);
|
|
||||||
}
|
|
||||||
return refs;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionVariable::_registered = MacroActionFactory::Register(
|
bool MacroActionVariable::_registered = MacroActionFactory::Register(
|
||||||
MacroActionVariable::id,
|
MacroActionVariable::id,
|
||||||
{MacroActionVariable::Create, MacroActionVariableEdit::Create,
|
{MacroActionVariable::Create, MacroActionVariableEdit::Create,
|
||||||
@@ -228,43 +218,6 @@ void MacroActionVariable::GenerateRandomNumber(Variable *var)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionVariable::PickRandomValue(Variable *var)
|
|
||||||
{
|
|
||||||
static std::random_device rd;
|
|
||||||
static std::mt19937 gen(rd());
|
|
||||||
static const uint8_t maxIter = 255;
|
|
||||||
|
|
||||||
if (_randomValues.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_randomValues.size() == 1) {
|
|
||||||
const auto &value = _randomValues.at(0);
|
|
||||||
var->SetValue(value);
|
|
||||||
_lastRandomValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uniform_int_distribution<int> dis(0, _randomValues.size() - 1);
|
|
||||||
StringVariable value = _randomValues.at(dis(gen));
|
|
||||||
|
|
||||||
uint8_t iter = 0;
|
|
||||||
for (; !_allowRepeatValues && iter < maxIter &&
|
|
||||||
_lastRandomValue.has_value() &&
|
|
||||||
std::string(value) == _lastRandomValue.value();
|
|
||||||
iter++) {
|
|
||||||
value = _randomValues.at(dis(gen));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter == maxIter) {
|
|
||||||
blog(LOG_INFO,
|
|
||||||
"giving up picking non-repeat random value after %d tries",
|
|
||||||
maxIter);
|
|
||||||
}
|
|
||||||
|
|
||||||
var->SetValue(value);
|
|
||||||
_lastRandomValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AskForInputParams {
|
struct AskForInputParams {
|
||||||
AskForInputParams(const QString &prompt_, const QString &placeholder_)
|
AskForInputParams(const QString &prompt_, const QString &placeholder_)
|
||||||
: prompt(prompt_),
|
: prompt(prompt_),
|
||||||
@@ -332,14 +285,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) {
|
||||||
@@ -447,19 +392,7 @@ bool MacroActionVariable::PerformAction()
|
|||||||
if (!value.has_value()) {
|
if (!value.has_value()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
var->SetValue(*value);
|
||||||
if (!_jsonQueryExtractSingle) {
|
|
||||||
var->SetValue(*value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto extracted = ExtractSingleJsonArrayElement(*value);
|
|
||||||
if (extracted.has_value()) {
|
|
||||||
var->SetValue(*extracted);
|
|
||||||
} else {
|
|
||||||
var->SetValue(*value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case Action::ARRAY_JSON: {
|
case Action::ARRAY_JSON: {
|
||||||
@@ -516,9 +449,6 @@ bool MacroActionVariable::PerformAction()
|
|||||||
case Action::RANDOM_NUMBER:
|
case Action::RANDOM_NUMBER:
|
||||||
GenerateRandomNumber(var.get());
|
GenerateRandomNumber(var.get());
|
||||||
return true;
|
return true;
|
||||||
case Action::RANDOM_LIST_VALUE:
|
|
||||||
PickRandomValue(var.get());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -550,7 +480,7 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
|
|||||||
_inputPlaceholder.Save(obj, "inputPlaceholder");
|
_inputPlaceholder.Save(obj, "inputPlaceholder");
|
||||||
_envVariableName.Save(obj, "environmentVariableName");
|
_envVariableName.Save(obj, "environmentVariableName");
|
||||||
_scene.Save(obj);
|
_scene.Save(obj);
|
||||||
_tempVar.Save(obj, GetMacro());
|
_tempVar.Save(obj);
|
||||||
_sceneItemIndex.Save(obj, "sceneItemIndex");
|
_sceneItemIndex.Save(obj, "sceneItemIndex");
|
||||||
obs_data_set_int(obj, "direction", static_cast<int>(_direction));
|
obs_data_set_int(obj, "direction", static_cast<int>(_direction));
|
||||||
_stringLength.Save(obj, "stringLength");
|
_stringLength.Save(obj, "stringLength");
|
||||||
@@ -559,12 +489,8 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
|
|||||||
_randomNumberStart.Save(obj, "randomNumberStart");
|
_randomNumberStart.Save(obj, "randomNumberStart");
|
||||||
_randomNumberEnd.Save(obj, "randomNumberEnd");
|
_randomNumberEnd.Save(obj, "randomNumberEnd");
|
||||||
obs_data_set_bool(obj, "generateInteger", _generateInteger);
|
obs_data_set_bool(obj, "generateInteger", _generateInteger);
|
||||||
_randomValues.Save(obj, "randomValues", "value");
|
|
||||||
obs_data_set_bool(obj, "allowRepeatValues", _allowRepeatValues);
|
|
||||||
_jsonQuery.Save(obj, "jsonQuery");
|
_jsonQuery.Save(obj, "jsonQuery");
|
||||||
_jsonIndex.Save(obj, "jsonIndex");
|
_jsonIndex.Save(obj, "jsonIndex");
|
||||||
obs_data_set_bool(obj, "jsonQueryExtractSingle",
|
|
||||||
_jsonQueryExtractSingle);
|
|
||||||
|
|
||||||
obs_data_set_int(obj, "version", 1);
|
obs_data_set_int(obj, "version", 1);
|
||||||
|
|
||||||
@@ -621,12 +547,8 @@ bool MacroActionVariable::Load(obs_data_t *obj)
|
|||||||
_randomNumberStart.Load(obj, "randomNumberStart");
|
_randomNumberStart.Load(obj, "randomNumberStart");
|
||||||
_randomNumberEnd.Load(obj, "randomNumberEnd");
|
_randomNumberEnd.Load(obj, "randomNumberEnd");
|
||||||
_generateInteger = obs_data_get_bool(obj, "generateInteger");
|
_generateInteger = obs_data_get_bool(obj, "generateInteger");
|
||||||
_randomValues.Load(obj, "randomValues", "value");
|
|
||||||
_allowRepeatValues = obs_data_get_bool(obj, "allowRepeatValues");
|
|
||||||
_jsonQuery.Load(obj, "jsonQuery");
|
_jsonQuery.Load(obj, "jsonQuery");
|
||||||
_jsonIndex.Load(obj, "jsonIndex");
|
_jsonIndex.Load(obj, "jsonIndex");
|
||||||
_jsonQueryExtractSingle =
|
|
||||||
obs_data_get_bool(obj, "jsonQueryExtractSingle");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -747,8 +669,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,
|
||||||
@@ -793,8 +713,6 @@ static inline void populateActionSelection(QComboBox *list)
|
|||||||
"AdvSceneSwitcher.action.variable.type.roundToInt"},
|
"AdvSceneSwitcher.action.variable.type.roundToInt"},
|
||||||
{MacroActionVariable::Action::RANDOM_NUMBER,
|
{MacroActionVariable::Action::RANDOM_NUMBER,
|
||||||
"AdvSceneSwitcher.action.variable.type.randomNumber"},
|
"AdvSceneSwitcher.action.variable.type.randomNumber"},
|
||||||
{MacroActionVariable::Action::RANDOM_LIST_VALUE,
|
|
||||||
"AdvSceneSwitcher.action.variable.type.randomListValue"},
|
|
||||||
{true, ""}, // Separator
|
{true, ""}, // Separator
|
||||||
|
|
||||||
{MacroActionVariable::Action::USER_INPUT,
|
{MacroActionVariable::Action::USER_INPUT,
|
||||||
@@ -872,10 +790,11 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
_segmentValueStatus(new QLabel()),
|
_segmentValueStatus(new QLabel()),
|
||||||
_segmentValue(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
_segmentValue(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
||||||
_substringLayout(new QVBoxLayout()),
|
_substringLayout(new QVBoxLayout()),
|
||||||
_subStringControlsLayout(new QHBoxLayout()),
|
_subStringIndexEntryLayout(new QHBoxLayout()),
|
||||||
|
_subStringRegexEntryLayout(new QHBoxLayout()),
|
||||||
_subStringStart(new VariableSpinBox(this)),
|
_subStringStart(new VariableSpinBox(this)),
|
||||||
_subStringSize(new VariableSpinBox(this)),
|
_subStringSize(new VariableSpinBox(this)),
|
||||||
_subStringRegex(new RegexConfigWidget(parent)),
|
_substringRegex(new RegexConfigWidget(parent)),
|
||||||
_regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
_regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
||||||
_regexMatchIdx(new VariableSpinBox(this)),
|
_regexMatchIdx(new VariableSpinBox(this)),
|
||||||
_findReplaceLayout(new QHBoxLayout()),
|
_findReplaceLayout(new QHBoxLayout()),
|
||||||
@@ -907,28 +826,10 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.generateInteger"),
|
"AdvSceneSwitcher.action.variable.generateInteger"),
|
||||||
this)),
|
this)),
|
||||||
_randomNumberLayout(new QVBoxLayout()),
|
_randomLayout(new QVBoxLayout()),
|
||||||
_randomValues(new StringListEdit(this)),
|
|
||||||
_allowRepeatValues(new QCheckBox(
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.variable.type.allowRepeat"),
|
|
||||||
this)),
|
|
||||||
_randomValueLayout(new QVBoxLayout()),
|
|
||||||
_jsonQuery(new VariableLineEdit(this)),
|
_jsonQuery(new VariableLineEdit(this)),
|
||||||
_jsonQueryHelp(new HelpIcon(
|
_jsonQueryHelp(new QLabel(this)),
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.variable.type.queryJson.info"),
|
|
||||||
this)),
|
|
||||||
_jsonIndex(new VariableSpinBox(this)),
|
_jsonIndex(new VariableSpinBox(this)),
|
||||||
_jsonExtractSingle(new QCheckBox(
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.variable.type.queryJson.extractSingle"),
|
|
||||||
this)),
|
|
||||||
_jsonExtractSingleHelp(new HelpIcon(
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.variable.type.queryJson.extractSingle.info"),
|
|
||||||
this)),
|
|
||||||
_jsonQueryLayout(new QVBoxLayout()),
|
|
||||||
_entryLayout(new QHBoxLayout())
|
_entryLayout(new QHBoxLayout())
|
||||||
{
|
{
|
||||||
_numValue->setMinimum(-9999999999);
|
_numValue->setMinimum(-9999999999);
|
||||||
@@ -958,13 +859,15 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
_randomNumberStart->setMaximum(9999999999);
|
_randomNumberStart->setMaximum(9999999999);
|
||||||
_randomNumberEnd->setMinimum(-9999999999);
|
_randomNumberEnd->setMinimum(-9999999999);
|
||||||
_randomNumberEnd->setMaximum(9999999999);
|
_randomNumberEnd->setMaximum(9999999999);
|
||||||
_randomValues->SetMaxStringSize(99999999);
|
const QString path = GetThemeTypeName() == "Light"
|
||||||
|
? ":/res/images/help.svg"
|
||||||
|
: ":/res/images/help_light.svg";
|
||||||
|
const QIcon icon(path);
|
||||||
|
const QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||||
|
_jsonQueryHelp->setPixmap(pixmap);
|
||||||
|
_jsonQueryHelp->setToolTip(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.type.queryJson.info"));
|
||||||
_jsonIndex->setMaximum(999);
|
_jsonIndex->setMaximum(999);
|
||||||
auto jsonExtractSingleLayout = new QHBoxLayout();
|
|
||||||
jsonExtractSingleLayout->addWidget(_jsonExtractSingle);
|
|
||||||
jsonExtractSingleLayout->addWidget(_jsonExtractSingleHelp);
|
|
||||||
jsonExtractSingleLayout->addStretch();
|
|
||||||
_jsonQueryLayout->addLayout(jsonExtractSingleLayout);
|
|
||||||
|
|
||||||
QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)),
|
QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)),
|
||||||
this, SLOT(VariableChanged(const QString &)));
|
this, SLOT(VariableChanged(const QString &)));
|
||||||
@@ -981,8 +884,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
QWidget::connect(_segmentIdx,
|
QWidget::connect(_segmentIdx,
|
||||||
SIGNAL(SelectionChanged(const IntVariable &)), this,
|
SIGNAL(SelectionChanged(const IntVariable &)), this,
|
||||||
SLOT(SegmentIndexChanged(const IntVariable &)));
|
SLOT(SegmentIndexChanged(const IntVariable &)));
|
||||||
QWidget::connect(MacroSignalManager::Instance(),
|
QWidget::connect(window(), SIGNAL(MacroSegmentOrderChanged()), this,
|
||||||
SIGNAL(SegmentOrderChanged()), this,
|
|
||||||
SLOT(MacroSegmentOrderChanged()));
|
SLOT(MacroSegmentOrderChanged()));
|
||||||
QWidget::connect(
|
QWidget::connect(
|
||||||
_subStringStart,
|
_subStringStart,
|
||||||
@@ -992,7 +894,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
_subStringSize,
|
_subStringSize,
|
||||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||||
this, SLOT(SubStringSizeChanged(const NumberVariable<int> &)));
|
this, SLOT(SubStringSizeChanged(const NumberVariable<int> &)));
|
||||||
QWidget::connect(_subStringRegex,
|
QWidget::connect(_substringRegex,
|
||||||
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
|
||||||
SLOT(SubStringRegexChanged(const RegexConfig &)));
|
SLOT(SubStringRegexChanged(const RegexConfig &)));
|
||||||
QWidget::connect(_regexPattern, SIGNAL(textChanged()), this,
|
QWidget::connect(_regexPattern, SIGNAL(textChanged()), this,
|
||||||
@@ -1052,19 +954,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
SLOT(RandomNumberEndChanged(const NumberVariable<double> &)));
|
SLOT(RandomNumberEndChanged(const NumberVariable<double> &)));
|
||||||
QWidget::connect(_generateInteger, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(_generateInteger, SIGNAL(stateChanged(int)), this,
|
||||||
SLOT(GenerateIntegerChanged(int)));
|
SLOT(GenerateIntegerChanged(int)));
|
||||||
QWidget::connect(_randomValues,
|
|
||||||
SIGNAL(StringListChanged(const StringList &)), this,
|
|
||||||
SLOT(RandomValueListChanged(const StringList &)));
|
|
||||||
QWidget::connect(_allowRepeatValues, SIGNAL(stateChanged(int)), this,
|
|
||||||
SLOT(AllowRepeatValuesChanged(int)));
|
|
||||||
QWidget::connect(_jsonQuery, SIGNAL(editingFinished()), this,
|
QWidget::connect(_jsonQuery, SIGNAL(editingFinished()), this,
|
||||||
SLOT(JsonQueryChanged()));
|
SLOT(JsonQueryChanged()));
|
||||||
QWidget::connect(
|
QWidget::connect(
|
||||||
_jsonIndex,
|
_jsonIndex,
|
||||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||||
this, SLOT(JsonIndexChanged(const NumberVariable<int> &)));
|
this, SLOT(JsonIndexChanged(const NumberVariable<int> &)));
|
||||||
QWidget::connect(_jsonExtractSingle, SIGNAL(stateChanged(int)), this,
|
|
||||||
SLOT(JsonQueryExtractSingleChanged(int)));
|
|
||||||
|
|
||||||
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{variables}}", _variables},
|
{"{{variables}}", _variables},
|
||||||
@@ -1073,6 +968,9 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
{"{{strValue}}", _strValue},
|
{"{{strValue}}", _strValue},
|
||||||
{"{{numValue}}", _numValue},
|
{"{{numValue}}", _numValue},
|
||||||
{"{{segmentIndex}}", _segmentIdx},
|
{"{{segmentIndex}}", _segmentIdx},
|
||||||
|
{"{{subStringStart}}", _subStringStart},
|
||||||
|
{"{{subStringSize}}", _subStringSize},
|
||||||
|
{"{{regexMatchIdx}}", _regexMatchIdx},
|
||||||
{"{{findRegex}}", _findRegex},
|
{"{{findRegex}}", _findRegex},
|
||||||
{"{{findStr}}", _findStr},
|
{"{{findStr}}", _findStr},
|
||||||
{"{{replaceStr}}", _replaceStr},
|
{"{{replaceStr}}", _replaceStr},
|
||||||
@@ -1104,7 +1002,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.layout.substringIndex"),
|
"AdvSceneSwitcher.action.variable.layout.substringIndex"),
|
||||||
_subStringControlsLayout, widgetPlaceholders);
|
_subStringIndexEntryLayout, widgetPlaceholders);
|
||||||
|
|
||||||
|
PlaceWidgets(
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.layout.substringRegex"),
|
||||||
|
_subStringRegexEntryLayout, widgetPlaceholders);
|
||||||
|
|
||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
@@ -1125,23 +1028,20 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.layout.randomNumber"),
|
"AdvSceneSwitcher.action.variable.layout.randomNumber"),
|
||||||
randomLayout, widgetPlaceholders);
|
randomLayout, widgetPlaceholders);
|
||||||
_randomNumberLayout->addLayout(randomLayout);
|
_randomLayout->addLayout(randomLayout);
|
||||||
_randomNumberLayout->addWidget(_generateInteger);
|
_randomLayout->addWidget(_generateInteger);
|
||||||
|
|
||||||
_randomValueLayout->addWidget(_randomValues);
|
|
||||||
_randomValueLayout->addWidget(_allowRepeatValues);
|
|
||||||
|
|
||||||
auto regexConfigLayout = new QHBoxLayout;
|
auto regexConfigLayout = new QHBoxLayout;
|
||||||
regexConfigLayout->addWidget(_subStringRegex);
|
regexConfigLayout->addWidget(_substringRegex);
|
||||||
regexConfigLayout->addStretch();
|
regexConfigLayout->addStretch();
|
||||||
|
|
||||||
_substringLayout->addLayout(_subStringControlsLayout);
|
_substringLayout->addLayout(_subStringIndexEntryLayout);
|
||||||
|
_substringLayout->addLayout(_subStringRegexEntryLayout);
|
||||||
_substringLayout->addWidget(_regexPattern);
|
_substringLayout->addWidget(_regexPattern);
|
||||||
_substringLayout->addLayout(regexConfigLayout);
|
_substringLayout->addLayout(regexConfigLayout);
|
||||||
|
|
||||||
auto layout = new QVBoxLayout;
|
auto layout = new QVBoxLayout;
|
||||||
layout->addLayout(_entryLayout);
|
layout->addLayout(_entryLayout);
|
||||||
layout->addLayout(_jsonQueryLayout);
|
|
||||||
layout->addLayout(_substringLayout);
|
layout->addLayout(_substringLayout);
|
||||||
layout->addWidget(_segmentValueStatus);
|
layout->addWidget(_segmentValueStatus);
|
||||||
layout->addWidget(_segmentValue);
|
layout->addWidget(_segmentValue);
|
||||||
@@ -1149,8 +1049,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
layout->addWidget(_mathExpressionResult);
|
layout->addWidget(_mathExpressionResult);
|
||||||
layout->addLayout(_promptLayout);
|
layout->addLayout(_promptLayout);
|
||||||
layout->addLayout(_placeholderLayout);
|
layout->addLayout(_placeholderLayout);
|
||||||
layout->addLayout(_randomNumberLayout);
|
layout->addLayout(_randomLayout);
|
||||||
layout->addLayout(_randomValueLayout);
|
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
@@ -1184,7 +1083,7 @@ void MacroActionVariableEdit::UpdateEntryData()
|
|||||||
: MacroSegmentSelection::Type::ACTION);
|
: MacroSegmentSelection::Type::ACTION);
|
||||||
_subStringStart->SetValue(_entryData->_subStringStart);
|
_subStringStart->SetValue(_entryData->_subStringStart);
|
||||||
_subStringSize->SetValue(_entryData->_subStringSize);
|
_subStringSize->SetValue(_entryData->_subStringSize);
|
||||||
_subStringRegex->SetRegexConfig(_entryData->_subStringRegex);
|
_substringRegex->SetRegexConfig(_entryData->_subStringRegex);
|
||||||
_findRegex->SetRegexConfig(_entryData->_findRegex);
|
_findRegex->SetRegexConfig(_entryData->_findRegex);
|
||||||
_regexPattern->setPlainText(
|
_regexPattern->setPlainText(
|
||||||
QString::fromStdString(_entryData->_regexPattern));
|
QString::fromStdString(_entryData->_regexPattern));
|
||||||
@@ -1209,11 +1108,8 @@ void MacroActionVariableEdit::UpdateEntryData()
|
|||||||
_randomNumberStart->SetValue(_entryData->_randomNumberStart);
|
_randomNumberStart->SetValue(_entryData->_randomNumberStart);
|
||||||
_randomNumberEnd->SetValue(_entryData->_randomNumberEnd);
|
_randomNumberEnd->SetValue(_entryData->_randomNumberEnd);
|
||||||
_generateInteger->setChecked(_entryData->_generateInteger);
|
_generateInteger->setChecked(_entryData->_generateInteger);
|
||||||
_allowRepeatValues->setChecked(_entryData->_allowRepeatValues);
|
|
||||||
_randomValues->SetStringList(_entryData->_randomValues);
|
|
||||||
_jsonQuery->setText(_entryData->_jsonQuery);
|
_jsonQuery->setText(_entryData->_jsonQuery);
|
||||||
_jsonIndex->SetValue(_entryData->_jsonIndex);
|
_jsonIndex->SetValue(_entryData->_jsonIndex);
|
||||||
_jsonExtractSingle->setChecked(_entryData->_jsonQueryExtractSingle);
|
|
||||||
|
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
@@ -1493,7 +1389,6 @@ void MacroActionVariableEdit::SelectionChanged(const TempVariableRef &var)
|
|||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
_entryData->_tempVar = var;
|
_entryData->_tempVar = var;
|
||||||
IncrementTempVarInUseGeneration();
|
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1555,18 +1450,6 @@ void MacroActionVariableEdit::GenerateIntegerChanged(int value)
|
|||||||
_entryData->_generateInteger = value;
|
_entryData->_generateInteger = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionVariableEdit::RandomValueListChanged(const StringList &values)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_randomValues = values;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionVariableEdit::AllowRepeatValuesChanged(int value)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_allowRepeatValues = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionVariableEdit::JsonQueryChanged()
|
void MacroActionVariableEdit::JsonQueryChanged()
|
||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
@@ -1579,12 +1462,6 @@ void MacroActionVariableEdit::JsonIndexChanged(const NumberVariable<int> &value)
|
|||||||
_entryData->_jsonIndex = value;
|
_entryData->_jsonIndex = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionVariableEdit::JsonQueryExtractSingleChanged(int value)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_jsonQueryExtractSingle = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionVariableEdit::SetWidgetVisibility()
|
void MacroActionVariableEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
if (!_entryData) {
|
if (!_entryData) {
|
||||||
@@ -1611,20 +1488,8 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
{"{{jsonQuery}}", _jsonQuery},
|
{"{{jsonQuery}}", _jsonQuery},
|
||||||
{"{{jsonQueryHelp}}", _jsonQueryHelp},
|
{"{{jsonQueryHelp}}", _jsonQueryHelp},
|
||||||
{"{{jsonIndex}}", _jsonIndex},
|
{"{{jsonIndex}}", _jsonIndex},
|
||||||
{"{{subStringRegex}}", _subStringRegex},
|
|
||||||
{"{{subStringStart}}", _subStringStart},
|
|
||||||
{"{{subStringSize}}", _subStringSize},
|
|
||||||
{"{{regexMatchIdx}}", _regexMatchIdx},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto &[_, widget] : widgetPlaceholders) {
|
|
||||||
_entryLayout->removeWidget(widget);
|
|
||||||
_subStringControlsLayout->removeWidget(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearLayout(_entryLayout);
|
|
||||||
ClearLayout(_subStringControlsLayout);
|
|
||||||
|
|
||||||
const char *layoutString = "";
|
const char *layoutString = "";
|
||||||
if (_entryData->_action == MacroActionVariable::Action::PAD) {
|
if (_entryData->_action == MacroActionVariable::Action::PAD) {
|
||||||
layoutString = obs_module_text(
|
layoutString = obs_module_text(
|
||||||
@@ -1633,15 +1498,16 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
MacroActionVariable::Action::TRUNCATE) {
|
MacroActionVariable::Action::TRUNCATE) {
|
||||||
layoutString = obs_module_text(
|
layoutString = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.layout.truncate");
|
"AdvSceneSwitcher.action.variable.layout.truncate");
|
||||||
} else if (_entryData->_action ==
|
|
||||||
MacroActionVariable::Action::COPY_VAR) {
|
|
||||||
layoutString = obs_module_text(
|
|
||||||
"AdvSceneSwitcher.action.variable.layout.copy");
|
|
||||||
} else {
|
} else {
|
||||||
layoutString = obs_module_text(
|
layoutString = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.layout.other");
|
"AdvSceneSwitcher.action.variable.layout.other");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto &[_, widget] : widgetPlaceholders) {
|
||||||
|
_entryLayout->removeWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearLayout(_entryLayout);
|
||||||
PlaceWidgets(layoutString, _entryLayout, widgetPlaceholders);
|
PlaceWidgets(layoutString, _entryLayout, widgetPlaceholders);
|
||||||
|
|
||||||
if (_entryData->_action == MacroActionVariable::Action::SET_VALUE ||
|
if (_entryData->_action == MacroActionVariable::Action::SET_VALUE ||
|
||||||
@@ -1658,7 +1524,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 ==
|
||||||
@@ -1688,25 +1553,15 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
MacroActionVariable::Action::SET_ACTION_VALUE ||
|
MacroActionVariable::Action::SET_ACTION_VALUE ||
|
||||||
_entryData->_action ==
|
_entryData->_action ==
|
||||||
MacroActionVariable::Action::SET_CONDITION_VALUE);
|
MacroActionVariable::Action::SET_CONDITION_VALUE);
|
||||||
|
|
||||||
bool showRegex = _entryData->_subStringRegex.Enabled();
|
|
||||||
layoutString =
|
|
||||||
showRegex
|
|
||||||
? "AdvSceneSwitcher.action.variable.layout.substringRegex"
|
|
||||||
: "AdvSceneSwitcher.action.variable.layout.substringIndex";
|
|
||||||
PlaceWidgets(obs_module_text(layoutString), _subStringControlsLayout,
|
|
||||||
widgetPlaceholders);
|
|
||||||
_subStringStart->setVisible(!showRegex);
|
|
||||||
_subStringSize->setVisible(!showRegex);
|
|
||||||
_regexMatchIdx->setVisible(showRegex);
|
|
||||||
|
|
||||||
SetLayoutVisible(_substringLayout,
|
SetLayoutVisible(_substringLayout,
|
||||||
_entryData->_action ==
|
_entryData->_action ==
|
||||||
MacroActionVariable::Action::SUBSTRING);
|
MacroActionVariable::Action::SUBSTRING);
|
||||||
_regexPattern->setVisible(
|
if (_entryData->_action == MacroActionVariable::Action::SUBSTRING) {
|
||||||
showRegex &&
|
bool showRegex = _entryData->_subStringRegex.Enabled();
|
||||||
_entryData->_action == MacroActionVariable::Action::SUBSTRING);
|
SetLayoutVisible(_subStringIndexEntryLayout, !showRegex);
|
||||||
|
SetLayoutVisible(_subStringRegexEntryLayout, showRegex);
|
||||||
|
_regexPattern->setVisible(showRegex);
|
||||||
|
}
|
||||||
SetLayoutVisible(_findReplaceLayout,
|
SetLayoutVisible(_findReplaceLayout,
|
||||||
_entryData->_action ==
|
_entryData->_action ==
|
||||||
MacroActionVariable::Action::FIND_AND_REPLACE);
|
MacroActionVariable::Action::FIND_AND_REPLACE);
|
||||||
@@ -1771,22 +1626,15 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
MacroActionVariable::Action::PAD);
|
MacroActionVariable::Action::PAD);
|
||||||
_caseType->setVisible(_entryData->_action ==
|
_caseType->setVisible(_entryData->_action ==
|
||||||
MacroActionVariable::Action::CHANGE_CASE);
|
MacroActionVariable::Action::CHANGE_CASE);
|
||||||
SetLayoutVisible(_randomNumberLayout,
|
SetLayoutVisible(_randomLayout,
|
||||||
_entryData->_action ==
|
_entryData->_action ==
|
||||||
MacroActionVariable::Action::RANDOM_NUMBER);
|
MacroActionVariable::Action::RANDOM_NUMBER);
|
||||||
SetLayoutVisible(
|
|
||||||
_randomValueLayout,
|
|
||||||
_entryData->_action ==
|
|
||||||
MacroActionVariable::Action::RANDOM_LIST_VALUE);
|
|
||||||
_jsonQuery->setVisible(_entryData->_action ==
|
_jsonQuery->setVisible(_entryData->_action ==
|
||||||
MacroActionVariable::Action::QUERY_JSON);
|
MacroActionVariable::Action::QUERY_JSON);
|
||||||
_jsonQueryHelp->setVisible(_entryData->_action ==
|
_jsonQueryHelp->setVisible(_entryData->_action ==
|
||||||
MacroActionVariable::Action::QUERY_JSON);
|
MacroActionVariable::Action::QUERY_JSON);
|
||||||
_jsonIndex->setVisible(_entryData->_action ==
|
_jsonIndex->setVisible(_entryData->_action ==
|
||||||
MacroActionVariable::Action::ARRAY_JSON);
|
MacroActionVariable::Action::ARRAY_JSON);
|
||||||
SetLayoutVisible(_jsonQueryLayout,
|
|
||||||
_entryData->_action ==
|
|
||||||
MacroActionVariable::Action::QUERY_JSON);
|
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include "resizing-text-edit.hpp"
|
#include "resizing-text-edit.hpp"
|
||||||
#include "scene-selection.hpp"
|
#include "scene-selection.hpp"
|
||||||
#include "single-char-selection.hpp"
|
#include "single-char-selection.hpp"
|
||||||
#include "string-list.hpp"
|
|
||||||
#include "variable-line-edit.hpp"
|
#include "variable-line-edit.hpp"
|
||||||
#include "variable-text-edit.hpp"
|
#include "variable-text-edit.hpp"
|
||||||
#include "variable-spinbox.hpp"
|
#include "variable-spinbox.hpp"
|
||||||
@@ -23,7 +22,6 @@ public:
|
|||||||
bool PostLoad();
|
bool PostLoad();
|
||||||
std::string GetShortDesc() const;
|
std::string GetShortDesc() const;
|
||||||
std::string GetId() const { return id; };
|
std::string GetId() const { return id; };
|
||||||
std::vector<TempVariableRef> GetTempVarRefs() const;
|
|
||||||
static std::shared_ptr<MacroAction> Create(Macro *m);
|
static std::shared_ptr<MacroAction> Create(Macro *m);
|
||||||
std::shared_ptr<MacroAction> Copy() const;
|
std::shared_ptr<MacroAction> Copy() const;
|
||||||
void SetSegmentIndexValue(int);
|
void SetSegmentIndexValue(int);
|
||||||
@@ -57,8 +55,6 @@ public:
|
|||||||
RANDOM_NUMBER,
|
RANDOM_NUMBER,
|
||||||
QUERY_JSON,
|
QUERY_JSON,
|
||||||
ARRAY_JSON,
|
ARRAY_JSON,
|
||||||
COPY_VAR,
|
|
||||||
RANDOM_LIST_VALUE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Action _action = Action::SET_VALUE;
|
Action _action = Action::SET_VALUE;
|
||||||
@@ -110,13 +106,8 @@ public:
|
|||||||
DoubleVariable _randomNumberEnd = 100;
|
DoubleVariable _randomNumberEnd = 100;
|
||||||
bool _generateInteger = true;
|
bool _generateInteger = true;
|
||||||
|
|
||||||
StringList _randomValues = {"value1", "value2", "value3"};
|
|
||||||
bool _allowRepeatValues = true;
|
|
||||||
std::optional<std::string> _lastRandomValue;
|
|
||||||
|
|
||||||
StringVariable _jsonQuery = "$.some.nested.value";
|
StringVariable _jsonQuery = "$.some.nested.value";
|
||||||
IntVariable _jsonIndex = 0;
|
IntVariable _jsonIndex = 0;
|
||||||
bool _jsonQueryExtractSingle = true;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DecrementCurrentSegmentVariableRef();
|
void DecrementCurrentSegmentVariableRef();
|
||||||
@@ -127,7 +118,6 @@ private:
|
|||||||
void HandleCaseChange(Variable *);
|
void HandleCaseChange(Variable *);
|
||||||
void SetToSceneItemName(Variable *);
|
void SetToSceneItemName(Variable *);
|
||||||
void GenerateRandomNumber(Variable *);
|
void GenerateRandomNumber(Variable *);
|
||||||
void PickRandomValue(Variable *);
|
|
||||||
|
|
||||||
std::weak_ptr<MacroSegment> _macroSegment;
|
std::weak_ptr<MacroSegment> _macroSegment;
|
||||||
int _segmentIdxLoadValue = -1;
|
int _segmentIdxLoadValue = -1;
|
||||||
@@ -184,11 +174,8 @@ private slots:
|
|||||||
void RandomNumberStartChanged(const NumberVariable<double> &);
|
void RandomNumberStartChanged(const NumberVariable<double> &);
|
||||||
void RandomNumberEndChanged(const NumberVariable<double> &);
|
void RandomNumberEndChanged(const NumberVariable<double> &);
|
||||||
void GenerateIntegerChanged(int);
|
void GenerateIntegerChanged(int);
|
||||||
void RandomValueListChanged(const StringList &);
|
|
||||||
void AllowRepeatValuesChanged(int);
|
|
||||||
void JsonQueryChanged();
|
void JsonQueryChanged();
|
||||||
void JsonIndexChanged(const NumberVariable<int> &);
|
void JsonIndexChanged(const NumberVariable<int> &);
|
||||||
void JsonQueryExtractSingleChanged(int);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
@@ -206,10 +193,11 @@ private:
|
|||||||
QLabel *_segmentValueStatus;
|
QLabel *_segmentValueStatus;
|
||||||
ResizingPlainTextEdit *_segmentValue;
|
ResizingPlainTextEdit *_segmentValue;
|
||||||
QVBoxLayout *_substringLayout;
|
QVBoxLayout *_substringLayout;
|
||||||
QHBoxLayout *_subStringControlsLayout;
|
QHBoxLayout *_subStringIndexEntryLayout;
|
||||||
|
QHBoxLayout *_subStringRegexEntryLayout;
|
||||||
VariableSpinBox *_subStringStart;
|
VariableSpinBox *_subStringStart;
|
||||||
VariableSpinBox *_subStringSize;
|
VariableSpinBox *_subStringSize;
|
||||||
RegexConfigWidget *_subStringRegex;
|
RegexConfigWidget *_substringRegex;
|
||||||
ResizingPlainTextEdit *_regexPattern;
|
ResizingPlainTextEdit *_regexPattern;
|
||||||
VariableSpinBox *_regexMatchIdx;
|
VariableSpinBox *_regexMatchIdx;
|
||||||
QHBoxLayout *_findReplaceLayout;
|
QHBoxLayout *_findReplaceLayout;
|
||||||
@@ -236,16 +224,10 @@ private:
|
|||||||
VariableDoubleSpinBox *_randomNumberStart;
|
VariableDoubleSpinBox *_randomNumberStart;
|
||||||
VariableDoubleSpinBox *_randomNumberEnd;
|
VariableDoubleSpinBox *_randomNumberEnd;
|
||||||
QCheckBox *_generateInteger;
|
QCheckBox *_generateInteger;
|
||||||
QVBoxLayout *_randomNumberLayout;
|
QVBoxLayout *_randomLayout;
|
||||||
StringListEdit *_randomValues;
|
|
||||||
QCheckBox *_allowRepeatValues;
|
|
||||||
QVBoxLayout *_randomValueLayout;
|
|
||||||
VariableLineEdit *_jsonQuery;
|
VariableLineEdit *_jsonQuery;
|
||||||
HelpIcon *_jsonQueryHelp;
|
QLabel *_jsonQueryHelp;
|
||||||
VariableSpinBox *_jsonIndex;
|
VariableSpinBox *_jsonIndex;
|
||||||
QCheckBox *_jsonExtractSingle;
|
|
||||||
HelpIcon *_jsonExtractSingleHelp;
|
|
||||||
QVBoxLayout *_jsonQueryLayout;
|
|
||||||
QHBoxLayout *_entryLayout;
|
QHBoxLayout *_entryLayout;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionVariable> _entryData;
|
std::shared_ptr<MacroActionVariable> _entryData;
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
#include "macro-condition-edit.hpp"
|
#include "macro-condition-edit.hpp"
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
#include "condition-logic.hpp"
|
|
||||||
#include "macro-settings.hpp"
|
#include "macro-settings.hpp"
|
||||||
#include "macro-signals.hpp"
|
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "path-helpers.hpp"
|
#include "path-helpers.hpp"
|
||||||
#include "plugin-state-helpers.hpp"
|
#include "plugin-state-helpers.hpp"
|
||||||
#include "section.hpp"
|
#include "section.hpp"
|
||||||
#include "switch-button.hpp"
|
|
||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
@@ -104,17 +100,14 @@ 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),
|
||||||
_enable(new SwitchButton()),
|
|
||||||
_logicSelection(new QComboBox()),
|
_logicSelection(new QComboBox()),
|
||||||
_conditionSelection(new FilterComboBox()),
|
_conditionSelection(new FilterComboBox()),
|
||||||
_dur(new DurationModifierEdit()),
|
_dur(new DurationModifierEdit()),
|
||||||
_entryData(entryData),
|
_entryData(entryData),
|
||||||
_isRoot(isRootCondition)
|
_isRoot(isRootCondition)
|
||||||
{
|
{
|
||||||
QWidget::connect(_enable, SIGNAL(checked(bool)), this,
|
|
||||||
SLOT(ConditionEnableChanged(bool)));
|
|
||||||
QWidget::connect(_logicSelection, SIGNAL(currentIndexChanged(int)),
|
QWidget::connect(_logicSelection, SIGNAL(currentIndexChanged(int)),
|
||||||
this, SLOT(LogicSelectionChanged(int)));
|
this, SLOT(LogicSelectionChanged(int)));
|
||||||
QWidget::connect(_conditionSelection,
|
QWidget::connect(_conditionSelection,
|
||||||
@@ -129,17 +122,14 @@ MacroConditionEdit::MacroConditionEdit(
|
|||||||
Logic::PopulateLogicTypeSelection(_logicSelection, isRootCondition);
|
Logic::PopulateLogicTypeSelection(_logicSelection, isRootCondition);
|
||||||
populateConditionSelection(_conditionSelection);
|
populateConditionSelection(_conditionSelection);
|
||||||
|
|
||||||
_section->AddHeaderWidget(_enable);
|
|
||||||
_section->AddHeaderWidget(_logicSelection);
|
_section->AddHeaderWidget(_logicSelection);
|
||||||
_section->AddHeaderWidget(_conditionSelection);
|
_section->AddHeaderWidget(_conditionSelection);
|
||||||
_section->AddHeaderWidget(_headerInfo);
|
_section->AddHeaderWidget(_headerInfo);
|
||||||
_section->AddHeaderWidget(_dur);
|
_section->AddHeaderWidget(_dur);
|
||||||
_section->AddHeaderWidget(_varMappingToggle);
|
|
||||||
|
|
||||||
QVBoxLayout *conditionLayout = new QVBoxLayout;
|
QVBoxLayout *conditionLayout = new QVBoxLayout;
|
||||||
conditionLayout->setContentsMargins({7, 7, 7, 7});
|
conditionLayout->setContentsMargins({7, 7, 7, 7});
|
||||||
conditionLayout->addWidget(_section);
|
conditionLayout->addWidget(_section);
|
||||||
conditionLayout->addWidget(_outputMappings);
|
|
||||||
_contentLayout->addLayout(conditionLayout);
|
_contentLayout->addLayout(conditionLayout);
|
||||||
|
|
||||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||||
@@ -162,17 +152,8 @@ void MacroConditionEdit::LogicSelectionChanged(int idx)
|
|||||||
const auto logic = static_cast<Logic::Type>(
|
const auto logic = static_cast<Logic::Type>(
|
||||||
_logicSelection->itemData(idx).toInt());
|
_logicSelection->itemData(idx).toInt());
|
||||||
(*_entryData)->SetLogicType(logic);
|
(*_entryData)->SetLogicType(logic);
|
||||||
}
|
|
||||||
|
|
||||||
void MacroConditionEdit::ConditionEnableChanged(bool value)
|
SetEnableAppearance(logic != Logic::Type::NONE);
|
||||||
{
|
|
||||||
if (_loading || !_entryData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
|
||||||
(*_entryData)->SetEnabled(value);
|
|
||||||
SetDisableEffect(!value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionEdit::IsRootNode() const
|
bool MacroConditionEdit::IsRootNode() const
|
||||||
@@ -185,9 +166,7 @@ void MacroConditionEdit::SetLogicSelection()
|
|||||||
const auto logic = (*_entryData)->GetLogicType();
|
const auto logic = (*_entryData)->GetLogicType();
|
||||||
_logicSelection->setCurrentIndex(
|
_logicSelection->setCurrentIndex(
|
||||||
_logicSelection->findData(static_cast<int>(logic)));
|
_logicSelection->findData(static_cast<int>(logic)));
|
||||||
const bool enabled = (*_entryData)->Enabled();
|
SetEnableAppearance(logic != Logic::Type::NONE);
|
||||||
_enable->setChecked(enabled);
|
|
||||||
SetEnableAppearance(enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionEdit::SetRootNode(bool root)
|
void MacroConditionEdit::SetRootNode(bool root)
|
||||||
@@ -225,10 +204,7 @@ void MacroConditionEdit::SetupWidgets(bool basicSetup)
|
|||||||
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
||||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
|
||||||
SLOT(ShowVariableMappings(bool)));
|
|
||||||
_section->SetContent(widget, (*_entryData)->GetCollapsed());
|
_section->SetContent(widget, (*_entryData)->GetCollapsed());
|
||||||
SetupVarMappings((*_entryData).get());
|
|
||||||
SetFocusPolicyOfWidgets();
|
SetFocusPolicyOfWidgets();
|
||||||
|
|
||||||
_allWidgetsAreSetup = true;
|
_allWidgetsAreSetup = true;
|
||||||
@@ -258,28 +234,20 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
|
|||||||
{
|
{
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
auto logic = (*_entryData)->GetLogicType();
|
auto logic = (*_entryData)->GetLogicType();
|
||||||
const bool enabled = (*_entryData)->Enabled();
|
|
||||||
_entryData->reset();
|
_entryData->reset();
|
||||||
*_entryData = MacroConditionFactory::Create(id, macro);
|
*_entryData = MacroConditionFactory::Create(id, macro);
|
||||||
(*_entryData)->SetIndex(idx);
|
(*_entryData)->SetIndex(idx);
|
||||||
(*_entryData)->SetLogicType(logic);
|
(*_entryData)->SetLogicType(logic);
|
||||||
(*_entryData)->SetEnabled(enabled);
|
|
||||||
(*_entryData)->PostLoad();
|
(*_entryData)->PostLoad();
|
||||||
RunAndClearPostLoadSteps();
|
RunPostLoadSteps();
|
||||||
}
|
}
|
||||||
auto widget =
|
auto widget =
|
||||||
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
||||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
|
||||||
SLOT(ShowVariableMappings(bool)));
|
|
||||||
_section->SetContent(widget);
|
_section->SetContent(widget);
|
||||||
SetupVarMappings((*_entryData).get());
|
|
||||||
_dur->setVisible(MacroConditionFactory::UsesDurationModifier(id));
|
_dur->setVisible(MacroConditionFactory::UsesDurationModifier(id));
|
||||||
SetFocusPolicyOfWidgets();
|
SetFocusPolicyOfWidgets();
|
||||||
|
|
||||||
emit MacroSignalManager::Instance()->ConditionTypeCreated(
|
|
||||||
QString::fromStdString(id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionEdit::DurationChanged(const Duration &seconds)
|
void MacroConditionEdit::DurationChanged(const Duration &seconds)
|
||||||
@@ -307,9 +275,289 @@ std::shared_ptr<MacroSegment> MacroConditionEdit::Data() const
|
|||||||
return *_entryData;
|
return *_entryData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionEdit::FocusTypeSelection()
|
void AdvSceneSwitcher::AddMacroCondition(int idx)
|
||||||
{
|
{
|
||||||
_conditionSelection->setFocus();
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx > (int)macro->Conditions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string id;
|
||||||
|
Logic::Type logic;
|
||||||
|
if (idx >= 1) {
|
||||||
|
id = macro->Conditions().at(idx - 1)->GetId();
|
||||||
|
if (idx == 1) {
|
||||||
|
logic = Logic::Type::OR;
|
||||||
|
} else {
|
||||||
|
logic = macro->Conditions().at(idx - 1)->GetLogicType();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id = MacroCondition::GetDefaultID();
|
||||||
|
logic = Logic::Type::ROOT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSDataAutoRelease data;
|
||||||
|
if (idx - 1 >= 0) {
|
||||||
|
data = obs_data_create();
|
||||||
|
macro->Conditions().at(idx - 1)->Save(data);
|
||||||
|
}
|
||||||
|
AddMacroCondition(macro.get(), idx, id, data.Get(), logic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::AddMacroCondition(Macro *macro, int idx,
|
||||||
|
const std::string &id,
|
||||||
|
obs_data_t *data, Logic::Type logic)
|
||||||
|
{
|
||||||
|
if (idx < 0 || idx > (int)macro->Conditions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
auto cond = macro->Conditions().emplace(
|
||||||
|
macro->Conditions().begin() + idx,
|
||||||
|
MacroConditionFactory::Create(id, macro));
|
||||||
|
if (data) {
|
||||||
|
macro->Conditions().at(idx)->Load(data);
|
||||||
|
}
|
||||||
|
macro->Conditions().at(idx)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
|
(*cond)->SetLogicType(logic);
|
||||||
|
macro->UpdateConditionIndices();
|
||||||
|
ui->conditionsList->Insert(
|
||||||
|
idx,
|
||||||
|
new MacroConditionEdit(this, ¯o->Conditions()[idx],
|
||||||
|
id, idx == 0));
|
||||||
|
SetConditionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightCondition(idx);
|
||||||
|
ui->conditionsList->SetHelpMsgVisible(false);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_conditionAdd_clicked()
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentConditionIdx == -1) {
|
||||||
|
AddMacroCondition((int)macro->Conditions().size());
|
||||||
|
} else {
|
||||||
|
AddMacroCondition(currentConditionIdx + 1);
|
||||||
|
}
|
||||||
|
if (currentConditionIdx != -1) {
|
||||||
|
MacroConditionSelectionChanged(currentConditionIdx + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= (int)macro->Conditions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
ui->conditionsList->Remove(idx);
|
||||||
|
macro->Conditions().erase(macro->Conditions().begin() + idx);
|
||||||
|
macro->UpdateConditionIndices();
|
||||||
|
if (idx == 0 && macro->Conditions().size() > 0) {
|
||||||
|
auto newRoot = macro->Conditions().at(0);
|
||||||
|
newRoot->SetLogicType(Logic::Type::ROOT_NONE);
|
||||||
|
static_cast<MacroConditionEdit *>(
|
||||||
|
ui->conditionsList->WidgetAt(0))
|
||||||
|
->SetRootNode(true);
|
||||||
|
}
|
||||||
|
SetConditionData(*macro);
|
||||||
|
}
|
||||||
|
MacroConditionSelectionChanged(-1);
|
||||||
|
lastInteracted = MacroSection::CONDITIONS;
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_conditionRemove_clicked()
|
||||||
|
{
|
||||||
|
if (currentConditionIdx == -1) {
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RemoveMacroCondition((int)macro->Conditions().size() - 1);
|
||||||
|
} else {
|
||||||
|
RemoveMacroCondition(currentConditionIdx);
|
||||||
|
}
|
||||||
|
MacroConditionSelectionChanged(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_conditionTop_clicked()
|
||||||
|
{
|
||||||
|
if (currentConditionIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MacroConditionReorder(0, currentConditionIdx);
|
||||||
|
MacroConditionSelectionChanged(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_conditionUp_clicked()
|
||||||
|
{
|
||||||
|
if (currentConditionIdx == -1 || currentConditionIdx == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MoveMacroConditionUp(currentConditionIdx);
|
||||||
|
MacroConditionSelectionChanged(currentConditionIdx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_conditionDown_clicked()
|
||||||
|
{
|
||||||
|
if (currentConditionIdx == -1 ||
|
||||||
|
currentConditionIdx ==
|
||||||
|
ui->conditionsList->ContentLayout()->count() - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MoveMacroConditionDown(currentConditionIdx);
|
||||||
|
MacroConditionSelectionChanged(currentConditionIdx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_conditionBottom_clicked()
|
||||||
|
{
|
||||||
|
if (currentConditionIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const int newIdx = ui->conditionsList->ContentLayout()->count() - 1;
|
||||||
|
MacroConditionReorder(newIdx, currentConditionIdx);
|
||||||
|
MacroConditionSelectionChanged(newIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::SwapConditions(Macro *m, int pos1, int pos2)
|
||||||
|
{
|
||||||
|
if (pos1 == pos2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos1 > pos2) {
|
||||||
|
std::swap(pos1, pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool root = pos1 == 0;
|
||||||
|
auto lock = LockContext();
|
||||||
|
iter_swap(m->Conditions().begin() + pos1,
|
||||||
|
m->Conditions().begin() + pos2);
|
||||||
|
m->UpdateConditionIndices();
|
||||||
|
|
||||||
|
auto c1 = m->Conditions().begin() + pos1;
|
||||||
|
auto c2 = m->Conditions().begin() + pos2;
|
||||||
|
if (root) {
|
||||||
|
auto logic1 = (*c1)->GetLogicType();
|
||||||
|
auto logic2 = (*c2)->GetLogicType();
|
||||||
|
(*c1)->SetLogicType(logic2);
|
||||||
|
(*c2)->SetLogicType(logic1);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto widget1 = static_cast<MacroConditionEdit *>(
|
||||||
|
ui->conditionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||||
|
auto widget2 = static_cast<MacroConditionEdit *>(
|
||||||
|
ui->conditionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
||||||
|
ui->conditionsList->Insert(pos1, widget2);
|
||||||
|
ui->conditionsList->Insert(pos2, widget1);
|
||||||
|
SetConditionData(*m);
|
||||||
|
widget2->SetRootNode(root);
|
||||||
|
widget1->SetRootNode(false);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MoveMacroConditionUp(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 1 || idx >= (int)macro->Conditions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapConditions(macro.get(), idx, idx - 1);
|
||||||
|
HighlightCondition(idx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MoveMacroConditionDown(int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx < 0 || idx >= (int)macro->Conditions().size() - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapConditions(macro.get(), idx, idx + 1);
|
||||||
|
HighlightCondition(idx + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroConditionSelectionChanged(int idx)
|
||||||
|
{
|
||||||
|
SetupMacroSegmentSelection(MacroSection::CONDITIONS, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroConditionReorder(int to, int from)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to == from || from < 0 || from > (int)macro->Conditions().size() ||
|
||||||
|
to < 0 || to > (int)macro->Conditions().size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
auto condition = macro->Conditions().at(from);
|
||||||
|
if (to == 0) {
|
||||||
|
condition->SetLogicType(Logic::Type::ROOT_NONE);
|
||||||
|
static_cast<MacroConditionEdit *>(
|
||||||
|
ui->conditionsList->WidgetAt(from))
|
||||||
|
->SetRootNode(true);
|
||||||
|
macro->Conditions().at(0)->SetLogicType(
|
||||||
|
Logic::Type::AND);
|
||||||
|
static_cast<MacroConditionEdit *>(
|
||||||
|
ui->conditionsList->WidgetAt(0))
|
||||||
|
->SetRootNode(false);
|
||||||
|
}
|
||||||
|
if (from == 0) {
|
||||||
|
condition->SetLogicType(Logic::Type::AND);
|
||||||
|
static_cast<MacroConditionEdit *>(
|
||||||
|
ui->conditionsList->WidgetAt(from))
|
||||||
|
->SetRootNode(false);
|
||||||
|
macro->Conditions().at(1)->SetLogicType(
|
||||||
|
Logic::Type::ROOT_NONE);
|
||||||
|
static_cast<MacroConditionEdit *>(
|
||||||
|
ui->conditionsList->WidgetAt(1))
|
||||||
|
->SetRootNode(true);
|
||||||
|
}
|
||||||
|
macro->Conditions().erase(macro->Conditions().begin() + from);
|
||||||
|
macro->Conditions().insert(macro->Conditions().begin() + to,
|
||||||
|
condition);
|
||||||
|
macro->UpdateConditionIndices();
|
||||||
|
ui->conditionsList->ContentLayout()->insertItem(
|
||||||
|
to, ui->conditionsList->ContentLayout()->takeAt(from));
|
||||||
|
SetConditionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightCondition(to);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
class SwitchButton;
|
|
||||||
|
|
||||||
class DurationModifierEdit : public QWidget {
|
class DurationModifierEdit : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@@ -36,27 +34,26 @@ 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);
|
||||||
void SetEntryData(std::shared_ptr<MacroCondition> *);
|
void SetEntryData(std::shared_ptr<MacroCondition> *);
|
||||||
void FocusTypeSelection() override;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void LogicSelectionChanged(int idx);
|
void LogicSelectionChanged(int idx);
|
||||||
void ConditionSelectionChanged(const QString &text);
|
void ConditionSelectionChanged(const QString &text);
|
||||||
void DurationChanged(const Duration &value);
|
void DurationChanged(const Duration &value);
|
||||||
void DurationModifierChanged(DurationModifier::Type m);
|
void DurationModifierChanged(DurationModifier::Type m);
|
||||||
void ConditionEnableChanged(bool);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetLogicSelection();
|
void SetLogicSelection();
|
||||||
std::shared_ptr<MacroSegment> Data() const;
|
std::shared_ptr<MacroSegment> Data() const;
|
||||||
|
|
||||||
SwitchButton *_enable;
|
|
||||||
QComboBox *_logicSelection;
|
QComboBox *_logicSelection;
|
||||||
FilterComboBox *_conditionSelection;
|
FilterComboBox *_conditionSelection;
|
||||||
DurationModifierEdit *_dur;
|
DurationModifierEdit *_dur;
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
#include "macro-condition-factory.hpp"
|
#include "macro-condition-factory.hpp"
|
||||||
#include "macro-segment-unknown.hpp"
|
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
using MacroConditionUnknown = MacroSegmentUnknown<MacroCondition>;
|
namespace {
|
||||||
|
|
||||||
|
class MacroConditionUnknown : public MacroCondition {
|
||||||
|
public:
|
||||||
|
MacroConditionUnknown(Macro *m) : MacroCondition(m) {}
|
||||||
|
bool CheckCondition() { return false; }
|
||||||
|
bool Save(obs_data_t *obj) const { return MacroCondition::Save(obj); };
|
||||||
|
bool Load(obs_data_t *obj) { return MacroCondition::Load(obj); };
|
||||||
|
std::string GetId() const { return "unknown"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
static std::recursive_mutex mutex;
|
static std::recursive_mutex mutex;
|
||||||
|
|
||||||
@@ -36,10 +46,9 @@ bool MacroConditionFactory::Deregister(const std::string &id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<MacroCondition>
|
static std::shared_ptr<MacroCondition> createUnknownCondition(Macro *m)
|
||||||
createUnknownCondition(Macro *m, const std::string &id)
|
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionUnknown>(m, id);
|
return std::make_shared<MacroConditionUnknown>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MacroCondition>
|
std::shared_ptr<MacroCondition>
|
||||||
@@ -49,7 +58,13 @@ MacroConditionFactory::Create(const std::string &id, Macro *m)
|
|||||||
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._create(m);
|
return it->second._create(m);
|
||||||
}
|
}
|
||||||
return createUnknownCondition(m, id);
|
return createUnknownCondition(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QWidget *createUnknownConditionWidget()
|
||||||
|
{
|
||||||
|
return new QLabel(
|
||||||
|
obs_module_text("AdvSceneSwitcher.condition.unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *
|
QWidget *
|
||||||
@@ -60,7 +75,7 @@ MacroConditionFactory::CreateWidget(const std::string &id, QWidget *parent,
|
|||||||
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._createWidget(parent, cond);
|
return it->second._createWidget(parent, cond);
|
||||||
}
|
}
|
||||||
return CreateUnknownSegmentWidget(false);
|
return createUnknownConditionWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MacroConditionFactory::GetConditionName(const std::string &id)
|
std::string MacroConditionFactory::GetConditionName(const std::string &id)
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
#include "macro-condition-macro.hpp"
|
#include "macro-condition-macro.hpp"
|
||||||
|
|
||||||
#include "layout-helpers.hpp"
|
#include "layout-helpers.hpp"
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "macro-helpers.hpp"
|
|
||||||
#include "macro-ref.hpp"
|
|
||||||
#include "macro-signals.hpp"
|
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
@@ -30,8 +26,6 @@ const static std::map<MacroConditionMacro::Type, std::string>
|
|||||||
"AdvSceneSwitcher.condition.macro.type.actionEnabled"},
|
"AdvSceneSwitcher.condition.macro.type.actionEnabled"},
|
||||||
{MacroConditionMacro::Type::PAUSED,
|
{MacroConditionMacro::Type::PAUSED,
|
||||||
"AdvSceneSwitcher.condition.macro.type.paused"},
|
"AdvSceneSwitcher.condition.macro.type.paused"},
|
||||||
{MacroConditionMacro::Type::ACTIONS_PERFORMED,
|
|
||||||
"AdvSceneSwitcher.condition.macro.type.actionsPerformed"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const static std::map<MacroConditionMacro::CounterCondition, std::string>
|
const static std::map<MacroConditionMacro::CounterCondition, std::string>
|
||||||
@@ -105,7 +99,7 @@ bool MacroConditionMacro::CheckActionStateCondition()
|
|||||||
if (!macro) {
|
if (!macro) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!IsValidActionIndex(macro.get(), _actionIndex - 1)) {
|
if (!IsValidMacroSegmentIndex(macro.get(), _actionIndex - 1, false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_type == Type::ACTION_DISABLED) {
|
if (_type == Type::ACTION_DISABLED) {
|
||||||
@@ -127,16 +121,6 @@ bool MacroConditionMacro::CheckPauseState()
|
|||||||
return macro->Paused();
|
return macro->Paused();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionMacro::CheckActionsPerformed()
|
|
||||||
{
|
|
||||||
auto macro = _macro.GetMacro();
|
|
||||||
if (!macro) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return macro->WasExecutedSince(macro->LastConditionCheckTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroConditionMacro::CheckCountCondition()
|
bool MacroConditionMacro::CheckCountCondition()
|
||||||
{
|
{
|
||||||
auto macro = _macro.GetMacro();
|
auto macro = _macro.GetMacro();
|
||||||
@@ -174,8 +158,6 @@ bool MacroConditionMacro::CheckCondition()
|
|||||||
return CheckActionStateCondition();
|
return CheckActionStateCondition();
|
||||||
case Type::PAUSED:
|
case Type::PAUSED:
|
||||||
return CheckPauseState();
|
return CheckPauseState();
|
||||||
case Type::ACTIONS_PERFORMED:
|
|
||||||
return CheckActionsPerformed();
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -318,7 +300,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);
|
||||||
@@ -326,8 +307,7 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
|
|||||||
|
|
||||||
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
||||||
this, SLOT(MacroChanged(const QString &)));
|
this, SLOT(MacroChanged(const QString &)));
|
||||||
QWidget::connect(MacroSignalManager::Instance(),
|
QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this,
|
||||||
SIGNAL(Remove(const QString &)), this,
|
|
||||||
SLOT(MacroRemove(const QString &)));
|
SLOT(MacroRemove(const QString &)));
|
||||||
QWidget::connect(_types, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_types, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(TypeChanged(int)));
|
SLOT(TypeChanged(int)));
|
||||||
@@ -434,9 +414,6 @@ void MacroConditionMacroEdit::SetupWidgets()
|
|||||||
case MacroConditionMacro::Type::PAUSED:
|
case MacroConditionMacro::Type::PAUSED:
|
||||||
SetupPauseWidgets();
|
SetupPauseWidgets();
|
||||||
break;
|
break;
|
||||||
case MacroConditionMacro::Type::ACTIONS_PERFORMED:
|
|
||||||
SetupActionsPerformedWidgets();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -495,14 +472,6 @@ void MacroConditionMacroEdit::SetupPauseWidgets()
|
|||||||
_settingsLine1, {{"{{macros}}", _macros}});
|
_settingsLine1, {{"{{macros}}", _macros}});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionMacroEdit::SetupActionsPerformedWidgets()
|
|
||||||
{
|
|
||||||
PlaceWidgets(
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.condition.macro.actionsPerformed.entry"),
|
|
||||||
_settingsLine1, {{"{{macros}}", _macros}});
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroConditionMacroEdit::SetWidgetVisibility()
|
void MacroConditionMacroEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
_macros->setVisible(
|
_macros->setVisible(
|
||||||
@@ -512,9 +481,7 @@ void MacroConditionMacroEdit::SetWidgetVisibility()
|
|||||||
MacroConditionMacro::Type::ACTION_DISABLED ||
|
MacroConditionMacro::Type::ACTION_DISABLED ||
|
||||||
_entryData->GetType() ==
|
_entryData->GetType() ==
|
||||||
MacroConditionMacro::Type::ACTION_ENABLED ||
|
MacroConditionMacro::Type::ACTION_ENABLED ||
|
||||||
_entryData->GetType() == MacroConditionMacro::Type::PAUSED ||
|
_entryData->GetType() == MacroConditionMacro::Type::PAUSED);
|
||||||
_entryData->GetType() ==
|
|
||||||
MacroConditionMacro::Type::ACTIONS_PERFORMED);
|
|
||||||
_counterConditions->setVisible(_entryData->GetType() ==
|
_counterConditions->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionMacro::Type::COUNT);
|
MacroConditionMacro::Type::COUNT);
|
||||||
_count->setVisible(_entryData->GetType() ==
|
_count->setVisible(_entryData->GetType() ==
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public:
|
|||||||
ACTION_DISABLED,
|
ACTION_DISABLED,
|
||||||
ACTION_ENABLED,
|
ACTION_ENABLED,
|
||||||
PAUSED,
|
PAUSED,
|
||||||
ACTIONS_PERFORMED,
|
|
||||||
};
|
};
|
||||||
void SetType(Type);
|
void SetType(Type);
|
||||||
Type GetType() const { return _type; }
|
Type GetType() const { return _type; }
|
||||||
@@ -67,7 +66,6 @@ private:
|
|||||||
bool CheckMultiStateCondition();
|
bool CheckMultiStateCondition();
|
||||||
bool CheckActionStateCondition();
|
bool CheckActionStateCondition();
|
||||||
bool CheckPauseState();
|
bool CheckPauseState();
|
||||||
bool CheckActionsPerformed();
|
|
||||||
|
|
||||||
void SetupTempVars();
|
void SetupTempVars();
|
||||||
|
|
||||||
@@ -136,7 +134,6 @@ private:
|
|||||||
void SetupCountWidgets();
|
void SetupCountWidgets();
|
||||||
void SetupActionStateWidgets(bool enable);
|
void SetupActionStateWidgets(bool enable);
|
||||||
void SetupPauseWidgets();
|
void SetupPauseWidgets();
|
||||||
void SetupActionsPerformedWidgets();
|
|
||||||
void SetWidgetVisibility();
|
void SetWidgetVisibility();
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,15 +6,6 @@ namespace advss {
|
|||||||
|
|
||||||
const std::string MacroConditionTempVar::id = "temp_var";
|
const std::string MacroConditionTempVar::id = "temp_var";
|
||||||
|
|
||||||
std::vector<TempVariableRef> MacroConditionTempVar::GetTempVarRefs() const
|
|
||||||
{
|
|
||||||
auto refs = MacroSegment::GetTempVarRefs();
|
|
||||||
if (_tempVar.HasValidID()) {
|
|
||||||
refs.push_back(_tempVar);
|
|
||||||
}
|
|
||||||
return refs;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroConditionTempVar::_registered = MacroConditionFactory::Register(
|
bool MacroConditionTempVar::_registered = MacroConditionFactory::Register(
|
||||||
MacroConditionTempVar::id,
|
MacroConditionTempVar::id,
|
||||||
{MacroConditionTempVar::Create, MacroConditionTempVarEdit::Create,
|
{MacroConditionTempVar::Create, MacroConditionTempVarEdit::Create,
|
||||||
@@ -163,7 +154,7 @@ bool MacroConditionTempVar::CheckCondition()
|
|||||||
bool MacroConditionTempVar::Save(obs_data_t *obj) const
|
bool MacroConditionTempVar::Save(obs_data_t *obj) const
|
||||||
{
|
{
|
||||||
MacroCondition::Save(obj);
|
MacroCondition::Save(obj);
|
||||||
_tempVar.Save(obj, GetMacro());
|
_tempVar.Save(obj);
|
||||||
obs_data_set_string(obj, "variableName",
|
obs_data_set_string(obj, "variableName",
|
||||||
GetWeakVariableName(_variable2).c_str());
|
GetWeakVariableName(_variable2).c_str());
|
||||||
_strValue.Save(obj, "strValue");
|
_strValue.Save(obj, "strValue");
|
||||||
@@ -275,7 +266,6 @@ void MacroConditionTempVarEdit::VariableChanged(const TempVariableRef &var)
|
|||||||
{
|
{
|
||||||
GUARD_LOADING_AND_LOCK();
|
GUARD_LOADING_AND_LOCK();
|
||||||
_entryData->_tempVar = var;
|
_entryData->_tempVar = var;
|
||||||
IncrementTempVarInUseGeneration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionTempVarEdit::Variable2Changed(const QString &text)
|
void MacroConditionTempVarEdit::Variable2Changed(const QString &text)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ public:
|
|||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
std::string GetShortDesc() const;
|
std::string GetShortDesc() const;
|
||||||
std::string GetId() const { return id; };
|
std::string GetId() const { return id; };
|
||||||
std::vector<TempVariableRef> GetTempVarRefs() const;
|
|
||||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionTempVar>(m);
|
return std::make_shared<MacroConditionTempVar>(m);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#include "macro-condition.hpp"
|
#include "macro-condition.hpp"
|
||||||
|
|
||||||
#include "condition-logic.hpp"
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
MacroCondition::MacroCondition(Macro *m, bool supportsVariableValue)
|
MacroCondition::MacroCondition(Macro *m, bool supportsVariableValue)
|
||||||
@@ -9,17 +7,6 @@ MacroCondition::MacroCondition(Macro *m, bool supportsVariableValue)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroCondition::EvaluateCondition()
|
|
||||||
{
|
|
||||||
bool newValue = CheckCondition();
|
|
||||||
_changed = _previousValue.has_value() && (*_previousValue != newValue);
|
|
||||||
const bool negate = _logic.IsNegationType(GetLogicType());
|
|
||||||
_risingEdge = _changed &&
|
|
||||||
((!negate && newValue) || (negate && !newValue));
|
|
||||||
_previousValue = newValue;
|
|
||||||
return newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroCondition::Save(obs_data_t *obj) const
|
bool MacroCondition::Save(obs_data_t *obj) const
|
||||||
{
|
{
|
||||||
MacroSegment::Save(obj);
|
MacroSegment::Save(obj);
|
||||||
@@ -33,10 +20,6 @@ bool MacroCondition::Load(obs_data_t *obj)
|
|||||||
{
|
{
|
||||||
MacroSegment::Load(obj);
|
MacroSegment::Load(obj);
|
||||||
_logic.Load(obj, "logic");
|
_logic.Load(obj, "logic");
|
||||||
if (_logic.GetType() == Logic::Type::NONE) {
|
|
||||||
SetEnabled(false);
|
|
||||||
_logic.SetType(Logic::Type::AND);
|
|
||||||
}
|
|
||||||
_durationModifier.Load(obj);
|
_durationModifier.Load(obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -56,8 +39,7 @@ void MacroCondition::ValidateLogicSelection(bool isRootCondition,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logic.SetType(Logic::Type::AND);
|
_logic.SetType(Logic::Type::NONE);
|
||||||
SetEnabled(false);
|
|
||||||
blog(LOG_WARNING,
|
blog(LOG_WARNING,
|
||||||
"setting invalid logic selection to 'ignore' for macro %s",
|
"setting invalid logic selection to 'ignore' for macro %s",
|
||||||
context);
|
context);
|
||||||
|
|||||||
@@ -4,19 +4,13 @@
|
|||||||
#include "duration-modifier.hpp"
|
#include "duration-modifier.hpp"
|
||||||
#include "macro-ref.hpp"
|
#include "macro-ref.hpp"
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
class EXPORT MacroCondition : public MacroSegment {
|
class EXPORT MacroCondition : public MacroSegment {
|
||||||
public:
|
public:
|
||||||
MacroCondition(Macro *m, bool supportsVariableValue = false);
|
MacroCondition(Macro *m, bool supportsVariableValue = false);
|
||||||
virtual ~MacroCondition() = default;
|
virtual ~MacroCondition() = default;
|
||||||
|
virtual bool CheckCondition() = 0;
|
||||||
bool EvaluateCondition();
|
|
||||||
bool HasChanged() const { return _changed; }
|
|
||||||
bool IsRisingEdge() const { return _risingEdge; }
|
|
||||||
|
|
||||||
virtual bool Save(obs_data_t *obj) const = 0;
|
virtual bool Save(obs_data_t *obj) const = 0;
|
||||||
virtual bool Load(obs_data_t *obj) = 0;
|
virtual bool Load(obs_data_t *obj) = 0;
|
||||||
|
|
||||||
@@ -34,15 +28,9 @@ public:
|
|||||||
|
|
||||||
static std::string_view GetDefaultID();
|
static std::string_view GetDefaultID();
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool CheckCondition() = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logic _logic = Logic(Logic::Type::ROOT_NONE);
|
Logic _logic = Logic(Logic::Type::ROOT_NONE);
|
||||||
DurationModifier _durationModifier;
|
DurationModifier _durationModifier;
|
||||||
std::optional<bool> _previousValue;
|
|
||||||
bool _changed = false;
|
|
||||||
bool _risingEdge = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EXPORT MacroRefCondition : virtual public MacroCondition {
|
class EXPORT MacroRefCondition : virtual public MacroCondition {
|
||||||
|
|||||||
@@ -1,397 +0,0 @@
|
|||||||
#include "macro-dock-settings.hpp"
|
|
||||||
|
|
||||||
#include "macro-dock-window.hpp"
|
|
||||||
#include "macro-dock.hpp"
|
|
||||||
#include "macro-helpers.hpp"
|
|
||||||
#include "macro.hpp"
|
|
||||||
#include "plugin-state-helpers.hpp"
|
|
||||||
#include "variable-string.hpp"
|
|
||||||
|
|
||||||
#include <obs-frontend-api.h>
|
|
||||||
#include <util/platform.h>
|
|
||||||
|
|
||||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(30, 0, 0)
|
|
||||||
#include <QDockWidget>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct DockMapEntry {
|
|
||||||
QAction *action = nullptr;
|
|
||||||
QWidget *dock = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
static std::unordered_map<const char *, DockMapEntry> dockIds;
|
|
||||||
static std::mutex dockMutex;
|
|
||||||
|
|
||||||
static bool obs_frontend_add_dock_by_id(const char *id, const char *title,
|
|
||||||
QWidget *widget)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(dockMutex);
|
|
||||||
if (dockIds.count(id) > 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
widget->setObjectName(id);
|
|
||||||
|
|
||||||
auto dock = new QDockWidget();
|
|
||||||
dock->setWindowTitle(title);
|
|
||||||
dock->setWidget(widget);
|
|
||||||
dock->setFloating(true);
|
|
||||||
dock->setVisible(false);
|
|
||||||
dock->setFeatures(QDockWidget::DockWidgetClosable |
|
|
||||||
QDockWidget::DockWidgetMovable |
|
|
||||||
QDockWidget::DockWidgetFloatable);
|
|
||||||
|
|
||||||
auto action = static_cast<QAction *>(obs_frontend_add_dock(dock));
|
|
||||||
if (!action) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dockIds[id] = {action, dock};
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void obs_frontend_remove_dock(const char *id)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(dockMutex);
|
|
||||||
auto it = dockIds.find(id);
|
|
||||||
if (it == dockIds.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
it->second.action->deleteLater();
|
|
||||||
it->second.dock->deleteLater();
|
|
||||||
dockIds.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
MacroDockSettings::MacroDockSettings(Macro *macro) : _macro(macro) {}
|
|
||||||
|
|
||||||
MacroDockSettings::~MacroDockSettings()
|
|
||||||
{
|
|
||||||
// Keep the dock widgets in case of shutdown so they can be restored by
|
|
||||||
// OBS on startup
|
|
||||||
if (!OBSIsShuttingDown()) {
|
|
||||||
RemoveDock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::Save(obs_data_t *obj, bool saveForCopy) const
|
|
||||||
{
|
|
||||||
OBSDataAutoRelease dockSettings = obs_data_create();
|
|
||||||
obs_data_set_bool(dockSettings, "register", _registerDock);
|
|
||||||
obs_data_set_bool(dockSettings, "standaloneDock", _standaloneDock);
|
|
||||||
obs_data_set_string(dockSettings, "dockWindow", _dockWindow.c_str());
|
|
||||||
obs_data_set_bool(dockSettings, "hasRunButton", _hasRunButton);
|
|
||||||
obs_data_set_bool(dockSettings, "hasPauseButton", _hasPauseButton);
|
|
||||||
obs_data_set_bool(dockSettings, "hasStatusLabel", _hasStatusLabel);
|
|
||||||
obs_data_set_bool(dockSettings, "highlightIfConditionsTrue",
|
|
||||||
_highlight);
|
|
||||||
_runButtonText.Save(dockSettings, "runButtonText");
|
|
||||||
_pauseButtonText.Save(dockSettings, "pauseButtonText");
|
|
||||||
_unpauseButtonText.Save(dockSettings, "unpauseButtonText");
|
|
||||||
_conditionsTrueStatusText.Save(dockSettings,
|
|
||||||
"conditionsTrueStatusText");
|
|
||||||
_conditionsFalseStatusText.Save(dockSettings,
|
|
||||||
"conditionsFalseStatusText");
|
|
||||||
if (saveForCopy) {
|
|
||||||
auto uuid = GenerateId();
|
|
||||||
obs_data_set_string(dockSettings, "dockId", uuid.c_str());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
obs_data_set_string(dockSettings, "dockId", _id.c_str());
|
|
||||||
}
|
|
||||||
obs_data_set_int(dockSettings, "version", 1);
|
|
||||||
obs_data_set_obj(obj, "dockSettings", dockSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::Load(obs_data_t *obj)
|
|
||||||
{
|
|
||||||
OBSDataAutoRelease dockSettings = obs_data_get_obj(obj, "dockSettings");
|
|
||||||
if (!dockSettings) {
|
|
||||||
// TODO: Remove this fallback
|
|
||||||
_hasRunButton = obs_data_get_bool(obj, "dockHasRunButton");
|
|
||||||
_hasPauseButton = obs_data_get_bool(obj, "dockHasPauseButton");
|
|
||||||
_registerDock = obs_data_get_bool(obj, "registerDock");
|
|
||||||
ResetDockIfEnabled();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_macroName = _macro->Name();
|
|
||||||
if (!obs_data_has_user_value(dockSettings, "version")) {
|
|
||||||
assert(_macro);
|
|
||||||
_id = std::string("ADVSS-") + _macroName;
|
|
||||||
} else {
|
|
||||||
_id = obs_data_get_string(dockSettings, "dockId");
|
|
||||||
}
|
|
||||||
|
|
||||||
_registerDock = obs_data_get_bool(dockSettings, "register");
|
|
||||||
|
|
||||||
// TODO: remove these default settings in a future version
|
|
||||||
obs_data_set_default_bool(dockSettings, "standaloneDock", true);
|
|
||||||
obs_data_set_default_string(dockSettings, "dockWindow", "Dock");
|
|
||||||
obs_data_set_default_string(
|
|
||||||
dockSettings, "runButtonText",
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.run"));
|
|
||||||
obs_data_set_default_string(
|
|
||||||
dockSettings, "pauseButtonText",
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.pause"));
|
|
||||||
obs_data_set_default_string(
|
|
||||||
dockSettings, "unpauseButtonText",
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.unpause"));
|
|
||||||
_standaloneDock = obs_data_get_bool(dockSettings, "standaloneDock");
|
|
||||||
_dockWindow = obs_data_get_string(dockSettings, "dockWindow");
|
|
||||||
_runButtonText.Load(dockSettings, "runButtonText");
|
|
||||||
_pauseButtonText.Load(dockSettings, "pauseButtonText");
|
|
||||||
_unpauseButtonText.Load(dockSettings, "unpauseButtonText");
|
|
||||||
_conditionsTrueStatusText.Load(dockSettings,
|
|
||||||
"conditionsTrueStatusText");
|
|
||||||
_conditionsFalseStatusText.Load(dockSettings,
|
|
||||||
"conditionsFalseStatusText");
|
|
||||||
if (_registerDock) {
|
|
||||||
_hasRunButton = obs_data_get_bool(dockSettings, "hasRunButton");
|
|
||||||
_hasPauseButton =
|
|
||||||
obs_data_get_bool(dockSettings, "hasPauseButton");
|
|
||||||
_hasStatusLabel =
|
|
||||||
obs_data_get_bool(dockSettings, "hasStatusLabel");
|
|
||||||
_highlight = obs_data_get_bool(dockSettings,
|
|
||||||
"highlightIfConditionsTrue");
|
|
||||||
}
|
|
||||||
|
|
||||||
ResetDockIfEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::EnableDock(bool enable)
|
|
||||||
{
|
|
||||||
// Only apply "on change" to avoid recreation of the dock widget
|
|
||||||
if (_registerDock == enable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveDock();
|
|
||||||
|
|
||||||
if (!enable) {
|
|
||||||
_registerDock = enable;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(_macro);
|
|
||||||
_macroName = _macro->Name();
|
|
||||||
_dock = new MacroDock(GetWeakMacroByName(_macroName.c_str()),
|
|
||||||
_runButtonText, _pauseButtonText,
|
|
||||||
_unpauseButtonText, _conditionsTrueStatusText,
|
|
||||||
_conditionsFalseStatusText, _highlight);
|
|
||||||
|
|
||||||
if (!_standaloneDock) {
|
|
||||||
auto window = GetDockWindowByName(_dockWindow);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
window->AddMacroDock(_dock, QString::fromStdString(_macroName));
|
|
||||||
_registerDock = enable;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!obs_frontend_add_dock_by_id(_id.c_str(), _macroName.c_str(),
|
|
||||||
_dock)) {
|
|
||||||
blog(LOG_INFO, "failed to add macro dock for macro %s",
|
|
||||||
_macroName.c_str());
|
|
||||||
_dock->deleteLater();
|
|
||||||
_dock = nullptr;
|
|
||||||
_registerDock = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_registerDock = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetIsStandaloneDock(bool value)
|
|
||||||
{
|
|
||||||
if (_standaloneDock == value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveDock();
|
|
||||||
_standaloneDock = value;
|
|
||||||
ResetDockIfEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetDockWindowName(const std::string &name)
|
|
||||||
{
|
|
||||||
if (_dockWindow == name) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveDock();
|
|
||||||
_dockWindow = name;
|
|
||||||
ResetDockIfEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetHasRunButton(bool value)
|
|
||||||
{
|
|
||||||
_hasRunButton = value;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->ShowRunButton(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetHasPauseButton(bool value)
|
|
||||||
{
|
|
||||||
_hasPauseButton = value;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->ShowPauseButton(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetHasStatusLabel(bool value)
|
|
||||||
{
|
|
||||||
_hasStatusLabel = value;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->ShowStatusLabel(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetHighlightEnable(bool value)
|
|
||||||
{
|
|
||||||
_highlight = value;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->EnableHighlight(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetRunButtonText(const std::string &text)
|
|
||||||
{
|
|
||||||
_runButtonText = text;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->SetRunButtonText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetPauseButtonText(const std::string &text)
|
|
||||||
{
|
|
||||||
_pauseButtonText = text;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->SetPauseButtonText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetUnpauseButtonText(const std::string &text)
|
|
||||||
{
|
|
||||||
_unpauseButtonText = text;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->SetUnpauseButtonText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetConditionsTrueStatusText(const std::string &text)
|
|
||||||
{
|
|
||||||
_conditionsTrueStatusText = text;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->SetConditionsTrueText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringVariable MacroDockSettings::ConditionsTrueStatusText() const
|
|
||||||
{
|
|
||||||
return _conditionsTrueStatusText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::SetConditionsFalseStatusText(const std::string &text)
|
|
||||||
{
|
|
||||||
_conditionsFalseStatusText = text;
|
|
||||||
if (!_dock) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dock->SetConditionsFalseText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringVariable MacroDockSettings::ConditionsFalseStatusText() const
|
|
||||||
{
|
|
||||||
return _conditionsFalseStatusText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::HandleMacroNameChange()
|
|
||||||
{
|
|
||||||
const auto newName = _macro->Name();
|
|
||||||
|
|
||||||
if (!_standaloneDock) {
|
|
||||||
auto window = GetDockWindowByName(_dockWindow);
|
|
||||||
if (!window) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->RenameMacro(_macroName, newName);
|
|
||||||
_macroName = newName;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_macroName != newName) {
|
|
||||||
RemoveDock();
|
|
||||||
_id = GenerateId();
|
|
||||||
_macroName = newName;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResetDockIfEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::ResetDockIfEnabled()
|
|
||||||
{
|
|
||||||
if (_registerDock) {
|
|
||||||
_registerDock = false;
|
|
||||||
EnableDock(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockSettings::RemoveDock()
|
|
||||||
{
|
|
||||||
if (_standaloneDock) {
|
|
||||||
obs_frontend_remove_dock(_id.c_str());
|
|
||||||
_dock = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto window = GetDockWindowByName(_dockWindow);
|
|
||||||
if (window) {
|
|
||||||
window->RemoveMacroDock(_dock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_dock) {
|
|
||||||
_dock = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string MacroDockSettings::GenerateId()
|
|
||||||
{
|
|
||||||
#if LIBOBS_API_VER > MAKE_SEMANTIC_VERSION(30, 0, 0)
|
|
||||||
auto uuid = os_generate_uuid();
|
|
||||||
auto id = std::string("advss-macro-dock-") + std::string(uuid);
|
|
||||||
bfree(uuid);
|
|
||||||
return id;
|
|
||||||
|
|
||||||
#else
|
|
||||||
static std::atomic_int16_t idCounter = 0;
|
|
||||||
return std::to_string(++idCounter);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "obs-module-helper.hpp"
|
|
||||||
#include "variable-string.hpp"
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
class Macro;
|
|
||||||
class MacroDock;
|
|
||||||
|
|
||||||
class MacroDockSettings {
|
|
||||||
public:
|
|
||||||
MacroDockSettings(Macro *macro);
|
|
||||||
~MacroDockSettings();
|
|
||||||
|
|
||||||
void Save(obs_data_t *obj, bool saveForCopy) const;
|
|
||||||
void Load(obs_data_t *obj);
|
|
||||||
|
|
||||||
void EnableDock(bool);
|
|
||||||
bool DockEnabled() const { return _registerDock; }
|
|
||||||
|
|
||||||
bool IsStandaloneDock() const { return _standaloneDock; }
|
|
||||||
void SetIsStandaloneDock(bool value);
|
|
||||||
std::string DockWindowName() const { return _dockWindow; }
|
|
||||||
void SetDockWindowName(const std::string &name);
|
|
||||||
|
|
||||||
void SetHasRunButton(bool value);
|
|
||||||
bool HasRunButton() const { return _hasRunButton; }
|
|
||||||
void SetHasPauseButton(bool value);
|
|
||||||
bool HasPauseButton() const { return _hasPauseButton; }
|
|
||||||
void SetHasStatusLabel(bool value);
|
|
||||||
bool HasStatusLabel() const { return _hasStatusLabel; }
|
|
||||||
void SetHighlightEnable(bool value);
|
|
||||||
bool HighlightEnabled() const { return _highlight; }
|
|
||||||
StringVariable RunButtonText() const { return _runButtonText; }
|
|
||||||
void SetRunButtonText(const std::string &text);
|
|
||||||
StringVariable PauseButtonText() const { return _pauseButtonText; }
|
|
||||||
void SetPauseButtonText(const std::string &text);
|
|
||||||
StringVariable UnpauseButtonText() const { return _unpauseButtonText; }
|
|
||||||
void SetUnpauseButtonText(const std::string &text);
|
|
||||||
void SetConditionsTrueStatusText(const std::string &text);
|
|
||||||
StringVariable ConditionsTrueStatusText() const;
|
|
||||||
void SetConditionsFalseStatusText(const std::string &text);
|
|
||||||
StringVariable ConditionsFalseStatusText() const;
|
|
||||||
|
|
||||||
void HandleMacroNameChange();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ResetDockIfEnabled();
|
|
||||||
void RemoveDock();
|
|
||||||
static std::string GenerateId();
|
|
||||||
|
|
||||||
bool _registerDock = false;
|
|
||||||
bool _standaloneDock = true;
|
|
||||||
std::string _dockWindow = "Dock";
|
|
||||||
bool _hasRunButton = true;
|
|
||||||
bool _hasPauseButton = true;
|
|
||||||
bool _hasStatusLabel = false;
|
|
||||||
bool _highlight = false;
|
|
||||||
StringVariable _runButtonText =
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.run");
|
|
||||||
StringVariable _pauseButtonText =
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.pause");
|
|
||||||
StringVariable _unpauseButtonText =
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.unpause");
|
|
||||||
StringVariable _conditionsTrueStatusText =
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.statusLabel.true");
|
|
||||||
StringVariable _conditionsFalseStatusText =
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroDock.statusLabel.false");
|
|
||||||
std::string _id = GenerateId();
|
|
||||||
std::string _macroName = "";
|
|
||||||
|
|
||||||
Macro *_macro = nullptr;
|
|
||||||
MacroDock *_dock = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
#include "macro-dock-window.hpp"
|
|
||||||
#include "log-helper.hpp"
|
|
||||||
#include "plugin-state-helpers.hpp"
|
|
||||||
|
|
||||||
#include <obs-frontend-api.h>
|
|
||||||
|
|
||||||
#include <QDockWidget>
|
|
||||||
#include <QLayout>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
static std::unordered_map<std::string, MacroDockWindow *> windows;
|
|
||||||
static std::unordered_map<std::string, QByteArray> windowGeometries;
|
|
||||||
static std::mutex mutex;
|
|
||||||
|
|
||||||
static void saveDocks(obs_data_t *obj)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
|
||||||
OBSDataArrayAutoRelease array = obs_data_array_create();
|
|
||||||
for (const auto &[name, window] : windows) {
|
|
||||||
OBSDataAutoRelease dockData = obs_data_create();
|
|
||||||
obs_data_set_string(dockData, "name", name.c_str());
|
|
||||||
obs_data_set_string(dockData, "geometry",
|
|
||||||
window->GetWindow()
|
|
||||||
->saveState()
|
|
||||||
.toBase64()
|
|
||||||
.toStdString()
|
|
||||||
.c_str());
|
|
||||||
obs_data_array_push_back(array, dockData);
|
|
||||||
}
|
|
||||||
obs_data_set_array(data, "docks", array);
|
|
||||||
obs_data_set_obj(obj, "dockWindows", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void restoreDockGeometry()
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
for (const auto &[name, dock] : windows) {
|
|
||||||
const auto it = windowGeometries.find(name);
|
|
||||||
if (it == windowGeometries.end()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dock->GetWindow()->restoreState(it->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void loadDocks(obs_data_t *obj)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
windowGeometries.clear();
|
|
||||||
OBSDataAutoRelease data = obs_data_get_obj(obj, "dockWindows");
|
|
||||||
OBSDataArrayAutoRelease array = obs_data_get_array(data, "docks");
|
|
||||||
auto size = obs_data_array_count(array);
|
|
||||||
for (size_t i = 0; i < size; ++i) {
|
|
||||||
OBSDataAutoRelease dockData = obs_data_array_item(array, i);
|
|
||||||
const auto name = obs_data_get_string(dockData, "name");
|
|
||||||
const auto geometry = QByteArray::fromBase64(
|
|
||||||
obs_data_get_string(dockData, "geometry"));
|
|
||||||
windowGeometries[name] = geometry;
|
|
||||||
}
|
|
||||||
AddPostLoadStep(restoreDockGeometry);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static bool _ = []() {
|
|
||||||
AddPluginInitStep([]() {
|
|
||||||
AddSaveStep(saveDocks);
|
|
||||||
AddLoadStep(loadDocks);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}();
|
|
||||||
|
|
||||||
MacroDockWindow::MacroDockWindow(const std::string &name)
|
|
||||||
: QFrame(),
|
|
||||||
_name(name),
|
|
||||||
_window(new QMainWindow())
|
|
||||||
{
|
|
||||||
setFrameShape(QFrame::StyledPanel);
|
|
||||||
setFrameShadow(QFrame::Sunken);
|
|
||||||
_window->setDockNestingEnabled(true);
|
|
||||||
auto layout = new QVBoxLayout;
|
|
||||||
layout->addWidget(_window);
|
|
||||||
setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *MacroDockWindow::AddMacroDock(QWidget *widget, const QString &title)
|
|
||||||
{
|
|
||||||
auto dock = new QDockWidget();
|
|
||||||
dock->setWindowTitle(title);
|
|
||||||
dock->setWidget(widget);
|
|
||||||
dock->setVisible(true);
|
|
||||||
dock->setFeatures(QDockWidget::DockWidgetMovable);
|
|
||||||
dock->setObjectName(title);
|
|
||||||
_window->addDockWidget(Qt::RightDockWidgetArea, dock);
|
|
||||||
return dock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockWindow::RenameMacro(const std::string &oldName,
|
|
||||||
const std::string &newName)
|
|
||||||
{
|
|
||||||
auto docks = _window->findChildren<QDockWidget *>();
|
|
||||||
for (const auto dock : docks) {
|
|
||||||
if (dock->windowTitle() == QString::fromStdString(oldName)) {
|
|
||||||
dock->setWindowTitle(QString::fromStdString(newName));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDockWindow::RemoveMacroDock(QWidget *widget)
|
|
||||||
{
|
|
||||||
bool removedDock = false;
|
|
||||||
auto docks = _window->findChildren<QDockWidget *>();
|
|
||||||
for (const auto dock : docks) {
|
|
||||||
if (dock->widget() == widget) {
|
|
||||||
_window->removeDockWidget(dock);
|
|
||||||
dock->deleteLater();
|
|
||||||
removedDock = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OBSIsShuttingDown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool shouldRemoveDockWindow = docks.isEmpty() ||
|
|
||||||
(removedDock && docks.count() == 1);
|
|
||||||
if (!shouldRemoveDockWindow) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
auto it = windows.find(_name);
|
|
||||||
if (it != windows.end()) {
|
|
||||||
windows.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto id = "advss-dock-window-" + _name;
|
|
||||||
obs_frontend_remove_dock(id.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
QMainWindow *MacroDockWindow::GetWindow() const
|
|
||||||
{
|
|
||||||
return _window;
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroDockWindow *GetDockWindowByName(const std::string &name)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
auto it = windows.find(name);
|
|
||||||
if (it != windows.end()) {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto window = new MacroDockWindow(name);
|
|
||||||
const auto id = "advss-dock-window-" + name;
|
|
||||||
if (!obs_frontend_add_dock_by_id(id.c_str(), name.c_str(), window)) {
|
|
||||||
blog(LOG_INFO, "failed to add macro dock window '%s'",
|
|
||||||
id.c_str());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
windows[name] = window;
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
class MacroDockWindow : public QFrame {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MacroDockWindow(const std::string &name);
|
|
||||||
QWidget *AddMacroDock(QWidget *, const QString &title);
|
|
||||||
void RenameMacro(const std::string &oldName,
|
|
||||||
const std::string &newName);
|
|
||||||
void RemoveMacroDock(QWidget *);
|
|
||||||
QMainWindow *GetWindow() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string _name;
|
|
||||||
QMainWindow *_window;
|
|
||||||
};
|
|
||||||
|
|
||||||
MacroDockWindow *GetDockWindowByName(const std::string &name);
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -30,10 +30,9 @@ MacroDock::MacroDock(std::weak_ptr<Macro> m,
|
|||||||
|
|
||||||
auto macro = _macro.lock();
|
auto macro = _macro.lock();
|
||||||
if (macro) {
|
if (macro) {
|
||||||
const auto &settings = macro->GetDockSettings();
|
_run->setVisible(macro->DockHasRunButton());
|
||||||
_run->setVisible(settings.HasRunButton());
|
_pauseToggle->setVisible(macro->DockHasPauseButton());
|
||||||
_pauseToggle->setVisible(settings.HasPauseButton());
|
_statusText->setVisible(macro->DockHasStatusLabel());
|
||||||
_statusText->setVisible(settings.HasStatusLabel());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget::connect(_run, SIGNAL(clicked()), this, SLOT(RunClicked()));
|
QWidget::connect(_run, SIGNAL(clicked()), this, SLOT(RunClicked()));
|
||||||
@@ -110,7 +109,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");
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "condition-logic.hpp"
|
|
||||||
|
|
||||||
#include <ui_macro-edit.h>
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
class Macro;
|
|
||||||
class MacroSegment;
|
|
||||||
|
|
||||||
class MacroEdit : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MacroEdit(QWidget *parent, QStringList helpMsg = {});
|
|
||||||
void SetMacro(const std::shared_ptr<Macro> &);
|
|
||||||
std::shared_ptr<Macro> GetMacro() const;
|
|
||||||
void ClearSegmentWidgetCacheFor(Macro *) const;
|
|
||||||
void SetControlsDisabled(bool disable) const;
|
|
||||||
void HighlightAction(int idx, QColor color = QColor(Qt::green)) const;
|
|
||||||
void HighlightElseAction(int idx,
|
|
||||||
QColor color = QColor(Qt::green)) const;
|
|
||||||
void HighlightCondition(int idx,
|
|
||||||
QColor color = QColor(Qt::green)) const;
|
|
||||||
void ResetConditionHighlights();
|
|
||||||
void ResetActionHighlights();
|
|
||||||
void SetActionData(Macro &m) const;
|
|
||||||
void SetElseActionData(Macro &m) const;
|
|
||||||
void SetConditionData(Macro &m) const;
|
|
||||||
void SwapActions(Macro *m, int pos1, int pos2);
|
|
||||||
void SwapElseActions(Macro *m, int pos1, int pos2);
|
|
||||||
void SwapConditions(Macro *m, int pos1, int pos2);
|
|
||||||
void CopyMacroSegment();
|
|
||||||
void PasteMacroSegment();
|
|
||||||
bool IsEmpty() const;
|
|
||||||
void ShowAllMacroSections();
|
|
||||||
void HideElseSection() const;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void on_conditionAdd_clicked();
|
|
||||||
void on_conditionRemove_clicked();
|
|
||||||
void on_conditionTop_clicked();
|
|
||||||
void on_conditionUp_clicked();
|
|
||||||
void on_conditionDown_clicked();
|
|
||||||
void on_conditionBottom_clicked();
|
|
||||||
void on_actionAdd_clicked();
|
|
||||||
void on_actionRemove_clicked();
|
|
||||||
void on_actionTop_clicked();
|
|
||||||
void on_actionUp_clicked();
|
|
||||||
void on_actionDown_clicked();
|
|
||||||
void on_actionBottom_clicked();
|
|
||||||
void on_toggleElseActions_clicked() const;
|
|
||||||
void on_elseActionAdd_clicked();
|
|
||||||
void on_elseActionRemove_clicked();
|
|
||||||
void on_elseActionTop_clicked();
|
|
||||||
void on_elseActionUp_clicked();
|
|
||||||
void on_elseActionDown_clicked();
|
|
||||||
void on_elseActionBottom_clicked();
|
|
||||||
void UpMacroSegmentHotkey();
|
|
||||||
void DownMacroSegmentHotkey();
|
|
||||||
void DeleteMacroSegmentHotkey();
|
|
||||||
void ShowMacroActionsContextMenu(const QPoint &);
|
|
||||||
void ShowMacroElseActionsContextMenu(const QPoint &);
|
|
||||||
void ShowMacroConditionsContextMenu(const QPoint &);
|
|
||||||
void ExpandAllActions() const;
|
|
||||||
void ExpandAllElseActions() const;
|
|
||||||
void ExpandAllConditions() const;
|
|
||||||
void CollapseAllActions() const;
|
|
||||||
void CollapseAllElseActions() const;
|
|
||||||
void CollapseAllConditions() const;
|
|
||||||
void MinimizeActions() const;
|
|
||||||
void MaximizeActions() const;
|
|
||||||
void MinimizeElseActions() const;
|
|
||||||
void MaximizeElseActions() const;
|
|
||||||
void MinimizeConditions() const;
|
|
||||||
void MaximizeConditions() const;
|
|
||||||
void SetElseActionsStateToHidden() const;
|
|
||||||
void SetElseActionsStateToVisible() const;
|
|
||||||
void MacroActionSelectionChanged(int idx);
|
|
||||||
void MacroActionReorder(int to, int target);
|
|
||||||
void AddMacroAction(Macro *macro, int idx, const std::string &id,
|
|
||||||
obs_data_t *data);
|
|
||||||
void AddMacroAction(int idx);
|
|
||||||
void RemoveMacroAction(int idx);
|
|
||||||
void MoveMacroActionUp(int idx);
|
|
||||||
void MoveMacroActionDown(int idx);
|
|
||||||
void MacroElseActionSelectionChanged(int idx);
|
|
||||||
void MacroElseActionReorder(int to, int target);
|
|
||||||
void AddMacroElseAction(Macro *macro, int idx, const std::string &id,
|
|
||||||
obs_data_t *data);
|
|
||||||
void AddMacroElseAction(int idx);
|
|
||||||
void RemoveMacroElseAction(int idx);
|
|
||||||
void MoveMacroElseActionUp(int idx);
|
|
||||||
void MoveMacroElseActionDown(int idx);
|
|
||||||
void MacroConditionSelectionChanged(int idx);
|
|
||||||
void MacroConditionReorder(int to, int target);
|
|
||||||
void AddMacroCondition(int idx);
|
|
||||||
void AddMacroCondition(Macro *macro, int idx, const std::string &id,
|
|
||||||
obs_data_t *data, Logic::Type logic);
|
|
||||||
void RemoveMacroCondition(int idx);
|
|
||||||
void MoveMacroConditionUp(int idx);
|
|
||||||
void MoveMacroConditionDown(int idx);
|
|
||||||
void HighlightControls() const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void MacroAdded(const QString &name);
|
|
||||||
void MacroRemoved(const QString &name);
|
|
||||||
void MacroRenamed(const QString &oldName, const QString &newName);
|
|
||||||
void MacroSegmentOrderChanged();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
|
|
||||||
|
|
||||||
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
|
|
||||||
void PopulateMacroElseActions(Macro &m, uint32_t afterIdx = 0);
|
|
||||||
void PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
|
|
||||||
void ScrollAndFocusNewSegment(MacroSegmentList *list, int newIdx,
|
|
||||||
int *currentIdx);
|
|
||||||
void SetupMacroSegmentSelection(MacroSection type, int idx);
|
|
||||||
void
|
|
||||||
SetupContextMenu(const QPoint &pos,
|
|
||||||
const std::function<void(MacroEdit *, int)> &remove,
|
|
||||||
const std::function<void(MacroEdit *)> &expand,
|
|
||||||
const std::function<void(MacroEdit *)> &collapse,
|
|
||||||
const std::function<void(MacroEdit *)> &maximize,
|
|
||||||
const std::function<void(MacroEdit *)> &minimize,
|
|
||||||
MacroSegmentList *list);
|
|
||||||
void RunSegmentHighlightChecks();
|
|
||||||
bool ElseSectionIsVisible() const;
|
|
||||||
|
|
||||||
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
|
||||||
int currentConditionIdx = -1;
|
|
||||||
int currentActionIdx = -1;
|
|
||||||
int currentElseActionIdx = -1;
|
|
||||||
|
|
||||||
std::shared_ptr<Macro> _currentMacro;
|
|
||||||
|
|
||||||
std::unique_ptr<Ui_MacroEdit> ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
#include "macro-export-extensions.hpp"
|
|
||||||
|
|
||||||
#include "action-queue.hpp"
|
|
||||||
#include "variable.hpp"
|
|
||||||
|
|
||||||
#include <obs.hpp>
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
static bool setup();
|
|
||||||
static bool setupDone = setup();
|
|
||||||
|
|
||||||
static bool setup()
|
|
||||||
{
|
|
||||||
// --- Variables ---
|
|
||||||
AddMacroExportExtension(
|
|
||||||
{"AdvSceneSwitcher.macroTab.export.variables", "variables",
|
|
||||||
[](obs_data_t *data, const QStringList &selectedIds) {
|
|
||||||
if (selectedIds.isEmpty()) {
|
|
||||||
SaveVariables(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OBSDataArrayAutoRelease array =
|
|
||||||
obs_data_array_create();
|
|
||||||
for (const auto &v : GetVariables()) {
|
|
||||||
const QString name =
|
|
||||||
QString::fromStdString(v->Name());
|
|
||||||
if (!selectedIds.contains(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
OBSDataAutoRelease item = obs_data_create();
|
|
||||||
v->Save(item);
|
|
||||||
obs_data_array_push_back(array, item);
|
|
||||||
}
|
|
||||||
obs_data_set_array(data, "variables", array);
|
|
||||||
},
|
|
||||||
[](obs_data_t *data, const QStringList &) {
|
|
||||||
ImportVariables(data);
|
|
||||||
},
|
|
||||||
[]() -> QList<QPair<QString, QString>> {
|
|
||||||
QList<QPair<QString, QString>> items;
|
|
||||||
for (const auto &v : GetVariables()) {
|
|
||||||
const QString name =
|
|
||||||
QString::fromStdString(v->Name());
|
|
||||||
items.append({name, name});
|
|
||||||
}
|
|
||||||
return items;
|
|
||||||
}});
|
|
||||||
|
|
||||||
// --- Action Queues ---
|
|
||||||
AddMacroExportExtension(
|
|
||||||
{"AdvSceneSwitcher.macroTab.export.actionQueues",
|
|
||||||
"actionQueues",
|
|
||||||
[](obs_data_t *data, const QStringList &selectedIds) {
|
|
||||||
if (selectedIds.isEmpty()) {
|
|
||||||
SaveActionQueues(data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OBSDataArrayAutoRelease array =
|
|
||||||
obs_data_array_create();
|
|
||||||
for (const auto &q : GetActionQueues()) {
|
|
||||||
const QString name =
|
|
||||||
QString::fromStdString(q->Name());
|
|
||||||
if (!selectedIds.contains(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
OBSDataAutoRelease item = obs_data_create();
|
|
||||||
q->Save(item);
|
|
||||||
obs_data_array_push_back(array, item);
|
|
||||||
}
|
|
||||||
obs_data_set_array(data, "actionQueues", array);
|
|
||||||
},
|
|
||||||
[](obs_data_t *data, const QStringList &) {
|
|
||||||
ImportQueues(data);
|
|
||||||
},
|
|
||||||
[]() -> QList<QPair<QString, QString>> {
|
|
||||||
QList<QPair<QString, QString>> items;
|
|
||||||
for (const auto &q : GetActionQueues()) {
|
|
||||||
const QString name =
|
|
||||||
QString::fromStdString(q->Name());
|
|
||||||
items.append({name, name});
|
|
||||||
}
|
|
||||||
return items;
|
|
||||||
}});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#include "macro-export-extensions.hpp"
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
static std::vector<MacroExportExtension> extensions;
|
|
||||||
|
|
||||||
void AddMacroExportExtension(const MacroExportExtension &ext)
|
|
||||||
{
|
|
||||||
extensions.emplace_back(ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<MacroExportExtension> &GetMacroExportExtensions()
|
|
||||||
{
|
|
||||||
return extensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "export-symbol-helper.hpp"
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <obs-data.h>
|
|
||||||
#include <QList>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QString>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace advss {
|
|
||||||
|
|
||||||
struct MacroExportExtension {
|
|
||||||
const char *displayNameKey;
|
|
||||||
const char *jsonKey;
|
|
||||||
|
|
||||||
// Export callback.
|
|
||||||
// Write content into 'data'. 'selectedIds' contains the item IDs the
|
|
||||||
// user explicitly checked; if empty (no per-item widget provided) save
|
|
||||||
// everything.
|
|
||||||
std::function<void(obs_data_t *data, const QStringList &selectedIds)>
|
|
||||||
save;
|
|
||||||
|
|
||||||
// Import callback.
|
|
||||||
// Read content from 'data'. 'selectedIds' contains the item IDs the
|
|
||||||
// user explicitly checked; if empty import every item found in 'data'.
|
|
||||||
std::function<void(obs_data_t *data, const QStringList &selectedIds)>
|
|
||||||
load;
|
|
||||||
|
|
||||||
// Optional: enumerate items available for export as (id, displayName)
|
|
||||||
// pairs. When nullptr the extension appears as a single all-or-nothing
|
|
||||||
// checkbox in the export dialog.
|
|
||||||
std::function<QList<QPair<QString, QString>>()> getExportItems =
|
|
||||||
nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
EXPORT void AddMacroExportExtension(const MacroExportExtension &ext);
|
|
||||||
const std::vector<MacroExportExtension> &GetMacroExportExtensions();
|
|
||||||
|
|
||||||
} // namespace advss
|
|
||||||
@@ -1,183 +1,22 @@
|
|||||||
#include "macro-export-import-dialog.hpp"
|
#include "macro-export-import-dialog.hpp"
|
||||||
#include "macro-export-extensions.hpp"
|
|
||||||
#include "obs-module-helper.hpp"
|
#include "obs-module-helper.hpp"
|
||||||
#include "section.hpp"
|
|
||||||
|
|
||||||
#include <obs.hpp>
|
#include <obs.hpp>
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QScrollArea>
|
#include <QLabel>
|
||||||
#include <QSplitter>
|
#include <QDialogButtonBox>
|
||||||
#include <algorithm>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
static bool usePlainText = false;
|
static bool usePlainText = false;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
MacroExportImportDialog::MacroExportImportDialog(Type type)
|
||||||
// Compress / decompress helpers
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static QString compressMacroString(const QString &input)
|
|
||||||
{
|
|
||||||
QByteArray inputData = input.toUtf8();
|
|
||||||
auto compressedData = qCompress(inputData);
|
|
||||||
QByteArray encodedData = compressedData.toBase64();
|
|
||||||
return QString::fromUtf8(encodedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString decompressMacroString(const QString &input)
|
|
||||||
{
|
|
||||||
QByteArray encodedData = input.toUtf8();
|
|
||||||
QByteArray compressedData = QByteArray::fromBase64(encodedData);
|
|
||||||
auto outputData = qUncompress(compressedData);
|
|
||||||
return QString::fromUtf8(outputData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isValidData(const QString &json)
|
|
||||||
{
|
|
||||||
OBSDataAutoRelease data =
|
|
||||||
obs_data_create_from_json(json.toStdString().c_str());
|
|
||||||
return !!data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Extension section
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
QWidget *MacroExportImportDialog::BuildExtensionWidget()
|
|
||||||
{
|
|
||||||
auto wrapper = new QWidget(this);
|
|
||||||
auto wrapperLayout = new QVBoxLayout(wrapper);
|
|
||||||
wrapperLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
wrapperLayout->setSpacing(4);
|
|
||||||
|
|
||||||
wrapperLayout->addWidget(new QLabel(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.macroTab.export.additionalContent")));
|
|
||||||
|
|
||||||
auto outerContent = new QWidget();
|
|
||||||
auto outerLayout = new QVBoxLayout(outerContent);
|
|
||||||
outerLayout->setContentsMargins(4, 4, 4, 4);
|
|
||||||
outerLayout->setSpacing(4);
|
|
||||||
|
|
||||||
const auto &extensions = GetMacroExportExtensions();
|
|
||||||
|
|
||||||
std::vector<int> order(extensions.size());
|
|
||||||
std::iota(order.begin(), order.end(), 0);
|
|
||||||
std::sort(order.begin(), order.end(), [&](int a, int b) {
|
|
||||||
return QString::localeAwareCompare(
|
|
||||||
obs_module_text(extensions[a].displayNameKey),
|
|
||||||
obs_module_text(extensions[b].displayNameKey)) <
|
|
||||||
0;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (int extIdx : order) {
|
|
||||||
const auto &ext = extensions[extIdx];
|
|
||||||
ExtensionUI ui;
|
|
||||||
|
|
||||||
// Simple all-or-nothing checkbox (no sub-items).
|
|
||||||
if (!ext.getExportItems) {
|
|
||||||
ui.mainCheck = new QCheckBox(
|
|
||||||
obs_module_text(ext.displayNameKey),
|
|
||||||
outerContent);
|
|
||||||
ui.mainCheck->setChecked(false);
|
|
||||||
connect(ui.mainCheck, &QCheckBox::stateChanged, this,
|
|
||||||
&MacroExportImportDialog::UpdateExportString);
|
|
||||||
outerLayout->addWidget(ui.mainCheck);
|
|
||||||
_extensionUIs.append(std::move(ui));
|
|
||||||
_extensionOrder.push_back(extIdx);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extensions with per-item selection get their own inner
|
|
||||||
// Section: the main checkbox sits in the header (next to the
|
|
||||||
// toggle arrow) and the per-item checkboxes live in the
|
|
||||||
// collapsible content area.
|
|
||||||
auto items = ext.getExportItems();
|
|
||||||
if (items.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(items.begin(), items.end(),
|
|
||||||
[](const QPair<QString, QString> &a,
|
|
||||||
const QPair<QString, QString> &b) {
|
|
||||||
return QString::localeAwareCompare(
|
|
||||||
a.second, b.second) < 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto innerSection = new Section(200, outerContent);
|
|
||||||
|
|
||||||
ui.mainCheck =
|
|
||||||
new QCheckBox(obs_module_text(ext.displayNameKey));
|
|
||||||
ui.mainCheck->setChecked(false);
|
|
||||||
innerSection->AddHeaderWidget(ui.mainCheck);
|
|
||||||
|
|
||||||
auto subWidget = new QWidget();
|
|
||||||
auto subLayout = new QVBoxLayout(subWidget);
|
|
||||||
subLayout->setContentsMargins(4, 2, 4, 2);
|
|
||||||
subLayout->setSpacing(2);
|
|
||||||
|
|
||||||
for (const auto &[id, displayName] : items) {
|
|
||||||
auto cb = new QCheckBox(displayName, subWidget);
|
|
||||||
cb->setChecked(false);
|
|
||||||
subLayout->addWidget(cb);
|
|
||||||
ui.itemChecks.append({id, cb});
|
|
||||||
connect(cb, &QCheckBox::stateChanged, this,
|
|
||||||
&MacroExportImportDialog::UpdateExportString);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main checkbox toggles all sub-items.
|
|
||||||
// Capture uiIdx (position in _extensionUIs after append).
|
|
||||||
const int uiIdx = _extensionUIs.size();
|
|
||||||
connect(ui.mainCheck, &QCheckBox::stateChanged, this,
|
|
||||||
[this, uiIdx](int state) {
|
|
||||||
if (state == Qt::PartiallyChecked)
|
|
||||||
return;
|
|
||||||
const bool checked = (state == Qt::Checked);
|
|
||||||
if (uiIdx < _extensionUIs.size()) {
|
|
||||||
for (auto &[id, cb] :
|
|
||||||
_extensionUIs[uiIdx].itemChecks) {
|
|
||||||
QSignalBlocker b(cb);
|
|
||||||
cb->setChecked(checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateExportString();
|
|
||||||
});
|
|
||||||
|
|
||||||
innerSection->SetContent(subWidget, true);
|
|
||||||
outerLayout->addWidget(innerSection);
|
|
||||||
_extensionUIs.append(std::move(ui));
|
|
||||||
_extensionOrder.push_back(extIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
outerLayout->addStretch();
|
|
||||||
|
|
||||||
auto scrollArea = new QScrollArea(wrapper);
|
|
||||||
scrollArea->setWidget(outerContent);
|
|
||||||
scrollArea->setWidgetResizable(true);
|
|
||||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
scrollArea->setFrameShape(QFrame::NoFrame);
|
|
||||||
wrapperLayout->addWidget(scrollArea);
|
|
||||||
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Constructor
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
MacroExportImportDialog::MacroExportImportDialog(Type type,
|
|
||||||
const QString &baseJson)
|
|
||||||
: QDialog(nullptr),
|
: QDialog(nullptr),
|
||||||
_baseJson(baseJson),
|
|
||||||
_importExportString(new QPlainTextEdit(this)),
|
_importExportString(new QPlainTextEdit(this)),
|
||||||
_usePlainText(new QCheckBox(obs_module_text(
|
_usePlainText(new QCheckBox(obs_module_text(
|
||||||
"AdvSceneSwitcher.macroTab.export.usePlainText")))
|
"AdvSceneSwitcher.macroTab.export.usePlainText")))
|
||||||
{
|
{
|
||||||
_importExportString->setReadOnly(type == Type::EXPORT_MACRO);
|
_importExportString->setReadOnly(type == Type::EXPORT_MACRO);
|
||||||
|
|
||||||
auto label = new QLabel(obs_module_text(
|
auto label = new QLabel(obs_module_text(
|
||||||
type == Type::EXPORT_MACRO
|
type == Type::EXPORT_MACRO
|
||||||
? "AdvSceneSwitcher.macroTab.export.info"
|
? "AdvSceneSwitcher.macroTab.export.info"
|
||||||
@@ -200,90 +39,40 @@ MacroExportImportDialog::MacroExportImportDialog(Type type,
|
|||||||
connect(_usePlainText, &QCheckBox::stateChanged, this,
|
connect(_usePlainText, &QCheckBox::stateChanged, this,
|
||||||
&MacroExportImportDialog::UsePlainTextChanged);
|
&MacroExportImportDialog::UsePlainTextChanged);
|
||||||
|
|
||||||
auto layout = new QVBoxLayout(this);
|
auto layout = new QVBoxLayout;
|
||||||
|
layout->addWidget(label);
|
||||||
if (type == Type::EXPORT_MACRO && !GetMacroExportExtensions().empty()) {
|
layout->addWidget(_importExportString);
|
||||||
auto splitter = new QSplitter(Qt::Vertical, this);
|
layout->addWidget(_usePlainText);
|
||||||
splitter->setChildrenCollapsible(false);
|
|
||||||
splitter->addWidget(BuildExtensionWidget());
|
|
||||||
|
|
||||||
auto textWidget = new QWidget(splitter);
|
|
||||||
auto textLayout = new QVBoxLayout(textWidget);
|
|
||||||
textLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
textLayout->addWidget(label);
|
|
||||||
textLayout->addWidget(_importExportString);
|
|
||||||
textLayout->addWidget(_usePlainText);
|
|
||||||
splitter->addWidget(textWidget);
|
|
||||||
|
|
||||||
layout->addWidget(splitter);
|
|
||||||
} else {
|
|
||||||
layout->addWidget(label);
|
|
||||||
layout->addWidget(_importExportString);
|
|
||||||
layout->addWidget(_usePlainText);
|
|
||||||
}
|
|
||||||
|
|
||||||
layout->addWidget(buttons);
|
layout->addWidget(buttons);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
|
||||||
|
|
||||||
if (type == Type::EXPORT_MACRO) {
|
|
||||||
RefreshExportText();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
QString compressMacroString(const QString &input)
|
||||||
// Export string helpers
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
QString MacroExportImportDialog::BuildExportJson() const
|
|
||||||
{
|
{
|
||||||
OBSDataAutoRelease data =
|
QByteArray inputData = input.toUtf8();
|
||||||
obs_data_create_from_json(_baseJson.toStdString().c_str());
|
auto compressedData = qCompress(inputData);
|
||||||
if (!data) {
|
QByteArray encodedData = compressedData.toBase64();
|
||||||
return _baseJson;
|
return QString::fromUtf8(encodedData);
|
||||||
}
|
|
||||||
|
|
||||||
const auto &extensions = GetMacroExportExtensions();
|
|
||||||
for (int i = 0; i < (int)_extensionUIs.size(); ++i) {
|
|
||||||
const auto &ui = _extensionUIs[i];
|
|
||||||
|
|
||||||
QStringList selectedIds;
|
|
||||||
if (ui.itemChecks.isEmpty()) {
|
|
||||||
if (!ui.mainCheck->isChecked()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (const auto &[id, cb] : ui.itemChecks) {
|
|
||||||
if (cb->isChecked()) {
|
|
||||||
selectedIds << id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectedIds.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extensions[_extensionOrder[i]].save(data, selectedIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *json = obs_data_get_json(data);
|
|
||||||
return json ? QString::fromUtf8(json) : QString{};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroExportImportDialog::RefreshExportText()
|
QString decompressMacroString(const QString &input)
|
||||||
{
|
{
|
||||||
const QString json = BuildExportJson();
|
QByteArray encodedData = input.toUtf8();
|
||||||
if (usePlainText) {
|
QByteArray compressedData = QByteArray::fromBase64(encodedData);
|
||||||
_importExportString->setPlainText(json);
|
auto outputData = qUncompress(compressedData);
|
||||||
} else {
|
return QString::fromUtf8(outputData);
|
||||||
_importExportString->setPlainText(compressMacroString(json));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroExportImportDialog::UpdateExportString()
|
void MacroExportImportDialog::ExportMacros(const QString &json)
|
||||||
{
|
{
|
||||||
RefreshExportText();
|
MacroExportImportDialog dialog(
|
||||||
|
MacroExportImportDialog::Type::EXPORT_MACRO);
|
||||||
|
dialog._importExportString->setPlainText(compressMacroString(json));
|
||||||
|
dialog.adjustSize();
|
||||||
|
dialog.updateGeometry();
|
||||||
|
dialog.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroExportImportDialog::UsePlainTextChanged(int value)
|
void MacroExportImportDialog::UsePlainTextChanged(int value)
|
||||||
@@ -301,45 +90,26 @@ void MacroExportImportDialog::UsePlainTextChanged(int value)
|
|||||||
usePlainText = value;
|
usePlainText = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
static bool isValidData(const QString &json)
|
||||||
// Static entry points
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void MacroExportImportDialog::ExportMacros(obs_data_t *macroData)
|
|
||||||
{
|
{
|
||||||
const char *rawJson = obs_data_get_json(macroData);
|
OBSDataAutoRelease data =
|
||||||
const QString baseJson = rawJson ? QString::fromUtf8(rawJson)
|
obs_data_create_from_json(json.toStdString().c_str());
|
||||||
: QString{};
|
return !!data;
|
||||||
|
|
||||||
MacroExportImportDialog dialog(Type::EXPORT_MACRO, baseJson);
|
|
||||||
dialog.adjustSize();
|
|
||||||
dialog.updateGeometry();
|
|
||||||
dialog.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroExportImportDialog::ImportMacros(QString &json)
|
bool MacroExportImportDialog::ImportMacros(QString &json)
|
||||||
{
|
{
|
||||||
MacroExportImportDialog dialog(Type::IMPORT_MACRO);
|
MacroExportImportDialog dialog(
|
||||||
if (dialog.exec() != QDialog::Accepted) {
|
MacroExportImportDialog::Type::IMPORT_MACRO);
|
||||||
return false;
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
}
|
json = decompressMacroString(
|
||||||
|
dialog._importExportString->toPlainText());
|
||||||
json = decompressMacroString(dialog._importExportString->toPlainText());
|
if (!isValidData(json)) { // Fallback to support raw json format
|
||||||
if (!isValidData(json)) {
|
json = dialog._importExportString->toPlainText();
|
||||||
// Fallback: support raw (uncompressed) JSON pasted directly.
|
|
||||||
json = dialog._importExportString->toPlainText();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke all extension load callbacks.
|
|
||||||
OBSDataAutoRelease data =
|
|
||||||
obs_data_create_from_json(json.toStdString().c_str());
|
|
||||||
if (data) {
|
|
||||||
for (const auto &ext : GetMacroExportExtensions()) {
|
|
||||||
ext.load(data, {});
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,47 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QList>
|
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
#include <obs-data.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
class MacroExportImportDialog : public QDialog {
|
class MacroExportImportDialog : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum class Type { EXPORT_MACRO, IMPORT_MACRO };
|
enum class Type { EXPORT_MACRO, IMPORT_MACRO };
|
||||||
|
MacroExportImportDialog(Type type);
|
||||||
|
|
||||||
static void ExportMacros(obs_data_t *macroData);
|
static void ExportMacros(const QString &json);
|
||||||
static bool ImportMacros(QString &json);
|
static bool ImportMacros(QString &json);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void UsePlainTextChanged(int);
|
void UsePlainTextChanged(int);
|
||||||
void UpdateExportString();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit MacroExportImportDialog(Type type,
|
|
||||||
const QString &baseJson = {});
|
|
||||||
|
|
||||||
// Per-extension widgets
|
|
||||||
struct ExtensionUI {
|
|
||||||
QCheckBox *mainCheck = nullptr;
|
|
||||||
// (itemId, checkbox) pairs - empty when no per-item selection.
|
|
||||||
QList<QPair<QString, QCheckBox *>> itemChecks;
|
|
||||||
};
|
|
||||||
|
|
||||||
QWidget *BuildExtensionWidget();
|
|
||||||
QString BuildExportJson() const;
|
|
||||||
void RefreshExportText();
|
|
||||||
|
|
||||||
QString _baseJson;
|
|
||||||
QPlainTextEdit *_importExportString;
|
QPlainTextEdit *_importExportString;
|
||||||
QCheckBox *_usePlainText;
|
QCheckBox *_usePlainText;
|
||||||
QList<ExtensionUI> _extensionUIs;
|
|
||||||
std::vector<int> _extensionOrder;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "macro-helpers.hpp"
|
#include "macro-helpers.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "macro-action-macro.hpp"
|
|
||||||
#include "plugin-state-helpers.hpp"
|
#include "plugin-state-helpers.hpp"
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
@@ -9,87 +8,6 @@ static std::atomic_bool abortMacroWait = {false};
|
|||||||
static std::atomic_bool macroSceneSwitched = {false};
|
static std::atomic_bool macroSceneSwitched = {false};
|
||||||
static std::atomic_int shutdownConditionCount = {0};
|
static std::atomic_int shutdownConditionCount = {0};
|
||||||
|
|
||||||
static void appendNestedMacros(std::deque<std::shared_ptr<Macro>> ¯os,
|
|
||||||
Macro *macro)
|
|
||||||
{
|
|
||||||
if (!macro) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto iterate = [¯os](const std::deque<
|
|
||||||
std::shared_ptr<MacroAction>> &actions) {
|
|
||||||
for (const auto &action : actions) {
|
|
||||||
const auto nestedMacroAction =
|
|
||||||
dynamic_cast<MacroActionMacro *>(action.get());
|
|
||||||
if (!nestedMacroAction) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
macros.push_back(nestedMacroAction->_nestedMacro);
|
|
||||||
appendNestedMacros(
|
|
||||||
macros, nestedMacroAction->_nestedMacro.get());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
iterate(macro->Actions());
|
|
||||||
iterate(macro->ElseActions());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::deque<std::shared_ptr<Macro>> &GetTopLevelMacros()
|
|
||||||
{
|
|
||||||
static std::deque<std::shared_ptr<Macro>> macros;
|
|
||||||
return macros;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::deque<std::shared_ptr<Macro>> &GetTemporaryMacros()
|
|
||||||
{
|
|
||||||
static std::deque<std::shared_ptr<Macro>> tempMacros;
|
|
||||||
return tempMacros;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::deque<std::shared_ptr<Macro>> GetAllMacros()
|
|
||||||
{
|
|
||||||
auto macros = GetTopLevelMacros();
|
|
||||||
for (const auto &topLevelMacro : macros) {
|
|
||||||
appendNestedMacros(macros, topLevelMacro.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &tempMacros = GetTemporaryMacros();
|
|
||||||
macros.insert(macros.end(), tempMacros.begin(), tempMacros.end());
|
|
||||||
for (const auto &tempMacro : tempMacros) {
|
|
||||||
appendNestedMacros(macros, tempMacro.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return macros;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -99,15 +17,6 @@ GetMacroActions(Macro *macro)
|
|||||||
return macro->Actions();
|
return macro->Actions();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::deque<std::shared_ptr<MacroAction>>>
|
|
||||||
GetMacroElseActions(Macro *macro)
|
|
||||||
{
|
|
||||||
if (!macro) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return macro->ElseActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::deque<std::shared_ptr<MacroCondition>>>
|
std::optional<std::deque<std::shared_ptr<MacroCondition>>>
|
||||||
GetMacroConditions(Macro *macro)
|
GetMacroConditions(Macro *macro)
|
||||||
{
|
{
|
||||||
@@ -117,32 +26,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()
|
||||||
@@ -214,20 +100,6 @@ bool MacroIsPaused(const Macro *macro)
|
|||||||
return macro ? macro->Paused() : true;
|
return macro ? macro->Paused() : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMacroPaused(Macro *macro, bool paused)
|
|
||||||
{
|
|
||||||
if (macro) {
|
|
||||||
macro->SetPaused(paused);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopMacro(Macro *macro)
|
|
||||||
{
|
|
||||||
if (macro) {
|
|
||||||
macro->Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroWasPausedSince(
|
bool MacroWasPausedSince(
|
||||||
const Macro *macro,
|
const Macro *macro,
|
||||||
const std::chrono::high_resolution_clock::time_point &time)
|
const std::chrono::high_resolution_clock::time_point &time)
|
||||||
@@ -251,20 +123,9 @@ void AddMacroHelperThread(Macro *macro, std::thread &&newThread)
|
|||||||
macro->AddHelperThread(std::move(newThread));
|
macro->AddHelperThread(std::move(newThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RunMacroActions(Macro *macro, bool forceParallel, bool ignorePause)
|
bool RunMacroActions(Macro *macro)
|
||||||
{
|
{
|
||||||
return macro && macro->PerformActions(true, forceParallel, ignorePause);
|
return macro && macro->PerformActions(true);
|
||||||
}
|
|
||||||
|
|
||||||
bool RunMacroElseActions(Macro *macro, bool forceParallel, bool ignorePause)
|
|
||||||
{
|
|
||||||
return macro &&
|
|
||||||
macro->PerformActions(false, forceParallel, ignorePause);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckMacroConditions(Macro *macro, bool ignorePause)
|
|
||||||
{
|
|
||||||
return macro && macro->CheckConditions(ignorePause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetMacroConditionTimers(Macro *macro)
|
void ResetMacroConditionTimers(Macro *macro)
|
||||||
@@ -283,42 +144,20 @@ void ResetMacroRunCount(Macro *macro)
|
|||||||
macro->ResetRunCount();
|
macro->ResetRunCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValidActionIndex(const Macro *m, const int idx)
|
bool IsValidMacroSegmentIndex(const Macro *m, const int idx, bool isCondition)
|
||||||
{
|
{
|
||||||
if (!m || idx < 0) {
|
if (!m || idx < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (isCondition) {
|
||||||
if (idx >= (int)m->Actions().size()) {
|
if (idx >= (int)m->Conditions().size()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (idx >= (int)m->Actions().size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsValidElseActionIndex(const Macro *m, const int idx)
|
|
||||||
{
|
|
||||||
if (!m || idx < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idx >= (int)m->ElseActions().size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsValidConditionIndex(const Macro *m, const int idx)
|
|
||||||
{
|
|
||||||
if (!m || idx < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idx >= (int)m->Conditions().size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
#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>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
struct obs_data;
|
struct obs_data;
|
||||||
@@ -19,25 +18,16 @@ class Macro;
|
|||||||
class MacroAction;
|
class MacroAction;
|
||||||
class MacroCondition;
|
class MacroCondition;
|
||||||
|
|
||||||
static const int macro_func = 10;
|
EXPORT std::deque<std::shared_ptr<Macro>> &GetMacros();
|
||||||
|
|
||||||
EXPORT std::deque<std::shared_ptr<Macro>> &GetTopLevelMacros();
|
|
||||||
std::deque<std::shared_ptr<Macro>> &GetTemporaryMacros();
|
|
||||||
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>>>
|
|
||||||
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();
|
||||||
@@ -58,8 +48,6 @@ LastMacroConditionCheckTime(const Macro *);
|
|||||||
|
|
||||||
EXPORT bool MacroIsStopped(const Macro *);
|
EXPORT bool MacroIsStopped(const Macro *);
|
||||||
EXPORT bool MacroIsPaused(const Macro *);
|
EXPORT bool MacroIsPaused(const Macro *);
|
||||||
EXPORT void SetMacroPaused(Macro *, bool paused);
|
|
||||||
EXPORT void StopMacro(Macro *);
|
|
||||||
EXPORT bool
|
EXPORT bool
|
||||||
MacroWasPausedSince(const Macro *,
|
MacroWasPausedSince(const Macro *,
|
||||||
const std::chrono::high_resolution_clock::time_point &);
|
const std::chrono::high_resolution_clock::time_point &);
|
||||||
@@ -68,16 +56,10 @@ EXPORT bool MacroWasCheckedSinceLastStart(const Macro *);
|
|||||||
EXPORT void AddMacroHelperThread(Macro *, std::thread &&);
|
EXPORT void AddMacroHelperThread(Macro *, std::thread &&);
|
||||||
|
|
||||||
EXPORT bool CheckMacros();
|
EXPORT bool CheckMacros();
|
||||||
EXPORT bool CheckMacroConditions(Macro *, bool ignorePause = false);
|
|
||||||
|
|
||||||
EXPORT bool RunMacroActions(Macro *, bool forceParallel = false,
|
EXPORT bool RunMacroActions(Macro *);
|
||||||
bool ignorePause = false);
|
|
||||||
EXPORT bool RunMacroElseActions(Macro *, bool forceParallel = false,
|
|
||||||
bool ignorePause = false);
|
|
||||||
EXPORT bool RunMacros();
|
EXPORT bool RunMacros();
|
||||||
|
void StopAllMacros();
|
||||||
void SignalStopAllMacros();
|
|
||||||
void WaitForAllMacros();
|
|
||||||
|
|
||||||
EXPORT void LoadMacros(obs_data_t *obj);
|
EXPORT void LoadMacros(obs_data_t *obj);
|
||||||
EXPORT void SaveMacros(obs_data_t *obj);
|
EXPORT void SaveMacros(obs_data_t *obj);
|
||||||
@@ -86,8 +68,6 @@ EXPORT void InvalidateMacroTempVarValues();
|
|||||||
EXPORT void ResetMacroConditionTimers(Macro *);
|
EXPORT void ResetMacroConditionTimers(Macro *);
|
||||||
EXPORT void ResetMacroRunCount(Macro *);
|
EXPORT void ResetMacroRunCount(Macro *);
|
||||||
|
|
||||||
bool IsValidActionIndex(const Macro *m, const int idx);
|
bool IsValidMacroSegmentIndex(const Macro *m, const int idx, bool isCondition);
|
||||||
bool IsValidElseActionIndex(const Macro *m, const int idx);
|
|
||||||
bool IsValidConditionIndex(const Macro *m, const int idx);
|
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "macro-list.hpp"
|
#include "macro-list.hpp"
|
||||||
#include "macro-helpers.hpp"
|
#include "macro-helpers.hpp"
|
||||||
#include "macro-selection.hpp"
|
#include "macro-selection.hpp"
|
||||||
#include "macro-signals.hpp"
|
|
||||||
#include "obs-module-helper.hpp"
|
#include "obs-module-helper.hpp"
|
||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
|
|
||||||
@@ -11,11 +10,11 @@ MacroList::MacroList(QWidget *parent, bool allowDuplicates, bool reorder)
|
|||||||
: ListEditor(parent, reorder),
|
: ListEditor(parent, reorder),
|
||||||
_allowDuplicates(allowDuplicates)
|
_allowDuplicates(allowDuplicates)
|
||||||
{
|
{
|
||||||
QWidget::connect(MacroSignalManager::Instance(),
|
QWidget::connect(window(),
|
||||||
SIGNAL(Rename(const QString &, const QString &)), this,
|
SIGNAL(MacroRenamed(const QString &, const QString &)),
|
||||||
|
this,
|
||||||
SLOT(MacroRename(const QString &, const QString &)));
|
SLOT(MacroRename(const QString &, const QString &)));
|
||||||
QWidget::connect(MacroSignalManager::Instance(),
|
QWidget::connect(window(), SIGNAL(MacroRemoved(const QString &)), this,
|
||||||
SIGNAL(Remove(const QString &)), this,
|
|
||||||
SLOT(MacroRemove(const QString &)));
|
SLOT(MacroRemove(const QString &)));
|
||||||
UpdateListSize();
|
UpdateListSize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
#include "macro-ref.hpp"
|
#include "macro-ref.hpp"
|
||||||
|
|
||||||
#include "macro-helpers.hpp"
|
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "plugin-state-helpers.hpp"
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -22,7 +19,6 @@ void MacroRef::Load(obs_data_t *obj)
|
|||||||
auto name = obs_data_get_string(obj, "macro");
|
auto name = obs_data_get_string(obj, "macro");
|
||||||
_postLoadName = name;
|
_postLoadName = name;
|
||||||
_macro = GetWeakMacroByName(name);
|
_macro = GetWeakMacroByName(name);
|
||||||
AddPostLoadStep([this]() { MacroRef::PostLoad(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroRef::PostLoad()
|
void MacroRef::PostLoad()
|
||||||
@@ -75,11 +71,11 @@ void LoadMacroList(obs_data_t *obj, std::vector<MacroRef> ¯os,
|
|||||||
{
|
{
|
||||||
obs_data_array_t *array = obs_data_get_array(obj, name.c_str());
|
obs_data_array_t *array = obs_data_get_array(obj, name.c_str());
|
||||||
size_t count = obs_data_array_count(array);
|
size_t count = obs_data_array_count(array);
|
||||||
macros.reserve(macros.size() + count);
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
obs_data_t *array_obj = obs_data_array_item(array, i);
|
obs_data_t *array_obj = obs_data_array_item(array, i);
|
||||||
macros.emplace_back();
|
MacroRef ref;
|
||||||
macros.back().Load(array_obj);
|
ref.Load(array_obj);
|
||||||
|
macros.push_back(ref);
|
||||||
obs_data_release(array_obj);
|
obs_data_release(array_obj);
|
||||||
}
|
}
|
||||||
obs_data_array_release(array);
|
obs_data_array_release(array);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user