Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b74e9d2e2a |
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -22,7 +22,6 @@ A clear and concise description of what you expected to happen.
|
||||
|
||||
**Logs**
|
||||
Please provide a log of your issue with verbose logging enabled (See General tab of the plugin).
|
||||
In case of a crash, please also include the corresponding crash log.
|
||||
See [here](https://obsproject.com/forum/threads/please-post-a-log-with-your-issue-heres-how.23074/) for a description where to find the log files and how to share them.
|
||||
Please share the currently used plugin settings by exporting them them to a file (See General tab of the plugin).
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
79
.github/actions/build-dependencies/action.yml
vendored
@@ -1,79 +0,0 @@
|
||||
name: 'Setup plugin build dependencies'
|
||||
description: 'Builds the plugin build dependencies'
|
||||
inputs:
|
||||
target:
|
||||
description: 'Build target for dependencies'
|
||||
required: true
|
||||
config:
|
||||
description: 'Build configuration'
|
||||
required: false
|
||||
default: 'Release'
|
||||
visualStudio:
|
||||
description: 'Visual Studio version (Windows only)'
|
||||
required: false
|
||||
default: 'Visual Studio 16 2019'
|
||||
workingDirectory:
|
||||
description: 'Working directory for packaging'
|
||||
required: false
|
||||
default: ${{ github.workspace }}
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Setup cmake
|
||||
uses: jwlawson/actions-setup-cmake@v1.13
|
||||
with:
|
||||
cmake-version: '3.24.x'
|
||||
|
||||
- name: Restore cached dependencies
|
||||
id: restore-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ env.DEP_DIR }}
|
||||
key: ${{ env.DEP_DIR }}-${{ runner.os }}-${{ inputs.target }}
|
||||
|
||||
- name: Run macOS Build
|
||||
if: ${{ runner.os == 'macOS' && steps.restore-cache.outputs.cache-hit != 'true' }}
|
||||
shell: zsh {0}
|
||||
run: |
|
||||
build_args=(
|
||||
-c ${{ inputs.config }}
|
||||
-t macos-${{ inputs.target }}
|
||||
)
|
||||
|
||||
if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
|
||||
|
||||
${{ inputs.workingDirectory }}/.github/scripts/build-deps-macos.zsh -o ${{ env.DEP_DIR }} ${build_args}
|
||||
|
||||
- name: Run Linux Build
|
||||
if: ${{ runner.os == 'Linux' && steps.restore-cache.outputs.cache-hit != 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
build_args=(
|
||||
-c ${{ inputs.config }}
|
||||
-t linux-${{ inputs.target }}
|
||||
)
|
||||
|
||||
if [[ -n "${CI}" && -n "${RUNNER_DEBUG}" ]]; then
|
||||
build_args+=(--debug)
|
||||
fi
|
||||
|
||||
${{ inputs.workingDirectory }}/.github/scripts/build-deps-linux.sh -o ${{ env.DEP_DIR }} "${build_args[@]}"
|
||||
|
||||
- name: Run Windows Build
|
||||
if: ${{ runner.os == 'Windows' && steps.restore-cache.outputs.cache-hit != 'true' }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
$BuildArgs = @{
|
||||
Target = '${{ inputs.target }}'
|
||||
Configuration = '${{ inputs.config }}'
|
||||
CMakeGenerator = '${{ inputs.visualStudio }}'
|
||||
}
|
||||
|
||||
if ( ( Test-Path env:CI ) -and ( Test-Path env:RUNNER_DEBUG ) ) {
|
||||
$BuildArgs += @{
|
||||
Debug = $true
|
||||
}
|
||||
}
|
||||
|
||||
${{ inputs.workingDirectory }}/.github/scripts/Build-Deps-Windows.ps1 -OutDirName ${{ env.DEP_DIR }} @BuildArgs
|
||||
|
||||
6
.github/actions/build-plugin/action.yml
vendored
@@ -49,7 +49,7 @@ runs:
|
||||
if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(-s)
|
||||
if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
|
||||
|
||||
${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh -d ${{ env.DEP_DIR }} ${build_args}
|
||||
${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh ${build_args}
|
||||
|
||||
- name: Run Linux Build
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
@@ -68,7 +68,7 @@ runs:
|
||||
build_args+=(-p)
|
||||
fi
|
||||
|
||||
${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh -d ${{ env.DEP_DIR }} "${build_args[@]}"
|
||||
${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh "${build_args[@]}"
|
||||
|
||||
- name: Run Windows Build
|
||||
if: ${{ runner.os == 'Windows' }}
|
||||
@@ -86,4 +86,4 @@ runs:
|
||||
}
|
||||
}
|
||||
|
||||
${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 -ADVSSDepName ${{ env.DEP_DIR }} @BuildArgs
|
||||
${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 @BuildArgs
|
||||
|
||||
37
.github/actions/run-tests/action.yml
vendored
@@ -1,37 +0,0 @@
|
||||
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
|
||||
1
.github/scripts/.Wingetfile
vendored
@@ -1,4 +1,3 @@
|
||||
package '7zip.7zip', path: '7-zip', bin: '7z'
|
||||
package 'cmake', path: 'Cmake\bin', bin: 'cmake'
|
||||
package 'innosetup', path: 'Inno Setup 6', bin: 'iscc'
|
||||
package 'OpenSSL', path: 'OpenSSL', bin: 'openssl'
|
||||
|
||||
324
.github/scripts/.build-deps.zsh
vendored
@@ -1,324 +0,0 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
builtin emulate -L zsh
|
||||
setopt EXTENDED_GLOB
|
||||
setopt PUSHD_SILENT
|
||||
setopt ERR_EXIT
|
||||
setopt ERR_RETURN
|
||||
setopt NO_UNSET
|
||||
setopt PIPE_FAIL
|
||||
setopt NO_AUTO_PUSHD
|
||||
setopt NO_PUSHD_IGNORE_DUPS
|
||||
setopt FUNCTION_ARGZERO
|
||||
|
||||
## Enable for script debugging
|
||||
# setopt WARN_CREATE_GLOBAL
|
||||
# setopt WARN_NESTED_VAR
|
||||
# setopt XTRACE
|
||||
|
||||
autoload -Uz is-at-least && if ! is-at-least 5.2; then
|
||||
print -u2 -PR "%F{1}${funcstack[1]##*/}:%f Running on Zsh version %B${ZSH_VERSION}%b, but Zsh %B5.2%b is the minimum supported version. Upgrade Zsh to fix this issue."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_trap_error() {
|
||||
print -u2 -PR '%F{1} ✖︎ script execution error%f'
|
||||
print -PR -e "
|
||||
Callstack:
|
||||
${(j:\n :)funcfiletrace}
|
||||
"
|
||||
exit 2
|
||||
}
|
||||
|
||||
build() {
|
||||
if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h}
|
||||
local host_os=${${(s:-:)ZSH_ARGZERO:t:r}[3]}
|
||||
local target="${host_os}-${CPUTYPE}"
|
||||
local project_root=${SCRIPT_HOME:A:h:h}
|
||||
local buildspec_file="${project_root}/buildspec.json"
|
||||
|
||||
trap '_trap_error' ZERR
|
||||
|
||||
fpath=("${SCRIPT_HOME}/utils.zsh" ${fpath})
|
||||
autoload -Uz log_info log_error log_output set_loglevel check_${host_os} setup_${host_os} setup_obs setup_ccache
|
||||
|
||||
if [[ ! -r ${buildspec_file} ]] {
|
||||
log_error \
|
||||
'No buildspec.json found. Please create a build specification for your project.' \
|
||||
'A buildspec.json.template file is provided in the repository to get you started.'
|
||||
return 2
|
||||
}
|
||||
|
||||
typeset -g -a skips=()
|
||||
local -i _verbosity=1
|
||||
local -r _version='1.0.0'
|
||||
local -r -a _valid_targets=(
|
||||
macos-x86_64
|
||||
macos-arm64
|
||||
macos-universal
|
||||
linux-x86_64
|
||||
)
|
||||
local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel)
|
||||
if [[ ${host_os} == 'macos' ]] {
|
||||
local -r -a _valid_generators=(Xcode Ninja 'Unix Makefiles')
|
||||
local generator="${${CI:+Ninja}:-Xcode}"
|
||||
} else {
|
||||
local -r -a _valid_generators=(Ninja 'Unix Makefiles')
|
||||
local generator='Ninja'
|
||||
}
|
||||
local -r _usage="
|
||||
Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
|
||||
%BOptions%b:
|
||||
|
||||
%F{yellow} Build configuration options%f
|
||||
-----------------------------------------------------------------------------
|
||||
%B-t | --target%b Specify target - default: %B%F{green}${host_os}-${CPUTYPE}%f%b
|
||||
%B-c | --config%b Build configuration - default: %B%F{green}RelWithDebInfo%f%b
|
||||
%B-o | --out%b Output directory - default: %B%F{green}RelWithDebInfo%f%b
|
||||
%B--generator%b Specify build system to generate - default: %B%F{green}Ninja%f%b
|
||||
Available generators:
|
||||
- Ninja
|
||||
- Unix Makefiles
|
||||
- Xcode (macOS only)
|
||||
|
||||
%F{yellow} Output options%f
|
||||
-----------------------------------------------------------------------------
|
||||
%B-q | --quiet%b Quiet (error output only)
|
||||
%B-v | --verbose%b Verbose (more detailed output)
|
||||
%B--skip-[all|build|deps|unpack]%b Skip all|building OBS|checking for dependencies|unpacking dependencies
|
||||
%B--debug%b Debug (very detailed and added output)
|
||||
|
||||
%F{yellow} General options%f
|
||||
-----------------------------------------------------------------------------
|
||||
%B-h | --help%b Print this usage help
|
||||
%B-V | --version%b Print script version information"
|
||||
|
||||
local -a args
|
||||
while (( # )) {
|
||||
case ${1} {
|
||||
-t|--target|-c|--config|--generator)
|
||||
if (( # == 1 )) || [[ ${2:0:1} == '-' ]] {
|
||||
log_error "Missing value for option %B${1}%b"
|
||||
log_output ${_usage}
|
||||
exit 2
|
||||
}
|
||||
;;
|
||||
}
|
||||
case ${1} {
|
||||
--)
|
||||
shift
|
||||
args+=($@)
|
||||
break
|
||||
;;
|
||||
-t|--target)
|
||||
if (( ! ${_valid_targets[(Ie)${2}]} )) {
|
||||
log_error "Invalid value %B${2}%b for option %B${1}%b"
|
||||
log_output ${_usage}
|
||||
exit 2
|
||||
}
|
||||
target=${2}
|
||||
shift 2
|
||||
;;
|
||||
-c|--config)
|
||||
if (( ! ${_valid_configs[(Ie)${2}]} )) {
|
||||
log_error "Invalid value %B${2}%b for option %B${1}%b"
|
||||
log_output ${_usage}
|
||||
exit 2
|
||||
}
|
||||
BUILD_CONFIG=${2}
|
||||
shift 2
|
||||
;;
|
||||
-o|--out)
|
||||
OUT_DIR="${2}"
|
||||
shift 2
|
||||
;;
|
||||
-q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
|
||||
-v|--verbose) (( _verbosity += 1 )); shift ;;
|
||||
-h|--help) log_output ${_usage}; exit 0 ;;
|
||||
-V|--version) print -Pr "${_version}"; exit 0 ;;
|
||||
--debug) _verbosity=3; shift ;;
|
||||
--generator)
|
||||
if (( ! ${_valid_generators[(Ie)${2}]} )) {
|
||||
log_error "Invalid value %B${2}%b for option %B${1}%b"
|
||||
log_output ${_usage}
|
||||
exit 2
|
||||
}
|
||||
generator=${2}
|
||||
shift 2
|
||||
;;
|
||||
--skip-*)
|
||||
local _skip="${${(s:-:)1}[-1]}"
|
||||
local _check=(all deps unpack build)
|
||||
(( ${_check[(Ie)${_skip}]} )) || log_warning "Invalid skip mode %B${_skip}%b supplied"
|
||||
typeset -g -a skips=(${skips} ${_skip})
|
||||
shift
|
||||
;;
|
||||
*) log_error "Unknown option: %B${1}%b"; log_output ${_usage}; exit 2 ;;
|
||||
}
|
||||
}
|
||||
|
||||
set -- ${(@)args}
|
||||
set_loglevel ${_verbosity}
|
||||
|
||||
check_${host_os}
|
||||
setup_ccache
|
||||
|
||||
typeset -g QT_VERSION
|
||||
typeset -g DEPLOYMENT_TARGET
|
||||
typeset -g OBS_DEPS_VERSION
|
||||
setup_${host_os}
|
||||
|
||||
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})"
|
||||
|
||||
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 [[ -z "${OUT_DIR}" ]] {
|
||||
OUT_DIR="advss-build-dependencies"
|
||||
}
|
||||
mkdir -p "${project_root}/../${OUT_DIR}"
|
||||
local advss_dep_path="$(realpath ${project_root}/../${OUT_DIR})"
|
||||
local _plugin_deps="${project_root:h}/obs-build-dependencies/plugin-deps-${OBS_DEPS_VERSION}-qt${QT_VERSION}-${target##*-}"
|
||||
|
||||
case ${host_os} {
|
||||
macos)
|
||||
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}
|
||||
-DCMAKE_PREFIX_PATH="${advss_dep_path};${_plugin_deps}"
|
||||
-DCMAKE_INSTALL_PREFIX="${advss_dep_path}"
|
||||
)
|
||||
|
||||
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}
|
||||
|
||||
log_info "Building OpenCV ..."
|
||||
cmake --build ${opencv_build_dir} --config Release
|
||||
|
||||
log_info "Installing OpenCV..."
|
||||
cmake --install ${opencv_build_dir} --prefix "${advss_dep_path}" --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
|
||||
-DCMAKE_PREFIX_PATH="${advss_dep_path};${_plugin_deps}"
|
||||
-DCMAKE_INSTALL_PREFIX="${advss_dep_path}"
|
||||
)
|
||||
|
||||
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} --prefix "${advss_dep_path}" --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
|
||||
-DCMAKE_PREFIX_PATH="${advss_dep_path};${_plugin_deps}"
|
||||
-DCMAKE_INSTALL_PREFIX="${advss_dep_path}"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
log_info "Installing Tesseract..."
|
||||
cmake --install ${tesseract_build_dir} --prefix "${advss_dep_path}" --config Release
|
||||
popd
|
||||
|
||||
pushd ${advss_dep_path}
|
||||
log_info "Prepare openssl ..."
|
||||
rm -rf openssl
|
||||
git clone git://git.openssl.org/openssl.git --branch openssl-3.1.2 --depth 1
|
||||
mv openssl openssl_x86
|
||||
cp -r openssl_x86 openssl_arm
|
||||
|
||||
log_info "Building openssl x86 ..."
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.9
|
||||
cd openssl_x86
|
||||
./Configure darwin64-x86_64-cc shared
|
||||
make
|
||||
|
||||
log_info "Building openssl arm ..."
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.15
|
||||
cd ../openssl_arm
|
||||
./Configure enable-rc5 zlib darwin64-arm64-cc no-asm
|
||||
make
|
||||
|
||||
log_info "Combine arm and x86 openssl binaries ..."
|
||||
cd ..
|
||||
mkdir openssl-combined
|
||||
lipo -create openssl_x86/libcrypto.a openssl_arm/libcrypto.a -output openssl-combined/libcrypto.a
|
||||
lipo -create openssl_x86/libssl.a openssl_arm/libssl.a -output openssl-combined/libssl.a
|
||||
|
||||
log_info "Clean up openssl dir..."
|
||||
mv openssl_x86 openssl
|
||||
rm -rf openssl_arm
|
||||
;;
|
||||
linux)
|
||||
# Nothing to do for now
|
||||
;;
|
||||
}
|
||||
}
|
||||
|
||||
build ${@}
|
||||
122
.github/scripts/.build.zsh
vendored
@@ -36,7 +36,6 @@ build() {
|
||||
local target="${host_os}-${CPUTYPE}"
|
||||
local project_root=${SCRIPT_HOME:A:h:h}
|
||||
local buildspec_file="${project_root}/buildspec.json"
|
||||
local dep_dir=""
|
||||
|
||||
trap '_trap_error' ZERR
|
||||
|
||||
@@ -78,7 +77,6 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
%B-c | --config%b Build configuration - default: %B%F{green}RelWithDebInfo%f%b
|
||||
%B-s | --codesign%b Enable codesigning (macOS only)
|
||||
%B-p | --portable%b Enable portable mode (Linux only)
|
||||
%B-d | --dep%b Dependency directory name - default: %B%F{green}advss-build-dependencies%f%b
|
||||
%B--generator%b Specify build system to generate - default: %B%F{green}Ninja%f%b
|
||||
Available generators:
|
||||
- Ninja
|
||||
@@ -132,10 +130,6 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
BUILD_CONFIG=${2}
|
||||
shift 2
|
||||
;;
|
||||
-d|--dep)
|
||||
dep_dir="${2}"
|
||||
shift 2
|
||||
;;
|
||||
-s|--codesign) CODESIGN=1; shift ;;
|
||||
-p|--portable) typeset -g PORTABLE=1; shift ;;
|
||||
-q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
|
||||
@@ -174,34 +168,109 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
typeset -g OBS_DEPS_VERSION
|
||||
setup_${host_os}
|
||||
|
||||
local advss_deps_path
|
||||
if [[ -z "${dep_dir}" ]] {
|
||||
log_info "Building advss deps ..."
|
||||
dep_dir="advss-build-dependencies"
|
||||
${SCRIPT_HOME}/build-deps-${host_os}.zsh -c "${BUILD_CONFIG:-RelWithDebInfo}" -t "${target}" --generator "${generator}" -o "${dep_dir}" --skip-deps --skip-unpack
|
||||
}
|
||||
advss_deps_path=$(realpath ${project_root}/../${dep_dir})
|
||||
log_info "Using advss deps at $advss_deps_path ..."
|
||||
|
||||
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})"
|
||||
|
||||
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"
|
||||
|
||||
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}
|
||||
)
|
||||
|
||||
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}
|
||||
|
||||
log_info "Building OpenCV ..."
|
||||
cmake --build ${opencv_build_dir} --config Release
|
||||
|
||||
log_info "Installing OpenCV..."
|
||||
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'' \
|
||||
@@ -220,7 +289,7 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
local -a cmake_args=(
|
||||
-DCMAKE_BUILD_TYPE=${BUILD_CONFIG:-RelWithDebInfo}
|
||||
-DQT_VERSION=${QT_VERSION}
|
||||
-DCMAKE_PREFIX_PATH="${_plugin_deps};${advss_deps_path}"
|
||||
-DCMAKE_PREFIX_PATH="${_plugin_deps}"
|
||||
)
|
||||
|
||||
if (( _loglevel == 0 )) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR)
|
||||
@@ -237,17 +306,12 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
|
||||
num_procs=$(( $(sysctl -n hw.ncpu) + 1 ))
|
||||
|
||||
local openssl_lib_dir="${advss_deps_path}/openssl-combined/"
|
||||
local openssl_include_dir="${advss_deps_path}/openssl/include"
|
||||
|
||||
cmake_args+=(
|
||||
-DCMAKE_FRAMEWORK_PATH="${_plugin_deps}/Frameworks"
|
||||
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||
-DOBS_CODESIGN_LINKER=ON
|
||||
-DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}"
|
||||
-DOPENSSL_INCLUDE_DIR="${openssl_include_dir}"
|
||||
-DOPENSSL_LIBRARIES="${openssl_lib_dir}/libcrypto.a;${openssl_lib_dir}/libssl.a"
|
||||
)
|
||||
|
||||
;;
|
||||
|
||||
9
.github/scripts/.package.zsh
vendored
@@ -128,18 +128,9 @@ 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
|
||||
|
||||
|
||||
172
.github/scripts/Build-Deps-Windows.ps1
vendored
@@ -1,172 +0,0 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')]
|
||||
[string] $Configuration = 'RelWithDebInfo',
|
||||
[ValidateSet('x86', 'x64')]
|
||||
[string] $Target,
|
||||
[ValidateSet('Visual Studio 17 2022', 'Visual Studio 16 2019')]
|
||||
[string] $CMakeGenerator,
|
||||
[string] $OutDirName,
|
||||
[switch] $SkipDeps,
|
||||
[switch] $SkipUnpack
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if ( $DebugPreference -eq 'Continue' ) {
|
||||
$VerbosePreference = 'Continue'
|
||||
$InformationPreference = 'Continue'
|
||||
}
|
||||
|
||||
if ( $PSVersionTable.PSVersion -lt '7.0.0' ) {
|
||||
Write-Warning 'The obs-deps PowerShell build script requires PowerShell Core 7. Install or upgrade your PowerShell version: https://aka.ms/pscore6'
|
||||
exit 2
|
||||
}
|
||||
|
||||
function Build {
|
||||
trap {
|
||||
Pop-Location -Stack BuildTemp -ErrorAction 'SilentlyContinue'
|
||||
Write-Error $_
|
||||
exit 2
|
||||
}
|
||||
|
||||
$ScriptHome = $PSScriptRoot
|
||||
$ProjectRoot = Resolve-Path -Path "$PSScriptRoot/../.."
|
||||
$BuildSpecFile = "${ProjectRoot}/buildspec.json"
|
||||
|
||||
$UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
|
||||
|
||||
foreach ($Utility in $UtilityFunctions) {
|
||||
Write-Debug "Loading $($Utility.FullName)"
|
||||
. $Utility.FullName
|
||||
}
|
||||
|
||||
$BuildSpec = Get-Content -Path ${BuildSpecFile} -Raw | ConvertFrom-Json
|
||||
$ProductName = $BuildSpec.name
|
||||
$ProductVersion = $BuildSpec.version
|
||||
|
||||
$script:VisualStudioVersion = ''
|
||||
$script:PlatformSDK = '10.0.18363.657'
|
||||
|
||||
Setup-Host
|
||||
|
||||
if ( $CmakeGenerator -eq '' ) {
|
||||
$CmakeGenerator = $script:VisualStudioVersion
|
||||
}
|
||||
|
||||
$DepsPath = "plugin-deps-${script:DepsVersion}-*-${script:Target}"
|
||||
$OBSDepPath = "$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
||||
|
||||
if ( $OutDirName -eq '' ) {
|
||||
$OutDirName = "advss-build-dependencies"
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path ${ProjectRoot}/../${OutDirName}
|
||||
|
||||
$ADVSSDepPath = "$(Resolve-Path -Path ${ProjectRoot}/../${OutDirName})"
|
||||
|
||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
||||
|
||||
Push-Location -Stack BuildOpenCVTemp
|
||||
Ensure-Location $ProjectRoot
|
||||
|
||||
$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=${OBSDepPath}"
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
||||
"-DBUILD_LIST=core,imgproc,objdetect"
|
||||
)
|
||||
|
||||
Log-Information "Configuring OpenCV..."
|
||||
Invoke-External cmake -S ${OpenCVPath} -B ${OpenCVBuildPath} @OpenCVCmakeArgs
|
||||
|
||||
$OpenCVCmakeArgs = @(
|
||||
'--config', "Release"
|
||||
)
|
||||
|
||||
if ( $VerbosePreference -eq 'Continue' ) {
|
||||
$OpenCVCmakeArgs += ('--verbose')
|
||||
}
|
||||
|
||||
Log-Information "Building OpenCV..."
|
||||
Invoke-External cmake --build "${OpenCVBuildPath}" @OpenCVCmakeArgs
|
||||
Log-Information "Install OpenCV}..."
|
||||
Invoke-External cmake --install "${OpenCVBuildPath}" --prefix "${ADVSSDepPath}" @OpenCVCmakeArgs
|
||||
|
||||
$LeptonicaPath = "${ProjectRoot}/deps/leptonica"
|
||||
$LeptonicaBuildPath = "${LeptonicaPath}/build"
|
||||
|
||||
Push-Location -Stack BuildLeptonicaTemp
|
||||
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=${Configuration}"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${OBSDepPath}"
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
||||
"-DSW_BUILD=OFF"
|
||||
"-DLIBWEBP_SUPPORT=OFF"
|
||||
)
|
||||
|
||||
Log-Information "Configuring leptonica..."
|
||||
Invoke-External cmake -S ${LeptonicaPath} -B ${LeptonicaBuildPath} @LeptonicaCmakeArgs
|
||||
|
||||
$LeptonicaCmakeArgs = @(
|
||||
'--config', "${Configuration}"
|
||||
)
|
||||
|
||||
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 "${ADVSSDepPath}" @LeptonicaCmakeArgs
|
||||
|
||||
Push-Location -Stack BuildTesseractTemp
|
||||
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=${Configuration}"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${OBSDepPath}"
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
||||
"-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', "${Configuration}"
|
||||
)
|
||||
|
||||
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 "${ADVSSDepPath}" @TesseractCmakeArgs
|
||||
}
|
||||
|
||||
Build
|
||||
116
.github/scripts/Build-Windows.ps1
vendored
@@ -6,7 +6,6 @@ param(
|
||||
[string] $Target,
|
||||
[ValidateSet('Visual Studio 17 2022', 'Visual Studio 16 2019')]
|
||||
[string] $CMakeGenerator,
|
||||
[string] $ADVSSDepName,
|
||||
[switch] $SkipAll,
|
||||
[switch] $SkipBuild,
|
||||
[switch] $SkipDeps,
|
||||
@@ -61,17 +60,116 @@ function Build {
|
||||
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
|
||||
$DepInstallPath = "$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
||||
|
||||
if ( $ADVSSDepName -eq '' ) {
|
||||
Log-Information "Building advss deps ..."
|
||||
$ADVSSDepName = "advss-build-dependencies"
|
||||
invoke-expression -Command "$PSScriptRoot/Build-Deps-Windows.ps1 -Configuration $Configuration -Target $Target -CMakeGenerator `"$CMakeGenerator`" -OutDirName $ADVSSDepName -SkipDeps -SkipUnpack"
|
||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
||||
|
||||
Push-Location -Stack BuildOpenCVTemp
|
||||
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
||||
Ensure-Location $ProjectRoot
|
||||
|
||||
$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=${DepInstallPath}"
|
||||
"-DBUILD_LIST=core,imgproc,objdetect"
|
||||
)
|
||||
|
||||
Log-Information "Configuring OpenCV..."
|
||||
Invoke-External cmake -S ${OpenCVPath} -B ${OpenCVBuildPath} @OpenCVCmakeArgs
|
||||
|
||||
$OpenCVCmakeArgs = @(
|
||||
'--config', "Release"
|
||||
)
|
||||
|
||||
if ( $VerbosePreference -eq 'Continue' ) {
|
||||
$OpenCVCmakeArgs += ('--verbose')
|
||||
}
|
||||
|
||||
Log-Information "Building OpenCV..."
|
||||
Invoke-External cmake --build "${OpenCVBuildPath}" @OpenCVCmakeArgs
|
||||
}
|
||||
$ADVSSDepPath = "$(Resolve-Path -Path ${ProjectRoot}/../${script:ADVSSDepName})"
|
||||
Log-Information "Using advss deps at $ADVSSDepPath ..."
|
||||
Log-Information "Install OpenCV}..."
|
||||
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 -NoNewline
|
||||
| Out-File -Path ${ProjectRoot}/CMakeLists.txt
|
||||
|
||||
Setup-Obs
|
||||
|
||||
@@ -84,7 +182,7 @@ function Build {
|
||||
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
||||
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
||||
"-DCMAKE_BUILD_TYPE=${Configuration}"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath};${ADVSSDepPath}"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath}"
|
||||
"-DQT_VERSION=${script:QtVersion}"
|
||||
)
|
||||
|
||||
|
||||
13
.github/scripts/build-deps-linux.sh
vendored
@@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! type zsh > /dev/null 2>&1; then
|
||||
echo ' => Installing script dependency Zsh.'
|
||||
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install zsh
|
||||
fi
|
||||
|
||||
SCRIPT=$(readlink -f "${0}")
|
||||
SCRIPT_DIR=$(dirname "${SCRIPT}")
|
||||
|
||||
zsh ${SCRIPT_DIR}/build-deps-linux.zsh "${@}"
|
||||
1
.github/scripts/build-deps-linux.zsh
vendored
@@ -1 +0,0 @@
|
||||
.build-deps.zsh
|
||||
1
.github/scripts/build-deps-macos.zsh
vendored
@@ -1 +0,0 @@
|
||||
.build-deps.zsh
|
||||
2
.github/scripts/utils.zsh/check_packages
vendored
@@ -24,7 +24,7 @@ if (( ! ${+commands[packagesbuild]} )) {
|
||||
pushd
|
||||
mkcd ${project_root:h}/obs-build-dependencies
|
||||
|
||||
local packages_url='https://web.archive.org/web/20230727054218/http://s.sudre.free.fr/Software/files/Packages.dmg'
|
||||
local packages_url='http://s.sudre.free.fr/Software/files/Packages.dmg'
|
||||
local packages_hash='6afdd25386295974dad8f078b8f1e41cabebd08e72d970bf92f707c7e48b16c9'
|
||||
|
||||
if [[ ! -f Packages.dmg ]] {
|
||||
|
||||
50
.github/workflows/main.yml
vendored
@@ -17,7 +17,6 @@ on:
|
||||
env:
|
||||
PLUGIN_NAME: SceneSwitcher
|
||||
LIB_NAME: advanced-scene-switcher
|
||||
DEP_DIR: advss-build-dependencies-1
|
||||
|
||||
jobs:
|
||||
clang_check:
|
||||
@@ -116,6 +115,9 @@ jobs:
|
||||
with:
|
||||
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-
|
||||
@@ -144,13 +146,6 @@ jobs:
|
||||
print "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" >> $GITHUB_ENV
|
||||
print "CODESIGN_IDENT_INSTALLER=${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build Dependencies
|
||||
uses: ./plugin/.github/actions/build-dependencies
|
||||
with:
|
||||
workingDirectory: ${{ github.workspace }}/plugin
|
||||
target: ${{ matrix.arch }}
|
||||
config: RelWithDebInfo
|
||||
|
||||
- name: Build Plugin
|
||||
uses: ./plugin/.github/actions/build-plugin
|
||||
with:
|
||||
@@ -160,12 +155,6 @@ 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:
|
||||
@@ -253,13 +242,6 @@ jobs:
|
||||
echo 'found=false' >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Build Dependencies
|
||||
uses: ./plugin/.github/actions/build-dependencies
|
||||
with:
|
||||
workingDirectory: ${{ github.workspace }}/plugin
|
||||
target: ${{ matrix.arch }}
|
||||
config: RelWithDebInfo
|
||||
|
||||
- name: Build Plugin
|
||||
uses: ./plugin/.github/actions/build-plugin
|
||||
with:
|
||||
@@ -268,12 +250,6 @@ 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:
|
||||
@@ -341,6 +317,9 @@ jobs:
|
||||
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-
|
||||
@@ -366,14 +345,6 @@ jobs:
|
||||
|
||||
"found=$(([string]${LabelFound}).ToLower())" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Build Dependencies
|
||||
uses: ./plugin/.github/actions/build-dependencies
|
||||
with:
|
||||
workingDirectory: ${{ github.workspace }}/plugin
|
||||
target: ${{ matrix.arch }}
|
||||
config: RelWithDebInfo
|
||||
visualStudio: 'Visual Studio 17 2022'
|
||||
|
||||
- name: Build Plugin
|
||||
uses: ./plugin/.github/actions/build-plugin
|
||||
with:
|
||||
@@ -382,12 +353,6 @@ 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:
|
||||
@@ -442,11 +407,10 @@ 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@v1
|
||||
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5
|
||||
with:
|
||||
draft: true
|
||||
prerelease: true
|
||||
|
||||
1
.gitignore
vendored
@@ -91,7 +91,6 @@ Thumbs.db
|
||||
.settings
|
||||
.idea
|
||||
.metadata
|
||||
.vscode
|
||||
*.iml
|
||||
*.ipr
|
||||
*.sublime*
|
||||
|
||||
9
.gitmodules
vendored
@@ -16,12 +16,3 @@
|
||||
[submodule "deps/tesseract"]
|
||||
path = deps/tesseract
|
||||
url = https://github.com/tesseract-ocr/tesseract.git
|
||||
[submodule "deps/libremidi"]
|
||||
path = deps/libremidi
|
||||
url = https://github.com/jcelerier/libremidi.git
|
||||
[submodule "deps/cpp-httplib"]
|
||||
path = deps/cpp-httplib
|
||||
url = https://github.com/yhirose/cpp-httplib.git
|
||||
[submodule "deps/json"]
|
||||
path = deps/json
|
||||
url = https://github.com/nlohmann/json.git
|
||||
|
||||
@@ -42,20 +42,21 @@ target_sources(
|
||||
src/general.cpp
|
||||
src/hotkey.cpp
|
||||
src/hotkey.hpp
|
||||
src/hotkey.hpp
|
||||
src/platform-funcs.hpp
|
||||
src/scene-group.cpp
|
||||
src/scene-group.hpp
|
||||
src/status-control.cpp
|
||||
src/status-control.hpp
|
||||
src/switcher-data.cpp
|
||||
src/switcher-data.hpp
|
||||
src/switcher-data-structs.cpp
|
||||
src/switcher-data-structs.hpp
|
||||
src/version.cpp
|
||||
src/version.h)
|
||||
|
||||
# Legacy function sources
|
||||
target_sources(
|
||||
${LIB_NAME}
|
||||
PRIVATE src/legacy/scene-group.cpp
|
||||
src/legacy/scene-group.hpp
|
||||
src/legacy/scene-trigger.cpp
|
||||
PRIVATE src/legacy/scene-trigger.cpp
|
||||
src/legacy/scene-trigger.hpp
|
||||
src/legacy/switch-audio.cpp
|
||||
src/legacy/switch-audio.hpp
|
||||
@@ -73,6 +74,7 @@ target_sources(
|
||||
src/legacy/switch-network.hpp
|
||||
src/legacy/switch-pause.cpp
|
||||
src/legacy/switch-pause.hpp
|
||||
src/legacy/switch-priority.cpp
|
||||
src/legacy/switch-random.cpp
|
||||
src/legacy/switch-random.hpp
|
||||
src/legacy/switch-screen-region.cpp
|
||||
@@ -107,8 +109,6 @@ target_sources(
|
||||
src/macro-core/macro-action-macro.hpp
|
||||
src/macro-core/macro-action-media.cpp
|
||||
src/macro-core/macro-action-media.hpp
|
||||
src/macro-core/macro-action-osc.cpp
|
||||
src/macro-core/macro-action-osc.hpp
|
||||
src/macro-core/macro-action-plugin-state.cpp
|
||||
src/macro-core/macro-action-plugin-state.hpp
|
||||
src/macro-core/macro-action-profile.cpp
|
||||
@@ -125,8 +125,6 @@ target_sources(
|
||||
src/macro-core/macro-action-run.hpp
|
||||
src/macro-core/macro-action-scene-collection.cpp
|
||||
src/macro-core/macro-action-scene-collection.hpp
|
||||
src/macro-core/macro-action-scene-lock.cpp
|
||||
src/macro-core/macro-action-scene-lock.hpp
|
||||
src/macro-core/macro-action-scene-order.cpp
|
||||
src/macro-core/macro-action-scene-order.hpp
|
||||
src/macro-core/macro-action-scene-switch.cpp
|
||||
@@ -167,8 +165,6 @@ target_sources(
|
||||
src/macro-core/macro-condition-cursor.hpp
|
||||
src/macro-core/macro-condition-date.cpp
|
||||
src/macro-core/macro-condition-date.hpp
|
||||
src/macro-core/macro-condition-display.cpp
|
||||
src/macro-core/macro-condition-display.hpp
|
||||
src/macro-core/macro-condition-edit.cpp
|
||||
src/macro-core/macro-condition-edit.hpp
|
||||
src/macro-core/macro-condition-file.cpp
|
||||
@@ -195,16 +191,12 @@ 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
|
||||
src/macro-core/macro-condition-scene-transform.hpp
|
||||
src/macro-core/macro-condition-scene-visibility.cpp
|
||||
src/macro-core/macro-condition-scene-visibility.hpp
|
||||
src/macro-core/macro-condition-slideshow.cpp
|
||||
src/macro-core/macro-condition-slideshow.hpp
|
||||
src/macro-core/macro-condition-scene.cpp
|
||||
src/macro-core/macro-condition-scene.hpp
|
||||
src/macro-core/macro-condition-source.cpp
|
||||
@@ -213,8 +205,6 @@ target_sources(
|
||||
src/macro-core/macro-condition-streaming.hpp
|
||||
src/macro-core/macro-condition-studio-mode.cpp
|
||||
src/macro-core/macro-condition-studio-mode.hpp
|
||||
src/macro-core/macro-condition-tempvar.cpp
|
||||
src/macro-core/macro-condition-tempvar.hpp
|
||||
src/macro-core/macro-condition-timer.cpp
|
||||
src/macro-core/macro-condition-timer.hpp
|
||||
src/macro-core/macro-condition-transition.cpp
|
||||
@@ -229,8 +219,6 @@ 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
|
||||
@@ -256,41 +244,14 @@ target_sources(
|
||||
src/utils/curl-helper.hpp
|
||||
src/utils/duration-control.cpp
|
||||
src/utils/duration-control.hpp
|
||||
src/utils/export-symbol-helper.hpp
|
||||
src/utils/item-selection-helpers.cpp
|
||||
src/utils/item-selection-helpers.hpp
|
||||
src/utils/log-helper.hpp
|
||||
src/utils/file-selection.cpp
|
||||
src/utils/file-selection.hpp
|
||||
src/utils/filter-combo-box.cpp
|
||||
src/utils/filter-combo-box.hpp
|
||||
src/utils/filter-selection.cpp
|
||||
src/utils/filter-selection.hpp
|
||||
src/utils/macro-export-import-dialog.cpp
|
||||
src/utils/macro-export-import-dialog.hpp
|
||||
src/utils/macro-list.cpp
|
||||
src/utils/macro-list.hpp
|
||||
src/utils/macro-run-button.cpp
|
||||
src/utils/macro-run-button.hpp
|
||||
src/utils/macro-segment-selection.cpp
|
||||
src/utils/macro-segment-selection.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/non-modal-dialog.cpp
|
||||
src/utils/non-modal-dialog.hpp
|
||||
src/utils/obs-dock.hpp
|
||||
src/utils/obs-module-helper.cpp
|
||||
src/utils/obs-module-helper.hpp
|
||||
src/utils/osc-helpers.cpp
|
||||
src/utils/osc-helpers.hpp
|
||||
src/utils/priority-helper.cpp
|
||||
src/utils/priority-helper.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
|
||||
@@ -299,8 +260,6 @@ target_sources(
|
||||
src/utils/scene-item-selection.hpp
|
||||
src/utils/scene-selection.cpp
|
||||
src/utils/scene-selection.hpp
|
||||
src/utils/scene-switch-helpers.cpp
|
||||
src/utils/scene-switch-helpers.hpp
|
||||
src/utils/screenshot-helper.cpp
|
||||
src/utils/screenshot-helper.hpp
|
||||
src/utils/section.cpp
|
||||
@@ -309,32 +268,12 @@ target_sources(
|
||||
src/utils/slider-spinbox.hpp
|
||||
src/utils/source-selection.cpp
|
||||
src/utils/source-selection.hpp
|
||||
src/utils/source-setting.cpp
|
||||
src/utils/source-setting.hpp
|
||||
src/utils/string-list.cpp
|
||||
src/utils/string-list.hpp
|
||||
src/utils/striped-frame.cpp
|
||||
src/utils/striped-frame.hpp
|
||||
src/utils/switch-button.cpp
|
||||
src/utils/switch-button.hpp
|
||||
src/utils/sync-helper.cpp
|
||||
src/utils/sync-helper.hpp
|
||||
src/utils/temp-variable.cpp
|
||||
src/utils/temp-variable.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
|
||||
@@ -381,16 +320,7 @@ 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/exprtk")
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/deps/json/CMakeLists.txt")
|
||||
add_subdirectory(deps/json)
|
||||
else()
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
endif()
|
||||
target_link_libraries(${LIB_NAME} PUBLIC nlohmann_json::nlohmann_json)
|
||||
target_compile_definitions(${LIB_NAME} PRIVATE ADVSS_EXPORT_SYMBOLS=1)
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib")
|
||||
|
||||
# --- End of section ---
|
||||
|
||||
@@ -401,8 +331,7 @@ if(OS_WINDOWS)
|
||||
|
||||
target_compile_definitions(${LIB_NAME} PRIVATE UNICODE _UNICODE)
|
||||
if(MSVC)
|
||||
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267
|
||||
/bigobj)
|
||||
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267)
|
||||
endif()
|
||||
target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp)
|
||||
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
||||
@@ -519,4 +448,3 @@ endif()
|
||||
# --- End of section ---
|
||||
|
||||
add_subdirectory(src/macro-external)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@@ -22,5 +22,9 @@
|
||||
</array>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.13</string>
|
||||
<key>com.apple.security.automation.apple-events</key>
|
||||
<true/>
|
||||
<key>NSAppleEventsUsageDescription</key>
|
||||
<string>Advanced scene switcher needs additional permissions to be able to run AppleScript applications</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -25,7 +25,7 @@ DirExistsWarning=no
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Files]
|
||||
Source: "..\release\*"; Excludes: "*.zip"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "..\release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
Source: "..\LICENSE"; Flags: dontcopy
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
|
||||
@@ -146,15 +146,18 @@ AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Während des
|
||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||
AdvSceneSwitcher.condition.window="Fenster"
|
||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} existiert und ..."
|
||||
AdvSceneSwitcher.condition.window.entry.line2="... ist {{fullscreen}} Vollbild {{maximized}} Maximiert {{focused}} Fokusiert {{windowFocusChanged}} Vordergrundfenster geändert"
|
||||
AdvSceneSwitcher.condition.window.entry.line3="Aktuelles Vordergrundfenster: {{focusWindow}}"
|
||||
AdvSceneSwitcher.condition.file="Datei"
|
||||
AdvSceneSwitcher.condition.file.type.match="entspricht"
|
||||
AdvSceneSwitcher.condition.file.type.contentChange="Inhalt geändert"
|
||||
AdvSceneSwitcher.condition.file.type.dateChange="Änderungsdatum geändert"
|
||||
AdvSceneSwitcher.condition.file.remote="Entfernte Datei"
|
||||
AdvSceneSwitcher.condition.file.local="Lokale Datei"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.media="Medien"
|
||||
AdvSceneSwitcher.condition.media.source="Quelle"
|
||||
AdvSceneSwitcher.condition.media.anyOnScene="Beliebige Medienquelle in"
|
||||
@@ -216,7 +219,7 @@ AdvSceneSwitcher.condition.stream.state.start="Stream läuft"
|
||||
AdvSceneSwitcher.condition.stream.state.stop="Stream gestoppt"
|
||||
AdvSceneSwitcher.condition.stream.state.starting="Stream wird gestartet"
|
||||
AdvSceneSwitcher.condition.stream.state.stopping="Stream wird gestoppt"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
||||
AdvSceneSwitcher.condition.record="Aufnahme"
|
||||
AdvSceneSwitcher.condition.record.state.start="Aufnahme läuft"
|
||||
AdvSceneSwitcher.condition.record.state.pause="Aufnahme pausiert"
|
||||
@@ -325,9 +328,7 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Nächster Treffer bei: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Bei Wiederholung ausgewähltes Datum auf Wiederholungsdatum aktualisieren"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Szenenelement transformieren"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Transformation erhalten"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="Auf{{scenes}}{{sources}}{{types}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="entspricht Transformation"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.changed="hat sich geändert"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="Auf{{scenes}}{{sources}}passt zur Transformation"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||
AdvSceneSwitcher.condition.transition="Übergang"
|
||||
@@ -391,11 +392,12 @@ AdvSceneSwitcher.condition.variable.type.valueChanged="Wert verändert"
|
||||
AdvSceneSwitcher.condition.variable.type.equalsVariable="entspricht Variable"
|
||||
AdvSceneSwitcher.condition.variable.type.lessThanVariable="ist kleiner als die Variable"
|
||||
AdvSceneSwitcher.condition.variable.type.greaterThanVariable="ist größer als die Variable"
|
||||
AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.scene="Szene wechseln"
|
||||
AdvSceneSwitcher.action.scene.entry="Wechsle{{sceneTypes}}Szene zu{{scenes}}mittels{{transitions}}mit einer Dauer von{{duration}}Sekunden"
|
||||
AdvSceneSwitcher.action.scene.entry.noDuration="Wechsle{{sceneTypes}}Szene zu{{scenes}}mittels{{transitions}}"
|
||||
AdvSceneSwitcher.action.switchScene="Szene wechseln"
|
||||
AdvSceneSwitcher.action.scene.entry="Wechsle zu Szene{{scenes}}mittels{{transitions}}mit einer Dauer von{{duration}}Sekunden"
|
||||
AdvSceneSwitcher.action.scene.entry.noDuration="Wechsle zu Szene{{scenes}}mittels{{transitions}}"
|
||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Warten, bis der Übergang zur Zielszene abgeschlossen ist"
|
||||
AdvSceneSwitcher.action.wait="Warten"
|
||||
AdvSceneSwitcher.action.wait.type.fixed="fixe"
|
||||
@@ -426,7 +428,7 @@ AdvSceneSwitcher.action.recording.type.unpause="Aufnahme nicht mehr pausieren"
|
||||
AdvSceneSwitcher.action.recording.type.split="Aufnahme-Datei teilen"
|
||||
AdvSceneSwitcher.action.recording.pause.hint="Bitte beachten, dass je nach Aufnahmeeinstellung die Aufnahme möglicherweise nicht unterbrochen werden kann"
|
||||
AdvSceneSwitcher.action.recording.split.hint="Vergewissern, dass die automatische Dateiaufteilung in den OBS-Einstellungen aktiviert ist!"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.replay="Replay Buffer"
|
||||
AdvSceneSwitcher.action.replay.saveWarn="Warnung: Ein zu häufiges Speichern kann dazu führen, dass der Replay Buffer nicht gespeichert wird!"
|
||||
AdvSceneSwitcher.action.replay.type.stop="Replay Buffer stoppen"
|
||||
@@ -436,15 +438,20 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.streaming="Stream"
|
||||
AdvSceneSwitcher.action.streaming.type.stop="Stream stoppen"
|
||||
AdvSceneSwitcher.action.streaming.type.start="Stream starten"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.run="Ausführen"
|
||||
AdvSceneSwitcher.action.run.arguments="Argumente:"
|
||||
AdvSceneSwitcher.action.run.addArgument="Argument hinzufügen"
|
||||
AdvSceneSwitcher.action.run.addArgumentDescription="Neues Argument hinzufügen:"
|
||||
AdvSceneSwitcher.action.run.entry="Ausführen {{filePath}}"
|
||||
AdvSceneSwitcher.action.run.entry.workingDirectory="Arbeitsverzeichnis:{{workingDirectory}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility="Sichtbarkeit von Szenenelementen"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Anzeigen"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Verstecken"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Umschalten"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Quelle"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Beliebig"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Auf{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Auf{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
||||
AdvSceneSwitcher.action.filter="Filter"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Aktivieren"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Deaktivieren"
|
||||
@@ -459,7 +466,7 @@ AdvSceneSwitcher.action.source.type.refreshSettings="Aktualisieren der Quellenei
|
||||
AdvSceneSwitcher.action.source.type.pressSettingsButton="Drücken der Einstellungstaste"
|
||||
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="Kann verwendet werden, um Browser-, Medien- usw. Quellen zu aktualisieren"
|
||||
AdvSceneSwitcher.action.source.noSettingsButtons="Keine Buttons gefunden!"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
||||
AdvSceneSwitcher.action.source.warning="Warnung: Das globale Aktivieren und Deaktivieren von Quellen kann nicht über die OBS-Benutzeroberfläche gesteuert werden"
|
||||
AdvSceneSwitcher.action.source.getSettings="Aktuelle Einstellungen abfragen"
|
||||
AdvSceneSwitcher.action.media="Medien"
|
||||
@@ -469,14 +476,15 @@ AdvSceneSwitcher.action.media.type.stop="Stoppen"
|
||||
AdvSceneSwitcher.action.media.type.restart="Neu starten"
|
||||
AdvSceneSwitcher.action.media.type.next="Nächste"
|
||||
AdvSceneSwitcher.action.media.type.previous="Vorherige"
|
||||
AdvSceneSwitcher.action.media.type.seek.duration="Suche nach"
|
||||
AdvSceneSwitcher.action.media.type.seek="Suche nach"
|
||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
||||
AdvSceneSwitcher.action.macro="Makro"
|
||||
AdvSceneSwitcher.action.macro.type.pause="Pausieren"
|
||||
AdvSceneSwitcher.action.macro.type.unpause="Nicht mehr pausieren"
|
||||
AdvSceneSwitcher.action.macro.type.resetCounter="Zähler zurücksetzen"
|
||||
AdvSceneSwitcher.action.macro.type.run="Aktionen ausführen"
|
||||
AdvSceneSwitcher.action.macro.type.stop="Aktionen stoppen"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
||||
AdvSceneSwitcher.action.pluginState="Plugin-Status"
|
||||
AdvSceneSwitcher.action.pluginState.type.stop="Erweiterten Automatischen Szenenwechsler stoppen"
|
||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Ändern des Nichtübereinstimmungsverhaltens:"
|
||||
@@ -498,6 +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.sceneOrder="Reihenfolge der Szenenelemente"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Nach oben verschieben"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Nach unten verschieben"
|
||||
@@ -507,7 +516,7 @@ AdvSceneSwitcher.action.sceneOrder.type.movePosition="An Position verschieben"
|
||||
AdvSceneSwitcher.action.sceneOrder.entry="Auf{{scenes}}{{actions}}{{sources}}{{position}}"
|
||||
AdvSceneSwitcher.action.sceneTransform="Szenenelement transformieren"
|
||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Transformation erhalten"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="Auf{{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="Auf{{scenes}}transformieren{{sources}}"
|
||||
AdvSceneSwitcher.action.file="Datei"
|
||||
AdvSceneSwitcher.action.file.type.write="Schreiben"
|
||||
AdvSceneSwitcher.action.file.type.append="Anhängen"
|
||||
@@ -536,6 +545,7 @@ AdvSceneSwitcher.action.random="Zufall"
|
||||
AdvSceneSwitcher.action.random.allowRepeat="Aufeinanderfolgende Ausführung desselben Makros zulassen"
|
||||
AdvSceneSwitcher.action.random.entry="Zufällige Ausführung eines der folgenden Makros (pausierte Makros werden ignoriert)"
|
||||
AdvSceneSwitcher.action.systray="Benachrichtigung im System-Tray"
|
||||
AdvSceneSwitcher.action.systray.entry="Benachrichtigung anzeigen: {{message}}"
|
||||
AdvSceneSwitcher.action.screenshot="Screenshot"
|
||||
AdvSceneSwitcher.action.screenshot.save.default="Standard"
|
||||
AdvSceneSwitcher.action.screenshot.save.custom="Benutzerdefiniert"
|
||||
@@ -558,6 +568,8 @@ AdvSceneSwitcher.action.sequence.continueFrom="Weiter mit ausgewähltem Element"
|
||||
AdvSceneSwitcher.action.websocket="Websocket"
|
||||
AdvSceneSwitcher.action.websocket.type.request="Anfrage"
|
||||
AdvSceneSwitcher.action.websocket.type.event="Ereignis"
|
||||
AdvSceneSwitcher.action.websocket.entry.request="Szenenwechsler {{type}} via {{connection}} senden"
|
||||
AdvSceneSwitcher.action.websocket.entry.event="Szenenwechsler {{type}} an verbundene Clients senden"
|
||||
AdvSceneSwitcher.action.http="HTTP"
|
||||
AdvSceneSwitcher.action.http.type.get="GET"
|
||||
AdvSceneSwitcher.action.http.type.post="POST"
|
||||
@@ -575,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}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
|
||||
|
||||
|
||||
; Transition Tab
|
||||
@@ -635,7 +647,7 @@ AdvSceneSwitcher.mediaTab.states.none="Keine Auswahl"
|
||||
AdvSceneSwitcher.mediaTab.states.playing="Abspielen"
|
||||
AdvSceneSwitcher.mediaTab.states.opening="Öffnen"
|
||||
AdvSceneSwitcher.mediaTab.states.buffering="Buffern"
|
||||
AdvSceneSwitcher.mediaTab.states.paused="Pausiert"
|
||||
AdvSceneSwitcher.mediaTab.states.Paused="Pausiert"
|
||||
AdvSceneSwitcher.mediaTab.states.stopped="Gestoppt"
|
||||
AdvSceneSwitcher.mediaTab.states.ended="Beendet"
|
||||
AdvSceneSwitcher.mediaTab.states.error="Fehler"
|
||||
@@ -713,7 +725,7 @@ AdvSceneSwitcher.sceneSequenceTab.loadFail="Laden der Einstellungen ist fehlgesc
|
||||
AdvSceneSwitcher.sceneSequenceTab.loadSuccess="Laden der Einstellungen war erfolgreich!"
|
||||
AdvSceneSwitcher.sceneSequenceTab.fileType="Text Dateien (*.txt)"
|
||||
AdvSceneSwitcher.sceneSequenceTab.interruptible="kann unterbrochen werden"
|
||||
AdvSceneSwitcher.sceneSequenceTab.interruptibleHint="Andere Szenenwechselmethoden können diese Sequenz unterbrechen"
|
||||
AdvSceneSwitcher.sceneSequenceTab.interruptibleHint="Andere Szenenwechselmethoden können diese Sequenz unterbrechen"
|
||||
AdvSceneSwitcher.sceneSequenceTab.entry="Wenn {{startScenes}} aktiv ist wechsle zu {{scenes}} nach {{delay}} mit {{transitions}} {{interruptible}}"
|
||||
AdvSceneSwitcher.sceneSequenceTab.extendEdit="Szenenfolge erweitern"
|
||||
AdvSceneSwitcher.sceneSequenceTab.extendEntry="Nach {{delay}} wechsle zu {{scenes}} mit {{transitions}}"
|
||||
|
||||
@@ -41,17 +41,17 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Exportar los a
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Importar los ajustes para Advanced Scene Switcher ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Archivos de texto (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="La importacion la configuracion de escenas fallo"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Configuración de escenas importada correctamente"
|
||||
AdvSceneSwitcher.generalTab.priority.fileContent="Contenido del archivo"
|
||||
AdvSceneSwitcher.generalTab.priority.sceneSequence="Secuencia de escenas"
|
||||
AdvSceneSwitcher.generalTab.priority.idleDetection="Detección de inactivos"
|
||||
AdvSceneSwitcher.generalTab.priority.executable="Ejecutable"
|
||||
AdvSceneSwitcher.generalTab.priority.screenRegion="Región de pantalla"
|
||||
AdvSceneSwitcher.generalTab.priority.windowTitle="Título de la ventana"
|
||||
AdvSceneSwitcher.generalTab.priority.media="Medios"
|
||||
AdvSceneSwitcher.generalTab.priority.time="Tiempo"
|
||||
AdvSceneSwitcher.generalTab.priority.audio="Audio"
|
||||
AdvSceneSwitcher.generalTab.priority.video="Video"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Configuración de escenas importada correctamente"
|
||||
AdvSceneSwitcher.generalTab.priority.fileContent="Contenido del archivo"
|
||||
AdvSceneSwitcher.generalTab.priority.sceneSequence="Secuencia de escenas"
|
||||
AdvSceneSwitcher.generalTab.priority.idleDetection="Detección de inactivos"
|
||||
AdvSceneSwitcher.generalTab.priority.executable="Ejecutable"
|
||||
AdvSceneSwitcher.generalTab.priority.screenRegion="Región de pantalla"
|
||||
AdvSceneSwitcher.generalTab.priority.windowTitle="Título de la ventana"
|
||||
AdvSceneSwitcher.generalTab.priority.media="Medios"
|
||||
AdvSceneSwitcher.generalTab.priority.time="Tiempo"
|
||||
AdvSceneSwitcher.generalTab.priority.audio="Audio"
|
||||
AdvSceneSwitcher.generalTab.priority.video="Video"
|
||||
AdvSceneSwitcher.generalTab.priority.macro="Macro"
|
||||
AdvSceneSwitcher.generalTab.setTransitionBy="Al cambiar las transiciones:"
|
||||
AdvSceneSwitcher.generalTab.transitionOverride="Establecer anulaciones de transición"
|
||||
@@ -61,38 +61,38 @@ AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="Al menos una opci
|
||||
; Macro Tab
|
||||
AdvSceneSwitcher.macroTab.title="Macro"
|
||||
AdvSceneSwitcher.macroTab.macros="Macros"
|
||||
AdvSceneSwitcher.macroTab.priorityWarning="Nota: Se recomienda configurar las macros para que sean la funcionalidad de máxima prioridad.\nEsta configuración se puede cambiar en la ficha General."
|
||||
AdvSceneSwitcher.macroTab.help="Las macros le permiten ejecutar una cadena de acciones en función de varias condiciones.\n\nHaga clic en el símbolo más resaltado para agregar una nueva macro."
|
||||
AdvSceneSwitcher.macroTab.editConditionHelp="Esta sección le permite definir las condiciones de la macro.\n\nSeleccione una macro existente o agregue una nueva a la izquierda.\nLuego haga clic en el botón más a continuación para agregar una nueva condición."
|
||||
AdvSceneSwitcher.macroTab.priorityWarning="Nota: Se recomienda configurar las macros para que sean la funcionalidad de máxima prioridad.\nEsta configuración se puede cambiar en la ficha General."
|
||||
AdvSceneSwitcher.macroTab.help="Las macros le permiten ejecutar una cadena de acciones en función de varias condiciones.\n\nHaga clic en el símbolo más resaltado para agregar una nueva macro."
|
||||
AdvSceneSwitcher.macroTab.editConditionHelp="Esta sección le permite definir las condiciones de la macro.\n\nSeleccione una macro existente o agregue una nueva a la izquierda.\nLuego haga clic en el botón más a continuación para agregar una nueva condición."
|
||||
AdvSceneSwitcher.macroTab.editActionHelp="Esta sección le permite definir acciones de la macro.\n\nSeleccione una macro existente o agregue una nueva a la izquierda.\nLuego haga clic en el botón más a continuación para agregar una nueva acción"
|
||||
AdvSceneSwitcher.macroTab.edit="Editar macro"
|
||||
AdvSceneSwitcher.macroTab.edit.logic="Tipo de lógica:"
|
||||
AdvSceneSwitcher.macroTab.edit.condition="Tipo de condición:"
|
||||
AdvSceneSwitcher.macroTab.edit.logic="Tipo de lógica:"
|
||||
AdvSceneSwitcher.macroTab.edit.condition="Tipo de condición:"
|
||||
AdvSceneSwitcher.macroTab.edit.action="Tipo de acción:"
|
||||
AdvSceneSwitcher.macroTab.add="Agregar nueva macro"
|
||||
AdvSceneSwitcher.macroTab.name="Nombre:"
|
||||
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
||||
AdvSceneSwitcher.macroTab.runFail="Error al ejecutar \"%1\" si se ha producido un error en una de las acciones o si la macro ya se está ejecutando."
|
||||
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
||||
AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición"
|
||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||
AdvSceneSwitcher.macroTab.exists="El nombre de la macro ya existe"
|
||||
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
||||
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
||||
AdvSceneSwitcher.macroTab.collapseAll="Contraer todo"
|
||||
AdvSceneSwitcher.macroTab.maximize="Maximizar"
|
||||
AdvSceneSwitcher.macroTab.add="Agregar nueva macro"
|
||||
AdvSceneSwitcher.macroTab.name="Nombre:"
|
||||
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
||||
AdvSceneSwitcher.macroTab.runFail="Error al ejecutar \"%1\" si se ha producido un error en una de las acciones o si la macro ya se está ejecutando."
|
||||
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
||||
AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición"
|
||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||
AdvSceneSwitcher.macroTab.exists="El nombre de la macro ya existe"
|
||||
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
||||
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
||||
AdvSceneSwitcher.macroTab.collapseAll="Contraer todo"
|
||||
AdvSceneSwitcher.macroTab.maximize="Maximizar"
|
||||
AdvSceneSwitcher.macroTab.minimize="Minimizar"
|
||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Resaltar macros ejecutadas recientemente"
|
||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="Resaltar condiciones de la macro seleccionada, que se evaluaron como verdaderas recientemente"
|
||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
|
||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Resaltar macros ejecutadas recientemente"
|
||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="Resaltar condiciones de la macro seleccionada, que se evaluaron como verdaderas recientemente"
|
||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
|
||||
|
||||
; Lógica de macros
|
||||
AdvSceneSwitcher.logic.none="Omitir entrada"
|
||||
AdvSceneSwitcher.logic.and="Y"
|
||||
AdvSceneSwitcher.logic.or="O"
|
||||
AdvSceneSwitcher.logic.andNot="Y no"
|
||||
AdvSceneSwitcher.logic.orNot="O no"
|
||||
AdvSceneSwitcher.logic.rootNone="Si"
|
||||
; Lógica de macros
|
||||
AdvSceneSwitcher.logic.none="Omitir entrada"
|
||||
AdvSceneSwitcher.logic.and="Y"
|
||||
AdvSceneSwitcher.logic.or="O"
|
||||
AdvSceneSwitcher.logic.andNot="Y no"
|
||||
AdvSceneSwitcher.logic.orNot="O no"
|
||||
AdvSceneSwitcher.logic.rootNone="Si"
|
||||
AdvSceneSwitcher.logic.not="Si no"
|
||||
|
||||
; Macro Conditions
|
||||
@@ -122,10 +122,12 @@ AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Durante la tr
|
||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||
AdvSceneSwitcher.condition.window="Ventana"
|
||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} existen y ..."
|
||||
AdvSceneSwitcher.condition.window.entry.line2="... es {{fullscreen}} pantalla completa {{maximized}} maximizada {{focused}} enfocada {{windowFocusChanged}} ventana de primer plano cambiada"
|
||||
AdvSceneSwitcher.condition.file="Archivo"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="Contenido de{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="Contenido de{{fileType}}{{filePath}}{{conditions}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.media="Medios"
|
||||
AdvSceneSwitcher.condition.media.anyOnScene="Cualquier fuente multimedia activada"
|
||||
AdvSceneSwitcher.condition.media.allOnScene="Todas las fuentes de medios activadas"
|
||||
@@ -177,7 +179,7 @@ AdvSceneSwitcher.condition.stream.state.start="Transmisión en ejecución"
|
||||
AdvSceneSwitcher.condition.stream.state.stop="Transmisión detenida"
|
||||
AdvSceneSwitcher.condition.stream.state.starting="Inicio de transmisión"
|
||||
AdvSceneSwitcher.condition.stream.state.stopping="Detener transmisión"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
||||
AdvSceneSwitcher.condition.record="Grabación"
|
||||
AdvSceneSwitcher.condition.record.state.start="Grabación en ejecución"
|
||||
AdvSceneSwitcher.condition.record.state.pause="Grabación en pausa"
|
||||
@@ -275,8 +277,7 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Próxima coincidencia en: %
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Transformar elemento de escena"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtener transformación"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="En{{scenes}}{{sources}}{{types}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="coincide con la transformación"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="En{{scenes}}{{sources}}coincide con la transformación"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||
AdvSceneSwitcher.condition.transition="Transición"
|
||||
@@ -323,8 +324,8 @@ AdvSceneSwitcher.condition.stats.dockHint="Puede abrir el panel de \"Estadístic
|
||||
AdvSceneSwitcher.condition.stats.entry="{{stats}} esta {{condition}} {{value}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.scene="Cambiar escena"
|
||||
AdvSceneSwitcher.action.scene.entry="Cambiar a la{{sceneTypes}}escena{{scenes}}usando{{transitions}}con una duración de{{duration}} segundos"
|
||||
AdvSceneSwitcher.action.switchScene="Cambiar escena"
|
||||
AdvSceneSwitcher.action.scene.entry="Cambiar a la escena {{scenes}} usando {{transitions}} con una duración de {{duration}} segundos"
|
||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Espere hasta que se complete la transición a la escena de destino"
|
||||
AdvSceneSwitcher.action.wait="Esperar"
|
||||
AdvSceneSwitcher.action.wait.type.fixed="fijo"
|
||||
@@ -349,7 +350,7 @@ AdvSceneSwitcher.action.recording.type.start="Iniciar grabación"
|
||||
AdvSceneSwitcher.action.recording.type.pause="Pausar grabación"
|
||||
AdvSceneSwitcher.action.recording.type.unpause="Reanudar grabación"
|
||||
AdvSceneSwitcher.action.recording.pause.hint="Tenga en cuenta que, dependiendo de la configuración de grabación, es posible que no pueda pausar la grabación"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.replay="Búfer de reproducción"
|
||||
AdvSceneSwitcher.action.replay.saveWarn="Advertencia: ¡Guardar con demasiada frecuencia puede hacer que el búfer de reproducción no se guarde realmente!"
|
||||
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
|
||||
@@ -359,14 +360,18 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.streaming="Transmisión"
|
||||
AdvSceneSwitcher.action.streaming.type.stop="Detener transmisión"
|
||||
AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.run="Ejecutar"
|
||||
AdvSceneSwitcher.action.run.arguments="Argumentos:"
|
||||
AdvSceneSwitcher.action.run.addArgument="Agregar argumento"
|
||||
AdvSceneSwitcher.action.run.addArgumentDescription="Añadir nuevo argumento:"
|
||||
AdvSceneSwitcher.action.run.entry="Ejecutar {{filePath}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility="Visibilidad del elemento de escena"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Mostrar"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Fuente"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Cualquiera"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="En{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="En{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
||||
AdvSceneSwitcher.action.filter="Filtro"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Deshabilitar"
|
||||
@@ -377,7 +382,7 @@ AdvSceneSwitcher.action.source="Fuente"
|
||||
AdvSceneSwitcher.action.source.type.enable="Habilitar"
|
||||
AdvSceneSwitcher.action.source.type.disable="Deshabilitar"
|
||||
AdvSceneSwitcher.action.source.type.settings="Establecer configuración"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
||||
AdvSceneSwitcher.action.source.warning="Advertencia: la IU de OBS no puede controlar la habilitación y deshabilitación global de fuentes"
|
||||
AdvSceneSwitcher.action.source.getSettings="Obtener la configuración actual"
|
||||
AdvSceneSwitcher.action.media="Medios"
|
||||
@@ -387,14 +392,15 @@ AdvSceneSwitcher.action.media.type.stop="Detener"
|
||||
AdvSceneSwitcher.action.media.type.restart="Reiniciar"
|
||||
AdvSceneSwitcher.action.media.type.next="Siguiente"
|
||||
AdvSceneSwitcher.action.media.type.previous="Anterior"
|
||||
AdvSceneSwitcher.action.media.type.seek.duration="Buscar"
|
||||
AdvSceneSwitcher.action.media.type.seek="Buscar"
|
||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
||||
AdvSceneSwitcher.action.macro="Macro"
|
||||
AdvSceneSwitcher.action.macro.type.pause="Pausa"
|
||||
AdvSceneSwitcher.action.macro.type.unpause="Reanudar"
|
||||
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
|
||||
AdvSceneSwitcher.action.macro.type.run="Ejecutar"
|
||||
AdvSceneSwitcher.action.macro.type.stop="Detener"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
||||
AdvSceneSwitcher.action.pluginState="Estado del complemento"
|
||||
AdvSceneSwitcher.action.pluginState.type.stop="Detener el complemento Advanced Scene Switcher"
|
||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Cambiar el comportamiento de no coincidencia:"
|
||||
@@ -416,6 +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.sceneOrder="Orden de elementos de escena"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Mover hacia arriba"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover hacia abajo"
|
||||
@@ -425,7 +432,7 @@ AdvSceneSwitcher.action.sceneOrder.type.movePosition="Mover a la posición"
|
||||
AdvSceneSwitcher.action.sceneOrder.entry="En{{scenes}}{{actions}}{{sources}}{{position}}"
|
||||
AdvSceneSwitcher.action.sceneTransform="Transformar elemento de escena"
|
||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Obtener transformación"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="En{{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="En{{scenes}}transformar{{sources}}"
|
||||
AdvSceneSwitcher.action.file="Archivo"
|
||||
AdvSceneSwitcher.action.file.type.write="Escribir"
|
||||
AdvSceneSwitcher.action.file.type.append="Agregar"
|
||||
@@ -453,6 +460,7 @@ AdvSceneSwitcher.action.timer.entry="{{timerAction}} temporizadores en {{macros}
|
||||
AdvSceneSwitcher.action.random="Aleatorio"
|
||||
AdvSceneSwitcher.action.random.entry="Ejecute aleatoriamente cualquiera de las siguientes macros (las macros en pausa se ignoran)"
|
||||
AdvSceneSwitcher.action.systray="Notificación de la bandeja del sistema"
|
||||
AdvSceneSwitcher.action.systray.entry="Mostrar notificación: {{message}}"
|
||||
AdvSceneSwitcher.action.screenshot="Captura de pantalla"
|
||||
AdvSceneSwitcher.action.screenshot.mainOutput="Salida principal de OBS"
|
||||
AdvSceneSwitcher.action.profile="Perfil"
|
||||
@@ -524,7 +532,7 @@ AdvSceneSwitcher.mediaTab.states.none="Ninguno"
|
||||
AdvSceneSwitcher.mediaTab.states.playing="Reproduciéndose"
|
||||
AdvSceneSwitcher.mediaTab.states.opening="Abriendo"
|
||||
AdvSceneSwitcher.mediaTab.states.buffering="Almacenando en búfer"
|
||||
AdvSceneSwitcher.mediaTab.states.paused="Pausado"
|
||||
AdvSceneSwitcher.mediaTab.states.Paused="Pausado"
|
||||
AdvSceneSwitcher.mediaTab.states.stopped="Detenido"
|
||||
AdvSceneSwitcher.mediaTab.states.ended="Finalizado"
|
||||
AdvSceneSwitcher.mediaTab.states.error="Error"
|
||||
@@ -566,7 +574,7 @@ AdvSceneSwitcher.fileTab.help="Esta pestaña te permitirá cambiar escenas autom
|
||||
; Random Tab
|
||||
AdvSceneSwitcher.randomTab.title="Aleatorio"
|
||||
AdvSceneSwitcher.randomTab.randomDisabledWarning="Funcionalidad deshabilitada - para activarla, selecciona \"Si no se cumple ninguna condición de cambio, cambiar a cualquier escena en la pestaña Aleatorio\" en la pestaña General"
|
||||
AdvSceneSwitcher.randomTab.entry="Si no se cumple ninguna condición de cambio, cambiar a {{scenes}} usando {{transitions}} después de {{delay}}"
|
||||
AdvSceneSwitcher.randomTab.entry="Si no se cumple ninguna condición de cambio, cambiar a {{scenes}} usando {{transitions}} después de {{delay}}"
|
||||
AdvSceneSwitcher.randomTab.help="El selector de escenas elegirá aleatoriamente una entrada en esta pestaña para cambiar durante el tiempo configurado.\nTen en cuenta que la misma entrada no se elegirá dos veces seguidas.\n\nHaz clic en el símbolo más resaltado para continuar."
|
||||
|
||||
; Time Tab
|
||||
|
||||
@@ -86,9 +86,10 @@ AdvSceneSwitcher.condition.scene="Сцена"
|
||||
AdvSceneSwitcher.condition.scene.type.current="Текущий"
|
||||
AdvSceneSwitcher.condition.scene.type.previous="Предыдущий"
|
||||
AdvSceneSwitcher.condition.window="Окно"
|
||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} существует и ..."
|
||||
AdvSceneSwitcher.condition.file="Файл"
|
||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.media="Медиа"
|
||||
AdvSceneSwitcher.condition.video="Видео"
|
||||
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
||||
@@ -115,8 +116,8 @@ AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Автоматиче
|
||||
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.scene="Переключить сцену"
|
||||
AdvSceneSwitcher.action.scene.entry="Перейти к сцене{{sceneTypes}}{{scenes}}используя{{transitions}}с продолжительностью{{duration}}секунд"
|
||||
AdvSceneSwitcher.action.switchScene="Переключить сцену"
|
||||
AdvSceneSwitcher.action.scene.entry="Перейти к сцене {{scenes}} используя {{transitions}} с продолжительностью {{duration}} секунд"
|
||||
AdvSceneSwitcher.action.wait="Подождать"
|
||||
AdvSceneSwitcher.action.wait.type.fixed="фиксированный"
|
||||
AdvSceneSwitcher.action.wait.type.random="случайный"
|
||||
@@ -134,7 +135,7 @@ AdvSceneSwitcher.action.recording.type.start="Начать запись"
|
||||
AdvSceneSwitcher.action.recording.type.pause="Пауза записи"
|
||||
AdvSceneSwitcher.action.recording.type.unpause="Снять запись с паузы"
|
||||
AdvSceneSwitcher.action.recording.pause.hint="Обратите внимание, что в зависимости от настроек записи вы можете не иметь возможности приостановить запись"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.replay="Буфер воспроизведения"
|
||||
AdvSceneSwitcher.action.replay.type.stop="Остановить буфер воспроизведения"
|
||||
AdvSceneSwitcher.action.replay.type.start="Начать воспроизведение буфера"
|
||||
@@ -143,7 +144,7 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.streaming="Потоковое вещание"
|
||||
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
||||
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.run="Запустить"
|
||||
|
||||
|
||||
@@ -204,7 +205,7 @@ AdvSceneSwitcher.mediaTab.states.none="Нет"
|
||||
AdvSceneSwitcher.mediaTab.states.playing="Играет"
|
||||
AdvSceneSwitcher.mediaTab.states.opening="Открытие"
|
||||
AdvSceneSwitcher.mediaTab.states.buffering="Буферизация"
|
||||
AdvSceneSwitcher.mediaTab.states.paused="Приостановлено"
|
||||
AdvSceneSwitcher.mediaTab.states.Paused="Приостановлено"
|
||||
AdvSceneSwitcher.mediaTab.states.stopped="Остановлено"
|
||||
AdvSceneSwitcher.mediaTab.states.ended="Закончилось"
|
||||
AdvSceneSwitcher.mediaTab.states.error="Ошибка"
|
||||
|
||||
@@ -112,10 +112,12 @@ AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Geçiş hedefi
|
||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||
AdvSceneSwitcher.condition.window="Pencere"
|
||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} Varolan ve ..."
|
||||
AdvSceneSwitcher.condition.window.entry.line2="... {{fullscreen}} Tam ekran {{maximized}} büyütüldü {{focused}} odaklanıldı {{windowFocusChanged}} ön plan penceresi değişikliği"
|
||||
AdvSceneSwitcher.condition.file="Dosya"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="İçerik{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="İçerik{{fileType}}{{filePath}}{{conditions}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.media="Medya"
|
||||
AdvSceneSwitcher.condition.media.anyOnScene="Herhangi bir medya kaynağı"
|
||||
AdvSceneSwitcher.condition.media.allOnScene="Tüm medya kaynakları "
|
||||
@@ -154,7 +156,7 @@ AdvSceneSwitcher.condition.stream.state.start="Yayın çalışıyor"
|
||||
AdvSceneSwitcher.condition.stream.state.stop="Yayın durdu"
|
||||
AdvSceneSwitcher.condition.stream.state.starting="Yayın başlıyor"
|
||||
AdvSceneSwitcher.condition.stream.state.stopping="Yayın duruyor"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
||||
AdvSceneSwitcher.condition.record="Kayıt"
|
||||
AdvSceneSwitcher.condition.record.state.start="Kayıt Çalışıyor"
|
||||
AdvSceneSwitcher.condition.record.state.pause="Kayıt durakladı"
|
||||
@@ -231,8 +233,7 @@ AdvSceneSwitcher.condition.date.state.before="Önce"
|
||||
AdvSceneSwitcher.condition.date.state.between="Arasında"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Sahne öğesi dönüşümü"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Dönüşümü al"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="Açık{{scenes}}{{sources}}{{types}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="dönüşümle eşleşir"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="Açık{{scenes}}{{sources}} dönüşümle eşleşir"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||
AdvSceneSwitcher.condition.transition="Geçiş"
|
||||
@@ -260,8 +261,8 @@ AdvSceneSwitcher.condition.openvr.entry.line2="{{controls}}"
|
||||
AdvSceneSwitcher.condition.openvr.entry.line3="HMD mevcut {{xPos}} x {{yPos}} x {{zPos}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.scene="Sahne Degistirici"
|
||||
AdvSceneSwitcher.action.scene.entry="Sahneyi{{sceneTypes}}{{scenes}}kullanarak{{transitions}}süresi olan{{duration}}saniye"
|
||||
AdvSceneSwitcher.action.switchScene="Sahne Degistirici"
|
||||
AdvSceneSwitcher.action.scene.entry="Sahneyi {{scenes}} kullanarak {{transitions}} süresi olan {{duration}} saniye"
|
||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Hedef sahneye geçiş tamamlanana kadar bekleyin"
|
||||
AdvSceneSwitcher.action.wait="Bekle"
|
||||
AdvSceneSwitcher.action.wait.type.fixed="sabit"
|
||||
@@ -280,7 +281,7 @@ AdvSceneSwitcher.action.recording.type.start="Kayıt Başlat"
|
||||
AdvSceneSwitcher.action.recording.type.pause="Kayıt Duraklat"
|
||||
AdvSceneSwitcher.action.recording.type.unpause="Kayıt Duraklatma"
|
||||
AdvSceneSwitcher.action.recording.pause.hint="Kayıt ayarlarınıza bağlı olarak kaydı duraklatamayabileceğinizi unutmayın."
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.replay="Tekrar arabelleği"
|
||||
AdvSceneSwitcher.action.replay.type.stop="Tekrar arabelleğini durdur"
|
||||
AdvSceneSwitcher.action.replay.type.start="Tekrar arabelleğini başlat"
|
||||
@@ -289,14 +290,18 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.streaming="Yayın"
|
||||
AdvSceneSwitcher.action.streaming.type.stop="Yayın durdur"
|
||||
AdvSceneSwitcher.action.streaming.type.start="Yayın başlat"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.run="Çalıştır"
|
||||
AdvSceneSwitcher.action.run.arguments="Argümanlar:"
|
||||
AdvSceneSwitcher.action.run.addArgument="Argüman ekle"
|
||||
AdvSceneSwitcher.action.run.addArgumentDescription="Yeni Argüman ekle:"
|
||||
AdvSceneSwitcher.action.run.entry="Çalıştır {{filePath}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility="Sahne öğesi görünürlüğü"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Göster"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Gizle"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Kayıt"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Herhangi"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Açık{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Açık{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
||||
AdvSceneSwitcher.action.filter="Filtrele"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Etkin"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Etkisiz"
|
||||
@@ -307,7 +312,7 @@ AdvSceneSwitcher.action.source="Kaynak"
|
||||
AdvSceneSwitcher.action.source.type.enable="Etkin"
|
||||
AdvSceneSwitcher.action.source.type.disable="Etkisiz"
|
||||
AdvSceneSwitcher.action.source.type.settings="Ayarları yap"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
||||
AdvSceneSwitcher.action.source.warning="Uyarı: Kaynakların global olarak etkinleştirilmesi ve devre dışı bırakılması, OBS UI tarafından kontrol edilemez"
|
||||
AdvSceneSwitcher.action.source.getSettings="Mevcut Ayarları yap"
|
||||
AdvSceneSwitcher.action.media="Medya"
|
||||
@@ -317,12 +322,13 @@ AdvSceneSwitcher.action.media.type.stop="Dur"
|
||||
AdvSceneSwitcher.action.media.type.restart="Yeniden Başlat"
|
||||
AdvSceneSwitcher.action.media.type.next="Sonraki"
|
||||
AdvSceneSwitcher.action.media.type.previous="Önceki"
|
||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
||||
AdvSceneSwitcher.action.macro="Makro"
|
||||
AdvSceneSwitcher.action.macro.type.pause="Duraklat"
|
||||
AdvSceneSwitcher.action.macro.type.unpause="Duraklatma"
|
||||
AdvSceneSwitcher.action.macro.type.resetCounter="Sayacı sıfırla"
|
||||
AdvSceneSwitcher.action.macro.type.run="Çalıştır"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
||||
AdvSceneSwitcher.action.pluginState="Eklenti durumu"
|
||||
AdvSceneSwitcher.action.pluginState.type.stop="Advanced Scene Switcher eklentisini durdurun"
|
||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Eşleşmeme davranışını değiştirin:"
|
||||
@@ -344,6 +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.sceneOrder="Sahne öğesi sırası"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Yukarı taşı"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Aşağı indir"
|
||||
@@ -353,7 +360,7 @@ AdvSceneSwitcher.action.sceneOrder.type.movePosition="Konuma taşı"
|
||||
AdvSceneSwitcher.action.sceneOrder.entry="Açık{{scenes}}{{actions}}{{sources}}{{position}}"
|
||||
AdvSceneSwitcher.action.sceneTransform="Sahne öğesi dönüşümü"
|
||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Dönüşümü al"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="Açık{{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="Açık{{scenes}}transform{{sources}}"
|
||||
AdvSceneSwitcher.action.file="Dosya"
|
||||
AdvSceneSwitcher.action.file.type.write="Yaz"
|
||||
AdvSceneSwitcher.action.file.type.append="Ekle"
|
||||
@@ -370,6 +377,7 @@ AdvSceneSwitcher.action.timer.entry="{{timerAction}} zamanlayıcılar açık {{m
|
||||
AdvSceneSwitcher.action.random="Rastgele"
|
||||
AdvSceneSwitcher.action.random.entry="Aşağıdaki makrolardan herhangi birini rastgele çalıştırın (duraklatılmış makrolar yoksayılır)"
|
||||
AdvSceneSwitcher.action.systray="Sistem tepsisi bildirimi"
|
||||
AdvSceneSwitcher.action.systray.entry="Bildirimleri göster: {{message}}"
|
||||
AdvSceneSwitcher.action.screenshot="Ekran görüntüsü"
|
||||
AdvSceneSwitcher.action.screenshot.mainOutput="OBS'nin ana çıkışı"
|
||||
AdvSceneSwitcher.action.profile="Profil"
|
||||
@@ -435,7 +443,7 @@ AdvSceneSwitcher.mediaTab.states.none="Yok"
|
||||
AdvSceneSwitcher.mediaTab.states.playing="Oynamak"
|
||||
AdvSceneSwitcher.mediaTab.states.opening="Açmak"
|
||||
AdvSceneSwitcher.mediaTab.states.buffering="Arabelleğe alma"
|
||||
AdvSceneSwitcher.mediaTab.states.paused="Duraklatıldı"
|
||||
AdvSceneSwitcher.mediaTab.states.Paused="Duraklatıldı"
|
||||
AdvSceneSwitcher.mediaTab.states.stopped="Durduruldu"
|
||||
AdvSceneSwitcher.mediaTab.states.ended="Bitti"
|
||||
AdvSceneSwitcher.mediaTab.states.error="Hata"
|
||||
|
||||
@@ -4,7 +4,7 @@ AdvSceneSwitcher.windowTitle="高级场景切换器"
|
||||
; General Tab
|
||||
AdvSceneSwitcher.generalTab.title="通用"
|
||||
AdvSceneSwitcher.generalTab.status="状态"
|
||||
AdvSceneSwitcher.generalTab.status.hotkeytips="快捷键可在OBS设置中设置<br><br>汉化作者:[ 从不咕咕的阿坤 ] - 全平台统一名 - 如对你有所帮助,劳烦点个关注!"
|
||||
AdvSceneSwitcher.generalTab.status.hotkeytips="快捷键可在OBS设置中设置"
|
||||
AdvSceneSwitcher.generalTab.status.currentStatus="当前状态:"
|
||||
AdvSceneSwitcher.generalTab.status.onStartup="在OBS启动时"
|
||||
AdvSceneSwitcher.generalTab.status.onStartup.asLastRun="按照最后运行时的状态"
|
||||
@@ -24,14 +24,11 @@ AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip="时间精度最
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.dontSwitch="不切换"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchToRandom="切换到随机场景列表中任意随机场景"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="切换到"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.cooldown="执行完操作后,跳过执行操作,为"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="在此期间,可能的匹配项将被忽略!"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="详细日志输出"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="保存窗口位置和大小"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="显示系统托盘通知"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="禁用UI提示"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="如果无法加载插件显示警告"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>加载以下插件库失败,这可能导致某些高级场景切换器功能不可用:%1 查看 OBS 日志了解详细信息.<br>可以在“常规”选项卡上禁用此消息.</body></html>"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="隐藏可通过宏操作的分组栏"
|
||||
AdvSceneSwitcher.generalTab.matchBehavior="场景匹配设置"
|
||||
AdvSceneSwitcher.generalTab.priority="优先级"
|
||||
@@ -81,39 +78,17 @@ AdvSceneSwitcher.macroTab.runFail="运行 \"%1\" 失败!\n其中一个操作失
|
||||
AdvSceneSwitcher.macroTab.runInParallel="与其他宏同时运行宏"
|
||||
AdvSceneSwitcher.macroTab.onChange="仅在条件更改时执行操作"
|
||||
AdvSceneSwitcher.macroTab.defaultname="宏 %1"
|
||||
AdvSceneSwitcher.macroTab.defaultGroupName="组 %1"
|
||||
AdvSceneSwitcher.macroTab.exists="宏名称已存在"
|
||||
AdvSceneSwitcher.macroTab.groupDeleteConfirm="您确定要删除 \"%1\"及其所有元素吗?"
|
||||
AdvSceneSwitcher.macroTab.deleteMultipleMacrosConfirmation="您确定要删除 %1 宏吗?"
|
||||
AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation="你确定你要删除 \"%1\"?"
|
||||
AdvSceneSwitcher.macroTab.contextMenuAdd="增加"
|
||||
AdvSceneSwitcher.macroTab.copy="创建副本"
|
||||
AdvSceneSwitcher.macroTab.group="对选定的宏进行分组"
|
||||
AdvSceneSwitcher.macroTab.ungroup="解除选定的组的分组"
|
||||
AdvSceneSwitcher.macroTab.rename="重命名"
|
||||
AdvSceneSwitcher.macroTab.remove="删除"
|
||||
AdvSceneSwitcher.macroTab.expandAll="全部展开"
|
||||
AdvSceneSwitcher.macroTab.collapseAll="全部收回"
|
||||
AdvSceneSwitcher.macroTab.maximize="最大化"
|
||||
AdvSceneSwitcher.macroTab.minimize="最小化"
|
||||
AdvSceneSwitcher.macroTab.highlightSettings="显示 设置"
|
||||
AdvSceneSwitcher.macroTab.hotkeySettings="热键 设置"
|
||||
AdvSceneSwitcher.macroTab.dockSettings="停靠 设置"
|
||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="突出显示最近执行的宏"
|
||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="突出显示最近运算为 真 的当前选定宏的条件"
|
||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="突出显示当前选定宏的最近执行的操作"
|
||||
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="使用快捷键控制新增宏的暂停状态"
|
||||
AdvSceneSwitcher.macroTab.currentDisableHotkeys="使用快捷键控制所选宏的暂停状态"
|
||||
AdvSceneSwitcher.macroTab.currentRegisterDock="注册停靠小部件以控制所选宏的暂停状态或手动运行它"
|
||||
AdvSceneSwitcher.macroTab.currentDockAddRunButton="添加按钮以运行宏"
|
||||
AdvSceneSwitcher.macroTab.currentDockAddPauseButton="添加按钮以暂停或取消暂停宏"
|
||||
AdvSceneSwitcher.macroTab.currentDockButtonText.run="运行按钮文本:"
|
||||
AdvSceneSwitcher.macroTab.currentDockButtonText.pause="暂停按钮文本:"
|
||||
AdvSceneSwitcher.macroTab.currentDockButtonText.unpause="取消暂停按钮文本:"
|
||||
|
||||
AdvSceneSwitcher.macroDock.pause="暂停"
|
||||
AdvSceneSwitcher.macroDock.unpause="取消暂停"
|
||||
AdvSceneSwitcher.macroDock.run="运行"
|
||||
|
||||
; Macro List
|
||||
AdvSceneSwitcher.macroList.deleted="删除"
|
||||
@@ -137,17 +112,10 @@ AdvSceneSwitcher.condition.audio.state.mute="静音"
|
||||
AdvSceneSwitcher.condition.audio.state.unmute="取消静音"
|
||||
AdvSceneSwitcher.condition.audio.type.output="输出音频"
|
||||
AdvSceneSwitcher.condition.audio.type.volume="配置音量级别"
|
||||
AdvSceneSwitcher.condition.audio.type.syncOffset="同步偏移"
|
||||
AdvSceneSwitcher.condition.audio.type.monitor="音频监控"
|
||||
AdvSceneSwitcher.condition.audio.type.balance="音频平衡"
|
||||
AdvSceneSwitcher.condition.audio.entry="{{checkType}} 的 {{audioSources}} 是 {{condition}}{{volume}}{{syncOffset}}{{monitorTypes}}"
|
||||
AdvSceneSwitcher.condition.cursor="屏幕区域"
|
||||
AdvSceneSwitcher.condition.cursor.type.region="当前位置"
|
||||
AdvSceneSwitcher.condition.cursor.type.moving="正在移动"
|
||||
AdvSceneSwitcher.condition.cursor.type.click="点击"
|
||||
AdvSceneSwitcher.condition.cursor.button.left="鼠标左键"
|
||||
AdvSceneSwitcher.condition.cursor.button.middle="鼠标中键"
|
||||
AdvSceneSwitcher.condition.cursor.button.right="鼠标右键"
|
||||
AdvSceneSwitcher.condition.cursor.showFrame="显示帧率"
|
||||
AdvSceneSwitcher.condition.cursor.hideFrame="隐藏帧率"
|
||||
AdvSceneSwitcher.condition.cursor.entry.line1="鼠标 处于{{conditions}}{{buttons}}{{minX}}{{minY}}{{maxX}}{{maxY}}{{toggleFrameButton}}"
|
||||
@@ -157,47 +125,36 @@ AdvSceneSwitcher.condition.scene.type.current="当前场景是"
|
||||
AdvSceneSwitcher.condition.scene.type.previous="上一个场景是"
|
||||
AdvSceneSwitcher.condition.scene.type.changed="场景改变了"
|
||||
AdvSceneSwitcher.condition.scene.type.notChanged="场景没有改变"
|
||||
AdvSceneSwitcher.condition.scene.type.currentPattern="当前场景匹配"
|
||||
AdvSceneSwitcher.condition.scene.type.previousPattern="上一个场景匹配"
|
||||
AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="在转场过程中检查转场源场景"
|
||||
AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="在转场过程中检查转场源场景"
|
||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||
AdvSceneSwitcher.condition.window="窗口"
|
||||
AdvSceneSwitcher.condition.window.entry.window="{{checkTitle}}窗口标题匹配{{windowRegex}}{{windows}}"
|
||||
AdvSceneSwitcher.condition.window.entry.fullscreen="{{fullscreen}}窗口为全屏"
|
||||
AdvSceneSwitcher.condition.window.entry.maximized="{{maximized}}窗口为最大化"
|
||||
AdvSceneSwitcher.condition.window.entry.focused="{{focused}}窗口为焦点"
|
||||
AdvSceneSwitcher.condition.window.entry.focusedChange="{{windowFocusChanged}}焦点窗口被改变"
|
||||
AdvSceneSwitcher.condition.window.entry.text="{{checkText}}窗口包含文本{{textRegex}}{{windowText}}"
|
||||
AdvSceneSwitcher.condition.window.entry.text.note="此选项可能不会对窗口中显示的每个文本起作用。\n如果是这种情况,您可以考虑使用视频条件OCR检查来代替。"
|
||||
AdvSceneSwitcher.condition.window.entry.currentFocus="当前焦点窗口:{{focusWindow}}"
|
||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} 存在..."
|
||||
AdvSceneSwitcher.condition.window.entry.line2="... 并且是 {{fullscreen}} 全屏 {{maximized}} 最大化 {{focused}} 获得焦点 {{windowFocusChanged}} 焦点窗口已更改"
|
||||
AdvSceneSwitcher.condition.window.entry.line3="当前焦点窗口: {{focusWindow}}"
|
||||
AdvSceneSwitcher.condition.file="文件"
|
||||
AdvSceneSwitcher.condition.file.type.match="内容完全匹配"
|
||||
AdvSceneSwitcher.condition.file.type.contentChange="内容已更改"
|
||||
AdvSceneSwitcher.condition.file.type.dateChange="修改日期已更改"
|
||||
AdvSceneSwitcher.condition.file.remote="远程文件"
|
||||
AdvSceneSwitcher.condition.file.local="本地文件"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line1="文件内容来自{{fileType}}{{filePath}}{{conditions}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||
AdvSceneSwitcher.condition.media="媒体"
|
||||
AdvSceneSwitcher.condition.media.source="源"
|
||||
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体源"
|
||||
AdvSceneSwitcher.condition.media.allOnScene="所有媒体源"
|
||||
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体来源"
|
||||
AdvSceneSwitcher.condition.media.allOnScene="所有媒体来源"
|
||||
AdvSceneSwitcher.condition.media.matchOnChange="仅在更改时匹配(注意:此选项将在未来版本中删除-请改用时间限制)"
|
||||
AdvSceneSwitcher.condition.media.inconsistencyInfo="不幸的是,并非所有媒体源类型的行为都相同(例如,媒体源与VLC视频源“停止”状态)。\n所以,请尝试适合您的设置!"
|
||||
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}} 的状态是 {{states}} 和 {{timeRestrictions}}{{time}}"
|
||||
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}的状态是{{states}}和{{timeRestrictions}}{{time}}"
|
||||
AdvSceneSwitcher.condition.video="视频"
|
||||
AdvSceneSwitcher.condition.video.condition.match="完全匹配"
|
||||
AdvSceneSwitcher.condition.video.condition.differ="不匹配"
|
||||
AdvSceneSwitcher.condition.video.condition.hasChanged="已改变"
|
||||
AdvSceneSwitcher.condition.video.condition.hasNotChanged="未改变"
|
||||
AdvSceneSwitcher.condition.video.condition.hasChanged="改变了"
|
||||
AdvSceneSwitcher.condition.video.condition.hasNotChanged="没有改变"
|
||||
AdvSceneSwitcher.condition.video.condition.noImage="没有输出"
|
||||
AdvSceneSwitcher.condition.video.condition.pattern="匹配模式"
|
||||
AdvSceneSwitcher.condition.video.condition.object="包含对象"
|
||||
AdvSceneSwitcher.condition.video.condition.brightness="亮度"
|
||||
AdvSceneSwitcher.condition.video.condition.ocr="包含文本"
|
||||
AdvSceneSwitcher.condition.video.askFileAction="是否要使用现有文件或创建当前选定源的屏幕截图?"
|
||||
AdvSceneSwitcher.condition.video.askFileAction.file="使用现有文件"
|
||||
AdvSceneSwitcher.condition.video.askFileAction.screenshot="创建屏幕截图"
|
||||
@@ -207,49 +164,28 @@ AdvSceneSwitcher.condition.video.usePatternForChangedCheck="使用模式匹配"
|
||||
AdvSceneSwitcher.condition.video.usePatternForChangedCheck.tooltip="这将允许您控制图像必须更改多少才能使条件为真."
|
||||
AdvSceneSwitcher.condition.video.patternThreshold="阈值: "
|
||||
AdvSceneSwitcher.condition.video.patternThresholdDescription="较高的阈值意味着模式需要更紧密地匹配视频源."
|
||||
AdvSceneSwitcher.condition.video.patternThresholdUseAlphaAsMask="使用alpha通道作为模式的遮罩."
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode="使用模式匹配方式 {{patternMatchingModes}}"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.crossCorrelation="交叉相关"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.correlationCoefficient="相关系数"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.squaredDifference="平方差"
|
||||
AdvSceneSwitcher.condition.video.patternMatchMode.tip="使用的最佳方法取决于具体问题和所涉及图像的特性。\n在实践中,通常需要使用不同的方法和参数进行实验,以找到对特定用例的最佳匹配。"
|
||||
AdvSceneSwitcher.condition.video.patternThresholdUseAlphaAsMask="使用alpha通道作为图案的遮罩."
|
||||
AdvSceneSwitcher.condition.video.brightnessThreshold="平均亮度:"
|
||||
AdvSceneSwitcher.condition.video.brightnessThresholdDescription="高的值表示明亮的图像,低的值表示较暗的图像。"
|
||||
AdvSceneSwitcher.condition.video.brightnessThresholdDescription="较高的值表示图像较亮,较低的值表示图像较暗。"
|
||||
AdvSceneSwitcher.condition.video.currentBrightness="当前平均亮度: %1"
|
||||
AdvSceneSwitcher.condition.video.objectScaleThreshold="模型比例: "
|
||||
AdvSceneSwitcher.condition.video.objectScaleThresholdDescription="较低的模型比例会产生更多的匹配,但将导致CPU负载更高."
|
||||
AdvSceneSwitcher.condition.video.objectScaleThresholdDescription="较低的模比例将导致更多的匹配,但会导致更高的CPU负载."
|
||||
AdvSceneSwitcher.condition.video.minNeighborDescription="较高的“最小区域”值将导致较少但质量较高的匹配."
|
||||
AdvSceneSwitcher.condition.video.showMatch="显示模式"
|
||||
AdvSceneSwitcher.condition.video.showMatch.loading="检查是否匹配"
|
||||
AdvSceneSwitcher.condition.video.showMatch.loading="Checking for match"
|
||||
AdvSceneSwitcher.condition.video.screenshotFail="无法获取源的屏幕截图!"
|
||||
AdvSceneSwitcher.condition.video.screenshotEmpty="屏幕截图为空 - 源是否可见?"
|
||||
AdvSceneSwitcher.condition.video.screenshotEmpty="Screenshot is empty - Is the source visible?"
|
||||
AdvSceneSwitcher.condition.video.patternMatchFail="没有找到模式!"
|
||||
AdvSceneSwitcher.condition.video.patternMatchSuccess="模式以红色突出显示"
|
||||
AdvSceneSwitcher.condition.video.patternMatchSuccess="Pattern is highlighted in red"
|
||||
AdvSceneSwitcher.condition.video.objectMatchFail="找不到对象!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="对象以红色突出显示"
|
||||
AdvSceneSwitcher.condition.video.ocrMatchSuccess="检测到的文本:\n\n%1"
|
||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="无法加载模型数据!"
|
||||
AdvSceneSwitcher.condition.video.selectColor="选择颜色"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleColumn="单列可变大小的文本"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleBlockVertText="垂直对齐的单个统一文本块"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleBlock="单个统一的文本块"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleLine="单个文本行"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleWord="单词"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.circleWord="圆圈中的单个单词"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleChar="单个字符"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.sparseText="不按特定顺序查找文本"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.sparseTextOSD="不按特定顺序查找文本(OSD)"
|
||||
AdvSceneSwitcher.condition.video.type.main="OBS的主输出"
|
||||
AdvSceneSwitcher.condition.video.type.source="源"
|
||||
AdvSceneSwitcher.condition.video.type.scene="场景"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小区域: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}每隔一段时间检查一次,来减少CPU负载 {{throttleCount}} 毫秒"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}通过只执行每一次检查来减少CPU负载 {{throttleCount}} 毫秒"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="仅在区域内执行检查"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="检查文本颜色:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="检查文本类型:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="最小尺寸:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="最大尺寸:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="选择区域"
|
||||
@@ -261,25 +197,21 @@ AdvSceneSwitcher.condition.stream.state.start="推流启动"
|
||||
AdvSceneSwitcher.condition.stream.state.stop="推流停止"
|
||||
AdvSceneSwitcher.condition.stream.state.starting="推流启动中"
|
||||
AdvSceneSwitcher.condition.stream.state.stopping="推流停止中"
|
||||
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="关键帧间隔等于"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
||||
AdvSceneSwitcher.condition.record="录制"
|
||||
AdvSceneSwitcher.condition.record.state.start="录制运行中"
|
||||
AdvSceneSwitcher.condition.record.state.pause="录制暂停"
|
||||
AdvSceneSwitcher.condition.record.state.stop="录制停止"
|
||||
AdvSceneSwitcher.condition.record.entry="{{recordState}}"
|
||||
AdvSceneSwitcher.condition.process="进程"
|
||||
AdvSceneSwitcher.condition.process.entry="{{processes}} 是正在运行 {{focused}} 并且是获得焦点"
|
||||
AdvSceneSwitcher.condition.process.entry="{{processes}} 是正在运行 {{focused}} 而且是获得焦点"
|
||||
AdvSceneSwitcher.condition.process.entry.focus="当前焦点进程: {{focusProcess}}"
|
||||
AdvSceneSwitcher.condition.idle="闲置检测"
|
||||
AdvSceneSwitcher.condition.idle.entry="没有键盘或鼠标输入{{duration}}"
|
||||
AdvSceneSwitcher.condition.pluginState="插件状态"
|
||||
AdvSceneSwitcher.condition.pluginState.state.start="插件已启动"
|
||||
AdvSceneSwitcher.condition.pluginState.state.restart="插件已重新启动"
|
||||
AdvSceneSwitcher.condition.pluginState.state.running="插件正在运行"
|
||||
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="在此时间间隔内触发了自动场景更改"
|
||||
AdvSceneSwitcher.condition.pluginState.state.running="高级场景切换程序正在运行"
|
||||
AdvSceneSwitcher.condition.pluginState.state.shutdown="OBS正在关闭"
|
||||
AdvSceneSwitcher.condition.pluginState.state.sceneCollection="场景集合已加载"
|
||||
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="场景被上一个宏改变"
|
||||
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
||||
AdvSceneSwitcher.condition.timer="计时器"
|
||||
AdvSceneSwitcher.condition.timer.type.fixed="固定"
|
||||
@@ -304,11 +236,11 @@ AdvSceneSwitcher.condition.macro.state.type.above="大于"
|
||||
AdvSceneSwitcher.condition.macro.state.type.equal="等于"
|
||||
AdvSceneSwitcher.condition.macro.count.reset="重置"
|
||||
AdvSceneSwitcher.condition.macro.pausedWarning="所选宏当前已暂停!"
|
||||
AdvSceneSwitcher.condition.macro.state.entry="{{macros}} 的条件为真"
|
||||
AdvSceneSwitcher.condition.macro.multistate.entry=" 以下宏的 {{multiStateConditions}}{{multiStateCount}} 的条件为真:"
|
||||
AdvSceneSwitcher.condition.macro.count.entry.line1="{{macros}} 执行 {{conditions}} {{count}} 次(相对于下面计数匹配)"
|
||||
AdvSceneSwitcher.condition.macro.state.entry="条件 {{macros}} 运行结果为真"
|
||||
AdvSceneSwitcher.condition.macro.multistate.entry="条件 {{multiStateConditions}}{{multiStateCount}} 以下宏运行结果为真:"
|
||||
AdvSceneSwitcher.condition.macro.count.entry.line1="{{macros}} 运行 {{conditions}} {{count}} 次(相对于下面计数匹配)"
|
||||
AdvSceneSwitcher.condition.macro.count.entry.line2="当前计数: {{currentCount}} {{resetCount}}"
|
||||
AdvSceneSwitcher.condition.source="源"
|
||||
AdvSceneSwitcher.condition.source="来源"
|
||||
AdvSceneSwitcher.condition.source.type.active="是激活状态"
|
||||
AdvSceneSwitcher.condition.source.type.showing="是显示状态"
|
||||
AdvSceneSwitcher.condition.source.type.settings="设置完全匹配"
|
||||
@@ -325,7 +257,7 @@ AdvSceneSwitcher.condition.filter.type.active="已启用"
|
||||
AdvSceneSwitcher.condition.filter.type.showing="已关闭"
|
||||
AdvSceneSwitcher.condition.filter.type.settings="设置完全匹配"
|
||||
AdvSceneSwitcher.condition.filter.getSettings="获取当前设置"
|
||||
AdvSceneSwitcher.condition.filter.entry.line1="在 {{sources}} 的 {{filters}} 是 {{conditions}}"
|
||||
AdvSceneSwitcher.condition.filter.entry.line1="在 {{sources}} {{filters}} {{conditions}}"
|
||||
AdvSceneSwitcher.condition.filter.entry.line2="{{settings}}"
|
||||
AdvSceneSwitcher.condition.filter.entry.line3="{{regex}} {{getSettings}}"
|
||||
AdvSceneSwitcher.condition.sceneOrder="场景项目顺序"
|
||||
@@ -357,8 +289,7 @@ AdvSceneSwitcher.condition.date.state.at="现在"
|
||||
AdvSceneSwitcher.condition.date.state.after="之后"
|
||||
AdvSceneSwitcher.condition.date.state.before="之前"
|
||||
AdvSceneSwitcher.condition.date.state.between="之间"
|
||||
AdvSceneSwitcher.condition.date.state.pattern="模式"
|
||||
AdvSceneSwitcher.condition.date.separator="到"
|
||||
AdvSceneSwitcher.condition.date.separator="和"
|
||||
AdvSceneSwitcher.condition.date.ignoreDate="如果未选中,日期组件将被忽略"
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="如果未选中,时间组件将被忽略"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="显示高级设置"
|
||||
@@ -366,13 +297,11 @@ AdvSceneSwitcher.condition.date.showSimpleSettings="显示简单设置"
|
||||
AdvSceneSwitcher.condition.date.entry.simple="在 {{dayOfWeek}} {{weekCondition}} {{ignoreWeekTime}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} 在匹配到日期时间后,每隔 {{duration}} 重复一次"
|
||||
AdvSceneSwitcher.condition.date.entry.pattern="当前日期 \"{{currentDate}}\" 匹配模式 {{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="下一次匹配 在: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} 重复时,将选定的日期更新为重复日期"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Next match at: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} On repeat update selected date to repeat date"
|
||||
AdvSceneSwitcher.condition.sceneTransform="场景项目被改变"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="内容或者设置被改变了"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="在 {{scenes}} {{sources}} {{types}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="匹配变换"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="在 {{scenes}} {{sources}} 匹配变换"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||
AdvSceneSwitcher.condition.transition="转场"
|
||||
@@ -387,7 +316,6 @@ AdvSceneSwitcher.condition.transition.entry="{{conditions}}{{transitions}}{{scen
|
||||
AdvSceneSwitcher.condition.sceneVisibility="场景项目可见"
|
||||
AdvSceneSwitcher.condition.sceneVisibility.type.shown="显示的"
|
||||
AdvSceneSwitcher.condition.sceneVisibility.type.hidden="隐藏的"
|
||||
AdvSceneSwitcher.condition.sceneVisibility.type.changed="可见性已更改"
|
||||
AdvSceneSwitcher.condition.sceneVisibility.entry="在 {{scenes}} {{sources}} 是 {{conditions}} "
|
||||
AdvSceneSwitcher.condition.studioMode="工作室模式"
|
||||
AdvSceneSwitcher.condition.studioMode.state.active="工作室模式处于活动状态"
|
||||
@@ -417,7 +345,7 @@ AdvSceneSwitcher.condition.stats.condition.above="大于"
|
||||
AdvSceneSwitcher.condition.stats.condition.equals="等于"
|
||||
AdvSceneSwitcher.condition.stats.condition.below="少于"
|
||||
AdvSceneSwitcher.condition.stats.dockHint="你可以打开“统计”窗口查看当前状态"
|
||||
AdvSceneSwitcher.condition.stats.entry="{{stats}} 是 {{condition}} {{value}}"
|
||||
AdvSceneSwitcher.condition.stats.entry="{{stats}} is {{condition}} {{value}}"
|
||||
AdvSceneSwitcher.condition.profile="配置文件"
|
||||
AdvSceneSwitcher.condition.profile.entry="当前活动的配置文件为 {{profiles}}"
|
||||
AdvSceneSwitcher.condition.websocket="websocket"
|
||||
@@ -433,24 +361,12 @@ AdvSceneSwitcher.condition.variable.type.number="是一个数字"
|
||||
AdvSceneSwitcher.condition.variable.type.lessThan="小于"
|
||||
AdvSceneSwitcher.condition.variable.type.greaterThan="大于"
|
||||
AdvSceneSwitcher.condition.variable.type.valueChanged="值已更改"
|
||||
AdvSceneSwitcher.condition.variable.type.equalsVariable="等于变量"
|
||||
AdvSceneSwitcher.condition.variable.type.lessThanVariable="小于变量"
|
||||
AdvSceneSwitcher.condition.variable.type.greaterThanVariable="大于变量"
|
||||
AdvSceneSwitcher.condition.run="运行"
|
||||
AdvSceneSwitcher.condition.run.entry="进程在超时 {{timeout}} 秒之前退出"
|
||||
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}检查退出代码{{exitCode}}"
|
||||
AdvSceneSwitcher.condition.midi="MIDI"
|
||||
AdvSceneSwitcher.condition.midi.entry="从{{device}} 收到的信息,符合:(从不咕咕的阿坤:这个好像是声卡工作是录音相关的功能,英文太抽象了,我就硬译过来了,如有相关设备,音乐好的,可以根据英文翻译好发给我!)"
|
||||
AdvSceneSwitcher.condition.midi.entry.listen="将MIDI信息选择设置为从选定设备上接收的信息: {{listenButton}}"
|
||||
AdvSceneSwitcher.condition.display="显示器"
|
||||
AdvSceneSwitcher.condition.display.type.displayName="连接的显示器的名称匹配"
|
||||
AdvSceneSwitcher.condition.display.type.displayCount="连接的显示器的数量为"
|
||||
AdvSceneSwitcher.condition.display.entry="{{conditions}}{{displays}}{{regex}}{{displayCount}}"
|
||||
AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.scene="切换场景"
|
||||
AdvSceneSwitcher.action.scene.entry="切换场景{{sceneTypes}}{{scenes}}使用{{transitions}}时长{{duration}}秒"
|
||||
AdvSceneSwitcher.action.scene.entry.noDuration="切换到场景{{sceneTypes}}{{scenes}}使用{{transitions}}"
|
||||
AdvSceneSwitcher.action.switchScene="切换场景"
|
||||
AdvSceneSwitcher.action.scene.entry="切换场景 {{scenes}} 使用 {{transitions}} 时长 {{duration}} 秒"
|
||||
AdvSceneSwitcher.action.scene.entry.noDuration="切换到场景{{scenes}}使用{{transitions}}"
|
||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="等待目标场景的过渡完成"
|
||||
AdvSceneSwitcher.action.wait="等待"
|
||||
AdvSceneSwitcher.action.wait.type.fixed="固定数值"
|
||||
@@ -462,10 +378,6 @@ AdvSceneSwitcher.action.audio.type.mute="静音"
|
||||
AdvSceneSwitcher.action.audio.type.unmute="取消静音"
|
||||
AdvSceneSwitcher.action.audio.type.sourceVolume="来源音量"
|
||||
AdvSceneSwitcher.action.audio.type.masterVolume="主音量"
|
||||
AdvSceneSwitcher.action.audio.type.syncOffset="设置同步偏移"
|
||||
AdvSceneSwitcher.action.audio.type.monitor="设置音频监听"
|
||||
AdvSceneSwitcher.action.audio.type.balance="设置平衡"
|
||||
AdvSceneSwitcher.action.audio.balance.description="选择的音频源将滑块方向移动(从不咕咕的阿坤的理解:左/右声道偏侧向)"
|
||||
AdvSceneSwitcher.action.audio.fade.type.duration="持续时间"
|
||||
AdvSceneSwitcher.action.audio.fade.type.rate="百分比"
|
||||
AdvSceneSwitcher.action.audio.fade.duration="{{fade}}淡出 {{fadeTypes}} {{duration}} 秒."
|
||||
@@ -479,45 +391,43 @@ AdvSceneSwitcher.action.recording.type.start="开始录制"
|
||||
AdvSceneSwitcher.action.recording.type.pause="暂停录制"
|
||||
AdvSceneSwitcher.action.recording.type.unpause="取消录制暂停"
|
||||
AdvSceneSwitcher.action.recording.type.split="分割录制文件"
|
||||
AdvSceneSwitcher.action.recording.type.changeOutputFolder="更改输出文件夹"
|
||||
AdvSceneSwitcher.action.recording.type.changeOutputFileFormat="改变文件名的格式"
|
||||
AdvSceneSwitcher.action.recording.pause.hint="请注意,根据您的录制设置,您可能无法暂停录制"
|
||||
AdvSceneSwitcher.action.recording.split.hint="确保先在OBS设置中启用自动分割文件!"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.replay="回放缓存"
|
||||
AdvSceneSwitcher.action.replay.saveWarn="警告:保存过于频繁可能会导致回放缓存实际上未保存!"
|
||||
AdvSceneSwitcher.action.replay.type.stop="停止回放缓存"
|
||||
AdvSceneSwitcher.action.replay.type.start="启动回放缓存"
|
||||
AdvSceneSwitcher.action.replay.type.save="保存回放缓存"
|
||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
||||
AdvSceneSwitcher.action.replay="回放缓冲区"
|
||||
AdvSceneSwitcher.action.replay.saveWarn="警告:保存过于频繁可能会导致重播缓冲区实际上未保存!"
|
||||
AdvSceneSwitcher.action.replay.type.stop="停止回放缓冲区"
|
||||
AdvSceneSwitcher.action.replay.type.start="启动回放缓冲区"
|
||||
AdvSceneSwitcher.action.replay.type.save="保存回放缓冲区"
|
||||
AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.streaming="推流"
|
||||
AdvSceneSwitcher.action.streaming.type.stop="停止推流"
|
||||
AdvSceneSwitcher.action.streaming.type.start="开始推流"
|
||||
AdvSceneSwitcher.action.streaming.type.keyFrameInterval="设置关键帧间隔"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||
AdvSceneSwitcher.action.run="运行"
|
||||
AdvSceneSwitcher.action.run.arguments="参数:"
|
||||
AdvSceneSwitcher.action.run.addArgument="添加参数"
|
||||
AdvSceneSwitcher.action.run.addArgumentDescription="添加新参数:"
|
||||
AdvSceneSwitcher.action.run.entry="运行 {{filePath}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility="场景项目可见性"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.show="显示"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="隐藏"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="切换"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="来源"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="全部"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="置{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="设置{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
||||
AdvSceneSwitcher.action.filter="滤镜"
|
||||
AdvSceneSwitcher.action.filter.type.enable="开启"
|
||||
AdvSceneSwitcher.action.filter.type.disable="关闭"
|
||||
AdvSceneSwitcher.action.filter.type.settings="参数设置"
|
||||
AdvSceneSwitcher.action.filter.entry="置 {{sources}} {{actions}} {{filters}}"
|
||||
AdvSceneSwitcher.action.filter.entry="在 {{sources}} {{actions}} {{filters}}"
|
||||
AdvSceneSwitcher.action.filter.getSettings="获取当前设置"
|
||||
AdvSceneSwitcher.action.source="源"
|
||||
AdvSceneSwitcher.action.source="来源"
|
||||
AdvSceneSwitcher.action.source.type.enable="启用"
|
||||
AdvSceneSwitcher.action.source.type.disable="停用"
|
||||
AdvSceneSwitcher.action.source.type.settings="配置设置"
|
||||
AdvSceneSwitcher.action.source.type.refreshSettings="刷新源设置"
|
||||
AdvSceneSwitcher.action.source.type.pressSettingsButton="按下设置按钮"
|
||||
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="可用于刷新浏览器、媒体、源、etc"
|
||||
AdvSceneSwitcher.action.source.noSettingsButtons="未找到按钮!"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="可用于刷新浏览器、媒体等源"
|
||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
||||
AdvSceneSwitcher.action.source.warning="警告:OBS UI无法控制全局启用和禁用源,注意,通过这个设置禁用,我测试,你必须通过这个在启用才行,不然点击小眼睛你无法显示!"
|
||||
AdvSceneSwitcher.action.source.getSettings="获取当前设置"
|
||||
AdvSceneSwitcher.action.media="媒体"
|
||||
@@ -527,21 +437,20 @@ AdvSceneSwitcher.action.media.type.stop="停止"
|
||||
AdvSceneSwitcher.action.media.type.restart="重新启动"
|
||||
AdvSceneSwitcher.action.media.type.next="下一个"
|
||||
AdvSceneSwitcher.action.media.type.previous="上一个"
|
||||
AdvSceneSwitcher.action.media.type.seek.duration="时间轴定位"
|
||||
AdvSceneSwitcher.action.media.type.seek="时间轴定位"
|
||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
||||
AdvSceneSwitcher.action.macro="宏"
|
||||
AdvSceneSwitcher.action.macro.type.pause="暂停"
|
||||
AdvSceneSwitcher.action.macro.type.unpause="取消暂停"
|
||||
AdvSceneSwitcher.action.macro.type.resetCounter="复位计数器"
|
||||
AdvSceneSwitcher.action.macro.type.run="运行操作"
|
||||
AdvSceneSwitcher.action.macro.type.stop="停止操作"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||
AdvSceneSwitcher.action.macro.type.run="运行"
|
||||
AdvSceneSwitcher.action.macro.type.stop="停止"
|
||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
||||
AdvSceneSwitcher.action.pluginState="插件状态"
|
||||
AdvSceneSwitcher.action.pluginState.type.stop="停止高级场景切换插件"
|
||||
AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项时:"
|
||||
AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项:"
|
||||
AdvSceneSwitcher.action.pluginState.type.import="从设置导入"
|
||||
AdvSceneSwitcher.action.pluginState.importWarning="注意:当“设置”窗口打开时,操作将被忽略。"
|
||||
AdvSceneSwitcher.action.pluginState.type.terminate="关闭 OBS"
|
||||
AdvSceneSwitcher.action.pluginState.terminateConfirm="OBS将在10秒后自动关闭!/n你想继续关闭OBS吗?"
|
||||
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}{{settingsWarning}}"
|
||||
AdvSceneSwitcher.action.virtualCamera="虚拟摄像机"
|
||||
AdvSceneSwitcher.action.virtualCamera.type.stop="停止虚拟摄像机"
|
||||
@@ -558,6 +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.sceneOrder="场景项目顺序"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="上移"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移"
|
||||
@@ -565,9 +475,9 @@ AdvSceneSwitcher.action.sceneOrder.type.moveTop="顶部"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="底部"
|
||||
AdvSceneSwitcher.action.sceneOrder.type.movePosition="移动到数值位置"
|
||||
AdvSceneSwitcher.action.sceneOrder.entry="在 {{scenes}} {{actions}} {{sources}} {{position}}"
|
||||
AdvSceneSwitcher.action.sceneTransform="场景项目转换"
|
||||
AdvSceneSwitcher.action.sceneTransform.getTransform="获得转换"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="在 {{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneTransform="场景项目变换"
|
||||
AdvSceneSwitcher.action.sceneTransform.getTransform="得到变换"
|
||||
AdvSceneSwitcher.action.sceneTransform.entry="在 {{scenes}} 变换 {{sources}}"
|
||||
AdvSceneSwitcher.action.file="文件"
|
||||
AdvSceneSwitcher.action.file.type.write="写入"
|
||||
AdvSceneSwitcher.action.file.type.append="追加写入"
|
||||
@@ -593,13 +503,9 @@ AdvSceneSwitcher.action.timer.type.reset="重置"
|
||||
AdvSceneSwitcher.action.timer.type.setTimeRemaining="设置剩余时间"
|
||||
AdvSceneSwitcher.action.timer.entry="{{timerAction}} 定时在 {{macros}} {{duration}}"
|
||||
AdvSceneSwitcher.action.random="随机"
|
||||
AdvSceneSwitcher.action.random.allowRepeat="允许连续执行同一宏"
|
||||
AdvSceneSwitcher.action.random.entry="随机运行以下任何宏(忽略暂停的宏)"
|
||||
AdvSceneSwitcher.action.systray="系统托盘通知"
|
||||
AdvSceneSwitcher.action.systray.title="标题:"
|
||||
AdvSceneSwitcher.action.systray.message="信息:"
|
||||
AdvSceneSwitcher.action.systray.icon="图标:"
|
||||
AdvSceneSwitcher.action.systray.iconHint="留空以使用默认图标"
|
||||
AdvSceneSwitcher.action.systray.entry="显示通知: {{message}}"
|
||||
AdvSceneSwitcher.action.screenshot="截图"
|
||||
AdvSceneSwitcher.action.screenshot.save.default="默认"
|
||||
AdvSceneSwitcher.action.screenshot.save.custom="其他"
|
||||
@@ -622,54 +528,21 @@ AdvSceneSwitcher.action.sequence.continueFrom="继续所选项目"
|
||||
AdvSceneSwitcher.action.websocket="websocket"
|
||||
AdvSceneSwitcher.action.websocket.type.request="request"
|
||||
AdvSceneSwitcher.action.websocket.type.event="event"
|
||||
AdvSceneSwitcher.action.websocket.entry.request="发送场景切换器 {{type}}{{connection}}"
|
||||
AdvSceneSwitcher.action.websocket.entry.event="发送场景切换器 {{type}} 到连接的客户端"
|
||||
AdvSceneSwitcher.action.http="Http"
|
||||
AdvSceneSwitcher.action.http.setHeaders="设置头信息(SET headers)"
|
||||
AdvSceneSwitcher.action.http.headers="头信息(headers):"
|
||||
AdvSceneSwitcher.action.http.addHeader="增加头信息(ADD headers)"
|
||||
AdvSceneSwitcher.action.http.type.get="获取(GET)"
|
||||
AdvSceneSwitcher.action.http.type.post="发送(POST)"
|
||||
AdvSceneSwitcher.action.http.type.get="GET"
|
||||
AdvSceneSwitcher.action.http.type.post="POST"
|
||||
AdvSceneSwitcher.action.http.entry.line1="发送 {{method}} 到 {{url}}"
|
||||
AdvSceneSwitcher.action.http.entry.line2="超时: {{timeout}} 秒"
|
||||
AdvSceneSwitcher.action.variable="变量"
|
||||
AdvSceneSwitcher.action.variable.type.set="设置为固定值"
|
||||
AdvSceneSwitcher.action.variable.type.set="设置"
|
||||
AdvSceneSwitcher.action.variable.type.append="追加"
|
||||
AdvSceneSwitcher.action.variable.type.appendVar="追加变量"
|
||||
AdvSceneSwitcher.action.variable.type.increment="增加"
|
||||
AdvSceneSwitcher.action.variable.type.decrement="减少"
|
||||
AdvSceneSwitcher.action.variable.type.setActionValue="设置为操作值"
|
||||
AdvSceneSwitcher.action.variable.type.setConditionValue="设置为条件值"
|
||||
AdvSceneSwitcher.action.variable.type.roundToInt="取整到最近的整数"
|
||||
AdvSceneSwitcher.action.variable.type.subString="设置为当前值的子字符串"
|
||||
AdvSceneSwitcher.action.variable.type.findAndReplace="在当前值中查找并替换"
|
||||
AdvSceneSwitcher.action.variable.type.mathExpression="数学表达式"
|
||||
AdvSceneSwitcher.action.variable.mathExpression.example="( 1 + 2 * 3 ) / 4"
|
||||
AdvSceneSwitcher.action.variable.findAndReplace.find="要查找的文本"
|
||||
AdvSceneSwitcher.action.variable.findAndReplace.replace="要替换为的文本"
|
||||
AdvSceneSwitcher.action.variable.subString.begin="开始"
|
||||
AdvSceneSwitcher.action.variable.subString.all="全部"
|
||||
AdvSceneSwitcher.action.variable.invalidSelection="无效选择!"
|
||||
AdvSceneSwitcher.action.variable.actionNoVariableSupport="不支持从 %1 个操作获取变量值!"
|
||||
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="不支持从 %1 条件中获取变量值!"
|
||||
AdvSceneSwitcher.action.variable.currentSegmentValue="当前值:"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}"
|
||||
AdvSceneSwitcher.action.variable.entry.substringIndex="子字符串开始:{{subStringStart}} 子字符串大小:{{subStringSize}}"
|
||||
AdvSceneSwitcher.action.variable.entry.substringRegex="使用正则表达式为 {{regexMatchIdx}} 匹配的值:"
|
||||
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{replaceStr}}"
|
||||
AdvSceneSwitcher.action.projector="投影仪"
|
||||
AdvSceneSwitcher.action.projector.type.source="源"
|
||||
AdvSceneSwitcher.action.projector.type.scene="场景"
|
||||
AdvSceneSwitcher.action.projector.type.preview="预览"
|
||||
AdvSceneSwitcher.action.projector.type.program="程序"
|
||||
AdvSceneSwitcher.action.projector.type.multiview="多视图"
|
||||
AdvSceneSwitcher.action.projector.display="显示"
|
||||
AdvSceneSwitcher.action.projector.windowed="窗口"
|
||||
AdvSceneSwitcher.action.projector.fullscreen="全屏"
|
||||
AdvSceneSwitcher.action.projector.entry="打开为{{windowTypes}} 的 {{types}}{{scenes}}{{sources}}投影"
|
||||
AdvSceneSwitcher.action.projector.entry.monitor="在 {{monitors}} 上 (从不咕咕的阿坤说:谨慎开启!)"
|
||||
AdvSceneSwitcher.action.midi="MIDI"
|
||||
AdvSceneSwitcher.action.midi.entry="发送消息到 {{device}}:"
|
||||
AdvSceneSwitcher.action.midi.entry.listen="将MIDI消息选择设置为 {{listenDevices}} 上传入的消息: {{listenButton}}"
|
||||
AdvSceneSwitcher.action.osc="打开声音控制"
|
||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
|
||||
|
||||
|
||||
; Transition Tab
|
||||
AdvSceneSwitcher.transitionTab.title="转场特效"
|
||||
@@ -728,7 +601,7 @@ AdvSceneSwitcher.mediaTab.states.none="无"
|
||||
AdvSceneSwitcher.mediaTab.states.playing="播放中"
|
||||
AdvSceneSwitcher.mediaTab.states.opening="打开中"
|
||||
AdvSceneSwitcher.mediaTab.states.buffering="缓冲中"
|
||||
AdvSceneSwitcher.mediaTab.states.paused="暂停"
|
||||
AdvSceneSwitcher.mediaTab.states.Paused="暂停"
|
||||
AdvSceneSwitcher.mediaTab.states.stopped="停止"
|
||||
AdvSceneSwitcher.mediaTab.states.ended="结束"
|
||||
AdvSceneSwitcher.mediaTab.states.error="错误"
|
||||
@@ -949,7 +822,6 @@ AdvSceneSwitcher.connection.password="密码:"
|
||||
AdvSceneSwitcher.connection.reconnect="自动重新连接:"
|
||||
AdvSceneSwitcher.connection.reconnectDelay="自动重新连接延迟:"
|
||||
AdvSceneSwitcher.connection.connectOnStart="启动时自动连接:"
|
||||
AdvSceneSwitcher.connection.useOBSWebsocketProtocol="<html><head/><body><p>如何使用 obs-websocket <a href=\"https://github.com/obsproject/obs-websocket/blob/master/docs/generated/protocol.md\"><span style=\" text-decoration: underline; color:#268bd2;\">protocol</span></a></p></body></html>"
|
||||
AdvSceneSwitcher.connection.test="测试连接"
|
||||
AdvSceneSwitcher.connection.status.disconnected="断开"
|
||||
AdvSceneSwitcher.connection.status.connecting="连接"
|
||||
@@ -963,68 +835,6 @@ AdvSceneSwitcher.regex.dotMatchNewline=". 匹配换行符"
|
||||
AdvSceneSwitcher.regex.multiLine="^ 和 $ 是匹配行的开始/结束"
|
||||
AdvSceneSwitcher.regex.extendedPattern="启用Qt的扩展模式语法"
|
||||
|
||||
AdvSceneSwitcher.process.showAdvanced="显示高级设置"
|
||||
AdvSceneSwitcher.process.arguments="参数:"
|
||||
AdvSceneSwitcher.process.addArgument="增加参数"
|
||||
AdvSceneSwitcher.process.addArgumentDescription="添加新参数:"
|
||||
AdvSceneSwitcher.process.entry="运行{{filePath}}{{advancedSettings}}"
|
||||
AdvSceneSwitcher.process.entry.workingDirectory="工作目录:{{workingDirectory}}"
|
||||
|
||||
AdvSceneSwitcher.math.expressionFail="计算表达式失败"
|
||||
|
||||
AdvSceneSwitcher.midi.deviceNamePattern="[端口 #%1] %2"
|
||||
AdvSceneSwitcher.midi.message.type="类型:"
|
||||
AdvSceneSwitcher.midi.message.type.optional="任意"
|
||||
AdvSceneSwitcher.midi.message.type.invalid="无效"
|
||||
AdvSceneSwitcher.midi.message.type.noteOff="关闭音符"
|
||||
AdvSceneSwitcher.midi.message.type.noteOn="打开音符"
|
||||
AdvSceneSwitcher.midi.message.type.polyphonicPressure="合成音压力"
|
||||
AdvSceneSwitcher.midi.message.type.controlChange="控制更改"
|
||||
AdvSceneSwitcher.midi.message.type.programChange="程序更改"
|
||||
AdvSceneSwitcher.midi.message.type.channelAftertouch="频道余音"
|
||||
AdvSceneSwitcher.midi.message.type.pitchBend="音高弯曲"
|
||||
AdvSceneSwitcher.midi.message.type.systemExclusive="系统独占"
|
||||
AdvSceneSwitcher.midi.message.type.timeCode="时间码"
|
||||
AdvSceneSwitcher.midi.message.type.songPositionPointer="歌曲位置指针"
|
||||
AdvSceneSwitcher.midi.message.type.songSelect="歌曲选择"
|
||||
AdvSceneSwitcher.midi.message.type.reserved1="保留 (1)"
|
||||
AdvSceneSwitcher.midi.message.type.reserved2="保留 (2)"
|
||||
AdvSceneSwitcher.midi.message.type.tuneRequest="调音请求"
|
||||
AdvSceneSwitcher.midi.message.type.endOfSystemExclusive="系统独占结束"
|
||||
AdvSceneSwitcher.midi.message.type.timeClock="时间时钟"
|
||||
AdvSceneSwitcher.midi.message.type.reserved3="保留 (3)"
|
||||
AdvSceneSwitcher.midi.message.type.startFile="开始文件"
|
||||
AdvSceneSwitcher.midi.message.type.continueFile="继续文件"
|
||||
AdvSceneSwitcher.midi.message.type.stopFile="停止文件"
|
||||
AdvSceneSwitcher.midi.message.type.reserved4="保留 (4)"
|
||||
AdvSceneSwitcher.midi.message.type.activeSensing="主动感应"
|
||||
AdvSceneSwitcher.midi.message.type.systemReset="系统充值"
|
||||
AdvSceneSwitcher.midi.message.type.unknown="未知"
|
||||
AdvSceneSwitcher.midi.message.channel="频道 :"
|
||||
AdvSceneSwitcher.midi.message.note="音符 / 值(1):"
|
||||
AdvSceneSwitcher.midi.message.value="值(2):"
|
||||
AdvSceneSwitcher.midi.message.placeholder="任意"
|
||||
AdvSceneSwitcher.midi.resetDevices="重新连接所有 MIDI 设备"
|
||||
AdvSceneSwitcher.midi.startListen="开始监听"
|
||||
AdvSceneSwitcher.midi.stopListen="停止监听"
|
||||
AdvSceneSwitcher.midi.startListenFail="设备正忙!\n其他设备已经在监听!"
|
||||
AdvSceneSwitcher.midi.deviceOpenFail="初始化 MIDI 设备失败!"
|
||||
|
||||
AdvSceneSwitcher.osc.network="网络"
|
||||
AdvSceneSwitcher.osc.network.protocol="协议:"
|
||||
AdvSceneSwitcher.osc.network.address="地址:"
|
||||
AdvSceneSwitcher.osc.network.port="端口:"
|
||||
AdvSceneSwitcher.osc.message="信息"
|
||||
AdvSceneSwitcher.osc.message.type.none="无"
|
||||
AdvSceneSwitcher.osc.message.type.float="浮点数哦"
|
||||
AdvSceneSwitcher.osc.message.type.int="整数"
|
||||
AdvSceneSwitcher.osc.message.type.string="字符串"
|
||||
AdvSceneSwitcher.osc.message.type.binaryBlob="二进制"
|
||||
AdvSceneSwitcher.osc.message.type.true="真"
|
||||
AdvSceneSwitcher.osc.message.type.false="假"
|
||||
AdvSceneSwitcher.osc.message.type.infinity="无限"
|
||||
AdvSceneSwitcher.osc.message.type.null="无"
|
||||
|
||||
AdvSceneSwitcher.selectScene="--选择场景--"
|
||||
AdvSceneSwitcher.selectPreviousScene="上个场景"
|
||||
AdvSceneSwitcher.selectCurrentScene="当前场景"
|
||||
@@ -1034,7 +844,7 @@ AdvSceneSwitcher.currentTransition="当前转场特效"
|
||||
AdvSceneSwitcher.anyTransition="任何转场特效"
|
||||
AdvSceneSwitcher.selectTransition="--选择转场特效--"
|
||||
AdvSceneSwitcher.selectWindow="--选择窗口--"
|
||||
AdvSceneSwitcher.selectSource="--选择源--"
|
||||
AdvSceneSwitcher.selectSource="--选择来源--"
|
||||
AdvSceneSwitcher.selectAudioSource="--选择音频源--"
|
||||
AdvSceneSwitcher.selectVideoSource="--选择视频源--"
|
||||
AdvSceneSwitcher.OBSVideoOutput="OBS的主要输出"
|
||||
@@ -1055,8 +865,8 @@ AdvSceneSwitcher.sceneItemSelection.any="任何"
|
||||
|
||||
AdvSceneSwitcher.status.active="运行中"
|
||||
AdvSceneSwitcher.status.inactive="已停止"
|
||||
AdvSceneSwitcher.running="插件正在运行"
|
||||
AdvSceneSwitcher.stopped="插件已停止"
|
||||
AdvSceneSwitcher.running="插件运行"
|
||||
AdvSceneSwitcher.stopped="插件停止"
|
||||
|
||||
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>这似乎是第一次启动高级场景切换程序.<br>请看一下 <a href=\"https://github.com/WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> 查看指南和示例列表.<br>如果有问题,在在OBS论坛插件帖子内提问 <a href=\"https://obsproject.com/forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:#268bd2;\">thread</span></a></p></body></html>"
|
||||
|
||||
@@ -1070,8 +880,4 @@ AdvSceneSwitcher.duration.condition.none="没有时间限制"
|
||||
AdvSceneSwitcher.duration.condition.more="时间少于"
|
||||
AdvSceneSwitcher.duration.condition.equal="时间等于"
|
||||
AdvSceneSwitcher.duration.condition.less="时间大于"
|
||||
AdvSceneSwitcher.duration.condition.within="在最后"
|
||||
|
||||
AdvSceneSwitcher.audio.monitor.none="关闭监听"
|
||||
AdvSceneSwitcher.audio.monitor.monitorOnly="仅监听(输出静音)"
|
||||
AdvSceneSwitcher.audio.monitor.both="监听并输出"
|
||||
AdvSceneSwitcher.duration.condition.within="保留结果后余存"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path d="m1,2c0,-0.27 0.11,-0.52 0.29,-0.71c0.39,-0.39 1.03,-0.39 1.42,0l5.29,5.3l5.29,-5.3c0.39,-0.39 1.03,-0.39 1.42,0c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71l-6,6c-0.39,0.39 -1.03,0.39 -1.42,0l-6,-6c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#fefefe" id="svg_1" transform="matrix(1, 0, 0, 1, 0, 0)"/>
|
||||
<path d="m1,8c0,-0.27 0.09,-0.52 0.28,-0.71c0.38,-0.39 1.03,-0.39 1.41,0l5.31,5.3l5.28,-5.3c0.38,-0.39 1.03,-0.39 1.41,0c0.19,0.19 0.31,0.44 0.31,0.71s-0.13,0.52 -0.31,0.71l-6,6c-0.38,0.39 -1.03,0.39 -1.41,0l-6,-6c-0.19,-0.19 -0.28,-0.44 -0.28,-0.71zm0,0" fill="#fefefe" id="svg_2"/>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 791 B |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path d="m1,8c0,-0.27 0.11,-0.52 0.29,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.29,-5.3l-5.29,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#fefefe" id="svg_1"/>
|
||||
<path d="m1,14c0,-0.27 0.11,-0.52 0.28,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.19,0.19 0.3,0.44 0.3,0.71s-0.11,0.52 -0.3,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.28,-5.3l-5.3,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.17,-0.19 -0.28,-0.44 -0.28,-0.71zm0,0" fill="#fefefe" id="svg_2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 753 B |
@@ -1,7 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="640" height="640" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||
<defs>
|
||||
<path d="m599.62,325.49c0,151.77 -123.21,274.98 -274.98,274.98c-151.76,0 -274.97,-123.21 -274.97,-274.98c0,-151.76 123.21,-274.97 274.97,-274.97c151.77,0 274.98,123.21 274.98,274.97z" id="c3Wyq0kfYS"/>
|
||||
<mask height="689.95" id="maskanTyyngos" maskUnits="userSpaceOnUse" width="689.95" x="-20.33" y="-19.48">
|
||||
<rect fill="white" height="689.95" id="svg_1" width="689.95" x="-20.33" y="-19.48"/>
|
||||
<use fill="black" id="svg_2" xlink:href="#c3Wyq0kfYS"/>
|
||||
</mask>
|
||||
<path d="m334.97,96.07c4.54,0 8.23,3.68 8.23,8.23c0,46.94 0,179.54 0,226.48c0,4.54 -3.69,8.22 -8.23,8.22c-5.77,0 -14.88,0 -20.66,0c-4.54,0 -8.22,-3.68 -8.22,-8.22c0,-46.94 0,-179.54 0,-226.48c0,-4.55 3.68,-8.23 8.22,-8.23c5.78,0 14.89,0 20.66,0z" id="fxMeu932c"/>
|
||||
<path d="m471.96,338.21c0.01,3.1 -2.5,5.62 -5.59,5.63c-32.02,0.09 -122.45,0.37 -154.46,0.47c-3.1,0.01 -5.61,-2.49 -5.62,-5.59c-0.02,-6.3 -0.06,-19.59 -0.08,-25.89c-0.01,-3.1 2.49,-5.62 5.59,-5.63c32.01,-0.09 122.44,-0.37 154.45,-0.47c3.1,-0.01 5.62,2.5 5.63,5.59c0.02,6.3 0.06,19.59 0.08,25.89z" id="h65nGmP2BL"/>
|
||||
</defs>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path fill="none" fill-opacity="null" id="svg_11" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02"/>
|
||||
<ellipse cx="103.84" cy="562.04" fill="#fefefe" id="svg_3" rx="80" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 103.843, 562.038)"/>
|
||||
<ellipse cx="506" cy="554" fill="#fefefe" id="svg_4" rx="77" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 506, 554)"/>
|
||||
<rect fill="#fefefe" height="359" id="svg_7" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" stroke-width="0" width="58" x="122" y="185"/>
|
||||
<rect fill="#fefefe" height="453" id="svg_8" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="58" x="522" y="84.5"/>
|
||||
<rect fill="#fefefe" height="37" id="svg_9" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-14.1985, 351.556, 146.245)" width="463.07" x="120.02" y="127.74"/>
|
||||
<rect fill="none" fill-opacity="null" height="0" id="svg_10" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="538.25" y="107.12"/>
|
||||
<path d="m537.42,112.06l0,-67.88l17.58,67.88z" fill="#fefefe" id="svg_16" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-90, 546.203, 78.1248)"/>
|
||||
<rect fill="#fefefe" height="0" id="svg_18" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="82.12" y="287.56"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
|
||||
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<text fill="#fefefe" font-family="Serif" font-size="24" id="svg_1" stroke="#fefefe" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="null" stroke-width="0" text-anchor="middle" transform="matrix(1.0974, 0, 0, 1.0974, -4.98544, 4.97639)" x="14" xml:space="preserve" y="13">*</text>
|
||||
<rect fill="#fefefe" height="3.3" id="svg_2" stroke="#fefefe" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="5" x="1" y="12"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 815 B |
@@ -1,8 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path d="M 87.803 77.194 L 68.212 57.602 c 9.5 -14.422 7.912 -34.054 -4.766 -46.732 c 0 0 -0.001 0 -0.001 0 c -14.495 -14.493 -38.08 -14.494 -52.574 0 c -14.494 14.495 -14.494 38.079 0 52.575 c 7.248 7.247 16.767 10.87 26.287 10.87 c 7.134 0 14.267 -2.035 20.445 -6.104 l 19.591 19.591 C 78.659 89.267 80.579 90 82.498 90 s 3.84 -0.733 5.305 -2.197 C 90.732 84.873 90.732 80.124 87.803 77.194 z M 21.48 52.837 c -8.645 -8.646 -8.645 -22.713 0 -31.358 c 4.323 -4.322 10 -6.483 15.679 -6.483 c 5.678 0 11.356 2.161 15.678 6.483 c 8.644 8.644 8.645 22.707 0.005 31.352 c -0.002 0.002 -0.004 0.003 -0.005 0.005 c -0.002 0.002 -0.003 0.003 -0.004 0.005 C 44.184 61.481 30.123 61.48 21.48 52.837 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: #fefefe; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,4 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path d="m1,2c0,-0.27 0.11,-0.52 0.29,-0.71c0.39,-0.39 1.03,-0.39 1.42,0l5.29,5.3l5.29,-5.3c0.39,-0.39 1.03,-0.39 1.42,0c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71l-6,6c-0.39,0.39 -1.03,0.39 -1.42,0l-6,-6c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_1"/>
|
||||
<path d="m1,8c0,-0.27 0.11,-0.52 0.29,-0.71c0.39,-0.39 1.03,-0.39 1.42,0l5.29,5.3l5.29,-5.3c0.39,-0.39 1.03,-0.39 1.42,0c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71l-6,6c-0.39,0.39 -1.03,0.39 -1.42,0l-6,-6c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_4" transform="matrix(1, 0, 0, 1, 0, 0)"/>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 791 B |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path d="m1,8c0,-0.27 0.11,-0.52 0.29,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.29,-5.3l-5.29,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_1"/>
|
||||
<path d="m1,14c0,-0.27 0.11,-0.52 0.29,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.29,-5.3l-5.29,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_2"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 757 B |
@@ -1,7 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="640" height="640" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||
<defs>
|
||||
<path d="m599.62,325.49c0,151.77 -123.21,274.98 -274.98,274.98c-151.76,0 -274.97,-123.21 -274.97,-274.98c0,-151.76 123.21,-274.97 274.97,-274.97c151.77,0 274.98,123.21 274.98,274.97z" id="c3Wyq0kfYS"/>
|
||||
<mask height="689.95" id="maskanTyyngos" maskUnits="userSpaceOnUse" width="689.95" x="-20.33" y="-19.48">
|
||||
<rect fill="white" height="689.95" id="svg_1" width="689.95" x="-20.33" y="-19.48"/>
|
||||
<use fill="black" id="svg_2" xlink:href="#c3Wyq0kfYS"/>
|
||||
</mask>
|
||||
<path d="m334.97,96.07c4.54,0 8.23,3.68 8.23,8.23c0,46.94 0,179.54 0,226.48c0,4.54 -3.69,8.22 -8.23,8.22c-5.77,0 -14.88,0 -20.66,0c-4.54,0 -8.22,-3.68 -8.22,-8.22c0,-46.94 0,-179.54 0,-226.48c0,-4.55 3.68,-8.23 8.22,-8.23c5.78,0 14.89,0 20.66,0z" id="fxMeu932c"/>
|
||||
<path d="m471.96,338.21c0.01,3.1 -2.5,5.62 -5.59,5.63c-32.02,0.09 -122.45,0.37 -154.46,0.47c-3.1,0.01 -5.61,-2.49 -5.62,-5.59c-0.02,-6.3 -0.06,-19.59 -0.08,-25.89c-0.01,-3.1 2.49,-5.62 5.59,-5.63c32.01,-0.09 122.44,-0.37 154.45,-0.47c3.1,-0.01 5.62,2.5 5.63,5.59c0.02,6.3 0.06,19.59 0.08,25.89z" id="h65nGmP2BL"/>
|
||||
</defs>
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<path fill="none" fill-opacity="null" id="svg_11" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02"/>
|
||||
<ellipse cx="103.84" cy="562.04" fill="#202020" id="svg_3" rx="80" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 103.843, 562.038)"/>
|
||||
<ellipse cx="506" cy="554" fill="#202020" id="svg_4" rx="77" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 506, 554)"/>
|
||||
<rect fill="#202020" height="359" id="svg_7" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" stroke-width="0" width="58" x="122" y="185"/>
|
||||
<rect fill="#202020" height="453" id="svg_8" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="58" x="522" y="84.5"/>
|
||||
<rect fill="#202020" height="37" id="svg_9" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-14.1985, 351.556, 146.245)" width="463.07" x="120.02" y="127.74"/>
|
||||
<rect fill="none" fill-opacity="null" height="0" id="svg_10" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="538.25" y="107.12"/>
|
||||
<path d="m537.42,112.06l0,-67.88l17.58,67.88z" fill="#202020" id="svg_16" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-90, 546.203, 78.1248)"/>
|
||||
<rect fill="#202020" height="0" id="svg_18" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="82.12" y="287.56"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
|
||||
|
||||
<g class="layer">
|
||||
<title>Layer 1</title>
|
||||
<text fill="#202020" font-family="Serif" font-size="24" id="svg_1" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="null" stroke-width="0" text-anchor="middle" transform="matrix(1.0974, 0, 0, 1.0974, -4.98544, 4.97639)" x="14" xml:space="preserve" y="13">*</text>
|
||||
<rect fill="#202020" height="3.3" id="svg_2" stroke="#202020" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="5" x="1" y="12"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 815 B |
@@ -1,8 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="256" height="256" viewBox="0 0 256 256" xml:space="preserve">
|
||||
|
||||
<defs>
|
||||
</defs>
|
||||
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(1.4065934065934016 1.4065934065934016) scale(2.81 2.81)" >
|
||||
<path d="M 87.803 77.194 L 68.212 57.602 c 9.5 -14.422 7.912 -34.054 -4.766 -46.732 c 0 0 -0.001 0 -0.001 0 c -14.495 -14.493 -38.08 -14.494 -52.574 0 c -14.494 14.495 -14.494 38.079 0 52.575 c 7.248 7.247 16.767 10.87 26.287 10.87 c 7.134 0 14.267 -2.035 20.445 -6.104 l 19.591 19.591 C 78.659 89.267 80.579 90 82.498 90 s 3.84 -0.733 5.305 -2.197 C 90.732 84.873 90.732 80.124 87.803 77.194 z M 21.48 52.837 c -8.645 -8.646 -8.645 -22.713 0 -31.358 c 4.323 -4.322 10 -6.483 15.679 -6.483 c 5.678 0 11.356 2.161 15.678 6.483 c 8.644 8.644 8.645 22.707 0.005 31.352 c -0.002 0.002 -0.004 0.003 -0.005 0.005 c -0.002 0.002 -0.003 0.003 -0.004 0.005 C 44.184 61.481 30.123 61.48 21.48 52.837 z" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: #202020; fill-rule: nonzero; opacity: 1;" transform=" matrix(1 0 0 1 0 0) " stroke-linecap="round" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,2 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,2 +1,3 @@
|
||||
<?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="#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>
|
||||
<!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>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
2
deps/asio
vendored
1
deps/cpp-httplib
vendored
41032
deps/exprtk/exprtk.hpp
vendored
1
deps/json
vendored
1
deps/libremidi
vendored
2
deps/websocketpp
vendored
@@ -67,8 +67,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>962</width>
|
||||
<height>1033</height>
|
||||
<width>957</width>
|
||||
<height>905</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||
@@ -256,54 +256,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="disableComboBoxFilter">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.comboBoxFilterDisable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_13">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_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>
|
||||
@@ -682,7 +634,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="advss::MacroTree" name="macros">
|
||||
<widget class="MacroTree" name="macros">
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@@ -829,7 +781,7 @@
|
||||
<property name="title">
|
||||
<string>AdvSceneSwitcher.macroTab.edit</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_38">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0,0,0,0,0,0,0">
|
||||
<item>
|
||||
@@ -843,7 +795,7 @@
|
||||
<widget class="QLineEdit" name="macroName"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="advss::MacroRunButton" name="runMacro">
|
||||
<widget class="QPushButton" name="runMacro">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.macroTab.run</string>
|
||||
</property>
|
||||
@@ -936,16 +888,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="advss::MacroSegmentList" name="conditionsList">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<property name="leftMargin">
|
||||
@@ -1022,19 +964,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="conditionTop">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="conditionUp">
|
||||
<property name="maximumSize">
|
||||
@@ -1070,19 +999,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="conditionBottom">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_15">
|
||||
<property name="orientation">
|
||||
@@ -1100,360 +1016,144 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QSplitter" name="macroElseActionSplitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="macroActions" native="true">
|
||||
<layout class="QVBoxLayout" name="macroActionsLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="advss::MacroSegmentList" name="actionsList">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionAdd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionRemove">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_133">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_47">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_132">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionTop">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionUp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">upArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionDown">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">downArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionBottom">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_14">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="macroElseActions" native="true">
|
||||
<layout class="QVBoxLayout" name="macroElseActionsLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="advss::MacroSegmentList" name="elseActionsList">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_33">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elseActionAdd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elseActionRemove">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_138">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_50">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_139">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elseActionTop">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elseActionUp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">upArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elseActionDown">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">downArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="elseActionBottom">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_22">
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="macroActions" native="true">
|
||||
<layout class="QVBoxLayout" name="macroActionsLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionAdd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionRemove">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_133">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_47">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_132">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionUp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">upArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="actionDown">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">downArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_14">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -4839,21 +4539,10 @@
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>advss::MacroTree</class>
|
||||
<class>MacroTree</class>
|
||||
<extends>QListView</extends>
|
||||
<header>macro-tree.hpp</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>advss::MacroSegmentList</class>
|
||||
<extends>QScrollArea</extends>
|
||||
<header>macro-segment-list.hpp</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>advss::MacroRunButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>macro-run-button.hpp</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "status-control.hpp"
|
||||
#include "scene-switch-helpers.hpp"
|
||||
#include "curl-helper.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "version.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QAction>
|
||||
#include <QFileDialog>
|
||||
#include <QDirIterator>
|
||||
#include <regex>
|
||||
#include <filesystem>
|
||||
|
||||
#include <obs-module.h>
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "status-control.hpp"
|
||||
#include "curl-helper.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "version.h"
|
||||
|
||||
const char *obs_module_text(const char *text)
|
||||
{
|
||||
return switcher->translate(text);
|
||||
}
|
||||
|
||||
obs_module_t *obs_current_module()
|
||||
{
|
||||
return switcher->modulePtr;
|
||||
}
|
||||
|
||||
SwitcherData *switcher = nullptr;
|
||||
SwitcherData *GetSwitcher()
|
||||
{
|
||||
return switcher;
|
||||
}
|
||||
|
||||
AdvSceneSwitcher *AdvSceneSwitcher::window = nullptr;
|
||||
|
||||
@@ -28,9 +40,11 @@ AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent)
|
||||
{
|
||||
switcher->settingsWindowOpened = true;
|
||||
ui->setupUi(this);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
switcher->Prune();
|
||||
LoadUI();
|
||||
loadUI();
|
||||
}
|
||||
|
||||
AdvSceneSwitcher::~AdvSceneSwitcher()
|
||||
@@ -41,76 +55,51 @@ AdvSceneSwitcher::~AdvSceneSwitcher()
|
||||
}
|
||||
}
|
||||
|
||||
static bool translationAvailable()
|
||||
bool translationAvailable()
|
||||
{
|
||||
return !!strcmp(obs_module_text("AdvSceneSwitcher.pluginName"),
|
||||
"AdvSceneSwitcher.pluginName");
|
||||
}
|
||||
|
||||
static void DisplayMissingDependencyWarning()
|
||||
void AdvSceneSwitcher::loadUI()
|
||||
{
|
||||
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";
|
||||
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 += "/";
|
||||
msg += QString::fromStdString(
|
||||
(std::filesystem::current_path().string()));
|
||||
msg += "/";
|
||||
#endif
|
||||
msg += obs_get_module_data_path(obs_current_module());
|
||||
DisplayMessage(msg);
|
||||
}
|
||||
msg += obs_get_module_data_path(obs_current_module());
|
||||
(void)DisplayMessage(msg);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::LoadUI()
|
||||
{
|
||||
DisplayMissingDataDirWarning();
|
||||
DisplayMissingDependencyWarning();
|
||||
setupGeneralTab();
|
||||
setupTitleTab();
|
||||
setupExecutableTab();
|
||||
setupRegionTab();
|
||||
setupPauseTab();
|
||||
setupSequenceTab();
|
||||
setupTransitionsTab();
|
||||
setupIdleTab();
|
||||
setupRandomTab();
|
||||
setupMediaTab();
|
||||
setupFileTab();
|
||||
setupTimeTab();
|
||||
setupAudioTab();
|
||||
setupVideoTab();
|
||||
setupNetworkTab();
|
||||
setupSceneGroupTab();
|
||||
setupTriggerTab();
|
||||
setupMacroTab();
|
||||
|
||||
SetupGeneralTab();
|
||||
SetupTitleTab();
|
||||
SetupExecutableTab();
|
||||
SetupRegionTab();
|
||||
SetupPauseTab();
|
||||
SetupSequenceTab();
|
||||
SetupTransitionsTab();
|
||||
SetupIdleTab();
|
||||
SetupRandomTab();
|
||||
SetupMediaTab();
|
||||
SetupFileTab();
|
||||
SetupTimeTab();
|
||||
SetupAudioTab();
|
||||
SetupVideoTab();
|
||||
SetupNetworkTab();
|
||||
SetupSceneGroupTab();
|
||||
SetupTriggerTab();
|
||||
SetupMacroTab();
|
||||
|
||||
SetDeprecationWarnings();
|
||||
SetTabOrder();
|
||||
SetCurrentTab();
|
||||
RestoreWindowGeo();
|
||||
CheckFirstTimeSetup();
|
||||
setDeprecationWarnings();
|
||||
setTabOrder();
|
||||
setCurrentTab();
|
||||
restoreWindowGeo();
|
||||
checkFirstTimeSetup();
|
||||
|
||||
loading = false;
|
||||
}
|
||||
@@ -118,19 +107,13 @@ void AdvSceneSwitcher::LoadUI()
|
||||
/******************************************************************************
|
||||
* Saving and loading
|
||||
******************************************************************************/
|
||||
static void AskForBackup(obs_data_t *obj);
|
||||
|
||||
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
{
|
||||
if (!switcher) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (saving) {
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->Prune();
|
||||
obs_data_t *obj = obs_data_create();
|
||||
switcher->SaveSettings(obj);
|
||||
switcher->saveSettings(obj);
|
||||
obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
|
||||
obs_data_release(obj);
|
||||
} else {
|
||||
@@ -144,10 +127,10 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
if (!obj) {
|
||||
obj = obs_data_create();
|
||||
}
|
||||
if (switcher->VersionChanged(obj, g_GIT_SHA1)) {
|
||||
if (switcher->versionChanged(obj, g_GIT_SHA1)) {
|
||||
AskForBackup(obj);
|
||||
}
|
||||
switcher->LoadSettings(obj);
|
||||
switcher->loadSettings(obj);
|
||||
obs_data_release(obj);
|
||||
switcher->m.unlock();
|
||||
|
||||
@@ -157,34 +140,6 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
}
|
||||
}
|
||||
|
||||
static void AskForBackup(obs_data_t *obj)
|
||||
{
|
||||
bool backupSettings = DisplayMessage(
|
||||
obs_module_text("AdvSceneSwitcher.askBackup"), true);
|
||||
|
||||
if (!backupSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString path = QFileDialog::getSaveFileName(
|
||||
nullptr,
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle"),
|
||||
GetDefaultSettingsSaveLocation(),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType"));
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Main switcher thread
|
||||
******************************************************************************/
|
||||
@@ -228,7 +183,7 @@ void SwitcherData::Thread()
|
||||
}
|
||||
|
||||
vblog(LOG_INFO, "try to sleep for %ld", duration.count());
|
||||
SetWaitScene();
|
||||
setWaitScene();
|
||||
cv.wait_for(lock, duration);
|
||||
|
||||
startTime = std::chrono::high_resolution_clock::now();
|
||||
@@ -242,13 +197,13 @@ void SwitcherData::Thread()
|
||||
if (checkPause()) {
|
||||
continue;
|
||||
}
|
||||
SetPreconditions();
|
||||
match = CheckForMatch(scene, transition, linger,
|
||||
setPreconditions();
|
||||
match = checkForMatch(scene, transition, linger,
|
||||
setPrevSceneAfterLinger, macroMatch);
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
CheckNoMatchSwitch(match, scene, transition, sleep);
|
||||
checkNoMatchSwitch(match, scene, transition, sleep);
|
||||
checkSwitchCooldown(match);
|
||||
|
||||
if (linger) {
|
||||
@@ -256,14 +211,14 @@ void SwitcherData::Thread()
|
||||
vblog(LOG_INFO, "sleep for %ld before switching scene",
|
||||
duration.count());
|
||||
|
||||
SetWaitScene();
|
||||
setWaitScene();
|
||||
cv.wait_for(lock, duration);
|
||||
|
||||
if (stop) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (SceneChangedDuringWait()) {
|
||||
if (sceneChangedDuringWait()) {
|
||||
vblog(LOG_INFO,
|
||||
"scene was changed manually - ignoring match");
|
||||
|
||||
@@ -274,13 +229,13 @@ void SwitcherData::Thread()
|
||||
}
|
||||
}
|
||||
|
||||
ResetForNextInterval();
|
||||
ClearWebsocketMessages();
|
||||
|
||||
if (match) {
|
||||
if (macroMatch) {
|
||||
RunMacros();
|
||||
runMacros();
|
||||
} else {
|
||||
SwitchScene({scene, transition, 0});
|
||||
switchScene({scene, transition, 0});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +248,7 @@ void SwitcherData::Thread()
|
||||
blog(LOG_INFO, "stopped");
|
||||
}
|
||||
|
||||
void SwitcherData::SetPreconditions()
|
||||
void SwitcherData::setPreconditions()
|
||||
{
|
||||
// Window title
|
||||
lastTitle = currentTitle;
|
||||
@@ -321,28 +276,13 @@ void SwitcherData::SetPreconditions()
|
||||
GetForegroundProcessName(currentForegroundProcess);
|
||||
|
||||
// Cursor
|
||||
std::pair<int, int> cursorPos = GetCursorPos();
|
||||
std::pair<int, int> cursorPos = getCursorPos();
|
||||
cursorPosChanged = cursorPos.first != switcher->lastCursorPos.first ||
|
||||
cursorPos.second != switcher->lastCursorPos.second;
|
||||
lastCursorPos = GetCursorPos();
|
||||
|
||||
// Macro
|
||||
InvalidateMacroTempVarValues();
|
||||
lastCursorPos = getCursorPos();
|
||||
}
|
||||
|
||||
void ClearWebsocketMessages();
|
||||
|
||||
void SwitcherData::ResetForNextInterval()
|
||||
{
|
||||
// Core reset functions
|
||||
ClearWebsocketMessages();
|
||||
// Plugin reset functions
|
||||
for (const auto &func : resetIntervalSteps) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
bool SwitcherData::CheckForMatch(OBSWeakSource &scene,
|
||||
bool SwitcherData::checkForMatch(OBSWeakSource &scene,
|
||||
OBSWeakSource &transition, int &linger,
|
||||
bool &setPrevSceneAfterLinger,
|
||||
bool ¯oMatch)
|
||||
@@ -392,7 +332,7 @@ bool SwitcherData::CheckForMatch(OBSWeakSource &scene,
|
||||
match = checkVideoSwitch(scene, transition);
|
||||
break;
|
||||
case macro_func:
|
||||
if (CheckMacros()) {
|
||||
if (checkMacros()) {
|
||||
match = true;
|
||||
macroMatch = true;
|
||||
}
|
||||
@@ -409,20 +349,48 @@ bool SwitcherData::CheckForMatch(OBSWeakSource &scene,
|
||||
return match;
|
||||
}
|
||||
|
||||
static void ResetMacros()
|
||||
void switchScene(const sceneSwitchInfo &sceneSwitch, bool force)
|
||||
{
|
||||
for (auto &m : switcher->macros) {
|
||||
m->ResetRunCount();
|
||||
m->ResetTimers();
|
||||
if (!sceneSwitch.scene && switcher->verbose) {
|
||||
blog(LOG_INFO, "nothing to switch to");
|
||||
return;
|
||||
}
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(sceneSwitch.scene);
|
||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
||||
|
||||
if (source && (source != currentSource || force)) {
|
||||
transitionData currentTransitionData;
|
||||
setNextTransition(sceneSwitch, currentSource,
|
||||
currentTransitionData);
|
||||
obs_frontend_set_current_scene(source);
|
||||
if (switcher->transitionOverrideOverride) {
|
||||
restoreTransitionOverride(source,
|
||||
currentTransitionData);
|
||||
}
|
||||
|
||||
if (switcher->verbose) {
|
||||
blog(LOG_INFO, "switched scene");
|
||||
}
|
||||
|
||||
if (switcher->networkConfig.ShouldSendSceneChange()) {
|
||||
switcher->server.sendMessage(sceneSwitch);
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void switchPreviewScene(const OBSWeakSource &ws)
|
||||
{
|
||||
auto source = obs_weak_source_get_source(ws);
|
||||
obs_frontend_set_current_preview_scene(source);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void SwitcherData::Start()
|
||||
{
|
||||
if (!(th && th->isRunning())) {
|
||||
ResetForNextInterval();
|
||||
ResetMacros();
|
||||
|
||||
stop = false;
|
||||
th = new SwitcherThread();
|
||||
th->start((QThread::Priority)threadPriority);
|
||||
@@ -447,7 +415,13 @@ void SwitcherData::Start()
|
||||
}
|
||||
}
|
||||
|
||||
bool CloseAllInputDialogs();
|
||||
void ResetMacros()
|
||||
{
|
||||
for (auto &m : switcher->macros) {
|
||||
m->ResetRunCount();
|
||||
m->ResetTimers();
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::Stop()
|
||||
{
|
||||
@@ -457,24 +431,12 @@ void SwitcherData::Stop()
|
||||
abortMacroWait = true;
|
||||
macroWaitCv.notify_all();
|
||||
macroTransitionCv.notify_all();
|
||||
th->wait();
|
||||
delete th;
|
||||
th = nullptr;
|
||||
|
||||
// Not waiting if a dialog was closed is a workaround to avoid
|
||||
// deadlocks when a variable input dialog is opened while Stop()
|
||||
// is called.
|
||||
//
|
||||
// The QEventLoop handling the dialog would not exit until Stop()
|
||||
// would return, which itself would wait for the switcher thread
|
||||
// to complete, which itself is blocked by the variable input
|
||||
// dialog.
|
||||
//
|
||||
// Must be reworked in the future, as this will not go well when
|
||||
// OBS is shutting down and a dialog is still opened.
|
||||
if (!CloseAllInputDialogs()) {
|
||||
th->wait();
|
||||
delete th;
|
||||
th = nullptr;
|
||||
}
|
||||
writeToStatusFile("Advanced Scene Switcher stopped");
|
||||
ResetMacros();
|
||||
}
|
||||
|
||||
server.stop();
|
||||
@@ -487,13 +449,13 @@ void SwitcherData::Stop()
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::SetWaitScene()
|
||||
void SwitcherData::setWaitScene()
|
||||
{
|
||||
waitScene = obs_frontend_get_current_scene();
|
||||
obs_source_release(waitScene);
|
||||
}
|
||||
|
||||
bool SwitcherData::SceneChangedDuringWait()
|
||||
bool SwitcherData::sceneChangedDuringWait()
|
||||
{
|
||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
||||
if (!currentSource) {
|
||||
@@ -506,7 +468,7 @@ bool SwitcherData::SceneChangedDuringWait()
|
||||
// Relies on the fact that switcher->currentScene will only be updated on event
|
||||
// OBS_FRONTEND_EVENT_SCENE_CHANGED but obs_frontend_get_current_scene() will
|
||||
// already return the scene to be transitioned to.
|
||||
bool SwitcherData::AnySceneTransitionStarted()
|
||||
bool SwitcherData::anySceneTransitionStarted()
|
||||
{
|
||||
auto currentSceneSrouce = obs_frontend_get_current_scene();
|
||||
auto currentScene = obs_source_get_weak_source(currentSceneSrouce);
|
||||
@@ -527,13 +489,13 @@ extern "C" void FreeSceneSwitcher()
|
||||
switcher = nullptr;
|
||||
}
|
||||
|
||||
static void handleSceneChange()
|
||||
void handleSceneChange()
|
||||
{
|
||||
switcher->lastSceneChangeTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Stop waiting if scene was changed
|
||||
if (switcher->SceneChangedDuringWait()) {
|
||||
if (switcher->sceneChangedDuringWait()) {
|
||||
switcher->cv.notify_one();
|
||||
}
|
||||
|
||||
@@ -561,33 +523,31 @@ static void handleSceneChange()
|
||||
}
|
||||
}
|
||||
|
||||
static void setLiveTime()
|
||||
void setLiveTime()
|
||||
{
|
||||
switcher->liveTime = QDateTime::currentDateTime();
|
||||
}
|
||||
|
||||
static void resetLiveTime()
|
||||
void resetLiveTime()
|
||||
{
|
||||
switcher->liveTime = QDateTime();
|
||||
}
|
||||
|
||||
static void checkAutoStartRecording()
|
||||
void checkAutoStartRecording()
|
||||
{
|
||||
if (switcher->autoStartEvent == SwitcherData::AutoStart::RECORDING ||
|
||||
switcher->autoStartEvent ==
|
||||
SwitcherData::AutoStart::RECORINDG_OR_STREAMING)
|
||||
if (switcher->autoStartEvent == AutoStartEvent::RECORDING ||
|
||||
switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
||||
switcher->Start();
|
||||
}
|
||||
|
||||
static void checkAutoStartStreaming()
|
||||
void checkAutoStartStreaming()
|
||||
{
|
||||
if (switcher->autoStartEvent == SwitcherData::AutoStart::STREAMING ||
|
||||
switcher->autoStartEvent ==
|
||||
SwitcherData::AutoStart::RECORINDG_OR_STREAMING)
|
||||
if (switcher->autoStartEvent == AutoStartEvent::STREAMING ||
|
||||
switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
||||
switcher->Start();
|
||||
}
|
||||
|
||||
static void handlePeviewSceneChange()
|
||||
void handlePeviewSceneChange()
|
||||
{
|
||||
if (switcher->networkConfig.ShouldSendPrviewSceneChange()) {
|
||||
auto source = obs_frontend_get_current_preview_scene();
|
||||
@@ -598,51 +558,43 @@ static void handlePeviewSceneChange()
|
||||
}
|
||||
}
|
||||
|
||||
static void setReplayBufferSaved()
|
||||
void setReplayBufferSaved()
|
||||
{
|
||||
switcher->replayBufferSaved = true;
|
||||
}
|
||||
|
||||
static void setTranstionEnd()
|
||||
void setTranstionEnd()
|
||||
{
|
||||
switcher->lastTransitionEndTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
switcher->macroTransitionCv.notify_all();
|
||||
}
|
||||
|
||||
static void setStreamStarting()
|
||||
void setStreamStarting()
|
||||
{
|
||||
switcher->lastStreamStartingTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
static void setStreamStopping()
|
||||
void setStreamStopping()
|
||||
{
|
||||
switcher->lastStreamStoppingTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
static void handleShutdown()
|
||||
void handleExit()
|
||||
{
|
||||
if (!switcher) {
|
||||
return;
|
||||
}
|
||||
switcher->obsIsShuttingDown = true;
|
||||
if (switcher->shutdownConditionCount) {
|
||||
if (switcher && switcher->obsIsShuttingDown &&
|
||||
switcher->shutdownConditionCount) {
|
||||
switcher->Stop();
|
||||
switcher->CheckMacros();
|
||||
switcher->RunMacros();
|
||||
|
||||
// Unfortunately this will not work as OBS will now allow saving
|
||||
// the scene collection data at this point, So any OBS specific
|
||||
// changes done during shutdown will be lost
|
||||
//
|
||||
// TODO: Look for a way to possibly resolve this
|
||||
obs_frontend_save();
|
||||
switcher->checkMacros();
|
||||
switcher->runMacros();
|
||||
}
|
||||
FreeSceneSwitcher();
|
||||
}
|
||||
|
||||
static void handleSceneCollectionChanging()
|
||||
void handleSceneCollectionChanging()
|
||||
{
|
||||
if (switcher->settingsWindowOpened) {
|
||||
AdvSceneSwitcher::window->close();
|
||||
@@ -663,12 +615,8 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case OBS_FRONTEND_EVENT_SCRIPTING_SHUTDOWN:
|
||||
// Note: We are intentionally not listening for
|
||||
// OBS_FRONTEND_EVENT_EXIT here as at that point all scene
|
||||
// collection data will already have been cleared and thus all
|
||||
// macros will have already been cleared
|
||||
handleShutdown();
|
||||
case OBS_FRONTEND_EVENT_EXIT:
|
||||
handleExit();
|
||||
break;
|
||||
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
|
||||
handleSceneChange();
|
||||
@@ -706,16 +654,13 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
||||
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGING:
|
||||
handleSceneCollectionChanging();
|
||||
break;
|
||||
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP:
|
||||
SaveSceneSwitcher(nullptr, false, nullptr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadPlugins()
|
||||
void LoadPlugins()
|
||||
{
|
||||
QFileInfo libPath(
|
||||
QString(obs_get_module_binary_path(obs_current_module())));
|
||||
@@ -739,7 +684,6 @@ static void LoadPlugins()
|
||||
blog(LOG_WARNING, "failed to load \"%s\": %s",
|
||||
file.toStdString().c_str(),
|
||||
lib->errorString().toStdString().c_str());
|
||||
switcher->loadFailureLibs << file;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,12 +703,14 @@ void OpenSettingsWindow()
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void InitSceneSwitcher(obs_module_t *module, translateFunc translate)
|
||||
extern "C" void InitSceneSwitcher(obs_module_t *m, translateFunc t)
|
||||
{
|
||||
blog(LOG_INFO, "version: %s", g_GIT_TAG);
|
||||
blog(LOG_INFO, "version: %s", g_GIT_SHA1);
|
||||
|
||||
switcher = new SwitcherData(module, translate);
|
||||
switcher = new SwitcherData;
|
||||
switcher->modulePtr = m;
|
||||
switcher->translate = t;
|
||||
|
||||
PlatformInit();
|
||||
LoadPlugins();
|
||||
@@ -777,5 +723,3 @@ extern "C" void InitSceneSwitcher(obs_module_t *module, translateFunc translate)
|
||||
obs_module_text("AdvSceneSwitcher.pluginName"));
|
||||
action->connect(action, &QAction::triggered, OpenSettingsWindow);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#pragma once
|
||||
#include "macro-segment-list.hpp"
|
||||
#include "log-helper.hpp"
|
||||
#include "switcher-data-structs.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
|
||||
#include <macro-segment-list.hpp>
|
||||
#include <ui_advanced-scene-switcher.h>
|
||||
|
||||
#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__)
|
||||
#define vblog(level, msg, ...) \
|
||||
if (switcher->verbose) { \
|
||||
blog(level, msg, ##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
class QCloseEvent;
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroActionEdit;
|
||||
class MacroConditionEdit;
|
||||
class Duration;
|
||||
class SequenceWidget;
|
||||
struct SceneGroup;
|
||||
|
||||
/*******************************************************************************
|
||||
* Advanced Scene Switcher window
|
||||
@@ -32,133 +33,134 @@ public:
|
||||
void reject() override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
void LoadUI();
|
||||
void SetShowFrames();
|
||||
void SetHideFrames();
|
||||
void clearFrames(QListWidget *list);
|
||||
|
||||
void SetTabOrder();
|
||||
void SetCurrentTab();
|
||||
void RestoreWindowGeo();
|
||||
void CheckFirstTimeSetup();
|
||||
int IgnoreWindowsFindByData(const QString &window);
|
||||
int IgnoreIdleWindowsFindByData(const QString &window);
|
||||
|
||||
/* --- Begin of general tab section --- */
|
||||
public:
|
||||
void SetupGeneralTab();
|
||||
void UpdateNonMatchingScene(const QString &name);
|
||||
void SetDeprecationWarnings();
|
||||
void OpenSequenceExtendEdit(SequenceWidget *sw);
|
||||
void SetEditSceneGroup(SceneGroup &sg);
|
||||
|
||||
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));
|
||||
void HighlightCondition(int idx, QColor color = QColor(Qt::green));
|
||||
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
|
||||
void PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
|
||||
void SetActionData(Macro &m);
|
||||
void SetConditionData(Macro &m);
|
||||
void SwapActions(Macro *m, int pos1, int pos2);
|
||||
void SwapConditions(Macro *m, int pos1, int pos2);
|
||||
|
||||
void loadUI();
|
||||
void setupGeneralTab();
|
||||
void setupTitleTab();
|
||||
void setupExecutableTab();
|
||||
void setupRegionTab();
|
||||
void setupPauseTab();
|
||||
void setupSequenceTab();
|
||||
void setupTransitionsTab();
|
||||
void setupIdleTab();
|
||||
void setupRandomTab();
|
||||
void setupMediaTab();
|
||||
void setupFileTab();
|
||||
void setupTimeTab();
|
||||
void setupAudioTab();
|
||||
void setupSceneGroupTab();
|
||||
void setupTriggerTab();
|
||||
void setupVideoTab();
|
||||
void setupNetworkTab();
|
||||
void setupMacroTab();
|
||||
void setDeprecationWarnings();
|
||||
void setTabOrder();
|
||||
void setCurrentTab();
|
||||
void restoreWindowGeo();
|
||||
void checkFirstTimeSetup();
|
||||
|
||||
signals:
|
||||
void MacroAdded(const QString &name);
|
||||
void MacroRemoved(const QString &name);
|
||||
void MacroRenamed(const QString &oldName, const QString &newName);
|
||||
void MacroSegmentOrderChanged();
|
||||
void HighlightMacrosChanged(bool value);
|
||||
void HighlightActionsChanged(bool value);
|
||||
void HighlightConditionsChanged(bool value);
|
||||
void SceneGroupAdded(const QString &name);
|
||||
void SceneGroupRemoved(const QString &name);
|
||||
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||
void ConnectionAdded(const QString &);
|
||||
void ConnectionRenamed(const QString &oldName, const QString &newName);
|
||||
void ConnectionRemoved(const QString &);
|
||||
void VariableAdded(const QString &);
|
||||
void VariableRenamed(const QString &oldName, const QString &newName);
|
||||
void VariableRemoved(const QString &);
|
||||
|
||||
public slots:
|
||||
void on_windowUp_clicked();
|
||||
void on_windowDown_clicked();
|
||||
void on_windowAdd_clicked();
|
||||
void on_windowRemove_clicked();
|
||||
void on_noMatchDontSwitch_clicked();
|
||||
void on_noMatchSwitch_clicked();
|
||||
void on_noMatchRandomSwitch_clicked();
|
||||
void NoMatchDelayDurationChanged(const Duration &);
|
||||
void CooldownDurationChanged(const Duration &);
|
||||
void NoMatchDelayDurationChanged(double);
|
||||
void NoMatchDelayUnitChanged(DurationUnit);
|
||||
void CooldownDurationChanged(double);
|
||||
void CooldownUnitChanged(DurationUnit);
|
||||
void on_startupBehavior_currentIndexChanged(int index);
|
||||
void on_autoStartEvent_currentIndexChanged(int index);
|
||||
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
|
||||
void on_checkInterval_valueChanged(int value);
|
||||
void on_tabMoved(int from, int to);
|
||||
void on_tabWidget_currentChanged(int index);
|
||||
void on_exportSettings_clicked();
|
||||
void on_importSettings_clicked();
|
||||
void on_verboseLogging_stateChanged(int state);
|
||||
void on_saveWindowGeo_stateChanged(int state);
|
||||
void on_showTrayNotifications_stateChanged(int state);
|
||||
void on_uiHintsDisable_stateChanged(int state);
|
||||
void on_disableComboBoxFilter_stateChanged(int state);
|
||||
void on_warnPluginLoadFailure_stateChanged(int state);
|
||||
void on_hideLegacyTabs_stateChanged(int state);
|
||||
void on_priorityUp_clicked();
|
||||
void on_priorityDown_clicked();
|
||||
void on_threadPriority_currentTextChanged(const QString &text);
|
||||
|
||||
/* --- End of legacy tab section --- */
|
||||
|
||||
/* --- Begin of macro tab section --- */
|
||||
public:
|
||||
void SetupMacroTab();
|
||||
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));
|
||||
void HighlightElseAction(int idx, QColor color = QColor(Qt::green));
|
||||
void HighlightCondition(int idx, QColor color = QColor(Qt::green));
|
||||
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
|
||||
void PopulateMacroElseActions(Macro &m, uint32_t afterIdx = 0);
|
||||
void PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
|
||||
void SetActionData(Macro &m);
|
||||
void SetElseActionData(Macro &m);
|
||||
void SetConditionData(Macro &m);
|
||||
void SwapActions(Macro *m, int pos1, int pos2);
|
||||
void SwapConditions(Macro *m, int pos1, int pos2);
|
||||
|
||||
public slots:
|
||||
void on_macroAdd_clicked();
|
||||
void on_macroRemove_clicked();
|
||||
void on_macroUp_clicked();
|
||||
void on_macroDown_clicked();
|
||||
void on_macroName_editingFinished();
|
||||
void on_runMacro_clicked();
|
||||
void on_runMacroInParallel_stateChanged(int value);
|
||||
void on_runMacroOnChange_stateChanged(int value);
|
||||
void on_conditionAdd_clicked();
|
||||
void on_conditionRemove_clicked();
|
||||
void on_conditionTop_clicked();
|
||||
void on_conditionUp_clicked();
|
||||
void on_conditionDown_clicked();
|
||||
void on_conditionBottom_clicked();
|
||||
void on_actionAdd_clicked();
|
||||
void on_actionRemove_clicked();
|
||||
void on_actionTop_clicked();
|
||||
void on_actionUp_clicked();
|
||||
void on_actionDown_clicked();
|
||||
void on_actionBottom_clicked();
|
||||
void on_elseActionAdd_clicked();
|
||||
void on_elseActionRemove_clicked();
|
||||
void on_elseActionTop_clicked();
|
||||
void on_elseActionUp_clicked();
|
||||
void on_elseActionDown_clicked();
|
||||
void on_elseActionBottom_clicked();
|
||||
void MacroSelectionAboutToChange();
|
||||
void MacroSelectionChanged();
|
||||
void MacroSelectionChanged(const QItemSelection &,
|
||||
const QItemSelection &);
|
||||
void UpMacroSegementHotkey();
|
||||
void DownMacroSegementHotkey();
|
||||
void DeleteMacroSegementHotkey();
|
||||
void ShowMacroContextMenu(const QPoint &);
|
||||
void ShowMacroActionsContextMenu(const QPoint &);
|
||||
void ShowMacroElseActionsContextMenu(const QPoint &);
|
||||
void ShowMacroConditionsContextMenu(const QPoint &);
|
||||
void CopyMacro();
|
||||
void RenameCurrentMacro();
|
||||
void ExportMacros();
|
||||
void ImportMacros();
|
||||
void ExpandAllActions();
|
||||
void ExpandAllElseActions();
|
||||
void ExpandAllConditions();
|
||||
void CollapseAllActions();
|
||||
void CollapseAllElseActions();
|
||||
void CollapseAllConditions();
|
||||
void MinimizeActions();
|
||||
void MaximizeActions();
|
||||
void MinimizeElseActions();
|
||||
void MaximizeElseActions();
|
||||
void MinimizeConditions();
|
||||
void MaximizeConditions();
|
||||
void MacroActionSelectionChanged(int idx);
|
||||
void MacroActionReorder(int to, int target);
|
||||
void AddMacroAction(int idx);
|
||||
void RemoveMacroAction(int idx);
|
||||
void MoveMacroActionUp(int idx);
|
||||
void MoveMacroActionDown(int idx);
|
||||
void MacroElseActionSelectionChanged(int idx);
|
||||
void MacroElseActionReorder(int to, int target);
|
||||
void AddMacroElseAction(int idx);
|
||||
void RemoveMacroElseAction(int idx);
|
||||
void SwapElseActions(Macro *m, int pos1, int pos2);
|
||||
void MoveMacroElseActionUp(int idx);
|
||||
void MoveMacroElseActionDown(int idx);
|
||||
void MacroConditionSelectionChanged(int idx);
|
||||
void MacroConditionReorder(int to, int target);
|
||||
void AddMacroCondition(int idx);
|
||||
@@ -173,84 +175,22 @@ public slots:
|
||||
void HighlightOnChange();
|
||||
void on_macroProperties_clicked();
|
||||
|
||||
signals:
|
||||
void MacroAdded(const QString &name);
|
||||
void MacroRemoved(const QString &name);
|
||||
void MacroRenamed(const QString &oldName, const QString &newName);
|
||||
void MacroSegmentOrderChanged();
|
||||
void SegmentTempVarsChanged();
|
||||
void HighlightMacrosChanged(bool value);
|
||||
void HighlightActionsChanged(bool value);
|
||||
void HighlightElseActionsChanged(bool value);
|
||||
void HighlightConditionsChanged(bool value);
|
||||
|
||||
void ConnectionAdded(const QString &);
|
||||
void ConnectionRenamed(const QString &oldName, const QString &newName);
|
||||
void ConnectionRemoved(const QString &);
|
||||
void VariableAdded(const QString &);
|
||||
void VariableRenamed(const QString &oldName, const QString &newName);
|
||||
void VariableRemoved(const QString &);
|
||||
|
||||
private:
|
||||
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
|
||||
|
||||
void SetupMacroSegmentSelection(MacroSection type, int idx);
|
||||
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &);
|
||||
bool MacroTabIsInFocus();
|
||||
|
||||
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
||||
int currentConditionIdx = -1;
|
||||
int currentActionIdx = -1;
|
||||
int currentElseActionIdx = -1;
|
||||
|
||||
/* --- End of macro tab section --- */
|
||||
|
||||
/* --- Begin of legacy tab section --- */
|
||||
public:
|
||||
void ClearFrames(QListWidget *list);
|
||||
int IgnoreWindowsFindByData(const QString &window);
|
||||
int IgnoreIdleWindowsFindByData(const QString &window);
|
||||
void OpenSequenceExtendEdit(SequenceWidget *sw);
|
||||
|
||||
// Window tab
|
||||
public:
|
||||
void SetupTitleTab();
|
||||
public slots:
|
||||
void on_windowUp_clicked();
|
||||
void on_windowDown_clicked();
|
||||
void on_windowAdd_clicked();
|
||||
void on_windowRemove_clicked();
|
||||
void on_ignoreWindows_currentRowChanged(int idx);
|
||||
void on_ignoreWindowsAdd_clicked();
|
||||
void on_ignoreWindowsRemove_clicked();
|
||||
|
||||
// Screen region tab
|
||||
public:
|
||||
void SetupRegionTab();
|
||||
public slots:
|
||||
void SetShowFrames();
|
||||
void SetHideFrames();
|
||||
void on_screenRegionSwitches_currentRowChanged(int idx);
|
||||
void on_showFrame_clicked();
|
||||
void on_screenRegionAdd_clicked();
|
||||
void on_screenRegionRemove_clicked();
|
||||
void on_screenRegionUp_clicked();
|
||||
void on_screenRegionDown_clicked();
|
||||
void updateScreenRegionCursorPos();
|
||||
|
||||
// Pause tab
|
||||
public:
|
||||
void SetupPauseTab();
|
||||
public slots:
|
||||
void on_pauseUp_clicked();
|
||||
void on_pauseDown_clicked();
|
||||
void on_pauseAdd_clicked();
|
||||
void on_pauseRemove_clicked();
|
||||
|
||||
// Sequence tab
|
||||
public:
|
||||
void SetupSequenceTab();
|
||||
public slots:
|
||||
void on_ignoreWindows_currentRowChanged(int idx);
|
||||
void on_ignoreWindowsAdd_clicked();
|
||||
void on_ignoreWindowsRemove_clicked();
|
||||
|
||||
void on_sceneSequenceAdd_clicked();
|
||||
void on_sceneSequenceRemove_clicked();
|
||||
void on_sceneSequenceUp_clicked();
|
||||
@@ -260,10 +200,15 @@ public slots:
|
||||
void on_sequenceEdit_clicked();
|
||||
void on_sceneSequenceSwitches_itemDoubleClicked(QListWidgetItem *item);
|
||||
|
||||
// Transition tab
|
||||
public:
|
||||
void SetupTransitionsTab();
|
||||
public slots:
|
||||
void on_verboseLogging_stateChanged(int state);
|
||||
void on_saveWindowGeo_stateChanged(int state);
|
||||
void on_showTrayNotifications_stateChanged(int state);
|
||||
void on_uiHintsDisable_stateChanged(int state);
|
||||
void on_hideLegacyTabs_stateChanged(int state);
|
||||
|
||||
void on_exportSettings_clicked();
|
||||
void on_importSettings_clicked();
|
||||
|
||||
void on_transitionsAdd_clicked();
|
||||
void on_transitionsRemove_clicked();
|
||||
void on_transitionsUp_clicked();
|
||||
@@ -274,95 +219,60 @@ public slots:
|
||||
void on_defaultTransitionsDown_clicked();
|
||||
void on_transitionOverridecheckBox_stateChanged(int state);
|
||||
void on_adjustActiveTransitionType_stateChanged(int state);
|
||||
void DefTransitionDelayValueChanged(int value);
|
||||
void defTransitionDelayValueChanged(int value);
|
||||
|
||||
// Executable tab
|
||||
public:
|
||||
void SetupExecutableTab();
|
||||
public slots:
|
||||
void on_executableUp_clicked();
|
||||
void on_executableDown_clicked();
|
||||
void on_executableAdd_clicked();
|
||||
void on_executableRemove_clicked();
|
||||
|
||||
// Idle tab
|
||||
public:
|
||||
void SetupIdleTab();
|
||||
public slots:
|
||||
void on_idleCheckBox_stateChanged(int state);
|
||||
void on_ignoreIdleWindows_currentRowChanged(int idx);
|
||||
void on_ignoreIdleAdd_clicked();
|
||||
void on_ignoreIdleRemove_clicked();
|
||||
|
||||
// Random tab
|
||||
public:
|
||||
void SetupRandomTab();
|
||||
public slots:
|
||||
void on_randomAdd_clicked();
|
||||
void on_randomRemove_clicked();
|
||||
|
||||
// File tab
|
||||
public:
|
||||
void SetupFileTab();
|
||||
public slots:
|
||||
void on_fileAdd_clicked();
|
||||
void on_fileRemove_clicked();
|
||||
void on_fileSwitches_currentRowChanged(int idx);
|
||||
void on_fileUp_clicked();
|
||||
void on_fileDown_clicked();
|
||||
void on_browseButton_clicked();
|
||||
void on_readFileCheckBox_stateChanged(int state);
|
||||
void on_readPathLineEdit_textChanged(const QString &text);
|
||||
void on_writePathLineEdit_textChanged(const QString &text);
|
||||
void on_browseButton_2_clicked();
|
||||
|
||||
// Media tab
|
||||
public:
|
||||
void SetupMediaTab();
|
||||
public slots:
|
||||
void on_executableUp_clicked();
|
||||
void on_executableDown_clicked();
|
||||
void on_executableAdd_clicked();
|
||||
void on_executableRemove_clicked();
|
||||
|
||||
void on_idleCheckBox_stateChanged(int state);
|
||||
void on_ignoreIdleWindows_currentRowChanged(int idx);
|
||||
void on_ignoreIdleAdd_clicked();
|
||||
void on_ignoreIdleRemove_clicked();
|
||||
|
||||
void on_randomAdd_clicked();
|
||||
void on_randomRemove_clicked();
|
||||
|
||||
void on_fileAdd_clicked();
|
||||
void on_fileRemove_clicked();
|
||||
void on_fileSwitches_currentRowChanged(int idx);
|
||||
void on_fileUp_clicked();
|
||||
void on_fileDown_clicked();
|
||||
|
||||
void on_mediaAdd_clicked();
|
||||
void on_mediaRemove_clicked();
|
||||
void on_mediaUp_clicked();
|
||||
void on_mediaDown_clicked();
|
||||
|
||||
// Time tab
|
||||
public:
|
||||
void SetupTimeTab();
|
||||
public slots:
|
||||
void on_timeAdd_clicked();
|
||||
void on_timeRemove_clicked();
|
||||
void on_timeUp_clicked();
|
||||
void on_timeDown_clicked();
|
||||
|
||||
// Video tab
|
||||
public:
|
||||
void SetupAudioTab();
|
||||
public slots:
|
||||
void on_audioAdd_clicked();
|
||||
void on_audioRemove_clicked();
|
||||
void on_audioUp_clicked();
|
||||
void on_audioDown_clicked();
|
||||
void on_audioFallback_toggled(bool on);
|
||||
|
||||
// Video tab
|
||||
public:
|
||||
void SetupVideoTab();
|
||||
public slots:
|
||||
void on_videoAdd_clicked();
|
||||
void on_videoRemove_clicked();
|
||||
void on_videoUp_clicked();
|
||||
void on_videoDown_clicked();
|
||||
void on_getScreenshot_clicked();
|
||||
|
||||
// Scene group tab
|
||||
public:
|
||||
void SetupNetworkTab();
|
||||
public slots:
|
||||
void on_serverSettings_toggled(bool on);
|
||||
void on_serverPort_valueChanged(int value);
|
||||
void on_lockToIPv4_stateChanged(int state);
|
||||
void on_serverRestart_clicked();
|
||||
void UpdateServerStatus();
|
||||
void updateServerStatus();
|
||||
void on_clientSettings_toggled(bool on);
|
||||
void on_clientHostname_textChanged(const QString &text);
|
||||
void on_clientPort_valueChanged(int value);
|
||||
@@ -370,41 +280,67 @@ public slots:
|
||||
void on_restrictSend_stateChanged(int state);
|
||||
void on_sendPreview_stateChanged(int state);
|
||||
void on_clientReconnect_clicked();
|
||||
void UpdateClientStatus();
|
||||
void updateClientStatus();
|
||||
|
||||
// Scene group tab
|
||||
public:
|
||||
void SetupSceneGroupTab();
|
||||
void SetEditSceneGroup(SceneGroup &sg);
|
||||
public slots:
|
||||
void on_sceneGroupAdd_clicked();
|
||||
void on_sceneGroupRemove_clicked();
|
||||
void on_sceneGroupUp_clicked();
|
||||
void on_sceneGroupDown_clicked();
|
||||
void on_sceneGroupName_editingFinished();
|
||||
void on_sceneGroups_currentRowChanged(int idx);
|
||||
|
||||
void on_sceneGroupSceneAdd_clicked();
|
||||
void on_sceneGroupSceneRemove_clicked();
|
||||
void on_sceneGroupSceneUp_clicked();
|
||||
void on_sceneGroupSceneDown_clicked();
|
||||
|
||||
signals:
|
||||
void SceneGroupAdded(const QString &name);
|
||||
void SceneGroupRemoved(const QString &name);
|
||||
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||
|
||||
// Trigger tab
|
||||
public:
|
||||
void SetupTriggerTab();
|
||||
public slots:
|
||||
void on_triggerAdd_clicked();
|
||||
void on_triggerRemove_clicked();
|
||||
void on_triggerUp_clicked();
|
||||
void on_triggerDown_clicked();
|
||||
|
||||
/* --- End of legacy tab section --- */
|
||||
void on_priorityUp_clicked();
|
||||
void on_priorityDown_clicked();
|
||||
void on_threadPriority_currentTextChanged(const QString &text);
|
||||
|
||||
void updateScreenRegionCursorPos();
|
||||
|
||||
private:
|
||||
bool MacroTabIsInFocus();
|
||||
|
||||
MacroSegmentList *conditionsList = nullptr;
|
||||
MacroSegmentList *actionsList = nullptr;
|
||||
|
||||
enum class MacroSection {
|
||||
CONDITIONS,
|
||||
ACTIONS,
|
||||
};
|
||||
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
||||
int currentConditionIdx = -1;
|
||||
int currentActionIdx = -1;
|
||||
};
|
||||
|
||||
void OpenSettingsWindow();
|
||||
|
||||
} // namespace advss
|
||||
/******************************************************************************
|
||||
* Sceneswitch helper
|
||||
******************************************************************************/
|
||||
void setNextTransition(const sceneSwitchInfo &ssi, obs_source_t *currentSource,
|
||||
transitionData &td);
|
||||
void overwriteTransitionOverride(const sceneSwitchInfo &ssi,
|
||||
transitionData &td);
|
||||
void restoreTransitionOverride(obs_source_t *scene, const transitionData &td);
|
||||
void switchScene(const sceneSwitchInfo &ssi, bool force = false);
|
||||
void switchPreviewScene(const OBSWeakSource &ws);
|
||||
|
||||
/******************************************************************************
|
||||
* Settings helper
|
||||
******************************************************************************/
|
||||
void AskForBackup(obs_data_t *obj);
|
||||
|
||||
/******************************************************************************
|
||||
* Main SwitcherData
|
||||
******************************************************************************/
|
||||
struct SwitcherData;
|
||||
extern SwitcherData *switcher;
|
||||
SwitcherData *GetSwitcher();
|
||||
|
||||
507
src/general.cpp
@@ -1,14 +1,11 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "status-control.hpp"
|
||||
#include "file-selection.hpp"
|
||||
#include "filter-combo-box.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "version.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
namespace advss {
|
||||
#include <QStandardPaths>
|
||||
|
||||
void AdvSceneSwitcher::reject()
|
||||
{
|
||||
@@ -33,7 +30,7 @@ void AdvSceneSwitcher::on_noMatchDontSwitch_clicked()
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = SwitcherData::NoMatch::NO_SWITCH;
|
||||
switcher->switchIfNotMatching = NO_SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
ui->randomDisabledWarning->setVisible(true);
|
||||
}
|
||||
@@ -45,7 +42,7 @@ void AdvSceneSwitcher::on_noMatchSwitch_clicked()
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = SwitcherData::NoMatch::SWITCH;
|
||||
switcher->switchIfNotMatching = SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(true);
|
||||
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
|
||||
ui->randomDisabledWarning->setVisible(true);
|
||||
@@ -58,29 +55,49 @@ void AdvSceneSwitcher::on_noMatchRandomSwitch_clicked()
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = SwitcherData::NoMatch::RANDOM_SWITCH;
|
||||
switcher->switchIfNotMatching = RANDOM_SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
ui->randomDisabledWarning->setVisible(false);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::NoMatchDelayDurationChanged(const Duration &dur)
|
||||
void AdvSceneSwitcher::NoMatchDelayDurationChanged(double sec)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->noMatchDelay = dur;
|
||||
switcher->noMatchDelay.seconds = sec;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::CooldownDurationChanged(const Duration &dur)
|
||||
void AdvSceneSwitcher::NoMatchDelayUnitChanged(DurationUnit unit)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->cooldown = dur;
|
||||
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;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
||||
@@ -90,8 +107,7 @@ void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->startupBehavior =
|
||||
static_cast<SwitcherData::StartupBehavior>(index);
|
||||
switcher->startupBehavior = (StartupBehavior)index;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
||||
@@ -101,7 +117,7 @@ void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->autoStartEvent = static_cast<SwitcherData::AutoStart>(index);
|
||||
switcher->autoStartEvent = static_cast<AutoStartEvent>(index);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
|
||||
@@ -132,9 +148,10 @@ void AdvSceneSwitcher::closeEvent(QCloseEvent *)
|
||||
}
|
||||
switcher->windowPos = this->pos();
|
||||
switcher->windowSize = this->size();
|
||||
switcher->macroActionConditionSplitterPosition =
|
||||
ui->macroActionConditionSplitter->sizes();
|
||||
switcher->macroListMacroEditSplitterPosition =
|
||||
ui->macroListMacroEditSplitter->sizes();
|
||||
MacroSelectionAboutToChange(); // Trigger saving of splitter states
|
||||
|
||||
obs_frontend_save();
|
||||
}
|
||||
@@ -175,26 +192,7 @@ void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
|
||||
switcher->disableHints = state;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_disableComboBoxFilter_stateChanged(int state)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
switcher->disableFilterComboboxFilter = state;
|
||||
FilterComboBox::SetFilterBehaviourEnabled(!state);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
switcher->warnPluginLoadFailure = state;
|
||||
}
|
||||
|
||||
static bool isLegacyTab(const QString &name)
|
||||
bool isLegacyTab(const QString &name)
|
||||
{
|
||||
return name == obs_module_text(
|
||||
"AdvSceneSwitcher.sceneGroupTab.title") ||
|
||||
@@ -239,7 +237,7 @@ void AdvSceneSwitcher::on_hideLegacyTabs_stateChanged(int state)
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetDeprecationWarnings()
|
||||
void AdvSceneSwitcher::setDeprecationWarnings()
|
||||
{
|
||||
QString toolTip =
|
||||
switcher->disableHints
|
||||
@@ -253,13 +251,70 @@ void AdvSceneSwitcher::SetDeprecationWarnings()
|
||||
}
|
||||
}
|
||||
|
||||
QString getDefaultSaveLocation()
|
||||
{
|
||||
QString desktopPath = QStandardPaths::writableLocation(
|
||||
QStandardPaths::DesktopLocation);
|
||||
|
||||
auto scName = obs_frontend_get_current_scene_collection();
|
||||
QString sceneCollectionName(scName);
|
||||
bfree(scName);
|
||||
|
||||
auto timestamp = QDateTime::currentDateTime();
|
||||
auto path = desktopPath + "/adv-ss-" + sceneCollectionName + "-" +
|
||||
timestamp.toString("yyyy.MM.dd.hh.mm.ss");
|
||||
|
||||
// Check if scene collection name contains invalid path characters
|
||||
QFile file(path);
|
||||
if (file.exists()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
bool validPath = file.open(QIODevice::WriteOnly);
|
||||
if (validPath) {
|
||||
file.remove();
|
||||
return path;
|
||||
}
|
||||
|
||||
return desktopPath + "/adv-ss-" +
|
||||
timestamp.toString("yyyy.MM.dd.hh.mm.ss");
|
||||
}
|
||||
|
||||
void AskForBackup(obs_data_t *obj)
|
||||
{
|
||||
bool backupSettings = DisplayMessage(
|
||||
obs_module_text("AdvSceneSwitcher.askBackup"), true);
|
||||
|
||||
if (!backupSettings) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString path = QFileDialog::getSaveFileName(
|
||||
nullptr,
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle"),
|
||||
getDefaultSaveLocation(),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType"));
|
||||
if (path.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_exportSettings_clicked()
|
||||
{
|
||||
QString directory = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
tr(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle")),
|
||||
GetDefaultSettingsSaveLocation(),
|
||||
getDefaultSaveLocation(),
|
||||
tr(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType")));
|
||||
if (directory.isEmpty()) {
|
||||
@@ -272,7 +327,7 @@ void AdvSceneSwitcher::on_exportSettings_clicked()
|
||||
}
|
||||
|
||||
obs_data_t *obj = obs_data_create();
|
||||
switcher->SaveSettings(obj);
|
||||
switcher->saveSettings(obj);
|
||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||
obs_data_release(obj);
|
||||
}
|
||||
@@ -312,7 +367,7 @@ void AdvSceneSwitcher::on_importSettings_clicked()
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->LoadSettings(obj);
|
||||
switcher->loadSettings(obj);
|
||||
obs_data_release(obj);
|
||||
switcher->lastImportPath = path.toStdString();
|
||||
|
||||
@@ -328,7 +383,7 @@ void AdvSceneSwitcher::on_importSettings_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
static int findTabIndex(QTabWidget *tabWidget, int pos)
|
||||
int findTabIndex(QTabWidget *tabWidget, int pos)
|
||||
{
|
||||
int at = -1;
|
||||
|
||||
@@ -402,10 +457,10 @@ static int findTabIndex(QTabWidget *tabWidget, int pos)
|
||||
return at;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetTabOrder()
|
||||
void AdvSceneSwitcher::setTabOrder()
|
||||
{
|
||||
if (!switcher->TabOrderValid()) {
|
||||
switcher->ResetTabOrder();
|
||||
if (!switcher->tabOrderValid()) {
|
||||
switcher->resetTabOrder();
|
||||
}
|
||||
|
||||
QTabBar *bar = ui->tabWidget->tabBar();
|
||||
@@ -420,22 +475,22 @@ void AdvSceneSwitcher::SetTabOrder()
|
||||
connect(bar, &QTabBar::tabMoved, this, &AdvSceneSwitcher::on_tabMoved);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetCurrentTab()
|
||||
void AdvSceneSwitcher::setCurrentTab()
|
||||
{
|
||||
if (switcher->lastOpenedTab >= 0) {
|
||||
ui->tabWidget->setCurrentIndex(switcher->lastOpenedTab);
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::RestoreWindowGeo()
|
||||
void AdvSceneSwitcher::restoreWindowGeo()
|
||||
{
|
||||
if (switcher->saveWindowGeo && WindowPosValid(switcher->windowPos)) {
|
||||
if (switcher->saveWindowGeo && windowPosValid(switcher->windowPos)) {
|
||||
this->resize(switcher->windowSize);
|
||||
this->move(switcher->windowPos);
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::CheckFirstTimeSetup()
|
||||
void AdvSceneSwitcher::checkFirstTimeSetup()
|
||||
{
|
||||
if (switcher->firstBoot && !switcher->disableHints) {
|
||||
switcher->firstBoot = false;
|
||||
@@ -456,7 +511,7 @@ void AdvSceneSwitcher::on_tabMoved(int from, int to)
|
||||
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
|
||||
{
|
||||
switcher->showFrame = false;
|
||||
ClearFrames(ui->screenRegionSwitches);
|
||||
clearFrames(ui->screenRegionSwitches);
|
||||
SetShowFrames();
|
||||
}
|
||||
|
||||
@@ -493,26 +548,18 @@ void AdvSceneSwitcher::on_adjustActiveTransitionType_stateChanged(int state)
|
||||
switcher->adjustActiveTransitionType = state;
|
||||
}
|
||||
|
||||
void SwitcherData::LoadSettings(obs_data_t *obj)
|
||||
void SwitcherData::loadSettings(obs_data_t *obj)
|
||||
{
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
// New post load steps to be declared during load
|
||||
postLoadSteps.clear();
|
||||
|
||||
// Needs to be loaded before any entries which might rely on scene group
|
||||
// selections to be available.
|
||||
loadSceneGroups(obj);
|
||||
LoadVariables(obj);
|
||||
LoadConnections(obj);
|
||||
|
||||
for (const auto &func : loadSteps) {
|
||||
func(obj);
|
||||
}
|
||||
|
||||
LoadMacros(obj);
|
||||
loadVariables(obj);
|
||||
loadMacros(obj);
|
||||
loadConnections(obj);
|
||||
loadWindowTitleSwitches(obj);
|
||||
loadScreenRegionSwitches(obj);
|
||||
loadPauseSwitches(obj);
|
||||
@@ -528,29 +575,24 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
||||
loadVideoSwitches(obj);
|
||||
loadNetworkSettings(obj);
|
||||
loadSceneTriggers(obj);
|
||||
LoadGeneralSettings(obj);
|
||||
LoadHotkeys(obj);
|
||||
LoadUISettings(obj);
|
||||
|
||||
for (const auto &func : postLoadSteps) {
|
||||
func();
|
||||
}
|
||||
loadGeneralSettings(obj);
|
||||
loadHotkeys(obj);
|
||||
loadUISettings(obj);
|
||||
|
||||
// Reset on startup and scene collection change
|
||||
switcher->lastOpenedTab = -1;
|
||||
startupLoadDone = true;
|
||||
}
|
||||
|
||||
void SwitcherData::SaveSettings(obs_data_t *obj)
|
||||
void SwitcherData::saveSettings(obs_data_t *obj)
|
||||
{
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
saveSceneGroups(obj);
|
||||
SaveMacros(obj);
|
||||
SaveConnections(obj);
|
||||
SaveVariables(obj);
|
||||
saveMacros(obj);
|
||||
saveConnections(obj);
|
||||
saveVariables(obj);
|
||||
saveWindowTitleSwitches(obj);
|
||||
saveScreenRegionSwitches(obj);
|
||||
savePauseSwitches(obj);
|
||||
@@ -566,33 +608,27 @@ void SwitcherData::SaveSettings(obs_data_t *obj)
|
||||
saveVideoSwitches(obj);
|
||||
saveNetworkSwitches(obj);
|
||||
saveSceneTriggers(obj);
|
||||
SaveGeneralSettings(obj);
|
||||
SaveHotkeys(obj);
|
||||
SaveUISettings(obj);
|
||||
SaveVersion(obj, g_GIT_SHA1);
|
||||
|
||||
for (const auto &func : saveSteps) {
|
||||
func(obj);
|
||||
}
|
||||
saveGeneralSettings(obj);
|
||||
saveHotkeys(obj);
|
||||
saveUISettings(obj);
|
||||
saveVersion(obj, g_GIT_SHA1);
|
||||
}
|
||||
|
||||
void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
||||
void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
||||
{
|
||||
obs_data_set_int(obj, "interval", interval);
|
||||
|
||||
std::string nonMatchingSceneName = GetWeakSourceName(nonMatchingScene);
|
||||
obs_data_set_string(obj, "non_matching_scene",
|
||||
nonMatchingSceneName.c_str());
|
||||
obs_data_set_int(obj, "switch_if_not_matching",
|
||||
static_cast<int>(switchIfNotMatching));
|
||||
noMatchDelay.Save(obj, "noMatchDelay");
|
||||
obs_data_set_int(obj, "switch_if_not_matching", switchIfNotMatching);
|
||||
noMatchDelay.Save(obj, "noMatchDelay", "noMatchDelayUnit");
|
||||
|
||||
cooldown.Save(obj, "cooldown");
|
||||
cooldown.Save(obj, "cooldown", "cooldownUnit");
|
||||
|
||||
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
|
||||
sceneColletionStop = false;
|
||||
obs_data_set_int(obj, "startup_behavior",
|
||||
static_cast<int>(startupBehavior));
|
||||
obs_data_set_int(obj, "startup_behavior", startupBehavior);
|
||||
|
||||
obs_data_set_int(obj, "autoStartEvent",
|
||||
static_cast<int>(autoStartEvent));
|
||||
@@ -601,12 +637,19 @@ 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, "disableFilterComboboxFilter",
|
||||
disableFilterComboboxFilter);
|
||||
obs_data_set_bool(obj, "warnPluginLoadFailure", warnPluginLoadFailure);
|
||||
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
||||
|
||||
SaveFunctionPriorities(obj, functionNamesByPriority);
|
||||
obs_data_set_int(obj, "priority0", functionNamesByPriority[0]);
|
||||
obs_data_set_int(obj, "priority1", functionNamesByPriority[1]);
|
||||
obs_data_set_int(obj, "priority2", functionNamesByPriority[2]);
|
||||
obs_data_set_int(obj, "priority3", functionNamesByPriority[3]);
|
||||
obs_data_set_int(obj, "priority4", functionNamesByPriority[4]);
|
||||
obs_data_set_int(obj, "priority5", functionNamesByPriority[5]);
|
||||
obs_data_set_int(obj, "priority6", functionNamesByPriority[6]);
|
||||
obs_data_set_int(obj, "priority7", functionNamesByPriority[7]);
|
||||
obs_data_set_int(obj, "priority8", functionNamesByPriority[8]);
|
||||
obs_data_set_int(obj, "priority9", functionNamesByPriority[9]);
|
||||
obs_data_set_int(obj, "priority10", functionNamesByPriority[10]);
|
||||
|
||||
obs_data_set_int(obj, "threadPriority", threadPriority);
|
||||
|
||||
@@ -618,58 +661,88 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
||||
obs_data_set_string(obj, "lastImportPath", lastImportPath.c_str());
|
||||
}
|
||||
|
||||
void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
||||
void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
{
|
||||
obs_data_set_default_int(obj, "interval", default_interval);
|
||||
interval = obs_data_get_int(obj, "interval");
|
||||
|
||||
obs_data_set_default_int(obj, "switch_if_not_matching",
|
||||
static_cast<int>(NoMatch::NO_SWITCH));
|
||||
obs_data_set_default_int(obj, "switch_if_not_matching", NO_SWITCH);
|
||||
switchIfNotMatching =
|
||||
(NoMatch)obs_data_get_int(obj, "switch_if_not_matching");
|
||||
std::string nonMatchingSceneName =
|
||||
obs_data_get_string(obj, "non_matching_scene");
|
||||
nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str());
|
||||
noMatchDelay.Load(obj, "noMatchDelay");
|
||||
noMatchDelay.Load(obj, "noMatchDelay", "noMatchDelayUnit");
|
||||
|
||||
cooldown.Load(obj, "cooldown");
|
||||
cooldown.Load(obj, "cooldown", "cooldownUnit");
|
||||
|
||||
stop = !obs_data_get_bool(obj, "active");
|
||||
startupBehavior =
|
||||
(StartupBehavior)obs_data_get_int(obj, "startup_behavior");
|
||||
if (startupBehavior == StartupBehavior::START) {
|
||||
if (startupBehavior == START) {
|
||||
stop = false;
|
||||
}
|
||||
if (startupBehavior == StartupBehavior::STOP) {
|
||||
if (startupBehavior == STOP) {
|
||||
stop = true;
|
||||
}
|
||||
|
||||
autoStartEvent =
|
||||
static_cast<AutoStart>(obs_data_get_int(obj, "autoStartEvent"));
|
||||
autoStartEvent = static_cast<AutoStartEvent>(
|
||||
obs_data_get_int(obj, "autoStartEvent"));
|
||||
|
||||
verbose = obs_data_get_bool(obj, "verbose");
|
||||
showSystemTrayNotifications =
|
||||
obs_data_get_bool(obj, "showSystemTrayNotifications");
|
||||
disableHints = obs_data_get_bool(obj, "disableHints");
|
||||
disableFilterComboboxFilter =
|
||||
obs_data_get_bool(obj, "disableFilterComboboxFilter");
|
||||
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");
|
||||
|
||||
SetDefaultFunctionPriorities(obj);
|
||||
LoadFunctionPriorities(obj, functionNamesByPriority);
|
||||
if (!PrioFuncsValid()) {
|
||||
functionNamesByPriority = GetDefaultFunctionPriorityList();
|
||||
obs_data_set_default_int(obj, "priority0", default_priority_0);
|
||||
obs_data_set_default_int(obj, "priority1", default_priority_1);
|
||||
obs_data_set_default_int(obj, "priority2", default_priority_2);
|
||||
obs_data_set_default_int(obj, "priority3", default_priority_3);
|
||||
obs_data_set_default_int(obj, "priority4", default_priority_4);
|
||||
obs_data_set_default_int(obj, "priority5", default_priority_5);
|
||||
obs_data_set_default_int(obj, "priority6", default_priority_6);
|
||||
obs_data_set_default_int(obj, "priority7", default_priority_7);
|
||||
obs_data_set_default_int(obj, "priority8", default_priority_8);
|
||||
|
||||
functionNamesByPriority[0] = (obs_data_get_int(obj, "priority0"));
|
||||
functionNamesByPriority[1] = (obs_data_get_int(obj, "priority1"));
|
||||
functionNamesByPriority[2] = (obs_data_get_int(obj, "priority2"));
|
||||
functionNamesByPriority[3] = (obs_data_get_int(obj, "priority3"));
|
||||
functionNamesByPriority[4] = (obs_data_get_int(obj, "priority4"));
|
||||
functionNamesByPriority[5] = (obs_data_get_int(obj, "priority5"));
|
||||
functionNamesByPriority[6] = (obs_data_get_int(obj, "priority6"));
|
||||
functionNamesByPriority[7] = (obs_data_get_int(obj, "priority7"));
|
||||
functionNamesByPriority[8] = (obs_data_get_int(obj, "priority8"));
|
||||
functionNamesByPriority[9] = (obs_data_get_int(obj, "priority9"));
|
||||
functionNamesByPriority[10] = (obs_data_get_int(obj, "priority10"));
|
||||
if (!prioFuncsValid()) {
|
||||
functionNamesByPriority[0] = (default_priority_0);
|
||||
functionNamesByPriority[1] = (default_priority_1);
|
||||
functionNamesByPriority[2] = (default_priority_2);
|
||||
functionNamesByPriority[3] = (default_priority_3);
|
||||
functionNamesByPriority[4] = (default_priority_4);
|
||||
functionNamesByPriority[5] = (default_priority_5);
|
||||
functionNamesByPriority[6] = (default_priority_6);
|
||||
functionNamesByPriority[7] = (default_priority_7);
|
||||
functionNamesByPriority[8] = (default_priority_8);
|
||||
functionNamesByPriority[9] = (default_priority_9);
|
||||
functionNamesByPriority[10] = (default_priority_10);
|
||||
}
|
||||
|
||||
obs_data_set_default_int(obj, "threadPriority",
|
||||
QThread::NormalPriority);
|
||||
threadPriority = obs_data_get_int(obj, "threadPriority");
|
||||
|
||||
transitionOverrideOverride =
|
||||
obs_data_get_bool(obj, "transitionOverrideOverride");
|
||||
// TODO: Remove this fallback in future version
|
||||
if (obs_data_has_user_value(obj, "tansitionOverrideOverride")) {
|
||||
transitionOverrideOverride =
|
||||
obs_data_get_bool(obj, "tansitionOverrideOverride");
|
||||
} else {
|
||||
transitionOverrideOverride =
|
||||
obs_data_get_bool(obj, "transitionOverrideOverride");
|
||||
}
|
||||
adjustActiveTransitionType =
|
||||
obs_data_get_bool(obj, "adjustActiveTransitionType");
|
||||
|
||||
@@ -682,7 +755,33 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
||||
lastImportPath = obs_data_get_string(obj, "lastImportPath");
|
||||
}
|
||||
|
||||
void SwitcherData::SaveUISettings(obs_data_t *obj)
|
||||
void saveSplitterPos(QList<int> &sizes, obs_data_t *obj, const std::string name)
|
||||
{
|
||||
auto array = obs_data_array_create();
|
||||
for (int i = 0; i < sizes.count(); ++i) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
obs_data_set_int(array_obj, "pos", sizes[i]);
|
||||
obs_data_array_push_back(array, array_obj);
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, name.c_str(), array);
|
||||
obs_data_array_release(array);
|
||||
}
|
||||
|
||||
void loadSplitterPos(QList<int> &sizes, obs_data_t *obj, const std::string name)
|
||||
{
|
||||
sizes.clear();
|
||||
obs_data_array_t *array = obs_data_get_array(obj, name.c_str());
|
||||
size_t count = obs_data_array_count(array);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *item = obs_data_array_item(array, i);
|
||||
sizes << obs_data_get_int(item, "pos");
|
||||
obs_data_release(item);
|
||||
}
|
||||
obs_data_array_release(array);
|
||||
}
|
||||
|
||||
void SwitcherData::saveUISettings(obs_data_t *obj)
|
||||
{
|
||||
obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
|
||||
obs_data_set_int(obj, "macroTabPos", tabOrder[1]);
|
||||
@@ -709,11 +808,13 @@ void SwitcherData::SaveUISettings(obs_data_t *obj)
|
||||
obs_data_set_int(obj, "windowWidth", windowSize.width());
|
||||
obs_data_set_int(obj, "windowHeight", windowSize.height());
|
||||
|
||||
SaveSplitterPos(macroListMacroEditSplitterPosition, obj,
|
||||
saveSplitterPos(macroActionConditionSplitterPosition, obj,
|
||||
"macroActionConditionSplitterPosition");
|
||||
saveSplitterPos(macroListMacroEditSplitterPosition, obj,
|
||||
"macroListMacroEditSplitterPosition");
|
||||
}
|
||||
|
||||
void SwitcherData::LoadUISettings(obs_data_t *obj)
|
||||
void SwitcherData::loadUISettings(obs_data_t *obj)
|
||||
{
|
||||
obs_data_set_default_int(obj, "generalTabPos", 0);
|
||||
obs_data_set_default_int(obj, "macroTabPos", 1);
|
||||
@@ -754,8 +855,8 @@ void SwitcherData::LoadUISettings(obs_data_t *obj)
|
||||
tabOrder.emplace_back((int)(obs_data_get_int(obj, "sceneGroupTabPos")));
|
||||
tabOrder.emplace_back((int)(obs_data_get_int(obj, "triggerTabPos")));
|
||||
|
||||
if (!TabOrderValid()) {
|
||||
ResetTabOrder();
|
||||
if (!tabOrderValid()) {
|
||||
resetTabOrder();
|
||||
}
|
||||
|
||||
saveWindowGeo = obs_data_get_bool(obj, "saveWindowGeo");
|
||||
@@ -763,12 +864,13 @@ void SwitcherData::LoadUISettings(obs_data_t *obj)
|
||||
(int)obs_data_get_int(obj, "windowPosY")};
|
||||
windowSize = {(int)obs_data_get_int(obj, "windowWidth"),
|
||||
(int)obs_data_get_int(obj, "windowHeight")};
|
||||
|
||||
LoadSplitterPos(macroListMacroEditSplitterPosition, obj,
|
||||
loadSplitterPos(macroActionConditionSplitterPosition, obj,
|
||||
"macroActionConditionSplitterPosition");
|
||||
loadSplitterPos(macroListMacroEditSplitterPosition, obj,
|
||||
"macroListMacroEditSplitterPosition");
|
||||
}
|
||||
|
||||
bool SwitcherData::TabOrderValid()
|
||||
bool SwitcherData::tabOrderValid()
|
||||
{
|
||||
auto tmp = std::vector<int>(tab_count);
|
||||
std::iota(tmp.begin(), tmp.end(), 0);
|
||||
@@ -782,13 +884,13 @@ bool SwitcherData::TabOrderValid()
|
||||
return true;
|
||||
}
|
||||
|
||||
void SwitcherData::ResetTabOrder()
|
||||
void SwitcherData::resetTabOrder()
|
||||
{
|
||||
tabOrder = std::vector<int>(tab_count);
|
||||
std::iota(tabOrder.begin(), tabOrder.end(), 0);
|
||||
}
|
||||
|
||||
void SwitcherData::CheckNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
||||
void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
||||
OBSWeakSource &transition, int &sleep)
|
||||
{
|
||||
if (match) {
|
||||
@@ -800,12 +902,12 @@ void SwitcherData::CheckNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
||||
return;
|
||||
}
|
||||
|
||||
if (switchIfNotMatching == NoMatch::SWITCH && nonMatchingScene) {
|
||||
if (switchIfNotMatching == SWITCH && nonMatchingScene) {
|
||||
match = true;
|
||||
scene = nonMatchingScene;
|
||||
transition = nullptr;
|
||||
}
|
||||
if (switchIfNotMatching == NoMatch::RANDOM_SWITCH) {
|
||||
if (switchIfNotMatching == RANDOM_SWITCH) {
|
||||
match = checkRandom(scene, transition, sleep);
|
||||
}
|
||||
}
|
||||
@@ -824,7 +926,7 @@ void SwitcherData::checkSwitchCooldown(bool &match)
|
||||
}
|
||||
}
|
||||
|
||||
static void populateStartupBehavior(QComboBox *cb)
|
||||
void populateStartupBehavior(QComboBox *cb)
|
||||
{
|
||||
cb->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.status.onStartup.asLastRun"));
|
||||
@@ -834,7 +936,7 @@ static void populateStartupBehavior(QComboBox *cb)
|
||||
"AdvSceneSwitcher.generalTab.status.onStartup.doNotStart"));
|
||||
}
|
||||
|
||||
static void populateAutoStartEventSelection(QComboBox *cb)
|
||||
void populateAutoStartEventSelection(QComboBox *cb)
|
||||
{
|
||||
cb->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.status.autoStart.never"));
|
||||
@@ -846,8 +948,53 @@ static void populateAutoStartEventSelection(QComboBox *cb)
|
||||
"AdvSceneSwitcher.generalTab.status.autoStart.recordingAndStreaming"));
|
||||
}
|
||||
|
||||
static void populatePriorityFunctionList(QListWidget *list)
|
||||
void AdvSceneSwitcher::setupGeneralTab()
|
||||
{
|
||||
populateSceneSelection(ui->noMatchSwitchScene, false);
|
||||
|
||||
if (switcher->switchIfNotMatching == SWITCH) {
|
||||
ui->noMatchSwitch->setChecked(true);
|
||||
ui->noMatchSwitchScene->setEnabled(true);
|
||||
} else if (switcher->switchIfNotMatching == NO_SWITCH) {
|
||||
ui->noMatchDontSwitch->setChecked(true);
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
} else {
|
||||
ui->noMatchRandomSwitch->setChecked(true);
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
}
|
||||
ui->noMatchSwitchScene->setCurrentText(
|
||||
GetWeakSourceName(switcher->nonMatchingScene).c_str());
|
||||
|
||||
DurationSelection *noMatchDelay = new DurationSelection();
|
||||
noMatchDelay->SetDuration(switcher->noMatchDelay);
|
||||
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)));
|
||||
|
||||
ui->checkInterval->setValue(switcher->interval);
|
||||
|
||||
DurationSelection *cooldownTime = new DurationSelection();
|
||||
cooldownTime->SetDuration(switcher->cooldown);
|
||||
cooldownTime->setToolTip(obs_module_text(
|
||||
"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)));
|
||||
|
||||
ui->verboseLogging->setChecked(switcher->verbose);
|
||||
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
|
||||
ui->showTrayNotifications->setChecked(
|
||||
switcher->showSystemTrayNotifications);
|
||||
ui->uiHintsDisable->setChecked(switcher->disableHints);
|
||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||
|
||||
for (int p : switcher->functionNamesByPriority) {
|
||||
std::string s = "";
|
||||
switch (p) {
|
||||
@@ -897,118 +1044,26 @@ static void populatePriorityFunctionList(QListWidget *list)
|
||||
break;
|
||||
}
|
||||
QString text(s.c_str());
|
||||
QListWidgetItem *item = new QListWidgetItem(text, list);
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(text, ui->priorityList);
|
||||
item->setData(Qt::UserRole, text);
|
||||
}
|
||||
}
|
||||
|
||||
static void populateThreadPriorityList(QComboBox *list)
|
||||
{
|
||||
for (int i = 0; i < (int)switcher->threadPriorities.size(); ++i) {
|
||||
list->addItem(switcher->threadPriorities[i].name.c_str());
|
||||
list->setItemData(
|
||||
ui->threadPriority->addItem(
|
||||
switcher->threadPriorities[i].name.c_str());
|
||||
ui->threadPriority->setItemData(
|
||||
i, switcher->threadPriorities[i].description.c_str(),
|
||||
Qt::ToolTipRole);
|
||||
if (switcher->threadPriority ==
|
||||
switcher->threadPriorities[i].value) {
|
||||
list->setCurrentText(
|
||||
ui->threadPriority->setCurrentText(
|
||||
switcher->threadPriorities[i].name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isGeneralTab(const QString &name)
|
||||
{
|
||||
return name == obs_module_text("AdvSceneSwitcher.generalTab.title");
|
||||
}
|
||||
|
||||
static int getGeneralTabIdx(QTabWidget *tabWidget)
|
||||
{
|
||||
for (int idx = 0; idx < tabWidget->count(); idx++) {
|
||||
if (isGeneralTab(tabWidget->tabText(idx))) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void setupGeneralTabInactiveWarning(QTabWidget *tabs)
|
||||
{
|
||||
auto callback = [tabs]() {
|
||||
const bool isRunning = switcher && switcher->th &&
|
||||
switcher->th->isRunning();
|
||||
auto idx = getGeneralTabIdx(tabs);
|
||||
tabs->setTabIcon(
|
||||
idx,
|
||||
isRunning ? QIcon()
|
||||
: QIcon::fromTheme(
|
||||
"obs",
|
||||
QIcon(":/res/images/warning.svg")));
|
||||
};
|
||||
|
||||
auto inactiveTimer = new QTimer(tabs);
|
||||
inactiveTimer->setInterval(1000);
|
||||
QObject::connect(inactiveTimer, &QTimer::timeout, callback);
|
||||
inactiveTimer->start();
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupGeneralTab()
|
||||
{
|
||||
PopulateSceneSelection(ui->noMatchSwitchScene, false);
|
||||
|
||||
if (switcher->switchIfNotMatching == SwitcherData::NoMatch::SWITCH) {
|
||||
ui->noMatchSwitch->setChecked(true);
|
||||
ui->noMatchSwitchScene->setEnabled(true);
|
||||
} else if (switcher->switchIfNotMatching ==
|
||||
SwitcherData::NoMatch::NO_SWITCH) {
|
||||
ui->noMatchDontSwitch->setChecked(true);
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
} else {
|
||||
ui->noMatchRandomSwitch->setChecked(true);
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
}
|
||||
ui->noMatchSwitchScene->setCurrentText(
|
||||
GetWeakSourceName(switcher->nonMatchingScene).c_str());
|
||||
|
||||
DurationSelection *noMatchDelay = new DurationSelection();
|
||||
noMatchDelay->SetDuration(switcher->noMatchDelay);
|
||||
noMatchDelay->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip"));
|
||||
ui->noMatchLayout->addWidget(noMatchDelay);
|
||||
QWidget::connect(noMatchDelay,
|
||||
SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(NoMatchDelayDurationChanged(const Duration &)));
|
||||
|
||||
ui->checkInterval->setValue(switcher->interval);
|
||||
|
||||
DurationSelection *cooldownTime = new DurationSelection();
|
||||
cooldownTime->SetDuration(switcher->cooldown);
|
||||
cooldownTime->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
|
||||
ui->cooldownLayout->addWidget(cooldownTime);
|
||||
ui->cooldownLayout->addStretch();
|
||||
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->disableComboBoxFilter->setChecked(
|
||||
switcher->disableFilterComboboxFilter);
|
||||
FilterComboBox::SetFilterBehaviourEnabled(
|
||||
!switcher->disableFilterComboboxFilter);
|
||||
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||
|
||||
populatePriorityFunctionList(ui->priorityList);
|
||||
populateThreadPriorityList(ui->threadPriority);
|
||||
|
||||
populateStartupBehavior(ui->startupBehavior);
|
||||
ui->startupBehavior->setCurrentIndex(
|
||||
static_cast<int>(switcher->startupBehavior));
|
||||
ui->startupBehavior->setCurrentIndex(switcher->startupBehavior);
|
||||
|
||||
populateAutoStartEventSelection(ui->autoStartEvent);
|
||||
ui->autoStartEvent->setCurrentIndex(
|
||||
@@ -1025,10 +1080,6 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
||||
// Hide the now empty invisible shell of the statusControl widget
|
||||
// as otherwise it could block user input
|
||||
statusControl->hide();
|
||||
setupGeneralTabInactiveWarning(ui->tabWidget);
|
||||
|
||||
MinimizeSizeOfColumn(ui->statusLayout, 0);
|
||||
setWindowTitle(windowTitle() + " - " + g_GIT_TAG);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
#include "hotkey.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include <obs-module.h>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
|
||||
namespace advss {
|
||||
|
||||
std::vector<std::weak_ptr<Hotkey>> Hotkey::_registeredHotkeys = {};
|
||||
uint32_t Hotkey::_hotkeyCounter = 1;
|
||||
|
||||
@@ -120,7 +117,7 @@ void Hotkey::ClearAllHotkeys()
|
||||
_registeredHotkeys.clear();
|
||||
}
|
||||
|
||||
static void startHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||
void startHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||
{
|
||||
if (pressed) {
|
||||
if (!(switcher->th && switcher->th->isRunning())) {
|
||||
@@ -129,7 +126,7 @@ static void startHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||
}
|
||||
}
|
||||
|
||||
static void stopHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||
void stopHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||
{
|
||||
if (pressed) {
|
||||
if (switcher->th && switcher->th->isRunning()) {
|
||||
@@ -138,8 +135,8 @@ static void stopHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||
}
|
||||
}
|
||||
|
||||
static void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
{
|
||||
if (pressed) {
|
||||
if (switcher->th && switcher->th->isRunning()) {
|
||||
@@ -150,8 +147,8 @@ static void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
}
|
||||
}
|
||||
|
||||
static void upMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
void upMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
{
|
||||
if (pressed && switcher->settingsWindowOpened &&
|
||||
AdvSceneSwitcher::window) {
|
||||
@@ -161,8 +158,8 @@ static void upMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
}
|
||||
}
|
||||
|
||||
static void downMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
void downMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
{
|
||||
if (pressed && switcher->settingsWindowOpened &&
|
||||
AdvSceneSwitcher::window) {
|
||||
@@ -172,8 +169,8 @@ static void downMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
}
|
||||
}
|
||||
|
||||
static void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
{
|
||||
if (pressed && switcher->settingsWindowOpened &&
|
||||
AdvSceneSwitcher::window) {
|
||||
@@ -183,7 +180,7 @@ static void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
}
|
||||
}
|
||||
|
||||
static void registerHotkeys()
|
||||
void registerHotkeys()
|
||||
{
|
||||
switcher->startHotkey = obs_hotkey_register_frontend(
|
||||
"startSwitcherHotkey",
|
||||
@@ -216,14 +213,14 @@ static void registerHotkeys()
|
||||
switcher->hotkeysRegistered = true;
|
||||
}
|
||||
|
||||
static void saveHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
||||
void saveHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
||||
{
|
||||
obs_data_array_t *a = obs_hotkey_save(id);
|
||||
obs_data_set_array(obj, name, a);
|
||||
obs_data_array_release(a);
|
||||
}
|
||||
|
||||
void SwitcherData::SaveHotkeys(obs_data_t *obj)
|
||||
void SwitcherData::saveHotkeys(obs_data_t *obj)
|
||||
{
|
||||
saveHotkey(obj, startHotkey, "startHotkey");
|
||||
saveHotkey(obj, stopHotkey, "stopHotkey");
|
||||
@@ -233,14 +230,14 @@ void SwitcherData::SaveHotkeys(obs_data_t *obj)
|
||||
saveHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
||||
}
|
||||
|
||||
static void loadHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
||||
void loadHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
||||
{
|
||||
obs_data_array_t *a = obs_data_get_array(obj, name);
|
||||
obs_hotkey_load(id, a);
|
||||
obs_data_array_release(a);
|
||||
}
|
||||
|
||||
void SwitcherData::LoadHotkeys(obs_data_t *obj)
|
||||
void SwitcherData::loadHotkeys(obs_data_t *obj)
|
||||
{
|
||||
if (!hotkeysRegistered) {
|
||||
registerHotkeys();
|
||||
@@ -252,5 +249,3 @@ void SwitcherData::LoadHotkeys(obs_data_t *obj)
|
||||
loadHotkey(obj, downMacroSegment, "downMacroSegmentHotkey");
|
||||
loadHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
namespace advss {
|
||||
|
||||
extern bool canSimulateKeyPresses;
|
||||
|
||||
class Hotkey {
|
||||
@@ -163,4 +161,4 @@ enum class HotkeyType {
|
||||
Key_NumpadEnter
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
void registerHotkeys();
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool SceneTrigger::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
@@ -159,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)
|
||||
@@ -269,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));
|
||||
@@ -352,7 +349,7 @@ void SwitcherData::loadSceneTriggers(obs_data_t *obj)
|
||||
obs_data_array_release(triggerArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupTriggerTab()
|
||||
void AdvSceneSwitcher::setupTriggerTab()
|
||||
{
|
||||
for (auto &s : switcher->sceneTriggers) {
|
||||
QListWidgetItem *item;
|
||||
@@ -401,7 +398,7 @@ void SceneTrigger::load(obs_data_t *obj)
|
||||
|
||||
static inline void populateTriggers(QComboBox *list)
|
||||
{
|
||||
AddSelectionEntry(
|
||||
addSelectionEntry(
|
||||
list,
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none"));
|
||||
@@ -416,7 +413,7 @@ static inline void populateTriggers(QComboBox *list)
|
||||
|
||||
inline void populateActions(QComboBox *list)
|
||||
{
|
||||
AddSelectionEntry(
|
||||
addSelectionEntry(
|
||||
list,
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.none"));
|
||||
@@ -463,15 +460,17 @@ SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
|
||||
SLOT(TriggerTypeChanged(int)));
|
||||
QWidget::connect(actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(TriggerActionChanged(int)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DurationUnitChanged(DurationUnit)));
|
||||
QWidget::connect(audioSources,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(AudioSourceChanged(const QString &)));
|
||||
|
||||
populateTriggers(triggers);
|
||||
populateActions(actions);
|
||||
PopulateAudioSelection(audioSources);
|
||||
populateAudioSelection(audioSources);
|
||||
|
||||
if (s) {
|
||||
triggers->setCurrentIndex(static_cast<int>(s->triggerType));
|
||||
@@ -495,7 +494,7 @@ SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
|
||||
{"{{audioSources}}", audioSources},
|
||||
{"{{duration}}", duration},
|
||||
{"{{scenes}}", scenes}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.sceneTriggerTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.sceneTriggerTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -553,14 +552,24 @@ void SceneTriggerWidget::TriggerActionChanged(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::DurationChanged(const Duration &duration)
|
||||
void SceneTriggerWidget::DurationChanged(double seconds)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration = duration;
|
||||
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;
|
||||
}
|
||||
|
||||
void SceneTriggerWidget::AudioSourceChanged(const QString &text)
|
||||
@@ -572,5 +581,3 @@ void SceneTriggerWidget::AudioSourceChanged(const QString &text)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->audioSource = GetWeakSourceByQString(text);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "switch-generic.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
enum class sceneTriggerType {
|
||||
NONE = 0,
|
||||
SCENE_ACTIVE = 1,
|
||||
@@ -73,7 +71,8 @@ public:
|
||||
private slots:
|
||||
void TriggerTypeChanged(int index);
|
||||
void TriggerActionChanged(int index);
|
||||
void DurationChanged(const Duration &);
|
||||
void DurationChanged(double seconds);
|
||||
void DurationUnitChanged(DurationUnit unit);
|
||||
void AudioSourceChanged(const QString &text);
|
||||
|
||||
private:
|
||||
@@ -84,5 +83,3 @@ private:
|
||||
|
||||
SceneTrigger *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "volume-control.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "volume-control.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool AudioSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
@@ -215,7 +212,7 @@ void SwitcherData::loadAudioSwitches(obs_data_t *obj)
|
||||
audioFallback.load(obj);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupAudioTab()
|
||||
void AdvSceneSwitcher::setupAudioTab()
|
||||
{
|
||||
for (auto &s : switcher->audioSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -441,15 +438,15 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
||||
SLOT(VolumeThresholdChanged(int)));
|
||||
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(audioSources,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(SourceChanged(const QString &)));
|
||||
QWidget::connect(ignoreInactiveSource, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(IgnoreInactiveChanged(int)));
|
||||
|
||||
PopulateAudioSelection(audioSources);
|
||||
populateAudioSelection(audioSources);
|
||||
populateConditionSelection(condition);
|
||||
|
||||
if (s) {
|
||||
@@ -470,7 +467,7 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
||||
{"{{ignoreInactiveSource}}", ignoreInactiveSource},
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.audioTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.audioTab.entry"),
|
||||
switchLayout, widgetPlaceholders);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
@@ -557,14 +554,14 @@ void AudioSwitchWidget::ConditionChanged(int cond)
|
||||
switchData->condition = (audioCondition)cond;
|
||||
}
|
||||
|
||||
void AudioSwitchWidget::DurationChanged(const Duration &dur)
|
||||
void AudioSwitchWidget::DurationChanged(double sec)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration = dur;
|
||||
switchData->duration.seconds = sec;
|
||||
}
|
||||
|
||||
void AudioSwitchWidget::IgnoreInactiveChanged(int state)
|
||||
@@ -583,8 +580,8 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
||||
{
|
||||
duration = new DurationSelection(this, false);
|
||||
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
|
||||
if (s) {
|
||||
duration->SetDuration(s->duration);
|
||||
@@ -595,7 +592,7 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{duration}}", duration},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.audioTab.multiMatchfallback"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
@@ -605,14 +602,12 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
||||
loading = false;
|
||||
}
|
||||
|
||||
void AudioSwitchFallbackWidget::DurationChanged(const Duration &dur)
|
||||
void AudioSwitchFallbackWidget::DurationChanged(double sec)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->duration = dur;
|
||||
switchData->duration.seconds = sec;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "duration-control.hpp"
|
||||
#include "volume-control.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto audio_func = 8;
|
||||
|
||||
typedef enum {
|
||||
@@ -77,7 +75,7 @@ private slots:
|
||||
void SourceChanged(const QString &text);
|
||||
void VolumeThresholdChanged(int vol);
|
||||
void ConditionChanged(int cond);
|
||||
void DurationChanged(const Duration &);
|
||||
void DurationChanged(double dur);
|
||||
void IgnoreInactiveChanged(int state);
|
||||
|
||||
private:
|
||||
@@ -98,12 +96,10 @@ public:
|
||||
AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s);
|
||||
|
||||
private slots:
|
||||
void DurationChanged(const Duration &dur);
|
||||
void DurationChanged(double dur);
|
||||
|
||||
private:
|
||||
DurationSelection *duration;
|
||||
|
||||
AudioSwitchFallback *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
bool ExecutableSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
|
||||
@@ -103,7 +99,7 @@ bool SwitcherData::checkExeSwitch(OBSWeakSource &scene,
|
||||
bool equals = runningProcesses.contains(s.exe);
|
||||
bool matches = (runningProcesses.indexOf(
|
||||
QRegularExpression(s.exe)) != -1);
|
||||
bool focus = (!s.inFocus || IsInFocus(s.exe));
|
||||
bool focus = (!s.inFocus || isInFocus(s.exe));
|
||||
|
||||
// True if current window is ignored AND switch equals OR matches last window
|
||||
bool ignore =
|
||||
@@ -160,7 +156,7 @@ void SwitcherData::loadExecutableSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(executableArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupExecutableTab()
|
||||
void AdvSceneSwitcher::setupExecutableTab()
|
||||
{
|
||||
for (auto &s : switcher->executableSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -212,7 +208,7 @@ ExecutableSwitchWidget::ExecutableSwitchWidget(QWidget *parent,
|
||||
QWidget::connect(requiresFocus, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(FocusChanged(int)));
|
||||
|
||||
PopulateProcessSelection(processes);
|
||||
populateProcessSelection(processes);
|
||||
|
||||
processes->setEditable(true);
|
||||
processes->setMaxVisibleItems(20);
|
||||
@@ -228,7 +224,7 @@ ExecutableSwitchWidget::ExecutableSwitchWidget(QWidget *parent,
|
||||
{"{{requiresFocus}}", requiresFocus},
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.executableTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.executableTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -276,5 +272,3 @@ void ExecutableSwitchWidget::FocusChanged(int state)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->inFocus = state;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <QCheckBox>
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto exe_func = 3;
|
||||
|
||||
struct ExecutableSwitch : SceneSwitcherEntry {
|
||||
@@ -44,5 +42,3 @@ private:
|
||||
|
||||
ExecutableSwitch *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "curl-helper.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
@@ -11,7 +6,9 @@
|
||||
#include <regex>
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "curl-helper.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool FileSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
@@ -119,7 +116,7 @@ void SwitcherData::writeToStatusFile(const QString &msg)
|
||||
if (file.open(QIODevice::ReadWrite)) {
|
||||
QTextStream stream(&file);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
stream << msg << "\n";
|
||||
stream << msg << endl;
|
||||
#else
|
||||
stream << msg << Qt::endl;
|
||||
#endif
|
||||
@@ -212,7 +209,7 @@ bool matchFileContent(QString &filedata, FileSwitch &s)
|
||||
}
|
||||
|
||||
QString text = QString::fromStdString(s.text);
|
||||
return CompareIgnoringLineEnding(text, filedata);
|
||||
return compareIgnoringLineEnding(text, filedata);
|
||||
}
|
||||
|
||||
bool checkRemoteFileContent(FileSwitch &s)
|
||||
@@ -414,7 +411,7 @@ void SwitcherData::loadFileSwitches(obs_data_t *obj)
|
||||
fileIO.writePath = obs_data_get_string(obj, "writePath");
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupFileTab()
|
||||
void AdvSceneSwitcher::setupFileTab()
|
||||
{
|
||||
ui->remoteFileWarningLabel->setText(
|
||||
obs_module_text("AdvSceneSwitcher.fileTab.remoteFileWarning1") +
|
||||
@@ -545,11 +542,11 @@ FileSwitchWidget::FileSwitchWidget(QWidget *parent, FileSwitch *s)
|
||||
QHBoxLayout *line1Layout = new QHBoxLayout;
|
||||
QHBoxLayout *line2Layout = new QHBoxLayout;
|
||||
QHBoxLayout *line3Layout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry"),
|
||||
line1Layout, widgetPlaceholders);
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry2"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry2"),
|
||||
line2Layout, widgetPlaceholders, false);
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry3"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry3"),
|
||||
line3Layout, widgetPlaceholders);
|
||||
mainLayout->addLayout(line1Layout);
|
||||
mainLayout->addLayout(line2Layout);
|
||||
@@ -668,5 +665,3 @@ void FileSwitchWidget::CheckFileContentChanged(int state)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->onlyMatchIfChanged = state;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -8,11 +8,8 @@
|
||||
#pragma once
|
||||
#include "switch-generic.hpp"
|
||||
#include <QPlainTextEdit>
|
||||
#include <QDateTime>
|
||||
#include <obs-module.h>
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto read_file_func = 0;
|
||||
|
||||
typedef enum {
|
||||
@@ -80,5 +77,3 @@ static inline QString MakeFileSwitchName(const QString &scene,
|
||||
const QString &fileName,
|
||||
const QString &text, bool useRegex,
|
||||
bool useTime, bool onlyMatchIfChanged);
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
constexpr auto previous_scene_name = "Previous Scene";
|
||||
constexpr auto current_transition_name = "Current Transition";
|
||||
|
||||
namespace advss {
|
||||
|
||||
static inline bool SceneGroupValid(SceneGroup *group)
|
||||
{
|
||||
if (group) {
|
||||
@@ -214,9 +208,9 @@ SwitchWidget::SwitchWidget(QWidget *parent, SceneSwitcherEntry *s,
|
||||
SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
|
||||
this, SLOT(SceneGroupRename(const QString &, const QString &)));
|
||||
|
||||
PopulateSceneSelection(scenes, usePreviousScene, false, false,
|
||||
populateSceneSelection(scenes, usePreviousScene, false, false,
|
||||
addSceneGroup, &switcher->sceneGroups);
|
||||
PopulateTransitionSelection(transitions, addCurrentTransition);
|
||||
populateTransitionSelection(transitions, addCurrentTransition);
|
||||
|
||||
switchData = s;
|
||||
showSwitchData();
|
||||
@@ -306,5 +300,3 @@ void SwitchWidget::TransitionChanged(const QString &text)
|
||||
switchData->transition = GetWeakTransitionByQString(text);
|
||||
switchData->useCurrentTransition = switchData->transition == nullptr;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "scene-group.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
enum class SwitchTargetType {
|
||||
Scene,
|
||||
SceneGroup,
|
||||
@@ -97,5 +95,3 @@ protected:
|
||||
|
||||
SceneSwitcherEntry *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <regex>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool IdleData::pause = false;
|
||||
IdleWidget *idleWidget = nullptr;
|
||||
@@ -42,7 +38,7 @@ bool SwitcherData::checkIdleSwitch(OBSWeakSource &scene,
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreIdle && SecondsSinceLastInput() > idleData.time) {
|
||||
if (!ignoreIdle && secondsSinceLastInput() > idleData.time) {
|
||||
if (idleData.alreadySwitched) {
|
||||
return false;
|
||||
}
|
||||
@@ -209,9 +205,9 @@ void SwitcherData::loadIdleSwitches(obs_data_t *obj)
|
||||
idleData.load(obj);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupIdleTab()
|
||||
void AdvSceneSwitcher::setupIdleTab()
|
||||
{
|
||||
PopulateWindowSelection(ui->ignoreIdleWindowsWindows);
|
||||
populateWindowSelection(ui->ignoreIdleWindowsWindows);
|
||||
|
||||
for (auto &window : switcher->ignoreIdleWindows) {
|
||||
QString text = QString::fromStdString(window);
|
||||
@@ -271,7 +267,7 @@ IdleWidget::IdleWidget(QWidget *parent, IdleData *s)
|
||||
{"{{duration}}", duration},
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.idleTab.idleswitch"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.idleTab.idleswitch"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -289,5 +285,3 @@ void IdleWidget::DurationChanged(int dur)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->idleData.time = dur;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#pragma once
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto default_idle_time = 60;
|
||||
constexpr auto idle_func = 2;
|
||||
|
||||
@@ -38,5 +36,3 @@ private:
|
||||
|
||||
IdleData *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
bool MediaSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
|
||||
@@ -235,7 +232,7 @@ void SwitcherData::loadMediaSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(mediaArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupMediaTab()
|
||||
void AdvSceneSwitcher::setupMediaTab()
|
||||
{
|
||||
for (auto &s : switcher->mediaSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -463,7 +460,7 @@ MediaSwitchWidget::MediaSwitchWidget(QWidget *parent, MediaSwitch *s)
|
||||
QWidget::connect(time, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(TimeChanged(int)));
|
||||
|
||||
PopulateMediaSelection(mediaSources);
|
||||
populateMediaSelection(mediaSources);
|
||||
populateMediaStates(states);
|
||||
populateTimeRestrictions(timeRestrictions);
|
||||
|
||||
@@ -486,7 +483,7 @@ MediaSwitchWidget::MediaSwitchWidget(QWidget *parent, MediaSwitch *s)
|
||||
{"{{time}}", time},
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.mediaTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.mediaTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -563,5 +560,3 @@ void MediaSwitchWidget::TimeChanged(int time)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->time = time;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#pragma once
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto media_func = 6;
|
||||
|
||||
typedef enum {
|
||||
@@ -85,5 +83,3 @@ private:
|
||||
|
||||
MediaSwitch *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -7,12 +7,8 @@ Most of this code is based on https://github.com/Palakis/obs-websocket
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "scene-switch-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
#define PARAM_SERVER_ENABLE "ServerEnabled"
|
||||
#define PARAM_SERVER_PORT "ServerPort"
|
||||
#define PARAM_LOCKTOIPV4 "LockToIPv4"
|
||||
@@ -128,9 +124,10 @@ WSServer::WSServer() : QObject(nullptr), _connections(), _clMutex()
|
||||
_server.set_reuse_addr(true);
|
||||
#endif
|
||||
|
||||
_server.set_open_handler(bind(&WSServer::onOpen, this, _1));
|
||||
_server.set_close_handler(bind(&WSServer::onClose, this, _1));
|
||||
_server.set_message_handler(bind(&WSServer::onMessage, this, _1, _2));
|
||||
_server.set_open_handler(bind(&WSServer::onOpen, this, ::_1));
|
||||
_server.set_close_handler(bind(&WSServer::onClose, this, ::_1));
|
||||
_server.set_message_handler(
|
||||
bind(&WSServer::onMessage, this, ::_1, ::_2));
|
||||
}
|
||||
|
||||
WSServer::~WSServer()
|
||||
@@ -224,7 +221,7 @@ void WSServer::stop()
|
||||
blog(LOG_INFO, "server stopped successfully");
|
||||
}
|
||||
|
||||
void WSServer::sendMessage(SceneSwitchInfo sceneSwitch, bool preview)
|
||||
void WSServer::sendMessage(sceneSwitchInfo sceneSwitch, bool preview)
|
||||
{
|
||||
if (!sceneSwitch.scene) {
|
||||
return;
|
||||
@@ -308,9 +305,9 @@ std::string processMessage(std::string payload)
|
||||
"'";
|
||||
}
|
||||
if (preview) {
|
||||
SwitchPreviewScene(scene);
|
||||
switchPreviewScene(scene);
|
||||
} else {
|
||||
SwitchScene({scene, transition, duration});
|
||||
switchScene({scene, transition, duration});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -364,10 +361,11 @@ WSClient::WSClient() : QObject(nullptr)
|
||||
_client.set_reuse_addr(true);
|
||||
#endif
|
||||
|
||||
_client.set_open_handler(bind(&WSClient::onOpen, this, _1));
|
||||
_client.set_fail_handler(bind(&WSClient::onFail, this, _1));
|
||||
_client.set_message_handler(bind(&WSClient::onMessage, this, _1, _2));
|
||||
_client.set_close_handler(bind(&WSClient::onClose, this, _1));
|
||||
_client.set_open_handler(bind(&WSClient::onOpen, this, ::_1));
|
||||
_client.set_fail_handler(bind(&WSClient::onFail, this, ::_1));
|
||||
_client.set_message_handler(
|
||||
bind(&WSClient::onMessage, this, ::_1, ::_2));
|
||||
_client.set_close_handler(bind(&WSClient::onClose, this, ::_1));
|
||||
}
|
||||
|
||||
WSClient::~WSClient()
|
||||
@@ -503,7 +501,7 @@ void SwitcherData::saveNetworkSwitches(obs_data_t *obj)
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupNetworkTab()
|
||||
void AdvSceneSwitcher::setupNetworkTab()
|
||||
{
|
||||
ui->serverSettings->setChecked(switcher->networkConfig.ServerEnabled);
|
||||
ui->serverPort->setValue(switcher->networkConfig.ServerPort);
|
||||
@@ -521,9 +519,9 @@ void AdvSceneSwitcher::SetupNetworkTab()
|
||||
|
||||
QTimer *statusTimer = new QTimer(this);
|
||||
connect(statusTimer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdateClientStatus()));
|
||||
SLOT(updateClientStatus()));
|
||||
connect(statusTimer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdateServerStatus()));
|
||||
SLOT(updateServerStatus()));
|
||||
statusTimer->start(500);
|
||||
}
|
||||
|
||||
@@ -574,7 +572,7 @@ void AdvSceneSwitcher::on_serverRestart_clicked()
|
||||
switcher->networkConfig.LockToIPv4);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::UpdateServerStatus()
|
||||
void AdvSceneSwitcher::updateServerStatus()
|
||||
{
|
||||
switch (switcher->serverStatus) {
|
||||
case ServerStatus::NOT_RUNNING:
|
||||
@@ -672,7 +670,7 @@ void AdvSceneSwitcher::on_clientReconnect_clicked()
|
||||
switcher->client.connect(switcher->networkConfig.GetClientUri());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::UpdateClientStatus()
|
||||
void AdvSceneSwitcher::updateClientStatus()
|
||||
{
|
||||
switch (switcher->clientStatus) {
|
||||
case ClientStatus::DISCONNECTED:
|
||||
@@ -711,5 +709,3 @@ Compatability::StdFunctionRunnable::StdFunctionRunnable(
|
||||
: cb(std::move(func))
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -19,13 +19,11 @@ Most of this code is based on https://github.com/Palakis/obs-websocket
|
||||
#include <websocketpp/server.hpp>
|
||||
#include <websocketpp/client.hpp>
|
||||
|
||||
namespace advss {
|
||||
|
||||
using websocketpp::connection_hdl;
|
||||
typedef websocketpp::server<websocketpp::config::asio> server;
|
||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||
|
||||
struct SceneSwitchInfo;
|
||||
struct sceneSwitchInfo;
|
||||
|
||||
class NetworkConfig {
|
||||
public:
|
||||
@@ -62,7 +60,7 @@ public:
|
||||
virtual ~WSServer();
|
||||
void start(quint16 port, bool lockToIPv4);
|
||||
void stop();
|
||||
void sendMessage(SceneSwitchInfo sceneSwitch, bool preview = false);
|
||||
void sendMessage(sceneSwitchInfo sceneSwitch, bool preview = false);
|
||||
QThreadPool *threadPool() { return &_threadPool; }
|
||||
|
||||
private:
|
||||
@@ -133,5 +131,3 @@ public:
|
||||
|
||||
QRunnable *CreateFunctionRunnable(std::function<void()> func);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <regex>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
static QMetaObject::Connection addPulse;
|
||||
|
||||
@@ -247,7 +244,7 @@ void SwitcherData::loadPauseSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(pauseArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupPauseTab()
|
||||
void AdvSceneSwitcher::setupPauseTab()
|
||||
{
|
||||
for (auto &s : switcher->pauseEntries) {
|
||||
QListWidgetItem *item;
|
||||
@@ -312,7 +309,7 @@ PauseEntryWidget::PauseEntryWidget(QWidget *parent, PauseEntry *s)
|
||||
|
||||
populatePauseTypes(pauseTypes);
|
||||
populatePauseTargets(pauseTargets);
|
||||
PopulateWindowSelection(windows);
|
||||
populateWindowSelection(windows);
|
||||
|
||||
windows->setEditable(true);
|
||||
windows->setMaxVisibleItems(20);
|
||||
@@ -338,7 +335,7 @@ PauseEntryWidget::PauseEntryWidget(QWidget *parent, PauseEntry *s)
|
||||
{"{{pauseTargets}}", pauseTargets},
|
||||
{"{{windows}}", windows}};
|
||||
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.pauseTab.pauseEntry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.pauseTab.pauseEntry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -413,5 +410,3 @@ bool PauseEntry::valid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#pragma once
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
enum class PauseType {
|
||||
Scene,
|
||||
Window,
|
||||
@@ -72,5 +70,3 @@ private:
|
||||
|
||||
PauseEntry *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
78
src/legacy/switch-priority.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void AdvSceneSwitcher::on_threadPriority_currentTextChanged(const QString &text)
|
||||
{
|
||||
if (loading || ui->threadPriority->count() !=
|
||||
(int)switcher->threadPriorities.size())
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
for (auto p : switcher->threadPriorities) {
|
||||
if (p.name == text.toUtf8().constData()) {
|
||||
switcher->threadPriority = p.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_priorityUp_clicked()
|
||||
{
|
||||
int currentIndex = ui->priorityList->currentRow();
|
||||
if (currentIndex != -1 && currentIndex != 0) {
|
||||
ui->priorityList->insertItem(
|
||||
currentIndex - 1,
|
||||
ui->priorityList->takeItem(currentIndex));
|
||||
ui->priorityList->setCurrentRow(currentIndex - 1);
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->functionNamesByPriority.begin() +
|
||||
currentIndex,
|
||||
switcher->functionNamesByPriority.begin() +
|
||||
currentIndex - 1);
|
||||
}
|
||||
ui->macroPriorityWarning->setVisible(
|
||||
switcher->functionNamesByPriority[0] != macro_func);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_priorityDown_clicked()
|
||||
{
|
||||
int currentIndex = ui->priorityList->currentRow();
|
||||
if (currentIndex != -1 &&
|
||||
currentIndex != ui->priorityList->count() - 1) {
|
||||
ui->priorityList->insertItem(
|
||||
currentIndex + 1,
|
||||
ui->priorityList->takeItem(currentIndex));
|
||||
ui->priorityList->setCurrentRow(currentIndex + 1);
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->functionNamesByPriority.begin() +
|
||||
currentIndex,
|
||||
switcher->functionNamesByPriority.begin() +
|
||||
currentIndex + 1);
|
||||
}
|
||||
ui->macroPriorityWarning->setVisible(
|
||||
switcher->functionNamesByPriority[0] != macro_func);
|
||||
}
|
||||
|
||||
bool SwitcherData::prioFuncsValid()
|
||||
{
|
||||
auto fNBPCopy = functionNamesByPriority;
|
||||
|
||||
std::sort(fNBPCopy.begin(), fNBPCopy.end());
|
||||
auto it = std::unique(fNBPCopy.begin(), fNBPCopy.end());
|
||||
bool wasUnique = (it == fNBPCopy.end());
|
||||
|
||||
if (!wasUnique) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int p : functionNamesByPriority) {
|
||||
if (p < 0 || p > 10) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool RandomSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
@@ -116,7 +113,7 @@ void SwitcherData::loadRandomSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(randomArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupRandomTab()
|
||||
void AdvSceneSwitcher::setupRandomTab()
|
||||
{
|
||||
for (auto &s : switcher->randomSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -143,8 +140,7 @@ void AdvSceneSwitcher::SetupRandomTab()
|
||||
border-radius: 7px; \
|
||||
border-color: rgb(0,0,0,0) \
|
||||
}");
|
||||
if (switcher->switchIfNotMatching !=
|
||||
SwitcherData::NoMatch::RANDOM_SWITCH) {
|
||||
if (switcher->switchIfNotMatching != RANDOM_SWITCH) {
|
||||
if (!switcher->disableHints) {
|
||||
PulseWidget(ui->randomDisabledWarning, QColor(Qt::red),
|
||||
QColor(0, 0, 0, 0));
|
||||
@@ -186,7 +182,7 @@ RandomSwitchWidget::RandomSwitchWidget(QWidget *parent, RandomSwitch *s)
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions},
|
||||
{"{{delay}}", delay}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.randomTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.randomTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -224,5 +220,3 @@ void RandomSwitchWidget::DelayChanged(double d)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->delay = d;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#pragma once
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
struct RandomSwitch : SceneSwitcherEntry {
|
||||
static bool pause;
|
||||
double delay = 0.0;
|
||||
@@ -38,5 +36,3 @@ private:
|
||||
|
||||
RandomSwitch *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool ScreenRegionSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
|
||||
void AdvSceneSwitcher::ClearFrames(QListWidget *list)
|
||||
void AdvSceneSwitcher::clearFrames(QListWidget *list)
|
||||
{
|
||||
for (int i = 0; i < list->count(); ++i) {
|
||||
ScreenRegionWidget *sw =
|
||||
@@ -51,7 +48,7 @@ void AdvSceneSwitcher::on_showFrame_clicked()
|
||||
showCurrentFrame(ui->screenRegionSwitches);
|
||||
} else {
|
||||
SetShowFrames();
|
||||
ClearFrames(ui->screenRegionSwitches);
|
||||
clearFrames(ui->screenRegionSwitches);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +59,7 @@ void AdvSceneSwitcher::on_screenRegionSwitches_currentRowChanged(int idx)
|
||||
}
|
||||
|
||||
if (switcher->showFrame) {
|
||||
ClearFrames(ui->screenRegionSwitches);
|
||||
clearFrames(ui->screenRegionSwitches);
|
||||
showCurrentFrame(ui->screenRegionSwitches);
|
||||
}
|
||||
}
|
||||
@@ -156,7 +153,7 @@ bool SwitcherData::checkScreenRegionSwitch(OBSWeakSource &scene,
|
||||
return false;
|
||||
}
|
||||
|
||||
std::pair<int, int> cursorPos = GetCursorPos();
|
||||
std::pair<int, int> cursorPos = getCursorPos();
|
||||
int minRegionSize = 99999;
|
||||
bool match = false;
|
||||
|
||||
@@ -191,7 +188,7 @@ bool SwitcherData::checkScreenRegionSwitch(OBSWeakSource &scene,
|
||||
|
||||
void AdvSceneSwitcher::updateScreenRegionCursorPos()
|
||||
{
|
||||
std::pair<int, int> position = GetCursorPos();
|
||||
std::pair<int, int> position = getCursorPos();
|
||||
ui->cursorXPosition->setText(QString::number(position.first));
|
||||
ui->cursorYPosition->setText(QString::number(position.second));
|
||||
}
|
||||
@@ -231,7 +228,7 @@ void SwitcherData::loadScreenRegionSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(screenRegionArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupRegionTab()
|
||||
void AdvSceneSwitcher::setupRegionTab()
|
||||
{
|
||||
for (auto &s : switcher->screenRegionSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -321,7 +318,7 @@ ScreenRegionWidget::ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s)
|
||||
QWidget::connect(maxY, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(MaxYChanged(int)));
|
||||
|
||||
PopulateSceneSelection(
|
||||
populateSceneSelection(
|
||||
excludeScenes, false, false, false, false, nullptr, true,
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.screenRegionTab.excludeScenes.None"),
|
||||
@@ -345,7 +342,7 @@ ScreenRegionWidget::ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s)
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions},
|
||||
{"{{excludeScenes}}", excludeScenes}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.screenRegionTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.screenRegionTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -458,5 +455,3 @@ void ScreenRegionWidget::drawFrame()
|
||||
switchData->maxY - switchData->minY);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <QSpinBox>
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto screen_region_func = 4;
|
||||
|
||||
struct ScreenRegionSwitch : SceneSwitcherEntry {
|
||||
@@ -57,5 +55,3 @@ private:
|
||||
|
||||
void drawFrame();
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <QScrollArea>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
constexpr auto max_extend_text_size = 150;
|
||||
|
||||
@@ -281,7 +278,7 @@ void SwitcherData::loadSceneSequenceSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(sceneSequenceArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupSequenceTab()
|
||||
void AdvSceneSwitcher::setupSequenceTab()
|
||||
{
|
||||
for (auto &s : switcher->sceneSequenceSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -458,7 +455,7 @@ bool SceneSequenceSwitch::checkDurationMatchInterruptible()
|
||||
|
||||
void SceneSequenceSwitch::prepareUninterruptibleMatch(int &linger)
|
||||
{
|
||||
int dur = delay.Milliseconds();
|
||||
int dur = delay.seconds * 1000;
|
||||
if (dur > 0) {
|
||||
linger = dur;
|
||||
}
|
||||
@@ -591,8 +588,10 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
||||
QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(SceneChanged(const QString &)));
|
||||
|
||||
QWidget::connect(delay, SIGNAL(DurationChanged(const Duration &)), this,
|
||||
SLOT(DelayChanged(const Duration &)));
|
||||
QWidget::connect(delay, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DelayChanged(double)));
|
||||
QWidget::connect(delay, SIGNAL(UnitChanged(DurationUnit)), this,
|
||||
SLOT(DelayUnitsChanged(DurationUnit)));
|
||||
QWidget::connect(startScenes,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(StartSceneChanged(const QString &)));
|
||||
@@ -604,7 +603,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
||||
QWidget::connect(reduce, SIGNAL(clicked()), this,
|
||||
SLOT(ReduceClicked()));
|
||||
|
||||
PopulateSceneSelection(startScenes);
|
||||
populateSceneSelection(startScenes);
|
||||
interruptible->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneSequenceTab.interruptibleHint"));
|
||||
|
||||
@@ -616,7 +615,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{delay}}", delay},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.sceneSequenceTab.extendEntry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
@@ -629,7 +628,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
||||
{"{{delay}}", delay},
|
||||
{"{{transitions}}", transitions},
|
||||
{"{{interruptible}}", interruptible}};
|
||||
PlaceWidgets(obs_module_text(
|
||||
placeWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneSequenceTab.entry"),
|
||||
startSequence, widgetPlaceholders);
|
||||
|
||||
@@ -690,14 +689,24 @@ void SequenceWidget::swapSwitchData(SequenceWidget *s1, SequenceWidget *s2)
|
||||
s2->setSwitchData(t);
|
||||
}
|
||||
|
||||
void SequenceWidget::DelayChanged(const Duration &delay)
|
||||
void SequenceWidget::DelayChanged(double sec)
|
||||
{
|
||||
if (loading || !switchData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->delay = delay;
|
||||
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;
|
||||
}
|
||||
|
||||
void SequenceWidget::setExtendedSequenceStartScene()
|
||||
@@ -796,5 +805,3 @@ void SequenceWidget::ReduceClicked()
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include "switch-generic.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto round_trip_func = 1;
|
||||
|
||||
struct SceneSequenceSwitch : SceneSwitcherEntry {
|
||||
@@ -61,7 +59,8 @@ public:
|
||||
|
||||
private slots:
|
||||
void SceneChanged(const QString &text);
|
||||
void DelayChanged(const Duration &delay);
|
||||
void DelayChanged(double delay);
|
||||
void DelayUnitsChanged(DurationUnit);
|
||||
void StartSceneChanged(const QString &text);
|
||||
void InterruptibleChanged(int state);
|
||||
void ExtendClicked();
|
||||
@@ -84,5 +83,3 @@ protected:
|
||||
|
||||
SceneSequenceSwitch *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
bool TimeSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
|
||||
@@ -182,7 +179,7 @@ void SwitcherData::loadTimeSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(timeArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupTimeTab()
|
||||
void AdvSceneSwitcher::setupTimeTab()
|
||||
{
|
||||
for (auto &s : switcher->timeSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -261,7 +258,7 @@ TimeSwitchWidget::TimeSwitchWidget(QWidget *parent, TimeSwitch *s)
|
||||
{"{{time}}", time},
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.timeTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.timeTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -309,5 +306,3 @@ void TimeSwitchWidget::TimeChanged(const QTime &time)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->time = time;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto time_func = 7;
|
||||
|
||||
typedef enum {
|
||||
@@ -56,5 +54,3 @@ private:
|
||||
|
||||
TimeSwitch *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
constexpr auto default_def_transition_dealy = 300;
|
||||
bool DefaultSceneTransition::pause = false;
|
||||
@@ -172,7 +169,7 @@ void SwitcherData::checkDefaultSceneTransitions()
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::DefTransitionDelayValueChanged(int value)
|
||||
void AdvSceneSwitcher::defTransitionDelayValueChanged(int value)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
@@ -182,6 +179,104 @@ void AdvSceneSwitcher::DefTransitionDelayValueChanged(int value)
|
||||
DefaultSceneTransition::delay = value;
|
||||
}
|
||||
|
||||
std::pair<obs_weak_source_t *, int> getNextTransition(obs_weak_source_t *scene1,
|
||||
obs_weak_source_t *scene2)
|
||||
{
|
||||
obs_weak_source_t *ws = nullptr;
|
||||
int duration = 0;
|
||||
if (scene1 && scene2) {
|
||||
for (SceneTransition &t : switcher->sceneTransitions) {
|
||||
if (!t.initialized()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t.scene == scene1 && t.scene2 == scene2) {
|
||||
ws = t.transition;
|
||||
duration = t.duration * 1000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::make_pair(ws, duration);
|
||||
}
|
||||
|
||||
void overwriteTransitionOverride(const sceneSwitchInfo &ssi, transitionData &td)
|
||||
{
|
||||
obs_source_t *scene = obs_weak_source_get_source(ssi.scene);
|
||||
obs_data_t *data = obs_source_get_private_settings(scene);
|
||||
|
||||
td.name = obs_data_get_string(data, "transition");
|
||||
td.duration = obs_data_get_int(data, "transition_duration");
|
||||
|
||||
std::string name = GetWeakSourceName(ssi.transition);
|
||||
|
||||
obs_data_set_string(data, "transition", name.c_str());
|
||||
obs_data_set_int(data, "transition_duration", ssi.duration);
|
||||
|
||||
obs_data_release(data);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void restoreTransitionOverride(obs_source_t *scene, const transitionData &td)
|
||||
{
|
||||
obs_data_t *data = obs_source_get_private_settings(scene);
|
||||
|
||||
obs_data_set_string(data, "transition", td.name.c_str());
|
||||
obs_data_set_int(data, "transition_duration", td.duration);
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
void setNextTransition(const sceneSwitchInfo &sceneSwitch,
|
||||
obs_source_t *currentSource, transitionData &td)
|
||||
{
|
||||
// Priority:
|
||||
// 1. Transition tab
|
||||
// 2. Individual switcher entry
|
||||
// 3. Current transition settings
|
||||
|
||||
// Transition Tab
|
||||
obs_weak_source_t *currentScene =
|
||||
obs_source_get_weak_source(currentSource);
|
||||
auto tinfo = getNextTransition(currentScene, sceneSwitch.scene);
|
||||
obs_weak_source_release(currentScene);
|
||||
|
||||
OBSWeakSource nextTransition = tinfo.first;
|
||||
int nextTransitionDuration = tinfo.second;
|
||||
|
||||
// Individual switcher entry
|
||||
if (!nextTransition) {
|
||||
nextTransition = sceneSwitch.transition;
|
||||
}
|
||||
if (!nextTransitionDuration) {
|
||||
nextTransitionDuration = sceneSwitch.duration;
|
||||
}
|
||||
|
||||
// Current transition settings
|
||||
if (!nextTransition) {
|
||||
auto ct = obs_frontend_get_current_transition();
|
||||
nextTransition = obs_source_get_weak_source(ct);
|
||||
obs_weak_source_release(nextTransition);
|
||||
obs_source_release(ct);
|
||||
}
|
||||
if (!nextTransitionDuration) {
|
||||
nextTransitionDuration = obs_frontend_get_transition_duration();
|
||||
}
|
||||
|
||||
if (switcher->adjustActiveTransitionType) {
|
||||
obs_frontend_set_transition_duration(nextTransitionDuration);
|
||||
auto t = obs_weak_source_get_source(nextTransition);
|
||||
obs_frontend_set_current_transition(t);
|
||||
obs_source_release(t);
|
||||
}
|
||||
|
||||
if (switcher->transitionOverrideOverride) {
|
||||
overwriteTransitionOverride({sceneSwitch.scene, nextTransition,
|
||||
nextTransitionDuration},
|
||||
td);
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::saveSceneTransitions(obs_data_t *obj)
|
||||
{
|
||||
obs_data_array_t *sceneTransitionsArray = obs_data_array_create();
|
||||
@@ -254,7 +349,7 @@ void SwitcherData::loadSceneTransitions(obs_data_t *obj)
|
||||
obs_data_get_int(obj, "defTransitionDelay");
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupTransitionsTab()
|
||||
void AdvSceneSwitcher::setupTransitionsTab()
|
||||
{
|
||||
for (auto &s : switcher->sceneTransitions) {
|
||||
QListWidgetItem *item;
|
||||
@@ -302,11 +397,11 @@ void AdvSceneSwitcher::SetupTransitionsTab()
|
||||
"AdvSceneSwitcher.transitionTab.defaultTransition.delay.help"));
|
||||
|
||||
QWidget::connect(defTransitionDelay, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(DefTransitionDelayValueChanged(int)));
|
||||
SLOT(defTransitionDelayValueChanged(int)));
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{defTransitionDelay}}", defTransitionDelay}};
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.transitionTab.defaultTransition.delay"),
|
||||
ui->defTransitionDelayLayout, widgetPlaceholders);
|
||||
@@ -354,7 +449,7 @@ TransitionSwitchWidget::TransitionSwitchWidget(QWidget *parent,
|
||||
QWidget::connect(duration, SIGNAL(valueChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
|
||||
PopulateSceneSelection(scenes2);
|
||||
populateSceneSelection(scenes2);
|
||||
|
||||
if (s) {
|
||||
scenes2->setCurrentText(GetWeakSourceName(s->scene2).c_str());
|
||||
@@ -367,7 +462,7 @@ TransitionSwitchWidget::TransitionSwitchWidget(QWidget *parent,
|
||||
{"{{scenes2}}", scenes2},
|
||||
{"{{duration}}", duration},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.transitionTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.transitionTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -423,7 +518,7 @@ DefTransitionSwitchWidget::DefTransitionSwitchWidget(QWidget *parent,
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{scenes}}", scenes}, {"{{transitions}}", transitions}};
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.transitionTab.defaultTransitionEntry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
@@ -497,5 +592,3 @@ void DefaultSceneTransition::setTransition()
|
||||
t = std::thread(setTransitionDelayed, transition, delay);
|
||||
t.detach();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
struct SceneTransition : SceneSwitcherEntry {
|
||||
OBSWeakSource scene2 = nullptr;
|
||||
double duration = 0.3;
|
||||
@@ -79,5 +77,3 @@ public:
|
||||
private:
|
||||
DefaultSceneTransition *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QBuffer>
|
||||
#include <QToolTip>
|
||||
#include <thread>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool VideoSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
@@ -185,7 +182,7 @@ void SwitcherData::loadVideoSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(videoArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupVideoTab()
|
||||
void AdvSceneSwitcher::setupVideoTab()
|
||||
{
|
||||
for (auto &s : switcher->videoSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -431,7 +428,7 @@ VideoSwitchWidget::VideoSwitchWidget(QWidget *parent, VideoSwitch *s)
|
||||
{"{{ignoreInactiveSource}}", ignoreInactiveSource},
|
||||
{"{{scenes}}", scenes},
|
||||
{"{{transitions}}", transitions}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.videoTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.videoTab.entry"),
|
||||
switchLayout, widgetPlaceholders);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
@@ -580,5 +577,3 @@ void VideoSwitchWidget::IgnoreInactiveChanged(int state)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->ignoreInactiveSource = state;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include "switch-generic.hpp"
|
||||
#include "screenshot-helper.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto video_func = 9;
|
||||
|
||||
enum class videoSwitchType {
|
||||
@@ -82,5 +80,3 @@ private:
|
||||
|
||||
VideoSwitch *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <regex>
|
||||
|
||||
namespace advss {
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
bool WindowSwitch::pause = false;
|
||||
static QMetaObject::Connection addPulse;
|
||||
@@ -181,8 +177,8 @@ void checkWindowTitleSwitchDirect(WindowSwitch &s,
|
||||
OBSWeakSource &transition)
|
||||
{
|
||||
bool focus = (!s.focus || s.window == currentWindowTitle);
|
||||
bool fullscreen = (!s.fullscreen || IsFullscreen(s.window));
|
||||
bool max = (!s.maximized || IsMaximized(s.window));
|
||||
bool fullscreen = (!s.fullscreen || isFullscreen(s.window));
|
||||
bool max = (!s.maximized || isMaximized(s.window));
|
||||
|
||||
if (focus && fullscreen && max) {
|
||||
match = true;
|
||||
@@ -207,8 +203,8 @@ void checkWindowTitleSwitchRegex(WindowSwitch &s,
|
||||
}
|
||||
|
||||
bool focus = (!s.focus || window == currentWindowTitle);
|
||||
bool fullscreen = (!s.fullscreen || IsFullscreen(window));
|
||||
bool max = (!s.maximized || IsMaximized(window));
|
||||
bool fullscreen = (!s.fullscreen || isFullscreen(window));
|
||||
bool max = (!s.maximized || isMaximized(window));
|
||||
|
||||
if (focus && fullscreen && max) {
|
||||
match = true;
|
||||
@@ -319,7 +315,7 @@ void SwitcherData::loadWindowTitleSwitches(obs_data_t *obj)
|
||||
obs_data_array_release(ignoreWindowsArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetupTitleTab()
|
||||
void AdvSceneSwitcher::setupTitleTab()
|
||||
{
|
||||
for (auto &s : switcher->windowSwitches) {
|
||||
QListWidgetItem *item;
|
||||
@@ -340,7 +336,7 @@ void AdvSceneSwitcher::SetupTitleTab()
|
||||
ui->windowHelp->setVisible(false);
|
||||
}
|
||||
|
||||
PopulateWindowSelection(ui->ignoreWindowsWindows);
|
||||
populateWindowSelection(ui->ignoreWindowsWindows);
|
||||
|
||||
for (auto &window : switcher->ignoreWindowsSwitches) {
|
||||
QString text = QString::fromStdString(window);
|
||||
@@ -398,7 +394,7 @@ WindowSwitchWidget::WindowSwitchWidget(QWidget *parent, WindowSwitch *s)
|
||||
QWidget::connect(focused, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(FocusChanged(int)));
|
||||
|
||||
PopulateWindowSelection(windows);
|
||||
populateWindowSelection(windows);
|
||||
|
||||
windows->setEditable(true);
|
||||
windows->setMaxVisibleItems(20);
|
||||
@@ -418,7 +414,7 @@ WindowSwitchWidget::WindowSwitchWidget(QWidget *parent, WindowSwitch *s)
|
||||
{"{{fullscreen}}", fullscreen},
|
||||
{"{{maximized}}", maximized},
|
||||
{"{{focused}}", focused}};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.windowTitleTab.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.windowTitleTab.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -486,5 +482,3 @@ void WindowSwitchWidget::FocusChanged(int state)
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->focus = state;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#pragma once
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr auto window_title_func = 5;
|
||||
|
||||
struct WindowSwitch : SceneSwitcherEntry {
|
||||
@@ -49,5 +47,3 @@ private:
|
||||
|
||||
WindowSwitch *switchData;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace advss {
|
||||
|
||||
static Display *xdisplay = 0;
|
||||
|
||||
static QLibrary *libXtstHandle = nullptr;
|
||||
@@ -317,7 +315,7 @@ bool windowStatesAreSet(const std::string &windowTitle,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsMaximized(const std::string &title)
|
||||
bool isMaximized(const std::string &title)
|
||||
{
|
||||
std::vector<QString> states;
|
||||
states.emplace_back("_NET_WM_STATE_MAXIMIZED_VERT");
|
||||
@@ -325,19 +323,13 @@ bool IsMaximized(const std::string &title)
|
||||
return windowStatesAreSet(title, states);
|
||||
}
|
||||
|
||||
bool IsFullscreen(const std::string &title)
|
||||
bool isFullscreen(const std::string &title)
|
||||
{
|
||||
std::vector<QString> states;
|
||||
states.emplace_back("_NET_WM_STATE_FULLSCREEN");
|
||||
return windowStatesAreSet(title, states);
|
||||
}
|
||||
|
||||
std::optional<std::string> GetTextInWindow(const std::string &)
|
||||
{
|
||||
// Not implemented
|
||||
return {};
|
||||
}
|
||||
|
||||
#ifdef USE_PROCPS
|
||||
void GetProcessList(QStringList &processes)
|
||||
{
|
||||
@@ -436,7 +428,7 @@ void GetForegroundProcessName(std::string &proc)
|
||||
proc = getProcNameFromPid(pid);
|
||||
}
|
||||
|
||||
bool IsInFocus(const QString &executable)
|
||||
bool isInFocus(const QString &executable)
|
||||
{
|
||||
std::string current;
|
||||
GetForegroundProcessName(current);
|
||||
@@ -450,7 +442,7 @@ bool IsInFocus(const QString &executable)
|
||||
return (equals || matches);
|
||||
}
|
||||
|
||||
int SecondsSinceLastInput()
|
||||
int secondsSinceLastInput()
|
||||
{
|
||||
if (!canGetIdleTime) {
|
||||
return 0;
|
||||
@@ -667,5 +659,3 @@ void PlatformCleanup()
|
||||
}
|
||||
cleanupDisplay();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#include "macro-action-audio.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr int64_t nsPerMs = 1000000;
|
||||
const std::string MacroActionAudio::id = "audio";
|
||||
|
||||
@@ -39,22 +37,6 @@ const static std::map<MacroActionAudio::FadeType, std::string> fadeTypes = {
|
||||
constexpr auto fadeInterval = std::chrono::milliseconds(100);
|
||||
constexpr float minFade = 0.000001f;
|
||||
|
||||
// For backwards compatibility
|
||||
#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(29, 0, 0)
|
||||
static float get_master_volume()
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
static void set_master_volume(float)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
auto get_master_volume = obs_get_master_volume;
|
||||
auto set_master_volume = obs_set_master_volume;
|
||||
#endif
|
||||
|
||||
void MacroActionAudio::SetFadeActive(bool value)
|
||||
{
|
||||
if (_action == Action::SOURCE_VOLUME) {
|
||||
@@ -103,7 +85,7 @@ void MacroActionAudio::SetVolume(float vol)
|
||||
obs_source_set_volume(s, vol);
|
||||
obs_source_release(s);
|
||||
} else {
|
||||
set_master_volume(vol);
|
||||
obs_set_master_volume(vol);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +100,7 @@ float MacroActionAudio::GetVolume()
|
||||
curVol = obs_source_get_volume(s);
|
||||
obs_source_release(s);
|
||||
} else {
|
||||
curVol = get_master_volume();
|
||||
curVol = obs_get_master_volume();
|
||||
}
|
||||
return curVol;
|
||||
}
|
||||
@@ -132,7 +114,7 @@ void MacroActionAudio::FadeVolume()
|
||||
int nrSteps = 0;
|
||||
float volStep = 0.;
|
||||
if (_fadeType == FadeType::DURATION) {
|
||||
nrSteps = _duration.Milliseconds() / fadeInterval.count();
|
||||
nrSteps = _duration.seconds * 1000 / fadeInterval.count();
|
||||
volStep = volDiff / nrSteps;
|
||||
} else {
|
||||
volStep = _rate / 1000.0f;
|
||||
@@ -230,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.GetValue(), _fade, _duration.Seconds());
|
||||
_volume, _fade, _duration.seconds);
|
||||
} else {
|
||||
blog(LOG_WARNING, "ignored unknown audio action %d",
|
||||
static_cast<int>(_action));
|
||||
@@ -243,16 +225,15 @@ 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);
|
||||
_syncOffset.Save(obj, "syncOffset");
|
||||
_balance.Save(obj, "balance");
|
||||
_volume.Save(obj, "volume");
|
||||
_rate.Save(obj, "rate");
|
||||
obs_data_set_double(obj, "balance", _balance);
|
||||
obs_data_set_int(obj, "volume", _volume);
|
||||
obs_data_set_double(obj, "rate", _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;
|
||||
}
|
||||
|
||||
@@ -262,19 +243,12 @@ 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"));
|
||||
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");
|
||||
}
|
||||
_balance = obs_data_get_double(obj, "balance");
|
||||
_volume = obs_data_get_int(obj, "volume");
|
||||
_rate = obs_data_get_double(obj, "rate");
|
||||
_fade = obs_data_get_bool(obj, "fade");
|
||||
if (obs_data_has_user_value(obj, "wait")) {
|
||||
_wait = obs_data_get_bool(obj, "wait");
|
||||
@@ -303,13 +277,15 @@ std::string MacroActionAudio::GetShortDesc() const
|
||||
static inline void populateActionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[action, name] : actionTypes) {
|
||||
if (action == MacroActionAudio::Action::MONITOR &&
|
||||
!obs_audio_monitoring_available()) {
|
||||
continue;
|
||||
if (action == MacroActionAudio::Action::MONITOR) {
|
||||
if (obs_audio_monitoring_available()) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(action));
|
||||
}
|
||||
} else {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(action));
|
||||
}
|
||||
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(action));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,16 +302,16 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_actions(new QComboBox),
|
||||
_fadeTypes(new QComboBox),
|
||||
_syncOffset(new VariableSpinBox),
|
||||
_syncOffset(new QSpinBox),
|
||||
_monitorTypes(new QComboBox),
|
||||
_balance(new SliderSpinBox(
|
||||
0., 1., "",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.audio.balance.description"))),
|
||||
_volumePercent(new VariableSpinBox),
|
||||
_volumePercent(new QSpinBox),
|
||||
_fade(new QCheckBox),
|
||||
_duration(new DurationSelection(parent, false)),
|
||||
_rate(new VariableDoubleSpinBox),
|
||||
_rate(new QDoubleSpinBox),
|
||||
_wait(new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.action.audio.fade.wait"))),
|
||||
_abortActiveFade(new QCheckBox(
|
||||
@@ -360,35 +336,27 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
populateFadeTypeSelection(_fadeTypes);
|
||||
PopulateMonitorTypeSelection(_monitorTypes);
|
||||
populateMonitorTypeSelection(_monitorTypes);
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||
SLOT(SourceChanged(const SourceSelection &)));
|
||||
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(_syncOffset, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(SyncOffsetChanged(int)));
|
||||
QWidget::connect(_balance, SIGNAL(DoubleValueChanged(double)), this,
|
||||
SLOT(BalanceChanged(double)));
|
||||
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(MonitorTypeChanged(int)));
|
||||
QWidget::connect(
|
||||
_volumePercent,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(VolumeChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_volumePercent, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(VolumeChanged(int)));
|
||||
QWidget::connect(_fade, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(FadeChanged(int)));
|
||||
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(_duration, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(DurationChanged(double)));
|
||||
QWidget::connect(_rate, SIGNAL(valueChanged(double)), this,
|
||||
SLOT(RateChanged(double)));
|
||||
QWidget::connect(_wait, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(WaitChanged(int)));
|
||||
QWidget::connect(_abortActiveFade, SIGNAL(stateChanged(int)), this,
|
||||
@@ -411,10 +379,10 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
{"{{fadeTypes}}", _fadeTypes},
|
||||
};
|
||||
QHBoxLayout *entryLayout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.audio.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.audio.entry"),
|
||||
entryLayout, widgetPlaceholders);
|
||||
_fadeTypeLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.action.audio.fade.duration"),
|
||||
_fadeTypeLayout, widgetPlaceholders);
|
||||
|
||||
@@ -433,7 +401,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
static bool hasVolumeControl(MacroActionAudio::Action action)
|
||||
bool hasVolumeControl(MacroActionAudio::Action action)
|
||||
{
|
||||
return action == MacroActionAudio::Action::SOURCE_VOLUME ||
|
||||
action == MacroActionAudio::Action::MASTER_VOLUME;
|
||||
@@ -451,11 +419,17 @@ void MacroActionAudioEdit::SetWidgetVisibility()
|
||||
_balance->setVisible(_entryData->_action ==
|
||||
MacroActionAudio::Action::BALANCE);
|
||||
|
||||
_fadeTypes->setDisabled(!_entryData->_fade);
|
||||
_wait->setDisabled(!_entryData->_fade);
|
||||
_abortActiveFade->setDisabled(!_entryData->_fade);
|
||||
_duration->setDisabled(!_entryData->_fade);
|
||||
_rate->setDisabled(!_entryData->_fade);
|
||||
|
||||
_fadeTypeLayout->removeWidget(_fade);
|
||||
_fadeTypeLayout->removeWidget(_fadeTypes);
|
||||
_fadeTypeLayout->removeWidget(_duration);
|
||||
_fadeTypeLayout->removeWidget(_rate);
|
||||
ClearLayout(_fadeTypeLayout);
|
||||
clearLayout(_fadeTypeLayout);
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{fade}}", _fade},
|
||||
{"{{duration}}", _duration},
|
||||
@@ -463,12 +437,12 @@ void MacroActionAudioEdit::SetWidgetVisibility()
|
||||
{"{{fadeTypes}}", _fadeTypes},
|
||||
};
|
||||
if (_entryData->_fadeType == MacroActionAudio::FadeType::DURATION) {
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.audio.fade.duration"),
|
||||
_fadeTypeLayout, widgetPlaceholders);
|
||||
} else {
|
||||
PlaceWidgets(obs_module_text(
|
||||
placeWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.action.audio.fade.rate"),
|
||||
_fadeTypeLayout, widgetPlaceholders);
|
||||
}
|
||||
@@ -478,24 +452,10 @@ void MacroActionAudioEdit::SetWidgetVisibility()
|
||||
_rate->setVisible(_entryData->_fadeType ==
|
||||
MacroActionAudio::FadeType::RATE);
|
||||
|
||||
SetLayoutVisible(_fadeTypeLayout,
|
||||
setLayoutVisible(_fadeTypeLayout,
|
||||
hasVolumeControl(_entryData->_action));
|
||||
SetLayoutVisible(_fadeOptionsLayout,
|
||||
setLayoutVisible(_fadeOptionsLayout,
|
||||
hasVolumeControl(_entryData->_action));
|
||||
_abortActiveFade->setVisible(hasVolumeControl(_entryData->_action) &&
|
||||
_entryData->_fade);
|
||||
_wait->setVisible(hasVolumeControl(_entryData->_action) &&
|
||||
_entryData->_fade);
|
||||
|
||||
// TODO: Remove this in a future version:
|
||||
if (_entryData->_action != MacroActionAudio::Action::MASTER_VOLUME &&
|
||||
obs_get_version() >= MAKE_SEMANTIC_VERSION(29, 0, 0)) {
|
||||
_actions->removeItem(_actions->findText(obs_module_text(
|
||||
actionTypes.at(MacroActionAudio::Action::MASTER_VOLUME)
|
||||
.c_str())));
|
||||
}
|
||||
|
||||
updateGeometry();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
@@ -508,13 +468,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));
|
||||
@@ -527,7 +487,7 @@ void MacroActionAudioEdit::SourceChanged(const SourceSelection &source)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_audioSource = source;
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
@@ -539,19 +499,19 @@ void MacroActionAudioEdit::ActionChanged(int idx)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_action = static_cast<MacroActionAudio::Action>(
|
||||
_actions->itemData(idx).toInt());
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::SyncOffsetChanged(const NumberVariable<int> &value)
|
||||
void MacroActionAudioEdit::SyncOffsetChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_syncOffset = value;
|
||||
}
|
||||
|
||||
@@ -561,27 +521,27 @@ void MacroActionAudioEdit::MonitorTypeChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_monitorType = static_cast<obs_monitoring_type>(value);
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::BalanceChanged(const NumberVariable<double> &value)
|
||||
void MacroActionAudioEdit::BalanceChanged(double value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_balance = value;
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::VolumeChanged(const NumberVariable<int> &value)
|
||||
void MacroActionAudioEdit::VolumeChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_volume = value;
|
||||
}
|
||||
|
||||
@@ -591,28 +551,28 @@ void MacroActionAudioEdit::FadeChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_fade = value;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::DurationChanged(const Duration &dur)
|
||||
void MacroActionAudioEdit::DurationChanged(double seconds)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_duration = dur;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroActionAudioEdit::RateChanged(const NumberVariable<double> &value)
|
||||
void MacroActionAudioEdit::RateChanged(double value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_rate = value;
|
||||
}
|
||||
|
||||
@@ -622,7 +582,7 @@ void MacroActionAudioEdit::WaitChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_wait = value;
|
||||
}
|
||||
|
||||
@@ -632,7 +592,7 @@ void MacroActionAudioEdit::AbortActiveFadeChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_abortActiveFade = value;
|
||||
}
|
||||
|
||||
@@ -642,9 +602,7 @@ void MacroActionAudioEdit::FadeTypeChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_fadeType = static_cast<MacroActionAudio::FadeType>(value);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroActionAudio : public MacroAction {
|
||||
public:
|
||||
MacroActionAudio(Macro *m) : MacroAction(m) {}
|
||||
@@ -44,13 +42,13 @@ public:
|
||||
|
||||
Action _action = Action::MUTE;
|
||||
FadeType _fadeType = FadeType::DURATION;
|
||||
NumberVariable<int> _syncOffset = 0;
|
||||
int64_t _syncOffset = 0;
|
||||
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
||||
NumberVariable<double> _balance = 0.5;
|
||||
NumberVariable<int> _volume = 0;
|
||||
double _balance = 0.5;
|
||||
int _volume = 0;
|
||||
bool _fade = false;
|
||||
Duration _duration;
|
||||
NumberVariable<double> _rate = 100.;
|
||||
double _rate = 100.;
|
||||
bool _wait = false;
|
||||
bool _abortActiveFade = false;
|
||||
|
||||
@@ -86,13 +84,13 @@ public:
|
||||
private slots:
|
||||
void SourceChanged(const SourceSelection &);
|
||||
void ActionChanged(int value);
|
||||
void SyncOffsetChanged(const NumberVariable<int> &value);
|
||||
void SyncOffsetChanged(int value);
|
||||
void MonitorTypeChanged(int value);
|
||||
void BalanceChanged(const NumberVariable<double> &value);
|
||||
void VolumeChanged(const NumberVariable<int> &value);
|
||||
void BalanceChanged(double value);
|
||||
void VolumeChanged(int value);
|
||||
void FadeChanged(int value);
|
||||
void DurationChanged(const Duration &seconds);
|
||||
void RateChanged(const NumberVariable<double> &value);
|
||||
void DurationChanged(double seconds);
|
||||
void RateChanged(double value);
|
||||
void WaitChanged(int value);
|
||||
void AbortActiveFadeChanged(int value);
|
||||
void FadeTypeChanged(int value);
|
||||
@@ -103,13 +101,13 @@ protected:
|
||||
SourceSelectionWidget *_sources;
|
||||
QComboBox *_actions;
|
||||
QComboBox *_fadeTypes;
|
||||
VariableSpinBox *_syncOffset;
|
||||
QSpinBox *_syncOffset;
|
||||
QComboBox *_monitorTypes;
|
||||
SliderSpinBox *_balance;
|
||||
VariableSpinBox *_volumePercent;
|
||||
QSpinBox *_volumePercent;
|
||||
QCheckBox *_fade;
|
||||
DurationSelection *_duration;
|
||||
VariableDoubleSpinBox *_rate;
|
||||
QDoubleSpinBox *_rate;
|
||||
QCheckBox *_wait;
|
||||
QCheckBox *_abortActiveFade;
|
||||
QHBoxLayout *_fadeTypeLayout;
|
||||
@@ -121,5 +119,3 @@ private:
|
||||
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "macro-action-scene-switch.hpp"
|
||||
#include "section.hpp"
|
||||
#include "switch-button.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QGraphicsOpacityEffect>
|
||||
|
||||
namespace advss {
|
||||
|
||||
std::map<std::string, MacroActionInfo> &MacroActionFactory::GetMap()
|
||||
{
|
||||
static std::map<std::string, MacroActionInfo> _methods;
|
||||
@@ -81,32 +75,26 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
||||
std::shared_ptr<MacroAction> *entryData,
|
||||
const std::string &id)
|
||||
: MacroSegmentEdit(switcher->macroProperties._highlightActions, parent),
|
||||
_actionSelection(new FilterComboBox()),
|
||||
_enable(new SwitchButton()),
|
||||
_actionSelection(new QComboBox()),
|
||||
_entryData(entryData)
|
||||
{
|
||||
QWidget::connect(_actionSelection,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(ActionSelectionChanged(const QString &)));
|
||||
QWidget::connect(_enable, SIGNAL(checked(bool)), this,
|
||||
SLOT(ActionEnableChanged(bool)));
|
||||
QWidget::connect(window(), SIGNAL(HighlightActionsChanged(bool)), this,
|
||||
SLOT(EnableHighlight(bool)));
|
||||
QWidget::connect(&_actionStateTimer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdateActionState()));
|
||||
|
||||
populateActionSelection(_actionSelection);
|
||||
|
||||
_section->AddHeaderWidget(_enable);
|
||||
_section->AddHeaderWidget(_actionSelection);
|
||||
_section->AddHeaderWidget(_headerInfo);
|
||||
|
||||
auto actionLayout = new QVBoxLayout;
|
||||
QVBoxLayout *actionLayout = new QVBoxLayout;
|
||||
actionLayout->setContentsMargins({7, 7, 7, 7});
|
||||
actionLayout->addWidget(_section);
|
||||
_contentLayout->addLayout(actionLayout);
|
||||
|
||||
auto mainLayout = new QHBoxLayout;
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
mainLayout->addWidget(_frame);
|
||||
@@ -115,7 +103,6 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
||||
_entryData = entryData;
|
||||
UpdateEntryData(id);
|
||||
|
||||
_actionStateTimer.start(300);
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
@@ -125,20 +112,15 @@ void MacroActionEdit::ActionSelectionChanged(const QString &text)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string id = MacroActionFactory::GetIdByName(text);
|
||||
if (id.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HeaderInfoChanged("");
|
||||
auto idx = _entryData->get()->GetIndex();
|
||||
auto macro = _entryData->get()->GetMacro();
|
||||
std::string id = MacroActionFactory::GetIdByName(text);
|
||||
HeaderInfoChanged("");
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->reset();
|
||||
*_entryData = MacroActionFactory::Create(id, macro);
|
||||
(*_entryData)->SetIndex(idx);
|
||||
(*_entryData)->PostLoad();
|
||||
}
|
||||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||
@@ -151,9 +133,6 @@ void MacroActionEdit::UpdateEntryData(const std::string &id)
|
||||
{
|
||||
_actionSelection->setCurrentText(
|
||||
obs_module_text(MacroActionFactory::GetActionName(id).c_str()));
|
||||
const bool enabled = (*_entryData)->Enabled();
|
||||
_enable->setChecked(enabled);
|
||||
SetDisableEffect(!enabled);
|
||||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||
@@ -168,51 +147,14 @@ void MacroActionEdit::SetEntryData(std::shared_ptr<MacroAction> *data)
|
||||
_entryData = data;
|
||||
}
|
||||
|
||||
void MacroActionEdit::SetDisableEffect(bool value)
|
||||
{
|
||||
if (value) {
|
||||
auto effect = new QGraphicsOpacityEffect(this);
|
||||
effect->setOpacity(0.5);
|
||||
_section->setGraphicsEffect(effect);
|
||||
} else {
|
||||
_section->setGraphicsEffect(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionEdit::ActionEnableChanged(bool value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
(*_entryData)->SetEnabled(value);
|
||||
SetDisableEffect(!value);
|
||||
}
|
||||
|
||||
void MacroActionEdit::UpdateActionState()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetEnableAppearance((*_entryData)->Enabled());
|
||||
}
|
||||
|
||||
void MacroActionEdit::SetEnableAppearance(bool value)
|
||||
{
|
||||
_enable->setChecked(value);
|
||||
SetDisableEffect(!value);
|
||||
}
|
||||
|
||||
std::shared_ptr<MacroSegment> MacroActionEdit::Data() const
|
||||
std::shared_ptr<MacroSegment> MacroActionEdit::Data()
|
||||
{
|
||||
return *_entryData;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::AddMacroAction(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
@@ -237,11 +179,10 @@ void AdvSceneSwitcher::AddMacroAction(int idx)
|
||||
auto data = obs_data_create();
|
||||
macro->Actions().at(idx - 1)->Save(data);
|
||||
macro->Actions().at(idx)->Load(data);
|
||||
macro->Actions().at(idx)->PostLoad();
|
||||
obs_data_release(data);
|
||||
}
|
||||
macro->UpdateActionIndices();
|
||||
ui->actionsList->Insert(
|
||||
actionsList->Insert(
|
||||
idx,
|
||||
new MacroActionEdit(this, ¯o->Actions()[idx], id));
|
||||
SetActionData(*macro);
|
||||
@@ -252,7 +193,7 @@ void AdvSceneSwitcher::AddMacroAction(int idx)
|
||||
|
||||
void AdvSceneSwitcher::on_actionAdd_clicked()
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
@@ -265,12 +206,12 @@ void AdvSceneSwitcher::on_actionAdd_clicked()
|
||||
if (currentActionIdx != -1) {
|
||||
MacroActionSelectionChanged(currentActionIdx + 1);
|
||||
}
|
||||
ui->actionsList->SetHelpMsgVisible(false);
|
||||
actionsList->SetHelpMsgVisible(false);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
@@ -281,7 +222,7 @@ void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
ui->actionsList->Remove(idx);
|
||||
actionsList->Remove(idx);
|
||||
macro->Actions().erase(macro->Actions().begin() + idx);
|
||||
switcher->abortMacroWait = true;
|
||||
switcher->macroWaitCv.notify_all();
|
||||
@@ -296,7 +237,7 @@ void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
||||
void AdvSceneSwitcher::on_actionRemove_clicked()
|
||||
{
|
||||
if (currentActionIdx == -1) {
|
||||
auto macro = GetSelectedMacro();
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
@@ -307,113 +248,21 @@ void AdvSceneSwitcher::on_actionRemove_clicked()
|
||||
MacroActionSelectionChanged(-1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_actionTop_clicked()
|
||||
{
|
||||
if (currentActionIdx == -1) {
|
||||
return;
|
||||
}
|
||||
MacroActionReorder(0, currentActionIdx);
|
||||
MacroActionSelectionChanged(0);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_actionUp_clicked()
|
||||
{
|
||||
if (currentActionIdx == -1 || currentActionIdx == 0) {
|
||||
if (currentActionIdx == -1) {
|
||||
return;
|
||||
}
|
||||
MoveMacroActionUp(currentActionIdx);
|
||||
MacroActionSelectionChanged(currentActionIdx - 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_actionDown_clicked()
|
||||
{
|
||||
if (currentActionIdx == -1 ||
|
||||
currentActionIdx == ui->actionsList->ContentLayout()->count() - 1) {
|
||||
return;
|
||||
}
|
||||
MoveMacroActionDown(currentActionIdx);
|
||||
MacroActionSelectionChanged(currentActionIdx + 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_actionBottom_clicked()
|
||||
{
|
||||
if (currentActionIdx == -1) {
|
||||
return;
|
||||
}
|
||||
const int newIdx = ui->actionsList->ContentLayout()->count() - 1;
|
||||
MacroActionReorder(newIdx, currentActionIdx);
|
||||
MacroActionSelectionChanged(newIdx);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_elseActionAdd_clicked()
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentElseActionIdx == -1) {
|
||||
AddMacroElseAction((int)macro->ElseActions().size());
|
||||
} else {
|
||||
AddMacroElseAction(currentElseActionIdx + 1);
|
||||
}
|
||||
if (currentElseActionIdx != -1) {
|
||||
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
|
||||
}
|
||||
ui->elseActionsList->SetHelpMsgVisible(false);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_elseActionRemove_clicked()
|
||||
{
|
||||
if (currentElseActionIdx == -1) {
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
RemoveMacroElseAction((int)macro->Actions().size() - 1);
|
||||
} else {
|
||||
RemoveMacroElseAction(currentElseActionIdx);
|
||||
}
|
||||
MacroElseActionSelectionChanged(-1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_elseActionTop_clicked()
|
||||
{
|
||||
if (currentElseActionIdx == -1) {
|
||||
return;
|
||||
}
|
||||
MacroElseActionReorder(0, currentElseActionIdx);
|
||||
MacroElseActionSelectionChanged(0);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_elseActionUp_clicked()
|
||||
{
|
||||
if (currentElseActionIdx == -1 || currentElseActionIdx == 0) {
|
||||
return;
|
||||
}
|
||||
MoveMacroElseActionUp(currentElseActionIdx);
|
||||
MacroElseActionSelectionChanged(currentElseActionIdx - 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_elseActionDown_clicked()
|
||||
{
|
||||
if (currentElseActionIdx == -1 ||
|
||||
currentElseActionIdx ==
|
||||
ui->elseActionsList->ContentLayout()->count() - 1) {
|
||||
return;
|
||||
}
|
||||
MoveMacroElseActionDown(currentElseActionIdx);
|
||||
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_elseActionBottom_clicked()
|
||||
{
|
||||
if (currentElseActionIdx == -1) {
|
||||
return;
|
||||
}
|
||||
const int newIdx = ui->elseActionsList->ContentLayout()->count() - 1;
|
||||
MacroElseActionReorder(newIdx, currentElseActionIdx);
|
||||
MacroElseActionSelectionChanged(newIdx);
|
||||
MoveMacroActionDown(currentActionIdx);
|
||||
MacroActionSelectionChanged(currentActionIdx + 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2)
|
||||
@@ -429,18 +278,18 @@ void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2)
|
||||
iter_swap(m->Actions().begin() + pos1, m->Actions().begin() + pos2);
|
||||
m->UpdateActionIndices();
|
||||
auto widget1 = static_cast<MacroActionEdit *>(
|
||||
ui->actionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||
actionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||
auto widget2 = static_cast<MacroActionEdit *>(
|
||||
ui->actionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
||||
ui->actionsList->Insert(pos1, widget2);
|
||||
ui->actionsList->Insert(pos2, widget1);
|
||||
actionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
||||
actionsList->Insert(pos1, widget2);
|
||||
actionsList->Insert(pos2, widget1);
|
||||
SetActionData(*m);
|
||||
emit(MacroSegmentOrderChanged());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MoveMacroActionUp(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
@@ -455,7 +304,7 @@ void AdvSceneSwitcher::MoveMacroActionUp(int idx)
|
||||
|
||||
void AdvSceneSwitcher::MoveMacroActionDown(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
@@ -468,170 +317,35 @@ void AdvSceneSwitcher::MoveMacroActionDown(int idx)
|
||||
HighlightAction(idx + 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MacroElseActionSelectionChanged(int idx)
|
||||
{
|
||||
SetupMacroSegmentSelection(MacroSection::ELSE_ACTIONS, idx);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MacroElseActionReorder(int to, int from)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (to == from || from < 0 || from > (int)macro->ElseActions().size() ||
|
||||
to < 0 || to > (int)macro->ElseActions().size()) {
|
||||
return;
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
auto action = macro->ElseActions().at(from);
|
||||
macro->ElseActions().erase(macro->ElseActions().begin() + from);
|
||||
macro->ElseActions().insert(macro->ElseActions().begin() + to,
|
||||
action);
|
||||
macro->UpdateElseActionIndices();
|
||||
ui->elseActionsList->ContentLayout()->insertItem(
|
||||
to, ui->elseActionsList->ContentLayout()->takeAt(from));
|
||||
SetElseActionData(*macro);
|
||||
}
|
||||
HighlightElseAction(to);
|
||||
emit(MacroSegmentOrderChanged());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::AddMacroElseAction(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string id;
|
||||
if (idx - 1 >= 0) {
|
||||
id = macro->ElseActions().at(idx - 1)->GetId();
|
||||
} else {
|
||||
MacroActionSwitchScene temp(nullptr);
|
||||
id = temp.GetId();
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
macro->ElseActions().emplace(
|
||||
macro->ElseActions().begin() + idx,
|
||||
MacroActionFactory::Create(id, macro.get()));
|
||||
if (idx - 1 >= 0) {
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
macro->ElseActions().at(idx - 1)->Save(data);
|
||||
macro->ElseActions().at(idx)->Load(data);
|
||||
}
|
||||
macro->ElseActions().at(idx)->PostLoad();
|
||||
macro->UpdateElseActionIndices();
|
||||
ui->elseActionsList->Insert(
|
||||
idx, new MacroActionEdit(
|
||||
this, ¯o->ElseActions()[idx], id));
|
||||
SetElseActionData(*macro);
|
||||
}
|
||||
HighlightElseAction(idx);
|
||||
emit(MacroSegmentOrderChanged());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::RemoveMacroElseAction(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx < 0 || idx >= (int)macro->ElseActions().size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
ui->elseActionsList->Remove(idx);
|
||||
macro->ElseActions().erase(macro->ElseActions().begin() + idx);
|
||||
switcher->abortMacroWait = true;
|
||||
switcher->macroWaitCv.notify_all();
|
||||
macro->UpdateElseActionIndices();
|
||||
SetActionData(*macro);
|
||||
}
|
||||
MacroElseActionSelectionChanged(-1);
|
||||
lastInteracted = MacroSection::ELSE_ACTIONS;
|
||||
emit(MacroSegmentOrderChanged());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SwapElseActions(Macro *m, int pos1, int pos2)
|
||||
{
|
||||
if (pos1 == pos2) {
|
||||
return;
|
||||
}
|
||||
if (pos1 > pos2) {
|
||||
std::swap(pos1, pos2);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
iter_swap(m->ElseActions().begin() + pos1,
|
||||
m->ElseActions().begin() + pos2);
|
||||
m->UpdateElseActionIndices();
|
||||
auto widget1 = static_cast<MacroActionEdit *>(
|
||||
ui->elseActionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||
auto widget2 = static_cast<MacroActionEdit *>(
|
||||
ui->elseActionsList->ContentLayout()
|
||||
->takeAt(pos2 - 1)
|
||||
->widget());
|
||||
ui->elseActionsList->Insert(pos1, widget2);
|
||||
ui->elseActionsList->Insert(pos2, widget1);
|
||||
SetElseActionData(*m);
|
||||
emit(MacroSegmentOrderChanged());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MoveMacroElseActionUp(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx < 1 || idx >= (int)macro->ElseActions().size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SwapElseActions(macro.get(), idx, idx - 1);
|
||||
HighlightElseAction(idx - 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MoveMacroElseActionDown(int idx)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx < 0 || idx >= (int)macro->ElseActions().size() - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
SwapElseActions(macro.get(), idx, idx + 1);
|
||||
HighlightElseAction(idx + 1);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MacroActionSelectionChanged(int idx)
|
||||
{
|
||||
SetupMacroSegmentSelection(MacroSection::ACTIONS, idx);
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
actionsList->SetSelection(idx);
|
||||
conditionsList->SetSelection(-1);
|
||||
|
||||
if (idx < 0 || (unsigned)idx >= macro->Actions().size()) {
|
||||
currentActionIdx = -1;
|
||||
} else {
|
||||
currentActionIdx = idx;
|
||||
lastInteracted = MacroSection::ACTIONS;
|
||||
}
|
||||
currentConditionIdx = -1;
|
||||
HighlightControls();
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MacroActionReorder(int to, int from)
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
auto macro = getSelectedMacro();
|
||||
if (!macro) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (to == from || from < 0 || from > (int)macro->Actions().size() ||
|
||||
to < 0 || to > (int)macro->Actions().size()) {
|
||||
if (from < 0 || from > (int)macro->Actions().size() || to < 0 ||
|
||||
to > (int)macro->Actions().size()) {
|
||||
return;
|
||||
}
|
||||
{
|
||||
@@ -640,12 +354,10 @@ void AdvSceneSwitcher::MacroActionReorder(int to, int from)
|
||||
macro->Actions().erase(macro->Actions().begin() + from);
|
||||
macro->Actions().insert(macro->Actions().begin() + to, action);
|
||||
macro->UpdateActionIndices();
|
||||
ui->actionsList->ContentLayout()->insertItem(
|
||||
to, ui->actionsList->ContentLayout()->takeAt(from));
|
||||
actionsList->ContentLayout()->insertItem(
|
||||
to, actionsList->ContentLayout()->takeAt(from));
|
||||
SetActionData(*macro);
|
||||
}
|
||||
HighlightAction(to);
|
||||
emit(MacroSegmentOrderChanged());
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
#pragma once
|
||||
#include "macro-action.hpp"
|
||||
#include "filter-combo-box.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <memory>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class SwitchButton;
|
||||
|
||||
struct MacroActionInfo {
|
||||
using TCreateMethod = std::shared_ptr<MacroAction> (*)(Macro *m);
|
||||
using TCreateWidgetMethod = QWidget *(*)(QWidget *parent,
|
||||
@@ -46,20 +42,12 @@ public:
|
||||
|
||||
private slots:
|
||||
void ActionSelectionChanged(const QString &text);
|
||||
void ActionEnableChanged(bool);
|
||||
void UpdateActionState();
|
||||
|
||||
private:
|
||||
std::shared_ptr<MacroSegment> Data() const;
|
||||
void SetDisableEffect(bool);
|
||||
void SetEnableAppearance(bool);
|
||||
std::shared_ptr<MacroSegment> Data();
|
||||
|
||||
FilterComboBox *_actionSelection;
|
||||
SwitchButton *_enable;
|
||||
QComboBox *_actionSelection;
|
||||
|
||||
std::shared_ptr<MacroAction> *_entryData;
|
||||
QTimer _actionStateTimer;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
#include "macro-action-file.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QFileDialog>
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroActionFile::id = "file";
|
||||
|
||||
bool MacroActionFile::_registered = MacroActionFactory::Register(
|
||||
@@ -56,7 +55,7 @@ void MacroActionFile::LogAction() const
|
||||
bool MacroActionFile::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
_file.Save(obj, "file");
|
||||
obs_data_set_string(obj, "file", _file.c_str());
|
||||
_text.Save(obj, "text");
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
return true;
|
||||
@@ -65,7 +64,7 @@ bool MacroActionFile::Save(obs_data_t *obj) const
|
||||
bool MacroActionFile::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_file.Load(obj, "file");
|
||||
_file = obs_data_get_string(obj, "file");
|
||||
_text.Load(obj, "text");
|
||||
_action = static_cast<FileAction>(obs_data_get_int(obj, "action"));
|
||||
return true;
|
||||
@@ -73,7 +72,7 @@ bool MacroActionFile::Load(obs_data_t *obj)
|
||||
|
||||
std::string MacroActionFile::GetShortDesc() const
|
||||
{
|
||||
return _file.UnresolvedValue();
|
||||
return _file;
|
||||
}
|
||||
|
||||
static inline void populateActionSelection(QComboBox *list)
|
||||
@@ -107,7 +106,7 @@ MacroActionFileEdit::MacroActionFileEdit(
|
||||
{"{{matchText}}", _text},
|
||||
{"{{actions}}", _actions},
|
||||
};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.file.entry"),
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.file.entry"),
|
||||
entryLayout, widgetPlaceholders);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
@@ -140,7 +139,7 @@ void MacroActionFileEdit::PathChanged(const QString &text)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_file = text.toUtf8().constData();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
@@ -152,7 +151,7 @@ void MacroActionFileEdit::TextChanged()
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_text = _text->toPlainText().toStdString();
|
||||
|
||||
adjustSize();
|
||||
@@ -165,8 +164,6 @@ void MacroActionFileEdit::ActionChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_action = static_cast<FileAction>(value);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include <QSpinBox>
|
||||
|
||||
namespace advss {
|
||||
|
||||
enum class FileAction {
|
||||
WRITE,
|
||||
APPEND,
|
||||
@@ -26,8 +24,9 @@ public:
|
||||
return std::make_shared<MacroActionFile>(m);
|
||||
}
|
||||
|
||||
StringVariable _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
StringVariable _text = obs_module_text("AdvSceneSwitcher.enterText");
|
||||
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
VariableResolvingString _text =
|
||||
obs_module_text("AdvSceneSwitcher.enterText");
|
||||
FileAction _action = FileAction::WRITE;
|
||||
|
||||
private:
|
||||
@@ -67,5 +66,3 @@ protected:
|
||||
private:
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "macro-action-filter.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroActionFilter::id = "filter";
|
||||
|
||||
bool MacroActionFilter::_registered = MacroActionFactory::Register(
|
||||
@@ -15,75 +14,42 @@ const static std::map<MacroActionFilter::Action, std::string> actionTypes = {
|
||||
"AdvSceneSwitcher.action.filter.type.enable"},
|
||||
{MacroActionFilter::Action::DISABLE,
|
||||
"AdvSceneSwitcher.action.filter.type.disable"},
|
||||
{MacroActionFilter::Action::TOGGLE,
|
||||
"AdvSceneSwitcher.action.filter.type.toggle"},
|
||||
{MacroActionFilter::Action::SETTINGS,
|
||||
"AdvSceneSwitcher.action.filter.type.settings"},
|
||||
};
|
||||
|
||||
const static std::map<MacroActionFilter::SettingsInputMethod, std::string>
|
||||
inputMethods = {
|
||||
{MacroActionFilter::SettingsInputMethod::INDIVIDUAL_MANUAL,
|
||||
"AdvSceneSwitcher.action.filter.inputMethod.individualManual"},
|
||||
{MacroActionFilter::SettingsInputMethod::INDIVIDUAL_TEMPVAR,
|
||||
"AdvSceneSwitcher.action.filter.inputMethod.individualTempvar"},
|
||||
{MacroActionFilter::SettingsInputMethod::JSON_STRING,
|
||||
"AdvSceneSwitcher.action.filter.inputMethod.json"},
|
||||
};
|
||||
|
||||
static void performActionHelper(
|
||||
MacroActionFilter::Action action, const OBSWeakSource &filter,
|
||||
MacroActionFilter::SettingsInputMethod settingsInputMethod,
|
||||
const SourceSetting &setting, const std::string &manualSettingValue,
|
||||
const TempVariableRef &tempVar, Macro *macro,
|
||||
const StringVariable &settingsString)
|
||||
void MacroActionFilter::ResolveVariables()
|
||||
{
|
||||
OBSSourceAutoRelease source = obs_weak_source_get_source(filter);
|
||||
switch (action) {
|
||||
case MacroActionFilter::Action::ENABLE:
|
||||
obs_source_set_enabled(source, true);
|
||||
break;
|
||||
case MacroActionFilter::Action::DISABLE:
|
||||
obs_source_set_enabled(source, false);
|
||||
break;
|
||||
case MacroActionFilter::Action::TOGGLE:
|
||||
obs_source_set_enabled(source, !obs_source_enabled(source));
|
||||
break;
|
||||
case MacroActionFilter::Action::SETTINGS:
|
||||
switch (settingsInputMethod) {
|
||||
case MacroActionFilter::SettingsInputMethod::INDIVIDUAL_MANUAL:
|
||||
SetSourceSetting(source, setting, manualSettingValue);
|
||||
break;
|
||||
case MacroActionFilter::SettingsInputMethod::INDIVIDUAL_TEMPVAR: {
|
||||
auto var = tempVar.GetTempVariable(macro);
|
||||
if (!var) {
|
||||
break;
|
||||
}
|
||||
auto value = var->Value();
|
||||
if (!value) {
|
||||
break;
|
||||
}
|
||||
SetSourceSetting(source, setting, *value);
|
||||
break;
|
||||
}
|
||||
case MacroActionFilter::SettingsInputMethod::JSON_STRING:
|
||||
SetSourceSettings(source, settingsString);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (_source.GetType() == SourceSelection::Type::SOURCE) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name = GetWeakSourceName(_filter);
|
||||
if (!name.empty()) {
|
||||
_filterName = name;
|
||||
}
|
||||
_filter = GetWeakFilterByName(_source.GetSource(), _filterName.c_str());
|
||||
}
|
||||
|
||||
bool MacroActionFilter::PerformAction()
|
||||
{
|
||||
auto filters = _filter.GetFilters(_source);
|
||||
for (const auto &filter : filters) {
|
||||
performActionHelper(_action, filter, _settingsInputMethod,
|
||||
_setting, _manualSettingValue, _tempVar,
|
||||
GetMacro(), _settingsString);
|
||||
ResolveVariables();
|
||||
|
||||
auto s = obs_weak_source_get_source(_filter);
|
||||
switch (_action) {
|
||||
case Action::ENABLE:
|
||||
obs_source_set_enabled(s, true);
|
||||
break;
|
||||
case Action::DISABLE:
|
||||
obs_source_set_enabled(s, false);
|
||||
break;
|
||||
case Action::SETTINGS:
|
||||
setSourceSettings(s, _settings);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
obs_source_release(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -93,7 +59,7 @@ void MacroActionFilter::LogAction() const
|
||||
if (it != actionTypes.end()) {
|
||||
vblog(LOG_INFO,
|
||||
"performed action \"%s\" for filter \"%s\" on source \"%s\"",
|
||||
it->second.c_str(), _filter.ToString().c_str(),
|
||||
it->second.c_str(), GetWeakSourceName(_filter).c_str(),
|
||||
_source.ToString(true).c_str());
|
||||
} else {
|
||||
blog(LOG_WARNING, "ignored unknown filter action %d",
|
||||
@@ -105,15 +71,9 @@ bool MacroActionFilter::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
_source.Save(obj);
|
||||
_filter.Save(obj, "filter");
|
||||
obs_data_set_string(obj, "filter", _filterName.c_str());
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
obs_data_set_int(obj, "inputMethod",
|
||||
static_cast<int>(_settingsInputMethod));
|
||||
_setting.Save(obj);
|
||||
_manualSettingValue.Save(obj, "manualSettingValue");
|
||||
_tempVar.Save(obj);
|
||||
_settingsString.Save(obj, "settings");
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
_settings.Save(obj, "settings");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -121,36 +81,18 @@ bool MacroActionFilter::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_source.Load(obj);
|
||||
_filter.Load(obj, _source, "filter");
|
||||
// TODO: Remove this fallback in future version
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
const auto value = obs_data_get_int(obj, "action");
|
||||
if (value == 2) {
|
||||
_action = Action::SETTINGS;
|
||||
} else {
|
||||
_action = static_cast<Action>(value);
|
||||
}
|
||||
} else {
|
||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||
}
|
||||
// TODO: Remove fallback in future version
|
||||
if (obs_data_has_user_value(obj, "inputMethod")) {
|
||||
_settingsInputMethod = static_cast<SettingsInputMethod>(
|
||||
obs_data_get_int(obj, "inputMethod"));
|
||||
} else {
|
||||
_settingsInputMethod = SettingsInputMethod::JSON_STRING;
|
||||
}
|
||||
_setting.Load(obj);
|
||||
_settingsString.Load(obj, "settings");
|
||||
_manualSettingValue.Load(obj, "manualSettingValue");
|
||||
_tempVar.Load(obj, GetMacro());
|
||||
_filterName = obs_data_get_string(obj, "filter");
|
||||
_filter = GetWeakFilterByQString(_source.GetSource(),
|
||||
_filterName.c_str());
|
||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||
_settings.Load(obj, "settings");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroActionFilter::GetShortDesc() const
|
||||
{
|
||||
if (!_filter.ToString().empty() && !_source.ToString().empty()) {
|
||||
return _source.ToString() + " - " + _filter.ToString();
|
||||
if (_filter && !_source.ToString().empty()) {
|
||||
return _source.ToString() + " - " + GetWeakSourceName(_filter);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -162,29 +104,15 @@ static inline void populateActionSelection(QComboBox *list)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateSettingsInputMethods(QComboBox *list)
|
||||
{
|
||||
list->clear();
|
||||
for (const auto &[value, name] : inputMethods) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(value));
|
||||
}
|
||||
}
|
||||
|
||||
MacroActionFilterEdit::MacroActionFilterEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionFilter> entryData)
|
||||
: QWidget(parent),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_filters(new FilterSelectionWidget(this, _sources, true)),
|
||||
_filters(new QComboBox()),
|
||||
_actions(new QComboBox()),
|
||||
_getSettings(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.action.filter.getSettings"))),
|
||||
_settingsLayout(new QHBoxLayout()),
|
||||
_settingsInputMethods(new QComboBox(this)),
|
||||
_manualSettingValue(new VariableTextEdit(this, 5, 1, 1)),
|
||||
_tempVars(new TempVariableSelection(this)),
|
||||
_filterSettings(new SourceSettingSelection(this)),
|
||||
_settingsString(new VariableTextEdit(this))
|
||||
_settings(new VariableTextEdit(this))
|
||||
{
|
||||
_filters->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
|
||||
@@ -193,60 +121,35 @@ MacroActionFilterEdit::MacroActionFilterEdit(
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
populateSettingsInputMethods(_settingsInputMethods);
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||
SLOT(SourceChanged(const SourceSelection &)));
|
||||
QWidget::connect(_filters,
|
||||
SIGNAL(FilterChanged(const FilterSelection &)), this,
|
||||
SLOT(FilterChanged(const FilterSelection &)));
|
||||
QWidget::connect(_filters, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(FilterChanged(const QString &)));
|
||||
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
|
||||
SLOT(GetSettingsClicked()));
|
||||
QWidget::connect(_settingsString, SIGNAL(textChanged()), this,
|
||||
SLOT(SettingsStringChanged()));
|
||||
QWidget::connect(_tempVars,
|
||||
SIGNAL(SelectionChanged(const TempVariableRef &)),
|
||||
this, SLOT(SelectionChanged(const TempVariableRef &)));
|
||||
QWidget::connect(_settingsInputMethods,
|
||||
SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(SettingsInputMethodChanged(int)));
|
||||
QWidget::connect(_manualSettingValue, SIGNAL(textChanged()), this,
|
||||
SLOT(ManualSettingsValueChanged()));
|
||||
QWidget::connect(_filterSettings,
|
||||
SIGNAL(SelectionChanged(const SourceSetting &)), this,
|
||||
SLOT(SelectionChanged(const SourceSetting &)));
|
||||
QWidget::connect(_settings, SIGNAL(textChanged()), this,
|
||||
SLOT(SettingsChanged()));
|
||||
|
||||
auto entrylayout = new QHBoxLayout;
|
||||
QHBoxLayout *entryLayout = new QHBoxLayout;
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{sources}}", _sources},
|
||||
{"{{filters}}", _filters},
|
||||
{"{{actions}}", _actions},
|
||||
{"{{settings}}", _filterSettings},
|
||||
{"{{settingsInputMethod}}", _settingsInputMethods},
|
||||
{"{{settingValue}}", _manualSettingValue},
|
||||
{"{{tempVar}}", _tempVars},
|
||||
{"{{sources}}", _sources}, {"{{filters}}", _filters},
|
||||
{"{{actions}}", _actions}, {"{{settings}}", _settings},
|
||||
{"{{getSettings}}", _getSettings},
|
||||
};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.filter.entry"),
|
||||
entrylayout, widgetPlaceholders);
|
||||
_settingsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.action.filter.entry.settings"),
|
||||
_settingsLayout, widgetPlaceholders);
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.filter.entry"),
|
||||
entryLayout, widgetPlaceholders);
|
||||
|
||||
auto buttonLayout = new QHBoxLayout;
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addWidget(_getSettings);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(entrylayout);
|
||||
mainLayout->addLayout(_settingsLayout);
|
||||
mainLayout->addWidget(_settingsString);
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(entryLayout);
|
||||
mainLayout->addWidget(_settings);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
@@ -263,17 +166,15 @@ void MacroActionFilterEdit::UpdateEntryData()
|
||||
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_sources->SetSource(_entryData->_source);
|
||||
_filters->SetFilter(_entryData->_source, _entryData->_filter);
|
||||
_settingsString->setPlainText(_entryData->_settingsString);
|
||||
const auto filters =
|
||||
_entryData->_filter.GetFilters(_entryData->_source);
|
||||
_filterSettings->SetSource(filters.empty() ? nullptr : filters.at(0));
|
||||
_filterSettings->SetSetting(_entryData->_setting);
|
||||
_settingsInputMethods->setCurrentIndex(_settingsInputMethods->findData(
|
||||
static_cast<int>(_entryData->_settingsInputMethod)));
|
||||
_tempVars->SetVariable(_entryData->_tempVar);
|
||||
_manualSettingValue->setPlainText(_entryData->_manualSettingValue);
|
||||
SetWidgetVisibility();
|
||||
populateFilterSelection(_filters, _entryData->_source.GetSource());
|
||||
_filters->setCurrentText(
|
||||
GetWeakSourceName(_entryData->_filter).c_str());
|
||||
_settings->setPlainText(_entryData->_settings);
|
||||
SetWidgetVisibility(_entryData->_action ==
|
||||
MacroActionFilter::Action::SETTINGS);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::SourceChanged(const SourceSelection &source)
|
||||
@@ -281,24 +182,25 @@ void MacroActionFilterEdit::SourceChanged(const SourceSelection &source)
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_source = source;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_source = source;
|
||||
}
|
||||
_filters->clear();
|
||||
populateFilterSelection(_filters, _entryData->_source.GetSource());
|
||||
_filters->adjustSize();
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::FilterChanged(const FilterSelection &filter)
|
||||
void MacroActionFilterEdit::FilterChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
auto lock = LockContext();
|
||||
_entryData->_filter = filter;
|
||||
}
|
||||
const auto filters =
|
||||
_entryData->_filter.GetFilters(_entryData->_source);
|
||||
_filterSettings->SetSource(filters.empty() ? nullptr : filters.at(0));
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_filterName = text.toStdString();
|
||||
_entryData->_filter =
|
||||
GetWeakFilterByQString(_entryData->_source.GetSource(), text);
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
@@ -309,129 +211,39 @@ void MacroActionFilterEdit::ActionChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_action = static_cast<MacroActionFilter::Action>(value);
|
||||
SetWidgetVisibility();
|
||||
SetWidgetVisibility(_entryData->_action ==
|
||||
MacroActionFilter::Action::SETTINGS);
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::GetSettingsClicked()
|
||||
{
|
||||
if (_loading || !_entryData ||
|
||||
_entryData->_filter.GetFilters(_entryData->_source).empty()) {
|
||||
if (_loading || !_entryData || !_entryData->_source.GetSource() ||
|
||||
!_entryData->_filter) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_entryData->_settingsInputMethod) {
|
||||
case MacroActionFilter::SettingsInputMethod::INDIVIDUAL_MANUAL: {
|
||||
const auto filters =
|
||||
_entryData->_filter.GetFilters(_entryData->_source);
|
||||
_manualSettingValue->setPlainText(GetSourceSettingValue(
|
||||
filters.empty() ? nullptr : filters.at(0),
|
||||
_entryData->_setting));
|
||||
break;
|
||||
}
|
||||
case MacroActionFilter::SettingsInputMethod::INDIVIDUAL_TEMPVAR:
|
||||
break;
|
||||
case MacroActionFilter::SettingsInputMethod::JSON_STRING: {
|
||||
const auto filters =
|
||||
_entryData->_filter.GetFilters(_entryData->_source);
|
||||
_settingsString->setPlainText(
|
||||
FormatJsonString(GetSourceSettings(
|
||||
filters.empty() ? nullptr : filters.at(0))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
_settings->setPlainText(
|
||||
formatJsonString(getSourceSettings(_entryData->_filter)));
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::SettingsStringChanged()
|
||||
void MacroActionFilterEdit::SettingsChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_settingsString =
|
||||
_settingsString->toPlainText().toStdString();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_settings = _settings->toPlainText().toStdString();
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::SettingsInputMethodChanged(int idx)
|
||||
void MacroActionFilterEdit::SetWidgetVisibility(bool showSettings)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_settingsInputMethod =
|
||||
static_cast<MacroActionFilter::SettingsInputMethod>(
|
||||
_settingsInputMethods->itemData(idx).toInt());
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::SelectionChanged(const TempVariableRef &var)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_tempVar = var;
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::SelectionChanged(const SourceSetting &setting)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_setting = setting;
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::ManualSettingsValueChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_manualSettingValue =
|
||||
_manualSettingValue->toPlainText().toStdString();
|
||||
|
||||
_settings->setVisible(showSettings);
|
||||
_getSettings->setVisible(showSettings);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionFilterEdit::SetWidgetVisibility()
|
||||
{
|
||||
SetLayoutVisible(_settingsLayout,
|
||||
_entryData->_action ==
|
||||
MacroActionFilter::Action::SETTINGS);
|
||||
_filterSettings->setVisible(
|
||||
_entryData->_action == MacroActionFilter::Action::SETTINGS &&
|
||||
_entryData->_settingsInputMethod !=
|
||||
MacroActionFilter::SettingsInputMethod::JSON_STRING);
|
||||
_settingsString->setVisible(
|
||||
_entryData->_action == MacroActionFilter::Action::SETTINGS &&
|
||||
_entryData->_settingsInputMethod ==
|
||||
MacroActionFilter::SettingsInputMethod::JSON_STRING);
|
||||
_getSettings->setVisible(_entryData->_action ==
|
||||
MacroActionFilter::Action::SETTINGS);
|
||||
_tempVars->setVisible(_entryData->_action ==
|
||||
MacroActionFilter::Action::SETTINGS &&
|
||||
_entryData->_settingsInputMethod ==
|
||||
MacroActionFilter::SettingsInputMethod::
|
||||
INDIVIDUAL_TEMPVAR);
|
||||
_manualSettingValue->setVisible(
|
||||
_entryData->_action == MacroActionFilter::Action::SETTINGS &&
|
||||
_entryData->_settingsInputMethod ==
|
||||
MacroActionFilter::SettingsInputMethod::
|
||||
INDIVIDUAL_MANUAL);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -2,15 +2,11 @@
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
#include "source-selection.hpp"
|
||||
#include "filter-selection.hpp"
|
||||
#include "source-setting.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QSpinBox>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroActionFilter : public MacroAction {
|
||||
public:
|
||||
MacroActionFilter(Macro *m) : MacroAction(m) {}
|
||||
@@ -28,29 +24,22 @@ public:
|
||||
enum class Action {
|
||||
ENABLE,
|
||||
DISABLE,
|
||||
TOGGLE,
|
||||
SETTINGS,
|
||||
};
|
||||
|
||||
enum class SettingsInputMethod {
|
||||
INDIVIDUAL_MANUAL,
|
||||
INDIVIDUAL_TEMPVAR,
|
||||
JSON_STRING,
|
||||
};
|
||||
SettingsInputMethod _settingsInputMethod =
|
||||
SettingsInputMethod::INDIVIDUAL_MANUAL;
|
||||
|
||||
SourceSelection _source;
|
||||
FilterSelection _filter;
|
||||
OBSWeakSource _filter;
|
||||
Action _action = Action::ENABLE;
|
||||
StringVariable _settingsString = "";
|
||||
TempVariableRef _tempVar;
|
||||
StringVariable _manualSettingValue = "";
|
||||
SourceSetting _setting;
|
||||
VariableResolvingString _settings = "";
|
||||
|
||||
private:
|
||||
void ResolveVariables();
|
||||
std::string _filterName = "";
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
|
||||
friend class MacroActionFilterEdit;
|
||||
};
|
||||
|
||||
class MacroActionFilterEdit : public QWidget {
|
||||
@@ -71,34 +60,22 @@ public:
|
||||
|
||||
private slots:
|
||||
void SourceChanged(const SourceSelection &);
|
||||
void FilterChanged(const FilterSelection &);
|
||||
void FilterChanged(const QString &);
|
||||
void ActionChanged(int value);
|
||||
void GetSettingsClicked();
|
||||
void SettingsStringChanged();
|
||||
void SettingsInputMethodChanged(int);
|
||||
void SelectionChanged(const TempVariableRef &);
|
||||
void SelectionChanged(const SourceSetting &);
|
||||
void ManualSettingsValueChanged();
|
||||
void SettingsChanged();
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
protected:
|
||||
SourceSelectionWidget *_sources;
|
||||
FilterSelectionWidget *_filters;
|
||||
QComboBox *_filters;
|
||||
QComboBox *_actions;
|
||||
QPushButton *_getSettings;
|
||||
QHBoxLayout *_settingsLayout;
|
||||
QComboBox *_settingsInputMethods;
|
||||
VariableTextEdit *_manualSettingValue;
|
||||
TempVariableSelection *_tempVars;
|
||||
SourceSettingSelection *_filterSettings;
|
||||
VariableTextEdit *_settingsString;
|
||||
|
||||
VariableTextEdit *_settings;
|
||||
std::shared_ptr<MacroActionFilter> _entryData;
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
void SetWidgetVisibility(bool);
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
#include "macro-action-hotkey.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <obs-interaction.h>
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroActionHotkey::id = "hotkey";
|
||||
|
||||
bool MacroActionHotkey::_registered = MacroActionFactory::Register(
|
||||
@@ -14,26 +10,6 @@ bool MacroActionHotkey::_registered = MacroActionFactory::Register(
|
||||
{MacroActionHotkey::Create, MacroActionHotkeyEdit::Create,
|
||||
"AdvSceneSwitcher.action.hotkey"});
|
||||
|
||||
const static std::map<MacroActionHotkey::Action, std::string> actionTypes = {
|
||||
{MacroActionHotkey::Action::OBS_HOTKEY,
|
||||
"AdvSceneSwitcher.action.hotkey.type.obs"},
|
||||
{MacroActionHotkey::Action::CUSTOM,
|
||||
"AdvSceneSwitcher.action.hotkey.type.custom"},
|
||||
};
|
||||
|
||||
const static std::map<obs_hotkey_registerer_type, std::string> hotkeyTypes = {
|
||||
{OBS_HOTKEY_REGISTERER_FRONTEND,
|
||||
"AdvSceneSwitcher.action.hotkey.type.obs.type.frontend"},
|
||||
{OBS_HOTKEY_REGISTERER_SOURCE,
|
||||
"AdvSceneSwitcher.action.hotkey.type.obs.type.soruce"},
|
||||
{OBS_HOTKEY_REGISTERER_OUTPUT,
|
||||
"AdvSceneSwitcher.action.hotkey.type.obs.type.output"},
|
||||
{OBS_HOTKEY_REGISTERER_ENCODER,
|
||||
"AdvSceneSwitcher.action.hotkey.type.obs.type.encoder"},
|
||||
{OBS_HOTKEY_REGISTERER_SERVICE,
|
||||
"AdvSceneSwitcher.action.hotkey.type.obs.type.service"},
|
||||
};
|
||||
|
||||
static std::unordered_map<HotkeyType, long> keyTable = {
|
||||
// Chars
|
||||
{HotkeyType::Key_A, OBS_KEY_A},
|
||||
@@ -154,8 +130,7 @@ static std::unordered_map<HotkeyType, long> keyTable = {
|
||||
//{HotkeyType::Key_NumpadEnter, ???},
|
||||
};
|
||||
|
||||
static obs_key_combination
|
||||
keysToOBSKeycombo(const std::vector<HotkeyType> &keys)
|
||||
obs_key_combination keysToOBSKeycombo(const std::vector<HotkeyType> &keys)
|
||||
{
|
||||
obs_key_combination combo{};
|
||||
auto it = keyTable.find(keys.back());
|
||||
@@ -203,7 +178,7 @@ keysToOBSKeycombo(const std::vector<HotkeyType> &keys)
|
||||
return combo;
|
||||
}
|
||||
|
||||
static void InjectKeys(const std::vector<HotkeyType> &keys, int duration)
|
||||
void InjectKeys(const std::vector<HotkeyType> &keys, int duration)
|
||||
{
|
||||
auto combo = keysToOBSKeycombo(keys);
|
||||
if (obs_key_combination_is_empty(combo)) {
|
||||
@@ -217,92 +192,7 @@ static void InjectKeys(const std::vector<HotkeyType> &keys, int duration)
|
||||
obs_hotkey_inject_event(combo, false);
|
||||
}
|
||||
|
||||
static void addNamePrefix(std::string &name, obs_hotkey_t *hotkey)
|
||||
{
|
||||
const auto type = obs_hotkey_get_registerer_type(hotkey);
|
||||
std::string prefix;
|
||||
if (type == OBS_HOTKEY_REGISTERER_SOURCE) {
|
||||
auto source = reinterpret_cast<obs_weak_source_t *>(
|
||||
obs_hotkey_get_registerer(hotkey));
|
||||
prefix = "[" + GetWeakSourceName(source) + "] ";
|
||||
} else if (type == OBS_HOTKEY_REGISTERER_OUTPUT) {
|
||||
auto weakOutput = reinterpret_cast<obs_weak_output_t *>(
|
||||
obs_hotkey_get_registerer(hotkey));
|
||||
std::string name;
|
||||
auto output = obs_weak_output_get_output(weakOutput);
|
||||
if (output) {
|
||||
name = obs_output_get_name(output);
|
||||
obs_output_release(output);
|
||||
}
|
||||
prefix = "[" + name + "] ";
|
||||
} else if (type == OBS_HOTKEY_REGISTERER_ENCODER) {
|
||||
auto weakEncoder = reinterpret_cast<obs_weak_encoder_t *>(
|
||||
obs_hotkey_get_registerer(hotkey));
|
||||
std::string name;
|
||||
auto encoder = obs_weak_encoder_get_encoder(weakEncoder);
|
||||
if (encoder) {
|
||||
name = obs_encoder_get_name(encoder);
|
||||
obs_encoder_release(encoder);
|
||||
}
|
||||
prefix = "[" + name + "] ";
|
||||
} else if (type == OBS_HOTKEY_REGISTERER_SERVICE) {
|
||||
auto weakService = reinterpret_cast<obs_weak_service_t *>(
|
||||
obs_hotkey_get_registerer(hotkey));
|
||||
std::string name;
|
||||
auto service = obs_weak_service_get_service(weakService);
|
||||
if (service) {
|
||||
name = obs_service_get_name(service);
|
||||
obs_service_release(service);
|
||||
}
|
||||
prefix = "[" + name + "] ";
|
||||
}
|
||||
name = prefix + name;
|
||||
}
|
||||
|
||||
static obs_hotkey_id getHotkeyIdByName(const std::string &name)
|
||||
{
|
||||
struct Parameters {
|
||||
std::string name;
|
||||
obs_hotkey_id id = OBS_INVALID_HOTKEY_ID;
|
||||
} params;
|
||||
|
||||
auto func = [](void *param, obs_hotkey_id id, obs_hotkey_t *hotkey) {
|
||||
auto params = static_cast<Parameters *>(param);
|
||||
std::string name = obs_hotkey_get_name(hotkey);
|
||||
addNamePrefix(name, hotkey);
|
||||
if (name == params->name) {
|
||||
params->id = id;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
params.name = name;
|
||||
obs_enum_hotkeys(func, ¶ms);
|
||||
return params.id;
|
||||
}
|
||||
|
||||
void MacroActionHotkey::SendOBSHotkey()
|
||||
{
|
||||
auto id = getHotkeyIdByName(_hotkeyName);
|
||||
if (id == OBS_INVALID_HOTKEY_ID) {
|
||||
blog(LOG_WARNING,
|
||||
"failed to get hotkey id for \"%s\" - key will not be pressed",
|
||||
_hotkeyName.c_str());
|
||||
return;
|
||||
}
|
||||
obs_queue_task(
|
||||
OBS_TASK_UI,
|
||||
[](void *param) {
|
||||
auto id = (size_t *)param;
|
||||
obs_hotkey_trigger_routed_callback(*id, false);
|
||||
obs_hotkey_trigger_routed_callback(*id, true);
|
||||
obs_hotkey_trigger_routed_callback(*id, false);
|
||||
},
|
||||
&id, true);
|
||||
}
|
||||
|
||||
void MacroActionHotkey::SendCustomHotkey()
|
||||
bool MacroActionHotkey::PerformAction()
|
||||
{
|
||||
std::vector<HotkeyType> keys;
|
||||
if (_leftShift) {
|
||||
@@ -334,7 +224,7 @@ void MacroActionHotkey::SendCustomHotkey()
|
||||
}
|
||||
|
||||
if (!keys.empty()) {
|
||||
int dur = _duration.Milliseconds();
|
||||
int dur = _duration;
|
||||
if (_onlySendToObs || !canSimulateKeyPresses) {
|
||||
std::thread t([keys, dur]() { InjectKeys(keys, dur); });
|
||||
t.detach();
|
||||
@@ -343,35 +233,18 @@ void MacroActionHotkey::SendCustomHotkey()
|
||||
t.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MacroActionHotkey::PerformAction()
|
||||
{
|
||||
switch (_action) {
|
||||
case advss::MacroActionHotkey::Action::OBS_HOTKEY:
|
||||
SendOBSHotkey();
|
||||
break;
|
||||
case advss::MacroActionHotkey::Action::CUSTOM:
|
||||
SendCustomHotkey();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroActionHotkey::LogAction() const
|
||||
{
|
||||
vblog(LOG_INFO, "sent hotkey type %d", static_cast<int>(_action));
|
||||
vblog(LOG_INFO, "sent hotkey");
|
||||
}
|
||||
|
||||
bool MacroActionHotkey::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
obs_data_set_int(obj, "hotkeyType", _hotkeyType);
|
||||
obs_data_set_string(obj, "hotkeyName", _hotkeyName.c_str());
|
||||
obs_data_set_int(obj, "key", static_cast<int>(_key));
|
||||
obs_data_set_bool(obj, "left_shift", _leftShift);
|
||||
obs_data_set_bool(obj, "right_shift", _rightShift);
|
||||
@@ -381,24 +254,14 @@ 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);
|
||||
_duration.Save(obj);
|
||||
obs_data_set_int(obj, "duration", _duration);
|
||||
obs_data_set_bool(obj, "onlyOBS", _onlySendToObs);
|
||||
obs_data_set_int(obj, "version", 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroActionHotkey::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
int version = obs_data_get_int(obj, "version");
|
||||
if (version != 2) {
|
||||
_action = Action::CUSTOM;
|
||||
} else {
|
||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||
}
|
||||
_hotkeyType = static_cast<obs_hotkey_registerer_type>(
|
||||
obs_data_get_int(obj, "hotkeyType"));
|
||||
_hotkeyName = obs_data_get_string(obj, "hotkeyName");
|
||||
_key = static_cast<HotkeyType>(obs_data_get_int(obj, "key"));
|
||||
_leftShift = obs_data_get_bool(obj, "left_shift");
|
||||
_rightShift = obs_data_get_bool(obj, "right_shift");
|
||||
@@ -408,11 +271,7 @@ 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");
|
||||
if (version == 0) {
|
||||
_duration = obs_data_get_int(obj, "duration") / 1000.0;
|
||||
} else {
|
||||
_duration.Load(obj);
|
||||
}
|
||||
_duration = obs_data_get_int(obj, "duration");
|
||||
_onlySendToObs = obs_data_get_bool(obj, "onlyOBS");
|
||||
return true;
|
||||
}
|
||||
@@ -527,100 +386,36 @@ static inline void populateKeySelection(QComboBox *list)
|
||||
list->addItem("NumpadEnter");
|
||||
}
|
||||
|
||||
static void populateActionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[_, value] : actionTypes) {
|
||||
list->addItem(obs_module_text(value.c_str()));
|
||||
}
|
||||
}
|
||||
static void populateHotkeyTypeSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[_, value] : hotkeyTypes) {
|
||||
list->addItem(obs_module_text(value.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
static void addNamePrefix(QString &name, obs_hotkey_t *hotkey)
|
||||
{
|
||||
auto temp = name.toStdString();
|
||||
addNamePrefix(temp, hotkey);
|
||||
name = QString::fromStdString(temp);
|
||||
}
|
||||
|
||||
static void populateHotkeyNames(QComboBox *list,
|
||||
obs_hotkey_registerer_type type)
|
||||
{
|
||||
struct Parameters {
|
||||
QStringList names;
|
||||
QStringList descriptions;
|
||||
obs_hotkey_registerer_type type;
|
||||
} params;
|
||||
|
||||
auto func = [](void *param, obs_hotkey_id, obs_hotkey_t *hotkey) {
|
||||
auto params = static_cast<Parameters *>(param);
|
||||
if (obs_hotkey_get_registerer_type(hotkey) == params->type) {
|
||||
QString description(obs_hotkey_get_description(hotkey));
|
||||
addNamePrefix(description, hotkey);
|
||||
params->descriptions.append(description);
|
||||
QString name(obs_hotkey_get_name(hotkey));
|
||||
addNamePrefix(name, hotkey);
|
||||
params->names.append(name);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
params.type = type;
|
||||
obs_enum_hotkeys(func, ¶ms);
|
||||
|
||||
list->clear();
|
||||
for (int i = 0; i < params.names.size(); i++) {
|
||||
list->addItem(params.descriptions.at(i), params.names.at(i));
|
||||
}
|
||||
AddSelectionEntry(list,
|
||||
obs_module_text("AdvSceneSwitcher.selectHotkey"));
|
||||
}
|
||||
|
||||
MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData)
|
||||
: QWidget(parent),
|
||||
_actionType(new QComboBox()),
|
||||
_hotkeyType(new QComboBox()),
|
||||
_obsHotkeys(new QComboBox()),
|
||||
_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"))),
|
||||
_entryLayout(new QHBoxLayout()),
|
||||
_keyConfigLayout(new QHBoxLayout())
|
||||
: QWidget(parent)
|
||||
{
|
||||
populateKeySelection(_keys);
|
||||
populateActionSelection(_actionType);
|
||||
populateHotkeyTypeSelection(_hotkeyType);
|
||||
_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(_actionType, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_hotkeyType, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(HotkeyTypeChanged(int)));
|
||||
QWidget::connect(_obsHotkeys, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(OBSHotkeyChanged(int)));
|
||||
QWidget::connect(_keys, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(KeyChanged(int)));
|
||||
QWidget::connect(_leftShift, SIGNAL(stateChanged(int)), this,
|
||||
@@ -639,26 +434,33 @@ MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
||||
SLOT(LMetaChanged(int)));
|
||||
QWidget::connect(_rightMeta, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(RMetaChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
QWidget::connect(_duration, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(DurationChanged(int)));
|
||||
QWidget::connect(_onlySendToOBS, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(OnlySendToOBSChanged(int)));
|
||||
|
||||
_entryLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_keyConfigLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_keyConfigLayout->addWidget(_leftShift);
|
||||
_keyConfigLayout->addWidget(_rightShift);
|
||||
_keyConfigLayout->addWidget(_leftCtrl);
|
||||
_keyConfigLayout->addWidget(_rightCtrl);
|
||||
_keyConfigLayout->addWidget(_leftAlt);
|
||||
_keyConfigLayout->addWidget(_rightAlt);
|
||||
_keyConfigLayout->addWidget(_leftMeta);
|
||||
_keyConfigLayout->addWidget(_rightMeta);
|
||||
_keyConfigLayout->addStretch();
|
||||
QHBoxLayout *line1Layout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{keys}}", _keys},
|
||||
{"{{duration}}", _duration},
|
||||
};
|
||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.hotkey.entry"),
|
||||
line1Layout, widgetPlaceholders);
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(_entryLayout);
|
||||
mainLayout->addLayout(_keyConfigLayout);
|
||||
QHBoxLayout *line2Layout = new QHBoxLayout;
|
||||
line2Layout->addWidget(_leftShift);
|
||||
line2Layout->addWidget(_rightShift);
|
||||
line2Layout->addWidget(_leftCtrl);
|
||||
line2Layout->addWidget(_rightCtrl);
|
||||
line2Layout->addWidget(_leftAlt);
|
||||
line2Layout->addWidget(_rightAlt);
|
||||
line2Layout->addWidget(_leftMeta);
|
||||
line2Layout->addWidget(_rightMeta);
|
||||
line2Layout->addStretch();
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(line1Layout);
|
||||
mainLayout->addLayout(line2Layout);
|
||||
mainLayout->addWidget(_onlySendToOBS);
|
||||
mainLayout->addWidget(_noKeyPressSimulationWarning);
|
||||
setLayout(mainLayout);
|
||||
@@ -670,76 +472,10 @@ MacroActionHotkeyEdit::MacroActionHotkeyEdit(
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::RepopulateOBSHotkeySelection()
|
||||
void MacroActionHotkeyEdit::SetWarningVisibility()
|
||||
{
|
||||
populateHotkeyNames(_obsHotkeys, _entryData->_hotkeyType);
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::SetWidgetVisibility()
|
||||
{
|
||||
_entryLayout->removeWidget(_actionType);
|
||||
_entryLayout->removeWidget(_hotkeyType);
|
||||
_entryLayout->removeWidget(_obsHotkeys);
|
||||
_entryLayout->removeWidget(_keys);
|
||||
_entryLayout->removeWidget(_duration);
|
||||
ClearLayout(_entryLayout);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
_entryData->_action ==
|
||||
MacroActionHotkey::Action::OBS_HOTKEY
|
||||
? "AdvSceneSwitcher.action.hotkey.entry.obs"
|
||||
: "AdvSceneSwitcher.action.hotkey.entry.custom"),
|
||||
_entryLayout,
|
||||
{
|
||||
{"{{actionType}}", _actionType},
|
||||
{"{{hotkeyType}}", _hotkeyType},
|
||||
{"{{obsHotkeys}}", _obsHotkeys},
|
||||
{"{{keys}}", _keys},
|
||||
{"{{duration}}", _duration},
|
||||
});
|
||||
|
||||
_noKeyPressSimulationWarning->setVisible(!_entryData->_onlySendToObs &&
|
||||
!canSimulateKeyPresses);
|
||||
SetLayoutVisible(_keyConfigLayout,
|
||||
_entryData->_action ==
|
||||
MacroActionHotkey::Action::CUSTOM);
|
||||
_duration->setVisible(_entryData->_action ==
|
||||
MacroActionHotkey::Action::CUSTOM);
|
||||
_keys->setVisible(_entryData->_action ==
|
||||
MacroActionHotkey::Action::CUSTOM);
|
||||
_onlySendToOBS->setVisible(_entryData->_action ==
|
||||
MacroActionHotkey::Action::CUSTOM);
|
||||
_hotkeyType->setVisible(_entryData->_action ==
|
||||
MacroActionHotkey::Action::OBS_HOTKEY);
|
||||
_obsHotkeys->setVisible(_entryData->_action ==
|
||||
MacroActionHotkey::Action::OBS_HOTKEY);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
static QString getHotkeyDescriptionByName(const std::string &name)
|
||||
{
|
||||
struct Parameters {
|
||||
std::string name;
|
||||
QString description = "";
|
||||
} params;
|
||||
|
||||
auto func = [](void *param, obs_hotkey_id, obs_hotkey_t *hotkey) {
|
||||
auto params = static_cast<Parameters *>(param);
|
||||
std::string name = obs_hotkey_get_name(hotkey);
|
||||
addNamePrefix(name, hotkey);
|
||||
if (name == params->name) {
|
||||
params->description =
|
||||
obs_hotkey_get_description(hotkey);
|
||||
addNamePrefix(params->description, hotkey);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
params.name = name;
|
||||
obs_enum_hotkeys(func, ¶ms);
|
||||
return params.description;
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::UpdateEntryData()
|
||||
@@ -748,11 +484,6 @@ void MacroActionHotkeyEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_actionType->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_hotkeyType->setCurrentIndex(static_cast<int>(_entryData->_hotkeyType));
|
||||
RepopulateOBSHotkeySelection();
|
||||
_obsHotkeys->setCurrentText(
|
||||
getHotkeyDescriptionByName(_entryData->_hotkeyName));
|
||||
_keys->setCurrentIndex(static_cast<int>(_entryData->_key));
|
||||
_leftShift->setChecked(_entryData->_leftShift);
|
||||
_rightShift->setChecked(_entryData->_rightShift);
|
||||
@@ -762,10 +493,10 @@ void MacroActionHotkeyEdit::UpdateEntryData()
|
||||
_rightAlt->setChecked(_entryData->_rightAlt);
|
||||
_leftMeta->setChecked(_entryData->_leftMeta);
|
||||
_rightMeta->setChecked(_entryData->_rightMeta);
|
||||
_duration->SetDuration(_entryData->_duration);
|
||||
_duration->setValue(_entryData->_duration);
|
||||
_onlySendToOBS->setChecked(_entryData->_onlySendToObs ||
|
||||
!canSimulateKeyPresses);
|
||||
SetWidgetVisibility();
|
||||
SetWarningVisibility();
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::LShiftChanged(int state)
|
||||
@@ -774,7 +505,7 @@ void MacroActionHotkeyEdit::LShiftChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_leftShift = state;
|
||||
}
|
||||
|
||||
@@ -784,7 +515,7 @@ void MacroActionHotkeyEdit::RShiftChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_rightShift = state;
|
||||
}
|
||||
|
||||
@@ -794,7 +525,7 @@ void MacroActionHotkeyEdit::LCtrlChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_leftCtrl = state;
|
||||
}
|
||||
|
||||
@@ -804,7 +535,7 @@ void MacroActionHotkeyEdit::RCtrlChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_rightCtrl = state;
|
||||
}
|
||||
|
||||
@@ -814,7 +545,7 @@ void MacroActionHotkeyEdit::LAltChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_leftAlt = state;
|
||||
}
|
||||
|
||||
@@ -824,7 +555,7 @@ void MacroActionHotkeyEdit::RAltChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_rightAlt = state;
|
||||
}
|
||||
|
||||
@@ -834,7 +565,7 @@ void MacroActionHotkeyEdit::LMetaChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_leftMeta = state;
|
||||
}
|
||||
|
||||
@@ -844,18 +575,18 @@ void MacroActionHotkeyEdit::RMetaChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_rightMeta = state;
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::DurationChanged(const Duration &dur)
|
||||
void MacroActionHotkeyEdit::DurationChanged(int ms)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_duration = dur;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_duration = ms;
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::OnlySendToOBSChanged(int state)
|
||||
@@ -864,9 +595,9 @@ void MacroActionHotkeyEdit::OnlySendToOBSChanged(int state)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_onlySendToObs = state;
|
||||
SetWidgetVisibility();
|
||||
SetWarningVisibility();
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::KeyChanged(int key)
|
||||
@@ -875,47 +606,6 @@ void MacroActionHotkeyEdit::KeyChanged(int key)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_key = static_cast<HotkeyType>(key);
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::ActionChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_action = static_cast<MacroActionHotkey::Action>(value);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::HotkeyTypeChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
{
|
||||
auto lock = LockContext();
|
||||
_entryData->_hotkeyType =
|
||||
static_cast<obs_hotkey_registerer_type>(value);
|
||||
}
|
||||
RepopulateOBSHotkeySelection();
|
||||
}
|
||||
|
||||
void MacroActionHotkeyEdit::OBSHotkeyChanged(int idx)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
if (idx == -1) {
|
||||
_entryData->_hotkeyName = "";
|
||||
return;
|
||||
}
|
||||
_entryData->_hotkeyName =
|
||||
_obsHotkeys->itemData(idx).toString().toStdString();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "hotkey.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroActionHotkey : public MacroAction {
|
||||
public:
|
||||
MacroActionHotkey(Macro *m) : MacroAction(m) {}
|
||||
@@ -23,15 +20,7 @@ public:
|
||||
return std::make_shared<MacroActionHotkey>(m);
|
||||
}
|
||||
|
||||
enum class Action {
|
||||
OBS_HOTKEY,
|
||||
CUSTOM,
|
||||
};
|
||||
Action _action = Action::OBS_HOTKEY;
|
||||
|
||||
obs_hotkey_registerer_type _hotkeyType = OBS_HOTKEY_REGISTERER_FRONTEND;
|
||||
std::string _hotkeyName;
|
||||
|
||||
OBSWeakSource _HotkeySource;
|
||||
HotkeyType _key = HotkeyType::Key_NoKey;
|
||||
bool _leftShift = false;
|
||||
bool _rightShift = false;
|
||||
@@ -41,7 +30,7 @@ public:
|
||||
bool _rightAlt = false;
|
||||
bool _leftMeta = false;
|
||||
bool _rightMeta = false;
|
||||
Duration _duration = 0.3;
|
||||
int _duration = 300; // in ms
|
||||
#ifdef __APPLE__
|
||||
bool _onlySendToObs = true;
|
||||
#else
|
||||
@@ -49,9 +38,6 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
void SendOBSHotkey();
|
||||
void SendCustomHotkey();
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
@@ -73,9 +59,6 @@ public:
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ActionChanged(int key);
|
||||
void HotkeyTypeChanged(int key);
|
||||
void OBSHotkeyChanged(int);
|
||||
void KeyChanged(int key);
|
||||
void LShiftChanged(int state);
|
||||
void RShiftChanged(int state);
|
||||
@@ -85,13 +68,10 @@ private slots:
|
||||
void RAltChanged(int state);
|
||||
void LMetaChanged(int state);
|
||||
void RMetaChanged(int state);
|
||||
void DurationChanged(const Duration &);
|
||||
void DurationChanged(int ms);
|
||||
void OnlySendToOBSChanged(int state);
|
||||
|
||||
protected:
|
||||
QComboBox *_actionType;
|
||||
QComboBox *_hotkeyType;
|
||||
QComboBox *_obsHotkeys;
|
||||
QComboBox *_keys;
|
||||
QCheckBox *_leftShift;
|
||||
QCheckBox *_rightShift;
|
||||
@@ -101,19 +81,14 @@ protected:
|
||||
QCheckBox *_rightAlt;
|
||||
QCheckBox *_leftMeta;
|
||||
QCheckBox *_rightMeta;
|
||||
DurationSelection *_duration;
|
||||
QSpinBox *_duration;
|
||||
QCheckBox *_onlySendToOBS;
|
||||
QLabel *_noKeyPressSimulationWarning;
|
||||
|
||||
std::shared_ptr<MacroActionHotkey> _entryData;
|
||||
|
||||
private:
|
||||
void RepopulateOBSHotkeySelection();
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QHBoxLayout *_entryLayout;
|
||||
QHBoxLayout *_keyConfigLayout;
|
||||
void SetWarningVisibility();
|
||||
QHBoxLayout *_mainLayout;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
#include "macro-action-http.hpp"
|
||||
#include "switcher-data.hpp"
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "curl-helper.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroActionHttp::id = "http";
|
||||
|
||||
bool MacroActionHttp::_registered = MacroActionFactory::Register(
|
||||
@@ -18,37 +16,22 @@ const static std::map<MacroActionHttp::Method, std::string> methods = {
|
||||
"AdvSceneSwitcher.action.http.type.post"},
|
||||
};
|
||||
|
||||
static size_t DropCB(void *, size_t size, size_t nmemb, std::string *)
|
||||
size_t DropCB(void *, size_t size, size_t nmemb, std::string *)
|
||||
{
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
static size_t WriteCB(void *ptr, size_t size, size_t nmemb, std::string *buffer)
|
||||
size_t WriteCB(void *ptr, size_t size, size_t nmemb, std::string *buffer)
|
||||
{
|
||||
buffer->append((char *)ptr, nmemb);
|
||||
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.Milliseconds());
|
||||
SetupHeaders();
|
||||
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.seconds * 1000);
|
||||
|
||||
std::string response;
|
||||
if (IsReferencedInVars()) {
|
||||
@@ -66,8 +49,7 @@ 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.Milliseconds());
|
||||
SetupHeaders();
|
||||
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.seconds * 1000);
|
||||
switcher->curl.Perform();
|
||||
}
|
||||
|
||||
@@ -108,10 +90,8 @@ void MacroActionHttp::LogAction() const
|
||||
bool MacroActionHttp::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
_url.Save(obj, "url");
|
||||
obs_data_set_string(obj, "url", _url.c_str());
|
||||
_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;
|
||||
@@ -120,10 +100,8 @@ bool MacroActionHttp::Save(obs_data_t *obj) const
|
||||
bool MacroActionHttp::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_url.Load(obj, "url");
|
||||
_url = obs_data_get_string(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;
|
||||
@@ -131,7 +109,7 @@ bool MacroActionHttp::Load(obs_data_t *obj)
|
||||
|
||||
std::string MacroActionHttp::GetShortDesc() const
|
||||
{
|
||||
return _url.UnresolvedValue();
|
||||
return _url;
|
||||
}
|
||||
|
||||
static inline void populateMethodSelection(QComboBox *list)
|
||||
@@ -144,19 +122,12 @@ static inline void populateMethodSelection(QComboBox *list)
|
||||
MacroActionHttpEdit::MacroActionHttpEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionHttp> entryData)
|
||||
: QWidget(parent),
|
||||
_url(new VariableLineEdit(this)),
|
||||
_url(new QLineEdit()),
|
||||
_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);
|
||||
_headerList->SetMaxStringSize(4096);
|
||||
|
||||
QWidget::connect(_url, SIGNAL(editingFinished()), this,
|
||||
SLOT(URLChanged()));
|
||||
@@ -164,13 +135,8 @@ MacroActionHttpEdit::MacroActionHttpEdit(
|
||||
SLOT(DataChanged()));
|
||||
QWidget::connect(_methods, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(MethodChanged(int)));
|
||||
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 &)));
|
||||
QWidget::connect(_timeout, SIGNAL(DurationChanged(double)), this,
|
||||
SLOT(TimeoutChanged(double)));
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{url}}", _url},
|
||||
@@ -179,22 +145,16 @@ MacroActionHttpEdit::MacroActionHttpEdit(
|
||||
{"{{timeout}}", _timeout},
|
||||
};
|
||||
auto *actionLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.action.http.entry.line1"),
|
||||
actionLayout, widgetPlaceholders);
|
||||
auto *timeoutLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
placeWidgets(
|
||||
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);
|
||||
@@ -210,10 +170,8 @@ void MacroActionHttpEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_url->setText(_entryData->_url);
|
||||
_url->setText(QString::fromStdString(_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();
|
||||
@@ -225,7 +183,7 @@ void MacroActionHttpEdit::URLChanged()
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_url = _url->text().toStdString();
|
||||
emit(HeaderInfoChanged(_url->text()));
|
||||
}
|
||||
@@ -236,48 +194,33 @@ void MacroActionHttpEdit::MethodChanged(int value)
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_method = static_cast<MacroActionHttp::Method>(value);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::TimeoutChanged(const Duration &dur)
|
||||
void MacroActionHttpEdit::TimeoutChanged(double seconds)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_timeout = dur;
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::SetHeadersChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_setHeaders = value;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::HeadersChanged(const StringList &headers)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_headers = headers;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_timeout.seconds = seconds;
|
||||
}
|
||||
|
||||
void MacroActionHttpEdit::SetWidgetVisibility()
|
||||
{
|
||||
_data->setVisible(_entryData->_method == MacroActionHttp::Method::POST);
|
||||
SetLayoutVisible(_headerListLayout, _entryData->_setHeaders);
|
||||
switch (_entryData->_method) {
|
||||
case MacroActionHttp::Method::GET:
|
||||
_data->hide();
|
||||
break;
|
||||
case MacroActionHttp::Method::POST:
|
||||
_data->show();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
@@ -289,11 +232,9 @@ void MacroActionHttpEdit::DataChanged()
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
_entryData->_data = _data->toPlainText().toUtf8().constData();
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||