Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bedbf6fb8 | ||
|
|
853150e458 | ||
|
|
1ddd48e008 | ||
|
|
17d24d642e | ||
|
|
87a46684cd | ||
|
|
e4c5193945 | ||
|
|
2e969bf6dd | ||
|
|
6db26d9f7b | ||
|
|
4f02c9ec36 | ||
|
|
2fdd39fba5 | ||
|
|
fe1ddc3a94 | ||
|
|
cff2d805db | ||
|
|
34425d3e47 | ||
|
|
4ac4f00620 | ||
|
|
e30a4623c5 | ||
|
|
e2f4dcaaee | ||
|
|
ebbf64ddae | ||
|
|
8b105ad22b | ||
|
|
f3416c5b1d | ||
|
|
e194fc5ee4 | ||
|
|
e465c81bf1 | ||
|
|
9dce6a99fd | ||
|
|
6f2c53d14e | ||
|
|
9044ae4ade | ||
|
|
0a422174bc | ||
|
|
c2020fe77c | ||
|
|
8beca6fcc7 | ||
|
|
18769df2ca | ||
|
|
2806fd6cdb | ||
|
|
b607940c8c | ||
|
|
dff599df4c | ||
|
|
b3cd38e019 | ||
|
|
61975e1992 | ||
|
|
1a8ad69f23 | ||
|
|
f21e40151b | ||
|
|
4e58769648 | ||
|
|
f9d6001025 | ||
|
|
ae5f5f90ff | ||
|
|
89db21d734 | ||
|
|
0e4b072650 | ||
|
|
13b0e00b27 | ||
|
|
bf5d8ca19e | ||
|
|
4a3339c09c | ||
|
|
b28c2b28b2 | ||
|
|
fcb3e648d2 | ||
|
|
5d6f08e38f | ||
|
|
b932af1c97 | ||
|
|
8874eb2b1c | ||
|
|
dcf9816a72 | ||
|
|
c8722c9f62 | ||
|
|
a82a2ccffe | ||
|
|
0bf70e443e | ||
|
|
3d6d690583 | ||
|
|
783f76d55d | ||
|
|
1dd46fb777 | ||
|
|
22bbd3a4ca | ||
|
|
3cd4b2251f | ||
|
|
9e4b003608 | ||
|
|
e66d0bc6b8 | ||
|
|
9a4abd78ed | ||
|
|
826bee8b1e | ||
|
|
143020dc27 | ||
|
|
be23065988 | ||
|
|
2cb62eae96 | ||
|
|
76c411d1e2 | ||
|
|
16fa91c2a1 | ||
|
|
b77f8717fe | ||
|
|
59ecf43c5f | ||
|
|
1fd8546354 | ||
|
|
7cb95cb3f6 | ||
|
|
160d19d6c1 | ||
|
|
a0550ca141 | ||
|
|
ac68fc016d | ||
|
|
5170307f72 | ||
|
|
3af0e51bd2 | ||
|
|
f34d1fe081 | ||
|
|
83c72ebba5 | ||
|
|
6ca8e6b3ea | ||
|
|
ba24fc2fab | ||
|
|
7f28b22599 | ||
|
|
4345db0d2e | ||
|
|
eddc10c3e2 | ||
|
|
46eaada0c4 | ||
|
|
f8b2dea270 | ||
|
|
90ebf0e0f8 | ||
|
|
1a819c807e |
37
.github/actions/run-tests/action.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: 'Package plugin'
|
||||
description: 'Packages the plugin for specified architecture and build config.'
|
||||
inputs:
|
||||
target:
|
||||
description: 'Build target'
|
||||
required: true
|
||||
workingDirectory:
|
||||
description: 'Working directory'
|
||||
required: false
|
||||
default: ${{ github.workspace }}
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Run macOS tests
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
shell: zsh {0}
|
||||
run: |
|
||||
if [[ '${{ inputs.target }}' != 'x86_64' ]]; then
|
||||
echo tests skipped!
|
||||
exit 0
|
||||
fi
|
||||
${{ inputs.workingDirectory }}/build_x86_64/tests/advanced-scene-switcher-tests
|
||||
|
||||
- name: Run Linux packaging
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ '${{ inputs.target }}' != 'x86_64' ]]; then
|
||||
exit 0
|
||||
fi
|
||||
${{ inputs.workingDirectory }}/build_x86_64/tests/advanced-scene-switcher-tests
|
||||
|
||||
- name: Run Windows packaging
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
${{ inputs.workingDirectory }}/build_x64/tests/RelWithDebInfo/advanced-scene-switcher-tests.exe
|
||||
87
.github/scripts/.build.zsh
vendored
@@ -170,26 +170,38 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
|
||||
local product_name
|
||||
local product_version
|
||||
local git_tag="$(git describe --tags)"
|
||||
|
||||
read -r product_name product_version <<< \
|
||||
"$(jq -r '. | {name, version} | join(" ")' ${buildspec_file})"
|
||||
|
||||
local opencv_dir="${project_root}/deps/opencv"
|
||||
local opencv_build_dir="${opencv_dir}/build_${target##*-}"
|
||||
if [[ "${git_tag}" =~ '^([0-9]+\.){0,2}(\*|[0-9]+)$' ]] {
|
||||
log_info "Using git tag as version identifier '${git_tag}'"
|
||||
product_version="${git_tag}"
|
||||
} else {
|
||||
log_info "Using buildspec.json version identifier '${product_version}'"
|
||||
}
|
||||
|
||||
case ${host_os} {
|
||||
macos)
|
||||
sed -i '' \
|
||||
"s/project(\(.*\) VERSION \(.*\))/project(${product_name} VERSION ${product_version})/" \
|
||||
"${project_root}/CMakeLists.txt"
|
||||
|
||||
# Note: IPP must be set to OFF to avoid build failures on ARM architectures
|
||||
local opencv_dir="${project_root}/deps/opencv"
|
||||
local opencv_build_dir="${opencv_dir}/build_${target##*-}"
|
||||
|
||||
local -a opencv_cmake_args=(
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DBUILD_LIST=core,imgproc,objdetect
|
||||
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||
-DWITH_IPP=OFF
|
||||
)
|
||||
|
||||
if [ "${target}" != "macos-x86_64" ]; then
|
||||
opencv_cmake_args+=(-DWITH_IPP=OFF)
|
||||
fi
|
||||
|
||||
pushd ${opencv_dir}
|
||||
log_info "Configure OpenCV ..."
|
||||
cmake -S . -B ${opencv_build_dir} -G ${generator} ${opencv_cmake_args}
|
||||
@@ -198,9 +210,73 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
cmake --build ${opencv_build_dir} --config Release
|
||||
|
||||
log_info "Installing OpenCV..."
|
||||
cmake --install ${opencv_build_dir} --config Release --prefix ${opencv_build_dir}
|
||||
cmake --install ${opencv_build_dir} --config Release || true
|
||||
popd
|
||||
|
||||
local leptonica_dir="${project_root}/deps/leptonica"
|
||||
local leptonica_build_dir="${leptonica_dir}/build_${target##*-}"
|
||||
|
||||
local -a leptonica_cmake_args=(
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||
-DSW_BUILD=OFF
|
||||
-DOPENJPEG_SUPPORT=OFF
|
||||
-DLIBWEBP_SUPPORT=OFF
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_GIF=TRUE
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_JPEG=TRUE
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_TIFF=TRUE
|
||||
-DCMAKE_DISABLE_FIND_PACKAGE_PNG=TRUE
|
||||
)
|
||||
|
||||
pushd ${leptonica_dir}
|
||||
log_info "Configure Leptonica ..."
|
||||
cmake -S . -B ${leptonica_build_dir} -G ${generator} ${leptonica_cmake_args}
|
||||
|
||||
log_info "Building Leptonica ..."
|
||||
cmake --build ${leptonica_build_dir} --config Release
|
||||
|
||||
log_info "Installing Leptonica..."
|
||||
# Workaround for "unknown file attribute: H" errors when running install
|
||||
cmake --install ${leptonica_build_dir} --config Release || :
|
||||
popd
|
||||
|
||||
local tesseract_dir="${project_root}/deps/tesseract"
|
||||
local tesseract_build_dir="${tesseract_dir}/build_${target##*-}"
|
||||
|
||||
local -a tesseract_cmake_args=(
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||
-DSW_BUILD=OFF
|
||||
-DBUILD_TRAINING_TOOLS=OFF
|
||||
)
|
||||
|
||||
if [ "${target}" != "macos-x86_64" ]; then
|
||||
tesseract_cmake_args+=(
|
||||
-DCMAKE_SYSTEM_PROCESSOR=aarch64
|
||||
-DHAVE_AVX=FALSE
|
||||
-DHAVE_AVX2=FALSE
|
||||
-DHAVE_AVX512F=FALSE
|
||||
-DHAVE_FMA=FALSE
|
||||
-DHAVE_SSE4_1=FALSE
|
||||
-DHAVE_NEON=TRUE
|
||||
)
|
||||
sed -i'.original' 's/HAVE_NEON FALSE/HAVE_NEON TRUE/g' "${tesseract_dir}/CMakeLists.txt"
|
||||
fi
|
||||
|
||||
pushd ${tesseract_dir}
|
||||
log_info "Configure Tesseract ..."
|
||||
cmake -S . -B ${tesseract_build_dir} -G ${generator} ${tesseract_cmake_args}
|
||||
|
||||
log_info "Building Tesseract ..."
|
||||
#cmake --build ${tesseract_build_dir} --config Release --target libtesseract
|
||||
cmake --build ${tesseract_build_dir} --config Release
|
||||
|
||||
log_info "Installing Tesseract..."
|
||||
#cmake --install ${tesseract_build_dir} --config Release --component libtesseract
|
||||
cmake --install ${tesseract_build_dir} --config Release
|
||||
popd
|
||||
;;
|
||||
linux)
|
||||
sed -i'' \
|
||||
@@ -242,7 +318,6 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||
-DOBS_CODESIGN_LINKER=ON
|
||||
-DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}"
|
||||
-DOpenCV_DIR="${opencv_build_dir}"
|
||||
)
|
||||
|
||||
;;
|
||||
|
||||
9
.github/scripts/.package.zsh
vendored
@@ -128,9 +128,18 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
|
||||
local product_name
|
||||
local product_version
|
||||
local git_tag="$(git describe --tags)"
|
||||
|
||||
read -r product_name product_version <<< \
|
||||
"$(jq -r '. | {name, version} | join(" ")' ${project_root}/buildspec.json)"
|
||||
|
||||
if [[ "${git_tag}" =~ '^([0-9]+\.){0,2}(\*|[0-9]+)$' ]] {
|
||||
log_info "Using git tag as version identifier '${git_tag}'"
|
||||
product_version="${git_tag}"
|
||||
} else {
|
||||
log_info "Using buildspec.json version identifier '${product_version}'"
|
||||
}
|
||||
|
||||
if [[ ${host_os} == 'macos' ]] {
|
||||
autoload -Uz check_packages read_codesign read_codesign_installer read_codesign_pass
|
||||
|
||||
|
||||
101
.github/scripts/Build-Windows.ps1
vendored
@@ -37,7 +37,7 @@ function Build {
|
||||
|
||||
$UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
|
||||
|
||||
foreach($Utility in $UtilityFunctions) {
|
||||
foreach ($Utility in $UtilityFunctions) {
|
||||
Write-Debug "Loading $($Utility.FullName)"
|
||||
. $Utility.FullName
|
||||
}
|
||||
@@ -57,18 +57,22 @@ function Build {
|
||||
$CmakeGenerator = $script:VisualStudioVersion
|
||||
}
|
||||
|
||||
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
|
||||
$DepInstallPath = "$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
||||
|
||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
||||
|
||||
Push-Location -Stack BuildOpenCVTemp
|
||||
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
||||
Ensure-Location $ProjectRoot
|
||||
|
||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
||||
$OpenCVCmakeArgs = @(
|
||||
'-G', $CmakeGenerator
|
||||
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
||||
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
||||
"-DCMAKE_BUILD_TYPE=Release"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath}"
|
||||
"-DBUILD_LIST=core,imgproc,objdetect"
|
||||
)
|
||||
|
||||
@@ -80,18 +84,92 @@ function Build {
|
||||
)
|
||||
|
||||
if ( $VerbosePreference -eq 'Continue' ) {
|
||||
$OpenCVCmakeArgs+=('--verbose')
|
||||
$OpenCVCmakeArgs += ('--verbose')
|
||||
}
|
||||
|
||||
Log-Information "Building OpenCV..."
|
||||
Invoke-External cmake --build "${OpenCVBuildPath}" @OpenCVCmakeArgs
|
||||
}
|
||||
Log-Information "Install OpenCV}..."
|
||||
Invoke-External cmake --install "${OpenCVBuildPath}" --prefix "${OpenCVBuildPath}" @OpenCVCmakeArgs
|
||||
Invoke-External cmake --install "${OpenCVBuildPath}" --prefix "${DepInstallPath}" @OpenCVCmakeArgs
|
||||
|
||||
$LeptonicaPath = "${ProjectRoot}/deps/leptonica"
|
||||
$LeptonicaBuildPath = "${LeptonicaPath}/build"
|
||||
|
||||
Push-Location -Stack BuildLeptonicaTemp
|
||||
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
||||
Ensure-Location $ProjectRoot
|
||||
|
||||
$LeptonicaCmakeArgs = @(
|
||||
'-G', $CmakeGenerator
|
||||
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
||||
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
||||
"-DCMAKE_BUILD_TYPE=Release"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath}"
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${DepInstallPath}"
|
||||
"-DSW_BUILD=OFF"
|
||||
"-DLIBWEBP_SUPPORT=OFF"
|
||||
)
|
||||
|
||||
Log-Information "Configuring leptonica..."
|
||||
Invoke-External cmake -S ${LeptonicaPath} -B ${LeptonicaBuildPath} @LeptonicaCmakeArgs
|
||||
|
||||
$LeptonicaCmakeArgs = @(
|
||||
'--config', "Release"
|
||||
)
|
||||
|
||||
if ( $VerbosePreference -eq 'Continue' ) {
|
||||
$LeptonicaCmakeArgs += ('--verbose')
|
||||
}
|
||||
|
||||
Log-Information "Building leptonica..."
|
||||
Invoke-External cmake --build "${LeptonicaBuildPath}" @LeptonicaCmakeArgs
|
||||
}
|
||||
Log-Information "Install leptonica..."
|
||||
Invoke-External cmake --install "${LeptonicaBuildPath}" --prefix "${DepInstallPath}" @LeptonicaCmakeArgs
|
||||
|
||||
Push-Location -Stack BuildTesseractTemp
|
||||
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
||||
Ensure-Location $ProjectRoot
|
||||
|
||||
$TesseractPath = "${ProjectRoot}/deps/tesseract"
|
||||
$TesseractBuildPath = "${TesseractPath}/build"
|
||||
|
||||
# Explicitly disable PkgConfig and tiff as it will lead build errors
|
||||
$TesseractCmakeArgs = @(
|
||||
'-G', $CmakeGenerator
|
||||
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
||||
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
||||
"-DCMAKE_BUILD_TYPE=Release"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath}"
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${DepInstallPath}"
|
||||
"-DSW_BUILD=OFF"
|
||||
"-DDISABLE_CURL=ON"
|
||||
"-DBUILD_TRAINING_TOOLS=OFF"
|
||||
"-DCMAKE_DISABLE_FIND_PACKAGE_TIFF=TRUE"
|
||||
"-DCMAKE_DISABLE_FIND_PACKAGE_PkgConfig=TRUE"
|
||||
)
|
||||
|
||||
Log-Information "Configuring tesseract..."
|
||||
Invoke-External cmake -S ${TesseractPath} -B ${TesseractBuildPath} @TesseractCmakeArgs
|
||||
|
||||
$TesseractCmakeArgs = @(
|
||||
'--config', "Release"
|
||||
)
|
||||
|
||||
if ( $VerbosePreference -eq 'Continue' ) {
|
||||
$TesseractCmakeArgs += ('--verbose')
|
||||
}
|
||||
|
||||
Log-Information "Building tesseract..."
|
||||
Invoke-External cmake --build "${TesseractBuildPath}" @TesseractCmakeArgs
|
||||
}
|
||||
Log-Information "Install tesseract..."
|
||||
Invoke-External cmake --install "${TesseractBuildPath}" --prefix "${DepInstallPath}" @TesseractCmakeArgs
|
||||
|
||||
(Get-Content -Path ${ProjectRoot}/CMakeLists.txt -Raw) `
|
||||
-replace "project\((.*) VERSION (.*)\)", "project(${ProductName} VERSION ${ProductVersion})" `
|
||||
| Out-File -Path ${ProjectRoot}/CMakeLists.txt
|
||||
| Out-File -Path ${ProjectRoot}/CMakeLists.txt
|
||||
|
||||
Setup-Obs
|
||||
|
||||
@@ -99,18 +177,13 @@ function Build {
|
||||
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
||||
Ensure-Location $ProjectRoot
|
||||
|
||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
||||
|
||||
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
|
||||
$CmakeArgs = @(
|
||||
'-G', $CmakeGenerator
|
||||
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
||||
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
||||
"-DCMAKE_BUILD_TYPE=${Configuration}"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath}"
|
||||
"-DQT_VERSION=${script:QtVersion}"
|
||||
"-DOpenCV_DIR=${OpenCVBuildPath}"
|
||||
)
|
||||
|
||||
Log-Debug "Attempting to configure OBS with CMake arguments: $($CmakeArgs | Out-String)"
|
||||
@@ -122,7 +195,7 @@ function Build {
|
||||
)
|
||||
|
||||
if ( $VerbosePreference -eq 'Continue' ) {
|
||||
$CmakeArgs+=('--verbose')
|
||||
$CmakeArgs += ('--verbose')
|
||||
}
|
||||
|
||||
Log-Information "Building ${ProductName}..."
|
||||
|
||||
1
.github/scripts/utils.zsh/setup_linux
vendored
@@ -38,6 +38,7 @@ if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) {
|
||||
libxtst-dev \
|
||||
libxss-dev \
|
||||
libopencv-dev \
|
||||
libtesseract-dev \
|
||||
libprocps-dev
|
||||
|
||||
local -a _qt_packages=()
|
||||
|
||||
45
.github/workflows/main.yml
vendored
@@ -113,7 +113,11 @@ jobs:
|
||||
id: ccache-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ github.workspace }}/.ccache
|
||||
path: |
|
||||
${{ github.workspace }}/.ccache
|
||||
${{ github.workspace }}/plugin/deps/opencv/build_*
|
||||
${{ github.workspace }}/plugin/deps/leptonica/build_*
|
||||
${{ github.workspace }}/plugin/deps/tesseract/build*
|
||||
key: macos-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
||||
restore-keys: |
|
||||
macos-${{ matrix.arch }}-ccache-plugin-
|
||||
@@ -151,6 +155,12 @@ jobs:
|
||||
codesign: 'true'
|
||||
codesignIdent: ${{ env.CODESIGN_IDENT }}
|
||||
|
||||
- name: Run tests
|
||||
uses: ./plugin/.github/actions/run-tests
|
||||
with:
|
||||
workingDirectory: ${{ github.workspace }}/plugin
|
||||
target: ${{ matrix.arch }}
|
||||
|
||||
- name: Package Plugin
|
||||
uses: ./plugin/.github/actions/package-plugin
|
||||
with:
|
||||
@@ -221,7 +231,8 @@ jobs:
|
||||
id: ccache-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ github.workspace }}/.ccache
|
||||
path: |
|
||||
${{ github.workspace }}/.ccache
|
||||
key: linux-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
||||
restore-keys: |
|
||||
linux-${{ matrix.arch }}-ccache-plugin-
|
||||
@@ -245,6 +256,12 @@ jobs:
|
||||
config: RelWithDebInfo
|
||||
portable: ${{ matrix.portable }}
|
||||
|
||||
- name: Run tests
|
||||
uses: ./plugin/.github/actions/run-tests
|
||||
with:
|
||||
workingDirectory: ${{ github.workspace }}/plugin
|
||||
target: ${{ matrix.arch }}
|
||||
|
||||
- name: Package Plugin
|
||||
uses: ./plugin/.github/actions/package-plugin
|
||||
with:
|
||||
@@ -301,9 +318,24 @@ jobs:
|
||||
id: setup
|
||||
run: |
|
||||
## SETUP ENVIRONMENT SCRIPT
|
||||
$CcacheDate = (Get-Date -Format "yyyy-M-d")
|
||||
"ccacheDate=${CcacheDate}" >> $env:GITHUB_OUTPUT
|
||||
$CommitHash = (git rev-parse HEAD)[0..8] -join ''
|
||||
"commitHash=${CommitHash}" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Restore Compilation Cache
|
||||
id: ccache-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
${{ github.workspace }}/.ccache
|
||||
${{ github.workspace }}/plugin/deps/opencv/build_*
|
||||
${{ github.workspace }}/plugin/deps/leptonica/build_*
|
||||
${{ github.workspace }}/plugin/deps/tesseract/build*
|
||||
key: windows-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
||||
restore-keys: |
|
||||
windows-${{ matrix.arch }}-ccache-plugin-
|
||||
|
||||
- name: Check for GitHub Labels
|
||||
id: seekingTesters
|
||||
working-directory: ${{ github.workspace }}/plugin
|
||||
@@ -333,6 +365,12 @@ jobs:
|
||||
config: RelWithDebInfo
|
||||
visualStudio: 'Visual Studio 17 2022'
|
||||
|
||||
- name: Run tests
|
||||
uses: ./plugin/.github/actions/run-tests
|
||||
with:
|
||||
workingDirectory: ${{ github.workspace }}/plugin
|
||||
target: ${{ matrix.arch }}
|
||||
|
||||
- name: Package Plugin
|
||||
uses: ./plugin/.github/actions/package-plugin
|
||||
with:
|
||||
@@ -387,10 +425,11 @@ jobs:
|
||||
for file in ${{ github.workspace }}/**/@(*.pkg|*.exe|*.deb|*.zip); do
|
||||
echo " ${file##*/}: $(sha256sum "${file}" | cut -d " " -f 1)" >> ${{ github.workspace }}/CHECKSUMS.txt
|
||||
done
|
||||
cat ${{ github.workspace }}/CHECKSUMS.txt
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: true
|
||||
prerelease: true
|
||||
|
||||
6
.gitmodules
vendored
@@ -10,3 +10,9 @@
|
||||
[submodule "deps/openvr"]
|
||||
path = deps/openvr
|
||||
url = https://github.com/ValveSoftware/openvr.git
|
||||
[submodule "deps/leptonica"]
|
||||
path = deps/leptonica
|
||||
url = https://github.com/DanBloomberg/leptonica.git
|
||||
[submodule "deps/tesseract"]
|
||||
path = deps/tesseract
|
||||
url = https://github.com/tesseract-ocr/tesseract.git
|
||||
|
||||
@@ -191,6 +191,8 @@ target_sources(
|
||||
src/macro-core/macro-condition-recording.hpp
|
||||
src/macro-core/macro-condition-replay-buffer.cpp
|
||||
src/macro-core/macro-condition-replay-buffer.hpp
|
||||
src/macro-core/macro-condition-run.cpp
|
||||
src/macro-core/macro-condition-run.hpp
|
||||
src/macro-core/macro-condition-scene-order.cpp
|
||||
src/macro-core/macro-condition-scene-order.hpp
|
||||
src/macro-core/macro-condition-scene-transform.cpp
|
||||
@@ -219,6 +221,8 @@ target_sources(
|
||||
src/macro-core/macro-condition-window.hpp
|
||||
src/macro-core/macro-condition.cpp
|
||||
src/macro-core/macro-condition.hpp
|
||||
src/macro-core/macro-dock.cpp
|
||||
src/macro-core/macro-dock.hpp
|
||||
src/macro-core/macro-properties.cpp
|
||||
src/macro-core/macro-properties.hpp
|
||||
src/macro-core/macro-ref.cpp
|
||||
@@ -250,8 +254,15 @@ target_sources(
|
||||
src/utils/file-selection.hpp
|
||||
src/utils/macro-list.cpp
|
||||
src/utils/macro-list.hpp
|
||||
src/utils/math-helpers.cpp
|
||||
src/utils/math-helpers.hpp
|
||||
src/utils/mouse-wheel-guard.cpp
|
||||
src/utils/mouse-wheel-guard.hpp
|
||||
src/utils/name-dialog.cpp
|
||||
src/utils/name-dialog.hpp
|
||||
src/utils/obs-dock.hpp
|
||||
src/utils/process-config.cpp
|
||||
src/utils/process-config.hpp
|
||||
src/utils/regex-config.cpp
|
||||
src/utils/regex-config.hpp
|
||||
src/utils/resizing-text-edit.cpp
|
||||
@@ -268,12 +279,24 @@ target_sources(
|
||||
src/utils/slider-spinbox.hpp
|
||||
src/utils/source-selection.cpp
|
||||
src/utils/source-selection.hpp
|
||||
src/utils/string-list.cpp
|
||||
src/utils/string-list.hpp
|
||||
src/utils/striped-frame.cpp
|
||||
src/utils/striped-frame.hpp
|
||||
src/utils/transition-selection.cpp
|
||||
src/utils/transition-selection.hpp
|
||||
src/utils/utility.cpp
|
||||
src/utils/utility.hpp
|
||||
src/utils/variable.cpp
|
||||
src/utils/variable.hpp
|
||||
src/utils/variable-line-edit.cpp
|
||||
src/utils/variable-line-edit.hpp
|
||||
src/utils/variable-number.tpp
|
||||
src/utils/variable-number.hpp
|
||||
src/utils/variable-spinbox.cpp
|
||||
src/utils/variable-spinbox.hpp
|
||||
src/utils/variable-string.cpp
|
||||
src/utils/variable-string.hpp
|
||||
src/utils/variable-text-edit.cpp
|
||||
src/utils/variable-text-edit.hpp
|
||||
src/utils/volume-control.cpp
|
||||
@@ -320,7 +343,8 @@ target_include_directories(
|
||||
${LIB_NAME}
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib")
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/exprtk")
|
||||
|
||||
# --- End of section ---
|
||||
|
||||
@@ -331,7 +355,8 @@ if(OS_WINDOWS)
|
||||
|
||||
target_compile_definitions(${LIB_NAME} PRIVATE UNICODE _UNICODE)
|
||||
if(MSVC)
|
||||
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267)
|
||||
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267
|
||||
/bigobj)
|
||||
endif()
|
||||
target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp)
|
||||
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
||||
@@ -448,3 +473,4 @@ endif()
|
||||
# --- End of section ---
|
||||
|
||||
add_subdirectory(src/macro-external)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@@ -25,7 +25,7 @@ DirExistsWarning=no
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Files]
|
||||
Source: "..\release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "..\release\*"; Excludes: "*.zip"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "..\LICENSE"; Flags: dontcopy
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
|
||||
@@ -506,7 +506,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Linke Meta-Taste"
|
||||
AdvSceneSwitcher.action.hotkey.rightMeta="Rechte Meta-Taste"
|
||||
AdvSceneSwitcher.action.hotkey.onlyOBS="Tastendruck nur an OBS senden"
|
||||
AdvSceneSwitcher.action.hotkey.disabled="Globale Tastendrücke können nicht simuliert werden - die Funktionalität beschränkt sich auf das Senden von Tastendrücken an OBS!"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Drücke {{keys}} für {{duration}} Millisekunden"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Drücke {{keys}} für {{duration}}"
|
||||
AdvSceneSwitcher.action.sceneOrder="Reihenfolge der Szenenelemente"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Nach oben verschieben"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Nach unten verschieben"
|
||||
@@ -587,7 +587,7 @@ AdvSceneSwitcher.action.variable.invalidSelection="Ungültige Auswahl!"
|
||||
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Das Abrufen von Variablenwerten aus %1 Aktionen wird nicht unterstützt!"
|
||||
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Das Abrufen von Variablenwerten aus %1 Bedingungen wird nicht unterstützt!"
|
||||
AdvSceneSwitcher.action.variable.currentSegmentValue="Aktueller Wert:"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
|
||||
|
||||
|
||||
; Transition Tab
|
||||
|
||||
@@ -30,6 +30,8 @@ AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Enable verbose loggi
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Save window position and size"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="Show system tray notifications"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="Display warning if plugins cannot be loaded"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
|
||||
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
|
||||
AdvSceneSwitcher.generalTab.priority="Priority"
|
||||
@@ -82,20 +84,33 @@ AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||
AdvSceneSwitcher.macroTab.defaultGroupName="Group %1"
|
||||
AdvSceneSwitcher.macroTab.exists="Macro name exists already"
|
||||
AdvSceneSwitcher.macroTab.groupDeleteConfirm="Are you sure you want to delete \"%1\" and all its elements?"
|
||||
AdvSceneSwitcher.macroTab.copy="Create copy of current macro"
|
||||
AdvSceneSwitcher.macroTab.group="Group selected items"
|
||||
AdvSceneSwitcher.macroTab.ungroup="Ungroup selected groups"
|
||||
AdvSceneSwitcher.macroTab.deleteMultipleMacrosConfirmation="Are you sure you want to delete %1 macros?"
|
||||
AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation="Are you sure you want to delete \"%1\"?"
|
||||
AdvSceneSwitcher.macroTab.contextMenuAdd="Add"
|
||||
AdvSceneSwitcher.macroTab.copy="Duplicate Macro"
|
||||
AdvSceneSwitcher.macroTab.group="Group Selected Macros"
|
||||
AdvSceneSwitcher.macroTab.ungroup="Ungroup Selected Groups"
|
||||
AdvSceneSwitcher.macroTab.rename="Rename"
|
||||
AdvSceneSwitcher.macroTab.remove="Remove"
|
||||
AdvSceneSwitcher.macroTab.expandAll="Expand all"
|
||||
AdvSceneSwitcher.macroTab.collapseAll="Collapse all"
|
||||
AdvSceneSwitcher.macroTab.maximize="Maximize"
|
||||
AdvSceneSwitcher.macroTab.minimize="Minimize"
|
||||
AdvSceneSwitcher.macroTab.highlightSettings="Visual settings"
|
||||
AdvSceneSwitcher.macroTab.hotkeySettings="Hotkey settings"
|
||||
AdvSceneSwitcher.macroTab.dockSettings="Dock settings"
|
||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros"
|
||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently"
|
||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="Highlight recently performed actions of currently selected macro"
|
||||
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="Register hotkeys to control the pause state of new macros"
|
||||
AdvSceneSwitcher.macroTab.currentDisableHotkeys="Register hotkeys to control the pause state of selected macro"
|
||||
AdvSceneSwitcher.macroTab.currentRegisterDock="Register dock widget to control the pause state of selected macro or run it manually"
|
||||
AdvSceneSwitcher.macroTab.currentDockAddRunButton="Add button to run the macro"
|
||||
AdvSceneSwitcher.macroTab.currentDockAddPauseButton="Add button to pause or unpause the macro"
|
||||
|
||||
AdvSceneSwitcher.macroDock.pause="Pause"
|
||||
AdvSceneSwitcher.macroDock.unpause="Unpause"
|
||||
AdvSceneSwitcher.macroDock.run="Run"
|
||||
|
||||
; Macro List
|
||||
AdvSceneSwitcher.macroList.deleted="deleted"
|
||||
@@ -174,6 +189,7 @@ AdvSceneSwitcher.condition.video.condition.noImage="has no output"
|
||||
AdvSceneSwitcher.condition.video.condition.pattern="matches pattern"
|
||||
AdvSceneSwitcher.condition.video.condition.object="contains object"
|
||||
AdvSceneSwitcher.condition.video.condition.brightness="brightness"
|
||||
AdvSceneSwitcher.condition.video.condition.ocr="contains text"
|
||||
AdvSceneSwitcher.condition.video.askFileAction="Do you want to use an existing file or create a screenshot of the currently selected source?"
|
||||
AdvSceneSwitcher.condition.video.askFileAction.file="Use existing file"
|
||||
AdvSceneSwitcher.condition.video.askFileAction.screenshot="Create screenshot"
|
||||
@@ -184,6 +200,11 @@ AdvSceneSwitcher.condition.video.usePatternForChangedCheck.tooltip="This will al
|
||||
AdvSceneSwitcher.condition.video.patternThreshold="Threshold: "
|
||||
AdvSceneSwitcher.condition.video.patternThresholdDescription="A higher threshold value means that the pattern needs to match the video source more closely."
|
||||
AdvSceneSwitcher.condition.video.patternThresholdUseAlphaAsMask="Use alpha channel as mask for pattern."
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode="Use pattern matching mode {{patternMatchingModes}}"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.crossCorrelation="Cross correlation"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.correlationCoefficient="Correlation coefficient"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.squaredDifference="Squared difference"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.tip="The best method to use depends on the specific problem and the characteristics of the images involved.\nIn practice, it's often necessary to experiment with different methods and parameters to find the best match for a particular use case."
|
||||
AdvSceneSwitcher.condition.video.brightnessThreshold="Average brightness is above:"
|
||||
AdvSceneSwitcher.condition.video.brightnessThresholdDescription="A high value is indicating a bright image and a low one a darker one."
|
||||
AdvSceneSwitcher.condition.video.currentBrightness="Current average brightness: %1"
|
||||
@@ -198,7 +219,18 @@ AdvSceneSwitcher.condition.video.patternMatchFail="Pattern was not found!"
|
||||
AdvSceneSwitcher.condition.video.patternMatchSuccess="Pattern is highlighted in red"
|
||||
AdvSceneSwitcher.condition.video.objectMatchFail="Object was not found!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red"
|
||||
AdvSceneSwitcher.condition.video.ocrMatchSuccess="Detected text:\n\n%1"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="Model data could not be loaded!"
|
||||
AdvSceneSwitcher.condition.video.selectColor="Select Color"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleColumn="Single column of text of variable sizes"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleBlockVertText="Single uniform block of vertically aligned text"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleBlock="Single uniform block of text"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleLine="Single text line"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleWord="Single word"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.circleWord="Single word in a circle"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleChar="Single character"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.sparseText="Find text in no particular order"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.sparseTextOSD="Find text in no particular order (OSD)"
|
||||
AdvSceneSwitcher.condition.video.type.main="OBS's main output"
|
||||
AdvSceneSwitcher.condition.video.type.source="Source"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Scene"
|
||||
@@ -208,6 +240,8 @@ AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum neighbors: {{minNeig
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduce CPU load by performing check only every {{throttleCount}} milliseconds"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Perform check only in area"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="Check for text color:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="Check for text type:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Minimum size:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Maximum size:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Select area"
|
||||
@@ -393,6 +427,9 @@ AdvSceneSwitcher.condition.variable.type.equalsVariable="equals variable"
|
||||
AdvSceneSwitcher.condition.variable.type.lessThanVariable="is less than variable"
|
||||
AdvSceneSwitcher.condition.variable.type.greaterThanVariable="is greater than variable"
|
||||
AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}"
|
||||
AdvSceneSwitcher.condition.run="Run"
|
||||
AdvSceneSwitcher.condition.run.entry="Process exits before timeout of{{timeout}} seconds"
|
||||
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}Check for exit code{{exitCode}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.switchScene="Switch scene"
|
||||
@@ -440,11 +477,6 @@ AdvSceneSwitcher.action.streaming.type.stop="Stop streaming"
|
||||
AdvSceneSwitcher.action.streaming.type.start="Start streaming"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.run="Run"
|
||||
AdvSceneSwitcher.action.run.arguments="Arguments:"
|
||||
AdvSceneSwitcher.action.run.addArgument="Add argument"
|
||||
AdvSceneSwitcher.action.run.addArgumentDescription="Add new argument:"
|
||||
AdvSceneSwitcher.action.run.entry="Run {{filePath}}"
|
||||
AdvSceneSwitcher.action.run.entry.workingDirectory="Working directory:{{workingDirectory}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility="Scene item visibility"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Show"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
|
||||
@@ -506,7 +538,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Left Meta"
|
||||
AdvSceneSwitcher.action.hotkey.rightMeta="Right Meta"
|
||||
AdvSceneSwitcher.action.hotkey.onlyOBS="Send keypress only to OBS"
|
||||
AdvSceneSwitcher.action.hotkey.disabled="Cannot simulate global key presses - functionality limited to sending key press to OBS!"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Press {{keys}} for {{duration}} milliseconds"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Press {{keys}} for {{duration}}"
|
||||
AdvSceneSwitcher.action.sceneOrder="Scene item order"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Move up"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down"
|
||||
@@ -571,6 +603,9 @@ AdvSceneSwitcher.action.websocket.type.event="Event"
|
||||
AdvSceneSwitcher.action.websocket.entry.request="Send scene switcher {{type}} via {{connection}}"
|
||||
AdvSceneSwitcher.action.websocket.entry.event="Send scene switcher {{type}} to connected clients"
|
||||
AdvSceneSwitcher.action.http="Http"
|
||||
AdvSceneSwitcher.action.http.setHeaders="Set headers"
|
||||
AdvSceneSwitcher.action.http.headers="Headers:"
|
||||
AdvSceneSwitcher.action.http.addHeader="Add header"
|
||||
AdvSceneSwitcher.action.http.type.get="GET"
|
||||
AdvSceneSwitcher.action.http.type.post="POST"
|
||||
AdvSceneSwitcher.action.http.entry.line1="Send {{method}} to {{url}}"
|
||||
@@ -585,15 +620,21 @@ AdvSceneSwitcher.action.variable.type.setActionValue="Set to action value"
|
||||
AdvSceneSwitcher.action.variable.type.setConditionValue="Set to condition value"
|
||||
AdvSceneSwitcher.action.variable.type.roundToInt="Round to nearest integer"
|
||||
AdvSceneSwitcher.action.variable.type.subString="Set to substring of current value"
|
||||
AdvSceneSwitcher.action.variable.type.findAndReplace="Find and replace in current value"
|
||||
AdvSceneSwitcher.action.variable.type.mathExpression="Mathematical expression"
|
||||
AdvSceneSwitcher.action.variable.mathExpression.example="( 1 + 2 * 3 ) / 4"
|
||||
AdvSceneSwitcher.action.variable.findAndReplace.find="Text to find"
|
||||
AdvSceneSwitcher.action.variable.findAndReplace.replace="Text to replace with"
|
||||
AdvSceneSwitcher.action.variable.subString.begin="Beginning"
|
||||
AdvSceneSwitcher.action.variable.subString.all="All"
|
||||
AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!"
|
||||
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!"
|
||||
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!"
|
||||
AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
|
||||
AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}} Substring size:{{subStringSize}}"
|
||||
AdvSceneSwitcher.action.variable.entry.substringRegex="Assign value of{{regexMatchIdx}}match using regular expression:"
|
||||
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{replaceStr}}"
|
||||
AdvSceneSwitcher.action.projector="Projector"
|
||||
AdvSceneSwitcher.action.projector.type.source="Source"
|
||||
AdvSceneSwitcher.action.projector.type.scene="Scene"
|
||||
@@ -898,6 +939,15 @@ AdvSceneSwitcher.regex.dotMatchNewline=". matches newlines"
|
||||
AdvSceneSwitcher.regex.multiLine="^ and $ match start/end of line"
|
||||
AdvSceneSwitcher.regex.extendedPattern="Enable Qt's ExtendedPatternSyntax"
|
||||
|
||||
AdvSceneSwitcher.process.showAdvanced="Show advanced settings"
|
||||
AdvSceneSwitcher.process.arguments="Arguments:"
|
||||
AdvSceneSwitcher.process.addArgument="Add argument"
|
||||
AdvSceneSwitcher.process.addArgumentDescription="Add new argument:"
|
||||
AdvSceneSwitcher.process.entry="Run{{filePath}}{{advancedSettings}}"
|
||||
AdvSceneSwitcher.process.entry.workingDirectory="Working directory:{{workingDirectory}}"
|
||||
|
||||
AdvSceneSwitcher.math.expressionFail="Failed evaluate expression"
|
||||
|
||||
AdvSceneSwitcher.selectScene="--select scene--"
|
||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||
|
||||
@@ -422,7 +422,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Meta izquierda"
|
||||
AdvSceneSwitcher.action.hotkey.rightMeta="Meta derecho"
|
||||
AdvSceneSwitcher.action.hotkey.onlyOBS="Enviar pulsación de tecla solo a OBS"
|
||||
AdvSceneSwitcher.action.hotkey.disabled="No se puede simular la pulsación de teclas: ¡funcionalidad desactivada!"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Presione {{keys}} durante {{duration}} milisegundos"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Presione {{keys}} durante {{duration}}"
|
||||
AdvSceneSwitcher.action.sceneOrder="Orden de elementos de escena"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Mover hacia arriba"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover hacia abajo"
|
||||
|
||||
@@ -350,7 +350,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Sol Meta"
|
||||
AdvSceneSwitcher.action.hotkey.rightMeta="Sağ Meta"
|
||||
AdvSceneSwitcher.action.hotkey.onlyOBS="Tuşa basımı yalnızca OBS'ye gönder"
|
||||
AdvSceneSwitcher.action.hotkey.disabled="Tuşa basma simülasyonu yapılamıyor - işlevsellik devre dışı!"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Bas {{keys}} uygun {{duration}} millisaniye"
|
||||
AdvSceneSwitcher.action.hotkey.entry="Bas {{keys}} uygun {{duration}}"
|
||||
AdvSceneSwitcher.action.sceneOrder="Sahne öğesi sırası"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Yukarı taşı"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Aşağı indir"
|
||||
|
||||
@@ -467,7 +467,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="左 Meta"
|
||||
AdvSceneSwitcher.action.hotkey.rightMeta="右 Meta"
|
||||
AdvSceneSwitcher.action.hotkey.onlyOBS="仅向OBS发送按键"
|
||||
AdvSceneSwitcher.action.hotkey.disabled="无法模拟按键-功能已禁用!"
|
||||
AdvSceneSwitcher.action.hotkey.entry="按下 {{keys}} for {{duration}} 毫秒"
|
||||
AdvSceneSwitcher.action.hotkey.entry="按下 {{keys}} for {{duration}}"
|
||||
AdvSceneSwitcher.action.sceneOrder="场景项目顺序"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="上移"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移"
|
||||
@@ -541,7 +541,7 @@ AdvSceneSwitcher.action.variable.type.append="追加"
|
||||
AdvSceneSwitcher.action.variable.type.appendVar="追加变量"
|
||||
AdvSceneSwitcher.action.variable.type.increment="增加"
|
||||
AdvSceneSwitcher.action.variable.type.decrement="减少"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
|
||||
|
||||
|
||||
; Transition Tab
|
||||
|
||||
4
data/res/images/DarkAdvanced.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 13.855469 0 l -1.539063 1.4375 c -0.453125 0.421875 -0.53125 1.148438 -0.269531 1.707031 l -5.886719 5.996094 c -0.011718 0 -0.019531 0 -0.03125 0 c -0.257812 -0.128906 -0.550781 -0.183594 -0.839844 -0.148437 c -0.328124 0.046874 -0.632812 0.199218 -0.867187 0.441406 l -3.945313 3.996094 c -0.3906245 0.375 -0.5468745 0.933593 -0.4062495 1.457031 c 0.1406255 0.523437 0.5546875 0.929687 1.0820315 1.058593 c 0.527344 0.132813 1.082031 -0.03125 1.453125 -0.425781 l 3.945312 -3.996093 c 0.472657 -0.453126 0.59375 -1.15625 0.296875 -1.738282 l 5.890625 -5.964844 c 0.558594 0.25 1.273438 0.148438 1.707031 -0.289062 l 1.414063 -1.5625 z m -10.308594 0.0898438 c -0.398437 0 -0.785156 0.0937502 -1.140625 0.2187502 l 1.882812 1.878906 c 0.390626 0.382812 0.390626 1 0 1.386719 l -0.710937 0.707031 c -0.386719 0.386719 -1 0.386719 -1.390625 0 l -1.882812 -1.878906 c -0.125 0.355468 -0.2187505 0.742187 -0.2187505 1.140625 c 0 1.90625 1.5507815 3.453125 3.4609375 3.453125 c 0.402344 0 0.789063 -0.09375 1.144531 -0.21875 l 1.175782 1.171875 h 0.058593 l 2.070313 -2.0625 l -1.203125 -1.203125 c 0.125 -0.359375 0.214843 -0.742188 0.214843 -1.140625 c 0 -1.90625 -1.546874 -3.4531252 -3.460937 -3.4531252 z m 6.550781 7.8906252 l -2.070312 2.066406 c 0.011718 0.027344 0.023437 0.058594 0.03125 0.089844 l 1.144531 1.140625 c -0.125 0.355468 -0.21875 0.742187 -0.21875 1.140625 c 0 1.902343 1.550781 3.449219 3.460937 3.449219 c 0.433594 0 0.855469 -0.101563 1.238282 -0.246094 l -2.007813 -2 c -0.386719 -0.386719 -0.386719 -1.035156 0 -1.417969 l 0.679688 -0.679687 c 0.195312 -0.191407 0.457031 -0.308594 0.710937 -0.308594 s 0.515625 0.117187 0.710938 0.308594 l 1.945312 1.941406 c 0.105469 -0.328125 0.183594 -0.683594 0.183594 -1.046875 c 0 -1.90625 -1.546875 -3.453125 -3.460938 -3.453125 c -0.398437 0 -0.785156 0.09375 -1.140624 0.21875 z m 0 0" fill="#fefefe"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
7
data/res/images/DarkGroup.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#fefefe">
|
||||
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8.882812 c 0.832032 0 1.578126 -0.402344 2.054688 -0.9375 c 0.472656 -0.53125 0.738281 -1.167969 0.910156 -1.800781 l 0.972656 -2.609375 c 0.390626 -1.449219 -0.09375 -2.652344 -0.820312 -3.167969 c -0.484375 -0.34375 -0.714844 -0.292969 -1 -0.324219 v -1.160156 c 0 -0.855469 -0.558594 -1.589844 -1.09375 -1.828125 c -0.53125 -0.238281 -1.011719 -0.167969 -1.011719 -0.167969 l 0.105469 -0.003906 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 2.585938 l 1.707031 1.707031 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 h 4 c 0.035156 0 0.070312 -0.003906 0.105469 -0.007812 c 0 0 0.019531 0.019531 -0.011719 0.003906 c -0.035156 -0.011719 -0.09375 -0.25 -0.09375 0.003906 v 2 c 0 0.550781 0.449219 1 1 1 c 1 0 1.046875 0.703125 0.886719 1.128906 l -0.972657 2.609375 c -0.117187 0.4375 -0.296874 0.800781 -0.472656 0.996094 c -0.175781 0.199219 -0.285156 0.265625 -0.558594 0.265625 h -8.882812 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.46875 -0.792969 1 -1 z m 0 0"/>
|
||||
<path d="m 7 6 l 0.042969 0.003906 c -0.914063 -0.042968 -1.75 0.390625 -2.195313 0.96875 c -0.710937 1.222656 -1.15625 2.277344 -1.800781 3.71875 c -0.171875 0.523438 0.117187 1.089844 0.640625 1.261719 c 0.527344 0.171875 1.09375 -0.117187 1.261719 -0.640625 c 0.488281 -1.011719 0.921875 -1.816406 1.339843 -2.808594 c 0.210938 -0.503906 0.703126 -0.492187 0.898438 -0.503906 h 5.8125 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1,3 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#d2d2d2" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g></g></g></svg>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#fefefe" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#fefefe" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#fefefe" fill-opacity="1"></use></g></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
4
data/res/images/LightAdvanced.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m 13.855469 0 l -1.539063 1.4375 c -0.453125 0.421875 -0.53125 1.148438 -0.269531 1.707031 l -5.886719 5.996094 c -0.011718 0 -0.019531 0 -0.03125 0 c -0.257812 -0.128906 -0.550781 -0.183594 -0.839844 -0.148437 c -0.328124 0.046874 -0.632812 0.199218 -0.867187 0.441406 l -3.945313 3.996094 c -0.3906245 0.375 -0.5468745 0.933593 -0.4062495 1.457031 c 0.1406255 0.523437 0.5546875 0.929687 1.0820315 1.058593 c 0.527344 0.132813 1.082031 -0.03125 1.453125 -0.425781 l 3.945312 -3.996093 c 0.472657 -0.453126 0.59375 -1.15625 0.296875 -1.738282 l 5.890625 -5.964844 c 0.558594 0.25 1.273438 0.148438 1.707031 -0.289062 l 1.414063 -1.5625 z m -10.308594 0.0898438 c -0.398437 0 -0.785156 0.0937502 -1.140625 0.2187502 l 1.882812 1.878906 c 0.390626 0.382812 0.390626 1 0 1.386719 l -0.710937 0.707031 c -0.386719 0.386719 -1 0.386719 -1.390625 0 l -1.882812 -1.878906 c -0.125 0.355468 -0.2187505 0.742187 -0.2187505 1.140625 c 0 1.90625 1.5507815 3.453125 3.4609375 3.453125 c 0.402344 0 0.789063 -0.09375 1.144531 -0.21875 l 1.175782 1.171875 h 0.058593 l 2.070313 -2.0625 l -1.203125 -1.203125 c 0.125 -0.359375 0.214843 -0.742188 0.214843 -1.140625 c 0 -1.90625 -1.546874 -3.4531252 -3.460937 -3.4531252 z m 6.550781 7.8906252 l -2.070312 2.066406 c 0.011718 0.027344 0.023437 0.058594 0.03125 0.089844 l 1.144531 1.140625 c -0.125 0.355468 -0.21875 0.742187 -0.21875 1.140625 c 0 1.902343 1.550781 3.449219 3.460937 3.449219 c 0.433594 0 0.855469 -0.101563 1.238282 -0.246094 l -2.007813 -2 c -0.386719 -0.386719 -0.386719 -1.035156 0 -1.417969 l 0.679688 -0.679687 c 0.195312 -0.191407 0.457031 -0.308594 0.710937 -0.308594 s 0.515625 0.117187 0.710938 0.308594 l 1.945312 1.941406 c 0.105469 -0.328125 0.183594 -0.683594 0.183594 -1.046875 c 0 -1.90625 -1.546875 -3.453125 -3.460938 -3.453125 c -0.398437 0 -0.785156 0.09375 -1.140624 0.21875 z m 0 0" fill="#202020"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
7
data/res/images/LightGroup.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#202020">
|
||||
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8.882812 c 0.832032 0 1.578126 -0.402344 2.054688 -0.9375 c 0.472656 -0.53125 0.738281 -1.167969 0.910156 -1.800781 l 0.972656 -2.609375 c 0.390626 -1.449219 -0.09375 -2.652344 -0.820312 -3.167969 c -0.484375 -0.34375 -0.714844 -0.292969 -1 -0.324219 v -1.160156 c 0 -0.855469 -0.558594 -1.589844 -1.09375 -1.828125 c -0.53125 -0.238281 -1.011719 -0.167969 -1.011719 -0.167969 l 0.105469 -0.003906 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 2.585938 l 1.707031 1.707031 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 h 4 c 0.035156 0 0.070312 -0.003906 0.105469 -0.007812 c 0 0 0.019531 0.019531 -0.011719 0.003906 c -0.035156 -0.011719 -0.09375 -0.25 -0.09375 0.003906 v 2 c 0 0.550781 0.449219 1 1 1 c 1 0 1.046875 0.703125 0.886719 1.128906 l -0.972657 2.609375 c -0.117187 0.4375 -0.296874 0.800781 -0.472656 0.996094 c -0.175781 0.199219 -0.285156 0.265625 -0.558594 0.265625 h -8.882812 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.46875 -0.792969 1 -1 z m 0 0"/>
|
||||
<path d="m 7 6 l 0.042969 0.003906 c -0.914063 -0.042968 -1.75 0.390625 -2.195313 0.96875 c -0.710937 1.222656 -1.15625 2.277344 -1.800781 3.71875 c -0.171875 0.523438 0.117187 1.089844 0.640625 1.261719 c 0.527344 0.171875 1.09375 -0.117187 1.261719 -0.640625 c 0.488281 -1.011719 0.921875 -1.816406 1.339843 -2.808594 c 0.210938 -0.503906 0.703126 -0.492187 0.898438 -0.503906 h 5.8125 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
2
data/res/images/LightTime.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#202020" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#202020" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#202020" fill-opacity="1"></use></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
BIN
data/res/ocr/eng.traineddata
Normal file
41032
deps/exprtk/exprtk.hpp
vendored
Normal file
1
deps/leptonica
vendored
Submodule
1
deps/tesseract
vendored
Submodule
@@ -256,6 +256,30 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="warnPluginLoadFailure">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_19">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_24">
|
||||
<item>
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
const char *obs_module_text(const char *text)
|
||||
{
|
||||
if (!switcher) {
|
||||
return "";
|
||||
}
|
||||
return switcher->translate(text);
|
||||
}
|
||||
|
||||
@@ -40,9 +43,7 @@ AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent)
|
||||
{
|
||||
switcher->settingsWindowOpened = true;
|
||||
ui->setupUi(this);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
switcher->Prune();
|
||||
loadUI();
|
||||
}
|
||||
@@ -55,26 +56,51 @@ AdvSceneSwitcher::~AdvSceneSwitcher()
|
||||
}
|
||||
}
|
||||
|
||||
bool translationAvailable()
|
||||
static bool translationAvailable()
|
||||
{
|
||||
return !!strcmp(obs_module_text("AdvSceneSwitcher.pluginName"),
|
||||
"AdvSceneSwitcher.pluginName");
|
||||
}
|
||||
|
||||
static void DisplayMissingDependencyWarning()
|
||||
{
|
||||
if (!switcher->warnPluginLoadFailure ||
|
||||
switcher->loadFailureLibs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString failedLibsString = "<ul>";
|
||||
for (const auto &lib : switcher->loadFailureLibs) {
|
||||
failedLibsString += "<li>" + lib + "</li>";
|
||||
}
|
||||
failedLibsString += "</ul>";
|
||||
QString warning(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage"));
|
||||
DisplayMessage(warning.arg(failedLibsString));
|
||||
}
|
||||
|
||||
static void DisplayMissingDataDirWarning()
|
||||
{
|
||||
if (translationAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString msg = "Failed to find plug-in's 'data' directory.\n"
|
||||
"Please check installation instructions!\n\n"
|
||||
"Data most likely expected at:\n\n";
|
||||
#ifdef _WIN32
|
||||
msg += QString::fromStdString(
|
||||
(std::filesystem::current_path().string()));
|
||||
msg += "/";
|
||||
#endif
|
||||
msg += obs_get_module_data_path(obs_current_module());
|
||||
DisplayMessage(msg);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::loadUI()
|
||||
{
|
||||
if (!translationAvailable()) {
|
||||
QString msg = "Failed to find plug-in's 'data' directory.\n"
|
||||
"Please check installation instructions!\n\n"
|
||||
"Data most likely expected at:\n\n";
|
||||
#ifdef _WIN32
|
||||
msg += QString::fromStdString(
|
||||
(std::filesystem::current_path().string()));
|
||||
msg += "/";
|
||||
#endif
|
||||
msg += obs_get_module_data_path(obs_current_module());
|
||||
(void)DisplayMessage(msg);
|
||||
}
|
||||
DisplayMissingDataDirWarning();
|
||||
DisplayMissingDependencyWarning();
|
||||
|
||||
setupGeneralTab();
|
||||
setupTitleTab();
|
||||
@@ -684,6 +710,7 @@ void LoadPlugins()
|
||||
blog(LOG_WARNING, "failed to load \"%s\": %s",
|
||||
file.toStdString().c_str(),
|
||||
lib->errorString().toStdString().c_str());
|
||||
switcher->loadFailureLibs << file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,10 @@ public:
|
||||
|
||||
bool addNewMacro(std::shared_ptr<Macro> &res, std::string &name,
|
||||
std::string format = "");
|
||||
void RemoveMacro(std::shared_ptr<Macro> &);
|
||||
void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
|
||||
std::shared_ptr<Macro> getSelectedMacro();
|
||||
std::vector<std::shared_ptr<Macro>> getSelectedMacros();
|
||||
void SetEditMacro(Macro &m);
|
||||
void SetMacroEditAreaDisabled(bool);
|
||||
void HighlightAction(int idx, QColor color = QColor(Qt::green));
|
||||
@@ -109,10 +112,8 @@ public slots:
|
||||
void on_noMatchDontSwitch_clicked();
|
||||
void on_noMatchSwitch_clicked();
|
||||
void on_noMatchRandomSwitch_clicked();
|
||||
void NoMatchDelayDurationChanged(double);
|
||||
void NoMatchDelayUnitChanged(DurationUnit);
|
||||
void CooldownDurationChanged(double);
|
||||
void CooldownUnitChanged(DurationUnit);
|
||||
void NoMatchDelayDurationChanged(const Duration &);
|
||||
void CooldownDurationChanged(const Duration &);
|
||||
void on_startupBehavior_currentIndexChanged(int index);
|
||||
void on_autoStartEvent_currentIndexChanged(int index);
|
||||
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
|
||||
@@ -145,6 +146,7 @@ public slots:
|
||||
void ShowMacroActionsContextMenu(const QPoint &);
|
||||
void ShowMacroConditionsContextMenu(const QPoint &);
|
||||
void CopyMacro();
|
||||
void RenameCurrentMacro();
|
||||
void ExpandAllActions();
|
||||
void ExpandAllConditions();
|
||||
void CollapseAllActions();
|
||||
@@ -200,6 +202,7 @@ public slots:
|
||||
void on_saveWindowGeo_stateChanged(int state);
|
||||
void on_showTrayNotifications_stateChanged(int state);
|
||||
void on_uiHintsDisable_stateChanged(int state);
|
||||
void on_warnPluginLoadFailure_stateChanged(int state);
|
||||
void on_hideLegacyTabs_stateChanged(int state);
|
||||
|
||||
void on_exportSettings_clicked();
|
||||
|
||||
@@ -60,44 +60,24 @@ void AdvSceneSwitcher::on_noMatchRandomSwitch_clicked()
|
||||
ui->randomDisabledWarning->setVisible(false);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::NoMatchDelayDurationChanged(double sec)
|
||||
void AdvSceneSwitcher::NoMatchDelayDurationChanged(const Duration &dur)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->noMatchDelay.seconds = sec;
|
||||
switcher->noMatchDelay = dur;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::NoMatchDelayUnitChanged(DurationUnit unit)
|
||||
void AdvSceneSwitcher::CooldownDurationChanged(const Duration &dur)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->noMatchDelay.displayUnit = unit;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::CooldownDurationChanged(double sec)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->cooldown.seconds = sec;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::CooldownUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->cooldown.displayUnit = unit;
|
||||
switcher->cooldown = dur;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
||||
@@ -192,6 +172,15 @@ void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
|
||||
switcher->disableHints = state;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
switcher->warnPluginLoadFailure = state;
|
||||
}
|
||||
|
||||
bool isLegacyTab(const QString &name)
|
||||
{
|
||||
return name == obs_module_text(
|
||||
@@ -558,8 +547,8 @@ void SwitcherData::loadSettings(obs_data_t *obj)
|
||||
// selections to be available.
|
||||
loadSceneGroups(obj);
|
||||
loadVariables(obj);
|
||||
loadMacros(obj);
|
||||
loadConnections(obj);
|
||||
loadMacros(obj);
|
||||
loadWindowTitleSwitches(obj);
|
||||
loadScreenRegionSwitches(obj);
|
||||
loadPauseSwitches(obj);
|
||||
@@ -622,9 +611,9 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
||||
obs_data_set_string(obj, "non_matching_scene",
|
||||
nonMatchingSceneName.c_str());
|
||||
obs_data_set_int(obj, "switch_if_not_matching", switchIfNotMatching);
|
||||
noMatchDelay.Save(obj, "noMatchDelay", "noMatchDelayUnit");
|
||||
noMatchDelay.Save(obj, "noMatchDelay");
|
||||
|
||||
cooldown.Save(obj, "cooldown", "cooldownUnit");
|
||||
cooldown.Save(obj, "cooldown");
|
||||
|
||||
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
|
||||
sceneColletionStop = false;
|
||||
@@ -637,6 +626,7 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
||||
obs_data_set_bool(obj, "showSystemTrayNotifications",
|
||||
showSystemTrayNotifications);
|
||||
obs_data_set_bool(obj, "disableHints", disableHints);
|
||||
obs_data_set_bool(obj, "warnPluginLoadFailure", warnPluginLoadFailure);
|
||||
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
||||
|
||||
obs_data_set_int(obj, "priority0", functionNamesByPriority[0]);
|
||||
@@ -672,9 +662,9 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
std::string nonMatchingSceneName =
|
||||
obs_data_get_string(obj, "non_matching_scene");
|
||||
nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str());
|
||||
noMatchDelay.Load(obj, "noMatchDelay", "noMatchDelayUnit");
|
||||
noMatchDelay.Load(obj, "noMatchDelay");
|
||||
|
||||
cooldown.Load(obj, "cooldown", "cooldownUnit");
|
||||
cooldown.Load(obj, "cooldown");
|
||||
|
||||
stop = !obs_data_get_bool(obj, "active");
|
||||
startupBehavior =
|
||||
@@ -693,6 +683,8 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
showSystemTrayNotifications =
|
||||
obs_data_get_bool(obj, "showSystemTrayNotifications");
|
||||
disableHints = obs_data_get_bool(obj, "disableHints");
|
||||
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
|
||||
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
|
||||
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
||||
hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs");
|
||||
|
||||
@@ -970,10 +962,9 @@ void AdvSceneSwitcher::setupGeneralTab()
|
||||
noMatchDelay->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip"));
|
||||
ui->noMatchLayout->addWidget(noMatchDelay);
|
||||
QWidget::connect(noMatchDelay, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(NoMatchDelayDurationChanged(double)));
|
||||
QWidget::connect(noMatchDelay, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(NoMatchDelayUnitChanged(DurationUnit)));
|
||||
QWidget::connect(noMatchDelay,
|
||||
SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(NoMatchDelayDurationChanged(const Duration &)));
|
||||
|
||||
ui->checkInterval->setValue(switcher->interval);
|
||||
|
||||
@@ -983,16 +974,16 @@ void AdvSceneSwitcher::setupGeneralTab()
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
|
||||
ui->cooldownLayout->addWidget(cooldownTime);
|
||||
ui->cooldownLayout->addStretch();
|
||||
QWidget::connect(cooldownTime, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(CooldownDurationChanged(double)));
|
||||
QWidget::connect(cooldownTime, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(CooldownUnitChanged(DurationUnit)));
|
||||
QWidget::connect(cooldownTime,
|
||||
SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(CooldownDurationChanged(const Duration &)));
|
||||
|
||||
ui->verboseLogging->setChecked(switcher->verbose);
|
||||
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
|
||||
ui->showTrayNotifications->setChecked(
|
||||
switcher->showSystemTrayNotifications);
|
||||
ui->uiHintsDisable->setChecked(switcher->disableHints);
|
||||
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||
|
||||
for (int p : switcher->functionNamesByPriority) {
|
||||
|
||||
@@ -156,7 +156,7 @@ void SceneTrigger::logMatch()
|
||||
blog(LOG_INFO,
|
||||
"scene '%s' in status '%s' triggering action '%s' after %f seconds",
|
||||
GetWeakSourceName(scene).c_str(), statusName.c_str(),
|
||||
actionName.c_str(), duration.seconds);
|
||||
actionName.c_str(), duration.Seconds());
|
||||
}
|
||||
|
||||
void frontEndActionThread(sceneTriggerAction action, double delay)
|
||||
@@ -266,14 +266,14 @@ void SceneTrigger::performAction()
|
||||
|
||||
if (isFrontendAction(triggerAction)) {
|
||||
t = std::thread(frontEndActionThread, triggerAction,
|
||||
duration.seconds);
|
||||
duration.Seconds());
|
||||
} else if (isAudioAction(triggerAction)) {
|
||||
bool mute = triggerAction == sceneTriggerAction::MUTE_SOURCE;
|
||||
t = std::thread(muteThread, audioSource, duration.seconds,
|
||||
t = std::thread(muteThread, audioSource, duration.Seconds(),
|
||||
mute);
|
||||
} else if (isSwitcherStatusAction(triggerAction)) {
|
||||
bool stop = triggerAction == sceneTriggerAction::STOP_SWITCHER;
|
||||
t = std::thread(statusThread, duration.seconds, stop);
|
||||
t = std::thread(statusThread, duration.Seconds(), stop);
|
||||
} else {
|
||||
blog(LOG_WARNING, "ignoring unknown action '%d'",
|
||||
static_cast<int>(triggerAction));
|
||||
@@ -460,10 +460,8 @@ SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
|
||||
SLOT(TriggerTypeChanged(int)));
|
||||
QWidget::connect(actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(TriggerActionChanged(int)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(audioSources,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(AudioSourceChanged(const QString &)));
|
||||
@@ -552,24 +550,14 @@ void SceneTriggerWidget::TriggerActionChanged(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::DurationChanged(double seconds)
|
||||
void SceneTriggerWidget::DurationChanged(const Duration &duration)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration.seconds = seconds;
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::DurationUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration.displayUnit = unit;
|
||||
switchData->duration = duration;
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::AudioSourceChanged(const QString &text)
|
||||
|
||||
@@ -71,8 +71,7 @@ public:
|
||||
private slots:
|
||||
void TriggerTypeChanged(int index);
|
||||
void TriggerActionChanged(int index);
|
||||
void DurationChanged(double seconds);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
void DurationChanged(const Duration &);
|
||||
void AudioSourceChanged(const QString &text);
|
||||
|
||||
private:
|
||||
|
||||
@@ -438,8 +438,8 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
||||
SLOT(VolumeThresholdChanged(int)));
|
||||
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(audioSources,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(SourceChanged(const QString &)));
|
||||
@@ -554,14 +554,14 @@ void AudioSwitchWidget::ConditionChanged(int cond)
|
||||
switchData->condition = (audioCondition)cond;
|
||||
}
|
||||
|
||||
void AudioSwitchWidget::DurationChanged(double sec)
|
||||
void AudioSwitchWidget::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration.seconds = sec;
|
||||
switchData->duration = dur;
|
||||
}
|
||||
|
||||
void AudioSwitchWidget::IgnoreInactiveChanged(int state)
|
||||
@@ -580,8 +580,8 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
||||
{
|
||||
duration = new DurationSelection(this, false);
|
||||
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
|
||||
if (s) {
|
||||
duration->SetDuration(s->duration);
|
||||
@@ -602,12 +602,12 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
||||
loading = false;
|
||||
}
|
||||
|
||||
void AudioSwitchFallbackWidget::DurationChanged(double sec)
|
||||
void AudioSwitchFallbackWidget::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration.seconds = sec;
|
||||
switchData->duration = dur;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ private slots:
|
||||
void SourceChanged(const QString &text);
|
||||
void VolumeThresholdChanged(int vol);
|
||||
void ConditionChanged(int cond);
|
||||
void DurationChanged(double dur);
|
||||
void DurationChanged(const Duration &);
|
||||
void IgnoreInactiveChanged(int state);
|
||||
|
||||
private:
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s);
|
||||
|
||||
private slots:
|
||||
void DurationChanged(double dur);
|
||||
void DurationChanged(const Duration &dur);
|
||||
|
||||
private:
|
||||
DurationSelection *duration;
|
||||
|
||||
@@ -455,7 +455,7 @@ bool SceneSequenceSwitch::checkDurationMatchInterruptible()
|
||||
|
||||
void SceneSequenceSwitch::prepareUninterruptibleMatch(int &linger)
|
||||
{
|
||||
int dur = delay.seconds * 1000;
|
||||
int dur = delay.Milliseconds();
|
||||
if (dur > 0) {
|
||||
linger = dur;
|
||||
}
|
||||
@@ -588,10 +588,8 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
||||
QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(SceneChanged(const QString &)));
|
||||
|
||||
QWidget::connect(delay, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DelayChanged(double)));
|
||||
QWidget::connect(delay, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DelayUnitsChanged(DurationUnit)));
|
||||
QWidget::connect(delay, SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(DelayChanged(const Duration &)));
|
||||
QWidget::connect(startScenes,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(StartSceneChanged(const QString &)));
|
||||
@@ -689,24 +687,14 @@ void SequenceWidget::swapSwitchData(SequenceWidget *s1, SequenceWidget *s2)
|
||||
s2->setSwitchData(t);
|
||||
}
|
||||
|
||||
void SequenceWidget::DelayChanged(double sec)
|
||||
void SequenceWidget::DelayChanged(const Duration &delay)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->delay.seconds = sec;
|
||||
}
|
||||
|
||||
void SequenceWidget::DelayUnitsChanged(DurationUnit unit)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->delay.displayUnit = unit;
|
||||
switchData->delay = delay;
|
||||
}
|
||||
|
||||
void SequenceWidget::setExtendedSequenceStartScene()
|
||||
|
||||
@@ -59,8 +59,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void SceneChanged(const QString &text);
|
||||
void DelayChanged(double delay);
|
||||
void DelayUnitsChanged(DurationUnit);
|
||||
void DelayChanged(const Duration &delay);
|
||||
void StartSceneChanged(const QString &text);
|
||||
void InterruptibleChanged(int state);
|
||||
void ExtendClicked();
|
||||
|
||||
@@ -114,7 +114,7 @@ void MacroActionAudio::FadeVolume()
|
||||
int nrSteps = 0;
|
||||
float volStep = 0.;
|
||||
if (_fadeType == FadeType::DURATION) {
|
||||
nrSteps = _duration.seconds * 1000 / fadeInterval.count();
|
||||
nrSteps = _duration.Milliseconds() / fadeInterval.count();
|
||||
volStep = volDiff / nrSteps;
|
||||
} else {
|
||||
volStep = _rate / 1000.0f;
|
||||
@@ -212,7 +212,7 @@ void MacroActionAudio::LogAction() const
|
||||
vblog(LOG_INFO,
|
||||
"performed action \"%s\" for source \"%s\" with volume %d with fade %d %f",
|
||||
it->second.c_str(), _audioSource.ToString(true).c_str(),
|
||||
_volume, _fade, _duration.seconds);
|
||||
_volume.GetValue(), _fade, _duration.Seconds());
|
||||
} else {
|
||||
blog(LOG_WARNING, "ignored unknown audio action %d",
|
||||
static_cast<int>(_action));
|
||||
@@ -225,15 +225,16 @@ bool MacroActionAudio::Save(obs_data_t *obj) const
|
||||
_duration.Save(obj);
|
||||
_audioSource.Save(obj, "audioSource");
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
obs_data_set_int(obj, "syncOffset", _syncOffset);
|
||||
obs_data_set_int(obj, "monitor", _monitorType);
|
||||
obs_data_set_double(obj, "balance", _balance);
|
||||
obs_data_set_int(obj, "volume", _volume);
|
||||
obs_data_set_double(obj, "rate", _rate);
|
||||
_syncOffset.Save(obj, "syncOffset");
|
||||
_balance.Save(obj, "balance");
|
||||
_volume.Save(obj, "volume");
|
||||
_rate.Save(obj, "rate");
|
||||
obs_data_set_bool(obj, "fade", _fade);
|
||||
obs_data_set_int(obj, "fadeType", static_cast<int>(_fadeType));
|
||||
obs_data_set_bool(obj, "wait", _wait);
|
||||
obs_data_set_bool(obj, "abortActiveFade", _abortActiveFade);
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -243,12 +244,19 @@ bool MacroActionAudio::Load(obs_data_t *obj)
|
||||
_duration.Load(obj);
|
||||
_audioSource.Load(obj, "audioSource");
|
||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||
_syncOffset = obs_data_get_int(obj, "syncOffset");
|
||||
_monitorType = static_cast<obs_monitoring_type>(
|
||||
obs_data_get_int(obj, "monitor"));
|
||||
_balance = obs_data_get_double(obj, "balance");
|
||||
_volume = obs_data_get_int(obj, "volume");
|
||||
_rate = obs_data_get_double(obj, "rate");
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
_syncOffset = obs_data_get_int(obj, "syncOffset");
|
||||
_balance = obs_data_get_double(obj, "balance");
|
||||
_volume = obs_data_get_int(obj, "volume");
|
||||
_rate = obs_data_get_double(obj, "rate");
|
||||
} else {
|
||||
_syncOffset.Load(obj, "syncOffset");
|
||||
_balance.Load(obj, "balance");
|
||||
_volume.Load(obj, "volume");
|
||||
_rate.Load(obj, "rate");
|
||||
}
|
||||
_fade = obs_data_get_bool(obj, "fade");
|
||||
if (obs_data_has_user_value(obj, "wait")) {
|
||||
_wait = obs_data_get_bool(obj, "wait");
|
||||
@@ -302,16 +310,16 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_actions(new QComboBox),
|
||||
_fadeTypes(new QComboBox),
|
||||
_syncOffset(new QSpinBox),
|
||||
_syncOffset(new VariableSpinBox),
|
||||
_monitorTypes(new QComboBox),
|
||||
_balance(new SliderSpinBox(
|
||||
0., 1., "",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.audio.balance.description"))),
|
||||
_volumePercent(new QSpinBox),
|
||||
_volumePercent(new VariableSpinBox),
|
||||
_fade(new QCheckBox),
|
||||
_duration(new DurationSelection(parent, false)),
|
||||
_rate(new QDoubleSpinBox),
|
||||
_rate(new VariableDoubleSpinBox),
|
||||
_wait(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.audio.fade.wait"))),
|
||||
_abortActiveFade(new QCheckBox(
|
||||
@@ -343,20 +351,28 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||
SLOT(SourceChanged(const SourceSelection &)));
|
||||
QWidget::connect(_syncOffset, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(SyncOffsetChanged(int)));
|
||||
QWidget::connect(_balance, SIGNAL(DoubleValueChanged(double)), this,
|
||||
SLOT(BalanceChanged(double)));
|
||||
QWidget::connect(
|
||||
_syncOffset,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(SyncOffsetChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(
|
||||
_balance,
|
||||
SIGNAL(DoubleValueChanged(const NumberVariable<double> &)),
|
||||
this, SLOT(BalanceChanged(const NumberVariable<double> &)));
|
||||
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(MonitorTypeChanged(int)));
|
||||
QWidget::connect(_volumePercent, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(VolumeChanged(int)));
|
||||
QWidget::connect(
|
||||
_volumePercent,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(VolumeChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_fade, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(FadeChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_rate, SIGNAL(valueChanged(double)), this,
|
||||
SLOT(RateChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(
|
||||
_rate,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<double> &)),
|
||||
this, SLOT(RateChanged(const NumberVariable<double> &)));
|
||||
QWidget::connect(_wait, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(WaitChanged(int)));
|
||||
QWidget::connect(_abortActiveFade, SIGNAL(stateChanged(int)), this,
|
||||
@@ -468,13 +484,13 @@ void MacroActionAudioEdit::UpdateEntryData()
|
||||
_sources->SetSource(_entryData->_audioSource);
|
||||
_actions->setCurrentIndex(
|
||||
_actions->findData(static_cast<int>(_entryData->_action)));
|
||||
_syncOffset->setValue(_entryData->_syncOffset);
|
||||
_syncOffset->SetValue(_entryData->_syncOffset);
|
||||
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
||||
_balance->SetDoubleValue(_entryData->_balance);
|
||||
_volumePercent->setValue(_entryData->_volume);
|
||||
_volumePercent->SetValue(_entryData->_volume);
|
||||
_fade->setChecked(_entryData->_fade);
|
||||
_duration->SetDuration(_entryData->_duration);
|
||||
_rate->setValue(_entryData->_rate);
|
||||
_rate->SetValue(_entryData->_rate);
|
||||
_wait->setChecked(_entryData->_wait);
|
||||
_abortActiveFade->setChecked(_entryData->_abortActiveFade);
|
||||
_fadeTypes->setCurrentIndex(static_cast<int>(_entryData->_fadeType));
|
||||
@@ -505,7 +521,7 @@ void MacroActionAudioEdit::ActionChanged(int idx)
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::SyncOffsetChanged(int value)
|
||||
void MacroActionAudioEdit::SyncOffsetChanged(const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -525,7 +541,7 @@ void MacroActionAudioEdit::MonitorTypeChanged(int value)
|
||||
_entryData->_monitorType = static_cast<obs_monitoring_type>(value);
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::BalanceChanged(double value)
|
||||
void MacroActionAudioEdit::BalanceChanged(const NumberVariable<double> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -535,7 +551,7 @@ void MacroActionAudioEdit::BalanceChanged(double value)
|
||||
_entryData->_balance = value;
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::VolumeChanged(int value)
|
||||
void MacroActionAudioEdit::VolumeChanged(const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -556,17 +572,17 @@ void MacroActionAudioEdit::FadeChanged(int value)
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::DurationChanged(double seconds)
|
||||
void MacroActionAudioEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::RateChanged(double value)
|
||||
void MacroActionAudioEdit::RateChanged(const NumberVariable<double> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
|
||||
@@ -42,13 +42,13 @@ public:
|
||||
|
||||
Action _action = Action::MUTE;
|
||||
FadeType _fadeType = FadeType::DURATION;
|
||||
int64_t _syncOffset = 0;
|
||||
NumberVariable<int> _syncOffset = 0;
|
||||
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
||||
double _balance = 0.5;
|
||||
int _volume = 0;
|
||||
NumberVariable<double> _balance = 0.5;
|
||||
NumberVariable<int> _volume = 0;
|
||||
bool _fade = false;
|
||||
Duration _duration;
|
||||
double _rate = 100.;
|
||||
NumberVariable<double> _rate = 100.;
|
||||
bool _wait = false;
|
||||
bool _abortActiveFade = false;
|
||||
|
||||
@@ -84,13 +84,13 @@ public:
|
||||
private slots:
|
||||
void SourceChanged(const SourceSelection &);
|
||||
void ActionChanged(int value);
|
||||
void SyncOffsetChanged(int value);
|
||||
void SyncOffsetChanged(const NumberVariable<int> &value);
|
||||
void MonitorTypeChanged(int value);
|
||||
void BalanceChanged(double value);
|
||||
void VolumeChanged(int value);
|
||||
void BalanceChanged(const NumberVariable<double> &value);
|
||||
void VolumeChanged(const NumberVariable<int> &value);
|
||||
void FadeChanged(int value);
|
||||
void DurationChanged(double seconds);
|
||||
void RateChanged(double value);
|
||||
void DurationChanged(const Duration &seconds);
|
||||
void RateChanged(const NumberVariable<double> &value);
|
||||
void WaitChanged(int value);
|
||||
void AbortActiveFadeChanged(int value);
|
||||
void FadeTypeChanged(int value);
|
||||
@@ -101,13 +101,13 @@ protected:
|
||||
SourceSelectionWidget *_sources;
|
||||
QComboBox *_actions;
|
||||
QComboBox *_fadeTypes;
|
||||
QSpinBox *_syncOffset;
|
||||
VariableSpinBox *_syncOffset;
|
||||
QComboBox *_monitorTypes;
|
||||
SliderSpinBox *_balance;
|
||||
QSpinBox *_volumePercent;
|
||||
VariableSpinBox *_volumePercent;
|
||||
QCheckBox *_fade;
|
||||
DurationSelection *_duration;
|
||||
QDoubleSpinBox *_rate;
|
||||
VariableDoubleSpinBox *_rate;
|
||||
QCheckBox *_wait;
|
||||
QCheckBox *_abortActiveFade;
|
||||
QHBoxLayout *_fadeTypeLayout;
|
||||
|
||||
@@ -55,7 +55,7 @@ void MacroActionFile::LogAction() const
|
||||
bool MacroActionFile::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_string(obj, "file", _file.c_str());
|
||||
_file.Save(obj, "file");
|
||||
_text.Save(obj, "text");
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
return true;
|
||||
@@ -64,7 +64,7 @@ bool MacroActionFile::Save(obs_data_t *obj) const
|
||||
bool MacroActionFile::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_file = obs_data_get_string(obj, "file");
|
||||
_file.Load(obj, "file");
|
||||
_text.Load(obj, "text");
|
||||
_action = static_cast<FileAction>(obs_data_get_int(obj, "action"));
|
||||
return true;
|
||||
@@ -72,7 +72,7 @@ bool MacroActionFile::Load(obs_data_t *obj)
|
||||
|
||||
std::string MacroActionFile::GetShortDesc() const
|
||||
{
|
||||
return _file;
|
||||
return _file.UnresolvedValue();
|
||||
}
|
||||
|
||||
static inline void populateActionSelection(QComboBox *list)
|
||||
|
||||
@@ -24,9 +24,8 @@ public:
|
||||
return std::make_shared<MacroActionFile>(m);
|
||||
}
|
||||
|
||||
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
VariableResolvingString _text =
|
||||
obs_module_text("AdvSceneSwitcher.enterText");
|
||||
StringVariable _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
StringVariable _text = obs_module_text("AdvSceneSwitcher.enterText");
|
||||
FileAction _action = FileAction::WRITE;
|
||||
|
||||
private:
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
SourceSelection _source;
|
||||
OBSWeakSource _filter;
|
||||
Action _action = Action::ENABLE;
|
||||
VariableResolvingString _settings = "";
|
||||
StringVariable _settings = "";
|
||||
|
||||
private:
|
||||
void ResolveVariables();
|
||||
|
||||
@@ -224,7 +224,7 @@ bool MacroActionHotkey::PerformAction()
|
||||
}
|
||||
|
||||
if (!keys.empty()) {
|
||||
int dur = _duration;
|
||||
int dur = _duration.Milliseconds();
|
||||
if (_onlySendToObs || !canSimulateKeyPresses) {
|
||||
std::thread t([keys, dur]() { InjectKeys(keys, dur); });
|
||||
t.detach();
|
||||
@@ -254,8 +254,9 @@ bool MacroActionHotkey::Save(obs_data_t *obj) const
|
||||
obs_data_set_bool(obj, "right_alt", _rightAlt);
|
||||
obs_data_set_bool(obj, "left_meta", _leftMeta);
|
||||
obs_data_set_bool(obj, "right_meta", _rightMeta);
|
||||
obs_data_set_int(obj, "duration", _duration);
|
||||
_duration.Save(obj);
|
||||
obs_data_set_bool(obj, "onlyOBS", _onlySendToObs);
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -271,7 +272,11 @@ bool MacroActionHotkey::Load(obs_data_t *obj)
|
||||
_rightAlt = obs_data_get_bool(obj, "right_alt");
|
||||
_leftMeta = obs_data_get_bool(obj, "left_meta");
|
||||
_rightMeta = obs_data_get_bool(obj, "right_meta");
|
||||
_duration = obs_data_get_int(obj, "duration");
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
_duration = obs_data_get_int(obj, "duration") / 1000.0;
|
||||
} else {
|
||||
_duration.Load(obj);
|
||||
}
|
||||
_onlySendToObs = obs_data_get_bool(obj, "onlyOBS");
|
||||
return true;
|
||||
}
|
||||
@@ -388,32 +393,30 @@ static inline void populateKeySelection(QComboBox *list)
|
||||
|
||||
MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData)
|
||||
: QWidget(parent)
|
||||
: QWidget(parent),
|
||||
_keys(new QComboBox()),
|
||||
_leftShift(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"))),
|
||||
_rightShift(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.action.hotkey.rightShift"))),
|
||||
_leftCtrl(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftCtrl"))),
|
||||
_rightCtrl(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.rightCtrl"))),
|
||||
_leftAlt(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftAlt"))),
|
||||
_rightAlt(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.rightAlt"))),
|
||||
_leftMeta(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftMeta"))),
|
||||
_rightMeta(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.rightMeta"))),
|
||||
_duration(new DurationSelection(this, false)),
|
||||
_onlySendToOBS(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.onlyOBS"))),
|
||||
_noKeyPressSimulationWarning(new QLabel(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.disabled")))
|
||||
{
|
||||
_keys = new QComboBox();
|
||||
_leftShift = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"));
|
||||
_rightShift = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.rightShift"));
|
||||
_leftCtrl = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftCtrl"));
|
||||
_rightCtrl = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.rightCtrl"));
|
||||
_leftAlt = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftAlt"));
|
||||
_rightAlt = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.rightAlt"));
|
||||
_leftMeta = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.leftMeta"));
|
||||
_rightMeta = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.rightMeta"));
|
||||
_duration = new QSpinBox();
|
||||
_duration->setMaximum(5000);
|
||||
_onlySendToOBS = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.onlyOBS"));
|
||||
_noKeyPressSimulationWarning = new QLabel(
|
||||
obs_module_text("AdvSceneSwitcher.action.hotkey.disabled"));
|
||||
|
||||
populateKeySelection(_keys);
|
||||
|
||||
QWidget::connect(_keys, SIGNAL(currentIndexChanged(int)), this,
|
||||
@@ -434,8 +437,8 @@ MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
||||
SLOT(LMetaChanged(int)));
|
||||
QWidget::connect(_rightMeta, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(RMetaChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(DurationChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_onlySendToOBS, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(OnlySendToOBSChanged(int)));
|
||||
|
||||
@@ -493,7 +496,7 @@ void MacroActionHotkeyEdit::UpdateEntryData()
|
||||
_rightAlt->setChecked(_entryData->_rightAlt);
|
||||
_leftMeta->setChecked(_entryData->_leftMeta);
|
||||
_rightMeta->setChecked(_entryData->_rightMeta);
|
||||
_duration->setValue(_entryData->_duration);
|
||||
_duration->SetDuration(_entryData->_duration);
|
||||
_onlySendToOBS->setChecked(_entryData->_onlySendToObs ||
|
||||
!canSimulateKeyPresses);
|
||||
SetWarningVisibility();
|
||||
@@ -579,14 +582,14 @@ void MacroActionHotkeyEdit::RMetaChanged(int state)
|
||||
_entryData->_rightMeta = state;
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::DurationChanged(int ms)
|
||||
void MacroActionHotkeyEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration = ms;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::OnlySendToOBSChanged(int state)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "hotkey.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
@@ -30,7 +31,7 @@ public:
|
||||
bool _rightAlt = false;
|
||||
bool _leftMeta = false;
|
||||
bool _rightMeta = false;
|
||||
int _duration = 300; // in ms
|
||||
Duration _duration = 0.3;
|
||||
#ifdef __APPLE__
|
||||
bool _onlySendToObs = true;
|
||||
#else
|
||||
@@ -68,7 +69,7 @@ private slots:
|
||||
void RAltChanged(int state);
|
||||
void LMetaChanged(int state);
|
||||
void RMetaChanged(int state);
|
||||
void DurationChanged(int ms);
|
||||
void DurationChanged(const Duration &);
|
||||
void OnlySendToOBSChanged(int state);
|
||||
|
||||
protected:
|
||||
@@ -81,7 +82,7 @@ protected:
|
||||
QCheckBox *_rightAlt;
|
||||
QCheckBox *_leftMeta;
|
||||
QCheckBox *_rightMeta;
|
||||
QSpinBox *_duration;
|
||||
DurationSelection *_duration;
|
||||
QCheckBox *_onlySendToOBS;
|
||||
QLabel *_noKeyPressSimulationWarning;
|
||||
|
||||
|
||||
@@ -27,11 +27,26 @@ size_t WriteCB(void *ptr, size_t size, size_t nmemb, std::string *buffer)
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
void MacroActionHttp::SetupHeaders()
|
||||
{
|
||||
if (!_setHeaders) {
|
||||
return;
|
||||
}
|
||||
struct curl_slist *headers = nullptr;
|
||||
for (auto &header : _headers) {
|
||||
headers = switcher->curl.SlistAppend(headers, header.c_str());
|
||||
}
|
||||
if (!_headers.empty()) {
|
||||
switcher->curl.SetOpt(CURLOPT_HTTPHEADER, headers);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionHttp::Get()
|
||||
{
|
||||
switcher->curl.SetOpt(CURLOPT_URL, _url.c_str());
|
||||
switcher->curl.SetOpt(CURLOPT_HTTPGET, 1L);
|
||||
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.seconds * 1000);
|
||||
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds());
|
||||
SetupHeaders();
|
||||
|
||||
std::string response;
|
||||
if (IsReferencedInVars()) {
|
||||
@@ -49,7 +64,8 @@ void MacroActionHttp::Post()
|
||||
{
|
||||
switcher->curl.SetOpt(CURLOPT_URL, _url.c_str());
|
||||
switcher->curl.SetOpt(CURLOPT_POSTFIELDS, _data.c_str());
|
||||
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.seconds * 1000);
|
||||
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds());
|
||||
SetupHeaders();
|
||||
switcher->curl.Perform();
|
||||
}
|
||||
|
||||
@@ -90,8 +106,10 @@ void MacroActionHttp::LogAction() const
|
||||
bool MacroActionHttp::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_string(obj, "url", _url.c_str());
|
||||
_url.Save(obj, "url");
|
||||
_data.Save(obj, "data");
|
||||
obs_data_set_bool(obj, "setHeaders", _setHeaders);
|
||||
_headers.Save(obj, "headers", "header");
|
||||
obs_data_set_int(obj, "method", static_cast<int>(_method));
|
||||
_timeout.Save(obj);
|
||||
return true;
|
||||
@@ -100,8 +118,10 @@ bool MacroActionHttp::Save(obs_data_t *obj) const
|
||||
bool MacroActionHttp::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_url = obs_data_get_string(obj, "url");
|
||||
_url.Load(obj, "url");
|
||||
_data.Load(obj, "data");
|
||||
_setHeaders = obs_data_get_bool(obj, "setHeaders");
|
||||
_headers.Load(obj, "headers", "header");
|
||||
_method = static_cast<Method>(obs_data_get_int(obj, "method"));
|
||||
_timeout.Load(obj);
|
||||
return true;
|
||||
@@ -109,7 +129,7 @@ bool MacroActionHttp::Load(obs_data_t *obj)
|
||||
|
||||
std::string MacroActionHttp::GetShortDesc() const
|
||||
{
|
||||
return _url;
|
||||
return _url.UnresolvedValue();
|
||||
}
|
||||
|
||||
static inline void populateMethodSelection(QComboBox *list)
|
||||
@@ -122,9 +142,15 @@ static inline void populateMethodSelection(QComboBox *list)
|
||||
MacroActionHttpEdit::MacroActionHttpEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionHttp> entryData)
|
||||
: QWidget(parent),
|
||||
_url(new QLineEdit()),
|
||||
_url(new VariableLineEdit(this)),
|
||||
_methods(new QComboBox()),
|
||||
_data(new VariableTextEdit(this)),
|
||||
_setHeaders(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.http.setHeaders"))),
|
||||
_headerListLayout(new QVBoxLayout()),
|
||||
_headerList(new StringListEdit(
|
||||
this, obs_module_text("AdvSceneSwitcher.action.http.headers"),
|
||||
obs_module_text("AdvSceneSwitcher.action.http.addHeader"))),
|
||||
_timeout(new DurationSelection(this, false))
|
||||
{
|
||||
populateMethodSelection(_methods);
|
||||
@@ -135,8 +161,13 @@ MacroActionHttpEdit::MacroActionHttpEdit(
|
||||
SLOT(DataChanged()));
|
||||
QWidget::connect(_methods, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(MethodChanged(int)));
|
||||
QWidget::connect(_timeout, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(TimeoutChanged(double)));
|
||||
QWidget::connect(_setHeaders, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(SetHeadersChanged(int)));
|
||||
QWidget::connect(_headerList,
|
||||
SIGNAL(StringListChanged(const StringList &)), this,
|
||||
SLOT(HeadersChanged(const StringList &)));
|
||||
QWidget::connect(_timeout, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(TimeoutChanged(const Duration &)));
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{url}}", _url},
|
||||
@@ -153,8 +184,14 @@ MacroActionHttpEdit::MacroActionHttpEdit(
|
||||
obs_module_text("AdvSceneSwitcher.action.http.entry.line2"),
|
||||
timeoutLayout, widgetPlaceholders);
|
||||
|
||||
_headerListLayout->addWidget(new QLabel(
|
||||
obs_module_text("AdvSceneSwitcher.action.http.headers")));
|
||||
_headerListLayout->addWidget(_headerList);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(actionLayout);
|
||||
mainLayout->addWidget(_setHeaders);
|
||||
mainLayout->addLayout(_headerListLayout);
|
||||
mainLayout->addWidget(_data);
|
||||
mainLayout->addLayout(timeoutLayout);
|
||||
setLayout(mainLayout);
|
||||
@@ -170,8 +207,10 @@ void MacroActionHttpEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_url->setText(QString::fromStdString(_entryData->_url));
|
||||
_url->setText(_entryData->_url);
|
||||
_data->setPlainText(_entryData->_data);
|
||||
_setHeaders->setChecked(_entryData->_setHeaders);
|
||||
_headerList->SetStringList(_entryData->_headers);
|
||||
_methods->setCurrentIndex(static_cast<int>(_entryData->_method));
|
||||
_timeout->SetDuration(_entryData->_timeout);
|
||||
SetWidgetVisibility();
|
||||
@@ -199,28 +238,43 @@ void MacroActionHttpEdit::MethodChanged(int value)
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::TimeoutChanged(double seconds)
|
||||
void MacroActionHttpEdit::TimeoutChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_timeout.seconds = seconds;
|
||||
_entryData->_timeout = dur;
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::SetHeadersChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_setHeaders = value;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::HeadersChanged(const StringList &headers)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_headers = headers;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::SetWidgetVisibility()
|
||||
{
|
||||
switch (_entryData->_method) {
|
||||
case MacroActionHttp::Method::GET:
|
||||
_data->hide();
|
||||
break;
|
||||
case MacroActionHttp::Method::POST:
|
||||
_data->show();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_data->setVisible(_entryData->_method == MacroActionHttp::Method::POST);
|
||||
setLayoutVisible(_headerListLayout, _entryData->_setHeaders);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
#include "duration-control.hpp"
|
||||
#include "string-list.hpp"
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
|
||||
class MacroActionHttp : public MacroAction {
|
||||
public:
|
||||
@@ -25,13 +28,15 @@ public:
|
||||
POST,
|
||||
};
|
||||
|
||||
std::string _url = obs_module_text("AdvSceneSwitcher.enterURL");
|
||||
VariableResolvingString _data =
|
||||
obs_module_text("AdvSceneSwitcher.enterText");
|
||||
StringVariable _url = obs_module_text("AdvSceneSwitcher.enterURL");
|
||||
StringVariable _data = obs_module_text("AdvSceneSwitcher.enterText");
|
||||
bool _setHeaders = false;
|
||||
StringList _headers;
|
||||
Method _method = Method::GET;
|
||||
Duration _timeout;
|
||||
Duration _timeout = Duration(1.0);
|
||||
|
||||
private:
|
||||
void SetupHeaders();
|
||||
void Get();
|
||||
void Post();
|
||||
|
||||
@@ -59,7 +64,9 @@ private slots:
|
||||
void DataChanged();
|
||||
void URLChanged();
|
||||
void MethodChanged(int);
|
||||
void TimeoutChanged(double seconds);
|
||||
void TimeoutChanged(const Duration &seconds);
|
||||
void SetHeadersChanged(int);
|
||||
void HeadersChanged(const StringList &);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -69,9 +76,12 @@ protected:
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QLineEdit *_url;
|
||||
VariableLineEdit *_url;
|
||||
QComboBox *_methods;
|
||||
VariableTextEdit *_data;
|
||||
QCheckBox *_setHeaders;
|
||||
QVBoxLayout *_headerListLayout;
|
||||
StringListEdit *_headerList;
|
||||
DurationSelection *_timeout;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
@@ -21,27 +21,28 @@ const static std::map<PerformMacroAction, std::string> actionTypes = {
|
||||
|
||||
bool MacroActionMacro::PerformAction()
|
||||
{
|
||||
if (!_macro.get()) {
|
||||
auto macro = _macro.GetMacro();
|
||||
if (!macro) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (_action) {
|
||||
case PerformMacroAction::PAUSE:
|
||||
_macro->SetPaused();
|
||||
macro->SetPaused();
|
||||
break;
|
||||
case PerformMacroAction::UNPAUSE:
|
||||
_macro->SetPaused(false);
|
||||
macro->SetPaused(false);
|
||||
break;
|
||||
case PerformMacroAction::RESET_COUNTER:
|
||||
_macro->ResetRunCount();
|
||||
macro->ResetRunCount();
|
||||
break;
|
||||
case PerformMacroAction::RUN:
|
||||
if (!_macro->Paused()) {
|
||||
_macro->PerformActions();
|
||||
if (!macro->Paused()) {
|
||||
macro->PerformActions();
|
||||
}
|
||||
break;
|
||||
case PerformMacroAction::STOP:
|
||||
_macro->Stop();
|
||||
macro->Stop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -51,26 +52,27 @@ bool MacroActionMacro::PerformAction()
|
||||
|
||||
void MacroActionMacro::LogAction() const
|
||||
{
|
||||
if (!_macro.get()) {
|
||||
auto macro = _macro.GetMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
switch (_action) {
|
||||
case PerformMacroAction::PAUSE:
|
||||
vblog(LOG_INFO, "paused \"%s\"", _macro->Name().c_str());
|
||||
vblog(LOG_INFO, "paused \"%s\"", macro->Name().c_str());
|
||||
break;
|
||||
case PerformMacroAction::UNPAUSE:
|
||||
vblog(LOG_INFO, "unpaused \"%s\"", _macro->Name().c_str());
|
||||
vblog(LOG_INFO, "unpaused \"%s\"", macro->Name().c_str());
|
||||
break;
|
||||
case PerformMacroAction::RESET_COUNTER:
|
||||
vblog(LOG_INFO, "reset counter for \"%s\"",
|
||||
_macro->Name().c_str());
|
||||
macro->Name().c_str());
|
||||
break;
|
||||
case PerformMacroAction::RUN:
|
||||
vblog(LOG_INFO, "run nested macro \"%s\"",
|
||||
_macro->Name().c_str());
|
||||
macro->Name().c_str());
|
||||
break;
|
||||
case PerformMacroAction::STOP:
|
||||
vblog(LOG_INFO, "stopped macro \"%s\"", _macro->Name().c_str());
|
||||
vblog(LOG_INFO, "stopped macro \"%s\"", macro->Name().c_str());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -96,10 +98,7 @@ bool MacroActionMacro::Load(obs_data_t *obj)
|
||||
|
||||
std::string MacroActionMacro::GetShortDesc() const
|
||||
{
|
||||
if (_macro.get()) {
|
||||
return _macro->Name();
|
||||
}
|
||||
return "";
|
||||
return _macro.Name();
|
||||
}
|
||||
|
||||
static inline void populateActionSelection(QComboBox *list)
|
||||
@@ -120,8 +119,6 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
||||
|
||||
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(MacroChanged(const QString &)));
|
||||
QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this,
|
||||
SLOT(MacroRemove(const QString &)));
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
|
||||
@@ -145,7 +142,7 @@ void MacroActionMacroEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_macros->SetCurrentMacro(_entryData->_macro.get());
|
||||
_macros->SetCurrentMacro(_entryData->_macro);
|
||||
if (_entryData->_action == PerformMacroAction::RUN ||
|
||||
_entryData->_action == PerformMacroAction::STOP) {
|
||||
_macros->HideSelectedMacro();
|
||||
@@ -159,7 +156,7 @@ void MacroActionMacroEdit::MacroChanged(const QString &text)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_macro.UpdateRef(text);
|
||||
_entryData->_macro = text;
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
@@ -180,10 +177,3 @@ void MacroActionMacroEdit::ActionChanged(int value)
|
||||
_macros->ShowAllMacros();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::MacroRemove(const QString &)
|
||||
{
|
||||
if (_entryData) {
|
||||
_entryData->_macro.UpdateRef();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
|
||||
private slots:
|
||||
void MacroChanged(const QString &text);
|
||||
void MacroRemove(const QString &name);
|
||||
void ActionChanged(int value);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -48,7 +48,7 @@ bool MacroActionMedia::PerformAction()
|
||||
obs_source_media_previous(source);
|
||||
break;
|
||||
case MediaAction::SEEK:
|
||||
obs_source_media_set_time(source, _seek.seconds * 1000);
|
||||
obs_source_media_set_time(source, _seek.Milliseconds());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -116,10 +116,8 @@ MacroActionMediaEdit::MacroActionMediaEdit(
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||
SLOT(SourceChanged(const SourceSelection &)));
|
||||
QWidget::connect(_seek, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_seek, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_seek, SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(DurationChanged(const Duration &)));
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
@@ -171,24 +169,14 @@ void MacroActionMediaEdit::ActionChanged(int value)
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMediaEdit::DurationChanged(double seconds)
|
||||
void MacroActionMediaEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_seek.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroActionMediaEdit::DurationUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_seek.displayUnit = unit;
|
||||
_entryData->_seek = dur;
|
||||
}
|
||||
|
||||
void MacroActionMediaEdit::SetWidgetVisibility()
|
||||
|
||||
@@ -58,8 +58,7 @@ public:
|
||||
private slots:
|
||||
void SourceChanged(const SourceSelection &);
|
||||
void ActionChanged(int value);
|
||||
void DurationChanged(double value);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
void DurationChanged(const Duration &value);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ bool MacroActionPluginState::Save(obs_data_t *obj) const
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
obs_data_set_int(obj, "value", _value);
|
||||
obs_data_set_string(obj, "scene", GetWeakSourceName(_scene).c_str());
|
||||
obs_data_set_string(obj, "settingsPath", _settingsPath.c_str());
|
||||
_settingsPath.Save(obj, "settingsPath");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ bool MacroActionPluginState::Load(obs_data_t *obj)
|
||||
_value = obs_data_get_int(obj, "value");
|
||||
const char *sceneName = obs_data_get_string(obj, "scene");
|
||||
_scene = GetWeakSourceByName(sceneName);
|
||||
_settingsPath = obs_data_get_string(obj, "settingsPath");
|
||||
_settingsPath.Load(obj, "settingsPath");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ void MacroActionPluginStateEdit::UpdateEntryData()
|
||||
populateValueSelection(_values, _entryData->_action);
|
||||
_values->setCurrentIndex(_entryData->_value);
|
||||
_scenes->setCurrentText(GetWeakSourceName(_entryData->_scene).c_str());
|
||||
_settings->SetPath(QString::fromStdString(_entryData->_settingsPath));
|
||||
_settings->SetPath(_entryData->_settingsPath);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
|
||||
PluginStateAction _action = PluginStateAction::STOP;
|
||||
int _value = 0;
|
||||
std::string _settingsPath;
|
||||
StringVariable _settingsPath;
|
||||
OBSWeakSource _scene;
|
||||
|
||||
private:
|
||||
|
||||
@@ -249,7 +249,7 @@ void MacroActionProjectorEdit::MonitorChanged(int value)
|
||||
_entryData->_monitor = value;
|
||||
}
|
||||
|
||||
void MacroActionProjectorEdit::WindowTypeChanged(int value)
|
||||
void MacroActionProjectorEdit::WindowTypeChanged(int)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
|
||||
@@ -11,22 +11,30 @@ bool MacroActionRandom::_registered = MacroActionFactory::Register(
|
||||
{MacroActionRandom::Create, MacroActionRandomEdit::Create,
|
||||
"AdvSceneSwitcher.action.random"});
|
||||
|
||||
std::vector<MacroRef> getNextMacros(std::vector<MacroRef> ¯os,
|
||||
MacroRef &lastRandomMacro, bool allowRepeat)
|
||||
static bool validNextMacro(const std::shared_ptr<Macro> ¯o)
|
||||
{
|
||||
std::vector<MacroRef> res;
|
||||
return macro && !macro->Paused();
|
||||
}
|
||||
|
||||
static std::vector<std::shared_ptr<Macro>>
|
||||
getNextMacros(std::vector<MacroRef> ¯os, MacroRef &lastRandomMacroRef,
|
||||
bool allowRepeat)
|
||||
{
|
||||
std::vector<std::shared_ptr<Macro>> res;
|
||||
if (macros.size() == 1) {
|
||||
if (!macros[0].get() || macros[0]->Paused()) {
|
||||
return res;
|
||||
} else {
|
||||
return macros;
|
||||
auto macro = macros[0].GetMacro();
|
||||
if (validNextMacro(macro)) {
|
||||
res.push_back(macro);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
auto lastRandomMacro = lastRandomMacroRef.GetMacro();
|
||||
for (auto &m : macros) {
|
||||
if (m.get() && !m->Paused() &&
|
||||
(allowRepeat || (lastRandomMacro.get() != m.get()))) {
|
||||
res.push_back(m);
|
||||
auto macro = m.GetMacro();
|
||||
if (validNextMacro(macro) &&
|
||||
(allowRepeat || (lastRandomMacro != macro))) {
|
||||
res.push_back(macro);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@@ -42,7 +50,7 @@ bool MacroActionRandom::PerformAction()
|
||||
if (macros.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
if (macros.size() == 1 && macros[0].get()) {
|
||||
if (macros.size() == 1) {
|
||||
lastRandomMacro = macros[0];
|
||||
return macros[0]->PerformActions();
|
||||
}
|
||||
@@ -126,8 +134,7 @@ void MacroActionRandomEdit::MacroRemove(const QString &)
|
||||
|
||||
auto it = _entryData->_macros.begin();
|
||||
while (it != _entryData->_macros.end()) {
|
||||
it->UpdateRef();
|
||||
if (it->get() == nullptr) {
|
||||
if (!it->GetMacro()) {
|
||||
it = _entryData->_macros.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
@@ -188,9 +195,9 @@ bool MacroActionRandomEdit::ShouldShowAllowRepeat()
|
||||
if (_entryData->_macros.size() <= 1) {
|
||||
return false;
|
||||
}
|
||||
const auto macro = _entryData->_macros[0];
|
||||
const auto macro = _entryData->_macros[0].GetMacro();
|
||||
for (const auto &m : _entryData->_macros) {
|
||||
if (macro.get() != m.get()) {
|
||||
if (macro != m.GetMacro()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#include "macro-action-run.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "name-dialog.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QFileDialog>
|
||||
#include <QDesktopServices>
|
||||
|
||||
const std::string MacroActionRun::id = "run";
|
||||
@@ -15,137 +13,53 @@ bool MacroActionRun::_registered = MacroActionFactory::Register(
|
||||
|
||||
bool MacroActionRun::PerformAction()
|
||||
{
|
||||
if (!QProcess::startDetached(
|
||||
QString::fromStdString(_path), _args,
|
||||
QString::fromStdString(_workingDirectory)) &&
|
||||
_args.empty()) {
|
||||
bool procStarted = QProcess::startDetached(
|
||||
QString::fromStdString(_procConfig.Path()), _procConfig.Args(),
|
||||
QString::fromStdString(_procConfig.WorkingDir()));
|
||||
if (!procStarted && _procConfig.Args().empty()) {
|
||||
vblog(LOG_INFO, "run \"%s\" using QDesktopServices",
|
||||
_path.c_str());
|
||||
QDesktopServices::openUrl(
|
||||
QUrl::fromLocalFile(QString::fromStdString(_path)));
|
||||
_procConfig.Path().c_str());
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(
|
||||
QString::fromStdString(_procConfig.Path())));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroActionRun::LogAction() const
|
||||
{
|
||||
vblog(LOG_INFO, "run \"%s\"", _path.c_str());
|
||||
vblog(LOG_INFO, "run \"%s\"", _procConfig.UnresolvedPath().c_str());
|
||||
}
|
||||
|
||||
bool MacroActionRun::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_string(obj, "path", _path.c_str());
|
||||
obs_data_set_string(obj, "workingDirectory", _workingDirectory.c_str());
|
||||
obs_data_array_t *args = obs_data_array_create();
|
||||
for (auto &arg : _args) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
obs_data_set_string(array_obj, "arg",
|
||||
arg.toStdString().c_str());
|
||||
obs_data_array_push_back(args, array_obj);
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "args", args);
|
||||
obs_data_array_release(args);
|
||||
_procConfig.Save(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroActionRun::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_path = obs_data_get_string(obj, "path");
|
||||
_workingDirectory = obs_data_get_string(obj, "workingDirectory");
|
||||
obs_data_array_t *args = obs_data_get_array(obj, "args");
|
||||
size_t count = obs_data_array_count(args);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(args, i);
|
||||
_args << QString::fromStdString(
|
||||
obs_data_get_string(array_obj, "arg"));
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_array_release(args);
|
||||
_procConfig.Load(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroActionRun::GetShortDesc() const
|
||||
{
|
||||
return _path;
|
||||
return _procConfig.UnresolvedPath();
|
||||
}
|
||||
|
||||
MacroActionRunEdit::MacroActionRunEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionRun> entryData)
|
||||
: QWidget(parent),
|
||||
_filePath(new FileSelection()),
|
||||
_argList(new QListWidget()),
|
||||
_addArg(new QPushButton()),
|
||||
_removeArg(new QPushButton()),
|
||||
_argUp(new QPushButton()),
|
||||
_argDown(new QPushButton()),
|
||||
_workingDirectory(new FileSelection(FileSelection::Type::FOLDER))
|
||||
: QWidget(parent), _procConfig(new ProcessConfigEdit(this))
|
||||
{
|
||||
_addArg->setMaximumWidth(22);
|
||||
_addArg->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("addIconSmall")));
|
||||
_addArg->setFlat(true);
|
||||
_removeArg->setMaximumWidth(22);
|
||||
_removeArg->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("removeIconSmall")));
|
||||
_removeArg->setFlat(true);
|
||||
_argUp->setMaximumWidth(22);
|
||||
_argUp->setProperty("themeID",
|
||||
QVariant(QString::fromUtf8("upArrowIconSmall")));
|
||||
_argUp->setFlat(true);
|
||||
_argDown->setMaximumWidth(22);
|
||||
_argDown->setProperty(
|
||||
"themeID", QVariant(QString::fromUtf8("downArrowIconSmall")));
|
||||
_argDown->setFlat(true);
|
||||
QWidget::connect(_procConfig,
|
||||
SIGNAL(ConfigChanged(const ProcessConfig &)), this,
|
||||
SLOT(ProcessConfigChanged(const ProcessConfig &)));
|
||||
|
||||
QWidget::connect(_filePath, SIGNAL(PathChanged(const QString &)), this,
|
||||
SLOT(PathChanged(const QString &)));
|
||||
QWidget::connect(_addArg, SIGNAL(clicked()), this, SLOT(AddArg()));
|
||||
QWidget::connect(_removeArg, SIGNAL(clicked()), this,
|
||||
SLOT(RemoveArg()));
|
||||
QWidget::connect(_argUp, SIGNAL(clicked()), this, SLOT(ArgUp()));
|
||||
QWidget::connect(_argDown, SIGNAL(clicked()), this, SLOT(ArgDown()));
|
||||
QWidget::connect(_argList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
|
||||
this, SLOT(ArgItemClicked(QListWidgetItem *)));
|
||||
QWidget::connect(_workingDirectory,
|
||||
SIGNAL(PathChanged(const QString &)), this,
|
||||
SLOT(WorkingDirectoryChanged(const QString &)));
|
||||
|
||||
auto *entryLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{filePath}}", _filePath},
|
||||
{"{{workingDirectory}}", _workingDirectory},
|
||||
};
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.run.entry"),
|
||||
entryLayout, widgetPlaceholders, false);
|
||||
|
||||
auto argButtonLayout = new QHBoxLayout;
|
||||
argButtonLayout->addWidget(_addArg);
|
||||
argButtonLayout->addWidget(_removeArg);
|
||||
QFrame *line = new QFrame();
|
||||
line->setFrameShape(QFrame::VLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
argButtonLayout->addWidget(line);
|
||||
argButtonLayout->addWidget(_argUp);
|
||||
argButtonLayout->addWidget(_argDown);
|
||||
argButtonLayout->addStretch();
|
||||
|
||||
auto workingDirectoryLayout = new QHBoxLayout;
|
||||
placeWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.run.entry.workingDirectory"),
|
||||
workingDirectoryLayout, widgetPlaceholders, false);
|
||||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(entryLayout);
|
||||
mainLayout->addWidget(new QLabel(
|
||||
obs_module_text("AdvSceneSwitcher.action.run.arguments")));
|
||||
mainLayout->addWidget(_argList);
|
||||
mainLayout->addLayout(argButtonLayout);
|
||||
mainLayout->addLayout(workingDirectoryLayout);
|
||||
setLayout(mainLayout);
|
||||
auto *layout = new QVBoxLayout;
|
||||
layout->addWidget(_procConfig);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
@@ -157,142 +71,19 @@ void MacroActionRunEdit::UpdateEntryData()
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
_filePath->SetPath(QString::fromStdString(_entryData->_path));
|
||||
for (auto &arg : _entryData->_args) {
|
||||
QListWidgetItem *item = new QListWidgetItem(arg, _argList);
|
||||
item->setData(Qt::UserRole, arg);
|
||||
}
|
||||
_workingDirectory->SetPath(
|
||||
QString::fromStdString(_entryData->_workingDirectory));
|
||||
SetArgListSize();
|
||||
_procConfig->SetProcessConfig(_entryData->_procConfig);
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::PathChanged(const QString &text)
|
||||
void MacroActionRunEdit::ProcessConfigChanged(const ProcessConfig &conf)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_path = text.toUtf8().constData();
|
||||
_entryData->_procConfig = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::AddArg()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
bool accepted = AdvSSNameDialog::AskForName(
|
||||
this,
|
||||
obs_module_text("AdvSceneSwitcher.action.run.addArgument"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.run.addArgumentDescription"),
|
||||
name, "", 170, false);
|
||||
|
||||
if (!accepted || name.empty()) {
|
||||
return;
|
||||
}
|
||||
auto arg = QString::fromStdString(name);
|
||||
QVariant v = QVariant::fromValue(arg);
|
||||
QListWidgetItem *item = new QListWidgetItem(arg, _argList);
|
||||
item->setData(Qt::UserRole, arg);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_args << arg;
|
||||
SetArgListSize();
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::RemoveArg()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
int idx = _argList->currentRow();
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
_entryData->_args.removeAt(idx);
|
||||
|
||||
QListWidgetItem *item = _argList->currentItem();
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
delete item;
|
||||
SetArgListSize();
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::ArgUp()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = _argList->currentRow();
|
||||
if (idx != -1 && idx != 0) {
|
||||
_argList->insertItem(idx - 1, _argList->takeItem(idx));
|
||||
_argList->setCurrentRow(idx - 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_args.move(idx, idx - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::ArgDown()
|
||||
{
|
||||
int idx = _argList->currentRow();
|
||||
if (idx != -1 && idx != _argList->count() - 1) {
|
||||
_argList->insertItem(idx + 1, _argList->takeItem(idx));
|
||||
_argList->setCurrentRow(idx + 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_args.move(idx, idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::ArgItemClicked(QListWidgetItem *item)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
bool accepted = AdvSSNameDialog::AskForName(
|
||||
this,
|
||||
obs_module_text("AdvSceneSwitcher.action.run.addArgument"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.run.addArgumentDescription"),
|
||||
name, item->text(), 170, false);
|
||||
|
||||
if (!accepted || name.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto arg = QString::fromStdString(name);
|
||||
QVariant v = QVariant::fromValue(arg);
|
||||
item->setText(arg);
|
||||
item->setData(Qt::UserRole, arg);
|
||||
int idx = _argList->currentRow();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_args[idx] = arg;
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::WorkingDirectoryChanged(const QString &path)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_entryData->_workingDirectory = path.toStdString();
|
||||
}
|
||||
|
||||
void MacroActionRunEdit::SetArgListSize()
|
||||
{
|
||||
setHeightToContentHeight(_argList);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "file-selection.hpp"
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QListWidget>
|
||||
#include <QStringList>
|
||||
#include "process-config.hpp"
|
||||
|
||||
class MacroActionRun : public MacroAction {
|
||||
public:
|
||||
@@ -21,9 +16,7 @@ public:
|
||||
return std::make_shared<MacroActionRun>(m);
|
||||
}
|
||||
|
||||
std::string _path = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
std::string _workingDirectory = "";
|
||||
QStringList _args;
|
||||
ProcessConfig _procConfig;
|
||||
|
||||
private:
|
||||
static bool _registered;
|
||||
@@ -46,13 +39,7 @@ public:
|
||||
}
|
||||
|
||||
private slots:
|
||||
void PathChanged(const QString &text);
|
||||
void AddArg();
|
||||
void RemoveArg();
|
||||
void ArgUp();
|
||||
void ArgDown();
|
||||
void ArgItemClicked(QListWidgetItem *);
|
||||
void WorkingDirectoryChanged(const QString &text);
|
||||
void ProcessConfigChanged(const ProcessConfig &);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -60,14 +47,6 @@ protected:
|
||||
std::shared_ptr<MacroActionRun> _entryData;
|
||||
|
||||
private:
|
||||
void SetArgListSize();
|
||||
|
||||
FileSelection *_filePath;
|
||||
QListWidget *_argList;
|
||||
QPushButton *_addArg;
|
||||
QPushButton *_removeArg;
|
||||
QPushButton *_argUp;
|
||||
QPushButton *_argDown;
|
||||
FileSelection *_workingDirectory;
|
||||
ProcessConfigEdit *_procConfig;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ bool MacroActionSwitchScene::WaitForTransition(OBSWeakSource &scene,
|
||||
OBSWeakSource &transition)
|
||||
{
|
||||
const int expectedTransitionDuration = getExpectedTransitionDuration(
|
||||
scene, transition, _duration.seconds);
|
||||
scene, transition, _duration.Seconds());
|
||||
switcher->abortMacroWait = false;
|
||||
|
||||
std::unique_lock<std::mutex> lock(switcher->m);
|
||||
@@ -121,7 +121,7 @@ bool MacroActionSwitchScene::PerformAction()
|
||||
{
|
||||
auto scene = _scene.GetScene();
|
||||
auto transition = _transition.GetTransition();
|
||||
switchScene({scene, transition, (int)(_duration.seconds * 1000)},
|
||||
switchScene({scene, transition, (int)(_duration.Milliseconds())},
|
||||
obs_frontend_preview_program_mode_active());
|
||||
if (_blockUntilTransitionDone && scene) {
|
||||
return WaitForTransition(scene, transition);
|
||||
@@ -196,8 +196,8 @@ MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
|
||||
SIGNAL(TransitionChanged(const TransitionSelection &)),
|
||||
this,
|
||||
SLOT(TransitionChanged(const TransitionSelection &)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_blockUntilTransitionDone, SIGNAL(stateChanged(int)),
|
||||
this, SLOT(BlockUntilTransitionDoneChanged(int)));
|
||||
|
||||
@@ -225,14 +225,14 @@ MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroActionSwitchSceneEdit::DurationChanged(double seconds)
|
||||
void MacroActionSwitchSceneEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionSwitchSceneEdit::BlockUntilTransitionDoneChanged(int state)
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
private slots:
|
||||
void SceneChanged(const SceneSelection &);
|
||||
void TransitionChanged(const TransitionSelection &);
|
||||
void DurationChanged(double seconds);
|
||||
void DurationChanged(const Duration &seconds);
|
||||
void BlockUntilTransitionDoneChanged(int state);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
|
||||
SceneSelection _scene;
|
||||
SceneItemSelection _source;
|
||||
VariableResolvingString _settings = "";
|
||||
StringVariable _settings = "";
|
||||
|
||||
private:
|
||||
void ApplySettings(const std::string &);
|
||||
|
||||
@@ -87,7 +87,7 @@ bool MacroActionScreenshot::Save(obs_data_t *obj) const
|
||||
_source.Save(obj);
|
||||
obs_data_set_int(obj, "saveType", static_cast<int>(_saveType));
|
||||
obs_data_set_int(obj, "targetType", static_cast<int>(_targetType));
|
||||
obs_data_set_string(obj, "savePath", _path.c_str());
|
||||
_path.Save(obj, "savePath");
|
||||
obs_data_set_int(obj, "version", _version);
|
||||
return true;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ bool MacroActionScreenshot::Load(obs_data_t *obj)
|
||||
_saveType = static_cast<SaveType>(obs_data_get_int(obj, "saveType"));
|
||||
_targetType =
|
||||
static_cast<TargetType>(obs_data_get_int(obj, "targetType"));
|
||||
_path = obs_data_get_string(obj, "savePath");
|
||||
_path.Load(obj, "savePath");
|
||||
|
||||
// TODO: Remove fallback for older versions
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
@@ -200,7 +200,7 @@ void MacroActionScreenshotEdit::UpdateEntryData()
|
||||
_scenes->SetScene(_entryData->_scene);
|
||||
_saveType->setCurrentIndex(static_cast<int>(_entryData->_saveType));
|
||||
_targetType->setCurrentIndex(static_cast<int>(_entryData->_targetType));
|
||||
_savePath->SetPath(QString::fromStdString(_entryData->_path));
|
||||
_savePath->SetPath(_entryData->_path);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ void MacroActionScreenshotEdit::PathChanged(const QString &text)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_path = text.toUtf8().constData();
|
||||
_entryData->_path = text.toStdString();
|
||||
}
|
||||
|
||||
void MacroActionScreenshotEdit::SourceChanged(const SourceSelection &source)
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
TargetType _targetType = TargetType::SOURCE;
|
||||
SceneSelection _scene;
|
||||
SourceSelection _source;
|
||||
std::string _path = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
StringVariable _path = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
|
||||
private:
|
||||
void FrontendScreenshot(OBSWeakSource &);
|
||||
|
||||
@@ -12,7 +12,8 @@ bool MacroActionSequence::_registered = MacroActionFactory::Register(
|
||||
int getNextUnpausedMacroIdx(std::vector<MacroRef> ¯os, int startIdx)
|
||||
{
|
||||
for (; (int)macros.size() > startIdx; ++startIdx) {
|
||||
if (macros[startIdx].get() && !macros[startIdx]->Paused()) {
|
||||
auto macro = macros[startIdx].GetMacro();
|
||||
if (macro && !macro->Paused()) {
|
||||
return startIdx;
|
||||
}
|
||||
}
|
||||
@@ -58,7 +59,7 @@ bool MacroActionSequence::PerformAction()
|
||||
return true;
|
||||
}
|
||||
|
||||
auto macro = GetNextMacro();
|
||||
auto macro = GetNextMacro().GetMacro();
|
||||
if (!macro.get()) {
|
||||
return true;
|
||||
}
|
||||
@@ -158,8 +159,8 @@ void MacroActionSequenceEdit::MacroRemove(const QString &)
|
||||
|
||||
auto it = _entryData->_macros.begin();
|
||||
while (it != _entryData->_macros.end()) {
|
||||
it->UpdateRef();
|
||||
if (it->get() == nullptr) {
|
||||
|
||||
if (!it->GetMacro()) {
|
||||
it = _entryData->_macros.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
@@ -250,12 +251,11 @@ void MacroActionSequenceEdit::UpdateStatusLine()
|
||||
QString nextMacroName =
|
||||
obs_module_text("AdvSceneSwitcher.action.sequence.status.none");
|
||||
if (_entryData) {
|
||||
if (_entryData->_lastSequenceMacro.get()) {
|
||||
lastMacroName = QString::fromStdString(
|
||||
_entryData->_lastSequenceMacro->Name());
|
||||
if (auto macro = _entryData->_lastSequenceMacro.GetMacro()) {
|
||||
lastMacroName = QString::fromStdString(macro->Name());
|
||||
}
|
||||
auto next = _entryData->GetNextMacro(false);
|
||||
if (next.get()) {
|
||||
auto next = _entryData->GetNextMacro(false).GetMacro();
|
||||
if (next) {
|
||||
nextMacroName = QString::fromStdString(next->Name());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
SourceSelection _source;
|
||||
SourceSettingButton _button;
|
||||
VariableResolvingString _settings = "";
|
||||
StringVariable _settings = "";
|
||||
SourceAction _action = SourceAction::ENABLE;
|
||||
|
||||
private:
|
||||
|
||||
@@ -9,16 +9,6 @@ bool MacroActionSudioMode::_registered = MacroActionFactory::Register(
|
||||
{MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
|
||||
"AdvSceneSwitcher.action.studioMode"});
|
||||
|
||||
// TODO: Remove in future version (backwards compatibility)
|
||||
static const std::string idOld1 = "scene_swap";
|
||||
static const std::string idOld2 = "preview_scene";
|
||||
static bool oldRegisterd1 = MacroActionFactory::Register(
|
||||
idOld1, {MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
|
||||
"AdvSceneSwitcher.action.studioMode"});
|
||||
static bool oldRegisterd2 = MacroActionFactory::Register(
|
||||
idOld2, {MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
|
||||
"AdvSceneSwitcher.action.studioMode"});
|
||||
|
||||
const static std::map<StudioModeAction, std::string> actionTypes = {
|
||||
{StudioModeAction::SWAP_SCENE,
|
||||
"AdvSceneSwitcher.action.studioMode.type.swap"},
|
||||
@@ -98,10 +88,6 @@ bool MacroActionSudioMode::Load(obs_data_t *obj)
|
||||
_action =
|
||||
static_cast<StudioModeAction>(obs_data_get_int(obj, "action"));
|
||||
_scene.Load(obj);
|
||||
// TODO: Remove in future version (backwards compatibility)
|
||||
if (obs_data_get_string(obj, "id") == idOld2) {
|
||||
_action = StudioModeAction::SET_SCENE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,11 @@ static std::map<TimerAction, std::string> timerActions = {
|
||||
|
||||
bool MacroActionTimer::PerformAction()
|
||||
{
|
||||
if (!_macro.get()) {
|
||||
auto macro = _macro.GetMacro();
|
||||
if (!macro) {
|
||||
return true;
|
||||
}
|
||||
for (auto c : _macro->Conditions()) {
|
||||
for (auto c : macro->Conditions()) {
|
||||
if (c->GetId() != "timer") {
|
||||
continue;
|
||||
}
|
||||
@@ -47,7 +48,7 @@ bool MacroActionTimer::PerformAction()
|
||||
break;
|
||||
case TimerAction::SET_TIME_REMAINING:
|
||||
timerCondition->_duration.SetTimeRemaining(
|
||||
_duration.seconds);
|
||||
_duration.Seconds());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -58,26 +59,27 @@ bool MacroActionTimer::PerformAction()
|
||||
|
||||
void MacroActionTimer::LogAction() const
|
||||
{
|
||||
if (!_macro.get()) {
|
||||
auto macro = _macro.GetMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
switch (_actionType) {
|
||||
case TimerAction::PAUSE:
|
||||
vblog(LOG_INFO, "paused timers on \"%s\"",
|
||||
_macro->Name().c_str());
|
||||
macro->Name().c_str());
|
||||
break;
|
||||
case TimerAction::CONTINUE:
|
||||
vblog(LOG_INFO, "continued timers on \"%s\"",
|
||||
_macro->Name().c_str());
|
||||
macro->Name().c_str());
|
||||
break;
|
||||
case TimerAction::RESET:
|
||||
vblog(LOG_INFO, "reset timers on \"%s\"",
|
||||
_macro->Name().c_str());
|
||||
macro->Name().c_str());
|
||||
break;
|
||||
case TimerAction::SET_TIME_REMAINING:
|
||||
vblog(LOG_INFO,
|
||||
"set time remaining of timers on \"%s\" to \"%s\"",
|
||||
_macro->Name().c_str(), _duration.ToString().c_str());
|
||||
macro->Name().c_str(), _duration.ToString().c_str());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -105,10 +107,7 @@ bool MacroActionTimer::Load(obs_data_t *obj)
|
||||
|
||||
std::string MacroActionTimer::GetShortDesc() const
|
||||
{
|
||||
if (_macro.get()) {
|
||||
return _macro->Name();
|
||||
}
|
||||
return "";
|
||||
return _macro.Name();
|
||||
}
|
||||
|
||||
static inline void populateTypeSelection(QComboBox *list)
|
||||
@@ -130,12 +129,8 @@ MacroActionTimerEdit::MacroActionTimerEdit(
|
||||
|
||||
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(MacroChanged(const QString &)));
|
||||
QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this,
|
||||
SLOT(MacroRemove(const QString &)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_timerAction, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionTypeChanged(int)));
|
||||
|
||||
@@ -160,7 +155,7 @@ void MacroActionTimerEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_macros->SetCurrentMacro(_entryData->_macro.get());
|
||||
_macros->SetCurrentMacro(_entryData->_macro);
|
||||
_duration->SetDuration(_entryData->_duration);
|
||||
_timerAction->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_actionType));
|
||||
@@ -188,24 +183,14 @@ void MacroActionTimerEdit::SetWidgetVisibility()
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void MacroActionTimerEdit::DurationChanged(double seconds)
|
||||
void MacroActionTimerEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroActionTimerEdit::DurationUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.displayUnit = unit;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionTimerEdit::MacroChanged(const QString &text)
|
||||
@@ -215,14 +200,7 @@ void MacroActionTimerEdit::MacroChanged(const QString &text)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_macro.UpdateRef(text);
|
||||
_entryData->_macro = text;
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroActionTimerEdit::MacroRemove(const QString &)
|
||||
{
|
||||
if (_entryData) {
|
||||
_entryData->_macro.UpdateRef();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,9 +52,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void MacroChanged(const QString &text);
|
||||
void MacroRemove(const QString &name);
|
||||
void DurationChanged(double value);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
void DurationChanged(const Duration &value);
|
||||
void ActionTypeChanged(int value);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -29,7 +29,8 @@ void MacroActionTransition::SetSceneTransition()
|
||||
obs_source_release(t);
|
||||
}
|
||||
if (_setDuration) {
|
||||
obs_frontend_set_transition_duration(_duration.seconds * 1000);
|
||||
obs_frontend_set_transition_duration(_duration.Seconds() *
|
||||
1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ void MacroActionTransition::SetTransitionOverride()
|
||||
}
|
||||
if (_setDuration) {
|
||||
obs_data_set_int(data, "transition_duration",
|
||||
_duration.seconds * 1000);
|
||||
_duration.Milliseconds());
|
||||
}
|
||||
obs_data_release(data);
|
||||
obs_source_release(scene);
|
||||
@@ -91,7 +92,7 @@ void MacroActionTransition::SetSourceTransition(bool show)
|
||||
}
|
||||
if (_setDuration) {
|
||||
obs_sceneitem_set_transition_duration(
|
||||
item, show, _duration.seconds * 1000);
|
||||
item, show, _duration.Milliseconds());
|
||||
}
|
||||
obs_sceneitem_release(item);
|
||||
}
|
||||
@@ -230,8 +231,8 @@ MacroActionTransitionEdit::MacroActionTransitionEdit(
|
||||
SIGNAL(TransitionChanged(const TransitionSelection &)),
|
||||
this,
|
||||
SLOT(TransitionChanged(const TransitionSelection &)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_setTransition, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(SetTransitionChanged(int)));
|
||||
QWidget::connect(_setDuration, SIGNAL(stateChanged(int)), this,
|
||||
@@ -334,14 +335,14 @@ void MacroActionTransitionEdit::TransitionChanged(const TransitionSelection &t)
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroActionTransitionEdit::DurationChanged(double seconds)
|
||||
void MacroActionTransitionEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionTransitionEdit::SetWidgetVisibility()
|
||||
|
||||
@@ -70,7 +70,7 @@ private slots:
|
||||
void SetTransitionChanged(int state);
|
||||
void SetDurationChanged(int state);
|
||||
void TransitionChanged(const TransitionSelection &);
|
||||
void DurationChanged(double seconds);
|
||||
void DurationChanged(const Duration &seconds);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "macro-action-variable.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "math-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
const std::string MacroActionVariable::id = "variable";
|
||||
@@ -29,6 +30,10 @@ static std::map<MacroActionVariable::Type, std::string> actionTypes = {
|
||||
"AdvSceneSwitcher.action.variable.type.roundToInt"},
|
||||
{MacroActionVariable::Type::SUBSTRING,
|
||||
"AdvSceneSwitcher.action.variable.type.subString"},
|
||||
{MacroActionVariable::Type::FIND_AND_REPLACE,
|
||||
"AdvSceneSwitcher.action.variable.type.findAndReplace"},
|
||||
{MacroActionVariable::Type::MATH_EXPRESSION,
|
||||
"AdvSceneSwitcher.action.variable.type.mathExpression"},
|
||||
};
|
||||
|
||||
static void apppend(Variable &var, const std::string &value)
|
||||
@@ -39,14 +44,14 @@ static void apppend(Variable &var, const std::string &value)
|
||||
|
||||
static void modifyNumValue(Variable &var, double val, const bool increment)
|
||||
{
|
||||
double current;
|
||||
if (!var.DoubleValue(current)) {
|
||||
auto current = var.DoubleValue();
|
||||
if (!current.has_value()) {
|
||||
return;
|
||||
}
|
||||
if (increment) {
|
||||
var.SetValue(current + val);
|
||||
var.SetValue(*current + val);
|
||||
} else {
|
||||
var.SetValue(current - val);
|
||||
var.SetValue(*current - val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,9 +100,26 @@ void MacroActionVariable::HandleRegexSubString(Variable *var)
|
||||
var->SetValue(match.captured(0).toStdString());
|
||||
}
|
||||
|
||||
void MacroActionVariable::HandleFindAndReplace(Variable *var)
|
||||
{
|
||||
auto value = var->Value();
|
||||
replaceAll(value, _findStr, _replaceStr);
|
||||
var->SetValue(value);
|
||||
}
|
||||
|
||||
void MacroActionVariable::HandleMathExpression(Variable *var)
|
||||
{
|
||||
auto result = EvalMathExpression(_mathExpression);
|
||||
if (std::holds_alternative<std::string>(result)) {
|
||||
blog(LOG_WARNING, "%s", std::get<std::string>(result).c_str());
|
||||
return;
|
||||
}
|
||||
var->SetValue(std::get<double>(result));
|
||||
}
|
||||
|
||||
bool MacroActionVariable::PerformAction()
|
||||
{
|
||||
auto var = GetVariableByName(_variableName);
|
||||
auto var = _variable.lock();
|
||||
if (!var) {
|
||||
return true;
|
||||
}
|
||||
@@ -110,7 +132,7 @@ bool MacroActionVariable::PerformAction()
|
||||
apppend(*var, _strValue);
|
||||
break;
|
||||
case Type::APPEND_VAR: {
|
||||
auto var2 = GetVariableByName(_variable2Name);
|
||||
auto var2 = _variable2.lock();
|
||||
if (!var2) {
|
||||
return true;
|
||||
}
|
||||
@@ -140,19 +162,27 @@ bool MacroActionVariable::PerformAction()
|
||||
break;
|
||||
}
|
||||
case Type::ROUND_TO_INT: {
|
||||
double curValue;
|
||||
if (!var->DoubleValue(curValue)) {
|
||||
auto curValue = var->DoubleValue();
|
||||
if (!curValue.has_value()) {
|
||||
return true;
|
||||
}
|
||||
var->SetValue(std::to_string(int(std::round(curValue))));
|
||||
var->SetValue(std::to_string(int(std::round(*curValue))));
|
||||
return true;
|
||||
}
|
||||
case Type::SUBSTRING: {
|
||||
if (_regex.Enabled()) {
|
||||
HandleRegexSubString(var);
|
||||
HandleRegexSubString(var.get());
|
||||
return true;
|
||||
}
|
||||
HandleIndexSubString(var);
|
||||
HandleIndexSubString(var.get());
|
||||
return true;
|
||||
}
|
||||
case Type::FIND_AND_REPLACE: {
|
||||
HandleFindAndReplace(var.get());
|
||||
return true;
|
||||
}
|
||||
case Type::MATH_EXPRESSION: {
|
||||
HandleMathExpression(var.get());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -163,8 +193,10 @@ bool MacroActionVariable::PerformAction()
|
||||
bool MacroActionVariable::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_string(obj, "variableName", _variableName.c_str());
|
||||
obs_data_set_string(obj, "variable2Name", _variable2Name.c_str());
|
||||
obs_data_set_string(obj, "variableName",
|
||||
GetWeakVariableName(_variable).c_str());
|
||||
obs_data_set_string(obj, "variable2Name",
|
||||
GetWeakVariableName(_variable2).c_str());
|
||||
obs_data_set_string(obj, "strValue", _strValue.c_str());
|
||||
obs_data_set_double(obj, "numValue", _numValue);
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_type));
|
||||
@@ -173,15 +205,20 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
|
||||
obs_data_set_int(obj, "subStringSize", _subStringSize);
|
||||
obs_data_set_string(obj, "regexPattern", _regexPattern.c_str());
|
||||
obs_data_set_int(obj, "regexMatchIdx", _regexMatchIdx);
|
||||
obs_data_set_string(obj, "findStr", _findStr.c_str());
|
||||
obs_data_set_string(obj, "replaceStr", _replaceStr.c_str());
|
||||
_regex.Save(obj);
|
||||
_mathExpression.Save(obj, "mathExpression");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroActionVariable::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_variableName = obs_data_get_string(obj, "variableName");
|
||||
_variable2Name = obs_data_get_string(obj, "variable2Name");
|
||||
_variable =
|
||||
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
|
||||
_variable2 = GetWeakVariableByName(
|
||||
obs_data_get_string(obj, "variable2Name"));
|
||||
_strValue = obs_data_get_string(obj, "strValue");
|
||||
_numValue = obs_data_get_double(obj, "numValue");
|
||||
_type = static_cast<Type>(obs_data_get_int(obj, "condition"));
|
||||
@@ -191,6 +228,9 @@ bool MacroActionVariable::Load(obs_data_t *obj)
|
||||
_regex.Load(obj);
|
||||
_regexPattern = obs_data_get_string(obj, "regexPattern");
|
||||
_regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx");
|
||||
_findStr = obs_data_get_string(obj, "findStr");
|
||||
_replaceStr = obs_data_get_string(obj, "replaceStr");
|
||||
_mathExpression.Load(obj, "mathExpression");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -202,7 +242,7 @@ bool MacroActionVariable::PostLoad()
|
||||
|
||||
std::string MacroActionVariable::GetShortDesc() const
|
||||
{
|
||||
return _variableName;
|
||||
return GetWeakVariableName(_variable);
|
||||
}
|
||||
|
||||
void MacroActionVariable::SetSegmentIndexValue(int value)
|
||||
@@ -303,7 +343,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
_subStringSize(new QSpinBox()),
|
||||
_regex(new RegexConfigWidget(parent)),
|
||||
_regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
||||
_regexMatchIdx(new QSpinBox())
|
||||
_regexMatchIdx(new QSpinBox()),
|
||||
_findReplaceLayout(new QHBoxLayout()),
|
||||
_findStr(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
||||
_replaceStr(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
||||
_mathExpression(new VariableLineEdit(this)),
|
||||
_mathExpressionResult(new QLabel())
|
||||
{
|
||||
_numValue->setMinimum(-9999999999);
|
||||
_numValue->setMaximum(9999999999);
|
||||
@@ -348,6 +393,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
SLOT(RegexPatternChanged()));
|
||||
QWidget::connect(_regexMatchIdx, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(RegexMatchIdxChanged(int)));
|
||||
QWidget::connect(_findStr, SIGNAL(textChanged()), this,
|
||||
SLOT(FindStrValueChanged()));
|
||||
QWidget::connect(_replaceStr, SIGNAL(textChanged()), this,
|
||||
SLOT(ReplaceStrValueChanged()));
|
||||
QWidget::connect(_mathExpression, SIGNAL(editingFinished()), this,
|
||||
SLOT(MathExpressionChanged()));
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{variables}}", _variables},
|
||||
@@ -359,6 +410,9 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
{"{{subStringStart}}", _subStringStart},
|
||||
{"{{subStringSize}}", _subStringSize},
|
||||
{"{{regexMatchIdx}}", _regexMatchIdx},
|
||||
{"{{findStr}}", _findStr},
|
||||
{"{{replaceStr}}", _replaceStr},
|
||||
{"{{mathExpression}}", _mathExpression},
|
||||
};
|
||||
auto entryLayout = new QHBoxLayout;
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"),
|
||||
@@ -374,6 +428,11 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
"AdvSceneSwitcher.action.variable.entry.substringRegex"),
|
||||
_subStringRegexEntryLayout, widgetPlaceholders);
|
||||
|
||||
placeWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.entry.findAndReplace"),
|
||||
_findReplaceLayout, widgetPlaceholders, false);
|
||||
|
||||
auto regexConfigLayout = new QHBoxLayout;
|
||||
regexConfigLayout->addWidget(_regex);
|
||||
regexConfigLayout->addStretch();
|
||||
@@ -388,6 +447,8 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
layout->addLayout(_substringLayout);
|
||||
layout->addWidget(_segmentValueStatus);
|
||||
layout->addWidget(_segmentValue);
|
||||
layout->addLayout(_findReplaceLayout);
|
||||
layout->addWidget(_mathExpressionResult);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
@@ -406,8 +467,8 @@ void MacroActionVariableEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_variables->SetVariable(_entryData->_variableName);
|
||||
_variables2->SetVariable(_entryData->_variable2Name);
|
||||
_variables->SetVariable(_entryData->_variable);
|
||||
_variables2->SetVariable(_entryData->_variable2);
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_type));
|
||||
_strValue->setPlainText(QString::fromStdString(_entryData->_strValue));
|
||||
_numValue->setValue(_entryData->_numValue);
|
||||
@@ -418,6 +479,10 @@ void MacroActionVariableEdit::UpdateEntryData()
|
||||
_regexPattern->setPlainText(
|
||||
QString::fromStdString(_entryData->_regexPattern));
|
||||
_regexMatchIdx->setValue(_entryData->_regexMatchIdx + 1);
|
||||
_findStr->setPlainText(QString::fromStdString(_entryData->_findStr));
|
||||
_replaceStr->setPlainText(
|
||||
QString::fromStdString(_entryData->_replaceStr));
|
||||
_mathExpression->setText(_entryData->_mathExpression);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -428,7 +493,7 @@ void MacroActionVariableEdit::VariableChanged(const QString &text)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_variableName = text.toStdString();
|
||||
_entryData->_variable = GetWeakVariableByQString(text);
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::Variable2Changed(const QString &text)
|
||||
@@ -438,7 +503,7 @@ void MacroActionVariableEdit::Variable2Changed(const QString &text)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_variable2Name = text.toStdString();
|
||||
_entryData->_variable2 = GetWeakVariableByQString(text);
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::ActionChanged(int value)
|
||||
@@ -467,6 +532,7 @@ void MacroActionVariableEdit::StrValueChanged()
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_strValue = _strValue->toPlainText().toStdString();
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::NumValueChanged(double val)
|
||||
@@ -623,6 +689,7 @@ void MacroActionVariableEdit::RegexPatternChanged()
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_regexPattern = _regexPattern->toPlainText().toStdString();
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::RegexMatchIdxChanged(int val)
|
||||
@@ -635,6 +702,52 @@ void MacroActionVariableEdit::RegexMatchIdxChanged(int val)
|
||||
_entryData->_regexMatchIdx = val - 1;
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::FindStrValueChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_findStr = _findStr->toPlainText().toStdString();
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::ReplaceStrValueChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_replaceStr = _replaceStr->toPlainText().toStdString();
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::MathExpressionChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_mathExpression = _mathExpression->text().toStdString();
|
||||
|
||||
// In case of invalid expression display an error
|
||||
auto result = EvalMathExpression(_entryData->_mathExpression);
|
||||
auto hasError = std::holds_alternative<std::string>(result);
|
||||
if (hasError) {
|
||||
_mathExpressionResult->setText(
|
||||
QString::fromStdString(std::get<std::string>(result)));
|
||||
}
|
||||
_mathExpressionResult->setVisible(hasError);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::MarkSelectedSegment()
|
||||
{
|
||||
if (switcher->disableHints) {
|
||||
@@ -710,6 +823,12 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
||||
setLayoutVisible(_subStringRegexEntryLayout, showRegex);
|
||||
_regexPattern->setVisible(showRegex);
|
||||
}
|
||||
setLayoutVisible(_findReplaceLayout,
|
||||
_entryData->_type ==
|
||||
MacroActionVariable::Type::FIND_AND_REPLACE);
|
||||
_mathExpression->setVisible(_entryData->_type ==
|
||||
MacroActionVariable::Type::MATH_EXPRESSION);
|
||||
_mathExpressionResult->hide();
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "resizing-text-edit.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "variable.hpp"
|
||||
#include "resizing-text-edit.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
|
||||
class MacroActionVariable : public MacroAction {
|
||||
public:
|
||||
@@ -31,11 +31,13 @@ public:
|
||||
SET_ACTION_VALUE,
|
||||
ROUND_TO_INT,
|
||||
SUBSTRING,
|
||||
FIND_AND_REPLACE,
|
||||
MATH_EXPRESSION,
|
||||
};
|
||||
|
||||
Type _type = Type::SET_FIXED_VALUE;
|
||||
std::string _variableName = "";
|
||||
std::string _variable2Name = "";
|
||||
std::weak_ptr<Variable> _variable;
|
||||
std::weak_ptr<Variable> _variable2;
|
||||
std::string _strValue = "";
|
||||
double _numValue = 0;
|
||||
int _subStringStart = 0;
|
||||
@@ -43,11 +45,19 @@ public:
|
||||
RegexConfig _regex = RegexConfig::PartialMatchRegexConfig();
|
||||
std::string _regexPattern = ".*";
|
||||
int _regexMatchIdx = 0;
|
||||
std::string _findStr = obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.findAndReplace.find");
|
||||
std::string _replaceStr = obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.findAndReplace.replace");
|
||||
StringVariable _mathExpression = obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.mathExpression.example");
|
||||
|
||||
private:
|
||||
void DecrementCurrentSegmentVariableRef();
|
||||
void HandleIndexSubString(Variable *);
|
||||
void HandleRegexSubString(Variable *);
|
||||
void HandleFindAndReplace(Variable *);
|
||||
void HandleMathExpression(Variable *);
|
||||
|
||||
std::weak_ptr<MacroSegment> _macroSegment;
|
||||
int _segmentIdxLoadValue = -1;
|
||||
@@ -85,6 +95,9 @@ private slots:
|
||||
void RegexChanged(RegexConfig conf);
|
||||
void RegexPatternChanged();
|
||||
void RegexMatchIdxChanged(int val);
|
||||
void FindStrValueChanged();
|
||||
void ReplaceStrValueChanged();
|
||||
void MathExpressionChanged();
|
||||
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
@@ -106,6 +119,11 @@ protected:
|
||||
RegexConfigWidget *_regex;
|
||||
ResizingPlainTextEdit *_regexPattern;
|
||||
QSpinBox *_regexMatchIdx;
|
||||
QHBoxLayout *_findReplaceLayout;
|
||||
ResizingPlainTextEdit *_findStr;
|
||||
ResizingPlainTextEdit *_replaceStr;
|
||||
VariableLineEdit *_mathExpression;
|
||||
QLabel *_mathExpressionResult;
|
||||
std::shared_ptr<MacroActionVariable> _entryData;
|
||||
|
||||
private:
|
||||
|
||||
@@ -34,14 +34,14 @@ bool MacroActionWait::PerformAction()
|
||||
{
|
||||
double sleepDuration;
|
||||
if (_waitType == WaitType::FIXED) {
|
||||
sleepDuration = _duration.seconds;
|
||||
sleepDuration = _duration.Seconds();
|
||||
} else {
|
||||
double min = (_duration.seconds < _duration2.seconds)
|
||||
? _duration.seconds
|
||||
: _duration2.seconds;
|
||||
double max = (_duration.seconds < _duration2.seconds)
|
||||
? _duration2.seconds
|
||||
: _duration.seconds;
|
||||
double min = (_duration.Seconds() < _duration2.Seconds())
|
||||
? _duration.Seconds()
|
||||
: _duration2.Seconds();
|
||||
double max = (_duration.Seconds() < _duration2.Seconds())
|
||||
? _duration2.Seconds()
|
||||
: _duration.Seconds();
|
||||
std::uniform_real_distribution<double> unif(min, max);
|
||||
sleepDuration = unif(re);
|
||||
}
|
||||
@@ -62,8 +62,9 @@ bool MacroActionWait::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
_duration.Save(obj);
|
||||
_duration2.Save(obj, "seconds2", "displayUnit2");
|
||||
_duration2.Save(obj, "duration2");
|
||||
obs_data_set_int(obj, "waitType", static_cast<int>(_waitType));
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,7 +72,14 @@ bool MacroActionWait::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_duration.Load(obj);
|
||||
_duration2.Load(obj, "seconds2", "displayUnit2");
|
||||
// TODO: remove this fallback
|
||||
if (obs_data_get_int(obj, "version") == 1) {
|
||||
_duration2.Load(obj, "duration2");
|
||||
} else {
|
||||
_duration2.Load(obj, "seconds2");
|
||||
_duration2.SetUnit(static_cast<Duration::Unit>(
|
||||
obs_data_get_int(obj, "displayUnit2")));
|
||||
}
|
||||
_waitType = static_cast<WaitType>(obs_data_get_int(obj, "waitType"));
|
||||
return true;
|
||||
}
|
||||
@@ -93,14 +101,10 @@ MacroActionWaitEdit::MacroActionWaitEdit(
|
||||
|
||||
populateTypeSelection(_waitType);
|
||||
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_duration2, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(Duration2Changed(double)));
|
||||
QWidget::connect(_duration2, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(Duration2UnitChanged(DurationUnit)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_duration2, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(Duration2Changed(const Duration &)));
|
||||
QWidget::connect(_waitType, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(TypeChanged(int)));
|
||||
|
||||
@@ -180,42 +184,22 @@ void MacroActionWaitEdit::TypeChanged(int value)
|
||||
_entryData->_waitType = type;
|
||||
}
|
||||
|
||||
void MacroActionWaitEdit::DurationChanged(double seconds)
|
||||
void MacroActionWaitEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionWaitEdit::DurationUnitChanged(DurationUnit unit)
|
||||
void MacroActionWaitEdit::Duration2Changed(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.displayUnit = unit;
|
||||
}
|
||||
|
||||
void MacroActionWaitEdit::Duration2Changed(double seconds)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration2.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroActionWaitEdit::Duration2UnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration2.displayUnit = unit;
|
||||
_entryData->_duration2 = dur;
|
||||
}
|
||||
|
||||
@@ -49,10 +49,8 @@ public:
|
||||
}
|
||||
|
||||
private slots:
|
||||
void DurationChanged(double value);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
void Duration2Changed(double value);
|
||||
void Duration2UnitChanged(DurationUnit unit);
|
||||
void DurationChanged(const Duration &value);
|
||||
void Duration2Changed(const Duration &value);
|
||||
void TypeChanged(int value);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -18,7 +18,7 @@ static std::map<MacroActionWebsocket::Type, std::string> actionTypes = {
|
||||
|
||||
void MacroActionWebsocket::SendRequest()
|
||||
{
|
||||
auto connection = GetConnectionByName(_connection);
|
||||
auto connection = _connection.lock();
|
||||
if (!connection) {
|
||||
return;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ void MacroActionWebsocket::LogAction() const
|
||||
switch (_type) {
|
||||
case MacroActionWebsocket::Type::REQUEST:
|
||||
vblog(LOG_INFO, "sent msg \"%s\" via \"%s\"", _message.c_str(),
|
||||
_connection.c_str());
|
||||
GetWeakConnectionName(_connection).c_str());
|
||||
break;
|
||||
case MacroActionWebsocket::Type::EVENT:
|
||||
vblog(LOG_INFO, "sent event \"%s\" to connected clients",
|
||||
@@ -62,7 +62,8 @@ bool MacroActionWebsocket::Save(obs_data_t *obj) const
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_int(obj, "type", static_cast<int>(_type));
|
||||
_message.Save(obj, "message");
|
||||
obs_data_set_string(obj, "connection", _connection.c_str());
|
||||
obs_data_set_string(obj, "connection",
|
||||
GetWeakConnectionName(_connection).c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,14 +72,15 @@ bool MacroActionWebsocket::Load(obs_data_t *obj)
|
||||
MacroAction::Load(obj);
|
||||
_type = static_cast<Type>(obs_data_get_int(obj, "type"));
|
||||
_message.Load(obj, "message");
|
||||
_connection = obs_data_get_string(obj, "connection");
|
||||
_connection =
|
||||
GetWeakConnectionByName(obs_data_get_string(obj, "connection"));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroActionWebsocket::GetShortDesc() const
|
||||
{
|
||||
if (_type == Type::REQUEST) {
|
||||
return _connection;
|
||||
return GetWeakConnectionName(_connection);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -206,6 +208,6 @@ void MacroActionWebsocketEdit::ConnectionSelectionChanged(
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_connection = connection.toStdString();
|
||||
_entryData->_connection = GetWeakConnectionByQString(connection);
|
||||
emit(HeaderInfoChanged(connection));
|
||||
}
|
||||
|
||||
@@ -28,9 +28,8 @@ public:
|
||||
};
|
||||
|
||||
Type _type = Type::REQUEST;
|
||||
VariableResolvingString _message =
|
||||
obs_module_text("AdvSceneSwitcher.enterText");
|
||||
std::string _connection;
|
||||
StringVariable _message = obs_module_text("AdvSceneSwitcher.enterText");
|
||||
std::weak_ptr<Connection> _connection;
|
||||
|
||||
private:
|
||||
void SendRequest();
|
||||
|
||||
@@ -29,9 +29,10 @@ MacroRefAction::MacroRefAction(Macro *m, bool supportsVariableValue)
|
||||
{
|
||||
}
|
||||
|
||||
void MacroRefAction::ResolveMacroRef()
|
||||
bool MacroRefAction::PostLoad()
|
||||
{
|
||||
_macro.UpdateRef();
|
||||
_macro.PostLoad();
|
||||
return true;
|
||||
}
|
||||
|
||||
MultiMacroRefAction::MultiMacroRefAction(Macro *m, bool supportsVariableValue)
|
||||
@@ -39,9 +40,10 @@ MultiMacroRefAction::MultiMacroRefAction(Macro *m, bool supportsVariableValue)
|
||||
{
|
||||
}
|
||||
|
||||
void MultiMacroRefAction::ResolveMacroRef()
|
||||
bool MultiMacroRefAction::PostLoad()
|
||||
{
|
||||
for (auto &m : _macros) {
|
||||
m.UpdateRef();
|
||||
for (auto ¯o : _macros) {
|
||||
macro.PostLoad();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,13 +15,15 @@ public:
|
||||
class MacroRefAction : virtual public MacroAction {
|
||||
public:
|
||||
MacroRefAction(Macro *m, bool supportsVariableValue = false);
|
||||
void ResolveMacroRef();
|
||||
bool PostLoad() override;
|
||||
|
||||
MacroRef _macro;
|
||||
};
|
||||
|
||||
class MultiMacroRefAction : virtual public MacroAction {
|
||||
public:
|
||||
MultiMacroRefAction(Macro *m, bool supportsVariableValue = false);
|
||||
void ResolveMacroRef();
|
||||
bool PostLoad() override;
|
||||
|
||||
std::vector<MacroRef> _macros;
|
||||
};
|
||||
|
||||
@@ -205,15 +205,16 @@ bool MacroConditionAudio::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
_audioSource.Save(obj, "audioSource");
|
||||
obs_data_set_int(obj, "volume", _volume);
|
||||
obs_data_set_int(obj, "syncOffset", _syncOffset);
|
||||
obs_data_set_int(obj, "monitor", _monitorType);
|
||||
obs_data_set_double(obj, "balance", _balance);
|
||||
_volume.Save(obj, "volume");
|
||||
_syncOffset.Save(obj, "syncOffset");
|
||||
_balance.Save(obj, "balance");
|
||||
obs_data_set_int(obj, "checkType", static_cast<int>(_checkType));
|
||||
obs_data_set_int(obj, "outputCondition",
|
||||
static_cast<int>(_outputCondition));
|
||||
obs_data_set_int(obj, "volumeCondition",
|
||||
static_cast<int>(_volumeCondition));
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -238,11 +239,17 @@ bool MacroConditionAudio::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_audioSource.Load(obj, "audioSource");
|
||||
_volume = obs_data_get_int(obj, "volume");
|
||||
_syncOffset = obs_data_get_int(obj, "syncOffset");
|
||||
_monitorType = static_cast<obs_monitoring_type>(
|
||||
obs_data_get_int(obj, "monitor"));
|
||||
_balance = obs_data_get_double(obj, "balance");
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
_volume = obs_data_get_int(obj, "volume");
|
||||
_syncOffset = obs_data_get_int(obj, "syncOffset");
|
||||
_balance = obs_data_get_double(obj, "balance");
|
||||
} else {
|
||||
_volume.Load(obj, "volume");
|
||||
_syncOffset.Load(obj, "syncOffset");
|
||||
_balance.Load(obj, "balance");
|
||||
}
|
||||
_checkType = static_cast<Type>(obs_data_get_int(obj, "checkType"));
|
||||
_outputCondition = static_cast<OutputCondition>(
|
||||
obs_data_get_int(obj, "outputCondition"));
|
||||
@@ -320,8 +327,8 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||
_checkTypes(new QComboBox()),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_condition(new QComboBox()),
|
||||
_volume(new QSpinBox()),
|
||||
_syncOffset(new QSpinBox()),
|
||||
_volume(new VariableSpinBox()),
|
||||
_syncOffset(new VariableSpinBox()),
|
||||
_monitorTypes(new QComboBox),
|
||||
_balance(new SliderSpinBox(0., 1., ""))
|
||||
{
|
||||
@@ -339,14 +346,21 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||
|
||||
QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(CheckTypeChanged(int)));
|
||||
QWidget::connect(_volume, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(VolumeThresholdChanged(int)));
|
||||
QWidget::connect(_syncOffset, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(SyncOffsetChanged(int)));
|
||||
QWidget::connect(
|
||||
_volume,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this,
|
||||
SLOT(VolumeThresholdChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(
|
||||
_syncOffset,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(SyncOffsetChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(MonitorTypeChanged(int)));
|
||||
QWidget::connect(_balance, SIGNAL(DoubleValueChanged(double)), this,
|
||||
SLOT(BalanceChanged(double)));
|
||||
QWidget::connect(
|
||||
_balance,
|
||||
SIGNAL(DoubleValueChanged(const NumberVariable<double> &)),
|
||||
this, SLOT(BalanceChanged(const NumberVariable<double> &)));
|
||||
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_sources,
|
||||
@@ -391,8 +405,8 @@ void MacroConditionAudioEdit::UpdateVolmeterSource()
|
||||
layout->addWidget(_volMeter);
|
||||
|
||||
QWidget::connect(_volMeter->GetSlider(), SIGNAL(valueChanged(int)),
|
||||
_volume, SLOT(setValue(int)));
|
||||
QWidget::connect(_volume, SIGNAL(valueChanged(int)),
|
||||
_volume, SLOT(SetFixedValue(int)));
|
||||
QWidget::connect(_volume, SIGNAL(FixedValueChanged(int)),
|
||||
_volMeter->GetSlider(), SLOT(setValue(int)));
|
||||
|
||||
// Slider will default to 0 so set it manually once
|
||||
@@ -405,16 +419,19 @@ void MacroConditionAudioEdit::SourceChanged(const SourceSelection &source)
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_audioSource = source;
|
||||
_entryData->ResetVolmeter();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_audioSource = source;
|
||||
_entryData->ResetVolmeter();
|
||||
}
|
||||
UpdateVolmeterSource();
|
||||
SetWidgetVisibility();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionAudioEdit::VolumeThresholdChanged(int vol)
|
||||
void MacroConditionAudioEdit::VolumeThresholdChanged(
|
||||
const NumberVariable<int> &vol)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -424,7 +441,7 @@ void MacroConditionAudioEdit::VolumeThresholdChanged(int vol)
|
||||
_entryData->_volume = vol;
|
||||
}
|
||||
|
||||
void MacroConditionAudioEdit::SyncOffsetChanged(int value)
|
||||
void MacroConditionAudioEdit::SyncOffsetChanged(const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -444,7 +461,7 @@ void MacroConditionAudioEdit::MonitorTypeChanged(int value)
|
||||
_entryData->_monitorType = static_cast<obs_monitoring_type>(value);
|
||||
}
|
||||
|
||||
void MacroConditionAudioEdit::BalanceChanged(double value)
|
||||
void MacroConditionAudioEdit::BalanceChanged(const NumberVariable<double> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -504,8 +521,8 @@ void MacroConditionAudioEdit::UpdateEntryData()
|
||||
}
|
||||
|
||||
_sources->SetSource(_entryData->_audioSource);
|
||||
_volume->setValue(_entryData->_volume);
|
||||
_syncOffset->setValue(_entryData->_syncOffset);
|
||||
_volume->SetValue(_entryData->_volume);
|
||||
_syncOffset->SetValue(_entryData->_syncOffset);
|
||||
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
||||
_balance->SetDoubleValue(_entryData->_balance);
|
||||
_checkTypes->setCurrentIndex(_checkTypes->findData(
|
||||
|
||||
@@ -50,10 +50,10 @@ public:
|
||||
};
|
||||
|
||||
SourceSelection _audioSource;
|
||||
int _volume = 0;
|
||||
int64_t _syncOffset = 0;
|
||||
NumberVariable<int> _volume = 0;
|
||||
NumberVariable<int> _syncOffset = 0;
|
||||
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
||||
double _balance = 0.5;
|
||||
NumberVariable<double> _balance = 0.5;
|
||||
Type _checkType = Type::OUTPUT_VOLUME;
|
||||
OutputCondition _outputCondition = OutputCondition::ABOVE;
|
||||
VolumeCondition _volumeCondition = VolumeCondition::ABOVE;
|
||||
@@ -90,12 +90,12 @@ public:
|
||||
|
||||
private slots:
|
||||
void SourceChanged(const SourceSelection &);
|
||||
void VolumeThresholdChanged(int vol);
|
||||
void VolumeThresholdChanged(const NumberVariable<int> &vol);
|
||||
void ConditionChanged(int cond);
|
||||
void CheckTypeChanged(int cond);
|
||||
void SyncOffsetChanged(int value);
|
||||
void SyncOffsetChanged(const NumberVariable<int> &value);
|
||||
void MonitorTypeChanged(int value);
|
||||
void BalanceChanged(double value);
|
||||
void BalanceChanged(const NumberVariable<double> &value);
|
||||
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
@@ -104,8 +104,8 @@ protected:
|
||||
QComboBox *_checkTypes;
|
||||
SourceSelectionWidget *_sources;
|
||||
QComboBox *_condition;
|
||||
QSpinBox *_volume;
|
||||
QSpinBox *_syncOffset;
|
||||
VariableSpinBox *_volume;
|
||||
VariableSpinBox *_syncOffset;
|
||||
QComboBox *_monitorTypes;
|
||||
SliderSpinBox *_balance;
|
||||
VolControl *_volMeter = nullptr;
|
||||
|
||||
@@ -77,10 +77,11 @@ bool MacroConditionCursor::Save(obs_data_t *obj) const
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
obs_data_set_int(obj, "button", static_cast<int>(_button));
|
||||
obs_data_set_int(obj, "minX", _minX);
|
||||
obs_data_set_int(obj, "minY", _minY);
|
||||
obs_data_set_int(obj, "maxX", _maxX);
|
||||
obs_data_set_int(obj, "maxY", _maxY);
|
||||
_minX.Save(obj, "minX");
|
||||
_minY.Save(obj, "minY");
|
||||
_maxX.Save(obj, "maxX");
|
||||
_maxY.Save(obj, "maxY");
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -89,10 +90,17 @@ bool MacroConditionCursor::Load(obs_data_t *obj)
|
||||
MacroCondition::Load(obj);
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
_button = static_cast<Button>(obs_data_get_int(obj, "button"));
|
||||
_minX = obs_data_get_int(obj, "minX");
|
||||
_minY = obs_data_get_int(obj, "minY");
|
||||
_maxX = obs_data_get_int(obj, "maxX");
|
||||
_maxY = obs_data_get_int(obj, "maxY");
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
_minX = obs_data_get_int(obj, "minX");
|
||||
_minY = obs_data_get_int(obj, "minY");
|
||||
_maxX = obs_data_get_int(obj, "maxX");
|
||||
_maxY = obs_data_get_int(obj, "maxY");
|
||||
} else {
|
||||
_minX.Load(obj, "minX");
|
||||
_minY.Load(obj, "minY");
|
||||
_maxX.Load(obj, "maxX");
|
||||
_maxY.Load(obj, "maxY");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,10 +123,10 @@ static inline void populateButtonSelection(QComboBox *list)
|
||||
MacroConditionCursorEdit::MacroConditionCursorEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionCursor> entryData)
|
||||
: QWidget(parent),
|
||||
_minX(new QSpinBox()),
|
||||
_minY(new QSpinBox()),
|
||||
_maxX(new QSpinBox()),
|
||||
_maxY(new QSpinBox()),
|
||||
_minX(new VariableSpinBox()),
|
||||
_minY(new VariableSpinBox()),
|
||||
_maxX(new VariableSpinBox()),
|
||||
_maxY(new VariableSpinBox()),
|
||||
_conditions(new QComboBox()),
|
||||
_buttons(new QComboBox()),
|
||||
_frameToggle(new QPushButton(obs_module_text(
|
||||
@@ -151,14 +159,22 @@ MacroConditionCursorEdit::MacroConditionCursorEdit(
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_buttons, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ButtonChanged(int)));
|
||||
QWidget::connect(_minX, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(MinXChanged(int)));
|
||||
QWidget::connect(_minY, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(MinYChanged(int)));
|
||||
QWidget::connect(_maxX, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(MaxXChanged(int)));
|
||||
QWidget::connect(_maxY, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(MaxYChanged(int)));
|
||||
QWidget::connect(
|
||||
_minX,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(MinXChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(
|
||||
_minY,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(MinYChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(
|
||||
_maxX,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(MaxXChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(
|
||||
_maxY,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(MaxYChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_frameToggle, SIGNAL(clicked()), this,
|
||||
SLOT(ToggleFrame()));
|
||||
|
||||
@@ -217,7 +233,7 @@ void MacroConditionCursorEdit::ButtonChanged(int index)
|
||||
_buttons->itemData(index).toInt());
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::MinXChanged(int pos)
|
||||
void MacroConditionCursorEdit::MinXChanged(const NumberVariable<int> &pos)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -228,7 +244,7 @@ void MacroConditionCursorEdit::MinXChanged(int pos)
|
||||
SetupFrame();
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::MinYChanged(int pos)
|
||||
void MacroConditionCursorEdit::MinYChanged(const NumberVariable<int> &pos)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -239,7 +255,7 @@ void MacroConditionCursorEdit::MinYChanged(int pos)
|
||||
SetupFrame();
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::MaxXChanged(int pos)
|
||||
void MacroConditionCursorEdit::MaxXChanged(const NumberVariable<int> &pos)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -250,7 +266,7 @@ void MacroConditionCursorEdit::MaxXChanged(int pos)
|
||||
SetupFrame();
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::MaxYChanged(int pos)
|
||||
void MacroConditionCursorEdit::MaxYChanged(const NumberVariable<int> &pos)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -334,18 +350,20 @@ void MacroConditionCursorEdit::SetupFrame()
|
||||
Qt::WindowStaysOnTopHint);
|
||||
_frame.setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
|
||||
if (_entryData) {
|
||||
QRect rect(_entryData->_minX, _entryData->_minY,
|
||||
_entryData->_maxX - _entryData->_minX,
|
||||
_entryData->_maxY - _entryData->_minY);
|
||||
|
||||
if (rect.size().height() == 0 || rect.size().width() == 0) {
|
||||
_frame.setGeometry(0, 0, 1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
_frame.setGeometry(getScreenUnionRect().intersected(rect));
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
QRect rect(_entryData->_minX, _entryData->_minY,
|
||||
_entryData->_maxX - _entryData->_minX,
|
||||
_entryData->_maxY - _entryData->_minY);
|
||||
|
||||
if (rect.size().height() <= 0 || rect.size().width() <= 0) {
|
||||
_frame.setGeometry(0, 0, 1, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
_frame.setGeometry(getScreenUnionRect().intersected(rect));
|
||||
}
|
||||
|
||||
void MacroConditionCursorEdit::UpdateEntryData()
|
||||
@@ -356,9 +374,9 @@ void MacroConditionCursorEdit::UpdateEntryData()
|
||||
|
||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_buttons->setCurrentIndex(static_cast<int>(_entryData->_button));
|
||||
_minX->setValue(_entryData->_minX);
|
||||
_minY->setValue(_entryData->_minY);
|
||||
_maxX->setValue(_entryData->_maxX);
|
||||
_maxY->setValue(_entryData->_maxY);
|
||||
_minX->SetValue(_entryData->_minX);
|
||||
_minY->SetValue(_entryData->_minY);
|
||||
_maxX->SetValue(_entryData->_maxX);
|
||||
_maxY->SetValue(_entryData->_maxY);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
#include "macro.hpp"
|
||||
#include "striped-frame.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
|
||||
#include <QSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
#include <QFrame>
|
||||
|
||||
class MacroConditionCursor : public MacroCondition {
|
||||
public:
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
|
||||
Condition _condition = Condition::REGION;
|
||||
Button _button = Button::LEFT;
|
||||
int _minX = 0, _minY = 0, _maxX = 0, _maxY = 0;
|
||||
NumberVariable<int> _minX = 0, _minY = 0, _maxX = 0, _maxY = 0;
|
||||
|
||||
private:
|
||||
bool CheckClick();
|
||||
@@ -62,18 +63,18 @@ public:
|
||||
private slots:
|
||||
void ConditionChanged(int idx);
|
||||
void ButtonChanged(int idx);
|
||||
void MinXChanged(int pos);
|
||||
void MinYChanged(int pos);
|
||||
void MaxXChanged(int pos);
|
||||
void MaxYChanged(int pos);
|
||||
void MinXChanged(const NumberVariable<int> &pos);
|
||||
void MinYChanged(const NumberVariable<int> &pos);
|
||||
void MaxXChanged(const NumberVariable<int> &pos);
|
||||
void MaxYChanged(const NumberVariable<int> &pos);
|
||||
void UpdateCursorPos();
|
||||
void ToggleFrame();
|
||||
|
||||
protected:
|
||||
QSpinBox *_minX;
|
||||
QSpinBox *_minY;
|
||||
QSpinBox *_maxX;
|
||||
QSpinBox *_maxY;
|
||||
VariableSpinBox *_minX;
|
||||
VariableSpinBox *_minY;
|
||||
VariableSpinBox *_maxX;
|
||||
VariableSpinBox *_maxY;
|
||||
QComboBox *_conditions;
|
||||
QComboBox *_buttons;
|
||||
QPushButton *_frameToggle;
|
||||
@@ -86,6 +87,6 @@ private:
|
||||
void SetWidgetVisibility();
|
||||
void SetupFrame();
|
||||
QTimer _timer;
|
||||
QFrame _frame;
|
||||
StripedFrame _frame;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
@@ -165,8 +165,8 @@ bool MacroConditionDate::CheckRegularDate(int64_t msSinceLastCheck)
|
||||
}
|
||||
|
||||
if (match && _repeat) {
|
||||
_dateTime = _dateTime.addSecs(_duration.seconds);
|
||||
_dateTime2 = _dateTime2.addSecs(_duration.seconds);
|
||||
_dateTime = _dateTime.addSecs(_duration.Seconds());
|
||||
_dateTime2 = _dateTime2.addSecs(_duration.Seconds());
|
||||
}
|
||||
|
||||
return match;
|
||||
@@ -398,10 +398,8 @@ MacroConditionDateEdit::MacroConditionDateEdit(
|
||||
SLOT(RepeatChanged(int)));
|
||||
QWidget::connect(_updateOnRepeat, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(UpdateOnRepeatChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_advancedSettingsTooggle, SIGNAL(clicked()), this,
|
||||
SLOT(AdvancedSettingsToggleClicked()));
|
||||
QWidget::connect(_pattern, SIGNAL(editingFinished()), this,
|
||||
@@ -589,24 +587,14 @@ void MacroConditionDateEdit::UpdateOnRepeatChanged(int state)
|
||||
_entryData->_updateOnRepeat = state;
|
||||
}
|
||||
|
||||
void MacroConditionDateEdit::DurationChanged(double seconds)
|
||||
void MacroConditionDateEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroConditionDateEdit::DurationUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.displayUnit = unit;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroConditionDateEdit::AdvancedSettingsToggleClicked()
|
||||
|
||||
@@ -100,8 +100,7 @@ private slots:
|
||||
void IgnoreTimeChanged(int state);
|
||||
void RepeatChanged(int state);
|
||||
void UpdateOnRepeatChanged(int state);
|
||||
void DurationChanged(double seconds);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
void DurationChanged(const Duration &seconds);
|
||||
void AdvancedSettingsToggleClicked();
|
||||
void ShowNextMatch();
|
||||
void UpdateCurrentTime();
|
||||
|
||||
@@ -121,15 +121,14 @@ DurationModifierEdit::DurationModifierEdit(QWidget *parent)
|
||||
_duration = new DurationSelection(parent);
|
||||
_toggle = new QPushButton(parent);
|
||||
_toggle->setMaximumWidth(22);
|
||||
_toggle->setIcon(
|
||||
QIcon(QString::fromStdString(getDataFilePath("res/time.svg"))));
|
||||
const auto path = QString::fromStdString(getDataFilePath(
|
||||
"res/images/" + GetThemeTypeName() + "Time.svg"));
|
||||
_toggle->setIcon(QIcon(path));
|
||||
populateDurationModifierTypes(_condition);
|
||||
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(_ModifierChanged(int)));
|
||||
QObject::connect(_duration, &DurationSelection::DurationChanged, this,
|
||||
&DurationModifierEdit::DurationChanged);
|
||||
QObject::connect(_duration, &DurationSelection::UnitChanged, this,
|
||||
&DurationModifierEdit::UnitChanged);
|
||||
QWidget::connect(_toggle, SIGNAL(clicked()), this,
|
||||
SLOT(ToggleClicked()));
|
||||
|
||||
@@ -150,11 +149,6 @@ void DurationModifierEdit::SetValue(DurationModifier &value)
|
||||
_duration->setVisible(value.GetType() != DurationModifier::Type::NONE);
|
||||
}
|
||||
|
||||
void DurationModifierEdit::SetUnit(DurationUnit u)
|
||||
{
|
||||
_duration->SetUnit(u);
|
||||
}
|
||||
|
||||
void DurationModifierEdit::SetDuration(const Duration &d)
|
||||
{
|
||||
_duration->SetDuration(d);
|
||||
@@ -195,10 +189,8 @@ MacroConditionEdit::MacroConditionEdit(
|
||||
QWidget::connect(_conditionSelection,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(ConditionSelectionChanged(const QString &)));
|
||||
QWidget::connect(_dur, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_dur, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_dur, SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_dur, SIGNAL(ModifierChanged(DurationModifier::Type)),
|
||||
this,
|
||||
SLOT(DurationModifierChanged(DurationModifier::Type)));
|
||||
@@ -324,7 +316,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
|
||||
SetFocusPolicyOfWidgets();
|
||||
}
|
||||
|
||||
void MacroConditionEdit::DurationChanged(double seconds)
|
||||
void MacroConditionEdit::DurationChanged(const Duration &seconds)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -344,16 +336,6 @@ void MacroConditionEdit::DurationModifierChanged(DurationModifier::Type m)
|
||||
(*_entryData)->SetDurationModifier(m);
|
||||
}
|
||||
|
||||
void MacroConditionEdit::DurationUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
(*_entryData)->SetDurationUnit(unit);
|
||||
}
|
||||
|
||||
std::shared_ptr<MacroSegment> MacroConditionEdit::Data()
|
||||
{
|
||||
return *_entryData;
|
||||
@@ -375,7 +357,7 @@ void AdvSceneSwitcher::AddMacroCondition(int idx)
|
||||
if (idx >= 1) {
|
||||
id = macro->Conditions().at(idx - 1)->GetId();
|
||||
if (idx == 1) {
|
||||
logic = LogicType::NONE;
|
||||
logic = LogicType::OR;
|
||||
} else {
|
||||
logic = macro->Conditions().at(idx - 1)->GetLogicType();
|
||||
}
|
||||
|
||||
@@ -35,15 +35,13 @@ class DurationModifierEdit : public QWidget {
|
||||
public:
|
||||
DurationModifierEdit(QWidget *parent = nullptr);
|
||||
void SetValue(DurationModifier &value);
|
||||
void SetUnit(DurationUnit u);
|
||||
void SetDuration(const Duration &d);
|
||||
|
||||
private slots:
|
||||
void _ModifierChanged(int value);
|
||||
void ToggleClicked();
|
||||
signals:
|
||||
void DurationChanged(double value);
|
||||
void UnitChanged(DurationUnit u);
|
||||
void DurationChanged(const Duration &value);
|
||||
void ModifierChanged(DurationModifier::Type value);
|
||||
|
||||
private:
|
||||
@@ -69,9 +67,8 @@ public:
|
||||
private slots:
|
||||
void LogicSelectionChanged(int idx);
|
||||
void ConditionSelectionChanged(const QString &text);
|
||||
void DurationChanged(double seconds);
|
||||
void DurationChanged(const Duration &value);
|
||||
void DurationModifierChanged(DurationModifier::Type m);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
|
||||
private:
|
||||
void SetLogicSelection();
|
||||
|
||||
@@ -65,7 +65,8 @@ bool MacroConditionFile::MatchFileContent(QString &filedata)
|
||||
|
||||
bool MacroConditionFile::CheckRemoteFileContent()
|
||||
{
|
||||
std::string data = getRemoteData(_file);
|
||||
std::string path = _file;
|
||||
std::string data = getRemoteData(path);
|
||||
SetVariableValue(data);
|
||||
QString qdata = QString::fromStdString(data);
|
||||
return MatchFileContent(qdata);
|
||||
@@ -99,7 +100,8 @@ bool MacroConditionFile::CheckChangeContent()
|
||||
QString filedata;
|
||||
switch (_fileType) {
|
||||
case FileType::LOCAL: {
|
||||
QFile file(QString::fromStdString(_file));
|
||||
std::string path = _file;
|
||||
QFile file(QString::fromStdString(path));
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
@@ -107,7 +109,8 @@ bool MacroConditionFile::CheckChangeContent()
|
||||
file.close();
|
||||
} break;
|
||||
case FileType::REMOTE: {
|
||||
std::string data = getRemoteData(_file);
|
||||
std::string path = _file;
|
||||
std::string data = getRemoteData(path);
|
||||
QString filedata = QString::fromStdString(data);
|
||||
} break;
|
||||
default:
|
||||
@@ -166,7 +169,7 @@ bool MacroConditionFile::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
_regex.Save(obj);
|
||||
obs_data_set_string(obj, "file", _file.c_str());
|
||||
_file.Save(obj, "file");
|
||||
_text.Save(obj, "text");
|
||||
obs_data_set_int(obj, "fileType", static_cast<int>(_fileType));
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
@@ -184,7 +187,7 @@ bool MacroConditionFile::Load(obs_data_t *obj)
|
||||
_regex.CreateBackwardsCompatibleRegex(
|
||||
obs_data_get_bool(obj, "useRegex"));
|
||||
}
|
||||
_file = obs_data_get_string(obj, "file");
|
||||
_file.Load(obj, "file");
|
||||
_text.Load(obj, "text");
|
||||
_fileType = static_cast<FileType>(obs_data_get_int(obj, "fileType"));
|
||||
_condition =
|
||||
@@ -196,7 +199,7 @@ bool MacroConditionFile::Load(obs_data_t *obj)
|
||||
|
||||
std::string MacroConditionFile::GetShortDesc() const
|
||||
{
|
||||
return _file;
|
||||
return _file.UnresolvedValue();
|
||||
}
|
||||
|
||||
static void populateFileTypes(QComboBox *list)
|
||||
@@ -292,7 +295,7 @@ void MacroConditionFileEdit::UpdateEntryData()
|
||||
|
||||
_fileTypes->setCurrentIndex(static_cast<int>(_entryData->_fileType));
|
||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_filePath->SetPath(QString::fromStdString(_entryData->_file));
|
||||
_filePath->SetPath(_entryData->_file);
|
||||
_matchText->setPlainText(_entryData->_text);
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
_checkModificationDate->setChecked(_entryData->_useTime);
|
||||
|
||||
@@ -35,9 +35,8 @@ public:
|
||||
DATE_CHANGE,
|
||||
};
|
||||
|
||||
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
VariableResolvingString _text =
|
||||
obs_module_text("AdvSceneSwitcher.enterText");
|
||||
StringVariable _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
StringVariable _text = obs_module_text("AdvSceneSwitcher.enterText");
|
||||
FileType _fileType = FileType::LOCAL;
|
||||
ConditionType _condition = ConditionType::MATCH;
|
||||
RegexConfig _regex;
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
SourceSelection _source;
|
||||
OBSWeakSource _filter;
|
||||
Condition _condition = Condition::ENABLED;
|
||||
VariableResolvingString _settings = "";
|
||||
StringVariable _settings = "";
|
||||
RegexConfig _regex;
|
||||
|
||||
private:
|
||||
|
||||
@@ -14,7 +14,7 @@ bool MacroConditionIdle::CheckCondition()
|
||||
{
|
||||
auto seconds = secondsSinceLastInput();
|
||||
SetVariableValue(std::to_string(seconds));
|
||||
return seconds >= _duration.seconds;
|
||||
return seconds >= _duration.Seconds();
|
||||
}
|
||||
|
||||
bool MacroConditionIdle::Save(obs_data_t *obj) const
|
||||
@@ -37,10 +37,8 @@ MacroConditionIdleEdit::MacroConditionIdleEdit(
|
||||
{
|
||||
_duration = new DurationSelection();
|
||||
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
@@ -55,24 +53,14 @@ MacroConditionIdleEdit::MacroConditionIdleEdit(
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionIdleEdit::DurationChanged(double seconds)
|
||||
void MacroConditionIdleEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroConditionIdleEdit::DurationUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.displayUnit = unit;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroConditionIdleEdit::UpdateEntryData()
|
||||
|
||||
@@ -41,8 +41,7 @@ public:
|
||||
}
|
||||
|
||||
private slots:
|
||||
void DurationChanged(double seconds);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
void DurationChanged(const Duration &seconds);
|
||||
|
||||
protected:
|
||||
DurationSelection *_duration;
|
||||
|
||||
@@ -44,11 +44,12 @@ bool MacroConditionMacro::CheckStateCondition()
|
||||
// Note:
|
||||
// Depending on the order the macro conditions are checked Matched() might
|
||||
// still return the state of the previous interval
|
||||
if (!_macro.get()) {
|
||||
auto macro = _macro.GetMacro();
|
||||
if (!macro) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return _macro->Matched();
|
||||
return macro->Matched();
|
||||
}
|
||||
|
||||
bool MacroConditionMacro::CheckMultiStateCondition()
|
||||
@@ -57,8 +58,9 @@ bool MacroConditionMacro::CheckMultiStateCondition()
|
||||
// Depending on the order the macro conditions are checked Matched() might
|
||||
// still return the state of the previous interval
|
||||
int matchedCount = 0;
|
||||
for (const auto ¯o : _macros) {
|
||||
if (!macro.get()) {
|
||||
for (const auto &m : _macros) {
|
||||
auto macro = m.GetMacro();
|
||||
if (!macro) {
|
||||
continue;
|
||||
}
|
||||
if (macro->Matched()) {
|
||||
@@ -82,17 +84,18 @@ bool MacroConditionMacro::CheckMultiStateCondition()
|
||||
|
||||
bool MacroConditionMacro::CheckCountCondition()
|
||||
{
|
||||
if (!_macro.get()) {
|
||||
auto macro = _macro.GetMacro();
|
||||
if (!macro) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (_counterCondition) {
|
||||
case CounterCondition::BELOW:
|
||||
return _macro->RunCount() < _count;
|
||||
return macro->RunCount() < _count;
|
||||
case CounterCondition::ABOVE:
|
||||
return _macro->RunCount() > _count;
|
||||
return macro->RunCount() > _count;
|
||||
case CounterCondition::EQUAL:
|
||||
return _macro->RunCount() == _count;
|
||||
return macro->RunCount() == _count;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -123,10 +126,11 @@ bool MacroConditionMacro::Save(obs_data_t *obj) const
|
||||
_macro.Save(obj);
|
||||
obs_data_set_int(obj, "type", static_cast<int>(_type));
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_counterCondition));
|
||||
obs_data_set_int(obj, "count", _count);
|
||||
obs_data_set_int(obj, "multiStateCount", _multiSateCount);
|
||||
_count.Save(obj, "count");
|
||||
_multiSateCount.Save(obj, "multiStateCount");
|
||||
obs_data_set_int(obj, "multiStateCondition",
|
||||
static_cast<int>(_multiSateCondition));
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -138,8 +142,6 @@ bool MacroConditionMacro::Load(obs_data_t *obj)
|
||||
_type = static_cast<Type>(obs_data_get_int(obj, "type"));
|
||||
_counterCondition = static_cast<CounterCondition>(
|
||||
obs_data_get_int(obj, "condition"));
|
||||
_count = obs_data_get_int(obj, "count");
|
||||
_multiSateCount = obs_data_get_int(obj, "multiStateCount");
|
||||
// TODO: Remove this fallback in future version
|
||||
if (!obs_data_has_user_value(obj, "multiStateCondition")) {
|
||||
_multiSateCondition = MultiStateCondition::ABOVE;
|
||||
@@ -147,15 +149,27 @@ bool MacroConditionMacro::Load(obs_data_t *obj)
|
||||
_multiSateCondition = static_cast<MultiStateCondition>(
|
||||
obs_data_get_int(obj, "multiStateCondition"));
|
||||
}
|
||||
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
_count = obs_data_get_int(obj, "count");
|
||||
_multiSateCount = obs_data_get_int(obj, "multiStateCount");
|
||||
} else {
|
||||
_count.Load(obj, "count");
|
||||
_multiSateCount.Load(obj, "multiStateCount");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionMacro::PostLoad()
|
||||
{
|
||||
return MacroRefCondition::PostLoad() &&
|
||||
MultiMacroRefCondtition::PostLoad();
|
||||
}
|
||||
|
||||
std::string MacroConditionMacro::GetShortDesc() const
|
||||
{
|
||||
if (_macro.get()) {
|
||||
return _macro->Name();
|
||||
}
|
||||
return "";
|
||||
return _macro.Name();
|
||||
}
|
||||
|
||||
static inline void populateTypeSelection(QComboBox *list)
|
||||
@@ -183,19 +197,19 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionMacro> entryData)
|
||||
: QWidget(parent),
|
||||
_macros(new MacroSelection(parent)),
|
||||
_types(new QComboBox(parent)),
|
||||
_counterConditions(new QComboBox(parent)),
|
||||
_count(new QSpinBox(parent)),
|
||||
_currentCount(new QLabel(parent)),
|
||||
_types(new QComboBox()),
|
||||
_counterConditions(new QComboBox()),
|
||||
_count(new VariableSpinBox()),
|
||||
_currentCount(new QLabel()),
|
||||
_pausedWarning(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.macro.pausedWarning"))),
|
||||
_resetCount(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.macro.count.reset"))),
|
||||
_settingsLine1(new QHBoxLayout),
|
||||
_settingsLine2(new QHBoxLayout),
|
||||
_settingsLine1(new QHBoxLayout()),
|
||||
_settingsLine2(new QHBoxLayout()),
|
||||
_macroList(new MacroList(this, false, false)),
|
||||
_multiStateConditions(new QComboBox(parent)),
|
||||
_multiStateCount(new QSpinBox(parent))
|
||||
_multiStateConditions(new QComboBox()),
|
||||
_multiStateCount(new VariableSpinBox())
|
||||
{
|
||||
_count->setMaximum(10000000);
|
||||
populateTypeSelection(_types);
|
||||
@@ -210,8 +224,10 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
|
||||
SLOT(TypeChanged(int)));
|
||||
QWidget::connect(_counterConditions, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(CountConditionChanged(int)));
|
||||
QWidget::connect(_count, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(CountChanged(int)));
|
||||
QWidget::connect(
|
||||
_count,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(CountChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_resetCount, SIGNAL(clicked()), this,
|
||||
SLOT(ResetClicked()));
|
||||
QWidget::connect(_macroList, SIGNAL(Added(const std::string &)), this,
|
||||
@@ -223,10 +239,13 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
|
||||
QWidget::connect(_multiStateConditions,
|
||||
SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(MultiStateConditionChanged(int)));
|
||||
QWidget::connect(_multiStateCount, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(MultiStateCountChanged(int)));
|
||||
QWidget::connect(
|
||||
_multiStateCount,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this,
|
||||
SLOT(MultiStateCountChanged(const NumberVariable<int> &)));
|
||||
|
||||
auto typesLayout = new QHBoxLayout;
|
||||
auto typesLayout = new QHBoxLayout();
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{types}}", _types},
|
||||
};
|
||||
@@ -234,7 +253,7 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
|
||||
"AdvSceneSwitcher.condition.macro.type.selection"),
|
||||
typesLayout, widgetPlaceholders);
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->addLayout(typesLayout);
|
||||
mainLayout->addLayout(_settingsLine1);
|
||||
mainLayout->addLayout(_settingsLine2);
|
||||
@@ -244,11 +263,13 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
|
||||
|
||||
_entryData = entryData;
|
||||
|
||||
connect(&_countTimer, SIGNAL(timeout()), this, SLOT(UpdateCount()));
|
||||
QWidget::connect(&_countTimer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdateCount()));
|
||||
_countTimer.start(1000);
|
||||
|
||||
_pausedWarning->setVisible(false);
|
||||
connect(&_pausedTimer, SIGNAL(timeout()), this, SLOT(UpdatePaused()));
|
||||
QWidget::connect(&_pausedTimer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdatePaused()));
|
||||
_pausedTimer.start(1000);
|
||||
|
||||
UpdateEntryData();
|
||||
@@ -270,6 +291,7 @@ void MacroConditionMacroEdit::ClearLayouts()
|
||||
|
||||
void MacroConditionMacroEdit::SetupStateWidgets()
|
||||
{
|
||||
SetWidgetVisibility();
|
||||
ClearLayouts();
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
@@ -278,12 +300,11 @@ void MacroConditionMacroEdit::SetupStateWidgets()
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.macro.state.entry"),
|
||||
_settingsLine1, widgetPlaceholders);
|
||||
SetWidgetVisibility();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::SetupMultiStateWidgets()
|
||||
{
|
||||
SetWidgetVisibility();
|
||||
ClearLayouts();
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
@@ -294,12 +315,11 @@ void MacroConditionMacroEdit::SetupMultiStateWidgets()
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.macro.multistate.entry"),
|
||||
_settingsLine1, widgetPlaceholders);
|
||||
SetWidgetVisibility();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::SetupCountWidgets()
|
||||
{
|
||||
SetWidgetVisibility();
|
||||
ClearLayouts();
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
@@ -317,8 +337,6 @@ void MacroConditionMacroEdit::SetupCountWidgets()
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.macro.count.entry.line2"),
|
||||
_settingsLine2, widgetPlaceholders);
|
||||
SetWidgetVisibility();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::SetWidgetVisibility()
|
||||
@@ -329,7 +347,6 @@ void MacroConditionMacroEdit::SetWidgetVisibility()
|
||||
_counterConditions->show();
|
||||
_count->show();
|
||||
_currentCount->show();
|
||||
_pausedWarning->show();
|
||||
_resetCount->show();
|
||||
_macroList->hide();
|
||||
_multiStateConditions->hide();
|
||||
@@ -340,7 +357,6 @@ void MacroConditionMacroEdit::SetWidgetVisibility()
|
||||
_counterConditions->hide();
|
||||
_count->hide();
|
||||
_currentCount->hide();
|
||||
_pausedWarning->show();
|
||||
_resetCount->hide();
|
||||
_macroList->hide();
|
||||
_multiStateConditions->hide();
|
||||
@@ -360,6 +376,8 @@ void MacroConditionMacroEdit::SetWidgetVisibility()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::UpdateEntryData()
|
||||
@@ -368,8 +386,7 @@ void MacroConditionMacroEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
auto test = _entryData->_type;
|
||||
switch (test) {
|
||||
switch (_entryData->_type) {
|
||||
case MacroConditionMacro::Type::COUNT:
|
||||
SetupCountWidgets();
|
||||
break;
|
||||
@@ -383,15 +400,15 @@ void MacroConditionMacroEdit::UpdateEntryData()
|
||||
break;
|
||||
}
|
||||
|
||||
_macros->SetCurrentMacro(_entryData->_macro.get());
|
||||
_macros->SetCurrentMacro(_entryData->_macro);
|
||||
_types->setCurrentIndex(static_cast<int>(_entryData->_type));
|
||||
_counterConditions->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_counterCondition));
|
||||
_count->setValue(_entryData->_count);
|
||||
_count->SetValue(_entryData->_count);
|
||||
_macroList->SetContent(_entryData->_macros);
|
||||
_multiStateConditions->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_multiSateCondition));
|
||||
_multiStateCount->setValue(_entryData->_multiSateCount);
|
||||
_multiStateCount->SetValue(_entryData->_multiSateCount);
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::MacroChanged(const QString &text)
|
||||
@@ -401,12 +418,12 @@ void MacroConditionMacroEdit::MacroChanged(const QString &text)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_macro.UpdateRef(text);
|
||||
_entryData->_macro = text;
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::CountChanged(int value)
|
||||
void MacroConditionMacroEdit::CountChanged(const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -433,12 +450,9 @@ void MacroConditionMacroEdit::MacroRemove(const QString &)
|
||||
return;
|
||||
}
|
||||
|
||||
_entryData->_macro.UpdateRef();
|
||||
|
||||
auto it = _entryData->_macros.begin();
|
||||
while (it != _entryData->_macros.end()) {
|
||||
it->UpdateRef();
|
||||
if (it->get() == nullptr) {
|
||||
if (!it->GetMacro()) {
|
||||
it = _entryData->_macros.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
@@ -473,18 +487,26 @@ void MacroConditionMacroEdit::TypeChanged(int type)
|
||||
|
||||
void MacroConditionMacroEdit::ResetClicked()
|
||||
{
|
||||
if (_loading || !_entryData || !_entryData->_macro.get()) {
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_entryData->_macro->ResetRunCount();
|
||||
auto macro = _entryData->_macro.GetMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
macro->ResetRunCount();
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::UpdateCount()
|
||||
{
|
||||
if (_entryData && _entryData->_macro.get()) {
|
||||
_currentCount->setText(
|
||||
QString::number(_entryData->_macro->RunCount()));
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto macro = _entryData->_macro.GetMacro();
|
||||
if (macro) {
|
||||
_currentCount->setText(QString::number(macro->RunCount()));
|
||||
} else {
|
||||
_currentCount->setText("-");
|
||||
}
|
||||
@@ -492,10 +514,11 @@ void MacroConditionMacroEdit::UpdateCount()
|
||||
|
||||
void MacroConditionMacroEdit::UpdatePaused()
|
||||
{
|
||||
auto macro = _entryData->_macro.GetMacro();
|
||||
_pausedWarning->setVisible(
|
||||
_entryData &&
|
||||
_entryData->_type != MacroConditionMacro::Type::MULTI_STATE &&
|
||||
_entryData->_macro.get() && _entryData->_macro->Paused());
|
||||
macro && macro->Paused());
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
@@ -510,7 +533,8 @@ void MacroConditionMacroEdit::MultiStateConditionChanged(int cond)
|
||||
static_cast<MacroConditionMacro::MultiStateCondition>(cond);
|
||||
}
|
||||
|
||||
void MacroConditionMacroEdit::MultiStateCountChanged(int value)
|
||||
void MacroConditionMacroEdit::MultiStateCountChanged(
|
||||
const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "macro.hpp"
|
||||
#include "macro-selection.hpp"
|
||||
#include "macro-list.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QSpinBox>
|
||||
@@ -22,6 +23,7 @@ public:
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
bool PostLoad() override;
|
||||
std::string GetShortDesc() const;
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||
@@ -42,7 +44,7 @@ public:
|
||||
EQUAL,
|
||||
};
|
||||
CounterCondition _counterCondition = CounterCondition::BELOW;
|
||||
int _count = 0;
|
||||
NumberVariable<int> _count = 0;
|
||||
|
||||
enum class MultiStateCondition {
|
||||
BELOW,
|
||||
@@ -50,7 +52,7 @@ public:
|
||||
ABOVE,
|
||||
};
|
||||
MultiStateCondition _multiSateCondition = MultiStateCondition::ABOVE;
|
||||
int _multiSateCount = 0;
|
||||
NumberVariable<int> _multiSateCount = 0;
|
||||
|
||||
private:
|
||||
bool CheckCountCondition();
|
||||
@@ -81,13 +83,13 @@ private slots:
|
||||
void MacroChanged(const QString &text);
|
||||
void MacroRemove(const QString &name);
|
||||
void TypeChanged(int type);
|
||||
void CountChanged(int value);
|
||||
void CountChanged(const NumberVariable<int> &value);
|
||||
void CountConditionChanged(int cond);
|
||||
void ResetClicked();
|
||||
void UpdateCount();
|
||||
void UpdatePaused();
|
||||
void MultiStateConditionChanged(int cond);
|
||||
void MultiStateCountChanged(int value);
|
||||
void MultiStateCountChanged(const NumberVariable<int> &value);
|
||||
void Add(const std::string &);
|
||||
void Remove(int);
|
||||
void Replace(int, const std::string &);
|
||||
@@ -98,7 +100,7 @@ protected:
|
||||
MacroSelection *_macros;
|
||||
QComboBox *_types;
|
||||
QComboBox *_counterConditions;
|
||||
QSpinBox *_count;
|
||||
VariableSpinBox *_count;
|
||||
QLabel *_currentCount;
|
||||
QLabel *_pausedWarning;
|
||||
QPushButton *_resetCount;
|
||||
@@ -106,7 +108,7 @@ protected:
|
||||
QHBoxLayout *_settingsLine2;
|
||||
MacroList *_macroList;
|
||||
QComboBox *_multiStateConditions;
|
||||
QSpinBox *_multiStateCount;
|
||||
VariableSpinBox *_multiStateCount;
|
||||
QTimer _countTimer;
|
||||
QTimer _pausedTimer;
|
||||
std::shared_ptr<MacroConditionMacro> _entryData;
|
||||
|
||||
@@ -71,18 +71,18 @@ bool MacroConditionMedia::CheckTime()
|
||||
match = true;
|
||||
break;
|
||||
case Time::TIME_RESTRICTION_SHORTER:
|
||||
match = currentTime < _time.seconds * 1000;
|
||||
match = currentTime < _time.Milliseconds();
|
||||
break;
|
||||
case Time::TIME_RESTRICTION_LONGER:
|
||||
match = currentTime > _time.seconds * 1000;
|
||||
match = currentTime > _time.Milliseconds();
|
||||
break;
|
||||
case Time::TIME_RESTRICTION_REMAINING_SHORTER:
|
||||
match = duration > currentTime &&
|
||||
duration - currentTime < _time.seconds * 1000;
|
||||
duration - currentTime < _time.Milliseconds();
|
||||
break;
|
||||
case Time::TIME_RESTRICTION_REMAINING_LONGER:
|
||||
match = duration > currentTime &&
|
||||
duration - currentTime > _time.seconds * 1000;
|
||||
duration - currentTime > _time.Milliseconds();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -429,10 +429,8 @@ MacroConditionMediaEdit::MacroConditionMediaEdit(
|
||||
SLOT(StateChanged(int)));
|
||||
QWidget::connect(_timeRestrictions, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(TimeRestrictionChanged(int)));
|
||||
QWidget::connect(_time, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(TimeChanged(double)));
|
||||
QWidget::connect(_time, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(TimeUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_time, SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(TimeChanged(const Duration &)));
|
||||
QWidget::connect(_onChange, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(OnChangeChanged(int)));
|
||||
|
||||
@@ -560,27 +558,14 @@ void MacroConditionMediaEdit::TimeRestrictionChanged(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void MacroConditionMediaEdit::TimeChanged(double seconds)
|
||||
void MacroConditionMediaEdit::TimeChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_time.seconds = seconds;
|
||||
if (_entryData->_sourceType != MacroConditionMedia::Type::SOURCE) {
|
||||
_entryData->UpdateMediaSourcesOfSceneList();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroConditionMediaEdit::TimeUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_time.displayUnit = unit;
|
||||
_entryData->_time = dur;
|
||||
if (_entryData->_sourceType != MacroConditionMedia::Type::SOURCE) {
|
||||
_entryData->UpdateMediaSourcesOfSceneList();
|
||||
}
|
||||
|
||||
@@ -116,8 +116,7 @@ private slots:
|
||||
void SceneChanged(const SceneSelection &);
|
||||
void StateChanged(int index);
|
||||
void TimeRestrictionChanged(int index);
|
||||
void TimeChanged(double seconds);
|
||||
void TimeUnitChanged(DurationUnit unit);
|
||||
void TimeChanged(const Duration &seconds);
|
||||
void OnChangeChanged(int);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -10,41 +10,43 @@ bool MacroConditionStats::_registered = MacroConditionFactory::Register(
|
||||
{MacroConditionStats::Create, MacroConditionStatsEdit::Create,
|
||||
"AdvSceneSwitcher.condition.stats"});
|
||||
|
||||
static std::map<StatsType, std::string> statsTypes = {
|
||||
{StatsType::FPS, "AdvSceneSwitcher.condition.stats.type.fps"},
|
||||
{StatsType::CPU_USAGE,
|
||||
static std::map<MacroConditionStats::Type, std::string> statsTypes = {
|
||||
{MacroConditionStats::Type::FPS,
|
||||
"AdvSceneSwitcher.condition.stats.type.fps"},
|
||||
{MacroConditionStats::Type::CPU_USAGE,
|
||||
"AdvSceneSwitcher.condition.stats.type.CPUUsage"},
|
||||
{StatsType::DISK_USAGE,
|
||||
{MacroConditionStats::Type::DISK_USAGE,
|
||||
"AdvSceneSwitcher.condition.stats.type.HDDSpaceAvailable"},
|
||||
{StatsType::MEM_USAGE,
|
||||
{MacroConditionStats::Type::MEM_USAGE,
|
||||
"AdvSceneSwitcher.condition.stats.type.memoryUsage"},
|
||||
{StatsType::AVG_FRAMETIME,
|
||||
{MacroConditionStats::Type::AVG_FRAMETIME,
|
||||
"AdvSceneSwitcher.condition.stats.type.averageTimeToRender"},
|
||||
{StatsType::RENDER_LAG,
|
||||
{MacroConditionStats::Type::RENDER_LAG,
|
||||
"AdvSceneSwitcher.condition.stats.type.missedFrames"},
|
||||
{StatsType::ENCODE_LAG,
|
||||
{MacroConditionStats::Type::ENCODE_LAG,
|
||||
"AdvSceneSwitcher.condition.stats.type.skippedFrames"},
|
||||
{StatsType::STREAM_DROPPED_FRAMES,
|
||||
{MacroConditionStats::Type::STREAM_DROPPED_FRAMES,
|
||||
"AdvSceneSwitcher.condition.stats.type.droppedFrames.stream"},
|
||||
{StatsType::STREAM_BITRATE,
|
||||
{MacroConditionStats::Type::STREAM_BITRATE,
|
||||
"AdvSceneSwitcher.condition.stats.type.bitrate.stream"},
|
||||
{StatsType::STREAM_MB_SENT,
|
||||
{MacroConditionStats::Type::STREAM_MB_SENT,
|
||||
"AdvSceneSwitcher.condition.stats.type.megabytesSent.stream"},
|
||||
{StatsType::RECORDING_DROPPED_FRAMES,
|
||||
{MacroConditionStats::Type::RECORDING_DROPPED_FRAMES,
|
||||
"AdvSceneSwitcher.condition.stats.type.droppedFrames.recording"},
|
||||
{StatsType::RECORDING_BITRATE,
|
||||
{MacroConditionStats::Type::RECORDING_BITRATE,
|
||||
"AdvSceneSwitcher.condition.stats.type.bitrate.recording"},
|
||||
{StatsType::RECORDING_MB_SENT,
|
||||
{MacroConditionStats::Type::RECORDING_MB_SENT,
|
||||
"AdvSceneSwitcher.condition.stats.type.megabytesSent.recording"},
|
||||
};
|
||||
|
||||
static std::map<StatsCondition, std::string> statsConditionTypes = {
|
||||
{StatsCondition::ABOVE,
|
||||
"AdvSceneSwitcher.condition.stats.condition.above"},
|
||||
{StatsCondition::EQUALS,
|
||||
"AdvSceneSwitcher.condition.stats.condition.equals"},
|
||||
{StatsCondition::BELOW,
|
||||
"AdvSceneSwitcher.condition.stats.condition.below"},
|
||||
static std::map<MacroConditionStats::Condition, std::string>
|
||||
statsConditionTypes = {
|
||||
{MacroConditionStats::Condition::ABOVE,
|
||||
"AdvSceneSwitcher.condition.stats.condition.above"},
|
||||
{MacroConditionStats::Condition::EQUALS,
|
||||
"AdvSceneSwitcher.condition.stats.condition.equals"},
|
||||
{MacroConditionStats::Condition::BELOW,
|
||||
"AdvSceneSwitcher.condition.stats.condition.below"},
|
||||
};
|
||||
|
||||
MacroConditionStats::MacroConditionStats(Macro *m)
|
||||
@@ -60,11 +62,11 @@ MacroConditionStats::~MacroConditionStats()
|
||||
bool MacroConditionStats::CheckFPS()
|
||||
{
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return obs_get_active_fps() > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(obs_get_active_fps(), _value, 0.01);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return obs_get_active_fps() < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -77,11 +79,11 @@ bool MacroConditionStats::CheckCPU()
|
||||
double usage = os_cpu_usage_info_query(_cpu_info);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return usage > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(usage, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return usage < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -95,11 +97,11 @@ bool MacroConditionStats::CheckMemory()
|
||||
(long double)os_get_proc_resident_size() / (1024.0l * 1024.0l);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return rss > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(rss, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return rss < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -112,11 +114,11 @@ bool MacroConditionStats::CheckAvgFrametime()
|
||||
auto num = (long double)obs_get_average_frame_time_ns() / 1000000.0l;
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return num > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(num, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return num < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -142,11 +144,11 @@ bool MacroConditionStats::CheckRenderLag()
|
||||
num *= 100.0l;
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return num > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(num, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return num < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -173,11 +175,11 @@ bool MacroConditionStats::CheckEncodeLag()
|
||||
num *= 100.0l;
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return num > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(num, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return num < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -230,11 +232,11 @@ bool MacroConditionStats::CheckStreamDroppedFrames()
|
||||
obs_output_release(output);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return _streamInfo.dropped_relative > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(_streamInfo.dropped_relative, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return _streamInfo.dropped_relative < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -249,11 +251,11 @@ bool MacroConditionStats::CheckStreamBitrate()
|
||||
obs_output_release(output);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return _streamInfo.kbps > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(_streamInfo.kbps, _value, 1.0);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return _streamInfo.kbps < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -269,11 +271,11 @@ bool MacroConditionStats::CheckStreamMBSent()
|
||||
long double num = (long double)totalBytes / (1024.0l * 1024.0l);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return num > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(num, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return num < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -288,12 +290,12 @@ bool MacroConditionStats::CheckRecordingDroppedFrames()
|
||||
obs_output_release(output);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return _recordingInfo.dropped_relative > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(_recordingInfo.dropped_relative, _value,
|
||||
0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return _recordingInfo.dropped_relative < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -308,11 +310,11 @@ bool MacroConditionStats::CheckRecordingBitrate()
|
||||
obs_output_release(output);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return _recordingInfo.kbps > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(_recordingInfo.kbps, _value, 1.0);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return _recordingInfo.kbps < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -328,11 +330,11 @@ bool MacroConditionStats::CheckRecordingMBSent()
|
||||
long double num = (long double)totalBytes / (1024.0l * 1024.0l);
|
||||
|
||||
switch (_condition) {
|
||||
case StatsCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
return num > _value;
|
||||
case StatsCondition::EQUALS:
|
||||
case Condition::EQUALS:
|
||||
return doubleEquals(num, _value, 0.1);
|
||||
case StatsCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
return num < _value;
|
||||
default:
|
||||
break;
|
||||
@@ -343,32 +345,32 @@ bool MacroConditionStats::CheckRecordingMBSent()
|
||||
bool MacroConditionStats::CheckCondition()
|
||||
{
|
||||
switch (_type) {
|
||||
case StatsType::FPS:
|
||||
case Type::FPS:
|
||||
return CheckFPS();
|
||||
case StatsType::CPU_USAGE:
|
||||
case Type::CPU_USAGE:
|
||||
return CheckCPU();
|
||||
case StatsType::DISK_USAGE:
|
||||
case Type::DISK_USAGE:
|
||||
// TODO: not implemented
|
||||
break;
|
||||
case StatsType::MEM_USAGE:
|
||||
case Type::MEM_USAGE:
|
||||
return CheckMemory();
|
||||
case StatsType::AVG_FRAMETIME:
|
||||
case Type::AVG_FRAMETIME:
|
||||
return CheckAvgFrametime();
|
||||
case StatsType::RENDER_LAG:
|
||||
case Type::RENDER_LAG:
|
||||
return CheckRenderLag();
|
||||
case StatsType::ENCODE_LAG:
|
||||
case Type::ENCODE_LAG:
|
||||
return CheckEncodeLag();
|
||||
case StatsType::STREAM_DROPPED_FRAMES:
|
||||
case Type::STREAM_DROPPED_FRAMES:
|
||||
return CheckStreamDroppedFrames();
|
||||
case StatsType::STREAM_BITRATE:
|
||||
case Type::STREAM_BITRATE:
|
||||
return CheckStreamBitrate();
|
||||
case StatsType::STREAM_MB_SENT:
|
||||
case Type::STREAM_MB_SENT:
|
||||
return CheckStreamMBSent();
|
||||
case StatsType::RECORDING_DROPPED_FRAMES:
|
||||
case Type::RECORDING_DROPPED_FRAMES:
|
||||
return CheckRecordingDroppedFrames();
|
||||
case StatsType::RECORDING_BITRATE:
|
||||
case Type::RECORDING_BITRATE:
|
||||
return CheckRecordingBitrate();
|
||||
case StatsType::RECORDING_MB_SENT:
|
||||
case Type::RECORDING_MB_SENT:
|
||||
return CheckRecordingMBSent();
|
||||
default:
|
||||
break;
|
||||
@@ -380,9 +382,10 @@ bool MacroConditionStats::CheckCondition()
|
||||
bool MacroConditionStats::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_double(obj, "value", _value);
|
||||
_value.Save(obj, "value");
|
||||
obs_data_set_int(obj, "type", static_cast<int>(_type));
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -390,10 +393,14 @@ bool MacroConditionStats::Load(obs_data_t *obj)
|
||||
{
|
||||
|
||||
MacroCondition::Load(obj);
|
||||
_value = obs_data_get_double(obj, "value");
|
||||
_type = static_cast<StatsType>(obs_data_get_int(obj, "type"));
|
||||
_condition =
|
||||
static_cast<StatsCondition>(obs_data_get_int(obj, "condition"));
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
_value = obs_data_get_double(obj, "value");
|
||||
} else {
|
||||
_value.Load(obj, "value");
|
||||
}
|
||||
_type = static_cast<MacroConditionStats::Type>(
|
||||
obs_data_get_int(obj, "type"));
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -412,7 +419,7 @@ static inline void populateStatsTypes(QComboBox *list)
|
||||
for (auto entry : statsTypes) {
|
||||
list->addItem(obs_module_text(entry.second.c_str()));
|
||||
// TODO: not implemented
|
||||
if (entry.first == StatsType::DISK_USAGE) {
|
||||
if (entry.first == MacroConditionStats::Type::DISK_USAGE) {
|
||||
qobject_cast<QListView *>(list->view())
|
||||
->setRowHidden(list->count() - 1, true);
|
||||
}
|
||||
@@ -430,9 +437,9 @@ static inline void populateConditionSelection(QComboBox *list)
|
||||
MacroConditionStatsEdit::MacroConditionStatsEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionStats> entryData)
|
||||
: QWidget(parent),
|
||||
_stats(new QComboBox),
|
||||
_condition(new QComboBox),
|
||||
_value(new QDoubleSpinBox)
|
||||
_stats(new QComboBox()),
|
||||
_condition(new QComboBox()),
|
||||
_value(new VariableDoubleSpinBox())
|
||||
{
|
||||
_value->setMaximum(999999999999);
|
||||
|
||||
@@ -442,8 +449,10 @@ MacroConditionStatsEdit::MacroConditionStatsEdit(
|
||||
setToolTip(
|
||||
obs_module_text("AdvSceneSwitcher.condition.stats.dockHint"));
|
||||
|
||||
QWidget::connect(_value, SIGNAL(valueChanged(double)), this,
|
||||
SLOT(ValueChanged(double)));
|
||||
QWidget::connect(
|
||||
_value,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<double> &)),
|
||||
this, SLOT(ValueChanged(const NumberVariable<double> &)));
|
||||
QWidget::connect(_stats, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(StatsTypeChanged(int)));
|
||||
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
|
||||
@@ -464,7 +473,7 @@ MacroConditionStatsEdit::MacroConditionStatsEdit(
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionStatsEdit::ValueChanged(double value)
|
||||
void MacroConditionStatsEdit::ValueChanged(const NumberVariable<double> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -482,10 +491,11 @@ void MacroConditionStatsEdit::StatsTypeChanged(int type)
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_type = static_cast<StatsType>(type);
|
||||
_entryData->_type =
|
||||
static_cast<MacroConditionStats::Type>(type);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
_value->setValue(0);
|
||||
_value->SetFixedValue(0);
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
@@ -497,7 +507,8 @@ void MacroConditionStatsEdit::ConditionChanged(int cond)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_condition = static_cast<StatsCondition>(cond);
|
||||
_entryData->_condition =
|
||||
static_cast<MacroConditionStats::Condition>(cond);
|
||||
}
|
||||
|
||||
void MacroConditionStatsEdit::UpdateEntryData()
|
||||
@@ -506,7 +517,7 @@ void MacroConditionStatsEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_value->setValue(_entryData->_value);
|
||||
_value->SetValue(_entryData->_value);
|
||||
_stats->setCurrentIndex(static_cast<int>(_entryData->_type));
|
||||
_condition->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
SetWidgetVisibility();
|
||||
@@ -519,55 +530,55 @@ void MacroConditionStatsEdit::SetWidgetVisibility()
|
||||
}
|
||||
|
||||
switch (_entryData->_type) {
|
||||
case StatsType::FPS:
|
||||
case MacroConditionStats::Type::FPS:
|
||||
_value->setMaximum(1000);
|
||||
_value->setSuffix("");
|
||||
break;
|
||||
case StatsType::CPU_USAGE:
|
||||
case MacroConditionStats::Type::CPU_USAGE:
|
||||
_value->setMaximum(100);
|
||||
_value->setSuffix("%");
|
||||
break;
|
||||
case StatsType::DISK_USAGE:
|
||||
case MacroConditionStats::Type::DISK_USAGE:
|
||||
_value->setMaximum(999999999999);
|
||||
_value->setSuffix("MB");
|
||||
break;
|
||||
case StatsType::MEM_USAGE:
|
||||
case MacroConditionStats::Type::MEM_USAGE:
|
||||
_value->setMaximum(999999999999);
|
||||
_value->setSuffix("MB");
|
||||
break;
|
||||
case StatsType::AVG_FRAMETIME:
|
||||
case MacroConditionStats::Type::AVG_FRAMETIME:
|
||||
_value->setMaximum(999999999999);
|
||||
_value->setSuffix("ms");
|
||||
break;
|
||||
case StatsType::RENDER_LAG:
|
||||
case MacroConditionStats::Type::RENDER_LAG:
|
||||
_value->setMaximum(100);
|
||||
_value->setSuffix("%");
|
||||
break;
|
||||
case StatsType::ENCODE_LAG:
|
||||
case MacroConditionStats::Type::ENCODE_LAG:
|
||||
_value->setMaximum(100);
|
||||
_value->setSuffix("%");
|
||||
break;
|
||||
case StatsType::STREAM_DROPPED_FRAMES:
|
||||
case MacroConditionStats::Type::STREAM_DROPPED_FRAMES:
|
||||
_value->setMaximum(100);
|
||||
_value->setSuffix("%");
|
||||
break;
|
||||
case StatsType::STREAM_BITRATE:
|
||||
case MacroConditionStats::Type::STREAM_BITRATE:
|
||||
_value->setMaximum(999999999999);
|
||||
_value->setSuffix("kb/s");
|
||||
break;
|
||||
case StatsType::STREAM_MB_SENT:
|
||||
case MacroConditionStats::Type::STREAM_MB_SENT:
|
||||
_value->setMaximum(999999999999);
|
||||
_value->setSuffix("MB");
|
||||
break;
|
||||
case StatsType::RECORDING_DROPPED_FRAMES:
|
||||
case MacroConditionStats::Type::RECORDING_DROPPED_FRAMES:
|
||||
_value->setMaximum(100);
|
||||
_value->setSuffix("%");
|
||||
break;
|
||||
case StatsType::RECORDING_BITRATE:
|
||||
case MacroConditionStats::Type::RECORDING_BITRATE:
|
||||
_value->setMaximum(999999999999);
|
||||
_value->setSuffix("kb/s");
|
||||
break;
|
||||
case StatsType::RECORDING_MB_SENT:
|
||||
case MacroConditionStats::Type::RECORDING_MB_SENT:
|
||||
_value->setMaximum(999999999999);
|
||||
_value->setSuffix("MB");
|
||||
break;
|
||||
|
||||
@@ -2,31 +2,9 @@
|
||||
#include "macro.hpp"
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <variable-spinbox.hpp>
|
||||
#include <util/platform.h>
|
||||
|
||||
enum class StatsType {
|
||||
FPS,
|
||||
CPU_USAGE,
|
||||
DISK_USAGE, // not implemented
|
||||
MEM_USAGE,
|
||||
AVG_FRAMETIME,
|
||||
RENDER_LAG,
|
||||
ENCODE_LAG,
|
||||
STREAM_DROPPED_FRAMES,
|
||||
STREAM_BITRATE,
|
||||
STREAM_MB_SENT,
|
||||
RECORDING_DROPPED_FRAMES, // not sure if this makes sense
|
||||
RECORDING_BITRATE,
|
||||
RECORDING_MB_SENT,
|
||||
};
|
||||
|
||||
enum class StatsCondition {
|
||||
ABOVE,
|
||||
EQUALS,
|
||||
BELOW,
|
||||
};
|
||||
|
||||
class MacroConditionStats : public MacroCondition {
|
||||
public:
|
||||
MacroConditionStats(Macro *m);
|
||||
@@ -41,9 +19,31 @@ public:
|
||||
return std::make_shared<MacroConditionStats>(m);
|
||||
}
|
||||
|
||||
double _value = 0;
|
||||
StatsType _type = StatsType::FPS;
|
||||
StatsCondition _condition = StatsCondition::ABOVE;
|
||||
NumberVariable<double> _value = 0.0;
|
||||
|
||||
enum class Type {
|
||||
FPS,
|
||||
CPU_USAGE,
|
||||
DISK_USAGE, // not implemented
|
||||
MEM_USAGE,
|
||||
AVG_FRAMETIME,
|
||||
RENDER_LAG,
|
||||
ENCODE_LAG,
|
||||
STREAM_DROPPED_FRAMES,
|
||||
STREAM_BITRATE,
|
||||
STREAM_MB_SENT,
|
||||
RECORDING_DROPPED_FRAMES, // not sure if this makes sense
|
||||
RECORDING_BITRATE,
|
||||
RECORDING_MB_SENT,
|
||||
};
|
||||
Type _type = Type::FPS;
|
||||
|
||||
enum class Condition {
|
||||
ABOVE,
|
||||
EQUALS,
|
||||
BELOW,
|
||||
};
|
||||
Condition _condition = Condition::ABOVE;
|
||||
|
||||
private:
|
||||
bool CheckFPS();
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ValueChanged(double value);
|
||||
void ValueChanged(const NumberVariable<double> &value);
|
||||
void StatsTypeChanged(int type);
|
||||
void ConditionChanged(int cond);
|
||||
|
||||
@@ -108,7 +108,7 @@ signals:
|
||||
protected:
|
||||
QComboBox *_stats;
|
||||
QComboBox *_condition;
|
||||
QDoubleSpinBox *_value;
|
||||
VariableDoubleSpinBox *_value;
|
||||
std::shared_ptr<MacroConditionStats> _entryData;
|
||||
|
||||
private:
|
||||
|
||||
222
src/macro-core/macro-condition-run.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "macro-condition-run.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QDesktopServices>
|
||||
|
||||
const std::string MacroConditionRun::id = "run";
|
||||
|
||||
bool MacroConditionRun::_registered = MacroConditionFactory::Register(
|
||||
MacroConditionRun::id,
|
||||
{MacroConditionRun::Create, MacroConditionRunEdit::Create,
|
||||
"AdvSceneSwitcher.condition.run"});
|
||||
|
||||
MacroConditionRun::~MacroConditionRun()
|
||||
{
|
||||
if (_thread.joinable()) {
|
||||
_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
bool MacroConditionRun::CheckCondition()
|
||||
{
|
||||
if (!_threadDone) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
|
||||
switch (_procStatus) {
|
||||
case MacroConditionRun::Status::FAILED_TO_START:
|
||||
SetVariableValue("Failed to start process");
|
||||
ret = false;
|
||||
break;
|
||||
case MacroConditionRun::Status::TIMEOUT:
|
||||
SetVariableValue("Timeout while running process");
|
||||
ret = false;
|
||||
break;
|
||||
case MacroConditionRun::Status::OK:
|
||||
ret = _checkExitCode ? _exitCode == _procExitCode : true;
|
||||
SetVariableValue(std::to_string(_procExitCode));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (_thread.joinable()) {
|
||||
_thread.join();
|
||||
}
|
||||
_threadDone = false;
|
||||
_thread = std::thread(&MacroConditionRun::RunProcess, this);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MacroConditionRun::RunProcess()
|
||||
{
|
||||
QProcess process;
|
||||
process.setWorkingDirectory(
|
||||
QString::fromStdString(_procConfig.WorkingDir()));
|
||||
process.start(QString::fromStdString(_procConfig.Path()),
|
||||
_procConfig.Args());
|
||||
int timeout = _timeout.Milliseconds();
|
||||
|
||||
vblog(LOG_INFO, "run \"%s\" with a timeout of %d ms",
|
||||
_procConfig.Path().c_str(), timeout);
|
||||
|
||||
bool procFinishedInTime = process.waitForFinished(timeout);
|
||||
|
||||
if (!procFinishedInTime) {
|
||||
if (process.error() == QProcess::FailedToStart) {
|
||||
vblog(LOG_INFO, "failed to start \"%s\"!",
|
||||
_procConfig.Path().c_str());
|
||||
_procStatus = Status::FAILED_TO_START;
|
||||
} else {
|
||||
vblog(LOG_INFO,
|
||||
"timeout while running \"%s\"\nAttempting to kill process!",
|
||||
_procConfig.Path().c_str());
|
||||
process.kill();
|
||||
process.waitForFinished();
|
||||
_procStatus = Status::TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
bool validExitCode = process.exitStatus() == QProcess::NormalExit;
|
||||
|
||||
if ((_checkExitCode && !validExitCode) || !procFinishedInTime) {
|
||||
_threadDone = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_procExitCode = process.exitCode();
|
||||
_procStatus = Status::OK;
|
||||
_threadDone = true;
|
||||
}
|
||||
|
||||
bool MacroConditionRun::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
_procConfig.Save(obj);
|
||||
obs_data_set_bool(obj, "checkExitCode", _checkExitCode);
|
||||
obs_data_set_int(obj, "exitCode", _exitCode);
|
||||
_timeout.Save(obj, "timeout");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionRun::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_procConfig.Load(obj);
|
||||
_checkExitCode = obs_data_get_bool(obj, "checkExitCode");
|
||||
_exitCode = obs_data_get_int(obj, "exitCode");
|
||||
_timeout.Load(obj, "timeout");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionRun::GetShortDesc() const
|
||||
{
|
||||
return _procConfig.UnresolvedPath();
|
||||
}
|
||||
|
||||
MacroConditionRunEdit::MacroConditionRunEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionRun> entryData)
|
||||
: QWidget(parent),
|
||||
_procConfig(new ProcessConfigEdit(this)),
|
||||
_checkExitCode(new QCheckBox()),
|
||||
_exitCode(new QSpinBox()),
|
||||
_timeout(new DurationSelection(this, false, 0.1))
|
||||
{
|
||||
_exitCode->setMinimum(-99999);
|
||||
_exitCode->setMaximum(999999);
|
||||
|
||||
QWidget::connect(_procConfig,
|
||||
SIGNAL(ConfigChanged(const ProcessConfig &)), this,
|
||||
SLOT(ProcessConfigChanged(const ProcessConfig &)));
|
||||
QWidget::connect(_timeout, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(TimeoutChanged(const Duration &)));
|
||||
QWidget::connect(_checkExitCode, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(CheckExitCodeChanged(int)));
|
||||
QWidget::connect(_exitCode, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(ExitCodeChanged(int)));
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{checkExitCode}}", _checkExitCode},
|
||||
{"{{exitCode}}", _exitCode},
|
||||
{"{{timeout}}", _timeout},
|
||||
};
|
||||
|
||||
auto exitLayout = new QHBoxLayout();
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.run.entry.exit"),
|
||||
exitLayout, widgetPlaceholders);
|
||||
auto timeoutLayout = new QHBoxLayout();
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.condition.run.entry"),
|
||||
timeoutLayout, widgetPlaceholders);
|
||||
|
||||
auto *layout = new QVBoxLayout;
|
||||
layout->addLayout(timeoutLayout);
|
||||
layout->addWidget(_procConfig);
|
||||
layout->addLayout(exitLayout);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionRunEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
_procConfig->SetProcessConfig(_entryData->_procConfig);
|
||||
_timeout->SetDuration(_entryData->_timeout);
|
||||
_checkExitCode->setChecked(_entryData->_checkExitCode);
|
||||
_exitCode->setValue(_entryData->_exitCode);
|
||||
}
|
||||
|
||||
void MacroConditionRunEdit::TimeoutChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_timeout = dur;
|
||||
}
|
||||
|
||||
void MacroConditionRunEdit::CheckExitCodeChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_checkExitCode = state;
|
||||
}
|
||||
|
||||
void MacroConditionRunEdit::ExitCodeChanged(int exitCode)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_exitCode = exitCode;
|
||||
}
|
||||
|
||||
void MacroConditionRunEdit::ProcessConfigChanged(const ProcessConfig &conf)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_procConfig = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
79
src/macro-core/macro-condition-run.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
#include "macro.hpp"
|
||||
#include "process-config.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
|
||||
class MacroConditionRun : public MacroCondition {
|
||||
public:
|
||||
MacroConditionRun(Macro *m) : MacroCondition(m, true) {}
|
||||
~MacroConditionRun();
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetShortDesc() const;
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroConditionRun>(m);
|
||||
}
|
||||
|
||||
ProcessConfig _procConfig;
|
||||
bool _checkExitCode = true;
|
||||
int _exitCode = 0;
|
||||
Duration _timeout = Duration(0.1);
|
||||
|
||||
private:
|
||||
enum class Status {
|
||||
NONE,
|
||||
FAILED_TO_START,
|
||||
TIMEOUT,
|
||||
OK,
|
||||
};
|
||||
|
||||
void RunProcess();
|
||||
|
||||
std::thread _thread;
|
||||
std::atomic_bool _threadDone{true};
|
||||
Status _procStatus = Status::NONE;
|
||||
int _procExitCode = 0;
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroConditionRunEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroConditionRunEdit(QWidget *parent,
|
||||
std::shared_ptr<MacroConditionRun> cond = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroCondition> cond)
|
||||
{
|
||||
return new MacroConditionRunEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroConditionRun>(cond));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ProcessConfigChanged(const ProcessConfig &);
|
||||
void TimeoutChanged(const Duration &);
|
||||
void CheckExitCodeChanged(int);
|
||||
void ExitCodeChanged(int);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
protected:
|
||||
ProcessConfigEdit *_procConfig;
|
||||
QCheckBox *_checkExitCode;
|
||||
QSpinBox *_exitCode;
|
||||
DurationSelection *_timeout;
|
||||
std::shared_ptr<MacroConditionRun> _entryData;
|
||||
|
||||
private:
|
||||
bool _loading = true;
|
||||
};
|
||||
@@ -10,13 +10,14 @@ bool MacroConditionSceneOrder::_registered = MacroConditionFactory::Register(
|
||||
{MacroConditionSceneOrder::Create, MacroConditionSceneOrderEdit::Create,
|
||||
"AdvSceneSwitcher.condition.sceneOrder"});
|
||||
|
||||
static std::map<SceneOrderCondition, std::string> sceneOrderConditionTypes = {
|
||||
{SceneOrderCondition::ABOVE,
|
||||
"AdvSceneSwitcher.condition.sceneOrder.type.above"},
|
||||
{SceneOrderCondition::BELOW,
|
||||
"AdvSceneSwitcher.condition.sceneOrder.type.below"},
|
||||
{SceneOrderCondition::POSITION,
|
||||
"AdvSceneSwitcher.condition.sceneOrder.type.position"},
|
||||
static std::map<MacroConditionSceneOrder::Condition, std::string>
|
||||
sceneOrderConditionTypes = {
|
||||
{MacroConditionSceneOrder::Condition::ABOVE,
|
||||
"AdvSceneSwitcher.condition.sceneOrder.type.above"},
|
||||
{MacroConditionSceneOrder::Condition::BELOW,
|
||||
"AdvSceneSwitcher.condition.sceneOrder.type.below"},
|
||||
{MacroConditionSceneOrder::Condition::POSITION,
|
||||
"AdvSceneSwitcher.condition.sceneOrder.type.position"},
|
||||
};
|
||||
|
||||
struct PosInfo2 {
|
||||
@@ -115,13 +116,13 @@ bool MacroConditionSceneOrder::CheckCondition()
|
||||
bool ret = false;
|
||||
|
||||
switch (_condition) {
|
||||
case SceneOrderCondition::ABOVE:
|
||||
case Condition::ABOVE:
|
||||
ret = isAbove(positions1, positions2);
|
||||
break;
|
||||
case SceneOrderCondition::BELOW:
|
||||
case Condition::BELOW:
|
||||
ret = isBelow(positions1, positions2);
|
||||
break;
|
||||
case SceneOrderCondition::POSITION:
|
||||
case Condition::POSITION:
|
||||
for (int p : positions1) {
|
||||
if (p == _position)
|
||||
ret = true;
|
||||
@@ -143,6 +144,8 @@ bool MacroConditionSceneOrder::Save(obs_data_t *obj) const
|
||||
_source2.Save(obj, "sceneItemSelection2");
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
obs_data_set_int(obj, "position", _position);
|
||||
_position.Save(obj, "position");
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -168,9 +171,12 @@ bool MacroConditionSceneOrder::Load(obs_data_t *obj)
|
||||
} else {
|
||||
_source2.Load(obj, "sceneItemSelection2");
|
||||
}
|
||||
_condition = static_cast<SceneOrderCondition>(
|
||||
obs_data_get_int(obj, "condition"));
|
||||
_position = obs_data_get_int(obj, "position");
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
_position = obs_data_get_int(obj, "position");
|
||||
} else {
|
||||
_position.Load(obj, "position");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -181,7 +187,7 @@ std::string MacroConditionSceneOrder::GetShortDesc() const
|
||||
}
|
||||
std::string header = _scene.ToString() + " - " + _source.ToString();
|
||||
if (!_source2.ToString().empty() &&
|
||||
_condition != SceneOrderCondition::POSITION) {
|
||||
_condition != MacroConditionSceneOrder::Condition::POSITION) {
|
||||
header += " - " + _source2.ToString();
|
||||
}
|
||||
return header;
|
||||
@@ -196,19 +202,19 @@ static inline void populateConditionSelection(QComboBox *list)
|
||||
|
||||
MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionSceneOrder> entryData)
|
||||
: QWidget(parent)
|
||||
: QWidget(parent),
|
||||
_scenes(new SceneSelectionWidget(window(), true, false, false, true)),
|
||||
_conditions(new QComboBox()),
|
||||
_sources(new SceneItemSelectionWidget(parent)),
|
||||
_sources2(new SceneItemSelectionWidget(parent)),
|
||||
_position(new VariableSpinBox()),
|
||||
_posInfo(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.sceneOrder.positionInfo")))
|
||||
{
|
||||
_scenes = new SceneSelectionWidget(window(), true, false, false, true);
|
||||
_sources = new SceneItemSelectionWidget(parent);
|
||||
_sources2 = new SceneItemSelectionWidget(parent);
|
||||
_conditions = new QComboBox();
|
||||
_position = new QSpinBox();
|
||||
_posInfo = new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.sceneOrder.positionInfo"));
|
||||
|
||||
populateConditionSelection(_conditions);
|
||||
if (entryData.get()) {
|
||||
if (entryData->_condition == SceneOrderCondition::POSITION) {
|
||||
if (entryData->_condition ==
|
||||
MacroConditionSceneOrder::Condition::POSITION) {
|
||||
_sources->SetPlaceholderType(
|
||||
SceneItemSelectionWidget::Placeholder::ANY);
|
||||
} else {
|
||||
@@ -232,8 +238,10 @@ MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit(
|
||||
SLOT(Source2Changed(const SceneItemSelection &)));
|
||||
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_position, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(PositionChanged(int)));
|
||||
QWidget::connect(
|
||||
_position,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(PositionChanged(const NumberVariable<int> &)));
|
||||
|
||||
auto entryLayout = new QHBoxLayout();
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
@@ -296,11 +304,12 @@ void MacroConditionSceneOrderEdit::ConditionChanged(int index)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_condition =
|
||||
static_cast<SceneOrderCondition>(index);
|
||||
static_cast<MacroConditionSceneOrder::Condition>(index);
|
||||
}
|
||||
SetWidgetVisibility(_entryData->_condition ==
|
||||
SceneOrderCondition::POSITION);
|
||||
if (_entryData->_condition == SceneOrderCondition::POSITION) {
|
||||
MacroConditionSceneOrder::Condition::POSITION);
|
||||
if (_entryData->_condition ==
|
||||
MacroConditionSceneOrder::Condition::POSITION) {
|
||||
_sources->SetPlaceholderType(
|
||||
SceneItemSelectionWidget::Placeholder::ANY);
|
||||
} else {
|
||||
@@ -312,7 +321,8 @@ void MacroConditionSceneOrderEdit::ConditionChanged(int index)
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionSceneOrderEdit::PositionChanged(int value)
|
||||
void MacroConditionSceneOrderEdit::PositionChanged(
|
||||
const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
@@ -339,8 +349,8 @@ void MacroConditionSceneOrderEdit::UpdateEntryData()
|
||||
_scenes->SetScene(_entryData->_scene);
|
||||
_sources->SetSceneItem(_entryData->_source);
|
||||
_sources2->SetSceneItem(_entryData->_source2);
|
||||
_position->setValue(_entryData->_position);
|
||||
_position->SetValue(_entryData->_position);
|
||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
SetWidgetVisibility(_entryData->_condition ==
|
||||
SceneOrderCondition::POSITION);
|
||||
MacroConditionSceneOrder::Condition::POSITION);
|
||||
}
|
||||
|
||||
@@ -2,16 +2,11 @@
|
||||
#include "macro.hpp"
|
||||
#include "scene-selection.hpp"
|
||||
#include "scene-item-selection.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
|
||||
enum class SceneOrderCondition {
|
||||
ABOVE,
|
||||
BELOW,
|
||||
POSITION,
|
||||
};
|
||||
|
||||
class MacroConditionSceneOrder : public MacroCondition {
|
||||
public:
|
||||
MacroConditionSceneOrder(Macro *m) : MacroCondition(m) {}
|
||||
@@ -28,8 +23,14 @@ public:
|
||||
SceneSelection _scene;
|
||||
SceneItemSelection _source;
|
||||
SceneItemSelection _source2;
|
||||
int _position = 0;
|
||||
SceneOrderCondition _condition = SceneOrderCondition::ABOVE;
|
||||
NumberVariable<int> _position = 0;
|
||||
|
||||
enum class Condition {
|
||||
ABOVE,
|
||||
BELOW,
|
||||
POSITION,
|
||||
};
|
||||
Condition _condition = Condition::ABOVE;
|
||||
|
||||
private:
|
||||
static bool _registered;
|
||||
@@ -58,7 +59,7 @@ private slots:
|
||||
void SourceChanged(const SceneItemSelection &);
|
||||
void Source2Changed(const SceneItemSelection &);
|
||||
void ConditionChanged(int cond);
|
||||
void PositionChanged(int cond);
|
||||
void PositionChanged(const NumberVariable<int> &);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
@@ -67,7 +68,7 @@ protected:
|
||||
QComboBox *_conditions;
|
||||
SceneItemSelectionWidget *_sources;
|
||||
SceneItemSelectionWidget *_sources2;
|
||||
QSpinBox *_position;
|
||||
VariableSpinBox *_position;
|
||||
QLabel *_posInfo;
|
||||
|
||||
std::shared_ptr<MacroConditionSceneOrder> _entryData;
|
||||
|
||||
@@ -17,13 +17,15 @@ bool MacroConditionSceneTransform::CheckCondition()
|
||||
bool ret = false;
|
||||
auto items = _source.GetSceneItems(_scene);
|
||||
|
||||
std::string json;
|
||||
for (auto &item : items) {
|
||||
auto json = getSceneItemTransform(item);
|
||||
json = getSceneItemTransform(item);
|
||||
if (matchJson(json, _settings, _regex)) {
|
||||
ret = true;
|
||||
}
|
||||
obs_sceneitem_release(item);
|
||||
}
|
||||
SetVariableValue(json);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
class MacroConditionSceneTransform : public MacroCondition {
|
||||
public:
|
||||
MacroConditionSceneTransform(Macro *m) : MacroCondition(m) {}
|
||||
MacroConditionSceneTransform(Macro *m) : MacroCondition(m, true) {}
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
SceneSelection _scene;
|
||||
SceneItemSelection _source;
|
||||
RegexConfig _regex;
|
||||
VariableResolvingString _settings = "";
|
||||
StringVariable _settings = "";
|
||||
|
||||
private:
|
||||
static bool _registered;
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
|
||||
SourceSelection _source;
|
||||
SourceCondition _condition = SourceCondition::ACTIVE;
|
||||
VariableResolvingString _settings = "";
|
||||
StringVariable _settings = "";
|
||||
RegexConfig _regex;
|
||||
|
||||
private:
|
||||
|
||||
@@ -35,12 +35,12 @@ bool MacroConditionTimer::CheckCondition()
|
||||
void MacroConditionTimer::SetRandomTimeRemaining()
|
||||
{
|
||||
double min, max;
|
||||
if (_duration.seconds <= _duration2.seconds) {
|
||||
min = _duration.seconds;
|
||||
max = _duration2.seconds;
|
||||
if (_duration.Seconds() <= _duration2.Seconds()) {
|
||||
min = _duration.Seconds();
|
||||
max = _duration2.Seconds();
|
||||
} else {
|
||||
min = _duration2.seconds;
|
||||
max = _duration.seconds;
|
||||
min = _duration2.Seconds();
|
||||
max = _duration.Seconds();
|
||||
}
|
||||
std::uniform_real_distribution<double> unif(min, max);
|
||||
|
||||
@@ -53,17 +53,18 @@ bool MacroConditionTimer::Save(obs_data_t *obj) const
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_int(obj, "type", static_cast<int>(_type));
|
||||
_duration.Save(obj);
|
||||
_duration2.Save(obj, "seconds2", "displayUnit2");
|
||||
_duration2.Save(obj, "duration2");
|
||||
if (_saveRemaining) {
|
||||
obs_data_set_double(obj, "remaining",
|
||||
_paused ? _remaining
|
||||
: _duration.TimeRemaining());
|
||||
} else {
|
||||
obs_data_set_double(obj, "remaining", _duration.seconds);
|
||||
obs_data_set_double(obj, "remaining", _duration.Seconds());
|
||||
}
|
||||
obs_data_set_bool(obj, "saveRemaining", _saveRemaining);
|
||||
obs_data_set_bool(obj, "paused", _paused);
|
||||
obs_data_set_bool(obj, "oneshot", _oneshot);
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -72,7 +73,14 @@ bool MacroConditionTimer::Load(obs_data_t *obj)
|
||||
MacroCondition::Load(obj);
|
||||
_type = static_cast<TimerType>(obs_data_get_int(obj, "type"));
|
||||
_duration.Load(obj);
|
||||
_duration2.Load(obj, "seconds2", "displayUnit2");
|
||||
// TODO: remove this fallback
|
||||
if (obs_data_get_int(obj, "version") == 1) {
|
||||
_duration2.Load(obj, "duration2");
|
||||
} else {
|
||||
_duration2.Load(obj, "seconds2");
|
||||
_duration2.SetUnit(static_cast<Duration::Unit>(
|
||||
obs_data_get_int(obj, "displayUnit2")));
|
||||
}
|
||||
_remaining = obs_data_get_double(obj, "remaining");
|
||||
_paused = obs_data_get_bool(obj, "paused");
|
||||
_saveRemaining = obs_data_get_bool(obj, "saveRemaining");
|
||||
@@ -103,7 +111,7 @@ void MacroConditionTimer::Continue()
|
||||
|
||||
void MacroConditionTimer::Reset()
|
||||
{
|
||||
_remaining = _duration.seconds;
|
||||
_remaining = _duration.Seconds();
|
||||
_duration.Reset();
|
||||
if (_type == TimerType::RANDOM) {
|
||||
SetRandomTimeRemaining();
|
||||
@@ -136,14 +144,10 @@ MacroConditionTimerEdit::MacroConditionTimerEdit(
|
||||
|
||||
QWidget::connect(_timerTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(TimerTypeChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(_duration2, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(Duration2Changed(double)));
|
||||
QWidget::connect(_duration2, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(Duration2UnitChanged(DurationUnit)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_duration2, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(Duration2Changed(const Duration &)));
|
||||
QWidget::connect(_pauseConinue, SIGNAL(clicked()), this,
|
||||
SLOT(PauseContinueClicked()));
|
||||
QWidget::connect(_reset, SIGNAL(clicked()), this, SLOT(ResetClicked()));
|
||||
@@ -201,44 +205,24 @@ void MacroConditionTimerEdit::TimerTypeChanged(int type)
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionTimerEdit::DurationChanged(double seconds)
|
||||
void MacroConditionTimerEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroConditionTimerEdit::DurationUnitChanged(DurationUnit unit)
|
||||
void MacroConditionTimerEdit::Duration2Changed(const Duration &dur)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.displayUnit = unit;
|
||||
}
|
||||
|
||||
void MacroConditionTimerEdit::Duration2Changed(double seconds)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration2.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroConditionTimerEdit::Duration2UnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration2.displayUnit = unit;
|
||||
_entryData->_duration2 = dur;
|
||||
}
|
||||
|
||||
void MacroConditionTimerEdit::SaveRemainingChanged(int state)
|
||||
|
||||