mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-07 09:05:57 -05:00
Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21a00d47cc | ||
|
|
3805aaeeec | ||
|
|
50dc404689 | ||
|
|
975eacbc7e | ||
|
|
7e56dc35b8 | ||
|
|
b3566d98bf | ||
|
|
15379a8e20 | ||
|
|
1e178f4223 | ||
|
|
c16a7b93ea | ||
|
|
f89bb1a750 | ||
|
|
79961aabe4 | ||
|
|
4686fc2b01 | ||
|
|
569b915c07 | ||
|
|
324d3fe7a5 | ||
|
|
ae8d0bf5cb | ||
|
|
17efa82057 | ||
|
|
c17523a476 | ||
|
|
33635d6991 | ||
|
|
d290dbe86b | ||
|
|
c1f5c49eda | ||
|
|
c3f4caa6f3 | ||
|
|
d4c7b0e455 | ||
|
|
b0cb52fe90 | ||
|
|
386f831cd4 | ||
|
|
449daa80cc | ||
|
|
3003547b83 | ||
|
|
1664eb672f | ||
|
|
0939dcacb6 | ||
|
|
54b81d1a42 | ||
|
|
626606100f | ||
|
|
53a0b76e8c | ||
|
|
e16ac9400a | ||
|
|
94060c236b | ||
|
|
890792c270 | ||
|
|
7bc1fc3d0d | ||
|
|
9ea90ed61b | ||
|
|
ce40b80d90 | ||
|
|
53fcd94c5a | ||
|
|
ecb6247959 | ||
|
|
3b4cb6934d | ||
|
|
babe93a6ce | ||
|
|
1e9173699c | ||
|
|
37ba7aa2ca | ||
|
|
a83d2d9910 | ||
|
|
0449064f5d | ||
|
|
6cf1073a3c | ||
|
|
9ac9171206 | ||
|
|
25ce8cd2e4 | ||
|
|
e50522ab89 | ||
|
|
4801502f32 | ||
|
|
e13e4b5ddd | ||
|
|
de8da553f1 | ||
|
|
6558792e73 | ||
|
|
ea5e92017e | ||
|
|
46199efb58 | ||
|
|
8a6eae6c97 | ||
|
|
67eef8a004 | ||
|
|
b5341e5cde | ||
|
|
ac6140b17a | ||
|
|
b1489d98f0 | ||
|
|
3b7119ec58 | ||
|
|
efa34d080e | ||
|
|
19a6277841 | ||
|
|
107e1413ed | ||
|
|
94416dd881 | ||
|
|
8efc39958f | ||
|
|
569f794e33 | ||
|
|
fc1460e592 | ||
|
|
d6e4ee0203 | ||
|
|
0c8135078d | ||
|
|
24f4b864c4 | ||
|
|
41e47f32b6 | ||
|
|
a73ccb15a1 | ||
|
|
36a78f49a5 | ||
|
|
cbd459b0a5 | ||
|
|
03bb1fd089 | ||
|
|
4e2c254717 | ||
|
|
fffb6c5f29 | ||
|
|
81f669e226 | ||
|
|
6484ae54c0 | ||
|
|
1c52caf5e9 | ||
|
|
ce1d4cce57 | ||
|
|
8246197ae6 | ||
|
|
8f90bf8846 | ||
|
|
b955e8a0ea | ||
|
|
81da32f7a2 | ||
|
|
5324fa9350 | ||
|
|
c375daa258 | ||
|
|
4f3bd699c8 | ||
|
|
f5024621c0 | ||
|
|
8308506d71 | ||
|
|
6605c19202 | ||
|
|
fdf1a94f97 | ||
|
|
6b6e37da92 | ||
|
|
0f0fc8ae4e | ||
|
|
4d7e2992e5 | ||
|
|
a5050d4810 | ||
|
|
9df6963f08 | ||
|
|
b833dd4576 | ||
|
|
39378ae20f | ||
|
|
5a2cb943f7 | ||
|
|
b88209f63d | ||
|
|
9c848938f8 | ||
|
|
07b86dda41 | ||
|
|
49e8bf7639 | ||
|
|
a2d0a7f544 | ||
|
|
1a8c894ddf | ||
|
|
3f51f63298 | ||
|
|
a0b4df574b | ||
|
|
68c6492c3f | ||
|
|
0ba7ba77d8 | ||
|
|
04b2b3474d | ||
|
|
ecbb5ebbd7 | ||
|
|
b62757b65d | ||
|
|
b1a3ab5493 | ||
|
|
abc3357180 | ||
|
|
29f9cba236 | ||
|
|
9a62522140 |
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -22,6 +22,7 @@ A clear and concise description of what you expected to happen.
|
|||||||
|
|
||||||
**Logs**
|
**Logs**
|
||||||
Please provide a log of your issue with verbose logging enabled (See General tab of the plugin).
|
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.
|
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).
|
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.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|||||||
79
.github/actions/build-dependencies/action.yml
vendored
Normal file
79
.github/actions/build-dependencies/action.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
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
6
.github/actions/build-plugin/action.yml
vendored
@@ -49,7 +49,7 @@ runs:
|
|||||||
if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(-s)
|
if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(-s)
|
||||||
if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
|
if (( ${+CI} && ${+RUNNER_DEBUG} )) build_args+=(--debug)
|
||||||
|
|
||||||
${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh ${build_args}
|
${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh -d ${{ env.DEP_DIR }} ${build_args}
|
||||||
|
|
||||||
- name: Run Linux Build
|
- name: Run Linux Build
|
||||||
if: ${{ runner.os == 'Linux' }}
|
if: ${{ runner.os == 'Linux' }}
|
||||||
@@ -68,7 +68,7 @@ runs:
|
|||||||
build_args+=(-p)
|
build_args+=(-p)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh "${build_args[@]}"
|
${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh -d ${{ env.DEP_DIR }} "${build_args[@]}"
|
||||||
|
|
||||||
- name: Run Windows Build
|
- name: Run Windows Build
|
||||||
if: ${{ runner.os == 'Windows' }}
|
if: ${{ runner.os == 'Windows' }}
|
||||||
@@ -86,4 +86,4 @@ runs:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 @BuildArgs
|
${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 -ADVSSDepName ${{ env.DEP_DIR }} @BuildArgs
|
||||||
|
|||||||
1
.github/scripts/.Wingetfile
vendored
1
.github/scripts/.Wingetfile
vendored
@@ -1,3 +1,4 @@
|
|||||||
package '7zip.7zip', path: '7-zip', bin: '7z'
|
package '7zip.7zip', path: '7-zip', bin: '7z'
|
||||||
package 'cmake', path: 'Cmake\bin', bin: 'cmake'
|
package 'cmake', path: 'Cmake\bin', bin: 'cmake'
|
||||||
package 'innosetup', path: 'Inno Setup 6', bin: 'iscc'
|
package 'innosetup', path: 'Inno Setup 6', bin: 'iscc'
|
||||||
|
package 'OpenSSL', path: 'OpenSSL', bin: 'openssl'
|
||||||
|
|||||||
324
.github/scripts/.build-deps.zsh
vendored
Executable file
324
.github/scripts/.build-deps.zsh
vendored
Executable file
@@ -0,0 +1,324 @@
|
|||||||
|
#!/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 ${@}
|
||||||
112
.github/scripts/.build.zsh
vendored
112
.github/scripts/.build.zsh
vendored
@@ -36,6 +36,7 @@ build() {
|
|||||||
local target="${host_os}-${CPUTYPE}"
|
local target="${host_os}-${CPUTYPE}"
|
||||||
local project_root=${SCRIPT_HOME:A:h:h}
|
local project_root=${SCRIPT_HOME:A:h:h}
|
||||||
local buildspec_file="${project_root}/buildspec.json"
|
local buildspec_file="${project_root}/buildspec.json"
|
||||||
|
local dep_dir=""
|
||||||
|
|
||||||
trap '_trap_error' ZERR
|
trap '_trap_error' ZERR
|
||||||
|
|
||||||
@@ -77,6 +78,7 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
%B-c | --config%b Build configuration - default: %B%F{green}RelWithDebInfo%f%b
|
%B-c | --config%b Build configuration - default: %B%F{green}RelWithDebInfo%f%b
|
||||||
%B-s | --codesign%b Enable codesigning (macOS only)
|
%B-s | --codesign%b Enable codesigning (macOS only)
|
||||||
%B-p | --portable%b Enable portable mode (Linux 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
|
%B--generator%b Specify build system to generate - default: %B%F{green}Ninja%f%b
|
||||||
Available generators:
|
Available generators:
|
||||||
- Ninja
|
- Ninja
|
||||||
@@ -130,6 +132,10 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
BUILD_CONFIG=${2}
|
BUILD_CONFIG=${2}
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
-d|--dep)
|
||||||
|
dep_dir="${2}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
-s|--codesign) CODESIGN=1; shift ;;
|
-s|--codesign) CODESIGN=1; shift ;;
|
||||||
-p|--portable) typeset -g PORTABLE=1; shift ;;
|
-p|--portable) typeset -g PORTABLE=1; shift ;;
|
||||||
-q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
|
-q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
|
||||||
@@ -168,6 +174,15 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
typeset -g OBS_DEPS_VERSION
|
typeset -g OBS_DEPS_VERSION
|
||||||
setup_${host_os}
|
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_name
|
||||||
local product_version
|
local product_version
|
||||||
local git_tag="$(git describe --tags)"
|
local git_tag="$(git describe --tags)"
|
||||||
@@ -187,96 +202,6 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
sed -i '' \
|
sed -i '' \
|
||||||
"s/project(\(.*\) VERSION \(.*\))/project(${product_name} VERSION ${product_version})/" \
|
"s/project(\(.*\) VERSION \(.*\))/project(${product_name} VERSION ${product_version})/" \
|
||||||
"${project_root}/CMakeLists.txt"
|
"${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)
|
linux)
|
||||||
sed -i'' \
|
sed -i'' \
|
||||||
@@ -295,7 +220,7 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
local -a cmake_args=(
|
local -a cmake_args=(
|
||||||
-DCMAKE_BUILD_TYPE=${BUILD_CONFIG:-RelWithDebInfo}
|
-DCMAKE_BUILD_TYPE=${BUILD_CONFIG:-RelWithDebInfo}
|
||||||
-DQT_VERSION=${QT_VERSION}
|
-DQT_VERSION=${QT_VERSION}
|
||||||
-DCMAKE_PREFIX_PATH="${_plugin_deps}"
|
-DCMAKE_PREFIX_PATH="${_plugin_deps};${advss_deps_path}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (( _loglevel == 0 )) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR)
|
if (( _loglevel == 0 )) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR)
|
||||||
@@ -312,12 +237,17 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
|
|
||||||
num_procs=$(( $(sysctl -n hw.ncpu) + 1 ))
|
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+=(
|
cmake_args+=(
|
||||||
-DCMAKE_FRAMEWORK_PATH="${_plugin_deps}/Frameworks"
|
-DCMAKE_FRAMEWORK_PATH="${_plugin_deps}/Frameworks"
|
||||||
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||||
-DOBS_CODESIGN_LINKER=ON
|
-DOBS_CODESIGN_LINKER=ON
|
||||||
-DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}"
|
-DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}"
|
||||||
|
-DOPENSSL_INCLUDE_DIR="${openssl_include_dir}"
|
||||||
|
-DOPENSSL_LIBRARIES="${openssl_lib_dir}/libcrypto.a;${openssl_lib_dir}/libssl.a"
|
||||||
)
|
)
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|||||||
172
.github/scripts/Build-Deps-Windows.ps1
vendored
Normal file
172
.github/scripts/Build-Deps-Windows.ps1
vendored
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
[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
116
.github/scripts/Build-Windows.ps1
vendored
@@ -6,6 +6,7 @@ param(
|
|||||||
[string] $Target,
|
[string] $Target,
|
||||||
[ValidateSet('Visual Studio 17 2022', 'Visual Studio 16 2019')]
|
[ValidateSet('Visual Studio 17 2022', 'Visual Studio 16 2019')]
|
||||||
[string] $CMakeGenerator,
|
[string] $CMakeGenerator,
|
||||||
|
[string] $ADVSSDepName,
|
||||||
[switch] $SkipAll,
|
[switch] $SkipAll,
|
||||||
[switch] $SkipBuild,
|
[switch] $SkipBuild,
|
||||||
[switch] $SkipDeps,
|
[switch] $SkipDeps,
|
||||||
@@ -60,116 +61,17 @@ function Build {
|
|||||||
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
|
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
|
||||||
$DepInstallPath = "$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
$DepInstallPath = "$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
||||||
|
|
||||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
if ( $ADVSSDepName -eq '' ) {
|
||||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
Log-Information "Building advss deps ..."
|
||||||
|
$ADVSSDepName = "advss-build-dependencies"
|
||||||
Push-Location -Stack BuildOpenCVTemp
|
invoke-expression -Command "$PSScriptRoot/Build-Deps-Windows.ps1 -Configuration $Configuration -Target $Target -CMakeGenerator `"$CMakeGenerator`" -OutDirName $ADVSSDepName -SkipDeps -SkipUnpack"
|
||||||
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
|
|
||||||
}
|
}
|
||||||
Log-Information "Install OpenCV}..."
|
$ADVSSDepPath = "$(Resolve-Path -Path ${ProjectRoot}/../${script:ADVSSDepName})"
|
||||||
Invoke-External cmake --install "${OpenCVBuildPath}" --prefix "${DepInstallPath}" @OpenCVCmakeArgs
|
Log-Information "Using advss deps at $ADVSSDepPath ..."
|
||||||
|
|
||||||
$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=${Configuration}"
|
|
||||||
"-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', "${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 "${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=${Configuration}"
|
|
||||||
"-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', "${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 "${DepInstallPath}" @TesseractCmakeArgs
|
|
||||||
|
|
||||||
(Get-Content -Path ${ProjectRoot}/CMakeLists.txt -Raw) `
|
(Get-Content -Path ${ProjectRoot}/CMakeLists.txt -Raw) `
|
||||||
-replace "project\((.*) VERSION (.*)\)", "project(${ProductName} VERSION ${ProductVersion})" `
|
-replace "project\((.*) VERSION (.*)\)", "project(${ProductName} VERSION ${ProductVersion})" `
|
||||||
| Out-File -Path ${ProjectRoot}/CMakeLists.txt
|
| Out-File -Path ${ProjectRoot}/CMakeLists.txt -NoNewline
|
||||||
|
|
||||||
Setup-Obs
|
Setup-Obs
|
||||||
|
|
||||||
@@ -182,7 +84,7 @@ function Build {
|
|||||||
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
||||||
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
||||||
"-DCMAKE_BUILD_TYPE=${Configuration}"
|
"-DCMAKE_BUILD_TYPE=${Configuration}"
|
||||||
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath}"
|
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath};${ADVSSDepPath}"
|
||||||
"-DQT_VERSION=${script:QtVersion}"
|
"-DQT_VERSION=${script:QtVersion}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
13
.github/scripts/build-deps-linux.sh
vendored
Executable file
13
.github/scripts/build-deps-linux.sh
vendored
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/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
Symbolic link
1
.github/scripts/build-deps-linux.zsh
vendored
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
.build-deps.zsh
|
||||||
1
.github/scripts/build-deps-macos.zsh
vendored
Symbolic link
1
.github/scripts/build-deps-macos.zsh
vendored
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
.build-deps.zsh
|
||||||
2
.github/scripts/utils.zsh/check_packages
vendored
2
.github/scripts/utils.zsh/check_packages
vendored
@@ -24,7 +24,7 @@ if (( ! ${+commands[packagesbuild]} )) {
|
|||||||
pushd
|
pushd
|
||||||
mkcd ${project_root:h}/obs-build-dependencies
|
mkcd ${project_root:h}/obs-build-dependencies
|
||||||
|
|
||||||
local packages_url='http://s.sudre.free.fr/Software/files/Packages.dmg'
|
local packages_url='https://web.archive.org/web/20230727054218/http://s.sudre.free.fr/Software/files/Packages.dmg'
|
||||||
local packages_hash='6afdd25386295974dad8f078b8f1e41cabebd08e72d970bf92f707c7e48b16c9'
|
local packages_hash='6afdd25386295974dad8f078b8f1e41cabebd08e72d970bf92f707c7e48b16c9'
|
||||||
|
|
||||||
if [[ ! -f Packages.dmg ]] {
|
if [[ ! -f Packages.dmg ]] {
|
||||||
|
|||||||
29
.github/workflows/main.yml
vendored
29
.github/workflows/main.yml
vendored
@@ -17,6 +17,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
PLUGIN_NAME: SceneSwitcher
|
PLUGIN_NAME: SceneSwitcher
|
||||||
LIB_NAME: advanced-scene-switcher
|
LIB_NAME: advanced-scene-switcher
|
||||||
|
DEP_DIR: advss-build-dependencies-1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
clang_check:
|
clang_check:
|
||||||
@@ -115,9 +116,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
${{ github.workspace }}/.ccache
|
${{ 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 }}
|
key: macos-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
macos-${{ matrix.arch }}-ccache-plugin-
|
macos-${{ matrix.arch }}-ccache-plugin-
|
||||||
@@ -146,6 +144,13 @@ jobs:
|
|||||||
print "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" >> $GITHUB_ENV
|
print "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" >> $GITHUB_ENV
|
||||||
print "CODESIGN_IDENT_INSTALLER=${{ secrets.MACOS_SIGNING_INSTALLER_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
|
- name: Build Plugin
|
||||||
uses: ./plugin/.github/actions/build-plugin
|
uses: ./plugin/.github/actions/build-plugin
|
||||||
with:
|
with:
|
||||||
@@ -248,6 +253,13 @@ jobs:
|
|||||||
echo 'found=false' >> $GITHUB_OUTPUT
|
echo 'found=false' >> $GITHUB_OUTPUT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
- name: Build Dependencies
|
||||||
|
uses: ./plugin/.github/actions/build-dependencies
|
||||||
|
with:
|
||||||
|
workingDirectory: ${{ github.workspace }}/plugin
|
||||||
|
target: ${{ matrix.arch }}
|
||||||
|
config: RelWithDebInfo
|
||||||
|
|
||||||
- name: Build Plugin
|
- name: Build Plugin
|
||||||
uses: ./plugin/.github/actions/build-plugin
|
uses: ./plugin/.github/actions/build-plugin
|
||||||
with:
|
with:
|
||||||
@@ -329,9 +341,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
${{ github.workspace }}/.ccache
|
${{ 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 }}
|
key: windows-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
windows-${{ matrix.arch }}-ccache-plugin-
|
windows-${{ matrix.arch }}-ccache-plugin-
|
||||||
@@ -357,6 +366,14 @@ jobs:
|
|||||||
|
|
||||||
"found=$(([string]${LabelFound}).ToLower())" >> $env:GITHUB_OUTPUT
|
"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
|
- name: Build Plugin
|
||||||
uses: ./plugin/.github/actions/build-plugin
|
uses: ./plugin/.github/actions/build-plugin
|
||||||
with:
|
with:
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -91,6 +91,7 @@ Thumbs.db
|
|||||||
.settings
|
.settings
|
||||||
.idea
|
.idea
|
||||||
.metadata
|
.metadata
|
||||||
|
.vscode
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
*.sublime*
|
*.sublime*
|
||||||
|
|||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -19,3 +19,9 @@
|
|||||||
[submodule "deps/libremidi"]
|
[submodule "deps/libremidi"]
|
||||||
path = deps/libremidi
|
path = deps/libremidi
|
||||||
url = https://github.com/jcelerier/libremidi.git
|
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
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ target_sources(
|
|||||||
src/macro-core/macro-condition-streaming.hpp
|
src/macro-core/macro-condition-streaming.hpp
|
||||||
src/macro-core/macro-condition-studio-mode.cpp
|
src/macro-core/macro-condition-studio-mode.cpp
|
||||||
src/macro-core/macro-condition-studio-mode.hpp
|
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.cpp
|
||||||
src/macro-core/macro-condition-timer.hpp
|
src/macro-core/macro-condition-timer.hpp
|
||||||
src/macro-core/macro-condition-transition.cpp
|
src/macro-core/macro-condition-transition.cpp
|
||||||
@@ -254,6 +256,7 @@ target_sources(
|
|||||||
src/utils/curl-helper.hpp
|
src/utils/curl-helper.hpp
|
||||||
src/utils/duration-control.cpp
|
src/utils/duration-control.cpp
|
||||||
src/utils/duration-control.hpp
|
src/utils/duration-control.hpp
|
||||||
|
src/utils/export-symbol-helper.hpp
|
||||||
src/utils/item-selection-helpers.cpp
|
src/utils/item-selection-helpers.cpp
|
||||||
src/utils/item-selection-helpers.hpp
|
src/utils/item-selection-helpers.hpp
|
||||||
src/utils/log-helper.hpp
|
src/utils/log-helper.hpp
|
||||||
@@ -267,6 +270,8 @@ target_sources(
|
|||||||
src/utils/macro-export-import-dialog.hpp
|
src/utils/macro-export-import-dialog.hpp
|
||||||
src/utils/macro-list.cpp
|
src/utils/macro-list.cpp
|
||||||
src/utils/macro-list.hpp
|
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.cpp
|
||||||
src/utils/macro-segment-selection.hpp
|
src/utils/macro-segment-selection.hpp
|
||||||
src/utils/math-helpers.cpp
|
src/utils/math-helpers.cpp
|
||||||
@@ -304,6 +309,8 @@ target_sources(
|
|||||||
src/utils/slider-spinbox.hpp
|
src/utils/slider-spinbox.hpp
|
||||||
src/utils/source-selection.cpp
|
src/utils/source-selection.cpp
|
||||||
src/utils/source-selection.hpp
|
src/utils/source-selection.hpp
|
||||||
|
src/utils/source-setting.cpp
|
||||||
|
src/utils/source-setting.hpp
|
||||||
src/utils/string-list.cpp
|
src/utils/string-list.cpp
|
||||||
src/utils/string-list.hpp
|
src/utils/string-list.hpp
|
||||||
src/utils/striped-frame.cpp
|
src/utils/striped-frame.cpp
|
||||||
@@ -312,6 +319,8 @@ target_sources(
|
|||||||
src/utils/switch-button.hpp
|
src/utils/switch-button.hpp
|
||||||
src/utils/sync-helper.cpp
|
src/utils/sync-helper.cpp
|
||||||
src/utils/sync-helper.hpp
|
src/utils/sync-helper.hpp
|
||||||
|
src/utils/temp-variable.cpp
|
||||||
|
src/utils/temp-variable.hpp
|
||||||
src/utils/transition-selection.cpp
|
src/utils/transition-selection.cpp
|
||||||
src/utils/transition-selection.hpp
|
src/utils/transition-selection.hpp
|
||||||
src/utils/utility.cpp
|
src/utils/utility.cpp
|
||||||
@@ -375,6 +384,14 @@ target_include_directories(
|
|||||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib"
|
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/exprtk")
|
"${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)
|
||||||
|
|
||||||
# --- End of section ---
|
# --- End of section ---
|
||||||
|
|
||||||
# --- Windows-specific build settings and tasks ---
|
# --- Windows-specific build settings and tasks ---
|
||||||
|
|||||||
@@ -146,18 +146,15 @@ AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Während des
|
|||||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
||||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||||
AdvSceneSwitcher.condition.window="Fenster"
|
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="Datei"
|
||||||
AdvSceneSwitcher.condition.file.type.match="entspricht"
|
AdvSceneSwitcher.condition.file.type.match="entspricht"
|
||||||
AdvSceneSwitcher.condition.file.type.contentChange="Inhalt geändert"
|
AdvSceneSwitcher.condition.file.type.contentChange="Inhalt geändert"
|
||||||
AdvSceneSwitcher.condition.file.type.dateChange="Änderungsdatum geändert"
|
AdvSceneSwitcher.condition.file.type.dateChange="Änderungsdatum geändert"
|
||||||
AdvSceneSwitcher.condition.file.remote="Entfernte Datei"
|
AdvSceneSwitcher.condition.file.remote="Entfernte Datei"
|
||||||
AdvSceneSwitcher.condition.file.local="Lokale Datei"
|
AdvSceneSwitcher.condition.file.local="Lokale Datei"
|
||||||
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}"
|
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Medien"
|
AdvSceneSwitcher.condition.media="Medien"
|
||||||
AdvSceneSwitcher.condition.media.source="Quelle"
|
AdvSceneSwitcher.condition.media.source="Quelle"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Beliebige Medienquelle in"
|
AdvSceneSwitcher.condition.media.anyOnScene="Beliebige Medienquelle in"
|
||||||
@@ -328,7 +325,9 @@ 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.date.entry.updateOnRepeat="{{updateOnRepeat}} Bei Wiederholung ausgewähltes Datum auf Wiederholungsdatum aktualisieren"
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Szenenelement transformieren"
|
AdvSceneSwitcher.condition.sceneTransform="Szenenelement transformieren"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Transformation erhalten"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Transformation erhalten"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="Auf{{scenes}}{{sources}}passt zur Transformation"
|
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.line2="{{settings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||||
AdvSceneSwitcher.condition.transition="Übergang"
|
AdvSceneSwitcher.condition.transition="Übergang"
|
||||||
@@ -392,12 +391,11 @@ AdvSceneSwitcher.condition.variable.type.valueChanged="Wert verändert"
|
|||||||
AdvSceneSwitcher.condition.variable.type.equalsVariable="entspricht Variable"
|
AdvSceneSwitcher.condition.variable.type.equalsVariable="entspricht Variable"
|
||||||
AdvSceneSwitcher.condition.variable.type.lessThanVariable="ist kleiner als die 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.type.greaterThanVariable="ist größer als die Variable"
|
||||||
AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}"
|
|
||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.switchScene="Szene wechseln"
|
AdvSceneSwitcher.action.scene="Szene wechseln"
|
||||||
AdvSceneSwitcher.action.scene.entry="Wechsle zu Szene{{scenes}}mittels{{transitions}}mit einer Dauer von{{duration}}Sekunden"
|
AdvSceneSwitcher.action.scene.entry="Wechsle{{sceneTypes}}Szene zu{{scenes}}mittels{{transitions}}mit einer Dauer von{{duration}}Sekunden"
|
||||||
AdvSceneSwitcher.action.scene.entry.noDuration="Wechsle zu Szene{{scenes}}mittels{{transitions}}"
|
AdvSceneSwitcher.action.scene.entry.noDuration="Wechsle{{sceneTypes}}Szene zu{{scenes}}mittels{{transitions}}"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Warten, bis der Übergang zur Zielszene abgeschlossen ist"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Warten, bis der Übergang zur Zielszene abgeschlossen ist"
|
||||||
AdvSceneSwitcher.action.wait="Warten"
|
AdvSceneSwitcher.action.wait="Warten"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="fixe"
|
AdvSceneSwitcher.action.wait.type.fixed="fixe"
|
||||||
@@ -440,11 +438,6 @@ AdvSceneSwitcher.action.streaming.type.stop="Stream stoppen"
|
|||||||
AdvSceneSwitcher.action.streaming.type.start="Stream starten"
|
AdvSceneSwitcher.action.streaming.type.start="Stream starten"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Ausführen"
|
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="Sichtbarkeit von Szenenelementen"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Anzeigen"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Anzeigen"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Verstecken"
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="Verstecken"
|
||||||
@@ -476,8 +469,7 @@ AdvSceneSwitcher.action.media.type.stop="Stoppen"
|
|||||||
AdvSceneSwitcher.action.media.type.restart="Neu starten"
|
AdvSceneSwitcher.action.media.type.restart="Neu starten"
|
||||||
AdvSceneSwitcher.action.media.type.next="Nächste"
|
AdvSceneSwitcher.action.media.type.next="Nächste"
|
||||||
AdvSceneSwitcher.action.media.type.previous="Vorherige"
|
AdvSceneSwitcher.action.media.type.previous="Vorherige"
|
||||||
AdvSceneSwitcher.action.media.type.seek="Suche nach"
|
AdvSceneSwitcher.action.media.type.seek.duration="Suche nach"
|
||||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
|
||||||
AdvSceneSwitcher.action.macro="Makro"
|
AdvSceneSwitcher.action.macro="Makro"
|
||||||
AdvSceneSwitcher.action.macro.type.pause="Pausieren"
|
AdvSceneSwitcher.action.macro.type.pause="Pausieren"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Nicht mehr pausieren"
|
AdvSceneSwitcher.action.macro.type.unpause="Nicht mehr pausieren"
|
||||||
@@ -506,7 +498,6 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Linke Meta-Taste"
|
|||||||
AdvSceneSwitcher.action.hotkey.rightMeta="Rechte Meta-Taste"
|
AdvSceneSwitcher.action.hotkey.rightMeta="Rechte Meta-Taste"
|
||||||
AdvSceneSwitcher.action.hotkey.onlyOBS="Tastendruck nur an OBS senden"
|
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.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}}"
|
|
||||||
AdvSceneSwitcher.action.sceneOrder="Reihenfolge der Szenenelemente"
|
AdvSceneSwitcher.action.sceneOrder="Reihenfolge der Szenenelemente"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Nach oben verschieben"
|
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Nach oben verschieben"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Nach unten verschieben"
|
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Nach unten verschieben"
|
||||||
@@ -567,8 +558,6 @@ AdvSceneSwitcher.action.sequence.continueFrom="Weiter mit ausgewähltem Element"
|
|||||||
AdvSceneSwitcher.action.websocket="Websocket"
|
AdvSceneSwitcher.action.websocket="Websocket"
|
||||||
AdvSceneSwitcher.action.websocket.type.request="Anfrage"
|
AdvSceneSwitcher.action.websocket.type.request="Anfrage"
|
||||||
AdvSceneSwitcher.action.websocket.type.event="Ereignis"
|
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="HTTP"
|
||||||
AdvSceneSwitcher.action.http.type.get="GET"
|
AdvSceneSwitcher.action.http.type.get="GET"
|
||||||
AdvSceneSwitcher.action.http.type.post="POST"
|
AdvSceneSwitcher.action.http.type.post="POST"
|
||||||
@@ -586,7 +575,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.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.conditionNoVariableSupport="Das Abrufen von Variablenwerten aus %1 Bedingungen wird nicht unterstützt!"
|
||||||
AdvSceneSwitcher.action.variable.currentSegmentValue="Aktueller Wert:"
|
AdvSceneSwitcher.action.variable.currentSegmentValue="Aktueller Wert:"
|
||||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
|
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}"
|
||||||
|
|
||||||
|
|
||||||
; Transition Tab
|
; Transition Tab
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -122,12 +122,10 @@ AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="Durante la tr
|
|||||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
||||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||||
AdvSceneSwitcher.condition.window="Ventana"
|
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="Archivo"
|
||||||
AdvSceneSwitcher.condition.file.entry.line1="Contenido de{{fileType}}{{filePath}}{{conditions}}"
|
AdvSceneSwitcher.condition.file.entry.line1="Contenido de{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Medios"
|
AdvSceneSwitcher.condition.media="Medios"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Cualquier fuente multimedia activada"
|
AdvSceneSwitcher.condition.media.anyOnScene="Cualquier fuente multimedia activada"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="Todas las fuentes de medios activadas"
|
AdvSceneSwitcher.condition.media.allOnScene="Todas las fuentes de medios activadas"
|
||||||
@@ -277,7 +275,8 @@ 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.date.entry.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha"
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Transformar elemento de escena"
|
AdvSceneSwitcher.condition.sceneTransform="Transformar elemento de escena"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtener transformación"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtener transformación"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="En{{scenes}}{{sources}}coincide con la 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.line2="{{settings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||||
AdvSceneSwitcher.condition.transition="Transición"
|
AdvSceneSwitcher.condition.transition="Transición"
|
||||||
@@ -324,8 +323,8 @@ AdvSceneSwitcher.condition.stats.dockHint="Puede abrir el panel de \"Estadístic
|
|||||||
AdvSceneSwitcher.condition.stats.entry="{{stats}} esta {{condition}} {{value}}"
|
AdvSceneSwitcher.condition.stats.entry="{{stats}} esta {{condition}} {{value}}"
|
||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.switchScene="Cambiar escena"
|
AdvSceneSwitcher.action.scene="Cambiar escena"
|
||||||
AdvSceneSwitcher.action.scene.entry="Cambiar a la escena {{scenes}} usando {{transitions}} con una duración de {{duration}} segundos"
|
AdvSceneSwitcher.action.scene.entry="Cambiar a la{{sceneTypes}}escena{{scenes}}usando{{transitions}}con una duración de{{duration}} segundos"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Espere hasta que se complete la transición a la escena de destino"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Espere hasta que se complete la transición a la escena de destino"
|
||||||
AdvSceneSwitcher.action.wait="Esperar"
|
AdvSceneSwitcher.action.wait="Esperar"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="fijo"
|
AdvSceneSwitcher.action.wait.type.fixed="fijo"
|
||||||
@@ -362,10 +361,6 @@ AdvSceneSwitcher.action.streaming.type.stop="Detener transmisión"
|
|||||||
AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión"
|
AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Ejecutar"
|
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="Visibilidad del elemento de escena"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Mostrar"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Mostrar"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
||||||
@@ -392,8 +387,7 @@ AdvSceneSwitcher.action.media.type.stop="Detener"
|
|||||||
AdvSceneSwitcher.action.media.type.restart="Reiniciar"
|
AdvSceneSwitcher.action.media.type.restart="Reiniciar"
|
||||||
AdvSceneSwitcher.action.media.type.next="Siguiente"
|
AdvSceneSwitcher.action.media.type.next="Siguiente"
|
||||||
AdvSceneSwitcher.action.media.type.previous="Anterior"
|
AdvSceneSwitcher.action.media.type.previous="Anterior"
|
||||||
AdvSceneSwitcher.action.media.type.seek="Buscar"
|
AdvSceneSwitcher.action.media.type.seek.duration="Buscar"
|
||||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
|
||||||
AdvSceneSwitcher.action.macro="Macro"
|
AdvSceneSwitcher.action.macro="Macro"
|
||||||
AdvSceneSwitcher.action.macro.type.pause="Pausa"
|
AdvSceneSwitcher.action.macro.type.pause="Pausa"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Reanudar"
|
AdvSceneSwitcher.action.macro.type.unpause="Reanudar"
|
||||||
@@ -422,7 +416,6 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Meta izquierda"
|
|||||||
AdvSceneSwitcher.action.hotkey.rightMeta="Meta derecho"
|
AdvSceneSwitcher.action.hotkey.rightMeta="Meta derecho"
|
||||||
AdvSceneSwitcher.action.hotkey.onlyOBS="Enviar pulsación de tecla solo a OBS"
|
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.disabled="No se puede simular la pulsación de teclas: ¡funcionalidad desactivada!"
|
||||||
AdvSceneSwitcher.action.hotkey.entry="Presione {{keys}} durante {{duration}}"
|
|
||||||
AdvSceneSwitcher.action.sceneOrder="Orden de elementos de escena"
|
AdvSceneSwitcher.action.sceneOrder="Orden de elementos de escena"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Mover hacia arriba"
|
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Mover hacia arriba"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover hacia abajo"
|
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover hacia abajo"
|
||||||
|
|||||||
1201
data/locale/fr-FR.ini
Normal file
1201
data/locale/fr-FR.ini
Normal file
File diff suppressed because it is too large
Load Diff
@@ -86,10 +86,9 @@ AdvSceneSwitcher.condition.scene="Сцена"
|
|||||||
AdvSceneSwitcher.condition.scene.type.current="Текущий"
|
AdvSceneSwitcher.condition.scene.type.current="Текущий"
|
||||||
AdvSceneSwitcher.condition.scene.type.previous="Предыдущий"
|
AdvSceneSwitcher.condition.scene.type.previous="Предыдущий"
|
||||||
AdvSceneSwitcher.condition.window="Окно"
|
AdvSceneSwitcher.condition.window="Окно"
|
||||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} существует и ..."
|
|
||||||
AdvSceneSwitcher.condition.file="Файл"
|
AdvSceneSwitcher.condition.file="Файл"
|
||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Медиа"
|
AdvSceneSwitcher.condition.media="Медиа"
|
||||||
AdvSceneSwitcher.condition.video="Видео"
|
AdvSceneSwitcher.condition.video="Видео"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
||||||
@@ -116,8 +115,8 @@ AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Автоматиче
|
|||||||
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.switchScene="Переключить сцену"
|
AdvSceneSwitcher.action.scene="Переключить сцену"
|
||||||
AdvSceneSwitcher.action.scene.entry="Перейти к сцене {{scenes}} используя {{transitions}} с продолжительностью {{duration}} секунд"
|
AdvSceneSwitcher.action.scene.entry="Перейти к сцене{{sceneTypes}}{{scenes}}используя{{transitions}}с продолжительностью{{duration}}секунд"
|
||||||
AdvSceneSwitcher.action.wait="Подождать"
|
AdvSceneSwitcher.action.wait="Подождать"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="фиксированный"
|
AdvSceneSwitcher.action.wait.type.fixed="фиксированный"
|
||||||
AdvSceneSwitcher.action.wait.type.random="случайный"
|
AdvSceneSwitcher.action.wait.type.random="случайный"
|
||||||
|
|||||||
@@ -112,12 +112,10 @@ AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="Geçiş hedefi
|
|||||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}"
|
||||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||||
AdvSceneSwitcher.condition.window="Pencere"
|
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="Dosya"
|
||||||
AdvSceneSwitcher.condition.file.entry.line1="İçerik{{fileType}}{{filePath}}{{conditions}}"
|
AdvSceneSwitcher.condition.file.entry.line1="İçerik{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Medya"
|
AdvSceneSwitcher.condition.media="Medya"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Herhangi bir medya kaynağı"
|
AdvSceneSwitcher.condition.media.anyOnScene="Herhangi bir medya kaynağı"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="Tüm medya kaynakları "
|
AdvSceneSwitcher.condition.media.allOnScene="Tüm medya kaynakları "
|
||||||
@@ -233,7 +231,8 @@ AdvSceneSwitcher.condition.date.state.before="Önce"
|
|||||||
AdvSceneSwitcher.condition.date.state.between="Arasında"
|
AdvSceneSwitcher.condition.date.state.between="Arasında"
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Sahne öğesi dönüşümü"
|
AdvSceneSwitcher.condition.sceneTransform="Sahne öğesi dönüşümü"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Dönüşümü al"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Dönüşümü al"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="Açık{{scenes}}{{sources}} dönüşümle eşleşir"
|
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.line2="{{settings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||||
AdvSceneSwitcher.condition.transition="Geçiş"
|
AdvSceneSwitcher.condition.transition="Geçiş"
|
||||||
@@ -261,8 +260,8 @@ AdvSceneSwitcher.condition.openvr.entry.line2="{{controls}}"
|
|||||||
AdvSceneSwitcher.condition.openvr.entry.line3="HMD mevcut {{xPos}} x {{yPos}} x {{zPos}}"
|
AdvSceneSwitcher.condition.openvr.entry.line3="HMD mevcut {{xPos}} x {{yPos}} x {{zPos}}"
|
||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.switchScene="Sahne Degistirici"
|
AdvSceneSwitcher.action.scene="Sahne Degistirici"
|
||||||
AdvSceneSwitcher.action.scene.entry="Sahneyi {{scenes}} kullanarak {{transitions}} süresi olan {{duration}} saniye"
|
AdvSceneSwitcher.action.scene.entry="Sahneyi{{sceneTypes}}{{scenes}}kullanarak{{transitions}}süresi olan{{duration}}saniye"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Hedef sahneye geçiş tamamlanana kadar bekleyin"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="Hedef sahneye geçiş tamamlanana kadar bekleyin"
|
||||||
AdvSceneSwitcher.action.wait="Bekle"
|
AdvSceneSwitcher.action.wait="Bekle"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="sabit"
|
AdvSceneSwitcher.action.wait.type.fixed="sabit"
|
||||||
@@ -292,10 +291,6 @@ AdvSceneSwitcher.action.streaming.type.stop="Yayın durdur"
|
|||||||
AdvSceneSwitcher.action.streaming.type.start="Yayın başlat"
|
AdvSceneSwitcher.action.streaming.type.start="Yayın başlat"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Çalıştır"
|
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="Sahne öğesi görünürlüğü"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Göster"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Göster"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Gizle"
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="Gizle"
|
||||||
@@ -322,7 +317,6 @@ AdvSceneSwitcher.action.media.type.stop="Dur"
|
|||||||
AdvSceneSwitcher.action.media.type.restart="Yeniden Başlat"
|
AdvSceneSwitcher.action.media.type.restart="Yeniden Başlat"
|
||||||
AdvSceneSwitcher.action.media.type.next="Sonraki"
|
AdvSceneSwitcher.action.media.type.next="Sonraki"
|
||||||
AdvSceneSwitcher.action.media.type.previous="Önceki"
|
AdvSceneSwitcher.action.media.type.previous="Önceki"
|
||||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
|
||||||
AdvSceneSwitcher.action.macro="Makro"
|
AdvSceneSwitcher.action.macro="Makro"
|
||||||
AdvSceneSwitcher.action.macro.type.pause="Duraklat"
|
AdvSceneSwitcher.action.macro.type.pause="Duraklat"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Duraklatma"
|
AdvSceneSwitcher.action.macro.type.unpause="Duraklatma"
|
||||||
@@ -350,7 +344,6 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Sol Meta"
|
|||||||
AdvSceneSwitcher.action.hotkey.rightMeta="Sağ Meta"
|
AdvSceneSwitcher.action.hotkey.rightMeta="Sağ Meta"
|
||||||
AdvSceneSwitcher.action.hotkey.onlyOBS="Tuşa basımı yalnızca OBS'ye gönder"
|
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.disabled="Tuşa basma simülasyonu yapılamıyor - işlevsellik devre dışı!"
|
||||||
AdvSceneSwitcher.action.hotkey.entry="Bas {{keys}} uygun {{duration}}"
|
|
||||||
AdvSceneSwitcher.action.sceneOrder="Sahne öğesi sırası"
|
AdvSceneSwitcher.action.sceneOrder="Sahne öğesi sırası"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Yukarı taşı"
|
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Yukarı taşı"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Aşağı indir"
|
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Aşağı indir"
|
||||||
|
|||||||
@@ -178,9 +178,9 @@ AdvSceneSwitcher.condition.file.type.contentChange="内容已更改"
|
|||||||
AdvSceneSwitcher.condition.file.type.dateChange="修改日期已更改"
|
AdvSceneSwitcher.condition.file.type.dateChange="修改日期已更改"
|
||||||
AdvSceneSwitcher.condition.file.remote="远程文件"
|
AdvSceneSwitcher.condition.file.remote="远程文件"
|
||||||
AdvSceneSwitcher.condition.file.local="本地文件"
|
AdvSceneSwitcher.condition.file.local="本地文件"
|
||||||
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}"
|
AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{conditions}}{{useRegex}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="媒体"
|
AdvSceneSwitcher.condition.media="媒体"
|
||||||
AdvSceneSwitcher.condition.media.source="源"
|
AdvSceneSwitcher.condition.media.source="源"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体源"
|
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体源"
|
||||||
@@ -371,7 +371,8 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="下一次匹配 在: %1"
|
|||||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} 重复时,将选定的日期更新为重复日期"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} 重复时,将选定的日期更新为重复日期"
|
||||||
AdvSceneSwitcher.condition.sceneTransform="场景项目被改变"
|
AdvSceneSwitcher.condition.sceneTransform="场景项目被改变"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="内容或者设置被改变了"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="内容或者设置被改变了"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="在 {{scenes}} {{sources}} 匹配变换"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line1="在 {{scenes}} {{sources}} {{types}}"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="匹配变换"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||||
AdvSceneSwitcher.condition.transition="转场"
|
AdvSceneSwitcher.condition.transition="转场"
|
||||||
@@ -435,7 +436,6 @@ AdvSceneSwitcher.condition.variable.type.valueChanged="值已更改"
|
|||||||
AdvSceneSwitcher.condition.variable.type.equalsVariable="等于变量"
|
AdvSceneSwitcher.condition.variable.type.equalsVariable="等于变量"
|
||||||
AdvSceneSwitcher.condition.variable.type.lessThanVariable="小于变量"
|
AdvSceneSwitcher.condition.variable.type.lessThanVariable="小于变量"
|
||||||
AdvSceneSwitcher.condition.variable.type.greaterThanVariable="大于变量"
|
AdvSceneSwitcher.condition.variable.type.greaterThanVariable="大于变量"
|
||||||
AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}"
|
|
||||||
AdvSceneSwitcher.condition.run="运行"
|
AdvSceneSwitcher.condition.run="运行"
|
||||||
AdvSceneSwitcher.condition.run.entry="进程在超时 {{timeout}} 秒之前退出"
|
AdvSceneSwitcher.condition.run.entry="进程在超时 {{timeout}} 秒之前退出"
|
||||||
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}检查退出代码{{exitCode}}"
|
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}检查退出代码{{exitCode}}"
|
||||||
@@ -448,9 +448,9 @@ AdvSceneSwitcher.condition.display.type.displayCount="连接的显示器的数
|
|||||||
AdvSceneSwitcher.condition.display.entry="{{conditions}}{{displays}}{{regex}}{{displayCount}}"
|
AdvSceneSwitcher.condition.display.entry="{{conditions}}{{displays}}{{regex}}{{displayCount}}"
|
||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.switchScene="切换场景"
|
AdvSceneSwitcher.action.scene="切换场景"
|
||||||
AdvSceneSwitcher.action.scene.entry="切换场景 {{scenes}} 使用 {{transitions}} 时长 {{duration}} 秒"
|
AdvSceneSwitcher.action.scene.entry="切换场景{{sceneTypes}}{{scenes}}使用{{transitions}}时长{{duration}}秒"
|
||||||
AdvSceneSwitcher.action.scene.entry.noDuration="切换到场景{{scenes}}使用{{transitions}}"
|
AdvSceneSwitcher.action.scene.entry.noDuration="切换到场景{{sceneTypes}}{{scenes}}使用{{transitions}}"
|
||||||
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="等待目标场景的过渡完成"
|
AdvSceneSwitcher.action.scene.blockUntilTransitionDone="等待目标场景的过渡完成"
|
||||||
AdvSceneSwitcher.action.wait="等待"
|
AdvSceneSwitcher.action.wait="等待"
|
||||||
AdvSceneSwitcher.action.wait.type.fixed="固定数值"
|
AdvSceneSwitcher.action.wait.type.fixed="固定数值"
|
||||||
@@ -527,8 +527,7 @@ AdvSceneSwitcher.action.media.type.stop="停止"
|
|||||||
AdvSceneSwitcher.action.media.type.restart="重新启动"
|
AdvSceneSwitcher.action.media.type.restart="重新启动"
|
||||||
AdvSceneSwitcher.action.media.type.next="下一个"
|
AdvSceneSwitcher.action.media.type.next="下一个"
|
||||||
AdvSceneSwitcher.action.media.type.previous="上一个"
|
AdvSceneSwitcher.action.media.type.previous="上一个"
|
||||||
AdvSceneSwitcher.action.media.type.seek="时间轴定位"
|
AdvSceneSwitcher.action.media.type.seek.duration="时间轴定位"
|
||||||
AdvSceneSwitcher.action.media.entry="{{actions}}{{duration}}{{mediaSources}}"
|
|
||||||
AdvSceneSwitcher.action.macro="宏"
|
AdvSceneSwitcher.action.macro="宏"
|
||||||
AdvSceneSwitcher.action.macro.type.pause="暂停"
|
AdvSceneSwitcher.action.macro.type.pause="暂停"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="取消暂停"
|
AdvSceneSwitcher.action.macro.type.unpause="取消暂停"
|
||||||
@@ -559,7 +558,6 @@ AdvSceneSwitcher.action.hotkey.leftMeta="左 Meta"
|
|||||||
AdvSceneSwitcher.action.hotkey.rightMeta="右 Meta"
|
AdvSceneSwitcher.action.hotkey.rightMeta="右 Meta"
|
||||||
AdvSceneSwitcher.action.hotkey.onlyOBS="仅向OBS发送按键"
|
AdvSceneSwitcher.action.hotkey.onlyOBS="仅向OBS发送按键"
|
||||||
AdvSceneSwitcher.action.hotkey.disabled="无法模拟按键-功能已禁用!"
|
AdvSceneSwitcher.action.hotkey.disabled="无法模拟按键-功能已禁用!"
|
||||||
AdvSceneSwitcher.action.hotkey.entry="按下 {{keys}} 在 {{duration}} 秒"
|
|
||||||
AdvSceneSwitcher.action.sceneOrder="场景项目顺序"
|
AdvSceneSwitcher.action.sceneOrder="场景项目顺序"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveUp="上移"
|
AdvSceneSwitcher.action.sceneOrder.type.moveUp="上移"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移"
|
AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移"
|
||||||
@@ -624,8 +622,6 @@ AdvSceneSwitcher.action.sequence.continueFrom="继续所选项目"
|
|||||||
AdvSceneSwitcher.action.websocket="websocket"
|
AdvSceneSwitcher.action.websocket="websocket"
|
||||||
AdvSceneSwitcher.action.websocket.type.request="request"
|
AdvSceneSwitcher.action.websocket.type.request="request"
|
||||||
AdvSceneSwitcher.action.websocket.type.event="event"
|
AdvSceneSwitcher.action.websocket.type.event="event"
|
||||||
AdvSceneSwitcher.action.websocket.entry.request="通过{{connection}} 发送场景切换器 {{type}}"
|
|
||||||
AdvSceneSwitcher.action.websocket.entry.event="发送场景切换器 {{type}} 到连接的客户端"
|
|
||||||
AdvSceneSwitcher.action.http="Http"
|
AdvSceneSwitcher.action.http="Http"
|
||||||
AdvSceneSwitcher.action.http.setHeaders="设置头信息(SET headers)"
|
AdvSceneSwitcher.action.http.setHeaders="设置头信息(SET headers)"
|
||||||
AdvSceneSwitcher.action.http.headers="头信息(headers):"
|
AdvSceneSwitcher.action.http.headers="头信息(headers):"
|
||||||
@@ -655,7 +651,7 @@ AdvSceneSwitcher.action.variable.invalidSelection="无效选择!"
|
|||||||
AdvSceneSwitcher.action.variable.actionNoVariableSupport="不支持从 %1 个操作获取变量值!"
|
AdvSceneSwitcher.action.variable.actionNoVariableSupport="不支持从 %1 个操作获取变量值!"
|
||||||
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="不支持从 %1 条件中获取变量值!"
|
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="不支持从 %1 条件中获取变量值!"
|
||||||
AdvSceneSwitcher.action.variable.currentSegmentValue="当前值:"
|
AdvSceneSwitcher.action.variable.currentSegmentValue="当前值:"
|
||||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
|
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.substringIndex="子字符串开始:{{subStringStart}} 子字符串大小:{{subStringSize}}"
|
||||||
AdvSceneSwitcher.action.variable.entry.substringRegex="使用正则表达式为 {{regexMatchIdx}} 匹配的值:"
|
AdvSceneSwitcher.action.variable.entry.substringRegex="使用正则表达式为 {{regexMatchIdx}} 匹配的值:"
|
||||||
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{replaceStr}}"
|
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{replaceStr}}"
|
||||||
|
|||||||
8
data/res/images/DarkSearch.svg
Normal file
8
data/res/images/DarkSearch.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
8
data/res/images/LightSearch.svg
Normal file
8
data/res/images/LightSearch.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
2
deps/asio
vendored
2
deps/asio
vendored
Submodule deps/asio updated: b73dc1d2c0...c465349fa5
1
deps/cpp-httplib
vendored
Submodule
1
deps/cpp-httplib
vendored
Submodule
Submodule deps/cpp-httplib added at c7ed1796a7
1
deps/json
vendored
Submodule
1
deps/json
vendored
Submodule
Submodule deps/json added at bc889afb4c
2
deps/websocketpp
vendored
2
deps/websocketpp
vendored
Submodule deps/websocketpp updated: c6d7e295bf...56123c8759
@@ -67,8 +67,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>957</width>
|
<width>962</width>
|
||||||
<height>905</height>
|
<height>1033</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||||
@@ -256,6 +256,30 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</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>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||||
<item>
|
<item>
|
||||||
@@ -805,7 +829,7 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>AdvSceneSwitcher.macroTab.edit</string>
|
<string>AdvSceneSwitcher.macroTab.edit</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
<layout class="QVBoxLayout" name="verticalLayout_38">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0,0,0,0,0,0,0">
|
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0,0,0,0,0,0,0">
|
||||||
<item>
|
<item>
|
||||||
@@ -819,7 +843,7 @@
|
|||||||
<widget class="QLineEdit" name="macroName"/>
|
<widget class="QLineEdit" name="macroName"/>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="runMacro">
|
<widget class="advss::MacroRunButton" name="runMacro">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>AdvSceneSwitcher.macroTab.run</string>
|
<string>AdvSceneSwitcher.macroTab.run</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -912,6 +936,16 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="advss::MacroSegmentList" name="conditionsList">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>1</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
@@ -1066,170 +1100,360 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="macroActions" native="true">
|
<widget class="QSplitter" name="macroElseActionSplitter">
|
||||||
<layout class="QVBoxLayout" name="macroActionsLayout">
|
<property name="orientation">
|
||||||
<property name="leftMargin">
|
<enum>Qt::Vertical</enum>
|
||||||
<number>0</number>
|
</property>
|
||||||
</property>
|
<widget class="QWidget" name="macroActions" native="true">
|
||||||
<property name="topMargin">
|
<layout class="QVBoxLayout" name="macroActionsLayout">
|
||||||
<number>0</number>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="rightMargin">
|
</property>
|
||||||
<number>0</number>
|
<property name="topMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="bottomMargin">
|
</property>
|
||||||
<number>0</number>
|
<property name="rightMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<item>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
<property name="bottomMargin">
|
||||||
<property name="leftMargin">
|
<number>0</number>
|
||||||
<number>9</number>
|
</property>
|
||||||
</property>
|
<item>
|
||||||
<item>
|
<widget class="advss::MacroSegmentList" name="actionsList">
|
||||||
<widget class="QPushButton" name="actionAdd">
|
<property name="minimumSize">
|
||||||
<property name="maximumSize">
|
<size>
|
||||||
<size>
|
<width>0</width>
|
||||||
<width>22</width>
|
<height>1</height>
|
||||||
<height>16777215</height>
|
</size>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
<property name="flat">
|
</item>
|
||||||
<bool>true</bool>
|
<item>
|
||||||
</property>
|
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
||||||
<property name="themeID" stdset="0">
|
<property name="leftMargin">
|
||||||
<string notr="true">addIconSmall</string>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="actionAdd">
|
||||||
<item>
|
<property name="maximumSize">
|
||||||
<widget class="QPushButton" name="actionRemove">
|
<size>
|
||||||
<property name="maximumSize">
|
<width>22</width>
|
||||||
<size>
|
<height>16777215</height>
|
||||||
<width>22</width>
|
</size>
|
||||||
<height>16777215</height>
|
</property>
|
||||||
</size>
|
<property name="flat">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="flat">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="themeID" stdset="0">
|
||||||
</property>
|
<string notr="true">addIconSmall</string>
|
||||||
<property name="themeID" stdset="0">
|
</property>
|
||||||
<string notr="true">removeIconSmall</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="actionRemove">
|
||||||
<item>
|
<property name="maximumSize">
|
||||||
<spacer name="horizontalSpacer_133">
|
<size>
|
||||||
<property name="orientation">
|
<width>22</width>
|
||||||
<enum>Qt::Horizontal</enum>
|
<height>16777215</height>
|
||||||
</property>
|
</size>
|
||||||
<property name="sizeType">
|
</property>
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
<property name="flat">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="sizeHint" stdset="0">
|
</property>
|
||||||
<size>
|
<property name="themeID" stdset="0">
|
||||||
<width>5</width>
|
<string notr="true">removeIconSmall</string>
|
||||||
<height>20</height>
|
</property>
|
||||||
</size>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</spacer>
|
<item>
|
||||||
</item>
|
<spacer name="horizontalSpacer_133">
|
||||||
<item>
|
<property name="orientation">
|
||||||
<widget class="Line" name="line_47">
|
<enum>Qt::Horizontal</enum>
|
||||||
<property name="orientation">
|
</property>
|
||||||
<enum>Qt::Vertical</enum>
|
<property name="sizeType">
|
||||||
</property>
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="sizeHint" stdset="0">
|
||||||
<item>
|
<size>
|
||||||
<spacer name="horizontalSpacer_132">
|
<width>5</width>
|
||||||
<property name="orientation">
|
<height>20</height>
|
||||||
<enum>Qt::Horizontal</enum>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeType">
|
</spacer>
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
<property name="sizeHint" stdset="0">
|
<widget class="Line" name="line_47">
|
||||||
<size>
|
<property name="orientation">
|
||||||
<width>5</width>
|
<enum>Qt::Vertical</enum>
|
||||||
<height>20</height>
|
</property>
|
||||||
</size>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</spacer>
|
<item>
|
||||||
</item>
|
<spacer name="horizontalSpacer_132">
|
||||||
<item>
|
<property name="orientation">
|
||||||
<widget class="QPushButton" name="actionTop">
|
<enum>Qt::Horizontal</enum>
|
||||||
<property name="maximumSize">
|
</property>
|
||||||
<size>
|
<property name="sizeType">
|
||||||
<width>22</width>
|
<enum>QSizePolicy::Fixed</enum>
|
||||||
<height>16777215</height>
|
</property>
|
||||||
</size>
|
<property name="sizeHint" stdset="0">
|
||||||
</property>
|
<size>
|
||||||
<property name="flat">
|
<width>5</width>
|
||||||
<bool>true</bool>
|
<height>20</height>
|
||||||
</property>
|
</size>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</spacer>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QPushButton" name="actionUp">
|
<item>
|
||||||
<property name="maximumSize">
|
<widget class="QPushButton" name="actionTop">
|
||||||
<size>
|
<property name="maximumSize">
|
||||||
<width>22</width>
|
<size>
|
||||||
<height>16777215</height>
|
<width>22</width>
|
||||||
</size>
|
<height>16777215</height>
|
||||||
</property>
|
</size>
|
||||||
<property name="flat">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="flat">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="themeID" stdset="0">
|
</property>
|
||||||
<string notr="true">upArrowIconSmall</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="actionUp">
|
||||||
<item>
|
<property name="maximumSize">
|
||||||
<widget class="QPushButton" name="actionDown">
|
<size>
|
||||||
<property name="maximumSize">
|
<width>22</width>
|
||||||
<size>
|
<height>16777215</height>
|
||||||
<width>22</width>
|
</size>
|
||||||
<height>16777215</height>
|
</property>
|
||||||
</size>
|
<property name="flat">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="flat">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="themeID" stdset="0">
|
||||||
</property>
|
<string notr="true">upArrowIconSmall</string>
|
||||||
<property name="themeID" stdset="0">
|
</property>
|
||||||
<string notr="true">downArrowIconSmall</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="actionDown">
|
||||||
<item>
|
<property name="maximumSize">
|
||||||
<widget class="QPushButton" name="actionBottom">
|
<size>
|
||||||
<property name="maximumSize">
|
<width>22</width>
|
||||||
<size>
|
<height>16777215</height>
|
||||||
<width>22</width>
|
</size>
|
||||||
<height>16777215</height>
|
</property>
|
||||||
</size>
|
<property name="flat">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="flat">
|
</property>
|
||||||
<bool>true</bool>
|
<property name="themeID" stdset="0">
|
||||||
</property>
|
<string notr="true">downArrowIconSmall</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
</item>
|
||||||
<spacer name="horizontalSpacer_14">
|
<item>
|
||||||
<property name="orientation">
|
<widget class="QPushButton" name="actionBottom">
|
||||||
<enum>Qt::Horizontal</enum>
|
<property name="maximumSize">
|
||||||
</property>
|
<size>
|
||||||
<property name="sizeHint" stdset="0">
|
<width>22</width>
|
||||||
<size>
|
<height>16777215</height>
|
||||||
<width>40</width>
|
</size>
|
||||||
<height>20</height>
|
</property>
|
||||||
</size>
|
<property name="flat">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
</spacer>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
</layout>
|
</item>
|
||||||
</item>
|
<item>
|
||||||
</layout>
|
<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>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -4619,6 +4843,17 @@
|
|||||||
<extends>QListView</extends>
|
<extends>QListView</extends>
|
||||||
<header>macro-tree.hpp</header>
|
<header>macro-tree.hpp</header>
|
||||||
</customwidget>
|
</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>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|||||||
@@ -1,13 +1,3 @@
|
|||||||
#include <QMainWindow>
|
|
||||||
#include <QAction>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QDirIterator>
|
|
||||||
#include <regex>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include <obs-module.h>
|
|
||||||
#include <obs-frontend-api.h>
|
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
#include "switcher-data.hpp"
|
#include "switcher-data.hpp"
|
||||||
#include "status-control.hpp"
|
#include "status-control.hpp"
|
||||||
@@ -17,6 +7,15 @@
|
|||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
#include "version.h"
|
#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 {
|
namespace advss {
|
||||||
|
|
||||||
AdvSceneSwitcher *AdvSceneSwitcher::window = nullptr;
|
AdvSceneSwitcher *AdvSceneSwitcher::window = nullptr;
|
||||||
@@ -326,14 +325,19 @@ void SwitcherData::SetPreconditions()
|
|||||||
cursorPosChanged = cursorPos.first != switcher->lastCursorPos.first ||
|
cursorPosChanged = cursorPos.first != switcher->lastCursorPos.first ||
|
||||||
cursorPos.second != switcher->lastCursorPos.second;
|
cursorPos.second != switcher->lastCursorPos.second;
|
||||||
lastCursorPos = GetCursorPos();
|
lastCursorPos = GetCursorPos();
|
||||||
|
|
||||||
|
// Macro
|
||||||
|
InvalidateMacroTempVarValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearWebsocketMessages();
|
||||||
|
|
||||||
void SwitcherData::ResetForNextInterval()
|
void SwitcherData::ResetForNextInterval()
|
||||||
{
|
{
|
||||||
// Core reset functions
|
// Core reset functions
|
||||||
ClearWebsocketMessages();
|
ClearWebsocketMessages();
|
||||||
// Plugin reset functions
|
// Plugin reset functions
|
||||||
for (const auto &func : resetForNextIntervalFuncs) {
|
for (const auto &func : resetIntervalSteps) {
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ public slots:
|
|||||||
void on_saveWindowGeo_stateChanged(int state);
|
void on_saveWindowGeo_stateChanged(int state);
|
||||||
void on_showTrayNotifications_stateChanged(int state);
|
void on_showTrayNotifications_stateChanged(int state);
|
||||||
void on_uiHintsDisable_stateChanged(int state);
|
void on_uiHintsDisable_stateChanged(int state);
|
||||||
|
void on_disableComboBoxFilter_stateChanged(int state);
|
||||||
void on_warnPluginLoadFailure_stateChanged(int state);
|
void on_warnPluginLoadFailure_stateChanged(int state);
|
||||||
void on_hideLegacyTabs_stateChanged(int state);
|
void on_hideLegacyTabs_stateChanged(int state);
|
||||||
void on_priorityUp_clicked();
|
void on_priorityUp_clicked();
|
||||||
@@ -83,10 +84,13 @@ public:
|
|||||||
void SetEditMacro(Macro &m);
|
void SetEditMacro(Macro &m);
|
||||||
void SetMacroEditAreaDisabled(bool);
|
void SetMacroEditAreaDisabled(bool);
|
||||||
void HighlightAction(int idx, QColor color = QColor(Qt::green));
|
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 HighlightCondition(int idx, QColor color = QColor(Qt::green));
|
||||||
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
|
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 PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
|
||||||
void SetActionData(Macro &m);
|
void SetActionData(Macro &m);
|
||||||
|
void SetElseActionData(Macro &m);
|
||||||
void SetConditionData(Macro &m);
|
void SetConditionData(Macro &m);
|
||||||
void SwapActions(Macro *m, int pos1, int pos2);
|
void SwapActions(Macro *m, int pos1, int pos2);
|
||||||
void SwapConditions(Macro *m, int pos1, int pos2);
|
void SwapConditions(Macro *m, int pos1, int pos2);
|
||||||
@@ -97,7 +101,6 @@ public slots:
|
|||||||
void on_macroUp_clicked();
|
void on_macroUp_clicked();
|
||||||
void on_macroDown_clicked();
|
void on_macroDown_clicked();
|
||||||
void on_macroName_editingFinished();
|
void on_macroName_editingFinished();
|
||||||
void on_runMacro_clicked();
|
|
||||||
void on_runMacroInParallel_stateChanged(int value);
|
void on_runMacroInParallel_stateChanged(int value);
|
||||||
void on_runMacroOnChange_stateChanged(int value);
|
void on_runMacroOnChange_stateChanged(int value);
|
||||||
void on_conditionAdd_clicked();
|
void on_conditionAdd_clicked();
|
||||||
@@ -112,29 +115,50 @@ public slots:
|
|||||||
void on_actionUp_clicked();
|
void on_actionUp_clicked();
|
||||||
void on_actionDown_clicked();
|
void on_actionDown_clicked();
|
||||||
void on_actionBottom_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();
|
||||||
void UpMacroSegementHotkey();
|
void UpMacroSegementHotkey();
|
||||||
void DownMacroSegementHotkey();
|
void DownMacroSegementHotkey();
|
||||||
void DeleteMacroSegementHotkey();
|
void DeleteMacroSegementHotkey();
|
||||||
void ShowMacroContextMenu(const QPoint &);
|
void ShowMacroContextMenu(const QPoint &);
|
||||||
void ShowMacroActionsContextMenu(const QPoint &);
|
void ShowMacroActionsContextMenu(const QPoint &);
|
||||||
|
void ShowMacroElseActionsContextMenu(const QPoint &);
|
||||||
void ShowMacroConditionsContextMenu(const QPoint &);
|
void ShowMacroConditionsContextMenu(const QPoint &);
|
||||||
void CopyMacro();
|
void CopyMacro();
|
||||||
void RenameCurrentMacro();
|
void RenameCurrentMacro();
|
||||||
void ExportMacros();
|
void ExportMacros();
|
||||||
void ImportMacros();
|
void ImportMacros();
|
||||||
void ExpandAllActions();
|
void ExpandAllActions();
|
||||||
|
void ExpandAllElseActions();
|
||||||
void ExpandAllConditions();
|
void ExpandAllConditions();
|
||||||
void CollapseAllActions();
|
void CollapseAllActions();
|
||||||
|
void CollapseAllElseActions();
|
||||||
void CollapseAllConditions();
|
void CollapseAllConditions();
|
||||||
void MinimizeActions();
|
void MinimizeActions();
|
||||||
|
void MaximizeActions();
|
||||||
|
void MinimizeElseActions();
|
||||||
|
void MaximizeElseActions();
|
||||||
void MinimizeConditions();
|
void MinimizeConditions();
|
||||||
|
void MaximizeConditions();
|
||||||
void MacroActionSelectionChanged(int idx);
|
void MacroActionSelectionChanged(int idx);
|
||||||
void MacroActionReorder(int to, int target);
|
void MacroActionReorder(int to, int target);
|
||||||
void AddMacroAction(int idx);
|
void AddMacroAction(int idx);
|
||||||
void RemoveMacroAction(int idx);
|
void RemoveMacroAction(int idx);
|
||||||
void MoveMacroActionUp(int idx);
|
void MoveMacroActionUp(int idx);
|
||||||
void MoveMacroActionDown(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 MacroConditionSelectionChanged(int idx);
|
||||||
void MacroConditionReorder(int to, int target);
|
void MacroConditionReorder(int to, int target);
|
||||||
void AddMacroCondition(int idx);
|
void AddMacroCondition(int idx);
|
||||||
@@ -154,8 +178,10 @@ signals:
|
|||||||
void MacroRemoved(const QString &name);
|
void MacroRemoved(const QString &name);
|
||||||
void MacroRenamed(const QString &oldName, const QString &newName);
|
void MacroRenamed(const QString &oldName, const QString &newName);
|
||||||
void MacroSegmentOrderChanged();
|
void MacroSegmentOrderChanged();
|
||||||
|
void SegmentTempVarsChanged();
|
||||||
void HighlightMacrosChanged(bool value);
|
void HighlightMacrosChanged(bool value);
|
||||||
void HighlightActionsChanged(bool value);
|
void HighlightActionsChanged(bool value);
|
||||||
|
void HighlightElseActionsChanged(bool value);
|
||||||
void HighlightConditionsChanged(bool value);
|
void HighlightConditionsChanged(bool value);
|
||||||
|
|
||||||
void ConnectionAdded(const QString &);
|
void ConnectionAdded(const QString &);
|
||||||
@@ -166,19 +192,16 @@ signals:
|
|||||||
void VariableRemoved(const QString &);
|
void VariableRemoved(const QString &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
|
||||||
|
|
||||||
|
void SetupMacroSegmentSelection(MacroSection type, int idx);
|
||||||
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &);
|
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &);
|
||||||
bool MacroTabIsInFocus();
|
bool MacroTabIsInFocus();
|
||||||
|
|
||||||
MacroSegmentList *conditionsList = nullptr;
|
|
||||||
MacroSegmentList *actionsList = nullptr;
|
|
||||||
|
|
||||||
enum class MacroSection {
|
|
||||||
CONDITIONS,
|
|
||||||
ACTIONS,
|
|
||||||
};
|
|
||||||
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
||||||
int currentConditionIdx = -1;
|
int currentConditionIdx = -1;
|
||||||
int currentActionIdx = -1;
|
int currentActionIdx = -1;
|
||||||
|
int currentElseActionIdx = -1;
|
||||||
|
|
||||||
/* --- End of macro tab section --- */
|
/* --- End of macro tab section --- */
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "switcher-data.hpp"
|
#include "switcher-data.hpp"
|
||||||
#include "status-control.hpp"
|
#include "status-control.hpp"
|
||||||
#include "file-selection.hpp"
|
#include "file-selection.hpp"
|
||||||
|
#include "filter-combo-box.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@@ -131,10 +132,9 @@ void AdvSceneSwitcher::closeEvent(QCloseEvent *)
|
|||||||
}
|
}
|
||||||
switcher->windowPos = this->pos();
|
switcher->windowPos = this->pos();
|
||||||
switcher->windowSize = this->size();
|
switcher->windowSize = this->size();
|
||||||
switcher->macroActionConditionSplitterPosition =
|
|
||||||
ui->macroActionConditionSplitter->sizes();
|
|
||||||
switcher->macroListMacroEditSplitterPosition =
|
switcher->macroListMacroEditSplitterPosition =
|
||||||
ui->macroListMacroEditSplitter->sizes();
|
ui->macroListMacroEditSplitter->sizes();
|
||||||
|
MacroSelectionAboutToChange(); // Trigger saving of splitter states
|
||||||
|
|
||||||
obs_frontend_save();
|
obs_frontend_save();
|
||||||
}
|
}
|
||||||
@@ -175,6 +175,16 @@ void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
|
|||||||
switcher->disableHints = 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)
|
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -489,11 +499,19 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
|||||||
return;
|
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
|
// Needs to be loaded before any entries which might rely on scene group
|
||||||
// selections to be available.
|
// selections to be available.
|
||||||
loadSceneGroups(obj);
|
loadSceneGroups(obj);
|
||||||
LoadVariables(obj);
|
LoadVariables(obj);
|
||||||
LoadConnections(obj);
|
LoadConnections(obj);
|
||||||
|
|
||||||
|
for (const auto &func : loadSteps) {
|
||||||
|
func(obj);
|
||||||
|
}
|
||||||
|
|
||||||
LoadMacros(obj);
|
LoadMacros(obj);
|
||||||
loadWindowTitleSwitches(obj);
|
loadWindowTitleSwitches(obj);
|
||||||
loadScreenRegionSwitches(obj);
|
loadScreenRegionSwitches(obj);
|
||||||
@@ -514,6 +532,10 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
|||||||
LoadHotkeys(obj);
|
LoadHotkeys(obj);
|
||||||
LoadUISettings(obj);
|
LoadUISettings(obj);
|
||||||
|
|
||||||
|
for (const auto &func : postLoadSteps) {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
// Reset on startup and scene collection change
|
// Reset on startup and scene collection change
|
||||||
switcher->lastOpenedTab = -1;
|
switcher->lastOpenedTab = -1;
|
||||||
startupLoadDone = true;
|
startupLoadDone = true;
|
||||||
@@ -548,6 +570,10 @@ void SwitcherData::SaveSettings(obs_data_t *obj)
|
|||||||
SaveHotkeys(obj);
|
SaveHotkeys(obj);
|
||||||
SaveUISettings(obj);
|
SaveUISettings(obj);
|
||||||
SaveVersion(obj, g_GIT_SHA1);
|
SaveVersion(obj, g_GIT_SHA1);
|
||||||
|
|
||||||
|
for (const auto &func : saveSteps) {
|
||||||
|
func(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
||||||
@@ -575,6 +601,8 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
|||||||
obs_data_set_bool(obj, "showSystemTrayNotifications",
|
obs_data_set_bool(obj, "showSystemTrayNotifications",
|
||||||
showSystemTrayNotifications);
|
showSystemTrayNotifications);
|
||||||
obs_data_set_bool(obj, "disableHints", disableHints);
|
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, "warnPluginLoadFailure", warnPluginLoadFailure);
|
||||||
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
||||||
|
|
||||||
@@ -623,6 +651,8 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
showSystemTrayNotifications =
|
showSystemTrayNotifications =
|
||||||
obs_data_get_bool(obj, "showSystemTrayNotifications");
|
obs_data_get_bool(obj, "showSystemTrayNotifications");
|
||||||
disableHints = obs_data_get_bool(obj, "disableHints");
|
disableHints = obs_data_get_bool(obj, "disableHints");
|
||||||
|
disableFilterComboboxFilter =
|
||||||
|
obs_data_get_bool(obj, "disableFilterComboboxFilter");
|
||||||
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
|
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
|
||||||
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
|
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
|
||||||
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
||||||
@@ -652,34 +682,6 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
lastImportPath = obs_data_get_string(obj, "lastImportPath");
|
lastImportPath = obs_data_get_string(obj, "lastImportPath");
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static 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)
|
void SwitcherData::SaveUISettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
|
obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
|
||||||
@@ -707,9 +709,7 @@ void SwitcherData::SaveUISettings(obs_data_t *obj)
|
|||||||
obs_data_set_int(obj, "windowWidth", windowSize.width());
|
obs_data_set_int(obj, "windowWidth", windowSize.width());
|
||||||
obs_data_set_int(obj, "windowHeight", windowSize.height());
|
obs_data_set_int(obj, "windowHeight", windowSize.height());
|
||||||
|
|
||||||
saveSplitterPos(macroActionConditionSplitterPosition, obj,
|
SaveSplitterPos(macroListMacroEditSplitterPosition, obj,
|
||||||
"macroActionConditionSplitterPosition");
|
|
||||||
saveSplitterPos(macroListMacroEditSplitterPosition, obj,
|
|
||||||
"macroListMacroEditSplitterPosition");
|
"macroListMacroEditSplitterPosition");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,9 +763,8 @@ void SwitcherData::LoadUISettings(obs_data_t *obj)
|
|||||||
(int)obs_data_get_int(obj, "windowPosY")};
|
(int)obs_data_get_int(obj, "windowPosY")};
|
||||||
windowSize = {(int)obs_data_get_int(obj, "windowWidth"),
|
windowSize = {(int)obs_data_get_int(obj, "windowWidth"),
|
||||||
(int)obs_data_get_int(obj, "windowHeight")};
|
(int)obs_data_get_int(obj, "windowHeight")};
|
||||||
loadSplitterPos(macroActionConditionSplitterPosition, obj,
|
|
||||||
"macroActionConditionSplitterPosition");
|
LoadSplitterPos(macroListMacroEditSplitterPosition, obj,
|
||||||
loadSplitterPos(macroListMacroEditSplitterPosition, obj,
|
|
||||||
"macroListMacroEditSplitterPosition");
|
"macroListMacroEditSplitterPosition");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,6 +996,10 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
ui->showTrayNotifications->setChecked(
|
ui->showTrayNotifications->setChecked(
|
||||||
switcher->showSystemTrayNotifications);
|
switcher->showSystemTrayNotifications);
|
||||||
ui->uiHintsDisable->setChecked(switcher->disableHints);
|
ui->uiHintsDisable->setChecked(switcher->disableHints);
|
||||||
|
ui->disableComboBoxFilter->setChecked(
|
||||||
|
switcher->disableFilterComboboxFilter);
|
||||||
|
FilterComboBox::SetFilterBehaviourEnabled(
|
||||||
|
!switcher->disableFilterComboboxFilter);
|
||||||
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
||||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void SwitcherData::writeToStatusFile(const QString &msg)
|
|||||||
if (file.open(QIODevice::ReadWrite)) {
|
if (file.open(QIODevice::ReadWrite)) {
|
||||||
QTextStream stream(&file);
|
QTextStream stream(&file);
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
stream << msg << endl;
|
stream << msg << "\n";
|
||||||
#else
|
#else
|
||||||
stream << msg << Qt::endl;
|
stream << msg << Qt::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ bool IsFullscreen(const std::string &title)
|
|||||||
return windowStatesAreSet(title, states);
|
return windowStatesAreSet(title, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> GetTextInWindow(const std::string &window)
|
std::optional<std::string> GetTextInWindow(const std::string &)
|
||||||
{
|
{
|
||||||
// Not implemented
|
// Not implemented
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -39,6 +39,22 @@ const static std::map<MacroActionAudio::FadeType, std::string> fadeTypes = {
|
|||||||
constexpr auto fadeInterval = std::chrono::milliseconds(100);
|
constexpr auto fadeInterval = std::chrono::milliseconds(100);
|
||||||
constexpr float minFade = 0.000001f;
|
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)
|
void MacroActionAudio::SetFadeActive(bool value)
|
||||||
{
|
{
|
||||||
if (_action == Action::SOURCE_VOLUME) {
|
if (_action == Action::SOURCE_VOLUME) {
|
||||||
@@ -87,7 +103,7 @@ void MacroActionAudio::SetVolume(float vol)
|
|||||||
obs_source_set_volume(s, vol);
|
obs_source_set_volume(s, vol);
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
} else {
|
} else {
|
||||||
obs_set_master_volume(vol);
|
set_master_volume(vol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +118,7 @@ float MacroActionAudio::GetVolume()
|
|||||||
curVol = obs_source_get_volume(s);
|
curVol = obs_source_get_volume(s);
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
} else {
|
} else {
|
||||||
curVol = obs_get_master_volume();
|
curVol = get_master_volume();
|
||||||
}
|
}
|
||||||
return curVol;
|
return curVol;
|
||||||
}
|
}
|
||||||
@@ -287,15 +303,13 @@ std::string MacroActionAudio::GetShortDesc() const
|
|||||||
static inline void populateActionSelection(QComboBox *list)
|
static inline void populateActionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (const auto &[action, name] : actionTypes) {
|
for (const auto &[action, name] : actionTypes) {
|
||||||
if (action == MacroActionAudio::Action::MONITOR) {
|
if (action == MacroActionAudio::Action::MONITOR &&
|
||||||
if (obs_audio_monitoring_available()) {
|
!obs_audio_monitoring_available()) {
|
||||||
list->addItem(obs_module_text(name.c_str()),
|
continue;
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,6 +487,14 @@ void MacroActionAudioEdit::SetWidgetVisibility()
|
|||||||
_wait->setVisible(hasVolumeControl(_entryData->_action) &&
|
_wait->setVisible(hasVolumeControl(_entryData->_action) &&
|
||||||
_entryData->_fade);
|
_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();
|
updateGeometry();
|
||||||
adjustSize();
|
adjustSize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ void MacroActionEdit::ActionSelectionChanged(const QString &text)
|
|||||||
_entryData->reset();
|
_entryData->reset();
|
||||||
*_entryData = MacroActionFactory::Create(id, macro);
|
*_entryData = MacroActionFactory::Create(id, macro);
|
||||||
(*_entryData)->SetIndex(idx);
|
(*_entryData)->SetIndex(idx);
|
||||||
|
(*_entryData)->PostLoad();
|
||||||
}
|
}
|
||||||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||||
@@ -204,7 +205,7 @@ void MacroActionEdit::SetEnableAppearance(bool value)
|
|||||||
SetDisableEffect(!value);
|
SetDisableEffect(!value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MacroSegment> MacroActionEdit::Data()
|
std::shared_ptr<MacroSegment> MacroActionEdit::Data() const
|
||||||
{
|
{
|
||||||
return *_entryData;
|
return *_entryData;
|
||||||
}
|
}
|
||||||
@@ -236,10 +237,11 @@ void AdvSceneSwitcher::AddMacroAction(int idx)
|
|||||||
auto data = obs_data_create();
|
auto data = obs_data_create();
|
||||||
macro->Actions().at(idx - 1)->Save(data);
|
macro->Actions().at(idx - 1)->Save(data);
|
||||||
macro->Actions().at(idx)->Load(data);
|
macro->Actions().at(idx)->Load(data);
|
||||||
|
macro->Actions().at(idx)->PostLoad();
|
||||||
obs_data_release(data);
|
obs_data_release(data);
|
||||||
}
|
}
|
||||||
macro->UpdateActionIndices();
|
macro->UpdateActionIndices();
|
||||||
actionsList->Insert(
|
ui->actionsList->Insert(
|
||||||
idx,
|
idx,
|
||||||
new MacroActionEdit(this, ¯o->Actions()[idx], id));
|
new MacroActionEdit(this, ¯o->Actions()[idx], id));
|
||||||
SetActionData(*macro);
|
SetActionData(*macro);
|
||||||
@@ -263,7 +265,7 @@ void AdvSceneSwitcher::on_actionAdd_clicked()
|
|||||||
if (currentActionIdx != -1) {
|
if (currentActionIdx != -1) {
|
||||||
MacroActionSelectionChanged(currentActionIdx + 1);
|
MacroActionSelectionChanged(currentActionIdx + 1);
|
||||||
}
|
}
|
||||||
actionsList->SetHelpMsgVisible(false);
|
ui->actionsList->SetHelpMsgVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
||||||
@@ -279,7 +281,7 @@ void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
|||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
actionsList->Remove(idx);
|
ui->actionsList->Remove(idx);
|
||||||
macro->Actions().erase(macro->Actions().begin() + idx);
|
macro->Actions().erase(macro->Actions().begin() + idx);
|
||||||
switcher->abortMacroWait = true;
|
switcher->abortMacroWait = true;
|
||||||
switcher->macroWaitCv.notify_all();
|
switcher->macroWaitCv.notify_all();
|
||||||
@@ -322,10 +324,11 @@ void AdvSceneSwitcher::on_actionUp_clicked()
|
|||||||
MoveMacroActionUp(currentActionIdx);
|
MoveMacroActionUp(currentActionIdx);
|
||||||
MacroActionSelectionChanged(currentActionIdx - 1);
|
MacroActionSelectionChanged(currentActionIdx - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_actionDown_clicked()
|
void AdvSceneSwitcher::on_actionDown_clicked()
|
||||||
{
|
{
|
||||||
if (currentActionIdx == -1 ||
|
if (currentActionIdx == -1 ||
|
||||||
currentActionIdx == actionsList->ContentLayout()->count() - 1) {
|
currentActionIdx == ui->actionsList->ContentLayout()->count() - 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MoveMacroActionDown(currentActionIdx);
|
MoveMacroActionDown(currentActionIdx);
|
||||||
@@ -337,11 +340,82 @@ void AdvSceneSwitcher::on_actionBottom_clicked()
|
|||||||
if (currentActionIdx == -1) {
|
if (currentActionIdx == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int newIdx = actionsList->ContentLayout()->count() - 1;
|
const int newIdx = ui->actionsList->ContentLayout()->count() - 1;
|
||||||
MacroActionReorder(newIdx, currentActionIdx);
|
MacroActionReorder(newIdx, currentActionIdx);
|
||||||
MacroActionSelectionChanged(newIdx);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2)
|
void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2)
|
||||||
{
|
{
|
||||||
if (pos1 == pos2) {
|
if (pos1 == pos2) {
|
||||||
@@ -355,11 +429,11 @@ void AdvSceneSwitcher::SwapActions(Macro *m, int pos1, int pos2)
|
|||||||
iter_swap(m->Actions().begin() + pos1, m->Actions().begin() + pos2);
|
iter_swap(m->Actions().begin() + pos1, m->Actions().begin() + pos2);
|
||||||
m->UpdateActionIndices();
|
m->UpdateActionIndices();
|
||||||
auto widget1 = static_cast<MacroActionEdit *>(
|
auto widget1 = static_cast<MacroActionEdit *>(
|
||||||
actionsList->ContentLayout()->takeAt(pos1)->widget());
|
ui->actionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||||
auto widget2 = static_cast<MacroActionEdit *>(
|
auto widget2 = static_cast<MacroActionEdit *>(
|
||||||
actionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
ui->actionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
||||||
actionsList->Insert(pos1, widget2);
|
ui->actionsList->Insert(pos1, widget2);
|
||||||
actionsList->Insert(pos2, widget1);
|
ui->actionsList->Insert(pos2, widget1);
|
||||||
SetActionData(*m);
|
SetActionData(*m);
|
||||||
emit(MacroSegmentOrderChanged());
|
emit(MacroSegmentOrderChanged());
|
||||||
}
|
}
|
||||||
@@ -394,24 +468,159 @@ void AdvSceneSwitcher::MoveMacroActionDown(int idx)
|
|||||||
HighlightAction(idx + 1);
|
HighlightAction(idx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::MacroActionSelectionChanged(int idx)
|
void AdvSceneSwitcher::MacroElseActionSelectionChanged(int idx)
|
||||||
|
{
|
||||||
|
SetupMacroSegmentSelection(MacroSection::ELSE_ACTIONS, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroElseActionReorder(int to, int from)
|
||||||
{
|
{
|
||||||
auto macro = GetSelectedMacro();
|
auto macro = GetSelectedMacro();
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
actionsList->SetSelection(idx);
|
if (to == from || from < 0 || from > (int)macro->ElseActions().size() ||
|
||||||
conditionsList->SetSelection(-1);
|
to < 0 || to > (int)macro->ElseActions().size()) {
|
||||||
|
return;
|
||||||
if (idx < 0 || (unsigned)idx >= macro->Actions().size()) {
|
|
||||||
currentActionIdx = -1;
|
|
||||||
} else {
|
|
||||||
currentActionIdx = idx;
|
|
||||||
lastInteracted = MacroSection::ACTIONS;
|
|
||||||
}
|
}
|
||||||
currentConditionIdx = -1;
|
{
|
||||||
HighlightControls();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::MacroActionReorder(int to, int from)
|
void AdvSceneSwitcher::MacroActionReorder(int to, int from)
|
||||||
@@ -431,8 +640,8 @@ void AdvSceneSwitcher::MacroActionReorder(int to, int from)
|
|||||||
macro->Actions().erase(macro->Actions().begin() + from);
|
macro->Actions().erase(macro->Actions().begin() + from);
|
||||||
macro->Actions().insert(macro->Actions().begin() + to, action);
|
macro->Actions().insert(macro->Actions().begin() + to, action);
|
||||||
macro->UpdateActionIndices();
|
macro->UpdateActionIndices();
|
||||||
actionsList->ContentLayout()->insertItem(
|
ui->actionsList->ContentLayout()->insertItem(
|
||||||
to, actionsList->ContentLayout()->takeAt(from));
|
to, ui->actionsList->ContentLayout()->takeAt(from));
|
||||||
SetActionData(*macro);
|
SetActionData(*macro);
|
||||||
}
|
}
|
||||||
HighlightAction(to);
|
HighlightAction(to);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ private slots:
|
|||||||
void UpdateActionState();
|
void UpdateActionState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<MacroSegment> Data();
|
std::shared_ptr<MacroSegment> Data() const;
|
||||||
void SetDisableEffect(bool);
|
void SetDisableEffect(bool);
|
||||||
void SetEnableAppearance(bool);
|
void SetEnableAppearance(bool);
|
||||||
|
|
||||||
|
|||||||
@@ -21,26 +21,69 @@ const static std::map<MacroActionFilter::Action, std::string> actionTypes = {
|
|||||||
"AdvSceneSwitcher.action.filter.type.settings"},
|
"AdvSceneSwitcher.action.filter.type.settings"},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MacroActionFilter::PerformAction()
|
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)
|
||||||
{
|
{
|
||||||
auto s = obs_weak_source_get_source(_filter.GetFilter(_source));
|
OBSSourceAutoRelease source = obs_weak_source_get_source(filter);
|
||||||
switch (_action) {
|
switch (action) {
|
||||||
case Action::ENABLE:
|
case MacroActionFilter::Action::ENABLE:
|
||||||
obs_source_set_enabled(s, true);
|
obs_source_set_enabled(source, true);
|
||||||
break;
|
break;
|
||||||
case Action::DISABLE:
|
case MacroActionFilter::Action::DISABLE:
|
||||||
obs_source_set_enabled(s, false);
|
obs_source_set_enabled(source, false);
|
||||||
break;
|
break;
|
||||||
case Action::TOGGLE:
|
case MacroActionFilter::Action::TOGGLE:
|
||||||
obs_source_set_enabled(s, !obs_source_enabled(s));
|
obs_source_set_enabled(source, !obs_source_enabled(source));
|
||||||
break;
|
break;
|
||||||
case Action::SETTINGS:
|
case MacroActionFilter::Action::SETTINGS:
|
||||||
SetSourceSettings(s, _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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
obs_source_release(s);
|
}
|
||||||
|
|
||||||
|
bool MacroActionFilter::PerformAction()
|
||||||
|
{
|
||||||
|
auto filters = _filter.GetFilters(_source);
|
||||||
|
for (const auto &filter : filters) {
|
||||||
|
performActionHelper(_action, filter, _settingsInputMethod,
|
||||||
|
_setting, _manualSettingValue, _tempVar,
|
||||||
|
GetMacro(), _settingsString);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +107,12 @@ bool MacroActionFilter::Save(obs_data_t *obj) const
|
|||||||
_source.Save(obj);
|
_source.Save(obj);
|
||||||
_filter.Save(obj, "filter");
|
_filter.Save(obj, "filter");
|
||||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||||
_settings.Save(obj, "settings");
|
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);
|
obs_data_set_int(obj, "version", 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -85,7 +133,17 @@ bool MacroActionFilter::Load(obs_data_t *obj)
|
|||||||
} else {
|
} else {
|
||||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||||
}
|
}
|
||||||
_settings.Load(obj, "settings");
|
// 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());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +162,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(
|
MacroActionFilterEdit::MacroActionFilterEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionFilter> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionFilter> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
@@ -112,7 +179,12 @@ MacroActionFilterEdit::MacroActionFilterEdit(
|
|||||||
_actions(new QComboBox()),
|
_actions(new QComboBox()),
|
||||||
_getSettings(new QPushButton(obs_module_text(
|
_getSettings(new QPushButton(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.filter.getSettings"))),
|
"AdvSceneSwitcher.action.filter.getSettings"))),
|
||||||
_settings(new VariableTextEdit(this))
|
_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))
|
||||||
{
|
{
|
||||||
_filters->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
_filters->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||||
|
|
||||||
@@ -121,6 +193,8 @@ MacroActionFilterEdit::MacroActionFilterEdit(
|
|||||||
sources.sort();
|
sources.sort();
|
||||||
_sources->SetSourceNameList(sources);
|
_sources->SetSourceNameList(sources);
|
||||||
|
|
||||||
|
populateSettingsInputMethods(_settingsInputMethods);
|
||||||
|
|
||||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(ActionChanged(int)));
|
SLOT(ActionChanged(int)));
|
||||||
QWidget::connect(_sources,
|
QWidget::connect(_sources,
|
||||||
@@ -131,27 +205,48 @@ MacroActionFilterEdit::MacroActionFilterEdit(
|
|||||||
SLOT(FilterChanged(const FilterSelection &)));
|
SLOT(FilterChanged(const FilterSelection &)));
|
||||||
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
|
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
|
||||||
SLOT(GetSettingsClicked()));
|
SLOT(GetSettingsClicked()));
|
||||||
QWidget::connect(_settings, SIGNAL(textChanged()), this,
|
QWidget::connect(_settingsString, SIGNAL(textChanged()), this,
|
||||||
SLOT(SettingsChanged()));
|
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 &)));
|
||||||
|
|
||||||
QHBoxLayout *entryLayout = new QHBoxLayout;
|
auto entrylayout = new QHBoxLayout;
|
||||||
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{sources}}", _sources}, {"{{filters}}", _filters},
|
{"{{sources}}", _sources},
|
||||||
{"{{actions}}", _actions}, {"{{settings}}", _settings},
|
{"{{filters}}", _filters},
|
||||||
|
{"{{actions}}", _actions},
|
||||||
|
{"{{settings}}", _filterSettings},
|
||||||
|
{"{{settingsInputMethod}}", _settingsInputMethods},
|
||||||
|
{"{{settingValue}}", _manualSettingValue},
|
||||||
|
{"{{tempVar}}", _tempVars},
|
||||||
{"{{getSettings}}", _getSettings},
|
{"{{getSettings}}", _getSettings},
|
||||||
};
|
};
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.filter.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.filter.entry"),
|
||||||
entryLayout, widgetPlaceholders);
|
entrylayout, widgetPlaceholders);
|
||||||
|
_settingsLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
PlaceWidgets(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.filter.entry.settings"),
|
||||||
|
_settingsLayout, widgetPlaceholders);
|
||||||
|
|
||||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
auto buttonLayout = new QHBoxLayout;
|
||||||
buttonLayout->addWidget(_getSettings);
|
buttonLayout->addWidget(_getSettings);
|
||||||
buttonLayout->addStretch();
|
buttonLayout->addStretch();
|
||||||
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addLayout(entryLayout);
|
mainLayout->addLayout(entrylayout);
|
||||||
mainLayout->addWidget(_settings);
|
mainLayout->addLayout(_settingsLayout);
|
||||||
|
mainLayout->addWidget(_settingsString);
|
||||||
mainLayout->addLayout(buttonLayout);
|
mainLayout->addLayout(buttonLayout);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -169,12 +264,16 @@ void MacroActionFilterEdit::UpdateEntryData()
|
|||||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||||
_sources->SetSource(_entryData->_source);
|
_sources->SetSource(_entryData->_source);
|
||||||
_filters->SetFilter(_entryData->_source, _entryData->_filter);
|
_filters->SetFilter(_entryData->_source, _entryData->_filter);
|
||||||
_settings->setPlainText(_entryData->_settings);
|
_settingsString->setPlainText(_entryData->_settingsString);
|
||||||
SetWidgetVisibility(_entryData->_action ==
|
const auto filters =
|
||||||
MacroActionFilter::Action::SETTINGS);
|
_entryData->_filter.GetFilters(_entryData->_source);
|
||||||
|
_filterSettings->SetSource(filters.empty() ? nullptr : filters.at(0));
|
||||||
adjustSize();
|
_filterSettings->SetSetting(_entryData->_setting);
|
||||||
updateGeometry();
|
_settingsInputMethods->setCurrentIndex(_settingsInputMethods->findData(
|
||||||
|
static_cast<int>(_entryData->_settingsInputMethod)));
|
||||||
|
_tempVars->SetVariable(_entryData->_tempVar);
|
||||||
|
_manualSettingValue->setPlainText(_entryData->_manualSettingValue);
|
||||||
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionFilterEdit::SourceChanged(const SourceSelection &source)
|
void MacroActionFilterEdit::SourceChanged(const SourceSelection &source)
|
||||||
@@ -193,8 +292,13 @@ void MacroActionFilterEdit::FilterChanged(const FilterSelection &filter)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
{
|
||||||
_entryData->_filter = filter;
|
auto lock = LockContext();
|
||||||
|
_entryData->_filter = filter;
|
||||||
|
}
|
||||||
|
const auto filters =
|
||||||
|
_entryData->_filter.GetFilters(_entryData->_source);
|
||||||
|
_filterSettings->SetSource(filters.empty() ? nullptr : filters.at(0));
|
||||||
emit HeaderInfoChanged(
|
emit HeaderInfoChanged(
|
||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
}
|
}
|
||||||
@@ -207,38 +311,125 @@ void MacroActionFilterEdit::ActionChanged(int value)
|
|||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_action = static_cast<MacroActionFilter::Action>(value);
|
_entryData->_action = static_cast<MacroActionFilter::Action>(value);
|
||||||
SetWidgetVisibility(_entryData->_action ==
|
SetWidgetVisibility();
|
||||||
MacroActionFilter::Action::SETTINGS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionFilterEdit::GetSettingsClicked()
|
void MacroActionFilterEdit::GetSettingsClicked()
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData ||
|
if (_loading || !_entryData ||
|
||||||
!_entryData->_filter.GetFilter(_entryData->_source)) {
|
_entryData->_filter.GetFilters(_entryData->_source).empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_settings->setPlainText(FormatJsonString(GetSourceSettings(
|
switch (_entryData->_settingsInputMethod) {
|
||||||
_entryData->_filter.GetFilter(_entryData->_source))));
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionFilterEdit::SettingsChanged()
|
void MacroActionFilterEdit::SettingsStringChanged()
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_settings = _settings->toPlainText().toStdString();
|
_entryData->_settingsString =
|
||||||
|
_settingsString->toPlainText().toStdString();
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionFilterEdit::SetWidgetVisibility(bool showSettings)
|
void MacroActionFilterEdit::SettingsInputMethodChanged(int idx)
|
||||||
{
|
{
|
||||||
_settings->setVisible(showSettings);
|
if (_loading || !_entryData) {
|
||||||
_getSettings->setVisible(showSettings);
|
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();
|
||||||
|
|
||||||
|
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();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "variable-text-edit.hpp"
|
#include "variable-text-edit.hpp"
|
||||||
#include "source-selection.hpp"
|
#include "source-selection.hpp"
|
||||||
#include "filter-selection.hpp"
|
#include "filter-selection.hpp"
|
||||||
|
#include "source-setting.hpp"
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
@@ -31,10 +32,21 @@ public:
|
|||||||
SETTINGS,
|
SETTINGS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SettingsInputMethod {
|
||||||
|
INDIVIDUAL_MANUAL,
|
||||||
|
INDIVIDUAL_TEMPVAR,
|
||||||
|
JSON_STRING,
|
||||||
|
};
|
||||||
|
SettingsInputMethod _settingsInputMethod =
|
||||||
|
SettingsInputMethod::INDIVIDUAL_MANUAL;
|
||||||
|
|
||||||
SourceSelection _source;
|
SourceSelection _source;
|
||||||
FilterSelection _filter;
|
FilterSelection _filter;
|
||||||
Action _action = Action::ENABLE;
|
Action _action = Action::ENABLE;
|
||||||
StringVariable _settings = "";
|
StringVariable _settingsString = "";
|
||||||
|
TempVariableRef _tempVar;
|
||||||
|
StringVariable _manualSettingValue = "";
|
||||||
|
SourceSetting _setting;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
@@ -62,7 +74,11 @@ private slots:
|
|||||||
void FilterChanged(const FilterSelection &);
|
void FilterChanged(const FilterSelection &);
|
||||||
void ActionChanged(int value);
|
void ActionChanged(int value);
|
||||||
void GetSettingsClicked();
|
void GetSettingsClicked();
|
||||||
void SettingsChanged();
|
void SettingsStringChanged();
|
||||||
|
void SettingsInputMethodChanged(int);
|
||||||
|
void SelectionChanged(const TempVariableRef &);
|
||||||
|
void SelectionChanged(const SourceSetting &);
|
||||||
|
void ManualSettingsValueChanged();
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
@@ -71,11 +87,17 @@ protected:
|
|||||||
FilterSelectionWidget *_filters;
|
FilterSelectionWidget *_filters;
|
||||||
QComboBox *_actions;
|
QComboBox *_actions;
|
||||||
QPushButton *_getSettings;
|
QPushButton *_getSettings;
|
||||||
VariableTextEdit *_settings;
|
QHBoxLayout *_settingsLayout;
|
||||||
|
QComboBox *_settingsInputMethods;
|
||||||
|
VariableTextEdit *_manualSettingValue;
|
||||||
|
TempVariableSelection *_tempVars;
|
||||||
|
SourceSettingSelection *_filterSettings;
|
||||||
|
VariableTextEdit *_settingsString;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionFilter> _entryData;
|
std::shared_ptr<MacroActionFilter> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetWidgetVisibility(bool);
|
void SetWidgetVisibility();
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "platform-funcs.hpp"
|
#include "platform-funcs.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
#include <obs-interaction.h>
|
#include <obs-interaction.h>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
@@ -723,7 +724,7 @@ static QString getHotkeyDescriptionByName(const std::string &name)
|
|||||||
QString description = "";
|
QString description = "";
|
||||||
} params;
|
} params;
|
||||||
|
|
||||||
auto func = [](void *param, obs_hotkey_id id, obs_hotkey_t *hotkey) {
|
auto func = [](void *param, obs_hotkey_id, obs_hotkey_t *hotkey) {
|
||||||
auto params = static_cast<Parameters *>(param);
|
auto params = static_cast<Parameters *>(param);
|
||||||
std::string name = obs_hotkey_get_name(hotkey);
|
std::string name = obs_hotkey_get_name(hotkey);
|
||||||
addNamePrefix(name, hotkey);
|
addNamePrefix(name, hotkey);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ bool MacroActionMacro::PerformAction()
|
|||||||
break;
|
break;
|
||||||
case Action::RUN:
|
case Action::RUN:
|
||||||
if (!macro->Paused()) {
|
if (!macro->Paused()) {
|
||||||
macro->PerformActions();
|
macro->PerformActions(true, false, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Action::STOP:
|
case Action::STOP:
|
||||||
|
|||||||
@@ -10,22 +10,45 @@ bool MacroActionMedia::_registered = MacroActionFactory::Register(
|
|||||||
{MacroActionMedia::Create, MacroActionMediaEdit::Create,
|
{MacroActionMedia::Create, MacroActionMediaEdit::Create,
|
||||||
"AdvSceneSwitcher.action.media"});
|
"AdvSceneSwitcher.action.media"});
|
||||||
|
|
||||||
const static std::map<MediaAction, std::string> actionTypes = {
|
const static std::map<MacroActionMedia::Action, std::string> actionTypes = {
|
||||||
{MediaAction::PLAY, "AdvSceneSwitcher.action.media.type.play"},
|
{MacroActionMedia::Action::PLAY,
|
||||||
{MediaAction::PAUSE, "AdvSceneSwitcher.action.media.type.pause"},
|
"AdvSceneSwitcher.action.media.type.play"},
|
||||||
{MediaAction::STOP, "AdvSceneSwitcher.action.media.type.stop"},
|
{MacroActionMedia::Action::PAUSE,
|
||||||
{MediaAction::RESTART, "AdvSceneSwitcher.action.media.type.restart"},
|
"AdvSceneSwitcher.action.media.type.pause"},
|
||||||
{MediaAction::NEXT, "AdvSceneSwitcher.action.media.type.next"},
|
{MacroActionMedia::Action::STOP,
|
||||||
{MediaAction::PREVIOUS, "AdvSceneSwitcher.action.media.type.previous"},
|
"AdvSceneSwitcher.action.media.type.stop"},
|
||||||
{MediaAction::SEEK, "AdvSceneSwitcher.action.media.type.seek"},
|
{MacroActionMedia::Action::RESTART,
|
||||||
|
"AdvSceneSwitcher.action.media.type.restart"},
|
||||||
|
{MacroActionMedia::Action::NEXT,
|
||||||
|
"AdvSceneSwitcher.action.media.type.next"},
|
||||||
|
{MacroActionMedia::Action::PREVIOUS,
|
||||||
|
"AdvSceneSwitcher.action.media.type.previous"},
|
||||||
|
{MacroActionMedia::Action::SEEK_DURATION,
|
||||||
|
"AdvSceneSwitcher.action.media.type.seek.duration"},
|
||||||
|
{MacroActionMedia::Action::SEEK_PERCENTAGE,
|
||||||
|
"AdvSceneSwitcher.action.media.type.seek.percentage"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string MacroActionMedia::GetShortDesc() const
|
||||||
|
{
|
||||||
|
return _mediaSource.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMedia::SeekToPercentage(obs_source_t *source) const
|
||||||
|
{
|
||||||
|
auto totalTimeMs = obs_source_media_get_duration(source);
|
||||||
|
auto percentageTimeMs = round(totalTimeMs * _seekPercentage / 100);
|
||||||
|
|
||||||
|
obs_source_media_set_time(source, percentageTimeMs);
|
||||||
|
}
|
||||||
|
|
||||||
bool MacroActionMedia::PerformAction()
|
bool MacroActionMedia::PerformAction()
|
||||||
{
|
{
|
||||||
auto source = obs_weak_source_get_source(_mediaSource.GetSource());
|
auto source = obs_weak_source_get_source(_mediaSource.GetSource());
|
||||||
obs_media_state state = obs_source_media_get_state(source);
|
obs_media_state state = obs_source_media_get_state(source);
|
||||||
|
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case MediaAction::PLAY:
|
case Action::PLAY:
|
||||||
if (state == OBS_MEDIA_STATE_STOPPED ||
|
if (state == OBS_MEDIA_STATE_STOPPED ||
|
||||||
state == OBS_MEDIA_STATE_ENDED) {
|
state == OBS_MEDIA_STATE_ENDED) {
|
||||||
obs_source_media_restart(source);
|
obs_source_media_restart(source);
|
||||||
@@ -33,27 +56,31 @@ bool MacroActionMedia::PerformAction()
|
|||||||
obs_source_media_play_pause(source, false);
|
obs_source_media_play_pause(source, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MediaAction::PAUSE:
|
case Action::PAUSE:
|
||||||
obs_source_media_play_pause(source, true);
|
obs_source_media_play_pause(source, true);
|
||||||
break;
|
break;
|
||||||
case MediaAction::STOP:
|
case Action::STOP:
|
||||||
obs_source_media_stop(source);
|
obs_source_media_stop(source);
|
||||||
break;
|
break;
|
||||||
case MediaAction::RESTART:
|
case Action::RESTART:
|
||||||
obs_source_media_restart(source);
|
obs_source_media_restart(source);
|
||||||
break;
|
break;
|
||||||
case MediaAction::NEXT:
|
case Action::NEXT:
|
||||||
obs_source_media_next(source);
|
obs_source_media_next(source);
|
||||||
break;
|
break;
|
||||||
case MediaAction::PREVIOUS:
|
case Action::PREVIOUS:
|
||||||
obs_source_media_previous(source);
|
obs_source_media_previous(source);
|
||||||
break;
|
break;
|
||||||
case MediaAction::SEEK:
|
case Action::SEEK_DURATION:
|
||||||
obs_source_media_set_time(source, _seek.Milliseconds());
|
obs_source_media_set_time(source, _seekDuration.Milliseconds());
|
||||||
|
break;
|
||||||
|
case Action::SEEK_PERCENTAGE:
|
||||||
|
SeekToPercentage(source);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_release(source);
|
obs_source_release(source);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -73,39 +100,42 @@ void MacroActionMedia::LogAction() const
|
|||||||
bool MacroActionMedia::Save(obs_data_t *obj) const
|
bool MacroActionMedia::Save(obs_data_t *obj) const
|
||||||
{
|
{
|
||||||
MacroAction::Save(obj);
|
MacroAction::Save(obj);
|
||||||
_mediaSource.Save(obj, "mediaSource");
|
|
||||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||||
_seek.Save(obj);
|
_seekDuration.Save(obj);
|
||||||
|
_seekPercentage.Save(obj, "seekPercentage");
|
||||||
|
_mediaSource.Save(obj, "mediaSource");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroActionMedia::Load(obs_data_t *obj)
|
bool MacroActionMedia::Load(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
MacroAction::Load(obj);
|
MacroAction::Load(obj);
|
||||||
|
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||||
|
_seekDuration.Load(obj);
|
||||||
|
_seekPercentage.Load(obj, "seekPercentage");
|
||||||
_mediaSource.Load(obj, "mediaSource");
|
_mediaSource.Load(obj, "mediaSource");
|
||||||
_action = static_cast<MediaAction>(obs_data_get_int(obj, "action"));
|
|
||||||
_seek.Load(obj);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string MacroActionMedia::GetShortDesc() const
|
return true;
|
||||||
{
|
|
||||||
return _mediaSource.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void populateActionSelection(QComboBox *list)
|
static inline void populateActionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : actionTypes) {
|
for (const auto &[_, name] : actionTypes) {
|
||||||
list->addItem(obs_module_text(entry.second.c_str()));
|
list->addItem(obs_module_text(name.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroActionMediaEdit::MacroActionMediaEdit(
|
MacroActionMediaEdit::MacroActionMediaEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionMedia> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionMedia> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
|
||||||
_actions(new QComboBox()),
|
_actions(new QComboBox()),
|
||||||
_seek(new DurationSelection())
|
_seekDuration(new DurationSelection()),
|
||||||
|
_seekPercentage(new SliderSpinBox(
|
||||||
|
0, 100,
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.media.seek.percentage.label"))),
|
||||||
|
_sources(new SourceSelectionWidget(this, QStringList(), true))
|
||||||
{
|
{
|
||||||
populateActionSelection(_actions);
|
populateActionSelection(_actions);
|
||||||
auto sources = GetMediaSourceNames();
|
auto sources = GetMediaSourceNames();
|
||||||
@@ -114,39 +144,67 @@ MacroActionMediaEdit::MacroActionMediaEdit(
|
|||||||
|
|
||||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(ActionChanged(int)));
|
SLOT(ActionChanged(int)));
|
||||||
|
QWidget::connect(_seekDuration,
|
||||||
|
SIGNAL(DurationChanged(const Duration &)), this,
|
||||||
|
SLOT(SeekDurationChanged(const Duration &)));
|
||||||
|
QWidget::connect(
|
||||||
|
_seekPercentage,
|
||||||
|
SIGNAL(DoubleValueChanged(const NumberVariable<double> &)),
|
||||||
|
this,
|
||||||
|
SLOT(SeekPercentageChanged(const NumberVariable<double> &)));
|
||||||
QWidget::connect(_sources,
|
QWidget::connect(_sources,
|
||||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||||
SLOT(SourceChanged(const SourceSelection &)));
|
SLOT(SourceChanged(const SourceSelection &)));
|
||||||
QWidget::connect(_seek, SIGNAL(DurationChanged(const Duration &)), this,
|
|
||||||
SLOT(DurationChanged(const Duration &)));
|
|
||||||
|
|
||||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
auto layout = new QHBoxLayout;
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{mediaSources}}", _sources},
|
|
||||||
{"{{actions}}", _actions},
|
{"{{actions}}", _actions},
|
||||||
{"{{duration}}", _seek},
|
{"{{seekDuration}}", _seekDuration},
|
||||||
|
{"{{seekPercentage}}", _seekPercentage},
|
||||||
|
{"{{mediaSources}}", _sources},
|
||||||
};
|
};
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.media.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.media.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
layout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(layout);
|
||||||
|
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
UpdateEntryData();
|
UpdateEntryData();
|
||||||
_loading = false;
|
_loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMediaEdit::UpdateEntryData()
|
void MacroActionMediaEdit::ActionChanged(int value)
|
||||||
{
|
{
|
||||||
if (!_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_sources->SetSource(_entryData->_mediaSource);
|
auto lock = LockContext();
|
||||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
_entryData->_action = static_cast<MacroActionMedia::Action>(value);
|
||||||
_seek->SetDuration(_entryData->_seek);
|
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionMediaEdit::SeekDurationChanged(const Duration &seekDuration)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_seekDuration = seekDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMediaEdit::SeekPercentageChanged(
|
||||||
|
const NumberVariable<double> &seekPercentage)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_seekPercentage = seekPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionMediaEdit::SourceChanged(const SourceSelection &source)
|
void MacroActionMediaEdit::SourceChanged(const SourceSelection &source)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
@@ -159,34 +217,32 @@ void MacroActionMediaEdit::SourceChanged(const SourceSelection &source)
|
|||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMediaEdit::ActionChanged(int value)
|
|
||||||
{
|
|
||||||
if (_loading || !_entryData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
|
||||||
_entryData->_action = static_cast<MediaAction>(value);
|
|
||||||
SetWidgetVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMediaEdit::DurationChanged(const Duration &dur)
|
|
||||||
{
|
|
||||||
if (_loading || !_entryData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
|
||||||
_entryData->_seek = dur;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroActionMediaEdit::SetWidgetVisibility()
|
void MacroActionMediaEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
if (!_entryData) {
|
if (!_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_seek->setVisible(_entryData->_action == MediaAction::SEEK);
|
|
||||||
|
_seekDuration->setVisible(_entryData->_action ==
|
||||||
|
MacroActionMedia::Action::SEEK_DURATION);
|
||||||
|
_seekPercentage->setVisible(_entryData->_action ==
|
||||||
|
MacroActionMedia::Action::SEEK_PERCENTAGE);
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionMediaEdit::UpdateEntryData()
|
||||||
|
{
|
||||||
|
if (!_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||||
|
_seekDuration->SetDuration(_entryData->_seekDuration);
|
||||||
|
_seekPercentage->SetDoubleValue(_entryData->_seekPercentage);
|
||||||
|
_sources->SetSource(_entryData->_mediaSource);
|
||||||
|
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,42 +1,45 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
#include "slider-spinbox.hpp"
|
||||||
#include "source-selection.hpp"
|
#include "source-selection.hpp"
|
||||||
|
|
||||||
#include <QSpinBox>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
enum class MediaAction {
|
|
||||||
PLAY,
|
|
||||||
PAUSE,
|
|
||||||
STOP,
|
|
||||||
RESTART,
|
|
||||||
NEXT,
|
|
||||||
PREVIOUS,
|
|
||||||
SEEK,
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacroActionMedia : public MacroAction {
|
class MacroActionMedia : public MacroAction {
|
||||||
public:
|
public:
|
||||||
MacroActionMedia(Macro *m) : MacroAction(m) {}
|
MacroActionMedia(Macro *m) : MacroAction(m) {}
|
||||||
bool PerformAction();
|
|
||||||
void LogAction() const;
|
|
||||||
bool Save(obs_data_t *obj) const;
|
|
||||||
bool Load(obs_data_t *obj);
|
|
||||||
std::string GetShortDesc() const;
|
|
||||||
std::string GetId() const { return id; };
|
|
||||||
static std::shared_ptr<MacroAction> Create(Macro *m)
|
static std::shared_ptr<MacroAction> Create(Macro *m)
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionMedia>(m);
|
return std::make_shared<MacroActionMedia>(m);
|
||||||
}
|
}
|
||||||
|
std::string GetId() const { return id; };
|
||||||
|
std::string GetShortDesc() const;
|
||||||
|
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction() const;
|
||||||
|
bool Save(obs_data_t *obj) const;
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
|
||||||
|
enum class Action {
|
||||||
|
PLAY,
|
||||||
|
PAUSE,
|
||||||
|
STOP,
|
||||||
|
RESTART,
|
||||||
|
NEXT,
|
||||||
|
PREVIOUS,
|
||||||
|
SEEK_DURATION,
|
||||||
|
SEEK_PERCENTAGE,
|
||||||
|
};
|
||||||
|
|
||||||
|
Action _action = Action::PLAY;
|
||||||
|
Duration _seekDuration;
|
||||||
|
DoubleVariable _seekPercentage = 50;
|
||||||
SourceSelection _mediaSource;
|
SourceSelection _mediaSource;
|
||||||
MediaAction _action = MediaAction::PLAY;
|
|
||||||
Duration _seek;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SeekToPercentage(obs_source_t *source) const;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
@@ -48,7 +51,6 @@ public:
|
|||||||
MacroActionMediaEdit(
|
MacroActionMediaEdit(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
std::shared_ptr<MacroActionMedia> entryData = nullptr);
|
std::shared_ptr<MacroActionMedia> entryData = nullptr);
|
||||||
void UpdateEntryData();
|
|
||||||
static QWidget *Create(QWidget *parent,
|
static QWidget *Create(QWidget *parent,
|
||||||
std::shared_ptr<MacroAction> action)
|
std::shared_ptr<MacroAction> action)
|
||||||
{
|
{
|
||||||
@@ -56,24 +58,27 @@ public:
|
|||||||
parent,
|
parent,
|
||||||
std::dynamic_pointer_cast<MacroActionMedia>(action));
|
std::dynamic_pointer_cast<MacroActionMedia>(action));
|
||||||
}
|
}
|
||||||
|
void UpdateEntryData();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void SourceChanged(const SourceSelection &);
|
|
||||||
void ActionChanged(int value);
|
void ActionChanged(int value);
|
||||||
void DurationChanged(const Duration &value);
|
void SeekDurationChanged(const Duration &seekDuration);
|
||||||
|
void
|
||||||
|
SeekPercentageChanged(const NumberVariable<double> &seekPercentage);
|
||||||
|
void SourceChanged(const SourceSelection &source);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
|
||||||
SourceSelectionWidget *_sources;
|
|
||||||
QComboBox *_actions;
|
|
||||||
DurationSelection *_seek;
|
|
||||||
std::shared_ptr<MacroActionMedia> _entryData;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetWidgetVisibility();
|
void SetWidgetVisibility();
|
||||||
|
|
||||||
QHBoxLayout *_mainLayout;
|
QComboBox *_actions;
|
||||||
|
DurationSelection *_seekDuration;
|
||||||
|
SliderSpinBox *_seekPercentage;
|
||||||
|
SourceSelectionWidget *_sources;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroActionMedia> _entryData;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ bool MacroActionProjector::PerformAction()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_fullscreen && _monitor == -1) {
|
||||||
|
blog(LOG_INFO, "refusing to open fullscreen projector"
|
||||||
|
" with invalid display selection");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
obs_frontend_open_projector(type, _fullscreen ? _monitor : -1, "",
|
obs_frontend_open_projector(type, _fullscreen ? _monitor : -1, "",
|
||||||
name.c_str());
|
name.c_str());
|
||||||
|
|
||||||
@@ -85,6 +91,7 @@ bool MacroActionProjector::Save(obs_data_t *obj) const
|
|||||||
MacroAction::Save(obj);
|
MacroAction::Save(obj);
|
||||||
obs_data_set_int(obj, "type", static_cast<int>(_type));
|
obs_data_set_int(obj, "type", static_cast<int>(_type));
|
||||||
obs_data_set_int(obj, "monitor", _monitor);
|
obs_data_set_int(obj, "monitor", _monitor);
|
||||||
|
obs_data_set_string(obj, "monitorName", _monitorName.c_str());
|
||||||
obs_data_set_bool(obj, "fullscreen", _fullscreen);
|
obs_data_set_bool(obj, "fullscreen", _fullscreen);
|
||||||
_scene.Save(obj);
|
_scene.Save(obj);
|
||||||
_source.Save(obj);
|
_source.Save(obj);
|
||||||
@@ -96,12 +103,50 @@ bool MacroActionProjector::Load(obs_data_t *obj)
|
|||||||
MacroAction::Load(obj);
|
MacroAction::Load(obj);
|
||||||
_type = static_cast<Type>(obs_data_get_int(obj, "type"));
|
_type = static_cast<Type>(obs_data_get_int(obj, "type"));
|
||||||
_monitor = obs_data_get_int(obj, "monitor");
|
_monitor = obs_data_get_int(obj, "monitor");
|
||||||
|
_monitorName = obs_data_get_string(obj, "monitorName");
|
||||||
_fullscreen = obs_data_get_bool(obj, "fullscreen");
|
_fullscreen = obs_data_get_bool(obj, "fullscreen");
|
||||||
_scene.Load(obj);
|
_scene.Load(obj);
|
||||||
_source.Load(obj);
|
_source.Load(obj);
|
||||||
|
|
||||||
|
if (MonitorSetupChanged()) {
|
||||||
|
blog(LOG_INFO, "monitor setup seems to have changed! "
|
||||||
|
"resetting projector action monitor selection!");
|
||||||
|
_monitor = -1;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionProjector::SetMonitor(int idx)
|
||||||
|
{
|
||||||
|
_monitor = idx;
|
||||||
|
auto monitorNames = GetMonitorNames();
|
||||||
|
if (_monitor < 0 || _monitor >= monitorNames.size()) {
|
||||||
|
// Monitor setup changed while settings were selected?
|
||||||
|
_monitorName = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_monitorName = monitorNames.at(_monitor).toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MacroActionProjector::GetMonitor() const
|
||||||
|
{
|
||||||
|
return _monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionProjector::MonitorSetupChanged()
|
||||||
|
{
|
||||||
|
if (_monitorName.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto monitorNames = GetMonitorNames();
|
||||||
|
if (_monitor < 0 || _monitor >= monitorNames.size()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return monitorNames.at(_monitor) !=
|
||||||
|
QString::fromStdString(_monitorName);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void populateSelectionTypes(QComboBox *list)
|
static inline void populateSelectionTypes(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : selectionTypes) {
|
for (auto entry : selectionTypes) {
|
||||||
@@ -134,6 +179,8 @@ MacroActionProjectorEdit::MacroActionProjectorEdit(
|
|||||||
sources.sort();
|
sources.sort();
|
||||||
_sources->SetSourceNameList(sources);
|
_sources->SetSourceNameList(sources);
|
||||||
_monitors->addItems(GetMonitorNames());
|
_monitors->addItems(GetMonitorNames());
|
||||||
|
_monitors->setPlaceholderText(
|
||||||
|
obs_module_text("AdvSceneSwitcher.selectDisplay"));
|
||||||
|
|
||||||
QWidget::connect(_windowTypes, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_windowTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(WindowTypeChanged(int)));
|
SLOT(WindowTypeChanged(int)));
|
||||||
@@ -177,7 +224,7 @@ void MacroActionProjectorEdit::UpdateEntryData()
|
|||||||
_types->setCurrentIndex(static_cast<int>(_entryData->_type));
|
_types->setCurrentIndex(static_cast<int>(_entryData->_type));
|
||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_sources->SetSource(_entryData->_source);
|
_sources->SetSource(_entryData->_source);
|
||||||
_monitors->setCurrentIndex(_entryData->_monitor);
|
_monitors->setCurrentIndex(_entryData->GetMonitor());
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +255,7 @@ void MacroActionProjectorEdit::MonitorChanged(int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_monitor = value;
|
_entryData->SetMonitor(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionProjectorEdit::WindowTypeChanged(int)
|
void MacroActionProjectorEdit::WindowTypeChanged(int)
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public:
|
|||||||
{
|
{
|
||||||
return std::make_shared<MacroActionProjector>(m);
|
return std::make_shared<MacroActionProjector>(m);
|
||||||
}
|
}
|
||||||
|
void SetMonitor(int);
|
||||||
|
int GetMonitor() const;
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
SOURCE,
|
SOURCE,
|
||||||
@@ -29,10 +31,15 @@ public:
|
|||||||
Type _type = Type::SCENE;
|
Type _type = Type::SCENE;
|
||||||
SourceSelection _source;
|
SourceSelection _source;
|
||||||
SceneSelection _scene;
|
SceneSelection _scene;
|
||||||
int _monitor = 0;
|
|
||||||
bool _fullscreen = true;
|
bool _fullscreen = true;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool MonitorSetupChanged();
|
||||||
|
|
||||||
|
int _monitor = -1;
|
||||||
|
// Only used to detect display setup changes
|
||||||
|
std::string _monitorName = "";
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,12 +54,12 @@ bool MacroActionRandom::PerformAction()
|
|||||||
}
|
}
|
||||||
if (macros.size() == 1) {
|
if (macros.size() == 1) {
|
||||||
lastRandomMacro = macros[0];
|
lastRandomMacro = macros[0];
|
||||||
return macros[0]->PerformActions();
|
return macros[0]->PerformActions(true);
|
||||||
}
|
}
|
||||||
srand((unsigned int)time(0));
|
srand((unsigned int)time(0));
|
||||||
size_t idx = std::rand() % (macros.size());
|
size_t idx = std::rand() % (macros.size());
|
||||||
lastRandomMacro = macros[idx];
|
lastRandomMacro = macros[idx];
|
||||||
return macros[idx]->PerformActions();
|
return macros[idx]->PerformActions(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionRandom::LogAction() const
|
void MacroActionRandom::LogAction() const
|
||||||
|
|||||||
@@ -12,7 +12,15 @@ const std::string MacroActionSwitchScene::id = "scene_switch";
|
|||||||
bool MacroActionSwitchScene::_registered = MacroActionFactory::Register(
|
bool MacroActionSwitchScene::_registered = MacroActionFactory::Register(
|
||||||
MacroActionSwitchScene::id,
|
MacroActionSwitchScene::id,
|
||||||
{MacroActionSwitchScene::Create, MacroActionSwitchSceneEdit::Create,
|
{MacroActionSwitchScene::Create, MacroActionSwitchSceneEdit::Create,
|
||||||
"AdvSceneSwitcher.action.switchScene"});
|
"AdvSceneSwitcher.action.scene"});
|
||||||
|
|
||||||
|
const static std::map<MacroActionSwitchScene::SceneType, std::string>
|
||||||
|
sceneTypes = {
|
||||||
|
{MacroActionSwitchScene::SceneType::PROGRAM,
|
||||||
|
"AdvSceneSwitcher.action.scene.type.program"},
|
||||||
|
{MacroActionSwitchScene::SceneType::PREVIEW,
|
||||||
|
"AdvSceneSwitcher.action.scene.type.preview"},
|
||||||
|
};
|
||||||
|
|
||||||
static void waitForTransitionChange(OBSWeakSource &transition,
|
static void waitForTransitionChange(OBSWeakSource &transition,
|
||||||
std::unique_lock<std::mutex> *lock,
|
std::unique_lock<std::mutex> *lock,
|
||||||
@@ -126,6 +134,14 @@ bool MacroActionSwitchScene::WaitForTransition(OBSWeakSource &scene,
|
|||||||
bool MacroActionSwitchScene::PerformAction()
|
bool MacroActionSwitchScene::PerformAction()
|
||||||
{
|
{
|
||||||
auto scene = _scene.GetScene();
|
auto scene = _scene.GetScene();
|
||||||
|
|
||||||
|
if (_sceneType == SceneType::PREVIEW) {
|
||||||
|
OBSSourceAutoRelease previewScneSource =
|
||||||
|
obs_weak_source_get_source(scene);
|
||||||
|
obs_frontend_set_current_preview_scene(previewScneSource);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto transition = _transition.GetTransition();
|
auto transition = _transition.GetTransition();
|
||||||
SwitchScene({scene, transition, (int)(_duration.Milliseconds())},
|
SwitchScene({scene, transition, (int)(_duration.Milliseconds())},
|
||||||
obs_frontend_preview_program_mode_active());
|
obs_frontend_preview_program_mode_active());
|
||||||
@@ -137,24 +153,9 @@ bool MacroActionSwitchScene::PerformAction()
|
|||||||
|
|
||||||
void MacroActionSwitchScene::LogAction() const
|
void MacroActionSwitchScene::LogAction() const
|
||||||
{
|
{
|
||||||
auto t = _scene.GetType();
|
vblog(LOG_INFO, "switch%s scene to '%s'",
|
||||||
auto sceneName = GetWeakSourceName(_scene.GetScene(false));
|
_sceneType == SceneType::PREVIEW ? " preview" : "",
|
||||||
switch (t) {
|
_scene.ToString(true).c_str());
|
||||||
case SceneSelection::Type::SCENE:
|
|
||||||
vblog(LOG_INFO, "switch to scene '%s'",
|
|
||||||
_scene.ToString(true).c_str());
|
|
||||||
break;
|
|
||||||
case SceneSelection::Type::GROUP:
|
|
||||||
vblog(LOG_INFO, "switch to scene '%s' (scene group '%s')",
|
|
||||||
sceneName.c_str(), _scene.ToString(true).c_str());
|
|
||||||
break;
|
|
||||||
case SceneSelection::Type::PREVIOUS:
|
|
||||||
vblog(LOG_INFO, "switch to previous scene '%s'",
|
|
||||||
sceneName.c_str());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroActionSwitchScene::Save(obs_data_t *obj) const
|
bool MacroActionSwitchScene::Save(obs_data_t *obj) const
|
||||||
@@ -165,6 +166,7 @@ bool MacroActionSwitchScene::Save(obs_data_t *obj) const
|
|||||||
_duration.Save(obj);
|
_duration.Save(obj);
|
||||||
obs_data_set_bool(obj, "blockUntilTransitionDone",
|
obs_data_set_bool(obj, "blockUntilTransitionDone",
|
||||||
_blockUntilTransitionDone);
|
_blockUntilTransitionDone);
|
||||||
|
obs_data_set_int(obj, "sceneType", static_cast<int>(_sceneType));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,6 +178,7 @@ bool MacroActionSwitchScene::Load(obs_data_t *obj)
|
|||||||
_duration.Load(obj);
|
_duration.Load(obj);
|
||||||
_blockUntilTransitionDone =
|
_blockUntilTransitionDone =
|
||||||
obs_data_get_bool(obj, "blockUntilTransitionDone");
|
obs_data_get_bool(obj, "blockUntilTransitionDone");
|
||||||
|
_sceneType = static_cast<SceneType>(obs_data_get_int(obj, "sceneType"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +187,13 @@ std::string MacroActionSwitchScene::GetShortDesc() const
|
|||||||
return _scene.ToString();
|
return _scene.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void populateTypeSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
for (const auto &[_, name] : sceneTypes) {
|
||||||
|
list->addItem(obs_module_text(name.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
|
MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionSwitchScene> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionSwitchScene> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
@@ -192,9 +202,11 @@ MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
|
|||||||
_duration(new DurationSelection(parent, false)),
|
_duration(new DurationSelection(parent, false)),
|
||||||
_blockUntilTransitionDone(new QCheckBox(obs_module_text(
|
_blockUntilTransitionDone(new QCheckBox(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.scene.blockUntilTransitionDone"))),
|
"AdvSceneSwitcher.action.scene.blockUntilTransitionDone"))),
|
||||||
|
_sceneTypes(new QComboBox()),
|
||||||
_entryLayout(new QHBoxLayout())
|
_entryLayout(new QHBoxLayout())
|
||||||
{
|
{
|
||||||
_duration->SpinBox()->setSpecialValueText("-");
|
_duration->SpinBox()->setSpecialValueText("-");
|
||||||
|
populateTypeSelection(_sceneTypes);
|
||||||
|
|
||||||
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
||||||
this, SLOT(SceneChanged(const SceneSelection &)));
|
this, SLOT(SceneChanged(const SceneSelection &)));
|
||||||
@@ -206,28 +218,29 @@ MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
|
|||||||
this, SLOT(DurationChanged(const Duration &)));
|
this, SLOT(DurationChanged(const Duration &)));
|
||||||
QWidget::connect(_blockUntilTransitionDone, SIGNAL(stateChanged(int)),
|
QWidget::connect(_blockUntilTransitionDone, SIGNAL(stateChanged(int)),
|
||||||
this, SLOT(BlockUntilTransitionDoneChanged(int)));
|
this, SLOT(BlockUntilTransitionDoneChanged(int)));
|
||||||
|
QWidget::connect(_sceneTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(SceneTypeChanged(int)));
|
||||||
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
|
||||||
{"{{scenes}}", _scenes},
|
|
||||||
{"{{transitions}}", _transitions},
|
|
||||||
{"{{duration}}", _duration},
|
|
||||||
{"{{blockUntilTransitionDone}}", _blockUntilTransitionDone},
|
|
||||||
};
|
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.scene.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.scene.entry"),
|
||||||
_entryLayout, widgetPlaceholders);
|
_entryLayout,
|
||||||
|
{{"{{scenes}}", _scenes},
|
||||||
|
{"{{transitions}}", _transitions},
|
||||||
|
{"{{duration}}", _duration},
|
||||||
|
{"{{sceneTypes}}", _sceneTypes}});
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addLayout(_entryLayout);
|
mainLayout->addLayout(_entryLayout);
|
||||||
mainLayout->addWidget(_blockUntilTransitionDone);
|
mainLayout->addWidget(_blockUntilTransitionDone);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
|
_sceneTypes->setCurrentIndex(static_cast<int>(_entryData->_sceneType));
|
||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_transitions->SetTransition(_entryData->_transition);
|
_transitions->SetTransition(_entryData->_transition);
|
||||||
_duration->SetDuration(_entryData->_duration);
|
_duration->SetDuration(_entryData->_duration);
|
||||||
_blockUntilTransitionDone->setChecked(
|
_blockUntilTransitionDone->setChecked(
|
||||||
_entryData->_blockUntilTransitionDone);
|
_entryData->_blockUntilTransitionDone);
|
||||||
SetDurationVisibility();
|
SetWidgetVisibility();
|
||||||
_loading = false;
|
_loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +264,44 @@ void MacroActionSwitchSceneEdit::BlockUntilTransitionDoneChanged(int state)
|
|||||||
_entryData->_blockUntilTransitionDone = state;
|
_entryData->_blockUntilTransitionDone = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSwitchSceneEdit::SetDurationVisibility()
|
void MacroActionSwitchSceneEdit::SceneTypeChanged(int value)
|
||||||
{
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_sceneType =
|
||||||
|
static_cast<MacroActionSwitchScene::SceneType>(value);
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionSwitchSceneEdit::SetWidgetVisibility()
|
||||||
|
{
|
||||||
|
_entryLayout->removeWidget(_scenes);
|
||||||
|
_entryLayout->removeWidget(_transitions);
|
||||||
|
_entryLayout->removeWidget(_duration);
|
||||||
|
_entryLayout->removeWidget(_sceneTypes);
|
||||||
|
ClearLayout(_entryLayout);
|
||||||
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
|
{"{{scenes}}", _scenes},
|
||||||
|
{"{{transitions}}", _transitions},
|
||||||
|
{"{{duration}}", _duration},
|
||||||
|
{"{{sceneTypes}}", _sceneTypes},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (_entryData->_sceneType ==
|
||||||
|
MacroActionSwitchScene::SceneType::PREVIEW) {
|
||||||
|
_transitions->hide();
|
||||||
|
_duration->hide();
|
||||||
|
PlaceWidgets(
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.scene.entry.preview"),
|
||||||
|
_entryLayout, widgetPlaceholders);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_transitions->show();
|
||||||
if (_entryData->_transition.GetType() !=
|
if (_entryData->_transition.GetType() !=
|
||||||
TransitionSelection::Type::TRANSITION) {
|
TransitionSelection::Type::TRANSITION) {
|
||||||
_duration->show();
|
_duration->show();
|
||||||
@@ -261,15 +310,6 @@ void MacroActionSwitchSceneEdit::SetDurationVisibility()
|
|||||||
_entryData->_transition.GetTransition());
|
_entryData->_transition.GetTransition());
|
||||||
_duration->setVisible(!fixedDuration);
|
_duration->setVisible(!fixedDuration);
|
||||||
|
|
||||||
_entryLayout->removeWidget(_scenes);
|
|
||||||
_entryLayout->removeWidget(_transitions);
|
|
||||||
_entryLayout->removeWidget(_duration);
|
|
||||||
ClearLayout(_entryLayout);
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
|
||||||
{"{{scenes}}", _scenes},
|
|
||||||
{"{{transitions}}", _transitions},
|
|
||||||
{"{{duration}}", _duration},
|
|
||||||
};
|
|
||||||
if (fixedDuration) {
|
if (fixedDuration) {
|
||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
@@ -302,7 +342,7 @@ void MacroActionSwitchSceneEdit::TransitionChanged(const TransitionSelection &t)
|
|||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_transition = t;
|
_entryData->_transition = t;
|
||||||
SetDurationVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ public:
|
|||||||
{
|
{
|
||||||
return std::make_shared<MacroActionSwitchScene>(m);
|
return std::make_shared<MacroActionSwitchScene>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class SceneType { PROGRAM, PREVIEW };
|
||||||
|
SceneType _sceneType = SceneType::PROGRAM;
|
||||||
SceneSelection _scene;
|
SceneSelection _scene;
|
||||||
TransitionSelection _transition;
|
TransitionSelection _transition;
|
||||||
Duration _duration;
|
Duration _duration;
|
||||||
@@ -55,20 +58,21 @@ private slots:
|
|||||||
void TransitionChanged(const TransitionSelection &);
|
void TransitionChanged(const TransitionSelection &);
|
||||||
void DurationChanged(const Duration &seconds);
|
void DurationChanged(const Duration &seconds);
|
||||||
void BlockUntilTransitionDoneChanged(int state);
|
void BlockUntilTransitionDoneChanged(int state);
|
||||||
|
void SceneTypeChanged(int);
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
|
||||||
SceneSelectionWidget *_scenes;
|
SceneSelectionWidget *_scenes;
|
||||||
TransitionSelectionWidget *_transitions;
|
TransitionSelectionWidget *_transitions;
|
||||||
DurationSelection *_duration;
|
DurationSelection *_duration;
|
||||||
QCheckBox *_blockUntilTransitionDone;
|
QCheckBox *_blockUntilTransitionDone;
|
||||||
|
QComboBox *_sceneTypes;
|
||||||
QHBoxLayout *_entryLayout;
|
QHBoxLayout *_entryLayout;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionSwitchScene> _entryData;
|
std::shared_ptr<MacroActionSwitchScene> _entryData;
|
||||||
|
|
||||||
private:
|
|
||||||
void SetDurationVisibility();
|
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ bool MacroActionSequence::PerformAction()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return macro->PerformActions();
|
return macro->PerformActions(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSequence::LogAction() const
|
void MacroActionSequence::LogAction() const
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ const static std::map<MacroActionSource::Action, std::string> actionTypes = {
|
|||||||
"AdvSceneSwitcher.action.source.type.deinterlaceMode"},
|
"AdvSceneSwitcher.action.source.type.deinterlaceMode"},
|
||||||
{MacroActionSource::Action::DEINTERLACE_FIELD_ORDER,
|
{MacroActionSource::Action::DEINTERLACE_FIELD_ORDER,
|
||||||
"AdvSceneSwitcher.action.source.type.deinterlaceOrder"},
|
"AdvSceneSwitcher.action.source.type.deinterlaceOrder"},
|
||||||
|
{MacroActionSource::Action::OPEN_INTERACTION_DIALOG,
|
||||||
|
"AdvSceneSwitcher.action.source.type.openInteractionDialog"},
|
||||||
|
{MacroActionSource::Action::OPEN_FILTER_DIALOG,
|
||||||
|
"AdvSceneSwitcher.action.source.type.openFilterDialog"},
|
||||||
|
{MacroActionSource::Action::OPEN_PROPERTIES_DIALOG,
|
||||||
|
"AdvSceneSwitcher.action.source.type.openPropertiesDialog"},
|
||||||
};
|
};
|
||||||
|
|
||||||
const static std::map<obs_deinterlace_mode, std::string> deinterlaceModes = {
|
const static std::map<obs_deinterlace_mode, std::string> deinterlaceModes = {
|
||||||
@@ -58,6 +64,16 @@ const static std::map<obs_deinterlace_field_order, std::string>
|
|||||||
"AdvSceneSwitcher.action.source.deinterlaceOrder.bottomFieldFirst"},
|
"AdvSceneSwitcher.action.source.deinterlaceOrder.bottomFieldFirst"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const static std::map<MacroActionSource::SettingsInputMethod, std::string>
|
||||||
|
inputMethods = {
|
||||||
|
{MacroActionSource::SettingsInputMethod::INDIVIDUAL_MANUAL,
|
||||||
|
"AdvSceneSwitcher.action.source.inputMethod.individualManual"},
|
||||||
|
{MacroActionSource::SettingsInputMethod::INDIVIDUAL_TEMPVAR,
|
||||||
|
"AdvSceneSwitcher.action.source.inputMethod.individualTempvar"},
|
||||||
|
{MacroActionSource::SettingsInputMethod::JSON_STRING,
|
||||||
|
"AdvSceneSwitcher.action.source.inputMethod.json"},
|
||||||
|
};
|
||||||
|
|
||||||
static std::vector<SourceSettingButton> getSourceButtons(OBSWeakSource source)
|
static std::vector<SourceSettingButton> getSourceButtons(OBSWeakSource source)
|
||||||
{
|
{
|
||||||
auto s = obs_weak_source_get_source(source);
|
auto s = obs_weak_source_get_source(source);
|
||||||
@@ -73,6 +89,7 @@ static std::vector<SourceSettingButton> getSourceButtons(OBSWeakSource source)
|
|||||||
buttons.emplace_back(button);
|
buttons.emplace_back(button);
|
||||||
} while (obs_property_next(&it));
|
} while (obs_property_next(&it));
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
|
obs_properties_destroy(sourceProperties);
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +127,12 @@ static void refreshSourceSettings(obs_source_t *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isInteractable(obs_source_t *source)
|
||||||
|
{
|
||||||
|
uint32_t flags = obs_source_get_output_flags(source);
|
||||||
|
return (flags & OBS_SOURCE_INTERACTION) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool MacroActionSource::PerformAction()
|
bool MacroActionSource::PerformAction()
|
||||||
{
|
{
|
||||||
auto s = obs_weak_source_get_source(_source.GetSource());
|
auto s = obs_weak_source_get_source(_source.GetSource());
|
||||||
@@ -121,7 +144,26 @@ bool MacroActionSource::PerformAction()
|
|||||||
obs_source_set_enabled(s, false);
|
obs_source_set_enabled(s, false);
|
||||||
break;
|
break;
|
||||||
case Action::SETTINGS:
|
case Action::SETTINGS:
|
||||||
SetSourceSettings(s, _settings);
|
switch (_settingsInputMethod) {
|
||||||
|
case SettingsInputMethod::INDIVIDUAL_MANUAL:
|
||||||
|
SetSourceSetting(s, _setting, _manualSettingValue);
|
||||||
|
break;
|
||||||
|
case SettingsInputMethod::INDIVIDUAL_TEMPVAR: {
|
||||||
|
auto var = _tempVar.GetTempVariable(GetMacro());
|
||||||
|
if (!var) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto value = var->Value();
|
||||||
|
if (!value) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SetSourceSetting(s, _setting, *value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SettingsInputMethod::JSON_STRING:
|
||||||
|
SetSourceSettings(s, _settingsString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Action::REFRESH_SETTINGS:
|
case Action::REFRESH_SETTINGS:
|
||||||
refreshSourceSettings(s);
|
refreshSourceSettings(s);
|
||||||
@@ -135,6 +177,22 @@ bool MacroActionSource::PerformAction()
|
|||||||
case Action::DEINTERLACE_FIELD_ORDER:
|
case Action::DEINTERLACE_FIELD_ORDER:
|
||||||
obs_source_set_deinterlace_field_order(s, _deinterlaceOrder);
|
obs_source_set_deinterlace_field_order(s, _deinterlaceOrder);
|
||||||
break;
|
break;
|
||||||
|
case Action::OPEN_INTERACTION_DIALOG:
|
||||||
|
if (isInteractable(s)) {
|
||||||
|
obs_frontend_open_source_interaction(s);
|
||||||
|
} else {
|
||||||
|
blog(LOG_INFO,
|
||||||
|
"refusing to open interaction dialog "
|
||||||
|
"for non intractable source \"%s\"",
|
||||||
|
_source.ToString().c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Action::OPEN_FILTER_DIALOG:
|
||||||
|
obs_frontend_open_source_filters(s);
|
||||||
|
break;
|
||||||
|
case Action::OPEN_PROPERTIES_DIALOG:
|
||||||
|
obs_frontend_open_source_properties(s);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -160,7 +218,12 @@ bool MacroActionSource::Save(obs_data_t *obj) const
|
|||||||
_source.Save(obj);
|
_source.Save(obj);
|
||||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||||
_button.Save(obj);
|
_button.Save(obj);
|
||||||
_settings.Save(obj, "settings");
|
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, "deinterlaceMode",
|
obs_data_set_int(obj, "deinterlaceMode",
|
||||||
static_cast<int>(_deinterlaceMode));
|
static_cast<int>(_deinterlaceMode));
|
||||||
obs_data_set_int(obj, "deinterlaceOrder",
|
obs_data_set_int(obj, "deinterlaceOrder",
|
||||||
@@ -174,7 +237,17 @@ bool MacroActionSource::Load(obs_data_t *obj)
|
|||||||
_source.Load(obj);
|
_source.Load(obj);
|
||||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||||
_button.Load(obj);
|
_button.Load(obj);
|
||||||
_settings.Load(obj, "settings");
|
// 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());
|
||||||
_deinterlaceMode = static_cast<obs_deinterlace_mode>(
|
_deinterlaceMode = static_cast<obs_deinterlace_mode>(
|
||||||
obs_data_get_int(obj, "deinterlaceMode"));
|
obs_data_get_int(obj, "deinterlaceMode"));
|
||||||
_deinterlaceOrder = static_cast<obs_deinterlace_field_order>(
|
_deinterlaceOrder = static_cast<obs_deinterlace_field_order>(
|
||||||
@@ -237,19 +310,34 @@ static inline void populateDeinterlaceFieldOrderSelection(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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MacroActionSourceEdit::MacroActionSourceEdit(
|
MacroActionSourceEdit::MacroActionSourceEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionSource> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionSource> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||||
_actions(new QComboBox()),
|
_actions(new QComboBox()),
|
||||||
_settingsButtons(new QComboBox()),
|
_settingsButtons(new QComboBox()),
|
||||||
|
_settingsLayout(new QHBoxLayout()),
|
||||||
|
_settingsInputMethods(new QComboBox(this)),
|
||||||
|
_manualSettingValue(new VariableTextEdit(this, 5, 1, 1)),
|
||||||
|
_tempVars(new TempVariableSelection(this)),
|
||||||
|
_sourceSettings(new SourceSettingSelection(this)),
|
||||||
|
_settingsString(new VariableTextEdit(this)),
|
||||||
_getSettings(new QPushButton(obs_module_text(
|
_getSettings(new QPushButton(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.source.getSettings"))),
|
"AdvSceneSwitcher.action.source.getSettings"))),
|
||||||
_settings(new VariableTextEdit(this)),
|
|
||||||
_deinterlaceMode(new QComboBox()),
|
_deinterlaceMode(new QComboBox()),
|
||||||
_deinterlaceOrder(new QComboBox()),
|
_deinterlaceOrder(new QComboBox()),
|
||||||
_warning(new QLabel(
|
_warning(new QLabel(
|
||||||
obs_module_text("AdvSceneSwitcher.action.source.warning")))
|
obs_module_text("AdvSceneSwitcher.action.source.warning")))
|
||||||
|
|
||||||
{
|
{
|
||||||
populateActionSelection(_actions);
|
populateActionSelection(_actions);
|
||||||
auto sources = GetSourceNames();
|
auto sources = GetSourceNames();
|
||||||
@@ -257,6 +345,7 @@ MacroActionSourceEdit::MacroActionSourceEdit(
|
|||||||
_sources->SetSourceNameList(sources);
|
_sources->SetSourceNameList(sources);
|
||||||
populateDeinterlaceModeSelection(_deinterlaceMode);
|
populateDeinterlaceModeSelection(_deinterlaceMode);
|
||||||
populateDeinterlaceFieldOrderSelection(_deinterlaceOrder);
|
populateDeinterlaceFieldOrderSelection(_deinterlaceOrder);
|
||||||
|
populateSettingsInputMethods(_settingsInputMethods);
|
||||||
|
|
||||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(ActionChanged(int)));
|
SLOT(ActionChanged(int)));
|
||||||
@@ -267,20 +356,33 @@ MacroActionSourceEdit::MacroActionSourceEdit(
|
|||||||
SLOT(SourceChanged(const SourceSelection &)));
|
SLOT(SourceChanged(const SourceSelection &)));
|
||||||
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
|
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
|
||||||
SLOT(GetSettingsClicked()));
|
SLOT(GetSettingsClicked()));
|
||||||
QWidget::connect(_settings, SIGNAL(textChanged()), this,
|
QWidget::connect(_settingsString, SIGNAL(textChanged()), this,
|
||||||
SLOT(SettingsChanged()));
|
SLOT(SettingsStringChanged()));
|
||||||
QWidget::connect(_deinterlaceMode, SIGNAL(currentIndexChanged(int)),
|
QWidget::connect(_deinterlaceMode, SIGNAL(currentIndexChanged(int)),
|
||||||
this, SLOT(DeinterlaceModeChanged(int)));
|
this, SLOT(DeinterlaceModeChanged(int)));
|
||||||
QWidget::connect(_deinterlaceOrder, SIGNAL(currentIndexChanged(int)),
|
QWidget::connect(_deinterlaceOrder, SIGNAL(currentIndexChanged(int)),
|
||||||
this, SLOT(DeinterlaceOrderChanged(int)));
|
this, SLOT(DeinterlaceOrderChanged(int)));
|
||||||
|
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(_sourceSettings,
|
||||||
|
SIGNAL(SelectionChanged(const SourceSetting &)), this,
|
||||||
|
SLOT(SelectionChanged(const SourceSetting &)));
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
auto entryLayout = new QHBoxLayout;
|
||||||
QHBoxLayout *entryLayout = new QHBoxLayout;
|
entryLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{sources}}", _sources},
|
{"{{sources}}", _sources},
|
||||||
{"{{actions}}", _actions},
|
{"{{actions}}", _actions},
|
||||||
{"{{settings}}", _settings},
|
{"{{settings}}", _sourceSettings},
|
||||||
|
{"{{settingsInputMethod}}", _settingsInputMethods},
|
||||||
|
{"{{settingValue}}", _manualSettingValue},
|
||||||
|
{"{{tempVar}}", _tempVars},
|
||||||
{"{{getSettings}}", _getSettings},
|
{"{{getSettings}}", _getSettings},
|
||||||
{"{{settingsButtons}}", _settingsButtons},
|
{"{{settingsButtons}}", _settingsButtons},
|
||||||
{"{{deinterlaceMode}}", _deinterlaceMode},
|
{"{{deinterlaceMode}}", _deinterlaceMode},
|
||||||
@@ -288,9 +390,17 @@ MacroActionSourceEdit::MacroActionSourceEdit(
|
|||||||
};
|
};
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.source.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.source.entry"),
|
||||||
entryLayout, widgetPlaceholders);
|
entryLayout, widgetPlaceholders);
|
||||||
|
_settingsLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
PlaceWidgets(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.source.entry.settings"),
|
||||||
|
_settingsLayout, widgetPlaceholders);
|
||||||
|
auto mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addLayout(entryLayout);
|
mainLayout->addLayout(entryLayout);
|
||||||
|
mainLayout->addLayout(_settingsLayout);
|
||||||
mainLayout->addWidget(_warning);
|
mainLayout->addWidget(_warning);
|
||||||
mainLayout->addWidget(_settings);
|
mainLayout->addWidget(_settingsString);
|
||||||
|
auto buttonLayout = new QHBoxLayout;
|
||||||
|
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
buttonLayout->addWidget(_getSettings);
|
buttonLayout->addWidget(_getSettings);
|
||||||
buttonLayout->addStretch();
|
buttonLayout->addStretch();
|
||||||
mainLayout->addLayout(buttonLayout);
|
mainLayout->addLayout(buttonLayout);
|
||||||
@@ -311,13 +421,20 @@ void MacroActionSourceEdit::UpdateEntryData()
|
|||||||
_entryData->_source.GetSource());
|
_entryData->_source.GetSource());
|
||||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||||
_sources->SetSource(_entryData->_source);
|
_sources->SetSource(_entryData->_source);
|
||||||
|
_sourceSettings->SetSource(_entryData->_source.GetSource());
|
||||||
|
_sourceSettings->SetSetting(_entryData->_setting);
|
||||||
_settingsButtons->setCurrentText(
|
_settingsButtons->setCurrentText(
|
||||||
QString::fromStdString(_entryData->_button.ToString()));
|
QString::fromStdString(_entryData->_button.ToString()));
|
||||||
_settings->setPlainText(_entryData->_settings);
|
_settingsString->setPlainText(_entryData->_settingsString);
|
||||||
_deinterlaceMode->setCurrentIndex(_deinterlaceMode->findData(
|
_deinterlaceMode->setCurrentIndex(_deinterlaceMode->findData(
|
||||||
static_cast<int>(_entryData->_deinterlaceMode)));
|
static_cast<int>(_entryData->_deinterlaceMode)));
|
||||||
_deinterlaceOrder->setCurrentIndex(_deinterlaceOrder->findData(
|
_deinterlaceOrder->setCurrentIndex(_deinterlaceOrder->findData(
|
||||||
static_cast<int>(_entryData->_deinterlaceOrder)));
|
static_cast<int>(_entryData->_deinterlaceOrder)));
|
||||||
|
_settingsInputMethods->setCurrentIndex(_settingsInputMethods->findData(
|
||||||
|
static_cast<int>(_entryData->_settingsInputMethod)));
|
||||||
|
_tempVars->SetVariable(_entryData->_tempVar);
|
||||||
|
_manualSettingValue->setPlainText(_entryData->_manualSettingValue);
|
||||||
|
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,6 +450,7 @@ void MacroActionSourceEdit::SourceChanged(const SourceSelection &source)
|
|||||||
}
|
}
|
||||||
populateSourceButtonSelection(_settingsButtons,
|
populateSourceButtonSelection(_settingsButtons,
|
||||||
_entryData->_source.GetSource());
|
_entryData->_source.GetSource());
|
||||||
|
_sourceSettings->SetSource(_entryData->_source.GetSource());
|
||||||
emit HeaderInfoChanged(
|
emit HeaderInfoChanged(
|
||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
}
|
}
|
||||||
@@ -365,18 +483,29 @@ void MacroActionSourceEdit::GetSettingsClicked()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_settings->setPlainText(FormatJsonString(
|
switch (_entryData->_settingsInputMethod) {
|
||||||
GetSourceSettings(_entryData->_source.GetSource())));
|
case MacroActionSource::SettingsInputMethod::INDIVIDUAL_MANUAL:
|
||||||
|
_manualSettingValue->setPlainText(GetSourceSettingValue(
|
||||||
|
_entryData->_source.GetSource(), _entryData->_setting));
|
||||||
|
break;
|
||||||
|
case MacroActionSource::SettingsInputMethod::INDIVIDUAL_TEMPVAR:
|
||||||
|
break;
|
||||||
|
case MacroActionSource::SettingsInputMethod::JSON_STRING:
|
||||||
|
_settingsString->setPlainText(FormatJsonString(
|
||||||
|
GetSourceSettings(_entryData->_source.GetSource())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSourceEdit::SettingsChanged()
|
void MacroActionSourceEdit::SettingsStringChanged()
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_settings = _settings->toPlainText().toStdString();
|
_entryData->_settingsString =
|
||||||
|
_settingsString->toPlainText().toStdString();
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
@@ -405,15 +534,81 @@ void MacroActionSourceEdit::DeinterlaceOrderChanged(int idx)
|
|||||||
_deinterlaceOrder->itemData(idx).toInt());
|
_deinterlaceOrder->itemData(idx).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionSourceEdit::SelectionChanged(const TempVariableRef &var)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_tempVar = var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionSourceEdit::SettingsInputMethodChanged(int idx)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_settingsInputMethod =
|
||||||
|
static_cast<MacroActionSource::SettingsInputMethod>(
|
||||||
|
_settingsInputMethods->itemData(idx).toInt());
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionSourceEdit::SelectionChanged(const SourceSetting &setting)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_setting = setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionSourceEdit::ManualSettingsValueChanged()
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_manualSettingValue =
|
||||||
|
_manualSettingValue->toPlainText().toStdString();
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionSourceEdit::SetWidgetVisibility()
|
void MacroActionSourceEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
const bool showSettings = _entryData->_action ==
|
SetLayoutVisible(_settingsLayout,
|
||||||
MacroActionSource::Action::SETTINGS;
|
_entryData->_action ==
|
||||||
|
MacroActionSource::Action::SETTINGS);
|
||||||
|
_sourceSettings->setVisible(
|
||||||
|
_entryData->_action == MacroActionSource::Action::SETTINGS &&
|
||||||
|
_entryData->_settingsInputMethod !=
|
||||||
|
MacroActionSource::SettingsInputMethod::JSON_STRING);
|
||||||
|
_settingsString->setVisible(
|
||||||
|
_entryData->_action == MacroActionSource::Action::SETTINGS &&
|
||||||
|
_entryData->_settingsInputMethod ==
|
||||||
|
MacroActionSource::SettingsInputMethod::JSON_STRING);
|
||||||
|
_getSettings->setVisible(_entryData->_action ==
|
||||||
|
MacroActionSource::Action::SETTINGS);
|
||||||
|
_tempVars->setVisible(_entryData->_action ==
|
||||||
|
MacroActionSource::Action::SETTINGS &&
|
||||||
|
_entryData->_settingsInputMethod ==
|
||||||
|
MacroActionSource::SettingsInputMethod::
|
||||||
|
INDIVIDUAL_TEMPVAR);
|
||||||
|
_manualSettingValue->setVisible(
|
||||||
|
_entryData->_action == MacroActionSource::Action::SETTINGS &&
|
||||||
|
_entryData->_settingsInputMethod ==
|
||||||
|
MacroActionSource::SettingsInputMethod::
|
||||||
|
INDIVIDUAL_MANUAL);
|
||||||
const bool showWarning =
|
const bool showWarning =
|
||||||
_entryData->_action == MacroActionSource::Action::ENABLE ||
|
_entryData->_action == MacroActionSource::Action::ENABLE ||
|
||||||
_entryData->_action == MacroActionSource::Action::DISABLE;
|
_entryData->_action == MacroActionSource::Action::DISABLE;
|
||||||
_settings->setVisible(showSettings);
|
|
||||||
_getSettings->setVisible(showSettings);
|
|
||||||
_warning->setVisible(showWarning);
|
_warning->setVisible(showWarning);
|
||||||
_settingsButtons->setVisible(
|
_settingsButtons->setVisible(
|
||||||
_entryData->_action ==
|
_entryData->_action ==
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "variable-text-edit.hpp"
|
#include "variable-text-edit.hpp"
|
||||||
#include "source-selection.hpp"
|
#include "source-selection.hpp"
|
||||||
|
#include "source-setting.hpp"
|
||||||
|
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
@@ -35,10 +36,13 @@ public:
|
|||||||
|
|
||||||
SourceSelection _source;
|
SourceSelection _source;
|
||||||
SourceSettingButton _button;
|
SourceSettingButton _button;
|
||||||
StringVariable _settings = "";
|
StringVariable _settingsString = "";
|
||||||
|
StringVariable _manualSettingValue = "";
|
||||||
obs_deinterlace_mode _deinterlaceMode = OBS_DEINTERLACE_MODE_DISABLE;
|
obs_deinterlace_mode _deinterlaceMode = OBS_DEINTERLACE_MODE_DISABLE;
|
||||||
obs_deinterlace_field_order _deinterlaceOrder =
|
obs_deinterlace_field_order _deinterlaceOrder =
|
||||||
OBS_DEINTERLACE_FIELD_ORDER_TOP;
|
OBS_DEINTERLACE_FIELD_ORDER_TOP;
|
||||||
|
TempVariableRef _tempVar;
|
||||||
|
SourceSetting _setting;
|
||||||
|
|
||||||
enum class Action {
|
enum class Action {
|
||||||
ENABLE,
|
ENABLE,
|
||||||
@@ -48,8 +52,19 @@ public:
|
|||||||
SETTINGS_BUTTON,
|
SETTINGS_BUTTON,
|
||||||
DEINTERLACE_MODE,
|
DEINTERLACE_MODE,
|
||||||
DEINTERLACE_FIELD_ORDER,
|
DEINTERLACE_FIELD_ORDER,
|
||||||
|
OPEN_INTERACTION_DIALOG,
|
||||||
|
OPEN_FILTER_DIALOG,
|
||||||
|
OPEN_PROPERTIES_DIALOG,
|
||||||
};
|
};
|
||||||
Action _action = Action::ENABLE;
|
Action _action = Action::SETTINGS;
|
||||||
|
|
||||||
|
enum class SettingsInputMethod {
|
||||||
|
INDIVIDUAL_MANUAL,
|
||||||
|
INDIVIDUAL_TEMPVAR,
|
||||||
|
JSON_STRING,
|
||||||
|
};
|
||||||
|
SettingsInputMethod _settingsInputMethod =
|
||||||
|
SettingsInputMethod::INDIVIDUAL_MANUAL;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
@@ -77,9 +92,13 @@ private slots:
|
|||||||
void ActionChanged(int value);
|
void ActionChanged(int value);
|
||||||
void ButtonChanged(int idx);
|
void ButtonChanged(int idx);
|
||||||
void GetSettingsClicked();
|
void GetSettingsClicked();
|
||||||
void SettingsChanged();
|
void SettingsStringChanged();
|
||||||
void DeinterlaceModeChanged(int);
|
void DeinterlaceModeChanged(int);
|
||||||
void DeinterlaceOrderChanged(int);
|
void DeinterlaceOrderChanged(int);
|
||||||
|
void SelectionChanged(const TempVariableRef &);
|
||||||
|
void SettingsInputMethodChanged(int);
|
||||||
|
void SelectionChanged(const SourceSetting &);
|
||||||
|
void ManualSettingsValueChanged();
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
@@ -87,11 +106,17 @@ protected:
|
|||||||
SourceSelectionWidget *_sources;
|
SourceSelectionWidget *_sources;
|
||||||
QComboBox *_actions;
|
QComboBox *_actions;
|
||||||
QComboBox *_settingsButtons;
|
QComboBox *_settingsButtons;
|
||||||
|
QHBoxLayout *_settingsLayout;
|
||||||
|
QComboBox *_settingsInputMethods;
|
||||||
|
VariableTextEdit *_manualSettingValue;
|
||||||
|
TempVariableSelection *_tempVars;
|
||||||
|
SourceSettingSelection *_sourceSettings;
|
||||||
|
VariableTextEdit *_settingsString;
|
||||||
QPushButton *_getSettings;
|
QPushButton *_getSettings;
|
||||||
VariableTextEdit *_settings;
|
|
||||||
QComboBox *_deinterlaceMode;
|
QComboBox *_deinterlaceMode;
|
||||||
QComboBox *_deinterlaceOrder;
|
QComboBox *_deinterlaceOrder;
|
||||||
QLabel *_warning;
|
QLabel *_warning;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionSource> _entryData;
|
std::shared_ptr<MacroActionSource> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ bool MacroActionSudioMode::_registered = MacroActionFactory::Register(
|
|||||||
{MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
|
{MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
|
||||||
"AdvSceneSwitcher.action.studioMode"});
|
"AdvSceneSwitcher.action.studioMode"});
|
||||||
|
|
||||||
const static std::map<StudioModeAction, std::string> actionTypes = {
|
const static std::map<MacroActionSudioMode::Action, std::string> actionTypes = {
|
||||||
{StudioModeAction::SWAP_SCENE,
|
{MacroActionSudioMode::Action::SWAP_SCENE,
|
||||||
"AdvSceneSwitcher.action.studioMode.type.swap"},
|
"AdvSceneSwitcher.action.studioMode.type.swap"},
|
||||||
{StudioModeAction::SET_SCENE,
|
{MacroActionSudioMode::Action::SET_SCENE,
|
||||||
"AdvSceneSwitcher.action.studioMode.type.setScene"},
|
"AdvSceneSwitcher.action.studioMode.type.setScene"},
|
||||||
{StudioModeAction::ENABLE_STUDIO_MODE,
|
{MacroActionSudioMode::Action::ENABLE_STUDIO_MODE,
|
||||||
"AdvSceneSwitcher.action.studioMode.type.enable"},
|
"AdvSceneSwitcher.action.studioMode.type.enable"},
|
||||||
{StudioModeAction::DISABLE_STUDIO_MODE,
|
{MacroActionSudioMode::Action::DISABLE_STUDIO_MODE,
|
||||||
"AdvSceneSwitcher.action.studioMode.type.disable"},
|
"AdvSceneSwitcher.action.studioMode.type.disable"},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,19 +41,19 @@ static void enableStudioMode(bool enable)
|
|||||||
bool MacroActionSudioMode::PerformAction()
|
bool MacroActionSudioMode::PerformAction()
|
||||||
{
|
{
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case StudioModeAction::SWAP_SCENE:
|
case Action::SWAP_SCENE:
|
||||||
obs_frontend_preview_program_trigger_transition();
|
obs_frontend_preview_program_trigger_transition();
|
||||||
break;
|
break;
|
||||||
case StudioModeAction::SET_SCENE: {
|
case Action::SET_SCENE: {
|
||||||
auto s = obs_weak_source_get_source(_scene.GetScene());
|
auto s = obs_weak_source_get_source(_scene.GetScene());
|
||||||
obs_frontend_set_current_preview_scene(s);
|
obs_frontend_set_current_preview_scene(s);
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StudioModeAction::ENABLE_STUDIO_MODE:
|
case Action::ENABLE_STUDIO_MODE:
|
||||||
enableStudioMode(true);
|
enableStudioMode(true);
|
||||||
break;
|
break;
|
||||||
case StudioModeAction::DISABLE_STUDIO_MODE:
|
case Action::DISABLE_STUDIO_MODE:
|
||||||
enableStudioMode(false);
|
enableStudioMode(false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -86,15 +86,14 @@ bool MacroActionSudioMode::Save(obs_data_t *obj) const
|
|||||||
bool MacroActionSudioMode::Load(obs_data_t *obj)
|
bool MacroActionSudioMode::Load(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
MacroAction::Load(obj);
|
MacroAction::Load(obj);
|
||||||
_action =
|
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||||
static_cast<StudioModeAction>(obs_data_get_int(obj, "action"));
|
|
||||||
_scene.Load(obj);
|
_scene.Load(obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MacroActionSudioMode::GetShortDesc() const
|
std::string MacroActionSudioMode::GetShortDesc() const
|
||||||
{
|
{
|
||||||
if (_action == StudioModeAction::SET_SCENE) {
|
if (_action == Action::SET_SCENE) {
|
||||||
return _scene.ToString();
|
return _scene.ToString();
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@@ -102,8 +101,9 @@ std::string MacroActionSudioMode::GetShortDesc() const
|
|||||||
|
|
||||||
static inline void populateActionSelection(QComboBox *list)
|
static inline void populateActionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : actionTypes) {
|
for (const auto &[id, name] : actionTypes) {
|
||||||
list->addItem(obs_module_text(entry.second.c_str()));
|
list->addItem(obs_module_text(name.c_str()),
|
||||||
|
static_cast<int>(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,9 +139,10 @@ void MacroActionSudioModeEdit::UpdateEntryData()
|
|||||||
if (!_entryData) {
|
if (!_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
_actions->setCurrentIndex(
|
||||||
|
_actions->findData(static_cast<int>(_entryData->_action)));
|
||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_scenes->setVisible(_entryData->_action == StudioModeAction::SET_SCENE);
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSudioModeEdit::SceneChanged(const SceneSelection &s)
|
void MacroActionSudioModeEdit::SceneChanged(const SceneSelection &s)
|
||||||
@@ -156,15 +157,27 @@ void MacroActionSudioModeEdit::SceneChanged(const SceneSelection &s)
|
|||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionSudioModeEdit::ActionChanged(int value)
|
void MacroActionSudioModeEdit::SetWidgetVisibility()
|
||||||
|
{
|
||||||
|
_scenes->setVisible(_entryData->_action ==
|
||||||
|
MacroActionSudioMode::Action::SET_SCENE);
|
||||||
|
|
||||||
|
if (_entryData->_action != MacroActionSudioMode::Action::SET_SCENE) {
|
||||||
|
_actions->removeItem(_actions->findData(static_cast<int>(
|
||||||
|
MacroActionSudioMode::Action::SET_SCENE)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionSudioModeEdit::ActionChanged(int index)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_action = static_cast<StudioModeAction>(value);
|
_entryData->_action = static_cast<MacroActionSudioMode::Action>(
|
||||||
_scenes->setVisible(_entryData->_action == StudioModeAction::SET_SCENE);
|
_actions->itemData(index).toInt());
|
||||||
|
SetWidgetVisibility();
|
||||||
emit HeaderInfoChanged(
|
emit HeaderInfoChanged(
|
||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,6 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
enum class StudioModeAction {
|
|
||||||
SWAP_SCENE,
|
|
||||||
SET_SCENE,
|
|
||||||
ENABLE_STUDIO_MODE,
|
|
||||||
DISABLE_STUDIO_MODE,
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacroActionSudioMode : public MacroAction {
|
class MacroActionSudioMode : public MacroAction {
|
||||||
public:
|
public:
|
||||||
MacroActionSudioMode(Macro *m) : MacroAction(m) {}
|
MacroActionSudioMode(Macro *m) : MacroAction(m) {}
|
||||||
@@ -25,7 +18,14 @@ public:
|
|||||||
return std::make_shared<MacroActionSudioMode>(m);
|
return std::make_shared<MacroActionSudioMode>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioModeAction _action = StudioModeAction::SWAP_SCENE;
|
enum class Action {
|
||||||
|
SWAP_SCENE,
|
||||||
|
SET_SCENE, // TODO: Remove in future version as the
|
||||||
|
// functionality moved to the scene switch action
|
||||||
|
ENABLE_STUDIO_MODE,
|
||||||
|
DISABLE_STUDIO_MODE,
|
||||||
|
};
|
||||||
|
Action _action = Action::SWAP_SCENE;
|
||||||
SceneSelection _scene;
|
SceneSelection _scene;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -55,12 +55,13 @@ private slots:
|
|||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
|
||||||
QComboBox *_actions;
|
QComboBox *_actions;
|
||||||
SceneSelectionWidget *_scenes;
|
SceneSelectionWidget *_scenes;
|
||||||
std::shared_ptr<MacroActionSudioMode> _entryData;
|
std::shared_ptr<MacroActionSudioMode> _entryData;
|
||||||
|
|
||||||
private:
|
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,16 @@ const static std::map<MacroActionVariable::Type, std::string> actionTypes = {
|
|||||||
"AdvSceneSwitcher.action.variable.type.mathExpression"},
|
"AdvSceneSwitcher.action.variable.type.mathExpression"},
|
||||||
{MacroActionVariable::Type::USER_INPUT,
|
{MacroActionVariable::Type::USER_INPUT,
|
||||||
"AdvSceneSwitcher.action.variable.type.askForValue"},
|
"AdvSceneSwitcher.action.variable.type.askForValue"},
|
||||||
|
{MacroActionVariable::Type::ENV_VARIABLE,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.environmentVariable"},
|
||||||
|
{MacroActionVariable::Type::SCENE_ITEM_COUNT,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.sceneItemCount"},
|
||||||
|
{MacroActionVariable::Type::STRING_LENGTH,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.stringLength"},
|
||||||
|
{MacroActionVariable::Type::EXTRACT_JSON,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.extractJson"},
|
||||||
|
{MacroActionVariable::Type::SET_TO_TEMPVAR,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.setToTempvar"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void apppend(Variable &var, const std::string &value)
|
static void apppend(Variable &var, const std::string &value)
|
||||||
@@ -126,6 +136,7 @@ void MacroActionVariable::HandleMathExpression(Variable *var)
|
|||||||
|
|
||||||
struct AskForInputParams {
|
struct AskForInputParams {
|
||||||
QString prompt;
|
QString prompt;
|
||||||
|
QString placeholder;
|
||||||
std::optional<std::string> result;
|
std::optional<std::string> result;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -134,6 +145,7 @@ static void askForInput(void *param)
|
|||||||
auto parameters = static_cast<AskForInputParams *>(param);
|
auto parameters = static_cast<AskForInputParams *>(param);
|
||||||
auto dialog = new NonModalMessageDialog(
|
auto dialog = new NonModalMessageDialog(
|
||||||
parameters->prompt, NonModalMessageDialog::Type::INPUT);
|
parameters->prompt, NonModalMessageDialog::Type::INPUT);
|
||||||
|
dialog->SetInput(parameters->placeholder);
|
||||||
parameters->result = dialog->GetInput();
|
parameters->result = dialog->GetInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +225,9 @@ bool MacroActionVariable::PerformAction()
|
|||||||
"AdvSceneSwitcher.action.variable.askForValuePromptDefault"))
|
"AdvSceneSwitcher.action.variable.askForValuePromptDefault"))
|
||||||
.arg(QString::fromStdString(
|
.arg(QString::fromStdString(
|
||||||
var->Name())),
|
var->Name())),
|
||||||
|
_useCustomPrompt && _useInputPlaceholder
|
||||||
|
? QString::fromStdString(_inputPlaceholder)
|
||||||
|
: "",
|
||||||
{}};
|
{}};
|
||||||
obs_queue_task(OBS_TASK_UI, askForInput, ¶ms, true);
|
obs_queue_task(OBS_TASK_UI, askForInput, ¶ms, true);
|
||||||
if (!params.result.has_value()) {
|
if (!params.result.has_value()) {
|
||||||
@@ -221,6 +236,38 @@ bool MacroActionVariable::PerformAction()
|
|||||||
var->SetValue(*params.result);
|
var->SetValue(*params.result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case Type::ENV_VARIABLE: {
|
||||||
|
var->SetValue(std::getenv(_envVariableName.c_str()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case Type::SCENE_ITEM_COUNT: {
|
||||||
|
var->SetValue(GetSceneItemCount(_scene.GetScene(false)));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case Type::STRING_LENGTH: {
|
||||||
|
var->SetValue(std::string(_strValue).length());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case Type::EXTRACT_JSON: {
|
||||||
|
auto value = GetJsonField(var->Value(), _strValue);
|
||||||
|
if (!value.has_value()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var->SetValue(*value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case Type::SET_TO_TEMPVAR: {
|
||||||
|
auto tempVar = _tempVar.GetTempVariable(GetMacro());
|
||||||
|
if (!tempVar) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto value = tempVar->Value();
|
||||||
|
if (!value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var->SetValue(*value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -233,7 +280,7 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
|
|||||||
GetWeakVariableName(_variable).c_str());
|
GetWeakVariableName(_variable).c_str());
|
||||||
obs_data_set_string(obj, "variable2Name",
|
obs_data_set_string(obj, "variable2Name",
|
||||||
GetWeakVariableName(_variable2).c_str());
|
GetWeakVariableName(_variable2).c_str());
|
||||||
obs_data_set_string(obj, "strValue", _strValue.c_str());
|
_strValue.Save(obj, "strValue");
|
||||||
obs_data_set_double(obj, "numValue", _numValue);
|
obs_data_set_double(obj, "numValue", _numValue);
|
||||||
obs_data_set_int(obj, "condition", static_cast<int>(_type));
|
obs_data_set_int(obj, "condition", static_cast<int>(_type));
|
||||||
obs_data_set_int(obj, "segmentIdx", GetSegmentIndexValue());
|
obs_data_set_int(obj, "segmentIdx", GetSegmentIndexValue());
|
||||||
@@ -241,12 +288,17 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
|
|||||||
obs_data_set_int(obj, "subStringSize", _subStringSize);
|
obs_data_set_int(obj, "subStringSize", _subStringSize);
|
||||||
obs_data_set_string(obj, "regexPattern", _regexPattern.c_str());
|
obs_data_set_string(obj, "regexPattern", _regexPattern.c_str());
|
||||||
obs_data_set_int(obj, "regexMatchIdx", _regexMatchIdx);
|
obs_data_set_int(obj, "regexMatchIdx", _regexMatchIdx);
|
||||||
obs_data_set_string(obj, "findStr", _findStr.c_str());
|
_findStr.Save(obj, "findStr");
|
||||||
obs_data_set_string(obj, "replaceStr", _replaceStr.c_str());
|
_replaceStr.Save(obj, "replaceStr");
|
||||||
_regex.Save(obj);
|
_regex.Save(obj);
|
||||||
_mathExpression.Save(obj, "mathExpression");
|
_mathExpression.Save(obj, "mathExpression");
|
||||||
obs_data_set_bool(obj, "useCustomPrompt", _useCustomPrompt);
|
obs_data_set_bool(obj, "useCustomPrompt", _useCustomPrompt);
|
||||||
_inputPrompt.Save(obj, "inputPrompt");
|
_inputPrompt.Save(obj, "inputPrompt");
|
||||||
|
obs_data_set_bool(obj, "useInputPlaceholder", _useInputPlaceholder);
|
||||||
|
_inputPlaceholder.Save(obj, "inputPlaceholder");
|
||||||
|
_envVariableName.Save(obj, "environmentVariableName");
|
||||||
|
_scene.Save(obj);
|
||||||
|
_tempVar.Save(obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +309,7 @@ bool MacroActionVariable::Load(obs_data_t *obj)
|
|||||||
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
|
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
|
||||||
_variable2 = GetWeakVariableByName(
|
_variable2 = GetWeakVariableByName(
|
||||||
obs_data_get_string(obj, "variable2Name"));
|
obs_data_get_string(obj, "variable2Name"));
|
||||||
_strValue = obs_data_get_string(obj, "strValue");
|
_strValue.Load(obj, "strValue");
|
||||||
_numValue = obs_data_get_double(obj, "numValue");
|
_numValue = obs_data_get_double(obj, "numValue");
|
||||||
_type = static_cast<Type>(obs_data_get_int(obj, "condition"));
|
_type = static_cast<Type>(obs_data_get_int(obj, "condition"));
|
||||||
_segmentIdxLoadValue = obs_data_get_int(obj, "segmentIdx");
|
_segmentIdxLoadValue = obs_data_get_int(obj, "segmentIdx");
|
||||||
@@ -266,11 +318,16 @@ bool MacroActionVariable::Load(obs_data_t *obj)
|
|||||||
_regex.Load(obj);
|
_regex.Load(obj);
|
||||||
_regexPattern = obs_data_get_string(obj, "regexPattern");
|
_regexPattern = obs_data_get_string(obj, "regexPattern");
|
||||||
_regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx");
|
_regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx");
|
||||||
_findStr = obs_data_get_string(obj, "findStr");
|
_findStr.Load(obj, "findStr");
|
||||||
_replaceStr = obs_data_get_string(obj, "replaceStr");
|
_replaceStr.Load(obj, "replaceStr");
|
||||||
_mathExpression.Load(obj, "mathExpression");
|
_mathExpression.Load(obj, "mathExpression");
|
||||||
_useCustomPrompt = obs_data_get_bool(obj, "useCustomPrompt");
|
_useCustomPrompt = obs_data_get_bool(obj, "useCustomPrompt");
|
||||||
_inputPrompt.Load(obj, "inputPrompt");
|
_inputPrompt.Load(obj, "inputPrompt");
|
||||||
|
_useInputPlaceholder = obs_data_get_bool(obj, "useInputPlaceholder");
|
||||||
|
_inputPlaceholder.Load(obj, "inputPlaceholder");
|
||||||
|
_envVariableName.Load(obj, "environmentVariableName");
|
||||||
|
_scene.Load(obj);
|
||||||
|
_tempVar.Load(obj, GetMacro());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,7 +370,7 @@ void MacroActionVariable::SetSegmentIndexValue(int value)
|
|||||||
|
|
||||||
_macroSegment = segment;
|
_macroSegment = segment;
|
||||||
if (segment) {
|
if (segment) {
|
||||||
segment->IncrementVariableRef();
|
IncrementVariableRef(segment.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,13 +412,14 @@ void MacroActionVariable::DecrementCurrentSegmentVariableRef()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
segment->DecrementVariableRef();
|
DecrementVariableRef(segment.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void populateTypeSelection(QComboBox *list)
|
static inline void populateTypeSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : actionTypes) {
|
for (const auto &[action, name] : actionTypes) {
|
||||||
list->addItem(obs_module_text(entry.second.c_str()));
|
list->addItem(obs_module_text(name.c_str()),
|
||||||
|
static_cast<int>(action));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,8 +428,8 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
_variables(new VariableSelection(this)),
|
_variables(new VariableSelection(this)),
|
||||||
_variables2(new VariableSelection(this)),
|
_variables2(new VariableSelection(this)),
|
||||||
_actions(new QComboBox()),
|
_actions(new FilterComboBox(this)),
|
||||||
_strValue(new ResizingPlainTextEdit(this, 5, 1, 1)),
|
_strValue(new VariableTextEdit(this, 5, 1, 1)),
|
||||||
_numValue(new QDoubleSpinBox()),
|
_numValue(new QDoubleSpinBox()),
|
||||||
_segmentIdx(new MacroSegmentSelection(
|
_segmentIdx(new MacroSegmentSelection(
|
||||||
this, MacroSegmentSelection::Type::CONDITION, false)),
|
this, MacroSegmentSelection::Type::CONDITION, false)),
|
||||||
@@ -386,13 +444,20 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
_regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
_regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
||||||
_regexMatchIdx(new QSpinBox()),
|
_regexMatchIdx(new QSpinBox()),
|
||||||
_findReplaceLayout(new QHBoxLayout()),
|
_findReplaceLayout(new QHBoxLayout()),
|
||||||
_findStr(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
_findStr(new VariableTextEdit(this, 10, 1, 1)),
|
||||||
_replaceStr(new ResizingPlainTextEdit(this, 10, 1, 1)),
|
_replaceStr(new VariableTextEdit(this, 10, 1, 1)),
|
||||||
_mathExpression(new VariableLineEdit(this)),
|
_mathExpression(new VariableLineEdit(this)),
|
||||||
_mathExpressionResult(new QLabel()),
|
_mathExpressionResult(new QLabel()),
|
||||||
_promptLayout(new QHBoxLayout()),
|
_promptLayout(new QHBoxLayout()),
|
||||||
_useCustomPrompt(new QCheckBox()),
|
_useCustomPrompt(new QCheckBox()),
|
||||||
_inputPrompt(new VariableLineEdit(this))
|
_inputPrompt(new VariableLineEdit(this)),
|
||||||
|
_placeholderLayout(new QHBoxLayout()),
|
||||||
|
_useInputPlaceholder(new QCheckBox()),
|
||||||
|
_inputPlaceholder(new VariableLineEdit(this)),
|
||||||
|
_envVariable(new VariableLineEdit(this)),
|
||||||
|
_scenes(new SceneSelectionWidget(this, true, false, true, true,
|
||||||
|
true)),
|
||||||
|
_tempVars(new TempVariableSelection(this))
|
||||||
{
|
{
|
||||||
_numValue->setMinimum(-9999999999);
|
_numValue->setMinimum(-9999999999);
|
||||||
_numValue->setMaximum(9999999999);
|
_numValue->setMaximum(9999999999);
|
||||||
@@ -447,6 +512,17 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
SLOT(UseCustomPromptChanged(int)));
|
SLOT(UseCustomPromptChanged(int)));
|
||||||
QWidget::connect(_inputPrompt, SIGNAL(editingFinished()), this,
|
QWidget::connect(_inputPrompt, SIGNAL(editingFinished()), this,
|
||||||
SLOT(InputPromptChanged()));
|
SLOT(InputPromptChanged()));
|
||||||
|
QWidget::connect(_useInputPlaceholder, SIGNAL(stateChanged(int)), this,
|
||||||
|
SLOT(UseInputPlaceholderChanged(int)));
|
||||||
|
QWidget::connect(_inputPlaceholder, SIGNAL(editingFinished()), this,
|
||||||
|
SLOT(InputPlaceholderChanged()));
|
||||||
|
QWidget::connect(_envVariable, SIGNAL(editingFinished()), this,
|
||||||
|
SLOT(EnvVariableChanged()));
|
||||||
|
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
||||||
|
this, SLOT(SceneChanged(const SceneSelection &)));
|
||||||
|
QWidget::connect(_tempVars,
|
||||||
|
SIGNAL(SelectionChanged(const TempVariableRef &)),
|
||||||
|
this, SLOT(SelectionChanged(const TempVariableRef &)));
|
||||||
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{variables}}", _variables},
|
{"{{variables}}", _variables},
|
||||||
@@ -463,6 +539,11 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
{"{{mathExpression}}", _mathExpression},
|
{"{{mathExpression}}", _mathExpression},
|
||||||
{"{{useCustomPrompt}}", _useCustomPrompt},
|
{"{{useCustomPrompt}}", _useCustomPrompt},
|
||||||
{"{{inputPrompt}}", _inputPrompt},
|
{"{{inputPrompt}}", _inputPrompt},
|
||||||
|
{"{{useInputPlaceholder}}", _useInputPlaceholder},
|
||||||
|
{"{{inputPlaceholder}}", _inputPlaceholder},
|
||||||
|
{"{{envVariableName}}", _envVariable},
|
||||||
|
{"{{scenes}}", _scenes},
|
||||||
|
{"{{tempVars}}", _tempVars},
|
||||||
};
|
};
|
||||||
auto entryLayout = new QHBoxLayout;
|
auto entryLayout = new QHBoxLayout;
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"),
|
||||||
@@ -485,8 +566,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
|
|
||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.entry.userInput"),
|
"AdvSceneSwitcher.action.variable.entry.userInput.customPrompt"),
|
||||||
_promptLayout, widgetPlaceholders);
|
_promptLayout, widgetPlaceholders);
|
||||||
|
PlaceWidgets(
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.entry.userInput.placeholder"),
|
||||||
|
_placeholderLayout, widgetPlaceholders);
|
||||||
|
|
||||||
auto regexConfigLayout = new QHBoxLayout;
|
auto regexConfigLayout = new QHBoxLayout;
|
||||||
regexConfigLayout->addWidget(_regex);
|
regexConfigLayout->addWidget(_regex);
|
||||||
@@ -505,6 +590,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
layout->addLayout(_findReplaceLayout);
|
layout->addLayout(_findReplaceLayout);
|
||||||
layout->addWidget(_mathExpressionResult);
|
layout->addWidget(_mathExpressionResult);
|
||||||
layout->addLayout(_promptLayout);
|
layout->addLayout(_promptLayout);
|
||||||
|
layout->addLayout(_placeholderLayout);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
@@ -525,8 +611,9 @@ void MacroActionVariableEdit::UpdateEntryData()
|
|||||||
|
|
||||||
_variables->SetVariable(_entryData->_variable);
|
_variables->SetVariable(_entryData->_variable);
|
||||||
_variables2->SetVariable(_entryData->_variable2);
|
_variables2->SetVariable(_entryData->_variable2);
|
||||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_type));
|
_actions->setCurrentIndex(
|
||||||
_strValue->setPlainText(QString::fromStdString(_entryData->_strValue));
|
_actions->findData(static_cast<int>(_entryData->_type)));
|
||||||
|
_strValue->setPlainText(_entryData->_strValue);
|
||||||
_numValue->setValue(_entryData->_numValue);
|
_numValue->setValue(_entryData->_numValue);
|
||||||
_segmentIdx->SetValue(_entryData->GetSegmentIndexValue() + 1);
|
_segmentIdx->SetValue(_entryData->GetSegmentIndexValue() + 1);
|
||||||
_segmentIdx->SetMacro(_entryData->GetMacro());
|
_segmentIdx->SetMacro(_entryData->GetMacro());
|
||||||
@@ -541,12 +628,16 @@ void MacroActionVariableEdit::UpdateEntryData()
|
|||||||
_regexPattern->setPlainText(
|
_regexPattern->setPlainText(
|
||||||
QString::fromStdString(_entryData->_regexPattern));
|
QString::fromStdString(_entryData->_regexPattern));
|
||||||
_regexMatchIdx->setValue(_entryData->_regexMatchIdx + 1);
|
_regexMatchIdx->setValue(_entryData->_regexMatchIdx + 1);
|
||||||
_findStr->setPlainText(QString::fromStdString(_entryData->_findStr));
|
_findStr->setPlainText(_entryData->_findStr);
|
||||||
_replaceStr->setPlainText(
|
_replaceStr->setPlainText(_entryData->_replaceStr);
|
||||||
QString::fromStdString(_entryData->_replaceStr));
|
|
||||||
_mathExpression->setText(_entryData->_mathExpression);
|
_mathExpression->setText(_entryData->_mathExpression);
|
||||||
_useCustomPrompt->setChecked(_entryData->_useCustomPrompt);
|
_useCustomPrompt->setChecked(_entryData->_useCustomPrompt);
|
||||||
_inputPrompt->setText(_entryData->_inputPrompt);
|
_inputPrompt->setText(_entryData->_inputPrompt);
|
||||||
|
_useInputPlaceholder->setChecked(_entryData->_useInputPlaceholder);
|
||||||
|
_inputPlaceholder->setText(_entryData->_inputPlaceholder);
|
||||||
|
_envVariable->setText(_entryData->_envVariableName);
|
||||||
|
_scenes->SetScene(_entryData->_scene);
|
||||||
|
_tempVars->SetVariable(_entryData->_tempVar);
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,14 +661,15 @@ void MacroActionVariableEdit::Variable2Changed(const QString &text)
|
|||||||
_entryData->_variable2 = GetWeakVariableByQString(text);
|
_entryData->_variable2 = GetWeakVariableByQString(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionVariableEdit::ActionChanged(int value)
|
void MacroActionVariableEdit::ActionChanged(int idx)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData || idx == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_type = static_cast<MacroActionVariable::Type>(value);
|
_entryData->_type = static_cast<MacroActionVariable::Type>(
|
||||||
|
_actions->itemData(idx).toInt());
|
||||||
|
|
||||||
if (_entryData->_type == MacroActionVariable::Type::SET_ACTION_VALUE) {
|
if (_entryData->_type == MacroActionVariable::Type::SET_ACTION_VALUE) {
|
||||||
_segmentIdx->SetType(MacroSegmentSelection::Type::ACTION);
|
_segmentIdx->SetType(MacroSegmentSelection::Type::ACTION);
|
||||||
@@ -674,7 +766,7 @@ void MacroActionVariableEdit::UpdateSegmentVariableValue()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!segment->SupportsVariableValue()) {
|
if (!SupportsVariableValue(segment.get())) {
|
||||||
std::string type;
|
std::string type;
|
||||||
QString fmt;
|
QString fmt;
|
||||||
|
|
||||||
@@ -699,8 +791,14 @@ void MacroActionVariableEdit::UpdateSegmentVariableValue()
|
|||||||
_segmentValueStatus->setText(obs_module_text(
|
_segmentValueStatus->setText(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.currentSegmentValue"));
|
"AdvSceneSwitcher.action.variable.currentSegmentValue"));
|
||||||
_segmentValue->show();
|
_segmentValue->show();
|
||||||
_segmentValue->setPlainText(
|
|
||||||
QString::fromStdString(segment->GetVariableValue()));
|
// Only update the text if the value changed to prevent possible text
|
||||||
|
// selections being lost
|
||||||
|
auto previousText = _segmentValue->toPlainText();
|
||||||
|
auto newText = QString::fromStdString(segment->GetVariableValue());
|
||||||
|
if (newText != previousText) {
|
||||||
|
_segmentValue->setPlainText(newText);
|
||||||
|
}
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
@@ -818,15 +916,9 @@ void MacroActionVariableEdit::UseCustomPromptChanged(int value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputPrompt->setVisible(value);
|
|
||||||
if (value) {
|
|
||||||
RemoveStretchIfPresent(_promptLayout);
|
|
||||||
} else {
|
|
||||||
AddStretchIfNecessary(_promptLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_useCustomPrompt = value;
|
_entryData->_useCustomPrompt = value;
|
||||||
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionVariableEdit::InputPromptChanged()
|
void MacroActionVariableEdit::InputPromptChanged()
|
||||||
@@ -839,6 +931,57 @@ void MacroActionVariableEdit::InputPromptChanged()
|
|||||||
_entryData->_inputPrompt = _inputPrompt->text().toStdString();
|
_entryData->_inputPrompt = _inputPrompt->text().toStdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::UseInputPlaceholderChanged(int value)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_useInputPlaceholder = value;
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::InputPlaceholderChanged()
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_inputPlaceholder = _inputPlaceholder->text().toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::EnvVariableChanged()
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_envVariableName = _envVariable->text().toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::SceneChanged(const SceneSelection &scene)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_scene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::SelectionChanged(const TempVariableRef &var)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_tempVar = var;
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionVariableEdit::SetWidgetVisibility()
|
void MacroActionVariableEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
if (!_entryData) {
|
if (!_entryData) {
|
||||||
@@ -850,7 +993,9 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
_strValue->setVisible(
|
_strValue->setVisible(
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroActionVariable::Type::SET_FIXED_VALUE ||
|
MacroActionVariable::Type::SET_FIXED_VALUE ||
|
||||||
_entryData->_type == MacroActionVariable::Type::APPEND);
|
_entryData->_type == MacroActionVariable::Type::APPEND ||
|
||||||
|
_entryData->_type == MacroActionVariable::Type::STRING_LENGTH ||
|
||||||
|
_entryData->_type == MacroActionVariable::Type::EXTRACT_JSON);
|
||||||
_numValue->setVisible(
|
_numValue->setVisible(
|
||||||
_entryData->_type == MacroActionVariable::Type::INCREMENT ||
|
_entryData->_type == MacroActionVariable::Type::INCREMENT ||
|
||||||
_entryData->_type == MacroActionVariable::Type::DECREMENT);
|
_entryData->_type == MacroActionVariable::Type::DECREMENT);
|
||||||
@@ -887,7 +1032,36 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
SetLayoutVisible(_promptLayout,
|
SetLayoutVisible(_promptLayout,
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroActionVariable::Type::USER_INPUT);
|
MacroActionVariable::Type::USER_INPUT);
|
||||||
_inputPrompt->setVisible(_entryData->_useCustomPrompt);
|
_inputPrompt->setVisible(
|
||||||
|
_entryData->_type == MacroActionVariable::Type::USER_INPUT &&
|
||||||
|
_entryData->_useCustomPrompt);
|
||||||
|
if (_entryData->_useCustomPrompt) {
|
||||||
|
RemoveStretchIfPresent(_promptLayout);
|
||||||
|
} else {
|
||||||
|
AddStretchIfNecessary(_promptLayout);
|
||||||
|
}
|
||||||
|
SetLayoutVisible(
|
||||||
|
_placeholderLayout,
|
||||||
|
_entryData->_type == MacroActionVariable::Type::USER_INPUT &&
|
||||||
|
_entryData->_useCustomPrompt);
|
||||||
|
_useInputPlaceholder->setVisible(
|
||||||
|
_entryData->_type == MacroActionVariable::Type::USER_INPUT &&
|
||||||
|
_entryData->_useCustomPrompt);
|
||||||
|
_inputPlaceholder->setVisible(
|
||||||
|
_entryData->_type == MacroActionVariable::Type::USER_INPUT &&
|
||||||
|
_entryData->_useCustomPrompt &&
|
||||||
|
_entryData->_useInputPlaceholder);
|
||||||
|
if (_entryData->_useInputPlaceholder) {
|
||||||
|
RemoveStretchIfPresent(_placeholderLayout);
|
||||||
|
} else {
|
||||||
|
AddStretchIfNecessary(_placeholderLayout);
|
||||||
|
}
|
||||||
|
_envVariable->setVisible(_entryData->_type ==
|
||||||
|
MacroActionVariable::Type::ENV_VARIABLE);
|
||||||
|
_scenes->setVisible(_entryData->_type ==
|
||||||
|
MacroActionVariable::Type::SCENE_ITEM_COUNT);
|
||||||
|
_tempVars->setVisible(_entryData->_type ==
|
||||||
|
MacroActionVariable::Type::SET_TO_TEMPVAR);
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
#include "macro-segment-selection.hpp"
|
#include "macro-segment-selection.hpp"
|
||||||
#include "regex-config.hpp"
|
#include "regex-config.hpp"
|
||||||
#include "resizing-text-edit.hpp"
|
#include "resizing-text-edit.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
#include "variable-line-edit.hpp"
|
#include "variable-line-edit.hpp"
|
||||||
|
#include "variable-text-edit.hpp"
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -37,27 +39,42 @@ public:
|
|||||||
FIND_AND_REPLACE,
|
FIND_AND_REPLACE,
|
||||||
MATH_EXPRESSION,
|
MATH_EXPRESSION,
|
||||||
USER_INPUT,
|
USER_INPUT,
|
||||||
|
ENV_VARIABLE,
|
||||||
|
SCENE_ITEM_COUNT,
|
||||||
|
STRING_LENGTH,
|
||||||
|
EXTRACT_JSON,
|
||||||
|
SET_TO_TEMPVAR,
|
||||||
};
|
};
|
||||||
|
|
||||||
Type _type = Type::SET_FIXED_VALUE;
|
Type _type = Type::SET_FIXED_VALUE;
|
||||||
std::weak_ptr<Variable> _variable;
|
std::weak_ptr<Variable> _variable;
|
||||||
std::weak_ptr<Variable> _variable2;
|
std::weak_ptr<Variable> _variable2;
|
||||||
std::string _strValue = "";
|
StringVariable _strValue = "";
|
||||||
double _numValue = 0;
|
double _numValue = 0;
|
||||||
int _subStringStart = 0;
|
int _subStringStart = 0;
|
||||||
int _subStringSize = 0;
|
int _subStringSize = 0;
|
||||||
RegexConfig _regex = RegexConfig::PartialMatchRegexConfig();
|
RegexConfig _regex = RegexConfig::PartialMatchRegexConfig();
|
||||||
std::string _regexPattern = ".*";
|
std::string _regexPattern = ".*";
|
||||||
int _regexMatchIdx = 0;
|
int _regexMatchIdx = 0;
|
||||||
std::string _findStr = obs_module_text(
|
StringVariable _findStr = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.findAndReplace.find");
|
"AdvSceneSwitcher.action.variable.findAndReplace.find");
|
||||||
std::string _replaceStr = obs_module_text(
|
StringVariable _replaceStr = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.findAndReplace.replace");
|
"AdvSceneSwitcher.action.variable.findAndReplace.replace");
|
||||||
StringVariable _mathExpression = obs_module_text(
|
StringVariable _mathExpression = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.mathExpression.example");
|
"AdvSceneSwitcher.action.variable.mathExpression.example");
|
||||||
bool _useCustomPrompt = false;
|
bool _useCustomPrompt = false;
|
||||||
StringVariable _inputPrompt = obs_module_text(
|
StringVariable _inputPrompt = obs_module_text(
|
||||||
"AdvSceneSwitcher.action.variable.askForValuePrompt");
|
"AdvSceneSwitcher.action.variable.askForValuePrompt");
|
||||||
|
bool _useInputPlaceholder = false;
|
||||||
|
StringVariable _inputPlaceholder =
|
||||||
|
obs_module_text("AdvSceneSwitcher.enterText");
|
||||||
|
#ifdef _WIN32
|
||||||
|
StringVariable _envVariableName = "USERPROFILE";
|
||||||
|
#else
|
||||||
|
StringVariable _envVariableName = "HOME";
|
||||||
|
#endif
|
||||||
|
SceneSelection _scene;
|
||||||
|
TempVariableRef _tempVar;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DecrementCurrentSegmentVariableRef();
|
void DecrementCurrentSegmentVariableRef();
|
||||||
@@ -107,15 +124,23 @@ private slots:
|
|||||||
void MathExpressionChanged();
|
void MathExpressionChanged();
|
||||||
void UseCustomPromptChanged(int);
|
void UseCustomPromptChanged(int);
|
||||||
void InputPromptChanged();
|
void InputPromptChanged();
|
||||||
|
void UseInputPlaceholderChanged(int);
|
||||||
|
void InputPlaceholderChanged();
|
||||||
|
void EnvVariableChanged();
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
void SelectionChanged(const TempVariableRef &var);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
void SetSegmentValueError(const QString &);
|
||||||
|
|
||||||
VariableSelection *_variables;
|
VariableSelection *_variables;
|
||||||
VariableSelection *_variables2;
|
VariableSelection *_variables2;
|
||||||
QComboBox *_actions;
|
FilterComboBox *_actions;
|
||||||
ResizingPlainTextEdit *_strValue;
|
VariableTextEdit *_strValue;
|
||||||
QDoubleSpinBox *_numValue;
|
QDoubleSpinBox *_numValue;
|
||||||
MacroSegmentSelection *_segmentIdx;
|
MacroSegmentSelection *_segmentIdx;
|
||||||
QLabel *_segmentValueStatus;
|
QLabel *_segmentValueStatus;
|
||||||
@@ -129,19 +154,21 @@ protected:
|
|||||||
ResizingPlainTextEdit *_regexPattern;
|
ResizingPlainTextEdit *_regexPattern;
|
||||||
QSpinBox *_regexMatchIdx;
|
QSpinBox *_regexMatchIdx;
|
||||||
QHBoxLayout *_findReplaceLayout;
|
QHBoxLayout *_findReplaceLayout;
|
||||||
ResizingPlainTextEdit *_findStr;
|
VariableTextEdit *_findStr;
|
||||||
ResizingPlainTextEdit *_replaceStr;
|
VariableTextEdit *_replaceStr;
|
||||||
VariableLineEdit *_mathExpression;
|
VariableLineEdit *_mathExpression;
|
||||||
QLabel *_mathExpressionResult;
|
QLabel *_mathExpressionResult;
|
||||||
QHBoxLayout *_promptLayout;
|
QHBoxLayout *_promptLayout;
|
||||||
QCheckBox *_useCustomPrompt;
|
QCheckBox *_useCustomPrompt;
|
||||||
VariableLineEdit *_inputPrompt;
|
VariableLineEdit *_inputPrompt;
|
||||||
|
QHBoxLayout *_placeholderLayout;
|
||||||
|
QCheckBox *_useInputPlaceholder;
|
||||||
|
VariableLineEdit *_inputPlaceholder;
|
||||||
|
VariableLineEdit *_envVariable;
|
||||||
|
SceneSelectionWidget *_scenes;
|
||||||
|
TempVariableSelection *_tempVars;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionVariable> _entryData;
|
std::shared_ptr<MacroActionVariable> _entryData;
|
||||||
|
|
||||||
private:
|
|
||||||
void SetWidgetVisibility();
|
|
||||||
void SetSegmentValueError(const QString &);
|
|
||||||
|
|
||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -47,6 +47,12 @@ const static std::map<MacroConditionAudio::VolumeCondition, std::string>
|
|||||||
"AdvSceneSwitcher.condition.audio.state.unmute"},
|
"AdvSceneSwitcher.condition.audio.state.unmute"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void MacroConditionAudio::SetType(const Type &type)
|
||||||
|
{
|
||||||
|
_checkType = type;
|
||||||
|
SetupTempVars();
|
||||||
|
}
|
||||||
|
|
||||||
MacroConditionAudio::~MacroConditionAudio()
|
MacroConditionAudio::~MacroConditionAudio()
|
||||||
{
|
{
|
||||||
obs_volmeter_remove_callback(_volmeter, SetVolumeLevel, this);
|
obs_volmeter_remove_callback(_volmeter, SetVolumeLevel, this);
|
||||||
@@ -74,6 +80,7 @@ bool MacroConditionAudio::CheckOutputCondition()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetVariableValue(std::to_string(curVolume));
|
SetVariableValue(std::to_string(curVolume));
|
||||||
|
SetTempVarValue("output_volume", std::to_string(curVolume));
|
||||||
|
|
||||||
// Reset for next check
|
// Reset for next check
|
||||||
_peak = -std::numeric_limits<float>::infinity();
|
_peak = -std::numeric_limits<float>::infinity();
|
||||||
@@ -118,6 +125,9 @@ bool MacroConditionAudio::CheckVolumeCondition()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetTempVarValue("configured_volume", std::to_string(curVolume));
|
||||||
|
SetTempVarValue("muted", muted ? "true" : "false");
|
||||||
|
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -137,6 +147,7 @@ bool MacroConditionAudio::CheckSyncOffset()
|
|||||||
ret = curOffset < _syncOffset;
|
ret = curOffset < _syncOffset;
|
||||||
}
|
}
|
||||||
SetVariableValue(std::to_string(curOffset));
|
SetVariableValue(std::to_string(curOffset));
|
||||||
|
SetTempVarValue("sync_offset", std::to_string(curOffset));
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -151,6 +162,8 @@ bool MacroConditionAudio::CheckMonitor()
|
|||||||
auto s = obs_weak_source_get_source(_audioSource.GetSource());
|
auto s = obs_weak_source_get_source(_audioSource.GetSource());
|
||||||
ret = obs_source_get_monitoring_type(s) == _monitorType;
|
ret = obs_source_get_monitoring_type(s) == _monitorType;
|
||||||
SetVariableValue("");
|
SetVariableValue("");
|
||||||
|
SetTempVarValue("monitor",
|
||||||
|
std::to_string(obs_source_get_monitoring_type(s)));
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -170,6 +183,7 @@ bool MacroConditionAudio::CheckBalance()
|
|||||||
ret = curBalance < _balance;
|
ret = curBalance < _balance;
|
||||||
}
|
}
|
||||||
SetVariableValue(std::to_string(curBalance));
|
SetVariableValue(std::to_string(curBalance));
|
||||||
|
SetTempVarValue("balance", std::to_string(curBalance));
|
||||||
obs_source_release(s);
|
obs_source_release(s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -290,6 +304,50 @@ void MacroConditionAudio::ResetVolmeter()
|
|||||||
_volmeter = AddVolmeterToSource(this, _audioSource.GetSource());
|
_volmeter = AddVolmeterToSource(this, _audioSource.GetSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionAudio::SetupTempVars()
|
||||||
|
{
|
||||||
|
MacroCondition::SetupTempVars();
|
||||||
|
switch (_checkType) {
|
||||||
|
case Type::OUTPUT_VOLUME:
|
||||||
|
AddTempvar(
|
||||||
|
"output_volume",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.output_volume"),
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.output_volume.description"));
|
||||||
|
break;
|
||||||
|
case Type::CONFIGURED_VOLUME:
|
||||||
|
AddTempvar(
|
||||||
|
"configured_volume",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.configured_volume"),
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.configured_volume.description"));
|
||||||
|
AddTempvar("muted",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.muted"));
|
||||||
|
break;
|
||||||
|
case Type::SYNC_OFFSET:
|
||||||
|
AddTempvar(
|
||||||
|
"sync_offset",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.sync_offset"));
|
||||||
|
break;
|
||||||
|
case Type::MONITOR:
|
||||||
|
AddTempvar("monitor",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.monitor"));
|
||||||
|
break;
|
||||||
|
case Type::BALANCE:
|
||||||
|
AddTempvar("balance",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.audio.balance"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void populateCheckTypes(QComboBox *list)
|
static inline void populateCheckTypes(QComboBox *list)
|
||||||
{
|
{
|
||||||
list->clear();
|
list->clear();
|
||||||
@@ -479,10 +537,9 @@ void MacroConditionAudioEdit::ConditionChanged(int cond)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
if (_entryData->_checkType ==
|
if (_entryData->GetType() == MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
_entryData->GetType() == MacroConditionAudio::Type::BALANCE ||
|
||||||
_entryData->_checkType == MacroConditionAudio::Type::BALANCE ||
|
_entryData->GetType() == MacroConditionAudio::Type::SYNC_OFFSET) {
|
||||||
_entryData->_checkType == MacroConditionAudio::Type::SYNC_OFFSET) {
|
|
||||||
_entryData->_outputCondition =
|
_entryData->_outputCondition =
|
||||||
static_cast<MacroConditionAudio::OutputCondition>(cond);
|
static_cast<MacroConditionAudio::OutputCondition>(cond);
|
||||||
} else {
|
} else {
|
||||||
@@ -499,16 +556,15 @@ void MacroConditionAudioEdit::CheckTypeChanged(int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_checkType = static_cast<MacroConditionAudio::Type>(
|
_entryData->SetType(static_cast<MacroConditionAudio::Type>(
|
||||||
_checkTypes->itemData(idx).toInt());
|
_checkTypes->itemData(idx).toInt()));
|
||||||
|
|
||||||
const QSignalBlocker b(_condition);
|
const QSignalBlocker b(_condition);
|
||||||
if (_entryData->_checkType ==
|
if (_entryData->GetType() == MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
_entryData->GetType() == MacroConditionAudio::Type::BALANCE ||
|
||||||
_entryData->_checkType == MacroConditionAudio::Type::BALANCE ||
|
_entryData->GetType() == MacroConditionAudio::Type::SYNC_OFFSET) {
|
||||||
_entryData->_checkType == MacroConditionAudio::Type::SYNC_OFFSET) {
|
|
||||||
populateOutputConditionSelection(_condition);
|
populateOutputConditionSelection(_condition);
|
||||||
} else if (_entryData->_checkType ==
|
} else if (_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::CONFIGURED_VOLUME) {
|
MacroConditionAudio::Type::CONFIGURED_VOLUME) {
|
||||||
populateVolumeConditionSelection(_condition);
|
populateVolumeConditionSelection(_condition);
|
||||||
}
|
}
|
||||||
@@ -526,17 +582,16 @@ void MacroConditionAudioEdit::UpdateEntryData()
|
|||||||
_syncOffset->SetValue(_entryData->_syncOffset);
|
_syncOffset->SetValue(_entryData->_syncOffset);
|
||||||
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
||||||
_balance->SetDoubleValue(_entryData->_balance);
|
_balance->SetDoubleValue(_entryData->_balance);
|
||||||
_checkTypes->setCurrentIndex(_checkTypes->findData(
|
_checkTypes->setCurrentIndex(
|
||||||
static_cast<int>(_entryData->_checkType)));
|
_checkTypes->findData(static_cast<int>(_entryData->GetType())));
|
||||||
|
|
||||||
if (_entryData->_checkType ==
|
if (_entryData->GetType() == MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
_entryData->GetType() == MacroConditionAudio::Type::BALANCE ||
|
||||||
_entryData->_checkType == MacroConditionAudio::Type::BALANCE ||
|
_entryData->GetType() == MacroConditionAudio::Type::SYNC_OFFSET) {
|
||||||
_entryData->_checkType == MacroConditionAudio::Type::SYNC_OFFSET) {
|
|
||||||
populateOutputConditionSelection(_condition);
|
populateOutputConditionSelection(_condition);
|
||||||
_condition->setCurrentIndex(
|
_condition->setCurrentIndex(
|
||||||
static_cast<int>(_entryData->_outputCondition));
|
static_cast<int>(_entryData->_outputCondition));
|
||||||
} else if (_entryData->_checkType ==
|
} else if (_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::CONFIGURED_VOLUME) {
|
MacroConditionAudio::Type::CONFIGURED_VOLUME) {
|
||||||
populateVolumeConditionSelection(_condition);
|
populateVolumeConditionSelection(_condition);
|
||||||
_condition->setCurrentIndex(
|
_condition->setCurrentIndex(
|
||||||
@@ -554,9 +609,9 @@ void MacroConditionAudioEdit::SetWidgetVisibility()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_volume->setVisible(
|
_volume->setVisible(
|
||||||
_entryData->_checkType ==
|
_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
||||||
(_entryData->_checkType ==
|
(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::CONFIGURED_VOLUME &&
|
MacroConditionAudio::Type::CONFIGURED_VOLUME &&
|
||||||
(_entryData->_volumeCondition ==
|
(_entryData->_volumeCondition ==
|
||||||
MacroConditionAudio::VolumeCondition::ABOVE ||
|
MacroConditionAudio::VolumeCondition::ABOVE ||
|
||||||
@@ -565,20 +620,20 @@ void MacroConditionAudioEdit::SetWidgetVisibility()
|
|||||||
_entryData->_volumeCondition ==
|
_entryData->_volumeCondition ==
|
||||||
MacroConditionAudio::VolumeCondition::BELOW)));
|
MacroConditionAudio::VolumeCondition::BELOW)));
|
||||||
_condition->setVisible(
|
_condition->setVisible(
|
||||||
_entryData->_checkType ==
|
_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
||||||
_entryData->_checkType ==
|
_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::CONFIGURED_VOLUME ||
|
MacroConditionAudio::Type::CONFIGURED_VOLUME ||
|
||||||
_entryData->_checkType == MacroConditionAudio::Type::BALANCE ||
|
_entryData->GetType() == MacroConditionAudio::Type::BALANCE ||
|
||||||
_entryData->_checkType ==
|
_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::SYNC_OFFSET);
|
MacroConditionAudio::Type::SYNC_OFFSET);
|
||||||
_syncOffset->setVisible(_entryData->_checkType ==
|
_syncOffset->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::SYNC_OFFSET);
|
MacroConditionAudio::Type::SYNC_OFFSET);
|
||||||
_monitorTypes->setVisible(_entryData->_checkType ==
|
_monitorTypes->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::MONITOR);
|
MacroConditionAudio::Type::MONITOR);
|
||||||
_balance->setVisible(_entryData->_checkType ==
|
_balance->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::BALANCE);
|
MacroConditionAudio::Type::BALANCE);
|
||||||
_volMeter->setVisible(_entryData->_checkType ==
|
_volMeter->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME);
|
MacroConditionAudio::Type::OUTPUT_VOLUME);
|
||||||
adjustSize();
|
adjustSize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public:
|
|||||||
MONITOR,
|
MONITOR,
|
||||||
BALANCE,
|
BALANCE,
|
||||||
};
|
};
|
||||||
|
void SetType(const Type &);
|
||||||
|
Type GetType() const { return _checkType; }
|
||||||
|
|
||||||
enum class OutputCondition {
|
enum class OutputCondition {
|
||||||
ABOVE,
|
ABOVE,
|
||||||
@@ -56,7 +58,6 @@ public:
|
|||||||
NumberVariable<int> _syncOffset = 0;
|
NumberVariable<int> _syncOffset = 0;
|
||||||
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
||||||
NumberVariable<double> _balance = 0.5;
|
NumberVariable<double> _balance = 0.5;
|
||||||
Type _checkType = Type::OUTPUT_VOLUME;
|
|
||||||
OutputCondition _outputCondition = OutputCondition::ABOVE;
|
OutputCondition _outputCondition = OutputCondition::ABOVE;
|
||||||
VolumeCondition _volumeCondition = VolumeCondition::ABOVE;
|
VolumeCondition _volumeCondition = VolumeCondition::ABOVE;
|
||||||
obs_volmeter_t *_volmeter = nullptr;
|
obs_volmeter_t *_volmeter = nullptr;
|
||||||
@@ -67,7 +68,9 @@ private:
|
|||||||
bool CheckSyncOffset();
|
bool CheckSyncOffset();
|
||||||
bool CheckMonitor();
|
bool CheckMonitor();
|
||||||
bool CheckBalance();
|
bool CheckBalance();
|
||||||
|
void SetupTempVars();
|
||||||
|
|
||||||
|
Type _checkType = Type::OUTPUT_VOLUME;
|
||||||
float _peak = -std::numeric_limits<float>::infinity();
|
float _peak = -std::numeric_limits<float>::infinity();
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ const static std::map<MacroConditionDate::Day, std::string> dayOfWeekNames = {
|
|||||||
bool MacroConditionDate::CheckDayOfWeek(int64_t msSinceLastCheck)
|
bool MacroConditionDate::CheckDayOfWeek(int64_t msSinceLastCheck)
|
||||||
{
|
{
|
||||||
QDateTime cur = QDateTime::currentDateTime();
|
QDateTime cur = QDateTime::currentDateTime();
|
||||||
SetVariableValue(cur.toString().toStdString());
|
SetVariables(cur);
|
||||||
|
|
||||||
if (_dayOfWeek != Day::ANY &&
|
if (_dayOfWeek != Day::ANY &&
|
||||||
cur.date().dayOfWeek() != static_cast<int>(_dayOfWeek)) {
|
cur.date().dayOfWeek() != static_cast<int>(_dayOfWeek)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -133,7 +134,7 @@ bool MacroConditionDate::CheckRegularDate(int64_t msSinceLastCheck)
|
|||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
QDateTime cur = QDateTime::currentDateTime();
|
QDateTime cur = QDateTime::currentDateTime();
|
||||||
SetVariableValue(cur.toString().toStdString());
|
SetVariables(cur);
|
||||||
|
|
||||||
if (_ignoreDate) {
|
if (_ignoreDate) {
|
||||||
_dateTime.setDate(cur.date());
|
_dateTime.setDate(cur.date());
|
||||||
@@ -304,6 +305,37 @@ QDateTime MacroConditionDate::GetNextMatchDateTime() const
|
|||||||
return _dateTime;
|
return _dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionDate::SetVariables(const QDateTime &date)
|
||||||
|
{
|
||||||
|
SetVariableValue(date.toString().toStdString());
|
||||||
|
|
||||||
|
SetTempVarValue("year", std::to_string(date.date().year()));
|
||||||
|
SetTempVarValue("month", std::to_string(date.date().month()));
|
||||||
|
SetTempVarValue("day", std::to_string(date.date().day()));
|
||||||
|
SetTempVarValue("hour", std::to_string(date.time().hour()));
|
||||||
|
SetTempVarValue("minute", std::to_string(date.time().minute()));
|
||||||
|
SetTempVarValue("second", std::to_string(date.time().second()));
|
||||||
|
SetTempVarValue("dayOfWeek", std::to_string(date.date().dayOfWeek()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionDate::SetupTempVars()
|
||||||
|
{
|
||||||
|
MacroCondition::SetupTempVars();
|
||||||
|
AddTempvar("year",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.date.year"));
|
||||||
|
AddTempvar("month",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.date.month"));
|
||||||
|
AddTempvar("day", obs_module_text("AdvSceneSwitcher.tempVar.date.day"));
|
||||||
|
AddTempvar("hour",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.date.hour"));
|
||||||
|
AddTempvar("minute",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.date.minute"));
|
||||||
|
AddTempvar("second",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.date.second"));
|
||||||
|
AddTempvar("dayOfWeek",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.date.dayOfWeek"));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void populateDaySelection(QComboBox *list)
|
static inline void populateDaySelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : dayOfWeekNames) {
|
for (auto entry : dayOfWeekNames) {
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ private:
|
|||||||
bool CheckRegularDate(int64_t);
|
bool CheckRegularDate(int64_t);
|
||||||
bool CheckBetween(const QDateTime &now);
|
bool CheckBetween(const QDateTime &now);
|
||||||
bool CheckPattern(QDateTime now, int64_t secondsSinceLastCheck);
|
bool CheckPattern(QDateTime now, int64_t secondsSinceLastCheck);
|
||||||
|
void SetVariables(const QDateTime &date);
|
||||||
|
void SetupTempVars();
|
||||||
|
|
||||||
QDateTime _dateTime = QDateTime::currentDateTime();
|
QDateTime _dateTime = QDateTime::currentDateTime();
|
||||||
QDateTime _dateTime2 = QDateTime::currentDateTime();
|
QDateTime _dateTime2 = QDateTime::currentDateTime();
|
||||||
|
|||||||
@@ -312,6 +312,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
|
|||||||
*_entryData = MacroConditionFactory::Create(id, macro);
|
*_entryData = MacroConditionFactory::Create(id, macro);
|
||||||
(*_entryData)->SetIndex(idx);
|
(*_entryData)->SetIndex(idx);
|
||||||
(*_entryData)->SetLogicType(logic);
|
(*_entryData)->SetLogicType(logic);
|
||||||
|
(*_entryData)->PostLoad();
|
||||||
}
|
}
|
||||||
auto widget =
|
auto widget =
|
||||||
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
||||||
@@ -342,7 +343,7 @@ void MacroConditionEdit::DurationModifierChanged(DurationModifier::Type m)
|
|||||||
(*_entryData)->SetDurationModifier(m);
|
(*_entryData)->SetDurationModifier(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<MacroSegment> MacroConditionEdit::Data()
|
std::shared_ptr<MacroSegment> MacroConditionEdit::Data() const
|
||||||
{
|
{
|
||||||
return *_entryData;
|
return *_entryData;
|
||||||
}
|
}
|
||||||
@@ -383,9 +384,10 @@ void AdvSceneSwitcher::AddMacroCondition(int idx)
|
|||||||
macro->Conditions().at(idx)->Load(data);
|
macro->Conditions().at(idx)->Load(data);
|
||||||
obs_data_release(data);
|
obs_data_release(data);
|
||||||
}
|
}
|
||||||
|
macro->Conditions().at(idx)->PostLoad();
|
||||||
(*cond)->SetLogicType(logic);
|
(*cond)->SetLogicType(logic);
|
||||||
macro->UpdateConditionIndices();
|
macro->UpdateConditionIndices();
|
||||||
conditionsList->Insert(
|
ui->conditionsList->Insert(
|
||||||
idx,
|
idx,
|
||||||
new MacroConditionEdit(this, ¯o->Conditions()[idx],
|
new MacroConditionEdit(this, ¯o->Conditions()[idx],
|
||||||
id, idx == 0));
|
id, idx == 0));
|
||||||
@@ -410,7 +412,7 @@ void AdvSceneSwitcher::on_conditionAdd_clicked()
|
|||||||
if (currentConditionIdx != -1) {
|
if (currentConditionIdx != -1) {
|
||||||
MacroConditionSelectionChanged(currentConditionIdx + 1);
|
MacroConditionSelectionChanged(currentConditionIdx + 1);
|
||||||
}
|
}
|
||||||
conditionsList->SetHelpMsgVisible(false);
|
ui->conditionsList->SetHelpMsgVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
||||||
@@ -426,14 +428,14 @@ void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
conditionsList->Remove(idx);
|
ui->conditionsList->Remove(idx);
|
||||||
macro->Conditions().erase(macro->Conditions().begin() + idx);
|
macro->Conditions().erase(macro->Conditions().begin() + idx);
|
||||||
macro->UpdateConditionIndices();
|
macro->UpdateConditionIndices();
|
||||||
if (idx == 0 && macro->Conditions().size() > 0) {
|
if (idx == 0 && macro->Conditions().size() > 0) {
|
||||||
auto newRoot = macro->Conditions().at(0);
|
auto newRoot = macro->Conditions().at(0);
|
||||||
newRoot->SetLogicType(LogicType::ROOT_NONE);
|
newRoot->SetLogicType(LogicType::ROOT_NONE);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
conditionsList->WidgetAt(0))
|
ui->conditionsList->WidgetAt(0))
|
||||||
->SetRootNode(true);
|
->SetRootNode(true);
|
||||||
}
|
}
|
||||||
SetConditionData(*macro);
|
SetConditionData(*macro);
|
||||||
@@ -479,7 +481,7 @@ void AdvSceneSwitcher::on_conditionDown_clicked()
|
|||||||
{
|
{
|
||||||
if (currentConditionIdx == -1 ||
|
if (currentConditionIdx == -1 ||
|
||||||
currentConditionIdx ==
|
currentConditionIdx ==
|
||||||
conditionsList->ContentLayout()->count() - 1) {
|
ui->conditionsList->ContentLayout()->count() - 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MoveMacroConditionDown(currentConditionIdx);
|
MoveMacroConditionDown(currentConditionIdx);
|
||||||
@@ -491,7 +493,7 @@ void AdvSceneSwitcher::on_conditionBottom_clicked()
|
|||||||
if (currentConditionIdx == -1) {
|
if (currentConditionIdx == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int newIdx = conditionsList->ContentLayout()->count() - 1;
|
const int newIdx = ui->conditionsList->ContentLayout()->count() - 1;
|
||||||
MacroConditionReorder(newIdx, currentConditionIdx);
|
MacroConditionReorder(newIdx, currentConditionIdx);
|
||||||
MacroConditionSelectionChanged(newIdx);
|
MacroConditionSelectionChanged(newIdx);
|
||||||
}
|
}
|
||||||
@@ -521,11 +523,11 @@ void AdvSceneSwitcher::SwapConditions(Macro *m, int pos1, int pos2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto widget1 = static_cast<MacroConditionEdit *>(
|
auto widget1 = static_cast<MacroConditionEdit *>(
|
||||||
conditionsList->ContentLayout()->takeAt(pos1)->widget());
|
ui->conditionsList->ContentLayout()->takeAt(pos1)->widget());
|
||||||
auto widget2 = static_cast<MacroConditionEdit *>(
|
auto widget2 = static_cast<MacroConditionEdit *>(
|
||||||
conditionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
ui->conditionsList->ContentLayout()->takeAt(pos2 - 1)->widget());
|
||||||
conditionsList->Insert(pos1, widget2);
|
ui->conditionsList->Insert(pos1, widget2);
|
||||||
conditionsList->Insert(pos2, widget1);
|
ui->conditionsList->Insert(pos2, widget1);
|
||||||
SetConditionData(*m);
|
SetConditionData(*m);
|
||||||
widget2->SetRootNode(root);
|
widget2->SetRootNode(root);
|
||||||
widget1->SetRootNode(false);
|
widget1->SetRootNode(false);
|
||||||
@@ -564,22 +566,7 @@ void AdvSceneSwitcher::MoveMacroConditionDown(int idx)
|
|||||||
|
|
||||||
void AdvSceneSwitcher::MacroConditionSelectionChanged(int idx)
|
void AdvSceneSwitcher::MacroConditionSelectionChanged(int idx)
|
||||||
{
|
{
|
||||||
auto macro = GetSelectedMacro();
|
SetupMacroSegmentSelection(MacroSection::CONDITIONS, idx);
|
||||||
if (!macro) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
conditionsList->SetSelection(idx);
|
|
||||||
actionsList->SetSelection(-1);
|
|
||||||
|
|
||||||
if (idx < 0 || (unsigned)idx >= macro->Conditions().size()) {
|
|
||||||
currentConditionIdx = -1;
|
|
||||||
} else {
|
|
||||||
currentConditionIdx = idx;
|
|
||||||
lastInteracted = MacroSection::CONDITIONS;
|
|
||||||
}
|
|
||||||
currentActionIdx = -1;
|
|
||||||
HighlightControls();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::MacroConditionReorder(int to, int from)
|
void AdvSceneSwitcher::MacroConditionReorder(int to, int from)
|
||||||
@@ -599,30 +586,30 @@ void AdvSceneSwitcher::MacroConditionReorder(int to, int from)
|
|||||||
if (to == 0) {
|
if (to == 0) {
|
||||||
condition->SetLogicType(LogicType::ROOT_NONE);
|
condition->SetLogicType(LogicType::ROOT_NONE);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
conditionsList->WidgetAt(from))
|
ui->conditionsList->WidgetAt(from))
|
||||||
->SetRootNode(true);
|
->SetRootNode(true);
|
||||||
macro->Conditions().at(0)->SetLogicType(LogicType::AND);
|
macro->Conditions().at(0)->SetLogicType(LogicType::AND);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
conditionsList->WidgetAt(0))
|
ui->conditionsList->WidgetAt(0))
|
||||||
->SetRootNode(false);
|
->SetRootNode(false);
|
||||||
}
|
}
|
||||||
if (from == 0) {
|
if (from == 0) {
|
||||||
condition->SetLogicType(LogicType::AND);
|
condition->SetLogicType(LogicType::AND);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
conditionsList->WidgetAt(from))
|
ui->conditionsList->WidgetAt(from))
|
||||||
->SetRootNode(false);
|
->SetRootNode(false);
|
||||||
macro->Conditions().at(1)->SetLogicType(
|
macro->Conditions().at(1)->SetLogicType(
|
||||||
LogicType::ROOT_NONE);
|
LogicType::ROOT_NONE);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
conditionsList->WidgetAt(1))
|
ui->conditionsList->WidgetAt(1))
|
||||||
->SetRootNode(true);
|
->SetRootNode(true);
|
||||||
}
|
}
|
||||||
macro->Conditions().erase(macro->Conditions().begin() + from);
|
macro->Conditions().erase(macro->Conditions().begin() + from);
|
||||||
macro->Conditions().insert(macro->Conditions().begin() + to,
|
macro->Conditions().insert(macro->Conditions().begin() + to,
|
||||||
condition);
|
condition);
|
||||||
macro->UpdateConditionIndices();
|
macro->UpdateConditionIndices();
|
||||||
conditionsList->ContentLayout()->insertItem(
|
ui->conditionsList->ContentLayout()->insertItem(
|
||||||
to, conditionsList->ContentLayout()->takeAt(from));
|
to, ui->conditionsList->ContentLayout()->takeAt(from));
|
||||||
SetConditionData(*macro);
|
SetConditionData(*macro);
|
||||||
}
|
}
|
||||||
HighlightCondition(to);
|
HighlightCondition(to);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void SetLogicSelection();
|
void SetLogicSelection();
|
||||||
std::shared_ptr<MacroSegment> Data();
|
std::shared_ptr<MacroSegment> Data() const;
|
||||||
|
|
||||||
QComboBox *_logicSelection;
|
QComboBox *_logicSelection;
|
||||||
FilterComboBox *_conditionSelection;
|
FilterComboBox *_conditionSelection;
|
||||||
|
|||||||
@@ -18,19 +18,20 @@ const static std::map<MacroConditionFilter::Condition, std::string>
|
|||||||
"AdvSceneSwitcher.condition.filter.type.active"},
|
"AdvSceneSwitcher.condition.filter.type.active"},
|
||||||
{MacroConditionFilter::Condition::DISABLED,
|
{MacroConditionFilter::Condition::DISABLED,
|
||||||
"AdvSceneSwitcher.condition.filter.type.showing"},
|
"AdvSceneSwitcher.condition.filter.type.showing"},
|
||||||
{MacroConditionFilter::Condition::SETTINGS,
|
{MacroConditionFilter::Condition::SETTINGS_MATCH,
|
||||||
"AdvSceneSwitcher.condition.filter.type.settings"},
|
"AdvSceneSwitcher.condition.filter.type.settings"},
|
||||||
|
{MacroConditionFilter::Condition::SETTINGS_CHANGED,
|
||||||
|
"AdvSceneSwitcher.condition.filter.type.settingsChanged"},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MacroConditionFilter::CheckCondition()
|
bool MacroConditionFilter::CheckConditionHelper(const OBSWeakSource &filter)
|
||||||
{
|
{
|
||||||
auto filterWeakSource = _filter.GetFilter(_source);
|
bool ret = false;
|
||||||
if (!filterWeakSource) {
|
OBSSourceAutoRelease filterSource = obs_weak_source_get_source(filter);
|
||||||
|
if (!filterSource.Get()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto filterSource = obs_weak_source_get_source(filterWeakSource);
|
|
||||||
|
|
||||||
bool ret = false;
|
|
||||||
switch (_condition) {
|
switch (_condition) {
|
||||||
case Condition::ENABLED:
|
case Condition::ENABLED:
|
||||||
ret = obs_source_enabled(filterSource);
|
ret = obs_source_enabled(filterSource);
|
||||||
@@ -38,18 +39,36 @@ bool MacroConditionFilter::CheckCondition()
|
|||||||
case Condition::DISABLED:
|
case Condition::DISABLED:
|
||||||
ret = !obs_source_enabled(filterSource);
|
ret = !obs_source_enabled(filterSource);
|
||||||
break;
|
break;
|
||||||
case Condition::SETTINGS:
|
case Condition::SETTINGS_MATCH:
|
||||||
ret = CompareSourceSettings(filterWeakSource, _settings,
|
ret = CompareSourceSettings(filter, _settings, _regex);
|
||||||
_regex);
|
|
||||||
if (IsReferencedInVars()) {
|
if (IsReferencedInVars()) {
|
||||||
SetVariableValue(GetSourceSettings(filterWeakSource));
|
SetVariableValue(GetSourceSettings(filter));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Condition::SETTINGS_CHANGED: {
|
||||||
|
std::string settings = GetSourceSettings(_source.GetSource());
|
||||||
|
ret = !_currentSettings.empty() && settings != _currentSettings;
|
||||||
|
_currentSettings = settings;
|
||||||
|
SetVariableValue(settings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
obs_source_release(filterSource);
|
bool MacroConditionFilter::CheckCondition()
|
||||||
|
{
|
||||||
|
auto filters = _filter.GetFilters(_source);
|
||||||
|
if (filters.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
for (const auto &filter : filters) {
|
||||||
|
ret = ret && CheckConditionHelper(filter);
|
||||||
|
}
|
||||||
|
|
||||||
if (GetVariableValue().empty()) {
|
if (GetVariableValue().empty()) {
|
||||||
SetVariableValue(ret ? "true" : "false");
|
SetVariableValue(ret ? "true" : "false");
|
||||||
@@ -95,8 +114,8 @@ std::string MacroConditionFilter::GetShortDesc() const
|
|||||||
|
|
||||||
static inline void populateConditionSelection(QComboBox *list)
|
static inline void populateConditionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : filterConditionTypes) {
|
for (const auto &[_, name] : filterConditionTypes) {
|
||||||
list->addItem(obs_module_text(entry.second.c_str()));
|
list->addItem(obs_module_text(name.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,19 +213,20 @@ void MacroConditionFilterEdit::ConditionChanged(int index)
|
|||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_condition =
|
_entryData->_condition =
|
||||||
static_cast<MacroConditionFilter::Condition>(index);
|
static_cast<MacroConditionFilter::Condition>(index);
|
||||||
SetSettingsSelectionVisible(_entryData->_condition ==
|
SetSettingsSelectionVisible(
|
||||||
MacroConditionFilter::Condition::SETTINGS);
|
_entryData->_condition ==
|
||||||
|
MacroConditionFilter::Condition::SETTINGS_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionFilterEdit::GetSettingsClicked()
|
void MacroConditionFilterEdit::GetSettingsClicked()
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData ||
|
if (_loading || !_entryData ||
|
||||||
!_entryData->_filter.GetFilter(_entryData->_source)) {
|
_entryData->_filter.GetFilters(_entryData->_source).empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString json = FormatJsonString(GetSourceSettings(
|
QString json = FormatJsonString(GetSourceSettings(
|
||||||
_entryData->_filter.GetFilter(_entryData->_source)));
|
_entryData->_filter.GetFilters(_entryData->_source).at(0)));
|
||||||
if (_entryData->_regex.Enabled()) {
|
if (_entryData->_regex.Enabled()) {
|
||||||
json = EscapeForRegex(json);
|
json = EscapeForRegex(json);
|
||||||
}
|
}
|
||||||
@@ -259,8 +279,9 @@ void MacroConditionFilterEdit::UpdateEntryData()
|
|||||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||||
_settings->setPlainText(_entryData->_settings);
|
_settings->setPlainText(_entryData->_settings);
|
||||||
_regex->SetRegexConfig(_entryData->_regex);
|
_regex->SetRegexConfig(_entryData->_regex);
|
||||||
SetSettingsSelectionVisible(_entryData->_condition ==
|
SetSettingsSelectionVisible(
|
||||||
MacroConditionFilter::Condition::SETTINGS);
|
_entryData->_condition ==
|
||||||
|
MacroConditionFilter::Condition::SETTINGS_MATCH);
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public:
|
|||||||
enum class Condition {
|
enum class Condition {
|
||||||
ENABLED,
|
ENABLED,
|
||||||
DISABLED,
|
DISABLED,
|
||||||
SETTINGS,
|
SETTINGS_MATCH,
|
||||||
|
SETTINGS_CHANGED,
|
||||||
};
|
};
|
||||||
|
|
||||||
SourceSelection _source;
|
SourceSelection _source;
|
||||||
@@ -37,6 +38,9 @@ public:
|
|||||||
RegexConfig _regex;
|
RegexConfig _regex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool CheckConditionHelper(const OBSWeakSource &);
|
||||||
|
|
||||||
|
std::string _currentSettings;
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "macro-condition-recording.hpp"
|
#include "macro-condition-recording.hpp"
|
||||||
|
#include "macro.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
@@ -10,45 +11,91 @@ bool MacroConditionRecord::_registered = MacroConditionFactory::Register(
|
|||||||
{MacroConditionRecord::Create, MacroConditionRecordEdit::Create,
|
{MacroConditionRecord::Create, MacroConditionRecordEdit::Create,
|
||||||
"AdvSceneSwitcher.condition.record"});
|
"AdvSceneSwitcher.condition.record"});
|
||||||
|
|
||||||
const static std::map<RecordState, std::string> recordStates = {
|
const static std::map<MacroConditionRecord::Condition, std::string>
|
||||||
{RecordState::STOP, "AdvSceneSwitcher.condition.record.state.stop"},
|
recordStates = {
|
||||||
{RecordState::PAUSE, "AdvSceneSwitcher.condition.record.state.pause"},
|
{MacroConditionRecord::Condition::STOP,
|
||||||
{RecordState::START, "AdvSceneSwitcher.condition.record.state.start"},
|
"AdvSceneSwitcher.condition.record.state.stop"},
|
||||||
|
{MacroConditionRecord::Condition::PAUSE,
|
||||||
|
"AdvSceneSwitcher.condition.record.state.pause"},
|
||||||
|
{MacroConditionRecord::Condition::START,
|
||||||
|
"AdvSceneSwitcher.condition.record.state.start"},
|
||||||
|
{MacroConditionRecord::Condition::SAVE_DONE,
|
||||||
|
"AdvSceneSwitcher.condition.record.state.saveDone"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MacroConditionRecord::MacroConditionRecord(Macro *m) : MacroCondition(m)
|
||||||
|
{
|
||||||
|
OBSOutputAutoRelease output = obs_frontend_get_recording_output();
|
||||||
|
if (!output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto sh = obs_output_get_signal_handler(output);
|
||||||
|
signal_handler_connect(sh, "stop", StopSignal, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroConditionRecord::~MacroConditionRecord()
|
||||||
|
{
|
||||||
|
OBSOutputAutoRelease output = obs_frontend_get_recording_output();
|
||||||
|
if (!output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto sh = obs_output_get_signal_handler(output);
|
||||||
|
signal_handler_disconnect(sh, "stop", StopSignal, this);
|
||||||
|
}
|
||||||
|
|
||||||
bool MacroConditionRecord::CheckCondition()
|
bool MacroConditionRecord::CheckCondition()
|
||||||
{
|
{
|
||||||
bool stateMatch = false;
|
switch (_condition) {
|
||||||
switch (_recordState) {
|
case Condition::STOP:
|
||||||
case RecordState::STOP:
|
return !obs_frontend_recording_active();
|
||||||
stateMatch = !obs_frontend_recording_active();
|
case Condition::PAUSE:
|
||||||
break;
|
return obs_frontend_recording_paused();
|
||||||
case RecordState::PAUSE:
|
case Condition::START:
|
||||||
stateMatch = obs_frontend_recording_paused();
|
return obs_frontend_recording_active();
|
||||||
break;
|
case Condition::SAVE_DONE:
|
||||||
case RecordState::START:
|
if (_recordingSaveDone) {
|
||||||
stateMatch = obs_frontend_recording_active();
|
_recordingSaveDone = false;
|
||||||
break;
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return stateMatch;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionRecord::Save(obs_data_t *obj) const
|
bool MacroConditionRecord::Save(obs_data_t *obj) const
|
||||||
{
|
{
|
||||||
MacroCondition::Save(obj);
|
MacroCondition::Save(obj);
|
||||||
obs_data_set_int(obj, "state", static_cast<int>(_recordState));
|
obs_data_set_int(obj, "state", static_cast<int>(_condition));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionRecord::Load(obs_data_t *obj)
|
bool MacroConditionRecord::Load(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
MacroCondition::Load(obj);
|
MacroCondition::Load(obj);
|
||||||
_recordState = static_cast<RecordState>(obs_data_get_int(obj, "state"));
|
_condition = static_cast<Condition>(obs_data_get_int(obj, "state"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionRecord::StopSignal(void *c, calldata_t *data)
|
||||||
|
{
|
||||||
|
auto condition = static_cast<MacroConditionRecord *>(c);
|
||||||
|
const auto macro = condition->GetMacro();
|
||||||
|
if (macro && macro->Paused()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long code = 0;
|
||||||
|
if (!calldata_get_int(data, "code", &code)) {
|
||||||
|
condition->_recordingSaveDone = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code == OBS_OUTPUT_SUCCESS) {
|
||||||
|
condition->_recordingSaveDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void populateStateSelection(QComboBox *list)
|
static inline void populateStateSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : recordStates) {
|
for (auto entry : recordStates) {
|
||||||
@@ -89,7 +136,8 @@ void MacroConditionRecordEdit::StateChanged(int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_recordState = static_cast<RecordState>(value);
|
_entryData->_condition =
|
||||||
|
static_cast<MacroConditionRecord::Condition>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionRecordEdit::UpdateEntryData()
|
void MacroConditionRecordEdit::UpdateEntryData()
|
||||||
@@ -98,8 +146,7 @@ void MacroConditionRecordEdit::UpdateEntryData()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_recordState->setCurrentIndex(
|
_recordState->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||||
static_cast<int>(_entryData->_recordState));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -6,15 +6,10 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
enum class RecordState {
|
|
||||||
STOP,
|
|
||||||
PAUSE,
|
|
||||||
START,
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacroConditionRecord : public MacroCondition {
|
class MacroConditionRecord : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
MacroConditionRecord(Macro *m) : MacroCondition(m) {}
|
MacroConditionRecord(Macro *m);
|
||||||
|
~MacroConditionRecord();
|
||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj) const;
|
bool Save(obs_data_t *obj) const;
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
@@ -24,9 +19,18 @@ public:
|
|||||||
return std::make_shared<MacroConditionRecord>(m);
|
return std::make_shared<MacroConditionRecord>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordState _recordState = RecordState::STOP;
|
enum class Condition {
|
||||||
|
STOP,
|
||||||
|
PAUSE,
|
||||||
|
START,
|
||||||
|
SAVE_DONE,
|
||||||
|
};
|
||||||
|
Condition _condition = Condition::STOP;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void StopSignal(void *condition, calldata_t *);
|
||||||
|
bool _recordingSaveDone = false;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "process-config.hpp"
|
#include "process-config.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
|
|
||||||
|
|||||||
@@ -12,19 +12,79 @@ bool MacroConditionSceneTransform::_registered =
|
|||||||
MacroConditionSceneTransformEdit::Create,
|
MacroConditionSceneTransformEdit::Create,
|
||||||
"AdvSceneSwitcher.condition.sceneTransform"});
|
"AdvSceneSwitcher.condition.sceneTransform"});
|
||||||
|
|
||||||
bool MacroConditionSceneTransform::CheckCondition()
|
const static std::map<MacroConditionSceneTransform::CondType, std::string>
|
||||||
|
conditionTypes = {
|
||||||
|
{MacroConditionSceneTransform::CondType::MATCHES,
|
||||||
|
"AdvSceneSwitcher.condition.sceneTransform.entry.type.matches"},
|
||||||
|
{MacroConditionSceneTransform::CondType::CHANGED,
|
||||||
|
"AdvSceneSwitcher.condition.sceneTransform.entry.type.changed"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool doesTransformOfAnySceneItemMatch(
|
||||||
|
const std::vector<OBSSceneItem> &items, const std::string &jsonCompare,
|
||||||
|
const RegexConfig ®ex, std::string &newVariable)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
auto items = _source.GetSceneItems(_scene);
|
|
||||||
|
|
||||||
std::string json;
|
std::string json;
|
||||||
for (const auto &item : items) {
|
for (const auto &item : items) {
|
||||||
json = GetSceneItemTransform(item);
|
json = GetSceneItemTransform(item);
|
||||||
if (MatchJson(json, _settings, _regex)) {
|
if (MatchJson(json, jsonCompare, regex)) {
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetVariableValue(json);
|
newVariable = json;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
didTransformOfAnySceneItemChange(const std::vector<OBSSceneItem> &items,
|
||||||
|
std::vector<std::string> &previousTransform,
|
||||||
|
std::string &newVariable)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
std::string json;
|
||||||
|
RegexConfig regex;
|
||||||
|
auto numItems = items.size();
|
||||||
|
if (previousTransform.size() < numItems) {
|
||||||
|
ret = true;
|
||||||
|
previousTransform.resize(numItems);
|
||||||
|
}
|
||||||
|
for (size_t idx = 0; idx < numItems; ++idx) {
|
||||||
|
auto const &item = items[idx];
|
||||||
|
json = GetSceneItemTransform(item);
|
||||||
|
if (!MatchJson(json, previousTransform[idx], regex)) {
|
||||||
|
ret = true;
|
||||||
|
previousTransform[idx] = json;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newVariable = json;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionSceneTransform::CheckCondition()
|
||||||
|
{
|
||||||
|
auto items = _source.GetSceneItems(_scene);
|
||||||
|
if (items.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string newVariable = "";
|
||||||
|
bool ret = false;
|
||||||
|
switch (_type) {
|
||||||
|
case CondType::MATCHES:
|
||||||
|
ret = doesTransformOfAnySceneItemMatch(items, _settings, _regex,
|
||||||
|
newVariable);
|
||||||
|
break;
|
||||||
|
case CondType::CHANGED:
|
||||||
|
ret = didTransformOfAnySceneItemChange(
|
||||||
|
items, _previousTransform, newVariable);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetVariableValue(newVariable);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +95,7 @@ bool MacroConditionSceneTransform::Save(obs_data_t *obj) const
|
|||||||
_source.Save(obj);
|
_source.Save(obj);
|
||||||
_settings.Save(obj, "settings");
|
_settings.Save(obj, "settings");
|
||||||
_regex.Save(obj);
|
_regex.Save(obj);
|
||||||
|
obs_data_set_int(obj, "type", static_cast<int>(_type));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +113,7 @@ bool MacroConditionSceneTransform::Load(obs_data_t *obj)
|
|||||||
_source.Load(obj);
|
_source.Load(obj);
|
||||||
_settings.Load(obj, "settings");
|
_settings.Load(obj, "settings");
|
||||||
_regex.Load(obj);
|
_regex.Load(obj);
|
||||||
|
_type = static_cast<CondType>(obs_data_get_int(obj, "type"));
|
||||||
// TOOD: remove in future version
|
// TOOD: remove in future version
|
||||||
if (obs_data_has_user_value(obj, "regex")) {
|
if (obs_data_has_user_value(obj, "regex")) {
|
||||||
_regex.CreateBackwardsCompatibleRegex(
|
_regex.CreateBackwardsCompatibleRegex(
|
||||||
@@ -69,6 +131,13 @@ std::string MacroConditionSceneTransform::GetShortDesc() const
|
|||||||
return _scene.ToString() + " - " + _source.ToString();
|
return _scene.ToString() + " - " + _source.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void populateTypesSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
for (const auto &entry : conditionTypes) {
|
||||||
|
list->addItem(obs_module_text(entry.second.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
|
MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
std::shared_ptr<MacroConditionSceneTransform> entryData)
|
std::shared_ptr<MacroConditionSceneTransform> entryData)
|
||||||
@@ -76,11 +145,14 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
|
|||||||
_scenes(new SceneSelectionWidget(window(), true, false, false, true)),
|
_scenes(new SceneSelectionWidget(window(), true, false, false, true)),
|
||||||
_sources(new SceneItemSelectionWidget(
|
_sources(new SceneItemSelectionWidget(
|
||||||
parent, true, SceneItemSelectionWidget::Placeholder::ANY)),
|
parent, true, SceneItemSelectionWidget::Placeholder::ANY)),
|
||||||
|
_types(new QComboBox()),
|
||||||
_getSettings(new QPushButton(obs_module_text(
|
_getSettings(new QPushButton(obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.sceneTransform.getTransform"))),
|
"AdvSceneSwitcher.condition.sceneTransform.getTransform"))),
|
||||||
_settings(new VariableTextEdit(this)),
|
_settings(new VariableTextEdit(this)),
|
||||||
_regex(new RegexConfigWidget(parent))
|
_regex(new RegexConfigWidget(parent))
|
||||||
{
|
{
|
||||||
|
populateTypesSelection(_types);
|
||||||
|
|
||||||
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
||||||
this, SLOT(SceneChanged(const SceneSelection &)));
|
this, SLOT(SceneChanged(const SceneSelection &)));
|
||||||
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
||||||
@@ -88,6 +160,8 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
|
|||||||
QWidget::connect(_sources,
|
QWidget::connect(_sources,
|
||||||
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
|
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
|
||||||
this, SLOT(SourceChanged(const SceneItemSelection &)));
|
this, SLOT(SourceChanged(const SceneItemSelection &)));
|
||||||
|
QWidget::connect(_types, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(TypeChanged(int)));
|
||||||
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
|
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
|
||||||
SLOT(GetSettingsClicked()));
|
SLOT(GetSettingsClicked()));
|
||||||
QWidget::connect(_settings, SIGNAL(textChanged()), this,
|
QWidget::connect(_settings, SIGNAL(textChanged()), this,
|
||||||
@@ -96,8 +170,11 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
|
|||||||
SLOT(RegexChanged(RegexConfig)));
|
SLOT(RegexChanged(RegexConfig)));
|
||||||
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{scenes}}", _scenes}, {"{{sources}}", _sources},
|
{"{{scenes}}", _scenes},
|
||||||
{"{{settings}}", _settings}, {"{{getSettings}}", _getSettings},
|
{"{{sources}}", _sources},
|
||||||
|
{"{{types}}", _types},
|
||||||
|
{"{{settings}}", _settings},
|
||||||
|
{"{{getSettings}}", _getSettings},
|
||||||
{"{{regex}}", _regex},
|
{"{{regex}}", _regex},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -136,11 +213,10 @@ void MacroConditionSceneTransformEdit::UpdateEntryData()
|
|||||||
|
|
||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_sources->SetSceneItem(_entryData->_source);
|
_sources->SetSceneItem(_entryData->_source);
|
||||||
|
_types->setCurrentIndex(static_cast<int>(_entryData->_type));
|
||||||
_regex->SetRegexConfig(_entryData->_regex);
|
_regex->SetRegexConfig(_entryData->_regex);
|
||||||
_settings->setPlainText(_entryData->_settings);
|
_settings->setPlainText(_entryData->_settings);
|
||||||
|
SetWidgetVisibility();
|
||||||
adjustSize();
|
|
||||||
updateGeometry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s)
|
void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s)
|
||||||
@@ -168,6 +244,18 @@ void MacroConditionSceneTransformEdit::SourceChanged(
|
|||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionSceneTransformEdit::TypeChanged(int index)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_type =
|
||||||
|
static_cast<MacroConditionSceneTransform::CondType>(index);
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
void MacroConditionSceneTransformEdit::GetSettingsClicked()
|
void MacroConditionSceneTransformEdit::GetSettingsClicked()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -213,4 +301,16 @@ void MacroConditionSceneTransformEdit::RegexChanged(RegexConfig conf)
|
|||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionSceneTransformEdit::SetWidgetVisibility()
|
||||||
|
{
|
||||||
|
const bool showSettingsAndRegex =
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionSceneTransform::CondType::MATCHES;
|
||||||
|
_settings->setVisible(showSettingsAndRegex);
|
||||||
|
_getSettings->setVisible(showSettingsAndRegex);
|
||||||
|
_regex->setVisible(showSettingsAndRegex);
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -23,12 +23,20 @@ public:
|
|||||||
return std::make_shared<MacroConditionSceneTransform>(m);
|
return std::make_shared<MacroConditionSceneTransform>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class CondType {
|
||||||
|
MATCHES,
|
||||||
|
CHANGED,
|
||||||
|
};
|
||||||
|
|
||||||
SceneSelection _scene;
|
SceneSelection _scene;
|
||||||
SceneItemSelection _source;
|
SceneItemSelection _source;
|
||||||
|
CondType _type = CondType::MATCHES;
|
||||||
RegexConfig _regex;
|
RegexConfig _regex;
|
||||||
StringVariable _settings = "";
|
StringVariable _settings = "";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::vector<std::string> _previousTransform;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
@@ -54,6 +62,7 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void SceneChanged(const SceneSelection &);
|
void SceneChanged(const SceneSelection &);
|
||||||
void SourceChanged(const SceneItemSelection &);
|
void SourceChanged(const SceneItemSelection &);
|
||||||
|
void TypeChanged(int type);
|
||||||
void GetSettingsClicked();
|
void GetSettingsClicked();
|
||||||
void SettingsChanged();
|
void SettingsChanged();
|
||||||
void RegexChanged(RegexConfig);
|
void RegexChanged(RegexConfig);
|
||||||
@@ -63,6 +72,7 @@ signals:
|
|||||||
protected:
|
protected:
|
||||||
SceneSelectionWidget *_scenes;
|
SceneSelectionWidget *_scenes;
|
||||||
SceneItemSelectionWidget *_sources;
|
SceneItemSelectionWidget *_sources;
|
||||||
|
QComboBox *_types;
|
||||||
QPushButton *_getSettings;
|
QPushButton *_getSettings;
|
||||||
VariableTextEdit *_settings;
|
VariableTextEdit *_settings;
|
||||||
RegexConfigWidget *_regex;
|
RegexConfigWidget *_regex;
|
||||||
@@ -70,6 +80,7 @@ protected:
|
|||||||
std::shared_ptr<MacroConditionSceneTransform> _entryData;
|
std::shared_ptr<MacroConditionSceneTransform> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ const static std::map<MacroConditionScene::Type, std::string> sceneTypes = {
|
|||||||
"AdvSceneSwitcher.condition.scene.type.current"},
|
"AdvSceneSwitcher.condition.scene.type.current"},
|
||||||
{MacroConditionScene::Type::PREVIOUS,
|
{MacroConditionScene::Type::PREVIOUS,
|
||||||
"AdvSceneSwitcher.condition.scene.type.previous"},
|
"AdvSceneSwitcher.condition.scene.type.previous"},
|
||||||
|
{MacroConditionScene::Type::PREVIEW,
|
||||||
|
"AdvSceneSwitcher.condition.scene.type.preview"},
|
||||||
{MacroConditionScene::Type::CHANGED,
|
{MacroConditionScene::Type::CHANGED,
|
||||||
"AdvSceneSwitcher.condition.scene.type.changed"},
|
"AdvSceneSwitcher.condition.scene.type.changed"},
|
||||||
{MacroConditionScene::Type::NOT_CHANGED,
|
{MacroConditionScene::Type::NOT_CHANGED,
|
||||||
@@ -24,6 +26,8 @@ const static std::map<MacroConditionScene::Type, std::string> sceneTypes = {
|
|||||||
"AdvSceneSwitcher.condition.scene.type.currentPattern"},
|
"AdvSceneSwitcher.condition.scene.type.currentPattern"},
|
||||||
{MacroConditionScene::Type::PREVIOUS_PATTERN,
|
{MacroConditionScene::Type::PREVIOUS_PATTERN,
|
||||||
"AdvSceneSwitcher.condition.scene.type.previousPattern"},
|
"AdvSceneSwitcher.condition.scene.type.previousPattern"},
|
||||||
|
{MacroConditionScene::Type::PREVIEW_PATTERN,
|
||||||
|
"AdvSceneSwitcher.condition.scene.type.previewPattern"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool sceneNameMatchesRegex(const OBSWeakSource &scene,
|
static bool sceneNameMatchesRegex(const OBSWeakSource &scene,
|
||||||
@@ -72,29 +76,55 @@ bool MacroConditionScene::CheckCondition()
|
|||||||
case Type::CURRENT: {
|
case Type::CURRENT: {
|
||||||
auto scene = getCurrentSceneHelper(_useTransitionTargetScene);
|
auto scene = getCurrentSceneHelper(_useTransitionTargetScene);
|
||||||
SetVariableValue(GetWeakSourceName(scene));
|
SetVariableValue(GetWeakSourceName(scene));
|
||||||
|
SetTempVarValue("current", GetWeakSourceName(scene));
|
||||||
return scene == _scene.GetScene(false);
|
return scene == _scene.GetScene(false);
|
||||||
}
|
}
|
||||||
case Type::PREVIOUS: {
|
case Type::PREVIOUS: {
|
||||||
auto scene = getPreviousSceneHelper(_useTransitionTargetScene);
|
auto scene = getPreviousSceneHelper(_useTransitionTargetScene);
|
||||||
SetVariableValue(GetWeakSourceName(scene));
|
SetVariableValue(GetWeakSourceName(scene));
|
||||||
|
SetTempVarValue("previous", GetWeakSourceName(scene));
|
||||||
|
return scene == _scene.GetScene(false);
|
||||||
|
}
|
||||||
|
case Type::PREVIEW: {
|
||||||
|
OBSSourceAutoRelease source =
|
||||||
|
obs_frontend_get_current_preview_scene();
|
||||||
|
OBSWeakSourceAutoRelease scene =
|
||||||
|
obs_source_get_weak_source(source);
|
||||||
|
SetVariableValue(GetWeakSourceName(scene));
|
||||||
|
SetTempVarValue("preview", GetWeakSourceName(scene));
|
||||||
return scene == _scene.GetScene(false);
|
return scene == _scene.GetScene(false);
|
||||||
}
|
}
|
||||||
case Type::CHANGED:
|
case Type::CHANGED:
|
||||||
SetVariableValue(GetWeakSourceName(switcher->currentScene));
|
SetVariableValue(GetWeakSourceName(switcher->currentScene));
|
||||||
|
SetTempVarValue("current",
|
||||||
|
GetWeakSourceName(switcher->currentScene));
|
||||||
return sceneChanged;
|
return sceneChanged;
|
||||||
case Type::NOT_CHANGED:
|
case Type::NOT_CHANGED:
|
||||||
SetVariableValue(GetWeakSourceName(switcher->currentScene));
|
SetVariableValue(GetWeakSourceName(switcher->currentScene));
|
||||||
|
SetTempVarValue("current",
|
||||||
|
GetWeakSourceName(switcher->currentScene));
|
||||||
return !sceneChanged;
|
return !sceneChanged;
|
||||||
case Type::CURRENT_PATTERN: {
|
case Type::CURRENT_PATTERN: {
|
||||||
auto scene = getCurrentSceneHelper(_useTransitionTargetScene);
|
auto scene = getCurrentSceneHelper(_useTransitionTargetScene);
|
||||||
SetVariableValue(GetWeakSourceName(scene));
|
SetVariableValue(GetWeakSourceName(scene));
|
||||||
|
SetTempVarValue("current", GetWeakSourceName(scene));
|
||||||
return sceneNameMatchesRegex(scene, _pattern);
|
return sceneNameMatchesRegex(scene, _pattern);
|
||||||
}
|
}
|
||||||
case Type::PREVIOUS_PATTERN: {
|
case Type::PREVIOUS_PATTERN: {
|
||||||
auto scene = getPreviousSceneHelper(_useTransitionTargetScene);
|
auto scene = getPreviousSceneHelper(_useTransitionTargetScene);
|
||||||
SetVariableValue(GetWeakSourceName(scene));
|
SetVariableValue(GetWeakSourceName(scene));
|
||||||
|
SetTempVarValue("previous", GetWeakSourceName(scene));
|
||||||
return sceneNameMatchesRegex(scene, _pattern);
|
return sceneNameMatchesRegex(scene, _pattern);
|
||||||
}
|
}
|
||||||
|
case Type::PREVIEW_PATTERN: {
|
||||||
|
OBSSourceAutoRelease source =
|
||||||
|
obs_frontend_get_current_preview_scene();
|
||||||
|
OBSWeakSourceAutoRelease scene =
|
||||||
|
obs_source_get_weak_source(source);
|
||||||
|
SetVariableValue(GetWeakSourceName(scene));
|
||||||
|
SetTempVarValue("preview", GetWeakSourceName(scene));
|
||||||
|
return sceneNameMatchesRegex(scene.Get(), _pattern);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -108,6 +138,7 @@ bool MacroConditionScene::Save(obs_data_t *obj) const
|
|||||||
obs_data_set_string(obj, "pattern", _pattern.c_str());
|
obs_data_set_string(obj, "pattern", _pattern.c_str());
|
||||||
obs_data_set_bool(obj, "useTransitionTargetScene",
|
obs_data_set_bool(obj, "useTransitionTargetScene",
|
||||||
_useTransitionTargetScene);
|
_useTransitionTargetScene);
|
||||||
|
obs_data_set_int(obj, "version", 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +155,46 @@ bool MacroConditionScene::Load(obs_data_t *obj)
|
|||||||
_useTransitionTargetScene =
|
_useTransitionTargetScene =
|
||||||
obs_data_get_bool(obj, "useTransitionTargetScene");
|
obs_data_get_bool(obj, "useTransitionTargetScene");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove fallback in future version
|
||||||
|
if (!obs_data_has_user_value(obj, "version")) {
|
||||||
|
enum {
|
||||||
|
CURRENT,
|
||||||
|
PREVIOUS,
|
||||||
|
CHANGED,
|
||||||
|
NOT_CHANGED,
|
||||||
|
CURRENT_PATTERN,
|
||||||
|
PREVIOUS_PATTERN,
|
||||||
|
};
|
||||||
|
|
||||||
|
int oldType = obs_data_get_int(obj, "type");
|
||||||
|
switch (oldType) {
|
||||||
|
case CURRENT:
|
||||||
|
_type = Type::CURRENT;
|
||||||
|
break;
|
||||||
|
case PREVIOUS:
|
||||||
|
_type = Type::PREVIOUS;
|
||||||
|
break;
|
||||||
|
case CHANGED:
|
||||||
|
_type = Type::CHANGED;
|
||||||
|
break;
|
||||||
|
case NOT_CHANGED:
|
||||||
|
_type = Type::NOT_CHANGED;
|
||||||
|
break;
|
||||||
|
case CURRENT_PATTERN:
|
||||||
|
_type = Type::CURRENT_PATTERN;
|
||||||
|
break;
|
||||||
|
case PREVIOUS_PATTERN:
|
||||||
|
_type = Type::PREVIOUS_PATTERN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"failed to convert scene condition type (%d) for macro %s",
|
||||||
|
oldType, GetMacro()->Name().c_str());
|
||||||
|
_type = Type::CURRENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,10 +206,46 @@ std::string MacroConditionScene::GetShortDesc() const
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionScene::SetupTempVars()
|
||||||
|
{
|
||||||
|
MacroCondition::SetupTempVars();
|
||||||
|
switch (_type) {
|
||||||
|
case Type::CURRENT:
|
||||||
|
case Type::CHANGED:
|
||||||
|
case Type::NOT_CHANGED:
|
||||||
|
case Type::CURRENT_PATTERN:
|
||||||
|
AddTempvar("current",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.scene.current"));
|
||||||
|
break;
|
||||||
|
case Type::PREVIOUS:
|
||||||
|
case Type::PREVIOUS_PATTERN:
|
||||||
|
AddTempvar("previous",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.scene.previous"));
|
||||||
|
break;
|
||||||
|
case Type::PREVIEW:
|
||||||
|
case Type::PREVIEW_PATTERN:
|
||||||
|
AddTempvar("preview",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.scene.preview"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionScene::SetType(const Type &type)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
SetupTempVars();
|
||||||
|
}
|
||||||
|
|
||||||
static inline void populateTypeSelection(QComboBox *list)
|
static inline void populateTypeSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : sceneTypes) {
|
for (const auto &[id, name] : sceneTypes) {
|
||||||
list->addItem(obs_module_text(entry.second.c_str()));
|
list->addItem(obs_module_text(name.c_str()),
|
||||||
|
static_cast<int>(id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,14 +306,15 @@ void MacroConditionSceneEdit::SceneChanged(const SceneSelection &s)
|
|||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionSceneEdit::TypeChanged(int value)
|
void MacroConditionSceneEdit::TypeChanged(int index)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_type = static_cast<MacroConditionScene::Type>(value);
|
_entryData->SetType(static_cast<MacroConditionScene::Type>(
|
||||||
|
_sceneType->itemData(index).toInt()));
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,32 +341,38 @@ void MacroConditionSceneEdit::UseTransitionTargetSceneChanged(int state)
|
|||||||
void MacroConditionSceneEdit::SetWidgetVisibility()
|
void MacroConditionSceneEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
_scenes->setVisible(
|
_scenes->setVisible(
|
||||||
_entryData->_type == MacroConditionScene::Type::CURRENT ||
|
_entryData->GetType() == MacroConditionScene::Type::CURRENT ||
|
||||||
_entryData->_type == MacroConditionScene::Type::PREVIOUS);
|
_entryData->GetType() == MacroConditionScene::Type::PREVIOUS ||
|
||||||
|
_entryData->GetType() == MacroConditionScene::Type::PREVIEW);
|
||||||
_useTransitionTargetScene->setVisible(
|
_useTransitionTargetScene->setVisible(
|
||||||
_entryData->_type == MacroConditionScene::Type::CURRENT ||
|
_entryData->GetType() == MacroConditionScene::Type::CURRENT ||
|
||||||
_entryData->_type == MacroConditionScene::Type::PREVIOUS ||
|
_entryData->GetType() == MacroConditionScene::Type::PREVIOUS ||
|
||||||
_entryData->_type ==
|
_entryData->GetType() ==
|
||||||
MacroConditionScene::Type::CURRENT_PATTERN ||
|
MacroConditionScene::Type::CURRENT_PATTERN ||
|
||||||
_entryData->_type ==
|
_entryData->GetType() ==
|
||||||
MacroConditionScene::Type::PREVIOUS_PATTERN);
|
MacroConditionScene::Type::PREVIOUS_PATTERN);
|
||||||
_pattern->setVisible(
|
_pattern->setVisible(
|
||||||
_entryData->_type ==
|
_entryData->GetType() ==
|
||||||
MacroConditionScene::Type::CURRENT_PATTERN ||
|
MacroConditionScene::Type::CURRENT_PATTERN ||
|
||||||
_entryData->_type ==
|
_entryData->GetType() ==
|
||||||
MacroConditionScene::Type::PREVIOUS_PATTERN);
|
MacroConditionScene::Type::PREVIOUS_PATTERN ||
|
||||||
|
_entryData->GetType() ==
|
||||||
|
MacroConditionScene::Type::PREVIEW_PATTERN);
|
||||||
|
|
||||||
if (_entryData->_type == MacroConditionScene::Type::PREVIOUS ||
|
if (_entryData->GetType() == MacroConditionScene::Type::PREVIOUS ||
|
||||||
_entryData->_type == MacroConditionScene::Type::PREVIOUS_PATTERN) {
|
_entryData->GetType() ==
|
||||||
|
MacroConditionScene::Type::PREVIOUS_PATTERN) {
|
||||||
_useTransitionTargetScene->setText(obs_module_text(
|
_useTransitionTargetScene->setText(obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour"));
|
"AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour"));
|
||||||
}
|
}
|
||||||
if (_entryData->_type == MacroConditionScene::Type::CURRENT ||
|
if (_entryData->GetType() == MacroConditionScene::Type::CURRENT ||
|
||||||
_entryData->_type == MacroConditionScene::Type::CURRENT_PATTERN) {
|
_entryData->GetType() ==
|
||||||
|
MacroConditionScene::Type::CURRENT_PATTERN) {
|
||||||
_useTransitionTargetScene->setText(obs_module_text(
|
_useTransitionTargetScene->setText(obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour"));
|
"AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour"));
|
||||||
}
|
}
|
||||||
adjustSize();
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionSceneEdit::UpdateEntryData()
|
void MacroConditionSceneEdit::UpdateEntryData()
|
||||||
@@ -268,7 +382,8 @@ void MacroConditionSceneEdit::UpdateEntryData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_sceneType->setCurrentIndex(static_cast<int>(_entryData->_type));
|
_sceneType->setCurrentIndex(
|
||||||
|
_sceneType->findData(static_cast<int>(_entryData->GetType())));
|
||||||
_pattern->setText(QString::fromStdString(_entryData->_pattern));
|
_pattern->setText(QString::fromStdString(_entryData->_pattern));
|
||||||
_useTransitionTargetScene->setChecked(
|
_useTransitionTargetScene->setChecked(
|
||||||
_entryData->_useTransitionTargetScene);
|
_entryData->_useTransitionTargetScene);
|
||||||
|
|||||||
@@ -23,16 +23,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
CURRENT,
|
CURRENT = 10,
|
||||||
PREVIOUS,
|
PREVIOUS = 20,
|
||||||
CHANGED,
|
PREVIEW = 30,
|
||||||
NOT_CHANGED,
|
CHANGED = 40,
|
||||||
CURRENT_PATTERN,
|
NOT_CHANGED = 50,
|
||||||
PREVIOUS_PATTERN,
|
CURRENT_PATTERN = 60,
|
||||||
|
PREVIOUS_PATTERN = 70,
|
||||||
|
PREVIEW_PATTERN = 80,
|
||||||
};
|
};
|
||||||
|
void SetType(const Type &);
|
||||||
|
Type GetType() const { return _type; }
|
||||||
|
|
||||||
SceneSelection _scene;
|
SceneSelection _scene;
|
||||||
Type _type = Type::CURRENT;
|
|
||||||
std::string _pattern = ".*Scene.*";
|
std::string _pattern = ".*Scene.*";
|
||||||
// During a transition "current" scene could either stand for the scene
|
// During a transition "current" scene could either stand for the scene
|
||||||
// being transitioned to or the scene still being transitioned away
|
// being transitioned to or the scene still being transitioned away
|
||||||
@@ -40,6 +43,9 @@ public:
|
|||||||
bool _useTransitionTargetScene = false;
|
bool _useTransitionTargetScene = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SetupTempVars();
|
||||||
|
|
||||||
|
Type _type = Type::CURRENT;
|
||||||
std::chrono::high_resolution_clock::time_point _lastSceneChangeTime{};
|
std::chrono::high_resolution_clock::time_point _lastSceneChangeTime{};
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
|
|||||||
@@ -6,10 +6,13 @@ namespace advss {
|
|||||||
|
|
||||||
const std::string MacroConditionSlideshow::id = "slideshow";
|
const std::string MacroConditionSlideshow::id = "slideshow";
|
||||||
|
|
||||||
bool MacroConditionSlideshow::_registered = MacroConditionFactory::Register(
|
bool MacroConditionSlideshow::_registered =
|
||||||
MacroConditionSlideshow::id,
|
obs_get_version() >= MAKE_SEMANTIC_VERSION(29, 1, 0) &&
|
||||||
{MacroConditionSlideshow::Create, MacroConditionSlideshowEdit::Create,
|
MacroConditionFactory::Register(
|
||||||
"AdvSceneSwitcher.condition.slideshow"});
|
MacroConditionSlideshow::id,
|
||||||
|
{MacroConditionSlideshow::Create,
|
||||||
|
MacroConditionSlideshowEdit::Create,
|
||||||
|
"AdvSceneSwitcher.condition.slideshow"});
|
||||||
|
|
||||||
static const std::map<MacroConditionSlideshow::Condition, std::string>
|
static const std::map<MacroConditionSlideshow::Condition, std::string>
|
||||||
conditions = {
|
conditions = {
|
||||||
@@ -200,9 +203,9 @@ MacroConditionSlideshowEdit::MacroConditionSlideshowEdit(
|
|||||||
QWidget *parent, std::shared_ptr<MacroConditionSlideshow> entryData)
|
QWidget *parent, std::shared_ptr<MacroConditionSlideshow> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
_conditions(new QComboBox(this)),
|
_conditions(new QComboBox(this)),
|
||||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
|
||||||
_index(new VariableSpinBox(this)),
|
_index(new VariableSpinBox(this)),
|
||||||
_path(new VariableLineEdit(this))
|
_path(new VariableLineEdit(this)),
|
||||||
|
_sources(new SourceSelectionWidget(this, QStringList(), true))
|
||||||
{
|
{
|
||||||
setToolTip(obs_module_text(
|
setToolTip(obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.slideshow.updateIntervalTooltip"));
|
"AdvSceneSwitcher.condition.slideshow.updateIntervalTooltip"));
|
||||||
|
|||||||
@@ -10,13 +10,16 @@ bool MacroConditionSource::_registered = MacroConditionFactory::Register(
|
|||||||
{MacroConditionSource::Create, MacroConditionSourceEdit::Create,
|
{MacroConditionSource::Create, MacroConditionSourceEdit::Create,
|
||||||
"AdvSceneSwitcher.condition.source"});
|
"AdvSceneSwitcher.condition.source"});
|
||||||
|
|
||||||
const static std::map<SourceCondition, std::string> sourceConditionTypes = {
|
const static std::map<MacroConditionSource::Condition, std::string>
|
||||||
{SourceCondition::ACTIVE,
|
sourceCnditionTypes = {
|
||||||
"AdvSceneSwitcher.condition.source.type.active"},
|
{MacroConditionSource::Condition::ACTIVE,
|
||||||
{SourceCondition::SHOWING,
|
"AdvSceneSwitcher.condition.source.type.active"},
|
||||||
"AdvSceneSwitcher.condition.source.type.showing"},
|
{MacroConditionSource::Condition::SHOWING,
|
||||||
{SourceCondition::SETTINGS,
|
"AdvSceneSwitcher.condition.source.type.showing"},
|
||||||
"AdvSceneSwitcher.condition.source.type.settings"},
|
{MacroConditionSource::Condition::SETTINGS_MATCH,
|
||||||
|
"AdvSceneSwitcher.condition.source.type.settings"},
|
||||||
|
{MacroConditionSource::Condition::SETTINGS_CHANGED,
|
||||||
|
"AdvSceneSwitcher.condition.source.type.settingsChanged"},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MacroConditionSource::CheckCondition()
|
bool MacroConditionSource::CheckCondition()
|
||||||
@@ -29,13 +32,13 @@ bool MacroConditionSource::CheckCondition()
|
|||||||
auto s = obs_weak_source_get_source(_source.GetSource());
|
auto s = obs_weak_source_get_source(_source.GetSource());
|
||||||
|
|
||||||
switch (_condition) {
|
switch (_condition) {
|
||||||
case SourceCondition::ACTIVE:
|
case Condition::ACTIVE:
|
||||||
ret = obs_source_active(s);
|
ret = obs_source_active(s);
|
||||||
break;
|
break;
|
||||||
case SourceCondition::SHOWING:
|
case Condition::SHOWING:
|
||||||
ret = obs_source_showing(s);
|
ret = obs_source_showing(s);
|
||||||
break;
|
break;
|
||||||
case SourceCondition::SETTINGS:
|
case Condition::SETTINGS_MATCH:
|
||||||
ret = CompareSourceSettings(_source.GetSource(), _settings,
|
ret = CompareSourceSettings(_source.GetSource(), _settings,
|
||||||
_regex);
|
_regex);
|
||||||
if (IsReferencedInVars()) {
|
if (IsReferencedInVars()) {
|
||||||
@@ -43,6 +46,13 @@ bool MacroConditionSource::CheckCondition()
|
|||||||
GetSourceSettings(_source.GetSource()));
|
GetSourceSettings(_source.GetSource()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Condition::SETTINGS_CHANGED: {
|
||||||
|
std::string settings = GetSourceSettings(_source.GetSource());
|
||||||
|
ret = !_currentSettings.empty() && settings != _currentSettings;
|
||||||
|
_currentSettings = settings;
|
||||||
|
SetVariableValue(settings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -70,8 +80,7 @@ bool MacroConditionSource::Load(obs_data_t *obj)
|
|||||||
{
|
{
|
||||||
MacroCondition::Load(obj);
|
MacroCondition::Load(obj);
|
||||||
_source.Load(obj);
|
_source.Load(obj);
|
||||||
_condition = static_cast<SourceCondition>(
|
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||||
obs_data_get_int(obj, "condition"));
|
|
||||||
_settings.Load(obj, "settings");
|
_settings.Load(obj, "settings");
|
||||||
_regex.Load(obj);
|
_regex.Load(obj);
|
||||||
// TOOD: remove in future version
|
// TOOD: remove in future version
|
||||||
@@ -89,8 +98,8 @@ std::string MacroConditionSource::GetShortDesc() const
|
|||||||
|
|
||||||
static inline void populateConditionSelection(QComboBox *list)
|
static inline void populateConditionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : sourceConditionTypes) {
|
for (const auto &[_, name] : sourceCnditionTypes) {
|
||||||
list->addItem(obs_module_text(entry.second.c_str()));
|
list->addItem(obs_module_text(name.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +182,8 @@ void MacroConditionSourceEdit::ConditionChanged(int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_condition = static_cast<SourceCondition>(index);
|
_entryData->_condition =
|
||||||
|
static_cast<MacroConditionSource::Condition>(index);
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,14 +230,18 @@ void MacroConditionSourceEdit::RegexChanged(RegexConfig conf)
|
|||||||
void MacroConditionSourceEdit::SetWidgetVisibility()
|
void MacroConditionSourceEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
_settings->setVisible(_entryData->_condition ==
|
_settings->setVisible(_entryData->_condition ==
|
||||||
SourceCondition::SETTINGS);
|
MacroConditionSource::Condition::SETTINGS_MATCH);
|
||||||
_getSettings->setVisible(_entryData->_condition ==
|
_getSettings->setVisible(
|
||||||
SourceCondition::SETTINGS);
|
_entryData->_condition ==
|
||||||
_regex->setVisible(_entryData->_condition == SourceCondition::SETTINGS);
|
MacroConditionSource::Condition::SETTINGS_MATCH);
|
||||||
|
_regex->setVisible(_entryData->_condition ==
|
||||||
|
MacroConditionSource::Condition::SETTINGS_MATCH);
|
||||||
|
|
||||||
setToolTip(
|
setToolTip(
|
||||||
(_entryData->_condition == SourceCondition::ACTIVE ||
|
(_entryData->_condition ==
|
||||||
_entryData->_condition == SourceCondition::SHOWING)
|
MacroConditionSource::Condition::ACTIVE ||
|
||||||
|
_entryData->_condition ==
|
||||||
|
MacroConditionSource::Condition::SHOWING)
|
||||||
? obs_module_text(
|
? obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.source.sceneVisibilityHint")
|
"AdvSceneSwitcher.condition.source.sceneVisibilityHint")
|
||||||
: "");
|
: "");
|
||||||
|
|||||||
@@ -10,12 +10,6 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
enum class SourceCondition {
|
|
||||||
ACTIVE,
|
|
||||||
SHOWING,
|
|
||||||
SETTINGS,
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacroConditionSource : public MacroCondition {
|
class MacroConditionSource : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
MacroConditionSource(Macro *m) : MacroCondition(m, true) {}
|
MacroConditionSource(Macro *m) : MacroCondition(m, true) {}
|
||||||
@@ -29,12 +23,21 @@ public:
|
|||||||
return std::make_shared<MacroConditionSource>(m);
|
return std::make_shared<MacroConditionSource>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Condition {
|
||||||
|
ACTIVE,
|
||||||
|
SHOWING,
|
||||||
|
SETTINGS_MATCH,
|
||||||
|
SETTINGS_CHANGED,
|
||||||
|
};
|
||||||
|
|
||||||
SourceSelection _source;
|
SourceSelection _source;
|
||||||
SourceCondition _condition = SourceCondition::ACTIVE;
|
Condition _condition = Condition::ACTIVE;
|
||||||
StringVariable _settings = "";
|
StringVariable _settings = "";
|
||||||
RegexConfig _regex;
|
RegexConfig _regex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string _currentSettings;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -155,6 +155,13 @@ void MacroConditionStudioModeEdit::SetWidgetVisibility()
|
|||||||
|
|
||||||
_scenes->setVisible(_entryData->_condition ==
|
_scenes->setVisible(_entryData->_condition ==
|
||||||
StudioModeCondition::PREVIEW_SCENE);
|
StudioModeCondition::PREVIEW_SCENE);
|
||||||
|
|
||||||
|
// TODO: Remove this workaround once the PREVIEW_SCENE condition type
|
||||||
|
// has been removed
|
||||||
|
if (_entryData->_condition != StudioModeCondition::PREVIEW_SCENE) {
|
||||||
|
_condition->removeItem(
|
||||||
|
static_cast<int>(StudioModeCondition::PREVIEW_SCENE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ namespace advss {
|
|||||||
enum class StudioModeCondition {
|
enum class StudioModeCondition {
|
||||||
STUDIO_MODE_ACTIVE,
|
STUDIO_MODE_ACTIVE,
|
||||||
STUDIO_MODE_NOT_ACTIVE,
|
STUDIO_MODE_NOT_ACTIVE,
|
||||||
PREVIEW_SCENE,
|
PREVIEW_SCENE, // TODO: Remove in future version as the functionality
|
||||||
|
// moved to the scene condition
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionStudioMode : public MacroCondition {
|
class MacroConditionStudioMode : public MacroCondition {
|
||||||
|
|||||||
368
src/macro-core/macro-condition-tempvar.cpp
Normal file
368
src/macro-core/macro-condition-tempvar.cpp
Normal file
@@ -0,0 +1,368 @@
|
|||||||
|
#include "macro-condition-tempvar.hpp"
|
||||||
|
#include "math-helpers.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
const std::string MacroConditionTempVar::id = "temp_var";
|
||||||
|
|
||||||
|
bool MacroConditionTempVar::_registered = MacroConditionFactory::Register(
|
||||||
|
MacroConditionTempVar::id,
|
||||||
|
{MacroConditionTempVar::Create, MacroConditionTempVarEdit::Create,
|
||||||
|
"AdvSceneSwitcher.condition.temporaryVariable"});
|
||||||
|
|
||||||
|
const static std::map<MacroConditionTempVar::Condition, std::string>
|
||||||
|
conditionTypes = {
|
||||||
|
{MacroConditionTempVar::Condition::EQUALS,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.compare"},
|
||||||
|
{MacroConditionTempVar::Condition::IS_EMPTY,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.empty"},
|
||||||
|
{MacroConditionTempVar::Condition::IS_NUMBER,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.number"},
|
||||||
|
{MacroConditionTempVar::Condition::LESS_THAN,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.lessThan"},
|
||||||
|
{MacroConditionTempVar::Condition::GREATER_THAN,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.greaterThan"},
|
||||||
|
{MacroConditionTempVar::Condition::VALUE_CHANGED,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.valueChanged"},
|
||||||
|
{MacroConditionTempVar::Condition::EQUALS_VARIABLE,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.equalsVariable"},
|
||||||
|
{MacroConditionTempVar::Condition::LESS_THAN_VARIABLE,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.lessThanVariable"},
|
||||||
|
{MacroConditionTempVar::Condition::GREATER_THAN_VARIABLE,
|
||||||
|
"AdvSceneSwitcher.condition.variable.type.greaterThanVariable"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool isNumber(const TempVariable &var)
|
||||||
|
{
|
||||||
|
auto value = var.Value();
|
||||||
|
if (!value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetDouble(*value).has_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool compareNumber(const TempVariable &var, double value, bool less)
|
||||||
|
{
|
||||||
|
auto tempVarValue = var.Value();
|
||||||
|
if (!tempVarValue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto doubleValue = GetDouble(*tempVarValue);
|
||||||
|
if (!doubleValue.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (less) {
|
||||||
|
return doubleValue < value;
|
||||||
|
}
|
||||||
|
return doubleValue > value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionTempVar::Compare(const TempVariable &var) const
|
||||||
|
{
|
||||||
|
auto value = var.Value();
|
||||||
|
if (!value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_regex.Enabled()) {
|
||||||
|
auto expr = _regex.GetRegularExpression(_strValue);
|
||||||
|
if (!expr.isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto match = expr.match(QString::fromStdString(*value));
|
||||||
|
return match.hasMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string(_strValue) == *value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionTempVar::ValueChanged(const TempVariable &var)
|
||||||
|
{
|
||||||
|
auto value = var.Value();
|
||||||
|
if (!value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool changed = *value != _lastValue;
|
||||||
|
if (changed) {
|
||||||
|
_lastValue = *value;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionTempVar::CompareVariables()
|
||||||
|
{
|
||||||
|
auto var1 = _tempVar.GetTempVariable(GetMacro());
|
||||||
|
auto var2 = _variable2.lock();
|
||||||
|
if (!var1 || !var2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tempVarValue = var1->Value();
|
||||||
|
if (!tempVarValue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto val1 = GetDouble(*tempVarValue);
|
||||||
|
auto val2 = var2->DoubleValue();
|
||||||
|
bool validNumbers = val1.has_value() && val2.has_value();
|
||||||
|
|
||||||
|
switch (_type) {
|
||||||
|
case MacroConditionTempVar::Condition::EQUALS_VARIABLE:
|
||||||
|
return *tempVarValue == var2->Value() ||
|
||||||
|
(validNumbers && val1 == val2);
|
||||||
|
case MacroConditionTempVar::Condition::LESS_THAN_VARIABLE:
|
||||||
|
return validNumbers && val1 < val2;
|
||||||
|
case MacroConditionTempVar::Condition::GREATER_THAN_VARIABLE:
|
||||||
|
return validNumbers && val1 > val2;
|
||||||
|
default:
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"Unexpected call of %s with condition type %d", __func__,
|
||||||
|
static_cast<int>(_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionTempVar::CheckCondition()
|
||||||
|
{
|
||||||
|
auto var = _tempVar.GetTempVariable(GetMacro());
|
||||||
|
if (!var) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_type) {
|
||||||
|
case MacroConditionTempVar::Condition::EQUALS:
|
||||||
|
return Compare(*var);
|
||||||
|
case MacroConditionTempVar::Condition::IS_EMPTY:
|
||||||
|
return var->Value().has_value() && var->Value()->empty();
|
||||||
|
case MacroConditionTempVar::Condition::IS_NUMBER:
|
||||||
|
return isNumber(*var);
|
||||||
|
case MacroConditionTempVar::Condition::LESS_THAN:
|
||||||
|
return compareNumber(*var, _numValue, true);
|
||||||
|
case MacroConditionTempVar::Condition::GREATER_THAN:
|
||||||
|
return compareNumber(*var, _numValue, false);
|
||||||
|
case MacroConditionTempVar::Condition::VALUE_CHANGED:
|
||||||
|
return ValueChanged(*var);
|
||||||
|
case MacroConditionTempVar::Condition::EQUALS_VARIABLE:
|
||||||
|
return CompareVariables();
|
||||||
|
case MacroConditionTempVar::Condition::LESS_THAN_VARIABLE:
|
||||||
|
return CompareVariables();
|
||||||
|
case MacroConditionTempVar::Condition::GREATER_THAN_VARIABLE:
|
||||||
|
return CompareVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionTempVar::Save(obs_data_t *obj) const
|
||||||
|
{
|
||||||
|
MacroCondition::Save(obj);
|
||||||
|
_tempVar.Save(obj);
|
||||||
|
obs_data_set_string(obj, "variableName",
|
||||||
|
GetWeakVariableName(_variable2).c_str());
|
||||||
|
_strValue.Save(obj, "strValue");
|
||||||
|
obs_data_set_double(obj, "numValue", _numValue);
|
||||||
|
obs_data_set_int(obj, "condition", static_cast<int>(_type));
|
||||||
|
_regex.Save(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionTempVar::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
MacroCondition::Load(obj);
|
||||||
|
_tempVar.Load(obj, GetMacro());
|
||||||
|
_variable2 =
|
||||||
|
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
|
||||||
|
_strValue.Load(obj, "strValue");
|
||||||
|
_numValue = obs_data_get_double(obj, "numValue");
|
||||||
|
_type = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||||
|
_regex.Load(obj);
|
||||||
|
// TODO: remove in future version
|
||||||
|
if (obs_data_has_user_value(obj, "regex")) {
|
||||||
|
_regex.CreateBackwardsCompatibleRegex(
|
||||||
|
obs_data_get_bool(obj, "regex"));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MacroConditionTempVar::GetShortDesc() const
|
||||||
|
{
|
||||||
|
auto var = _tempVar.GetTempVariable(GetMacro());
|
||||||
|
if (!var) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return var->Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void populateConditionSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
for (auto entry : conditionTypes) {
|
||||||
|
list->addItem(obs_module_text(entry.second.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroConditionTempVarEdit::MacroConditionTempVarEdit(
|
||||||
|
QWidget *parent, std::shared_ptr<MacroConditionTempVar> entryData)
|
||||||
|
: QWidget(parent),
|
||||||
|
_tempVars(new TempVariableSelection(this)),
|
||||||
|
_variables2(new VariableSelection(this)),
|
||||||
|
_conditions(new QComboBox()),
|
||||||
|
_strValue(new VariableTextEdit(this, 5, 1, 1)),
|
||||||
|
_numValue(new QDoubleSpinBox()),
|
||||||
|
_regex(new RegexConfigWidget(parent))
|
||||||
|
{
|
||||||
|
_numValue->setMinimum(-9999999999);
|
||||||
|
_numValue->setMaximum(9999999999);
|
||||||
|
populateConditionSelection(_conditions);
|
||||||
|
|
||||||
|
QWidget::connect(_tempVars,
|
||||||
|
SIGNAL(SelectionChanged(const TempVariableRef &)),
|
||||||
|
this, SLOT(VariableChanged(const TempVariableRef &)));
|
||||||
|
QWidget::connect(_variables2, SIGNAL(SelectionChanged(const QString &)),
|
||||||
|
this, SLOT(Variable2Changed(const QString &)));
|
||||||
|
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(ConditionChanged(int)));
|
||||||
|
QWidget::connect(_strValue, SIGNAL(textChanged()), this,
|
||||||
|
SLOT(StrValueChanged()));
|
||||||
|
QWidget::connect(_numValue, SIGNAL(valueChanged(double)), this,
|
||||||
|
SLOT(NumValueChanged(double)));
|
||||||
|
QWidget::connect(_regex, SIGNAL(RegexConfigChanged(RegexConfig)), this,
|
||||||
|
SLOT(RegexChanged(RegexConfig)));
|
||||||
|
|
||||||
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
|
{"{{variables}}", _tempVars},
|
||||||
|
{"{{variables2}}", _variables2},
|
||||||
|
{"{{conditions}}", _conditions},
|
||||||
|
{"{{strValue}}", _strValue},
|
||||||
|
{"{{numValue}}", _numValue},
|
||||||
|
{"{{regex}}", _regex},
|
||||||
|
};
|
||||||
|
|
||||||
|
auto layout = new QHBoxLayout;
|
||||||
|
PlaceWidgets(
|
||||||
|
obs_module_text("AdvSceneSwitcher.condition.variable.entry"),
|
||||||
|
layout, widgetPlaceholders);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
_entryData = entryData;
|
||||||
|
UpdateEntryData();
|
||||||
|
_loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::UpdateEntryData()
|
||||||
|
{
|
||||||
|
if (!_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tempVars->SetVariable(_entryData->_tempVar);
|
||||||
|
_variables2->SetVariable(_entryData->_variable2);
|
||||||
|
_conditions->setCurrentIndex(static_cast<int>(_entryData->_type));
|
||||||
|
_strValue->setPlainText(_entryData->_strValue);
|
||||||
|
_numValue->setValue(_entryData->_numValue);
|
||||||
|
_regex->SetRegexConfig(_entryData->_regex);
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::VariableChanged(const TempVariableRef &var)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_tempVar = var;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::Variable2Changed(const QString &text)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_variable2 = GetWeakVariableByQString(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::ConditionChanged(int value)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_type =
|
||||||
|
static_cast<MacroConditionTempVar::Condition>(value);
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::StrValueChanged()
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_strValue = _strValue->toPlainText().toStdString();
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::NumValueChanged(double val)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_numValue = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::RegexChanged(RegexConfig conf)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_regex = conf;
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTempVarEdit::SetWidgetVisibility()
|
||||||
|
{
|
||||||
|
if (!_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_regex->setVisible(_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::EQUALS);
|
||||||
|
_strValue->setVisible(_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::EQUALS);
|
||||||
|
_numValue->setVisible(
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::LESS_THAN ||
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::GREATER_THAN);
|
||||||
|
_numValue->setVisible(
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::LESS_THAN ||
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::GREATER_THAN);
|
||||||
|
_variables2->setVisible(
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::EQUALS_VARIABLE ||
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::LESS_THAN_VARIABLE ||
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionTempVar::Condition::GREATER_THAN_VARIABLE);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
100
src/macro-core/macro-condition-tempvar.hpp
Normal file
100
src/macro-core/macro-condition-tempvar.hpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-condition-edit.hpp"
|
||||||
|
#include "resizing-text-edit.hpp"
|
||||||
|
#include "variable.hpp"
|
||||||
|
#include "regex-config.hpp"
|
||||||
|
#include "variable-text-edit.hpp"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
class MacroConditionTempVar : public MacroCondition {
|
||||||
|
public:
|
||||||
|
MacroConditionTempVar(Macro *m) : MacroCondition(m) {}
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj) const;
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc() const;
|
||||||
|
std::string GetId() const { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionTempVar>(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Condition {
|
||||||
|
EQUALS,
|
||||||
|
IS_EMPTY,
|
||||||
|
IS_NUMBER,
|
||||||
|
LESS_THAN,
|
||||||
|
GREATER_THAN,
|
||||||
|
VALUE_CHANGED,
|
||||||
|
EQUALS_VARIABLE,
|
||||||
|
LESS_THAN_VARIABLE,
|
||||||
|
GREATER_THAN_VARIABLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
Condition _type = Condition::EQUALS;
|
||||||
|
TempVariableRef _tempVar;
|
||||||
|
std::weak_ptr<Variable> _variable2;
|
||||||
|
StringVariable _strValue = "";
|
||||||
|
double _numValue = 0;
|
||||||
|
RegexConfig _regex;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Compare(const TempVariable &) const;
|
||||||
|
bool ValueChanged(const TempVariable &);
|
||||||
|
bool CompareVariables();
|
||||||
|
|
||||||
|
std::string _lastValue = "";
|
||||||
|
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionTempVarEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionTempVarEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionTempVar> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionTempVarEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionTempVar>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void VariableChanged(const TempVariableRef &);
|
||||||
|
void Variable2Changed(const QString &);
|
||||||
|
void ConditionChanged(int);
|
||||||
|
void StrValueChanged();
|
||||||
|
void NumValueChanged(double);
|
||||||
|
void RegexChanged(RegexConfig);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TempVariableSelection *_tempVars;
|
||||||
|
VariableSelection *_variables2;
|
||||||
|
QComboBox *_conditions;
|
||||||
|
VariableTextEdit *_strValue;
|
||||||
|
QDoubleSpinBox *_numValue;
|
||||||
|
RegexConfigWidget *_regex;
|
||||||
|
std::shared_ptr<MacroConditionTempVar> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
@@ -10,18 +10,20 @@ bool MacroConditionTimer::_registered = MacroConditionFactory::Register(
|
|||||||
{MacroConditionTimer::Create, MacroConditionTimerEdit::Create,
|
{MacroConditionTimer::Create, MacroConditionTimerEdit::Create,
|
||||||
"AdvSceneSwitcher.condition.timer", false});
|
"AdvSceneSwitcher.condition.timer", false});
|
||||||
|
|
||||||
const static std::map<TimerType, std::string> timerTypes = {
|
const static std::map<MacroConditionTimer::TimerType, std::string> timerTypes = {
|
||||||
{TimerType::FIXED, "AdvSceneSwitcher.condition.timer.type.fixed"},
|
{MacroConditionTimer::TimerType::FIXED,
|
||||||
{TimerType::RANDOM, "AdvSceneSwitcher.condition.timer.type.random"},
|
"AdvSceneSwitcher.condition.timer.type.fixed"},
|
||||||
|
{MacroConditionTimer::TimerType::RANDOM,
|
||||||
|
"AdvSceneSwitcher.condition.timer.type.random"},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MacroConditionTimer::CheckCondition()
|
bool MacroConditionTimer::CheckCondition()
|
||||||
{
|
{
|
||||||
if (_paused) {
|
if (_paused) {
|
||||||
SetVariableValue(std::to_string(_remaining));
|
SetVariables(_remaining);
|
||||||
return _remaining == 0.;
|
return _remaining == 0.;
|
||||||
}
|
}
|
||||||
SetVariableValue(std::to_string(_duration.TimeRemaining()));
|
SetVariables(_duration.TimeRemaining());
|
||||||
if (_duration.DurationReached()) {
|
if (_duration.DurationReached()) {
|
||||||
if (!_oneshot) {
|
if (!_oneshot) {
|
||||||
_duration.Reset();
|
_duration.Reset();
|
||||||
@@ -120,6 +122,29 @@ void MacroConditionTimer::Reset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionTimer::SetVariables(double seconds)
|
||||||
|
{
|
||||||
|
SetVariableValue(std::to_string(seconds));
|
||||||
|
SetTempVarValue("seconds", std::to_string((int)seconds));
|
||||||
|
SetTempVarValue("minutes", std::to_string((int)(seconds / 60)));
|
||||||
|
SetTempVarValue("hours", std::to_string((int)(seconds / (60 * 60))));
|
||||||
|
SetTempVarValue("days",
|
||||||
|
std::to_string((int)(seconds / (60 * 60 * 24))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionTimer::SetupTempVars()
|
||||||
|
{
|
||||||
|
MacroCondition::SetupTempVars();
|
||||||
|
AddTempvar("seconds",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.timer.seconds"));
|
||||||
|
AddTempvar("minutes",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.timer.minutes"));
|
||||||
|
AddTempvar("hours",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.timer.hours"));
|
||||||
|
AddTempvar("days",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.timer.days"));
|
||||||
|
}
|
||||||
|
|
||||||
static inline void populateTimerTypeSelection(QComboBox *list)
|
static inline void populateTimerTypeSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (auto entry : timerTypes) {
|
for (auto entry : timerTypes) {
|
||||||
@@ -203,7 +228,7 @@ void MacroConditionTimerEdit::TimerTypeChanged(int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_type = static_cast<TimerType>(type);
|
_entryData->_type = static_cast<MacroConditionTimer::TimerType>(type);
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +362,7 @@ void MacroConditionTimerEdit::SetWidgetVisibility()
|
|||||||
{"{{duration2}}", _duration2},
|
{"{{duration2}}", _duration2},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_entryData->_type == TimerType::RANDOM) {
|
if (_entryData->_type == MacroConditionTimer::TimerType::RANDOM) {
|
||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.condition.timer.entry.line1.random"),
|
"AdvSceneSwitcher.condition.timer.entry.line1.random"),
|
||||||
|
|||||||
@@ -12,11 +12,6 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
enum class TimerType {
|
|
||||||
FIXED,
|
|
||||||
RANDOM,
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacroConditionTimer : public MacroCondition {
|
class MacroConditionTimer : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
MacroConditionTimer(Macro *m) : MacroCondition(m, true) {}
|
MacroConditionTimer(Macro *m) : MacroCondition(m, true) {}
|
||||||
@@ -32,6 +27,7 @@ public:
|
|||||||
void Continue();
|
void Continue();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
enum class TimerType { FIXED, RANDOM };
|
||||||
TimerType _type = TimerType::FIXED;
|
TimerType _type = TimerType::FIXED;
|
||||||
Duration _duration;
|
Duration _duration;
|
||||||
Duration _duration2;
|
Duration _duration2;
|
||||||
@@ -42,6 +38,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void SetRandomTimeRemaining();
|
void SetRandomTimeRemaining();
|
||||||
|
void SetVariables(double seconds);
|
||||||
|
void SetupTempVars();
|
||||||
|
|
||||||
std::default_random_engine _re;
|
std::default_random_engine _re;
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "macro-condition-variable.hpp"
|
#include "macro-condition-variable.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
const std::string MacroConditionVariable::id = "variable";
|
const std::string MacroConditionVariable::id = "variable";
|
||||||
@@ -12,25 +10,25 @@ bool MacroConditionVariable::_registered = MacroConditionFactory::Register(
|
|||||||
{MacroConditionVariable::Create, MacroConditionVariableEdit::Create,
|
{MacroConditionVariable::Create, MacroConditionVariableEdit::Create,
|
||||||
"AdvSceneSwitcher.condition.variable"});
|
"AdvSceneSwitcher.condition.variable"});
|
||||||
|
|
||||||
const static std::map<MacroConditionVariable::Type, std::string>
|
const static std::map<MacroConditionVariable::Condition, std::string>
|
||||||
conditionTypes = {
|
conditionTypes = {
|
||||||
{MacroConditionVariable::Type::EQUALS,
|
{MacroConditionVariable::Condition::EQUALS,
|
||||||
"AdvSceneSwitcher.condition.variable.type.compare"},
|
"AdvSceneSwitcher.condition.variable.type.compare"},
|
||||||
{MacroConditionVariable::Type::IS_EMPTY,
|
{MacroConditionVariable::Condition::IS_EMPTY,
|
||||||
"AdvSceneSwitcher.condition.variable.type.empty"},
|
"AdvSceneSwitcher.condition.variable.type.empty"},
|
||||||
{MacroConditionVariable::Type::IS_NUMBER,
|
{MacroConditionVariable::Condition::IS_NUMBER,
|
||||||
"AdvSceneSwitcher.condition.variable.type.number"},
|
"AdvSceneSwitcher.condition.variable.type.number"},
|
||||||
{MacroConditionVariable::Type::LESS_THAN,
|
{MacroConditionVariable::Condition::LESS_THAN,
|
||||||
"AdvSceneSwitcher.condition.variable.type.lessThan"},
|
"AdvSceneSwitcher.condition.variable.type.lessThan"},
|
||||||
{MacroConditionVariable::Type::GREATER_THAN,
|
{MacroConditionVariable::Condition::GREATER_THAN,
|
||||||
"AdvSceneSwitcher.condition.variable.type.greaterThan"},
|
"AdvSceneSwitcher.condition.variable.type.greaterThan"},
|
||||||
{MacroConditionVariable::Type::VALUE_CHANGED,
|
{MacroConditionVariable::Condition::VALUE_CHANGED,
|
||||||
"AdvSceneSwitcher.condition.variable.type.valueChanged"},
|
"AdvSceneSwitcher.condition.variable.type.valueChanged"},
|
||||||
{MacroConditionVariable::Type::EQUALS_VARIABLE,
|
{MacroConditionVariable::Condition::EQUALS_VARIABLE,
|
||||||
"AdvSceneSwitcher.condition.variable.type.equalsVariable"},
|
"AdvSceneSwitcher.condition.variable.type.equalsVariable"},
|
||||||
{MacroConditionVariable::Type::LESS_THAN_VARIABLE,
|
{MacroConditionVariable::Condition::LESS_THAN_VARIABLE,
|
||||||
"AdvSceneSwitcher.condition.variable.type.lessThanVariable"},
|
"AdvSceneSwitcher.condition.variable.type.lessThanVariable"},
|
||||||
{MacroConditionVariable::Type::GREATER_THAN_VARIABLE,
|
{MacroConditionVariable::Condition::GREATER_THAN_VARIABLE,
|
||||||
"AdvSceneSwitcher.condition.variable.type.greaterThanVariable"},
|
"AdvSceneSwitcher.condition.variable.type.greaterThanVariable"},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,7 +60,7 @@ bool MacroConditionVariable::Compare(const Variable &var) const
|
|||||||
return match.hasMatch();
|
return match.hasMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _strValue == var.Value();
|
return std::string(_strValue) == var.Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionVariable::ValueChanged(const Variable &var)
|
bool MacroConditionVariable::ValueChanged(const Variable &var)
|
||||||
@@ -87,12 +85,12 @@ bool MacroConditionVariable::CompareVariables()
|
|||||||
bool validNumbers = val1.has_value() && val2.has_value();
|
bool validNumbers = val1.has_value() && val2.has_value();
|
||||||
|
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case MacroConditionVariable::Type::EQUALS_VARIABLE:
|
case MacroConditionVariable::Condition::EQUALS_VARIABLE:
|
||||||
return var1->Value() == var2->Value() ||
|
return var1->Value() == var2->Value() ||
|
||||||
(validNumbers && val1 == val2);
|
(validNumbers && val1 == val2);
|
||||||
case MacroConditionVariable::Type::LESS_THAN_VARIABLE:
|
case MacroConditionVariable::Condition::LESS_THAN_VARIABLE:
|
||||||
return validNumbers && val1 < val2;
|
return validNumbers && val1 < val2;
|
||||||
case MacroConditionVariable::Type::GREATER_THAN_VARIABLE:
|
case MacroConditionVariable::Condition::GREATER_THAN_VARIABLE:
|
||||||
return validNumbers && val1 > val2;
|
return validNumbers && val1 > val2;
|
||||||
default:
|
default:
|
||||||
blog(LOG_WARNING,
|
blog(LOG_WARNING,
|
||||||
@@ -111,23 +109,23 @@ bool MacroConditionVariable::CheckCondition()
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case MacroConditionVariable::Type::EQUALS:
|
case MacroConditionVariable::Condition::EQUALS:
|
||||||
return Compare(*var);
|
return Compare(*var);
|
||||||
case MacroConditionVariable::Type::IS_EMPTY:
|
case MacroConditionVariable::Condition::IS_EMPTY:
|
||||||
return var->Value().empty();
|
return var->Value().empty();
|
||||||
case MacroConditionVariable::Type::IS_NUMBER:
|
case MacroConditionVariable::Condition::IS_NUMBER:
|
||||||
return isNumber(*var);
|
return isNumber(*var);
|
||||||
case MacroConditionVariable::Type::LESS_THAN:
|
case MacroConditionVariable::Condition::LESS_THAN:
|
||||||
return compareNumber(*var, _numValue, true);
|
return compareNumber(*var, _numValue, true);
|
||||||
case MacroConditionVariable::Type::GREATER_THAN:
|
case MacroConditionVariable::Condition::GREATER_THAN:
|
||||||
return compareNumber(*var, _numValue, false);
|
return compareNumber(*var, _numValue, false);
|
||||||
case MacroConditionVariable::Type::VALUE_CHANGED:
|
case MacroConditionVariable::Condition::VALUE_CHANGED:
|
||||||
return ValueChanged(*var);
|
return ValueChanged(*var);
|
||||||
case MacroConditionVariable::Type::EQUALS_VARIABLE:
|
case MacroConditionVariable::Condition::EQUALS_VARIABLE:
|
||||||
return CompareVariables();
|
return CompareVariables();
|
||||||
case MacroConditionVariable::Type::LESS_THAN_VARIABLE:
|
case MacroConditionVariable::Condition::LESS_THAN_VARIABLE:
|
||||||
return CompareVariables();
|
return CompareVariables();
|
||||||
case MacroConditionVariable::Type::GREATER_THAN_VARIABLE:
|
case MacroConditionVariable::Condition::GREATER_THAN_VARIABLE:
|
||||||
return CompareVariables();
|
return CompareVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +139,7 @@ bool MacroConditionVariable::Save(obs_data_t *obj) const
|
|||||||
GetWeakVariableName(_variable).c_str());
|
GetWeakVariableName(_variable).c_str());
|
||||||
obs_data_set_string(obj, "variable2Name",
|
obs_data_set_string(obj, "variable2Name",
|
||||||
GetWeakVariableName(_variable2).c_str());
|
GetWeakVariableName(_variable2).c_str());
|
||||||
obs_data_set_string(obj, "strValue", _strValue.c_str());
|
_strValue.Save(obj, "strValue");
|
||||||
obs_data_set_double(obj, "numValue", _numValue);
|
obs_data_set_double(obj, "numValue", _numValue);
|
||||||
obs_data_set_int(obj, "condition", static_cast<int>(_type));
|
obs_data_set_int(obj, "condition", static_cast<int>(_type));
|
||||||
_regex.Save(obj);
|
_regex.Save(obj);
|
||||||
@@ -155,9 +153,9 @@ bool MacroConditionVariable::Load(obs_data_t *obj)
|
|||||||
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
|
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
|
||||||
_variable2 = GetWeakVariableByName(
|
_variable2 = GetWeakVariableByName(
|
||||||
obs_data_get_string(obj, "variable2Name"));
|
obs_data_get_string(obj, "variable2Name"));
|
||||||
_strValue = obs_data_get_string(obj, "strValue");
|
_strValue.Load(obj, "strValue");
|
||||||
_numValue = obs_data_get_double(obj, "numValue");
|
_numValue = obs_data_get_double(obj, "numValue");
|
||||||
_type = static_cast<Type>(obs_data_get_int(obj, "condition"));
|
_type = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||||
_regex.Load(obj);
|
_regex.Load(obj);
|
||||||
// TODO: remove in future version
|
// TODO: remove in future version
|
||||||
if (obs_data_has_user_value(obj, "regex")) {
|
if (obs_data_has_user_value(obj, "regex")) {
|
||||||
@@ -185,7 +183,7 @@ MacroConditionVariableEdit::MacroConditionVariableEdit(
|
|||||||
_variables(new VariableSelection(this)),
|
_variables(new VariableSelection(this)),
|
||||||
_variables2(new VariableSelection(this)),
|
_variables2(new VariableSelection(this)),
|
||||||
_conditions(new QComboBox()),
|
_conditions(new QComboBox()),
|
||||||
_strValue(new ResizingPlainTextEdit(this, 5, 1, 1)),
|
_strValue(new VariableTextEdit(this, 5, 1, 1)),
|
||||||
_numValue(new QDoubleSpinBox()),
|
_numValue(new QDoubleSpinBox()),
|
||||||
_regex(new RegexConfigWidget(parent))
|
_regex(new RegexConfigWidget(parent))
|
||||||
{
|
{
|
||||||
@@ -215,19 +213,11 @@ MacroConditionVariableEdit::MacroConditionVariableEdit(
|
|||||||
{"{{regex}}", _regex},
|
{"{{regex}}", _regex},
|
||||||
};
|
};
|
||||||
|
|
||||||
QHBoxLayout *layout = new QHBoxLayout;
|
auto layout = new QHBoxLayout;
|
||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text("AdvSceneSwitcher.condition.variable.entry"),
|
obs_module_text("AdvSceneSwitcher.condition.variable.entry"),
|
||||||
layout, widgetPlaceholders);
|
layout, widgetPlaceholders);
|
||||||
|
setLayout(layout);
|
||||||
auto *regexLayout = new QHBoxLayout;
|
|
||||||
regexLayout->addWidget(_regex);
|
|
||||||
regexLayout->addStretch();
|
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
|
||||||
mainLayout->addLayout(layout);
|
|
||||||
mainLayout->addLayout(regexLayout);
|
|
||||||
setLayout(mainLayout);
|
|
||||||
|
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
UpdateEntryData();
|
UpdateEntryData();
|
||||||
@@ -243,7 +233,7 @@ void MacroConditionVariableEdit::UpdateEntryData()
|
|||||||
_variables->SetVariable(_entryData->_variable);
|
_variables->SetVariable(_entryData->_variable);
|
||||||
_variables2->SetVariable(_entryData->_variable2);
|
_variables2->SetVariable(_entryData->_variable2);
|
||||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_type));
|
_conditions->setCurrentIndex(static_cast<int>(_entryData->_type));
|
||||||
_strValue->setPlainText(QString::fromStdString(_entryData->_strValue));
|
_strValue->setPlainText(_entryData->_strValue);
|
||||||
_numValue->setValue(_entryData->_numValue);
|
_numValue->setValue(_entryData->_numValue);
|
||||||
_regex->SetRegexConfig(_entryData->_regex);
|
_regex->SetRegexConfig(_entryData->_regex);
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
@@ -277,7 +267,8 @@ void MacroConditionVariableEdit::ConditionChanged(int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_type = static_cast<MacroConditionVariable::Type>(value);
|
_entryData->_type =
|
||||||
|
static_cast<MacroConditionVariable::Condition>(value);
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +281,7 @@ void MacroConditionVariableEdit::StrValueChanged()
|
|||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_strValue = _strValue->toPlainText().toStdString();
|
_entryData->_strValue = _strValue->toPlainText().toStdString();
|
||||||
adjustSize();
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionVariableEdit::NumValueChanged(double val)
|
void MacroConditionVariableEdit::NumValueChanged(double val)
|
||||||
@@ -321,24 +313,26 @@ void MacroConditionVariableEdit::SetWidgetVisibility()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_regex->setVisible(_entryData->_type ==
|
_regex->setVisible(_entryData->_type ==
|
||||||
MacroConditionVariable::Type::EQUALS);
|
MacroConditionVariable::Condition::EQUALS);
|
||||||
_strValue->setVisible(_entryData->_type ==
|
_strValue->setVisible(_entryData->_type ==
|
||||||
MacroConditionVariable::Type::EQUALS);
|
MacroConditionVariable::Condition::EQUALS);
|
||||||
_numValue->setVisible(
|
_numValue->setVisible(
|
||||||
_entryData->_type == MacroConditionVariable::Type::LESS_THAN ||
|
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroConditionVariable::Type::GREATER_THAN);
|
MacroConditionVariable::Condition::LESS_THAN ||
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionVariable::Condition::GREATER_THAN);
|
||||||
_numValue->setVisible(
|
_numValue->setVisible(
|
||||||
_entryData->_type == MacroConditionVariable::Type::LESS_THAN ||
|
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroConditionVariable::Type::GREATER_THAN);
|
MacroConditionVariable::Condition::LESS_THAN ||
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroConditionVariable::Condition::GREATER_THAN);
|
||||||
_variables2->setVisible(
|
_variables2->setVisible(
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroConditionVariable::Type::EQUALS_VARIABLE ||
|
MacroConditionVariable::Condition::EQUALS_VARIABLE ||
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroConditionVariable::Type::LESS_THAN_VARIABLE ||
|
MacroConditionVariable::Condition::LESS_THAN_VARIABLE ||
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroConditionVariable::Type::GREATER_THAN_VARIABLE);
|
MacroConditionVariable::Condition::GREATER_THAN_VARIABLE);
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "resizing-text-edit.hpp"
|
#include "resizing-text-edit.hpp"
|
||||||
#include "variable.hpp"
|
#include "variable.hpp"
|
||||||
#include "regex-config.hpp"
|
#include "regex-config.hpp"
|
||||||
|
#include "variable-text-edit.hpp"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
@@ -24,7 +25,7 @@ public:
|
|||||||
return std::make_shared<MacroConditionVariable>(m);
|
return std::make_shared<MacroConditionVariable>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Type {
|
enum class Condition {
|
||||||
EQUALS,
|
EQUALS,
|
||||||
IS_EMPTY,
|
IS_EMPTY,
|
||||||
IS_NUMBER,
|
IS_NUMBER,
|
||||||
@@ -36,10 +37,10 @@ public:
|
|||||||
GREATER_THAN_VARIABLE,
|
GREATER_THAN_VARIABLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
Type _type = Type::EQUALS;
|
Condition _type = Condition::EQUALS;
|
||||||
std::weak_ptr<Variable> _variable;
|
std::weak_ptr<Variable> _variable;
|
||||||
std::weak_ptr<Variable> _variable2;
|
std::weak_ptr<Variable> _variable2;
|
||||||
std::string _strValue = "";
|
StringVariable _strValue = "";
|
||||||
double _numValue = 0;
|
double _numValue = 0;
|
||||||
RegexConfig _regex;
|
RegexConfig _regex;
|
||||||
|
|
||||||
@@ -86,7 +87,7 @@ protected:
|
|||||||
VariableSelection *_variables;
|
VariableSelection *_variables;
|
||||||
VariableSelection *_variables2;
|
VariableSelection *_variables2;
|
||||||
QComboBox *_conditions;
|
QComboBox *_conditions;
|
||||||
ResizingPlainTextEdit *_strValue;
|
VariableTextEdit *_strValue;
|
||||||
QDoubleSpinBox *_numValue;
|
QDoubleSpinBox *_numValue;
|
||||||
RegexConfigWidget *_regex;
|
RegexConfigWidget *_regex;
|
||||||
std::shared_ptr<MacroConditionVariable> _entryData;
|
std::shared_ptr<MacroConditionVariable> _entryData;
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ static bool windowContainsText(const std::string &window,
|
|||||||
return text == matchText;
|
return text == matchText;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionWindow::WindowMatches(const std::string &window)
|
bool MacroConditionWindow::WindowMatchesRequirements(
|
||||||
|
const std::string &window) const
|
||||||
{
|
{
|
||||||
const bool focusCheckOK = (!_focus || window == switcher->currentTitle);
|
const bool focusCheckOK = (!_focus || window == switcher->currentTitle);
|
||||||
if (!focusCheckOK) {
|
if (!focusCheckOK) {
|
||||||
@@ -60,26 +61,53 @@ bool MacroConditionWindow::WindowMatches(const std::string &window)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_checkText) {
|
|
||||||
auto text = GetTextInWindow(window);
|
|
||||||
SetVariableValue(text.value_or(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MacroConditionWindow::WindowMatches(
|
||||||
|
const std::vector<std::string> &windowList)
|
||||||
|
{
|
||||||
|
bool match = !_checkTitle ||
|
||||||
|
std::find(windowList.begin(), windowList.end(),
|
||||||
|
std::string(_window)) != windowList.end();
|
||||||
|
match = match && WindowMatchesRequirements(_window);
|
||||||
|
SetVariableValueBasedOnMatch(_window);
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
bool MacroConditionWindow::WindowRegexMatches(
|
bool MacroConditionWindow::WindowRegexMatches(
|
||||||
const std::vector<std::string> &windowList)
|
const std::vector<std::string> &windowList)
|
||||||
{
|
{
|
||||||
|
// No need to test if checking for window title is required as if the
|
||||||
|
// user has disabled window title matching the option will always be
|
||||||
|
// enabled in the backend and use the regular expression ".*".
|
||||||
|
|
||||||
for (const auto &window : windowList) {
|
for (const auto &window : windowList) {
|
||||||
if (matchRegex(_windowRegex, window, _window) &&
|
if (matchRegex(_windowRegex, window, _window) &&
|
||||||
WindowMatches(window)) {
|
WindowMatchesRequirements(window)) {
|
||||||
|
SetVariableValueBasedOnMatch(window);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SetVariableValueBasedOnMatch("");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionWindow::SetVariableValueBasedOnMatch(
|
||||||
|
const std::string &matchWindow)
|
||||||
|
{
|
||||||
|
SetTempVarValue("window", matchWindow);
|
||||||
|
if (!IsReferencedInVars()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_checkText) {
|
||||||
|
auto text = GetTextInWindow(matchWindow);
|
||||||
|
SetVariableValue(text.value_or(""));
|
||||||
|
} else {
|
||||||
|
SetVariableValue(switcher->currentTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool foregroundWindowChanged()
|
static bool foregroundWindowChanged()
|
||||||
{
|
{
|
||||||
return switcher->currentTitle != switcher->lastTitle;
|
return switcher->currentTitle != switcher->lastTitle;
|
||||||
@@ -87,19 +115,13 @@ static bool foregroundWindowChanged()
|
|||||||
|
|
||||||
bool MacroConditionWindow::CheckCondition()
|
bool MacroConditionWindow::CheckCondition()
|
||||||
{
|
{
|
||||||
SetVariableValue("");
|
|
||||||
if (!_checkText) {
|
|
||||||
SetVariableValue(switcher->currentTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> windowList;
|
std::vector<std::string> windowList;
|
||||||
GetWindowList(windowList);
|
GetWindowList(windowList);
|
||||||
|
|
||||||
bool match = false;
|
bool match = false;
|
||||||
if (_windowRegex.Enabled()) {
|
if (_windowRegex.Enabled()) {
|
||||||
match = WindowRegexMatches(windowList);
|
match = WindowRegexMatches(windowList);
|
||||||
} else {
|
} else {
|
||||||
match = WindowMatches(_window);
|
match = WindowMatches(windowList);
|
||||||
}
|
}
|
||||||
match = match && (!_windowFocusChanged || foregroundWindowChanged());
|
match = match && (!_windowFocusChanged || foregroundWindowChanged());
|
||||||
return match;
|
return match;
|
||||||
@@ -152,6 +174,15 @@ std::string MacroConditionWindow::GetShortDesc() const
|
|||||||
return _window;
|
return _window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroConditionWindow::SetupTempVars()
|
||||||
|
{
|
||||||
|
AddTempvar(
|
||||||
|
"window",
|
||||||
|
obs_module_text("AdvSceneSwitcher.tempVar.window.window"),
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.window.window.description"));
|
||||||
|
}
|
||||||
|
|
||||||
MacroConditionWindowEdit::MacroConditionWindowEdit(
|
MacroConditionWindowEdit::MacroConditionWindowEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroConditionWindow> entryData)
|
QWidget *parent, std::shared_ptr<MacroConditionWindow> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
|
|||||||
@@ -21,11 +21,6 @@ public:
|
|||||||
return std::make_shared<MacroConditionWindow>(m);
|
return std::make_shared<MacroConditionWindow>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
bool WindowMatches(const std::string &window);
|
|
||||||
bool WindowRegexMatches(const std::vector<std::string> &windowList);
|
|
||||||
|
|
||||||
public:
|
|
||||||
StringVariable _window;
|
StringVariable _window;
|
||||||
RegexConfig _windowRegex;
|
RegexConfig _windowRegex;
|
||||||
bool _checkTitle = true;
|
bool _checkTitle = true;
|
||||||
@@ -40,6 +35,12 @@ public:
|
|||||||
RegexConfig _textRegex = RegexConfig::PartialMatchRegexConfig();
|
RegexConfig _textRegex = RegexConfig::PartialMatchRegexConfig();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool WindowMatchesRequirements(const std::string &window) const;
|
||||||
|
bool WindowMatches(const std::vector<std::string> &windowList);
|
||||||
|
bool WindowRegexMatches(const std::vector<std::string> &windowList);
|
||||||
|
void SetVariableValueBasedOnMatch(const std::string &matchWindow);
|
||||||
|
void SetupTempVars();
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ void DurationModifier::Save(obs_data_t *obj, const char *condName,
|
|||||||
void DurationModifier::Load(obs_data_t *obj, const char *condName,
|
void DurationModifier::Load(obs_data_t *obj, const char *condName,
|
||||||
const char *duration)
|
const char *duration)
|
||||||
{
|
{
|
||||||
// For backwards compatability check if duration value exist without
|
// For backwards compatibility check if duration value exist without
|
||||||
// time constraint condition - if so assume DurationCondition::MORE
|
// time constraint condition - if so assume DurationCondition::MORE
|
||||||
if (!obs_data_has_user_value(obj, condName) &&
|
if (!obs_data_has_user_value(obj, condName) &&
|
||||||
obs_data_has_user_value(obj, duration)) {
|
obs_data_has_user_value(obj, duration)) {
|
||||||
@@ -105,7 +105,7 @@ bool MacroCondition::Load(obs_data_t *obj)
|
|||||||
_duration.Load(durObj);
|
_duration.Load(durObj);
|
||||||
obs_data_release(durObj);
|
obs_data_release(durObj);
|
||||||
} else {
|
} else {
|
||||||
// For backwards compatability
|
// For backwards compatibility
|
||||||
_duration.Load(obj);
|
_duration.Load(obj);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
MacroDock::MacroDock(Macro *m, QWidget *parent,
|
MacroDock::MacroDock(std::weak_ptr<Macro> m, QWidget *parent,
|
||||||
const StringVariable &runButtonText,
|
const StringVariable &runButtonText,
|
||||||
const StringVariable &pauseButtonText,
|
const StringVariable &pauseButtonText,
|
||||||
const StringVariable &unpauseButtonText,
|
const StringVariable &unpauseButtonText,
|
||||||
@@ -25,11 +25,12 @@ MacroDock::MacroDock(Macro *m, QWidget *parent,
|
|||||||
_statusText(new QLabel(conditionsFalseText.c_str())),
|
_statusText(new QLabel(conditionsFalseText.c_str())),
|
||||||
_macro(m)
|
_macro(m)
|
||||||
{
|
{
|
||||||
if (_macro) {
|
auto macro = _macro.lock();
|
||||||
setWindowTitle(QString::fromStdString(_macro->Name()));
|
if (macro) {
|
||||||
_run->setVisible(_macro->DockHasRunButton());
|
setWindowTitle(QString::fromStdString(macro->Name()));
|
||||||
_pauseToggle->setVisible(_macro->DockHasPauseButton());
|
_run->setVisible(macro->DockHasRunButton());
|
||||||
_statusText->setVisible(_macro->DockHasStatusLabel());
|
_pauseToggle->setVisible(macro->DockHasPauseButton());
|
||||||
|
_statusText->setVisible(macro->DockHasStatusLabel());
|
||||||
} else {
|
} else {
|
||||||
setWindowTitle("<deleted macro>");
|
setWindowTitle("<deleted macro>");
|
||||||
}
|
}
|
||||||
@@ -120,49 +121,52 @@ void MacroDock::EnableHighlight(bool value)
|
|||||||
|
|
||||||
void MacroDock::RunClicked()
|
void MacroDock::RunClicked()
|
||||||
{
|
{
|
||||||
if (!_macro) {
|
auto macro = _macro.lock();
|
||||||
|
if (!macro) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret = _macro->PerformActions();
|
auto ret = macro->PerformActions(true);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
QString err =
|
QString err =
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
||||||
DisplayMessage(err.arg(QString::fromStdString(_macro->Name())));
|
DisplayMessage(err.arg(QString::fromStdString(macro->Name())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroDock::PauseToggleClicked()
|
void MacroDock::PauseToggleClicked()
|
||||||
{
|
{
|
||||||
if (!_macro) {
|
auto macro = _macro.lock();
|
||||||
|
if (!macro) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_macro->SetPaused(!_macro->Paused());
|
macro->SetPaused(!macro->Paused());
|
||||||
UpdateText();
|
UpdateText();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroDock::UpdateText()
|
void MacroDock::UpdateText()
|
||||||
{
|
{
|
||||||
_run->setText(_runButtonText.c_str());
|
_run->setText(_runButtonText.c_str());
|
||||||
|
auto macro = _macro.lock();
|
||||||
if (!_macro) {
|
if (!macro) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pauseToggle->setText(_macro->Paused() ? _unpauseButtonText.c_str()
|
_pauseToggle->setText(macro->Paused() ? _unpauseButtonText.c_str()
|
||||||
: _pauseButtonText.c_str());
|
: _pauseButtonText.c_str());
|
||||||
_statusText->setText(_macro->Matched() ? _conditionsTrueText.c_str()
|
_statusText->setText(macro->Matched() ? _conditionsTrueText.c_str()
|
||||||
: _conditionsFalseText.c_str());
|
: _conditionsFalseText.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroDock::Highlight()
|
void MacroDock::Highlight()
|
||||||
{
|
{
|
||||||
if (!_highlight || !_macro) {
|
auto macro = _macro.lock();
|
||||||
|
if (!_highlight || !macro) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
if (_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
||||||
_macro->ExecutedSince(_lastHighlightCheckTime)) {
|
macro->ExecutedSince(_lastHighlightCheckTime)) {
|
||||||
PulseWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
PulseWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
||||||
}
|
}
|
||||||
_lastHighlightCheckTime = std::chrono::high_resolution_clock::now();
|
_lastHighlightCheckTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ class MacroDock : public OBSDock {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MacroDock(Macro *, QWidget *parent, const StringVariable &runButtonText,
|
MacroDock(std::weak_ptr<Macro>, QWidget *parent,
|
||||||
|
const StringVariable &runButtonText,
|
||||||
const StringVariable &pauseButtonText,
|
const StringVariable &pauseButtonText,
|
||||||
const StringVariable &unpauseButtonText,
|
const StringVariable &unpauseButtonText,
|
||||||
const StringVariable &conditionsTrueText,
|
const StringVariable &conditionsTrueText,
|
||||||
@@ -53,7 +54,7 @@ private:
|
|||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
std::chrono::high_resolution_clock::time_point _lastHighlightCheckTime{};
|
std::chrono::high_resolution_clock::time_point _lastHighlightCheckTime{};
|
||||||
|
|
||||||
Macro *_macro;
|
std::weak_ptr<Macro> _macro;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
@@ -44,6 +46,8 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
|||||||
"AdvSceneSwitcher.macroTab.newMacroRegisterHotkey"))),
|
"AdvSceneSwitcher.macroTab.newMacroRegisterHotkey"))),
|
||||||
_currentMacroRegisterHotkeys(new QCheckBox(obs_module_text(
|
_currentMacroRegisterHotkeys(new QCheckBox(obs_module_text(
|
||||||
"AdvSceneSwitcher.macroTab.currentDisableHotkeys"))),
|
"AdvSceneSwitcher.macroTab.currentDisableHotkeys"))),
|
||||||
|
_currentSkipOnStartup(new QCheckBox(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.macroTab.currentSkipExecutionOnStartup"))),
|
||||||
_currentMacroRegisterDock(new QCheckBox(obs_module_text(
|
_currentMacroRegisterDock(new QCheckBox(obs_module_text(
|
||||||
"AdvSceneSwitcher.macroTab.currentRegisterDock"))),
|
"AdvSceneSwitcher.macroTab.currentRegisterDock"))),
|
||||||
_currentMacroDockAddRunButton(new QCheckBox(obs_module_text(
|
_currentMacroDockAddRunButton(new QCheckBox(obs_module_text(
|
||||||
@@ -82,6 +86,12 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
|||||||
hotkeyLayout->addWidget(_currentMacroRegisterHotkeys);
|
hotkeyLayout->addWidget(_currentMacroRegisterHotkeys);
|
||||||
hotkeyOptions->setLayout(hotkeyLayout);
|
hotkeyOptions->setLayout(hotkeyLayout);
|
||||||
|
|
||||||
|
auto generalOptions = new QGroupBox(
|
||||||
|
obs_module_text("AdvSceneSwitcher.macroTab.generalSettings"));
|
||||||
|
auto generalLayout = new QVBoxLayout;
|
||||||
|
generalLayout->addWidget(_currentSkipOnStartup);
|
||||||
|
generalOptions->setLayout(generalLayout);
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
_dockLayout->addWidget(_currentMacroRegisterDock, row, 1, 1, 2);
|
_dockLayout->addWidget(_currentMacroRegisterDock, row, 1, 1, 2);
|
||||||
row++;
|
row++;
|
||||||
@@ -146,12 +156,23 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
|||||||
connect(_currentMacroDockAddStatusLabel, &QCheckBox::stateChanged, this,
|
connect(_currentMacroDockAddStatusLabel, &QCheckBox::stateChanged, this,
|
||||||
&MacroPropertiesDialog::StatusLabelEnableChanged);
|
&MacroPropertiesDialog::StatusLabelEnableChanged);
|
||||||
|
|
||||||
auto layout = new QVBoxLayout;
|
auto scrollArea = new QScrollArea(this);
|
||||||
|
scrollArea->setWidgetResizable(true);
|
||||||
|
scrollArea->setFrameShape(QFrame::NoFrame);
|
||||||
|
|
||||||
|
auto contentWidget = new QWidget(scrollArea);
|
||||||
|
auto layout = new QVBoxLayout(contentWidget);
|
||||||
layout->addWidget(highlightOptions);
|
layout->addWidget(highlightOptions);
|
||||||
layout->addWidget(hotkeyOptions);
|
layout->addWidget(hotkeyOptions);
|
||||||
|
layout->addWidget(generalOptions);
|
||||||
layout->addWidget(_dockOptions);
|
layout->addWidget(_dockOptions);
|
||||||
layout->addWidget(buttonbox);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
setLayout(layout);
|
scrollArea->setWidget(contentWidget);
|
||||||
|
|
||||||
|
auto dialogLayout = new QVBoxLayout();
|
||||||
|
dialogLayout->addWidget(scrollArea);
|
||||||
|
dialogLayout->addWidget(buttonbox);
|
||||||
|
setLayout(dialogLayout);
|
||||||
|
|
||||||
_executed->setChecked(prop._highlightExecuted);
|
_executed->setChecked(prop._highlightExecuted);
|
||||||
_conditions->setChecked(prop._highlightConditions);
|
_conditions->setChecked(prop._highlightConditions);
|
||||||
@@ -159,10 +180,12 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
|||||||
_newMacroRegisterHotkeys->setChecked(prop._newMacroRegisterHotkeys);
|
_newMacroRegisterHotkeys->setChecked(prop._newMacroRegisterHotkeys);
|
||||||
if (!macro || macro->IsGroup()) {
|
if (!macro || macro->IsGroup()) {
|
||||||
hotkeyOptions->hide();
|
hotkeyOptions->hide();
|
||||||
|
generalOptions->hide();
|
||||||
_dockOptions->hide();
|
_dockOptions->hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_currentMacroRegisterHotkeys->setChecked(macro->PauseHotkeysEnabled());
|
_currentMacroRegisterHotkeys->setChecked(macro->PauseHotkeysEnabled());
|
||||||
|
_currentSkipOnStartup->setChecked(macro->SkipExecOnStart());
|
||||||
const bool dockEnabled = macro->DockEnabled();
|
const bool dockEnabled = macro->DockEnabled();
|
||||||
_currentMacroRegisterDock->setChecked(dockEnabled);
|
_currentMacroRegisterDock->setChecked(dockEnabled);
|
||||||
_currentMacroDockAddRunButton->setChecked(macro->DockHasRunButton());
|
_currentMacroDockAddRunButton->setChecked(macro->DockHasRunButton());
|
||||||
@@ -194,6 +217,20 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
|
|||||||
dockEnabled && macro->DockHasStatusLabel());
|
dockEnabled && macro->DockHasStatusLabel());
|
||||||
MinimizeSizeOfColumn(_dockLayout, 0);
|
MinimizeSizeOfColumn(_dockLayout, 0);
|
||||||
Resize();
|
Resize();
|
||||||
|
|
||||||
|
// Try to set sensible initial size for the dialog window
|
||||||
|
QSize contentSize = contentWidget->sizeHint();
|
||||||
|
resize(contentSize.width() + layout->contentsMargins().left() +
|
||||||
|
layout->contentsMargins().right() +
|
||||||
|
dialogLayout->contentsMargins().left() +
|
||||||
|
dialogLayout->contentsMargins().right() +
|
||||||
|
scrollArea->verticalScrollBar()->sizeHint().width() + 20,
|
||||||
|
contentSize.height() + dialogLayout->spacing() +
|
||||||
|
buttonbox->sizeHint().height() +
|
||||||
|
dialogLayout->contentsMargins().top() +
|
||||||
|
dialogLayout->contentsMargins().bottom() +
|
||||||
|
scrollArea->horizontalScrollBar()->sizeHint().height() +
|
||||||
|
20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroPropertiesDialog::DockEnableChanged(int enabled)
|
void MacroPropertiesDialog::DockEnableChanged(int enabled)
|
||||||
@@ -244,8 +281,6 @@ void MacroPropertiesDialog::Resize()
|
|||||||
{
|
{
|
||||||
_dockOptions->adjustSize();
|
_dockOptions->adjustSize();
|
||||||
_dockOptions->updateGeometry();
|
_dockOptions->updateGeometry();
|
||||||
adjustSize();
|
|
||||||
updateGeometry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroPropertiesDialog::AskForSettings(QWidget *parent,
|
bool MacroPropertiesDialog::AskForSettings(QWidget *parent,
|
||||||
@@ -268,6 +303,7 @@ bool MacroPropertiesDialog::AskForSettings(QWidget *parent,
|
|||||||
|
|
||||||
macro->EnablePauseHotkeys(
|
macro->EnablePauseHotkeys(
|
||||||
dialog._currentMacroRegisterHotkeys->isChecked());
|
dialog._currentMacroRegisterHotkeys->isChecked());
|
||||||
|
macro->SetSkipExecOnStart(dialog._currentSkipOnStartup->isChecked());
|
||||||
macro->EnableDock(dialog._currentMacroRegisterDock->isChecked());
|
macro->EnableDock(dialog._currentMacroRegisterDock->isChecked());
|
||||||
macro->SetDockHasRunButton(
|
macro->SetDockHasRunButton(
|
||||||
dialog._currentMacroDockAddRunButton->isChecked());
|
dialog._currentMacroDockAddRunButton->isChecked());
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ private:
|
|||||||
QCheckBox *_newMacroRegisterHotkeys;
|
QCheckBox *_newMacroRegisterHotkeys;
|
||||||
// Current macro specific settings
|
// Current macro specific settings
|
||||||
QCheckBox *_currentMacroRegisterHotkeys;
|
QCheckBox *_currentMacroRegisterHotkeys;
|
||||||
|
QCheckBox *_currentSkipOnStartup;
|
||||||
QCheckBox *_currentMacroRegisterDock;
|
QCheckBox *_currentMacroRegisterDock;
|
||||||
QCheckBox *_currentMacroDockAddRunButton;
|
QCheckBox *_currentMacroDockAddRunButton;
|
||||||
QCheckBox *_currentMacroDockAddPauseButton;
|
QCheckBox *_currentMacroDockAddPauseButton;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "macro-segment.hpp"
|
#include "macro-segment.hpp"
|
||||||
|
#include "macro.hpp"
|
||||||
#include "section.hpp"
|
#include "section.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
#include "mouse-wheel-guard.hpp"
|
#include "mouse-wheel-guard.hpp"
|
||||||
@@ -26,11 +27,13 @@ bool MacroSegment::Save(obs_data_t *obj) const
|
|||||||
bool MacroSegment::Load(obs_data_t *obj)
|
bool MacroSegment::Load(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
_collapsed = obs_data_get_bool(obj, "collapsed");
|
_collapsed = obs_data_get_bool(obj, "collapsed");
|
||||||
|
ClearAvailableTempvars();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroSegment::PostLoad()
|
bool MacroSegment::PostLoad()
|
||||||
{
|
{
|
||||||
|
SetupTempVars();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,20 +71,111 @@ void MacroSegment::SetVariableValue(const std::string &value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroSegment::IncrementVariableRef()
|
void MacroSegment::SetupTempVars()
|
||||||
{
|
{
|
||||||
if (!_supportsVariableValue) {
|
ClearAvailableTempvars();
|
||||||
return;
|
|
||||||
}
|
|
||||||
_variableRefs++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroSegment::DecrementVariableRef()
|
void MacroSegment::ClearAvailableTempvars()
|
||||||
{
|
{
|
||||||
if (!_supportsVariableValue || _variableRefs == 0) {
|
_tempVariables.clear();
|
||||||
|
NotifyUIAboutTempVarChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<MacroSegment>
|
||||||
|
getSharedSegmentFromMacro(Macro *macro, const MacroSegment *segment)
|
||||||
|
{
|
||||||
|
auto matches = [segment](const std::shared_ptr<MacroSegment> &s) {
|
||||||
|
return s.get() == segment;
|
||||||
|
};
|
||||||
|
auto condIt = std::find_if(macro->Conditions().begin(),
|
||||||
|
macro->Conditions().end(), matches);
|
||||||
|
if (condIt != macro->Conditions().end()) {
|
||||||
|
return *condIt;
|
||||||
|
}
|
||||||
|
auto actionIt = std::find_if(macro->Actions().begin(),
|
||||||
|
macro->Actions().end(), matches);
|
||||||
|
if (actionIt != macro->Actions().end()) {
|
||||||
|
return *actionIt;
|
||||||
|
}
|
||||||
|
auto elseIt = std::find_if(macro->ElseActions().begin(),
|
||||||
|
macro->ElseActions().end(), matches);
|
||||||
|
if (elseIt != macro->ElseActions().end()) {
|
||||||
|
return *elseIt;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegment::AddTempvar(const std::string &id, const std::string &name,
|
||||||
|
const std::string &description)
|
||||||
|
{
|
||||||
|
auto macro = GetMacro();
|
||||||
|
if (!macro) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_variableRefs--;
|
|
||||||
|
auto sharedSegment = getSharedSegmentFromMacro(macro, this);
|
||||||
|
if (!sharedSegment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TempVariable var(id, name, description, sharedSegment);
|
||||||
|
_tempVariables.emplace_back(std::move(var));
|
||||||
|
NotifyUIAboutTempVarChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegment::SetTempVarValue(const std::string &id,
|
||||||
|
const std::string &value)
|
||||||
|
{
|
||||||
|
for (auto &var : _tempVariables) {
|
||||||
|
if (var.ID() != id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var.SetValue(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegment::InvalidateTempVarValues()
|
||||||
|
{
|
||||||
|
for (auto &var : _tempVariables) {
|
||||||
|
var.InvalidateValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<const TempVariable>
|
||||||
|
MacroSegment::GetTempVar(const std::string &id) const
|
||||||
|
{
|
||||||
|
TempVariable *result = nullptr;
|
||||||
|
for (auto &var : _tempVariables) {
|
||||||
|
if (var.ID() == id) {
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vblog(LOG_INFO, "cannot get value of unknown tempvar %s", id.c_str());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SupportsVariableValue(MacroSegment *segment)
|
||||||
|
{
|
||||||
|
return segment && segment->_supportsVariableValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IncrementVariableRef(MacroSegment *segment)
|
||||||
|
{
|
||||||
|
if (!segment || !segment->_supportsVariableValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
segment->_variableRefs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecrementVariableRef(MacroSegment *segment)
|
||||||
|
{
|
||||||
|
if (!segment || !segment->_supportsVariableValue ||
|
||||||
|
segment->_variableRefs == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
segment->_variableRefs--;
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroSegmentEdit::MacroSegmentEdit(bool highlight, QWidget *parent)
|
MacroSegmentEdit::MacroSegmentEdit(bool highlight, QWidget *parent)
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// The following helpers are used by all macro seements,
|
// The following helpers are used by all macro segments,
|
||||||
// so it makes sense to include them here:
|
// so it makes sense to include them here:
|
||||||
#include "log-helper.hpp"
|
#include "log-helper.hpp"
|
||||||
#include "obs-module-helper.hpp"
|
#include "obs-module-helper.hpp"
|
||||||
#include "sync-helper.hpp"
|
#include "sync-helper.hpp"
|
||||||
|
#include "temp-variable.hpp"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
@@ -34,16 +35,26 @@ public:
|
|||||||
virtual std::string GetId() const = 0;
|
virtual std::string GetId() const = 0;
|
||||||
void SetHighlight();
|
void SetHighlight();
|
||||||
bool Highlight();
|
bool Highlight();
|
||||||
bool SupportsVariableValue() const { return _supportsVariableValue; }
|
|
||||||
virtual std::string GetVariableValue() const;
|
virtual std::string GetVariableValue() const;
|
||||||
void IncrementVariableRef();
|
|
||||||
void DecrementVariableRef();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend bool SupportsVariableValue(MacroSegment *);
|
||||||
|
friend void IncrementVariableRef(MacroSegment *);
|
||||||
|
friend void DecrementVariableRef(MacroSegment *);
|
||||||
void SetVariableValue(const std::string &value);
|
void SetVariableValue(const std::string &value);
|
||||||
bool IsReferencedInVars() { return _variableRefs != 0; }
|
bool IsReferencedInVars() { return _variableRefs != 0; }
|
||||||
|
|
||||||
|
virtual void SetupTempVars();
|
||||||
|
void AddTempvar(const std::string &id, const std::string &name,
|
||||||
|
const std::string &description = "");
|
||||||
|
void SetTempVarValue(const std::string &id, const std::string &value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ClearAvailableTempvars();
|
||||||
|
std::optional<const TempVariable>
|
||||||
|
GetTempVar(const std::string &id) const;
|
||||||
|
void InvalidateTempVarValues();
|
||||||
|
|
||||||
// Macro helpers
|
// Macro helpers
|
||||||
Macro *_macro = nullptr;
|
Macro *_macro = nullptr;
|
||||||
int _idx = 0;
|
int _idx = 0;
|
||||||
@@ -56,6 +67,9 @@ private:
|
|||||||
const bool _supportsVariableValue = false;
|
const bool _supportsVariableValue = false;
|
||||||
int _variableRefs = 0;
|
int _variableRefs = 0;
|
||||||
std::string _variableValue;
|
std::string _variableValue;
|
||||||
|
std::vector<TempVariable> _tempVariables;
|
||||||
|
|
||||||
|
friend class Macro;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Section;
|
class Section;
|
||||||
@@ -70,6 +84,7 @@ public:
|
|||||||
void SetFocusPolicyOfWidgets();
|
void SetFocusPolicyOfWidgets();
|
||||||
void SetCollapsed(bool collapsed);
|
void SetCollapsed(bool collapsed);
|
||||||
void SetSelected(bool);
|
void SetSelected(bool);
|
||||||
|
virtual std::shared_ptr<MacroSegment> Data() const = 0;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
@@ -99,7 +114,6 @@ private:
|
|||||||
BELOW,
|
BELOW,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual std::shared_ptr<MacroSegment> Data() = 0;
|
|
||||||
void ShowDropLine(DropLineState);
|
void ShowDropLine(DropLineState);
|
||||||
|
|
||||||
// The reason for using two separate frame widget each with their own
|
// The reason for using two separate frame widget each with their own
|
||||||
|
|||||||
@@ -244,6 +244,7 @@ void AdvSceneSwitcher::ExportMacros()
|
|||||||
obs_data_release(obj);
|
obs_data_release(obj);
|
||||||
}
|
}
|
||||||
obs_data_set_array(data, "macros", macroArray);
|
obs_data_set_array(data, "macros", macroArray);
|
||||||
|
switcher->SaveVariables(data);
|
||||||
obs_data_array_release(macroArray);
|
obs_data_array_release(macroArray);
|
||||||
obs_data_set_string(data, "version", g_GIT_TAG);
|
obs_data_set_string(data, "version", g_GIT_TAG);
|
||||||
auto json = obs_data_get_json(data);
|
auto json = obs_data_get_json(data);
|
||||||
@@ -253,6 +254,76 @@ void AdvSceneSwitcher::ExportMacros()
|
|||||||
MacroExportImportDialog::ExportMacros(exportString);
|
MacroExportImportDialog::ExportMacros(exportString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
isValidMacroSegmentIdx(const std::deque<std::shared_ptr<MacroSegment>> &list,
|
||||||
|
int idx)
|
||||||
|
{
|
||||||
|
return (idx > 0 || (unsigned)idx < list.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::SetupMacroSegmentSelection(MacroSection type, int idx)
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroSegmentList *setList, *resetList1, *resetList2;
|
||||||
|
int *setIdx, *resetIdx1, *resetIdx2;
|
||||||
|
std::deque<std::shared_ptr<MacroSegment>> segements;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case AdvSceneSwitcher::MacroSection::CONDITIONS:
|
||||||
|
setList = ui->conditionsList;
|
||||||
|
setIdx = ¤tConditionIdx;
|
||||||
|
segements = {macro->Conditions().begin(),
|
||||||
|
macro->Conditions().end()};
|
||||||
|
|
||||||
|
resetList1 = ui->actionsList;
|
||||||
|
resetList2 = ui->elseActionsList;
|
||||||
|
resetIdx1 = ¤tActionIdx;
|
||||||
|
resetIdx2 = ¤tElseActionIdx;
|
||||||
|
break;
|
||||||
|
case AdvSceneSwitcher::MacroSection::ACTIONS:
|
||||||
|
setList = ui->actionsList;
|
||||||
|
setIdx = ¤tActionIdx;
|
||||||
|
segements = {macro->Actions().begin(), macro->Actions().end()};
|
||||||
|
|
||||||
|
resetList1 = ui->conditionsList;
|
||||||
|
resetList2 = ui->elseActionsList;
|
||||||
|
resetIdx1 = ¤tConditionIdx;
|
||||||
|
resetIdx2 = ¤tElseActionIdx;
|
||||||
|
break;
|
||||||
|
case AdvSceneSwitcher::MacroSection::ELSE_ACTIONS:
|
||||||
|
setList = ui->elseActionsList;
|
||||||
|
setIdx = ¤tElseActionIdx;
|
||||||
|
segements = {macro->ElseActions().begin(),
|
||||||
|
macro->ElseActions().end()};
|
||||||
|
|
||||||
|
resetList1 = ui->actionsList;
|
||||||
|
resetList2 = ui->conditionsList;
|
||||||
|
resetIdx1 = ¤tActionIdx;
|
||||||
|
resetIdx2 = ¤tConditionIdx;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setList->SetSelection(idx);
|
||||||
|
resetList1->SetSelection(-1);
|
||||||
|
resetList2->SetSelection(-1);
|
||||||
|
if (isValidMacroSegmentIdx(segements, idx)) {
|
||||||
|
*setIdx = idx;
|
||||||
|
} else {
|
||||||
|
*setIdx = -1;
|
||||||
|
}
|
||||||
|
*resetIdx1 = -1;
|
||||||
|
*resetIdx2 = -1;
|
||||||
|
|
||||||
|
lastInteracted = type;
|
||||||
|
HighlightControls();
|
||||||
|
}
|
||||||
|
|
||||||
bool AdvSceneSwitcher::ResolveMacroImportNameConflict(
|
bool AdvSceneSwitcher::ResolveMacroImportNameConflict(
|
||||||
std::shared_ptr<Macro> ¯o)
|
std::shared_ptr<Macro> ¯o)
|
||||||
{
|
{
|
||||||
@@ -297,6 +368,26 @@ bool AdvSceneSwitcher::ResolveMacroImportNameConflict(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool variableWithNameExists(const std::string &name)
|
||||||
|
{
|
||||||
|
return !!GetVariableByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void importVariables(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
OBSDataArrayAutoRelease array = obs_data_get_array(obj, "variables");
|
||||||
|
size_t count = obs_data_array_count(array);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
OBSDataAutoRelease data = obs_data_array_item(array, i);
|
||||||
|
auto var = Variable::Create();
|
||||||
|
var->Load(data);
|
||||||
|
if (variableWithNameExists(var->Name())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switcher->variables.emplace_back(var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::ImportMacros()
|
void AdvSceneSwitcher::ImportMacros()
|
||||||
{
|
{
|
||||||
QString json;
|
QString json;
|
||||||
@@ -310,6 +401,7 @@ void AdvSceneSwitcher::ImportMacros()
|
|||||||
ImportMacros();
|
ImportMacros();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
importVariables(data);
|
||||||
|
|
||||||
auto version = obs_data_get_string(data, "version");
|
auto version = obs_data_get_string(data, "version");
|
||||||
if (strcmp(version, g_GIT_TAG) != 0) {
|
if (strcmp(version, g_GIT_TAG) != 0) {
|
||||||
@@ -381,21 +473,6 @@ void AdvSceneSwitcher::on_macroName_editingFinished()
|
|||||||
RenameMacro(macro, newName);
|
RenameMacro(macro, newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_runMacro_clicked()
|
|
||||||
{
|
|
||||||
auto macro = GetSelectedMacro();
|
|
||||||
if (!macro) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = macro->PerformActions(true, true);
|
|
||||||
if (!ret) {
|
|
||||||
QString err =
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
|
||||||
DisplayMessage(err.arg(QString::fromStdString(macro->Name())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_runMacroInParallel_stateChanged(int value)
|
void AdvSceneSwitcher::on_runMacroInParallel_stateChanged(int value)
|
||||||
{
|
{
|
||||||
auto macro = GetSelectedMacro();
|
auto macro = GetSelectedMacro();
|
||||||
@@ -422,9 +499,20 @@ void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx)
|
|||||||
for (; afterIdx < actions.size(); afterIdx++) {
|
for (; afterIdx < actions.size(); afterIdx++) {
|
||||||
auto newEntry = new MacroActionEdit(this, &actions[afterIdx],
|
auto newEntry = new MacroActionEdit(this, &actions[afterIdx],
|
||||||
actions[afterIdx]->GetId());
|
actions[afterIdx]->GetId());
|
||||||
actionsList->Add(newEntry);
|
ui->actionsList->Add(newEntry);
|
||||||
}
|
}
|
||||||
actionsList->SetHelpMsgVisible(actions.size() == 0);
|
ui->actionsList->SetHelpMsgVisible(actions.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::PopulateMacroElseActions(Macro &m, uint32_t afterIdx)
|
||||||
|
{
|
||||||
|
auto &actions = m.ElseActions();
|
||||||
|
for (; afterIdx < actions.size(); afterIdx++) {
|
||||||
|
auto newEntry = new MacroActionEdit(this, &actions[afterIdx],
|
||||||
|
actions[afterIdx]->GetId());
|
||||||
|
ui->elseActionsList->Add(newEntry);
|
||||||
|
}
|
||||||
|
ui->elseActionsList->SetHelpMsgVisible(actions.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
|
void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
|
||||||
@@ -435,17 +523,35 @@ void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
|
|||||||
auto newEntry = new MacroConditionEdit(
|
auto newEntry = new MacroConditionEdit(
|
||||||
this, &conditions[afterIdx],
|
this, &conditions[afterIdx],
|
||||||
conditions[afterIdx]->GetId(), root);
|
conditions[afterIdx]->GetId(), root);
|
||||||
conditionsList->Add(newEntry);
|
ui->conditionsList->Add(newEntry);
|
||||||
root = false;
|
root = false;
|
||||||
}
|
}
|
||||||
conditionsList->SetHelpMsgVisible(conditions.size() == 0);
|
ui->conditionsList->SetHelpMsgVisible(conditions.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::SetActionData(Macro &m)
|
void AdvSceneSwitcher::SetActionData(Macro &m)
|
||||||
{
|
{
|
||||||
auto &actions = m.Actions();
|
auto &actions = m.Actions();
|
||||||
for (int idx = 0; idx < actionsList->ContentLayout()->count(); idx++) {
|
for (int idx = 0; idx < ui->actionsList->ContentLayout()->count();
|
||||||
auto item = actionsList->ContentLayout()->itemAt(idx);
|
idx++) {
|
||||||
|
auto item = ui->actionsList->ContentLayout()->itemAt(idx);
|
||||||
|
if (!item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto widget = static_cast<MacroActionEdit *>(item->widget());
|
||||||
|
if (!widget) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
widget->SetEntryData(&*(actions.begin() + idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::SetElseActionData(Macro &m)
|
||||||
|
{
|
||||||
|
auto &actions = m.ElseActions();
|
||||||
|
for (int idx = 0; idx < ui->elseActionsList->ContentLayout()->count();
|
||||||
|
idx++) {
|
||||||
|
auto item = ui->elseActionsList->ContentLayout()->itemAt(idx);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -460,9 +566,9 @@ void AdvSceneSwitcher::SetActionData(Macro &m)
|
|||||||
void AdvSceneSwitcher::SetConditionData(Macro &m)
|
void AdvSceneSwitcher::SetConditionData(Macro &m)
|
||||||
{
|
{
|
||||||
auto &conditions = m.Conditions();
|
auto &conditions = m.Conditions();
|
||||||
for (int idx = 0; idx < conditionsList->ContentLayout()->count();
|
for (int idx = 0; idx < ui->conditionsList->ContentLayout()->count();
|
||||||
idx++) {
|
idx++) {
|
||||||
auto item = conditionsList->ContentLayout()->itemAt(idx);
|
auto item = ui->conditionsList->ContentLayout()->itemAt(idx);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -474,6 +580,21 @@ void AdvSceneSwitcher::SetConditionData(Macro &m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void maximizeFirstSplitterEntry(QSplitter *splitter)
|
||||||
|
{
|
||||||
|
QList<int> newSizes;
|
||||||
|
newSizes << 999999;
|
||||||
|
for (int i = 0; i < splitter->sizes().size() - 1; i++) {
|
||||||
|
newSizes << 0;
|
||||||
|
}
|
||||||
|
splitter->setSizes(newSizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void centerSplitterPosition(QSplitter *splitter)
|
||||||
|
{
|
||||||
|
splitter->setSizes(QList<int>() << 999999 << 999999);
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::SetEditMacro(Macro &m)
|
void AdvSceneSwitcher::SetEditMacro(Macro &m)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -484,22 +605,40 @@ void AdvSceneSwitcher::SetEditMacro(Macro &m)
|
|||||||
ui->runMacroInParallel->setChecked(m.RunInParallel());
|
ui->runMacroInParallel->setChecked(m.RunInParallel());
|
||||||
ui->runMacroOnChange->setChecked(m.MatchOnChange());
|
ui->runMacroOnChange->setChecked(m.MatchOnChange());
|
||||||
}
|
}
|
||||||
conditionsList->Clear();
|
ui->conditionsList->Clear();
|
||||||
actionsList->Clear();
|
ui->actionsList->Clear();
|
||||||
|
ui->elseActionsList->Clear();
|
||||||
|
|
||||||
m.ResetUIHelpers();
|
m.ResetUIHelpers();
|
||||||
|
|
||||||
PopulateMacroConditions(m);
|
PopulateMacroConditions(m);
|
||||||
PopulateMacroActions(m);
|
PopulateMacroActions(m);
|
||||||
|
PopulateMacroElseActions(m);
|
||||||
SetMacroEditAreaDisabled(false);
|
SetMacroEditAreaDisabled(false);
|
||||||
|
|
||||||
|
currentActionIdx = -1;
|
||||||
|
currentElseActionIdx = -1;
|
||||||
|
currentConditionIdx = -1;
|
||||||
|
HighlightControls();
|
||||||
|
|
||||||
if (m.IsGroup()) {
|
if (m.IsGroup()) {
|
||||||
SetMacroEditAreaDisabled(true);
|
SetMacroEditAreaDisabled(true);
|
||||||
ui->macroName->setEnabled(true);
|
ui->macroName->setEnabled(true);
|
||||||
|
centerSplitterPosition(ui->macroActionConditionSplitter);
|
||||||
|
maximizeFirstSplitterEntry(ui->macroElseActionSplitter);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentActionIdx = -1;
|
if (!m.HasValidSplitterPositions()) {
|
||||||
currentConditionIdx = -1;
|
centerSplitterPosition(ui->macroActionConditionSplitter);
|
||||||
HighlightControls();
|
maximizeFirstSplitterEntry(ui->macroElseActionSplitter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->macroActionConditionSplitter->setSizes(
|
||||||
|
m.GetActionConditionSplitterPosition());
|
||||||
|
ui->macroElseActionSplitter->setSizes(
|
||||||
|
m.GetElseActionSplitterPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::SetMacroEditAreaDisabled(bool disable)
|
void AdvSceneSwitcher::SetMacroEditAreaDisabled(bool disable)
|
||||||
@@ -515,12 +654,17 @@ void AdvSceneSwitcher::SetMacroEditAreaDisabled(bool disable)
|
|||||||
|
|
||||||
void AdvSceneSwitcher::HighlightAction(int idx, QColor color)
|
void AdvSceneSwitcher::HighlightAction(int idx, QColor color)
|
||||||
{
|
{
|
||||||
actionsList->Highlight(idx, color);
|
ui->actionsList->Highlight(idx, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::HighlightElseAction(int idx, QColor color)
|
||||||
|
{
|
||||||
|
ui->elseActionsList->Highlight(idx, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::HighlightCondition(int idx, QColor color)
|
void AdvSceneSwitcher::HighlightCondition(int idx, QColor color)
|
||||||
{
|
{
|
||||||
conditionsList->Highlight(idx, color);
|
ui->conditionsList->Highlight(idx, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Macro> AdvSceneSwitcher::GetSelectedMacro()
|
std::shared_ptr<Macro> AdvSceneSwitcher::GetSelectedMacro()
|
||||||
@@ -533,6 +677,37 @@ std::vector<std::shared_ptr<Macro>> AdvSceneSwitcher::GetSelectedMacros()
|
|||||||
return ui->macros->GetCurrentMacros();
|
return ui->macros->GetCurrentMacros();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MacroSelectionAboutToChange()
|
||||||
|
{
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ui->macroName->isEnabled()) { // No macro is selected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto macro = GetMacroByQString(ui->macroName->text());
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro->SetActionConditionSplitterPosition(
|
||||||
|
ui->macroActionConditionSplitter->sizes());
|
||||||
|
|
||||||
|
auto elsePos = ui->macroElseActionSplitter->sizes();
|
||||||
|
// If only conditions are visible maximize the actions to avoid neither
|
||||||
|
// actions nor elseActions being visible when the condition <-> action
|
||||||
|
// splitter is moved
|
||||||
|
if (elsePos[0] == 0 && elsePos[1] == 0) {
|
||||||
|
macro->SetElseActionSplitterPosition(QList<int>()
|
||||||
|
<< 999999 << 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
macro->SetElseActionSplitterPosition(
|
||||||
|
ui->macroElseActionSplitter->sizes());
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::MacroSelectionChanged()
|
void AdvSceneSwitcher::MacroSelectionChanged()
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -542,10 +717,14 @@ void AdvSceneSwitcher::MacroSelectionChanged()
|
|||||||
auto macro = GetSelectedMacro();
|
auto macro = GetSelectedMacro();
|
||||||
if (!macro) {
|
if (!macro) {
|
||||||
SetMacroEditAreaDisabled(true);
|
SetMacroEditAreaDisabled(true);
|
||||||
conditionsList->Clear();
|
ui->conditionsList->Clear();
|
||||||
actionsList->Clear();
|
ui->actionsList->Clear();
|
||||||
conditionsList->SetHelpMsgVisible(true);
|
ui->elseActionsList->Clear();
|
||||||
actionsList->SetHelpMsgVisible(true);
|
ui->conditionsList->SetHelpMsgVisible(true);
|
||||||
|
ui->actionsList->SetHelpMsgVisible(true);
|
||||||
|
ui->elseActionsList->SetHelpMsgVisible(true);
|
||||||
|
centerSplitterPosition(ui->macroActionConditionSplitter);
|
||||||
|
maximizeFirstSplitterEntry(ui->macroElseActionSplitter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetEditMacro(*macro);
|
SetEditMacro(*macro);
|
||||||
@@ -583,8 +762,19 @@ void AdvSceneSwitcher::on_macroProperties_clicked()
|
|||||||
emit HighlightConditionsChanged(prop._highlightConditions);
|
emit HighlightConditionsChanged(prop._highlightConditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't restore splitter pos if an element is not visible at all
|
static void moveControlsToSplitter(QSplitter *splitter, int idx,
|
||||||
bool shouldResotreSplitterPos(const QList<int> &pos)
|
QLayoutItem *item)
|
||||||
|
{
|
||||||
|
static int splitterHandleWidth = 38;
|
||||||
|
auto handle = splitter->handle(idx);
|
||||||
|
auto layout = item->layout();
|
||||||
|
layout->setContentsMargins(7, 7, 7, 7);
|
||||||
|
handle->setLayout(layout);
|
||||||
|
splitter->setHandleWidth(splitterHandleWidth);
|
||||||
|
splitter->setStyleSheet("QSplitter::handle {background: transparent;}");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shouldRestoreSplitter(const QList<int> &pos)
|
||||||
{
|
{
|
||||||
if (pos.size() == 0) {
|
if (pos.size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -605,37 +795,44 @@ void AdvSceneSwitcher::SetupMacroTab()
|
|||||||
}
|
}
|
||||||
ui->macros->Reset(switcher->macros,
|
ui->macros->Reset(switcher->macros,
|
||||||
switcher->macroProperties._highlightExecuted);
|
switcher->macroProperties._highlightExecuted);
|
||||||
|
connect(ui->macros, SIGNAL(MacroSelectionAboutToChange()), this,
|
||||||
|
SLOT(MacroSelectionAboutToChange()));
|
||||||
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
|
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
|
||||||
SLOT(MacroSelectionChanged()));
|
SLOT(MacroSelectionChanged()));
|
||||||
|
ui->runMacro->SetMacroTree(ui->macros);
|
||||||
|
|
||||||
delete conditionsList;
|
ui->conditionsList->SetHelpMsg(
|
||||||
conditionsList = new MacroSegmentList(this);
|
|
||||||
conditionsList->SetHelpMsg(
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.editConditionHelp"));
|
obs_module_text("AdvSceneSwitcher.macroTab.editConditionHelp"));
|
||||||
connect(conditionsList, &MacroSegmentList::SelectionChagned, this,
|
connect(ui->conditionsList, &MacroSegmentList::SelectionChagned, this,
|
||||||
&AdvSceneSwitcher::MacroConditionSelectionChanged);
|
&AdvSceneSwitcher::MacroConditionSelectionChanged);
|
||||||
connect(conditionsList, &MacroSegmentList::Reorder, this,
|
connect(ui->conditionsList, &MacroSegmentList::Reorder, this,
|
||||||
&AdvSceneSwitcher::MacroConditionReorder);
|
&AdvSceneSwitcher::MacroConditionReorder);
|
||||||
ui->macroConditionsLayout->insertWidget(0, conditionsList);
|
|
||||||
|
|
||||||
delete actionsList;
|
ui->actionsList->SetHelpMsg(
|
||||||
actionsList = new MacroSegmentList(this);
|
|
||||||
actionsList->SetHelpMsg(
|
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.editActionHelp"));
|
obs_module_text("AdvSceneSwitcher.macroTab.editActionHelp"));
|
||||||
connect(actionsList, &MacroSegmentList::SelectionChagned, this,
|
connect(ui->actionsList, &MacroSegmentList::SelectionChagned, this,
|
||||||
&AdvSceneSwitcher::MacroActionSelectionChanged);
|
&AdvSceneSwitcher::MacroActionSelectionChanged);
|
||||||
connect(actionsList, &MacroSegmentList::Reorder, this,
|
connect(ui->actionsList, &MacroSegmentList::Reorder, this,
|
||||||
&AdvSceneSwitcher::MacroActionReorder);
|
&AdvSceneSwitcher::MacroActionReorder);
|
||||||
ui->macroActionsLayout->insertWidget(0, actionsList);
|
|
||||||
|
ui->elseActionsList->SetHelpMsg(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.macroTab.editElseActionHelp"));
|
||||||
|
connect(ui->elseActionsList, &MacroSegmentList::SelectionChagned, this,
|
||||||
|
&AdvSceneSwitcher::MacroElseActionSelectionChanged);
|
||||||
|
connect(ui->elseActionsList, &MacroSegmentList::Reorder, this,
|
||||||
|
&AdvSceneSwitcher::MacroElseActionReorder);
|
||||||
|
|
||||||
ui->macros->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->macros->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(ui->macros, &QWidget::customContextMenuRequested, this,
|
connect(ui->macros, &QWidget::customContextMenuRequested, this,
|
||||||
&AdvSceneSwitcher::ShowMacroContextMenu);
|
&AdvSceneSwitcher::ShowMacroContextMenu);
|
||||||
actionsList->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->actionsList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(actionsList, &QWidget::customContextMenuRequested, this,
|
connect(ui->actionsList, &QWidget::customContextMenuRequested, this,
|
||||||
&AdvSceneSwitcher::ShowMacroActionsContextMenu);
|
&AdvSceneSwitcher::ShowMacroActionsContextMenu);
|
||||||
conditionsList->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->elseActionsList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(conditionsList, &QWidget::customContextMenuRequested, this,
|
connect(ui->elseActionsList, &QWidget::customContextMenuRequested, this,
|
||||||
|
&AdvSceneSwitcher::ShowMacroElseActionsContextMenu);
|
||||||
|
ui->conditionsList->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(ui->conditionsList, &QWidget::customContextMenuRequested, this,
|
||||||
&AdvSceneSwitcher::ShowMacroConditionsContextMenu);
|
&AdvSceneSwitcher::ShowMacroConditionsContextMenu);
|
||||||
|
|
||||||
SetMacroEditAreaDisabled(true);
|
SetMacroEditAreaDisabled(true);
|
||||||
@@ -648,16 +845,10 @@ void AdvSceneSwitcher::SetupMacroTab()
|
|||||||
onChangeHighlightTimer.start();
|
onChangeHighlightTimer.start();
|
||||||
|
|
||||||
// Move condition controls into splitter handle layout
|
// Move condition controls into splitter handle layout
|
||||||
auto handle = ui->macroActionConditionSplitter->handle(1);
|
moveControlsToSplitter(ui->macroActionConditionSplitter, 1,
|
||||||
auto item = ui->macroConditionsLayout->takeAt(1);
|
ui->macroConditionsLayout->takeAt(1));
|
||||||
if (item) {
|
moveControlsToSplitter(ui->macroElseActionSplitter, 1,
|
||||||
auto layout = item->layout();
|
ui->macroActionsLayout->takeAt(1));
|
||||||
layout->setContentsMargins(7, 7, 7, 7);
|
|
||||||
handle->setLayout(layout);
|
|
||||||
ui->macroActionConditionSplitter->setHandleWidth(38);
|
|
||||||
}
|
|
||||||
ui->macroActionConditionSplitter->setStyleSheet(
|
|
||||||
"QSplitter::handle {background: transparent;}");
|
|
||||||
|
|
||||||
// Set action and condition control icons
|
// Set action and condition control icons
|
||||||
const std::string pathPrefix =
|
const std::string pathPrefix =
|
||||||
@@ -665,6 +856,9 @@ void AdvSceneSwitcher::SetupMacroTab()
|
|||||||
SetButtonIcon(ui->actionTop, (pathPrefix + "DoubleUp.svg").c_str());
|
SetButtonIcon(ui->actionTop, (pathPrefix + "DoubleUp.svg").c_str());
|
||||||
SetButtonIcon(ui->actionBottom,
|
SetButtonIcon(ui->actionBottom,
|
||||||
(pathPrefix + "DoubleDown.svg").c_str());
|
(pathPrefix + "DoubleDown.svg").c_str());
|
||||||
|
SetButtonIcon(ui->elseActionTop, (pathPrefix + "DoubleUp.svg").c_str());
|
||||||
|
SetButtonIcon(ui->elseActionBottom,
|
||||||
|
(pathPrefix + "DoubleDown.svg").c_str());
|
||||||
SetButtonIcon(ui->conditionTop, (pathPrefix + "DoubleUp.svg").c_str());
|
SetButtonIcon(ui->conditionTop, (pathPrefix + "DoubleUp.svg").c_str());
|
||||||
SetButtonIcon(ui->conditionBottom,
|
SetButtonIcon(ui->conditionBottom,
|
||||||
(pathPrefix + "DoubleDown.svg").c_str());
|
(pathPrefix + "DoubleDown.svg").c_str());
|
||||||
@@ -673,13 +867,11 @@ void AdvSceneSwitcher::SetupMacroTab()
|
|||||||
ui->macroListMacroEditSplitter->setStretchFactor(0, 1);
|
ui->macroListMacroEditSplitter->setStretchFactor(0, 1);
|
||||||
ui->macroListMacroEditSplitter->setStretchFactor(1, 4);
|
ui->macroListMacroEditSplitter->setStretchFactor(1, 4);
|
||||||
|
|
||||||
|
centerSplitterPosition(ui->macroActionConditionSplitter);
|
||||||
|
maximizeFirstSplitterEntry(ui->macroElseActionSplitter);
|
||||||
|
|
||||||
if (switcher->saveWindowGeo) {
|
if (switcher->saveWindowGeo) {
|
||||||
if (shouldResotreSplitterPos(
|
if (shouldRestoreSplitter(
|
||||||
switcher->macroActionConditionSplitterPosition)) {
|
|
||||||
ui->macroActionConditionSplitter->setSizes(
|
|
||||||
switcher->macroActionConditionSplitterPosition);
|
|
||||||
}
|
|
||||||
if (shouldResotreSplitterPos(
|
|
||||||
switcher->macroListMacroEditSplitterPosition)) {
|
switcher->macroListMacroEditSplitterPosition)) {
|
||||||
ui->macroListMacroEditSplitter->setSizes(
|
ui->macroListMacroEditSplitter->setSizes(
|
||||||
switcher->macroListMacroEditSplitterPosition);
|
switcher->macroListMacroEditSplitterPosition);
|
||||||
@@ -731,41 +923,55 @@ void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos)
|
|||||||
obs_module_text("AdvSceneSwitcher.macroTab.export"), this,
|
obs_module_text("AdvSceneSwitcher.macroTab.export"), this,
|
||||||
&AdvSceneSwitcher::ExportMacros);
|
&AdvSceneSwitcher::ExportMacros);
|
||||||
exportAction->setDisabled(ui->macros->SelectionEmpty());
|
exportAction->setDisabled(ui->macros->SelectionEmpty());
|
||||||
auto import = menu.addAction(
|
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.import"),
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.import"), this,
|
this, &AdvSceneSwitcher::ImportMacros);
|
||||||
&AdvSceneSwitcher::ImportMacros);
|
|
||||||
|
|
||||||
menu.exec(globalPos);
|
menu.exec(globalPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setupConextMenu(AdvSceneSwitcher *ss, const QPoint &pos,
|
||||||
|
std::function<void(AdvSceneSwitcher *)> expand,
|
||||||
|
std::function<void(AdvSceneSwitcher *)> collapse,
|
||||||
|
std::function<void(AdvSceneSwitcher *)> maximize,
|
||||||
|
std::function<void(AdvSceneSwitcher *)> minimize)
|
||||||
|
{
|
||||||
|
QMenu menu;
|
||||||
|
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.expandAll"),
|
||||||
|
ss, [ss, expand]() { expand(ss); });
|
||||||
|
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.collapseAll"),
|
||||||
|
ss, [ss, collapse]() { collapse(ss); });
|
||||||
|
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.maximize"),
|
||||||
|
ss, [ss, maximize]() { maximize(ss); });
|
||||||
|
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.minimize"),
|
||||||
|
ss, [ss, minimize]() { minimize(ss); });
|
||||||
|
menu.exec(pos);
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::ShowMacroActionsContextMenu(const QPoint &pos)
|
void AdvSceneSwitcher::ShowMacroActionsContextMenu(const QPoint &pos)
|
||||||
{
|
{
|
||||||
QPoint globalPos = actionsList->mapToGlobal(pos);
|
setupConextMenu(this, ui->actionsList->mapToGlobal(pos),
|
||||||
QMenu menu;
|
&AdvSceneSwitcher::ExpandAllActions,
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.expandAll"),
|
&AdvSceneSwitcher::CollapseAllActions,
|
||||||
this, &AdvSceneSwitcher::ExpandAllActions);
|
&AdvSceneSwitcher::MaximizeActions,
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.collapseAll"),
|
&AdvSceneSwitcher::MinimizeActions);
|
||||||
this, &AdvSceneSwitcher::CollapseAllActions);
|
}
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.maximize"),
|
|
||||||
this, &AdvSceneSwitcher::MinimizeConditions);
|
void AdvSceneSwitcher::ShowMacroElseActionsContextMenu(const QPoint &pos)
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.minimize"),
|
{
|
||||||
this, &AdvSceneSwitcher::MinimizeActions);
|
setupConextMenu(this, ui->elseActionsList->mapToGlobal(pos),
|
||||||
menu.exec(globalPos);
|
&AdvSceneSwitcher::ExpandAllElseActions,
|
||||||
|
&AdvSceneSwitcher::CollapseAllElseActions,
|
||||||
|
&AdvSceneSwitcher::MaximizeElseActions,
|
||||||
|
&AdvSceneSwitcher::MinimizeElseActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::ShowMacroConditionsContextMenu(const QPoint &pos)
|
void AdvSceneSwitcher::ShowMacroConditionsContextMenu(const QPoint &pos)
|
||||||
{
|
{
|
||||||
QPoint globalPos = conditionsList->mapToGlobal(pos);
|
setupConextMenu(this, ui->conditionsList->mapToGlobal(pos),
|
||||||
QMenu menu;
|
&AdvSceneSwitcher::ExpandAllConditions,
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.expandAll"),
|
&AdvSceneSwitcher::CollapseAllConditions,
|
||||||
this, &AdvSceneSwitcher::ExpandAllConditions);
|
&AdvSceneSwitcher::MaximizeConditions,
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.collapseAll"),
|
&AdvSceneSwitcher::MinimizeConditions);
|
||||||
this, &AdvSceneSwitcher::CollapseAllConditions);
|
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.maximize"),
|
|
||||||
this, &AdvSceneSwitcher::MinimizeActions);
|
|
||||||
menu.addAction(obs_module_text("AdvSceneSwitcher.macroTab.minimize"),
|
|
||||||
this, &AdvSceneSwitcher::MinimizeConditions);
|
|
||||||
menu.exec(globalPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::CopyMacro()
|
void AdvSceneSwitcher::CopyMacro()
|
||||||
@@ -795,60 +1001,103 @@ void AdvSceneSwitcher::CopyMacro()
|
|||||||
emit MacroAdded(QString::fromStdString(name));
|
emit MacroAdded(QString::fromStdString(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::ExpandAllActions()
|
void setCollapsedHelper(const std::shared_ptr<Macro> &m, MacroSegmentList *list,
|
||||||
|
bool collapsed)
|
||||||
{
|
{
|
||||||
auto m = GetSelectedMacro();
|
|
||||||
if (!m) {
|
if (!m) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionsList->SetCollapsed(false);
|
list->SetCollapsed(collapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::ExpandAllActions()
|
||||||
|
{
|
||||||
|
setCollapsedHelper(GetSelectedMacro(), ui->actionsList, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::ExpandAllElseActions()
|
||||||
|
{
|
||||||
|
setCollapsedHelper(GetSelectedMacro(), ui->elseActionsList, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::ExpandAllConditions()
|
void AdvSceneSwitcher::ExpandAllConditions()
|
||||||
{
|
{
|
||||||
auto m = GetSelectedMacro();
|
setCollapsedHelper(GetSelectedMacro(), ui->conditionsList, false);
|
||||||
if (!m) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
conditionsList->SetCollapsed(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::CollapseAllActions()
|
void AdvSceneSwitcher::CollapseAllActions()
|
||||||
{
|
{
|
||||||
auto m = GetSelectedMacro();
|
setCollapsedHelper(GetSelectedMacro(), ui->actionsList, true);
|
||||||
if (!m) {
|
}
|
||||||
return;
|
|
||||||
}
|
void AdvSceneSwitcher::CollapseAllElseActions()
|
||||||
actionsList->SetCollapsed(true);
|
{
|
||||||
|
setCollapsedHelper(GetSelectedMacro(), ui->elseActionsList, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::CollapseAllConditions()
|
void AdvSceneSwitcher::CollapseAllConditions()
|
||||||
{
|
{
|
||||||
auto m = GetSelectedMacro();
|
setCollapsedHelper(GetSelectedMacro(), ui->conditionsList, true);
|
||||||
if (!m) {
|
}
|
||||||
return;
|
|
||||||
}
|
static void reduceSizeOfSplitterIdx(QSplitter *splitter, int idx)
|
||||||
conditionsList->SetCollapsed(true);
|
{
|
||||||
|
auto sizes = splitter->sizes();
|
||||||
|
int sum = sizes[0] + sizes[1];
|
||||||
|
int reducedSize = sum / 10;
|
||||||
|
sizes[idx] = reducedSize;
|
||||||
|
sizes[(idx + 1) % 2] = sum - reducedSize;
|
||||||
|
splitter->setSizes(sizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::MinimizeActions()
|
void AdvSceneSwitcher::MinimizeActions()
|
||||||
{
|
{
|
||||||
QList<int> sizes = ui->macroActionConditionSplitter->sizes();
|
auto macro = GetSelectedMacro();
|
||||||
int sum = sizes[0] + sizes[1];
|
if (!macro) {
|
||||||
int actionsHeight = sum / 10;
|
return;
|
||||||
sizes[1] = actionsHeight;
|
}
|
||||||
sizes[0] = sum - actionsHeight;
|
if (macro->ElseActions().size() == 0) {
|
||||||
ui->macroActionConditionSplitter->setSizes(sizes);
|
reduceSizeOfSplitterIdx(ui->macroActionConditionSplitter, 1);
|
||||||
|
} else {
|
||||||
|
maximizeFirstSplitterEntry(ui->macroElseActionSplitter);
|
||||||
|
reduceSizeOfSplitterIdx(ui->macroActionConditionSplitter, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MaximizeActions()
|
||||||
|
{
|
||||||
|
MinimizeElseActions();
|
||||||
|
MinimizeConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MinimizeElseActions()
|
||||||
|
{
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (macro->ElseActions().size() == 0) {
|
||||||
|
maximizeFirstSplitterEntry(ui->macroElseActionSplitter);
|
||||||
|
} else {
|
||||||
|
reduceSizeOfSplitterIdx(ui->macroElseActionSplitter, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::MaximizeElseActions()
|
||||||
|
{
|
||||||
|
MinimizeConditions();
|
||||||
|
reduceSizeOfSplitterIdx(ui->macroElseActionSplitter, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::MinimizeConditions()
|
void AdvSceneSwitcher::MinimizeConditions()
|
||||||
{
|
{
|
||||||
QList<int> sizes = ui->macroActionConditionSplitter->sizes();
|
reduceSizeOfSplitterIdx(ui->macroActionConditionSplitter, 0);
|
||||||
int sum = sizes[0] + sizes[1];
|
}
|
||||||
int conditionsHeight = sum / 10;
|
|
||||||
sizes[0] = conditionsHeight;
|
void AdvSceneSwitcher::MaximizeConditions()
|
||||||
sizes[1] = sum - conditionsHeight;
|
{
|
||||||
ui->macroActionConditionSplitter->setSizes(sizes);
|
MinimizeElseActions();
|
||||||
|
MinimizeActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdvSceneSwitcher::MacroTabIsInFocus()
|
bool AdvSceneSwitcher::MacroTabIsInFocus()
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ static inline int
|
|||||||
ModelIndexToMacroIndex(int modelIdx,
|
ModelIndexToMacroIndex(int modelIdx,
|
||||||
const std::deque<std::shared_ptr<Macro>> ¯os)
|
const std::deque<std::shared_ptr<Macro>> ¯os)
|
||||||
{
|
{
|
||||||
assert(macros.size() >= modelIdx);
|
assert((int)macros.size() >= modelIdx);
|
||||||
int realIdx = 0;
|
int realIdx = 0;
|
||||||
const auto &m = macros[0];
|
const auto &m = macros[0];
|
||||||
bool inCollapsedGroup = m->IsGroup() && m->IsCollapsed();
|
bool inCollapsedGroup = m->IsGroup() && m->IsCollapsed();
|
||||||
@@ -609,7 +609,7 @@ bool MacroTreeModel::IsLastItem(std::shared_ptr<Macro> item) const
|
|||||||
bool MacroTreeModel::IsInValidState()
|
bool MacroTreeModel::IsInValidState()
|
||||||
{
|
{
|
||||||
// Check for reordering erros
|
// Check for reordering erros
|
||||||
for (int i = 0, j = 0; i < _macros.size(); i++) {
|
for (size_t i = 0, j = 0; i < _macros.size(); i++) {
|
||||||
const auto &m = _macros[i];
|
const auto &m = _macros[i];
|
||||||
if (QString::fromStdString(m->Name()) !=
|
if (QString::fromStdString(m->Name()) !=
|
||||||
data(index(j, 0), Qt::AccessibleTextRole)) {
|
data(index(j, 0), Qt::AccessibleTextRole)) {
|
||||||
@@ -622,7 +622,7 @@ bool MacroTreeModel::IsInValidState()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for group errors
|
// Check for group errors
|
||||||
for (int i = 0; i < _macros.size(); i++) {
|
for (size_t i = 0; i < _macros.size(); i++) {
|
||||||
const auto &m = _macros[i];
|
const auto &m = _macros[i];
|
||||||
if (!m->IsGroup()) {
|
if (!m->IsGroup()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1260,6 +1260,7 @@ void MacroTree::UngroupSelectedGroups()
|
|||||||
void MacroTree::SelectionChangedHelper(const QItemSelection &,
|
void MacroTree::SelectionChangedHelper(const QItemSelection &,
|
||||||
const QItemSelection &)
|
const QItemSelection &)
|
||||||
{
|
{
|
||||||
|
emit MacroSelectionAboutToChange();
|
||||||
emit MacroSelectionChanged();
|
emit MacroSelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ public slots:
|
|||||||
const QItemSelection &);
|
const QItemSelection &);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void MacroSelectionAboutToChange();
|
||||||
void MacroSelectionChanged();
|
void MacroSelectionChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Macro::~Macro()
|
|||||||
Stop();
|
Stop();
|
||||||
ClearHotkeys();
|
ClearHotkeys();
|
||||||
|
|
||||||
// Keep the dock widgets in case of shutdown so they can be rostored by
|
// Keep the dock widgets in case of shutdown so they can be restored by
|
||||||
// OBS on startup
|
// OBS on startup
|
||||||
if (!switcher->obsIsShuttingDown) {
|
if (!switcher->obsIsShuttingDown) {
|
||||||
RemoveDock();
|
RemoveDock();
|
||||||
@@ -176,24 +176,26 @@ bool Macro::CeckMatch()
|
|||||||
}
|
}
|
||||||
vblog(LOG_INFO, "Macro %s returned %d", _name.c_str(), _matched);
|
vblog(LOG_INFO, "Macro %s returned %d", _name.c_str(), _matched);
|
||||||
|
|
||||||
bool matchedBeforeOnChangeCheck = _matched;
|
_conditionSateChanged = _lastMatched != _matched;
|
||||||
if (_matched && _matchOnChange && _lastMatched) {
|
if (!_conditionSateChanged && _performActionsOnChange) {
|
||||||
vblog(LOG_INFO, "ignore match for Macro %s (on change)",
|
_onPreventedActionExecution = true;
|
||||||
_name.c_str());
|
|
||||||
_matched = false;
|
|
||||||
SetOnChangeHighlight();
|
|
||||||
}
|
}
|
||||||
_lastMatched = matchedBeforeOnChangeCheck;
|
_lastMatched = _matched;
|
||||||
_lastCheckTime = std::chrono::high_resolution_clock::now();
|
_lastCheckTime = std::chrono::high_resolution_clock::now();
|
||||||
return _matched;
|
return _matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Macro::PerformActions(bool forceParallel, bool ignorePause)
|
bool Macro::PerformActions(bool match, bool forceParallel, bool ignorePause)
|
||||||
{
|
{
|
||||||
if (!_done) {
|
if (!_done) {
|
||||||
vblog(LOG_INFO, "macro %s already running", _name.c_str());
|
vblog(LOG_INFO, "macro %s already running", _name.c_str());
|
||||||
return !forceParallel;
|
return !forceParallel;
|
||||||
}
|
}
|
||||||
|
std::function<bool(bool)> runFunc =
|
||||||
|
match ? std::bind(&Macro::RunActions, this,
|
||||||
|
std::placeholders::_1)
|
||||||
|
: std::bind(&Macro::RunElseActions, this,
|
||||||
|
std::placeholders::_1);
|
||||||
_stop = false;
|
_stop = false;
|
||||||
_done = false;
|
_done = false;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
@@ -202,9 +204,9 @@ bool Macro::PerformActions(bool forceParallel, bool ignorePause)
|
|||||||
_backgroundThread.join();
|
_backgroundThread.join();
|
||||||
}
|
}
|
||||||
_backgroundThread = std::thread(
|
_backgroundThread = std::thread(
|
||||||
[this, ignorePause] { RunActions(ignorePause); });
|
[this, runFunc, ignorePause] { runFunc(ignorePause); });
|
||||||
} else {
|
} else {
|
||||||
RunActions(ret, ignorePause);
|
ret = runFunc(ignorePause);
|
||||||
}
|
}
|
||||||
_lastExecutionTime = std::chrono::high_resolution_clock::now();
|
_lastExecutionTime = std::chrono::high_resolution_clock::now();
|
||||||
auto group = _parent.lock();
|
auto group = _parent.lock();
|
||||||
@@ -223,6 +225,28 @@ bool Macro::ExecutedSince(
|
|||||||
return _lastExecutionTime > time;
|
return _lastExecutionTime > time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Macro::ShouldRunActions() const
|
||||||
|
{
|
||||||
|
const bool hasActionsToExecute =
|
||||||
|
(_matched || _elseActions.size() > 0) &&
|
||||||
|
(!_performActionsOnChange || _conditionSateChanged);
|
||||||
|
|
||||||
|
if (VerboseLoggingEnabled() && _performActionsOnChange &&
|
||||||
|
!_conditionSateChanged) {
|
||||||
|
if (_matched && _actions.size() > 0) {
|
||||||
|
blog(LOG_INFO, "skip actions for Macro %s (on change)",
|
||||||
|
_name.c_str());
|
||||||
|
}
|
||||||
|
if (!_matched && _elseActions.size() > 0) {
|
||||||
|
blog(LOG_INFO,
|
||||||
|
"skip else actions for Macro %s (on change)",
|
||||||
|
_name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasActionsToExecute;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t Macro::MsSinceLastCheck() const
|
int64_t Macro::MsSinceLastCheck() const
|
||||||
{
|
{
|
||||||
if (_lastCheckTime.time_since_epoch().count() == 0) {
|
if (_lastCheckTime.time_since_epoch().count() == 0) {
|
||||||
@@ -251,37 +275,47 @@ void Macro::ResetTimers()
|
|||||||
_lastExecutionTime = {};
|
_lastExecutionTime = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Macro::RunActions(bool &retVal, bool ignorePause)
|
bool Macro::RunActionsHelper(
|
||||||
|
const std::deque<std::shared_ptr<MacroAction>> &actionsToRun,
|
||||||
|
bool ignorePause)
|
||||||
{
|
{
|
||||||
bool ret = true;
|
// Create copy of action list as elements might be removed, inserted, or
|
||||||
for (auto &a : _actions) {
|
// reordered while actions are currently being executed.
|
||||||
if (a->Enabled()) {
|
auto actions = actionsToRun;
|
||||||
a->LogAction();
|
|
||||||
ret = ret && a->PerformAction();
|
bool actionsExecutedSuccessfully = true;
|
||||||
|
for (auto &action : actions) {
|
||||||
|
if (action->Enabled()) {
|
||||||
|
action->LogAction();
|
||||||
|
actionsExecutedSuccessfully =
|
||||||
|
actionsExecutedSuccessfully &&
|
||||||
|
action->PerformAction();
|
||||||
} else {
|
} else {
|
||||||
vblog(LOG_INFO, "skipping disabled action %s",
|
vblog(LOG_INFO, "skipping disabled action %s",
|
||||||
a->GetId().c_str());
|
action->GetId().c_str());
|
||||||
}
|
}
|
||||||
if (!ret || (_paused && !ignorePause) || _stop || _die) {
|
if (!actionsExecutedSuccessfully || (_paused && !ignorePause) ||
|
||||||
retVal = ret;
|
_stop || _die) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (a->Enabled()) {
|
if (action->Enabled()) {
|
||||||
a->SetHighlight();
|
action->SetHighlight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_done = true;
|
_done = true;
|
||||||
|
return actionsExecutedSuccessfully;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Macro::RunActions(bool ignorePause)
|
bool Macro::RunActions(bool ignorePause)
|
||||||
{
|
{
|
||||||
bool unused;
|
vblog(LOG_INFO, "running actions of %s", _name.c_str());
|
||||||
RunActions(unused, ignorePause);
|
return RunActionsHelper(_actions, ignorePause);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Macro::SetOnChangeHighlight()
|
bool Macro::RunElseActions(bool ignorePause)
|
||||||
{
|
{
|
||||||
_onChangeTriggered = true;
|
vblog(LOG_INFO, "running else actions of %s", _name.c_str());
|
||||||
|
return RunActionsHelper(_elseActions, ignorePause);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Macro::DockIsVisible() const
|
bool Macro::DockIsVisible() const
|
||||||
@@ -289,6 +323,11 @@ bool Macro::DockIsVisible() const
|
|||||||
return _dock && _dockAction && _dock->isVisible();
|
return _dock && _dockAction && _dock->isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Macro::SetMatchOnChange(bool onChange)
|
||||||
|
{
|
||||||
|
_performActionsOnChange = onChange;
|
||||||
|
}
|
||||||
|
|
||||||
void Macro::SetPaused(bool pause)
|
void Macro::SetPaused(bool pause)
|
||||||
{
|
{
|
||||||
if (_paused && !pause) {
|
if (_paused && !pause) {
|
||||||
@@ -322,6 +361,126 @@ void Macro::Stop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<TempVariable> Macro::GetTempVars(MacroSegment *filter) const
|
||||||
|
{
|
||||||
|
std::vector<TempVariable> res;
|
||||||
|
|
||||||
|
auto addTempVars = [&res](const std::deque<std::shared_ptr<MacroSegment>>
|
||||||
|
&segments) {
|
||||||
|
for (const auto &s : segments) {
|
||||||
|
const auto &tempVars = s->_tempVariables;
|
||||||
|
res.insert(res.end(), tempVars.begin(), tempVars.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addTempVars({_conditions.begin(), _conditions.end()});
|
||||||
|
addTempVars({_actions.begin(), _actions.end()});
|
||||||
|
addTempVars({_elseActions.begin(), _elseActions.end()});
|
||||||
|
|
||||||
|
if (!filter) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto isCondition = [this](const MacroSegment *segment) -> bool {
|
||||||
|
return std::find_if(_conditions.begin(), _conditions.end(),
|
||||||
|
[segment](
|
||||||
|
const std::shared_ptr<MacroSegment>
|
||||||
|
&ptr) {
|
||||||
|
return ptr.get() == segment;
|
||||||
|
}) != _conditions.end();
|
||||||
|
};
|
||||||
|
auto isAction = [this](MacroSegment *segment) -> bool {
|
||||||
|
return std::find_if(_actions.begin(), _actions.end(),
|
||||||
|
[segment](
|
||||||
|
const std::shared_ptr<MacroSegment>
|
||||||
|
&ptr) {
|
||||||
|
return ptr.get() == segment;
|
||||||
|
}) != _actions.end();
|
||||||
|
};
|
||||||
|
auto isElseAction = [this](MacroSegment *segment) -> bool {
|
||||||
|
return std::find_if(_elseActions.begin(), _elseActions.end(),
|
||||||
|
[segment](
|
||||||
|
const std::shared_ptr<MacroSegment>
|
||||||
|
&ptr) {
|
||||||
|
return ptr.get() == segment;
|
||||||
|
}) != _elseActions.end();
|
||||||
|
};
|
||||||
|
|
||||||
|
const int filterIndex = filter->GetIndex();
|
||||||
|
// Remove all actions and else actions and conditions after filterIndex
|
||||||
|
if (isCondition(filter)) {
|
||||||
|
for (auto it = res.begin(); it != res.end();) {
|
||||||
|
auto segment = it->Segment().lock().get();
|
||||||
|
if (isCondition(segment) &&
|
||||||
|
segment->GetIndex() >= filterIndex) {
|
||||||
|
it = res.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isAction(segment) || isElseAction(segment)) {
|
||||||
|
it = res.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// Remove all else actions and actions after filterIndex
|
||||||
|
if (isAction(filter)) {
|
||||||
|
for (auto it = res.begin(); it != res.end();) {
|
||||||
|
auto segment = it->Segment().lock().get();
|
||||||
|
if (isAction(segment) &&
|
||||||
|
segment->GetIndex() >= filterIndex) {
|
||||||
|
it = res.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isElseAction(segment)) {
|
||||||
|
it = res.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// Remove all actions and elseActions after filterIndex
|
||||||
|
for (auto it = res.begin(); it != res.end();) {
|
||||||
|
auto segment = it->Segment().lock().get();
|
||||||
|
if (isElseAction(segment) &&
|
||||||
|
segment->GetIndex() >= filterIndex) {
|
||||||
|
it = res.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (isAction(segment)) {
|
||||||
|
it = res.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<const TempVariable> Macro::GetTempVar(const MacroSegment *segment,
|
||||||
|
const std::string &id) const
|
||||||
|
{
|
||||||
|
if (!segment) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return segment->GetTempVar(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Macro::InvalidateTempVarValues() const
|
||||||
|
{
|
||||||
|
auto invalidateHelper =
|
||||||
|
[](const std::deque<std::shared_ptr<MacroSegment>> &segments) {
|
||||||
|
for (const auto &s : segments) {
|
||||||
|
s->InvalidateTempVarValues();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
invalidateHelper({_conditions.begin(), _conditions.end()});
|
||||||
|
invalidateHelper({_actions.begin(), _actions.end()});
|
||||||
|
invalidateHelper({_elseActions.begin(), _elseActions.end()});
|
||||||
|
}
|
||||||
|
|
||||||
std::deque<std::shared_ptr<MacroCondition>> &Macro::Conditions()
|
std::deque<std::shared_ptr<MacroCondition>> &Macro::Conditions()
|
||||||
{
|
{
|
||||||
return _conditions;
|
return _conditions;
|
||||||
@@ -332,22 +491,39 @@ std::deque<std::shared_ptr<MacroAction>> &Macro::Actions()
|
|||||||
return _actions;
|
return _actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Macro::UpdateActionIndices()
|
std::deque<std::shared_ptr<MacroAction>> &Macro::ElseActions()
|
||||||
|
{
|
||||||
|
return _elseActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateIndicesHelper(std::deque<std::shared_ptr<MacroSegment>> &list)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (auto a : _actions) {
|
for (auto segment : list) {
|
||||||
a->SetIndex(idx);
|
segment->SetIndex(idx);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Macro::UpdateActionIndices()
|
||||||
|
{
|
||||||
|
std::deque<std::shared_ptr<MacroSegment>> list(_actions.begin(),
|
||||||
|
_actions.end());
|
||||||
|
updateIndicesHelper(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Macro::UpdateElseActionIndices()
|
||||||
|
{
|
||||||
|
std::deque<std::shared_ptr<MacroSegment>> list(_elseActions.begin(),
|
||||||
|
_elseActions.end());
|
||||||
|
updateIndicesHelper(list);
|
||||||
|
}
|
||||||
|
|
||||||
void Macro::UpdateConditionIndices()
|
void Macro::UpdateConditionIndices()
|
||||||
{
|
{
|
||||||
int idx = 0;
|
std::deque<std::shared_ptr<MacroSegment>> list(_conditions.begin(),
|
||||||
for (auto c : _conditions) {
|
_conditions.end());
|
||||||
c->SetIndex(idx);
|
updateIndicesHelper(list);
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Macro> Macro::Parent() const
|
std::shared_ptr<Macro> Macro::Parent() const
|
||||||
@@ -360,55 +536,57 @@ bool Macro::Save(obs_data_t *obj) const
|
|||||||
obs_data_set_string(obj, "name", _name.c_str());
|
obs_data_set_string(obj, "name", _name.c_str());
|
||||||
obs_data_set_bool(obj, "pause", _paused);
|
obs_data_set_bool(obj, "pause", _paused);
|
||||||
obs_data_set_bool(obj, "parallel", _runInParallel);
|
obs_data_set_bool(obj, "parallel", _runInParallel);
|
||||||
obs_data_set_bool(obj, "onChange", _matchOnChange);
|
obs_data_set_bool(obj, "onChange", _performActionsOnChange);
|
||||||
|
obs_data_set_bool(obj, "skipExecOnStart", _skipExecOnStart);
|
||||||
|
|
||||||
obs_data_set_bool(obj, "group", _isGroup);
|
obs_data_set_bool(obj, "group", _isGroup);
|
||||||
if (_isGroup) {
|
if (_isGroup) {
|
||||||
auto groupData = obs_data_create();
|
OBSDataAutoRelease groupData = obs_data_create();
|
||||||
obs_data_set_bool(groupData, "collapsed", _isCollapsed);
|
obs_data_set_bool(groupData, "collapsed", _isCollapsed);
|
||||||
obs_data_set_int(groupData, "size", _groupSize);
|
obs_data_set_int(groupData, "size", _groupSize);
|
||||||
obs_data_set_obj(obj, "groupData", groupData);
|
obs_data_set_obj(obj, "groupData", groupData);
|
||||||
obs_data_release(groupData);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveDockSettings(obj);
|
SaveDockSettings(obj);
|
||||||
|
|
||||||
|
SaveSplitterPos(_actionConditionSplitterPosition, obj,
|
||||||
|
"macroActionConditionSplitterPosition");
|
||||||
|
SaveSplitterPos(_elseActionSplitterPosition, obj,
|
||||||
|
"macroElseActionSplitterPosition");
|
||||||
|
|
||||||
obs_data_set_bool(obj, "registerHotkeys", _registerHotkeys);
|
obs_data_set_bool(obj, "registerHotkeys", _registerHotkeys);
|
||||||
obs_data_array_t *pauseHotkey = obs_hotkey_save(_pauseHotkey);
|
OBSDataArrayAutoRelease pauseHotkey = obs_hotkey_save(_pauseHotkey);
|
||||||
obs_data_set_array(obj, "pauseHotkey", pauseHotkey);
|
obs_data_set_array(obj, "pauseHotkey", pauseHotkey);
|
||||||
obs_data_array_release(pauseHotkey);
|
OBSDataArrayAutoRelease unpauseHotkey = obs_hotkey_save(_unpauseHotkey);
|
||||||
obs_data_array_t *unpauseHotkey = obs_hotkey_save(_unpauseHotkey);
|
|
||||||
obs_data_set_array(obj, "unpauseHotkey", unpauseHotkey);
|
obs_data_set_array(obj, "unpauseHotkey", unpauseHotkey);
|
||||||
obs_data_array_release(unpauseHotkey);
|
OBSDataArrayAutoRelease togglePauseHotkey =
|
||||||
obs_data_array_t *togglePauseHotkey =
|
|
||||||
obs_hotkey_save(_togglePauseHotkey);
|
obs_hotkey_save(_togglePauseHotkey);
|
||||||
obs_data_set_array(obj, "togglePauseHotkey", togglePauseHotkey);
|
obs_data_set_array(obj, "togglePauseHotkey", togglePauseHotkey);
|
||||||
obs_data_array_release(togglePauseHotkey);
|
|
||||||
|
|
||||||
obs_data_array_t *conditions = obs_data_array_create();
|
OBSDataArrayAutoRelease conditions = obs_data_array_create();
|
||||||
for (auto &c : _conditions) {
|
for (auto &c : _conditions) {
|
||||||
obs_data_t *array_obj = obs_data_create();
|
OBSDataAutoRelease arrayObj = obs_data_create();
|
||||||
|
c->Save(arrayObj);
|
||||||
c->Save(array_obj);
|
obs_data_array_push_back(conditions, arrayObj);
|
||||||
obs_data_array_push_back(conditions, array_obj);
|
|
||||||
|
|
||||||
obs_data_release(array_obj);
|
|
||||||
}
|
}
|
||||||
obs_data_set_array(obj, "conditions", conditions);
|
obs_data_set_array(obj, "conditions", conditions);
|
||||||
obs_data_array_release(conditions);
|
|
||||||
|
|
||||||
obs_data_array_t *actions = obs_data_array_create();
|
OBSDataArrayAutoRelease actions = obs_data_array_create();
|
||||||
for (auto &a : _actions) {
|
for (auto &a : _actions) {
|
||||||
obs_data_t *array_obj = obs_data_create();
|
OBSDataAutoRelease arrayObj = obs_data_create();
|
||||||
|
a->Save(arrayObj);
|
||||||
a->Save(array_obj);
|
obs_data_array_push_back(actions, arrayObj);
|
||||||
obs_data_array_push_back(actions, array_obj);
|
|
||||||
|
|
||||||
obs_data_release(array_obj);
|
|
||||||
}
|
}
|
||||||
obs_data_set_array(obj, "actions", actions);
|
obs_data_set_array(obj, "actions", actions);
|
||||||
obs_data_array_release(actions);
|
|
||||||
|
OBSDataArrayAutoRelease elseActions = obs_data_array_create();
|
||||||
|
for (auto &a : _elseActions) {
|
||||||
|
OBSDataAutoRelease arrayObj = obs_data_create();
|
||||||
|
a->Save(arrayObj);
|
||||||
|
obs_data_array_push_back(elseActions, arrayObj);
|
||||||
|
}
|
||||||
|
obs_data_set_array(obj, "elseActions", elseActions);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -452,72 +630,69 @@ bool Macro::Load(obs_data_t *obj)
|
|||||||
_name = obs_data_get_string(obj, "name");
|
_name = obs_data_get_string(obj, "name");
|
||||||
_paused = obs_data_get_bool(obj, "pause");
|
_paused = obs_data_get_bool(obj, "pause");
|
||||||
_runInParallel = obs_data_get_bool(obj, "parallel");
|
_runInParallel = obs_data_get_bool(obj, "parallel");
|
||||||
_matchOnChange = obs_data_get_bool(obj, "onChange");
|
_performActionsOnChange = obs_data_get_bool(obj, "onChange");
|
||||||
|
_skipExecOnStart = obs_data_get_bool(obj, "skipExecOnStart");
|
||||||
|
|
||||||
_isGroup = obs_data_get_bool(obj, "group");
|
_isGroup = obs_data_get_bool(obj, "group");
|
||||||
if (_isGroup) {
|
if (_isGroup) {
|
||||||
auto groupData = obs_data_get_obj(obj, "groupData");
|
OBSDataAutoRelease groupData =
|
||||||
|
obs_data_get_obj(obj, "groupData");
|
||||||
_isCollapsed = obs_data_get_bool(groupData, "collapsed");
|
_isCollapsed = obs_data_get_bool(groupData, "collapsed");
|
||||||
_groupSize = obs_data_get_int(groupData, "size");
|
_groupSize = obs_data_get_int(groupData, "size");
|
||||||
obs_data_release(groupData);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadDockSettings(obj);
|
LoadDockSettings(obj);
|
||||||
|
|
||||||
|
LoadSplitterPos(_actionConditionSplitterPosition, obj,
|
||||||
|
"macroActionConditionSplitterPosition");
|
||||||
|
LoadSplitterPos(_elseActionSplitterPosition, obj,
|
||||||
|
"macroElseActionSplitterPosition");
|
||||||
|
|
||||||
obs_data_set_default_bool(obj, "registerHotkeys", true);
|
obs_data_set_default_bool(obj, "registerHotkeys", true);
|
||||||
_registerHotkeys = obs_data_get_bool(obj, "registerHotkeys");
|
_registerHotkeys = obs_data_get_bool(obj, "registerHotkeys");
|
||||||
if (_registerHotkeys) {
|
if (_registerHotkeys) {
|
||||||
SetupHotkeys();
|
SetupHotkeys();
|
||||||
}
|
}
|
||||||
obs_data_array_t *pauseHotkey = obs_data_get_array(obj, "pauseHotkey");
|
OBSDataArrayAutoRelease pauseHotkey =
|
||||||
|
obs_data_get_array(obj, "pauseHotkey");
|
||||||
obs_hotkey_load(_pauseHotkey, pauseHotkey);
|
obs_hotkey_load(_pauseHotkey, pauseHotkey);
|
||||||
obs_data_array_release(pauseHotkey);
|
OBSDataArrayAutoRelease unpauseHotkey =
|
||||||
obs_data_array_t *unpauseHotkey =
|
|
||||||
obs_data_get_array(obj, "unpauseHotkey");
|
obs_data_get_array(obj, "unpauseHotkey");
|
||||||
obs_hotkey_load(_unpauseHotkey, unpauseHotkey);
|
obs_hotkey_load(_unpauseHotkey, unpauseHotkey);
|
||||||
obs_data_array_release(unpauseHotkey);
|
OBSDataArrayAutoRelease togglePauseHotkey =
|
||||||
obs_data_array_t *togglePauseHotkey =
|
|
||||||
obs_data_get_array(obj, "togglePauseHotkey");
|
obs_data_get_array(obj, "togglePauseHotkey");
|
||||||
obs_hotkey_load(_togglePauseHotkey, togglePauseHotkey);
|
obs_hotkey_load(_togglePauseHotkey, togglePauseHotkey);
|
||||||
obs_data_array_release(togglePauseHotkey);
|
|
||||||
SetHotkeysDesc();
|
SetHotkeysDesc();
|
||||||
|
|
||||||
bool root = true;
|
bool root = true;
|
||||||
obs_data_array_t *conditions = obs_data_get_array(obj, "conditions");
|
OBSDataArrayAutoRelease conditions =
|
||||||
|
obs_data_get_array(obj, "conditions");
|
||||||
size_t count = obs_data_array_count(conditions);
|
size_t count = obs_data_array_count(conditions);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
obs_data_t *array_obj = obs_data_array_item(conditions, i);
|
OBSDataAutoRelease arrayObj =
|
||||||
|
obs_data_array_item(conditions, i);
|
||||||
std::string id = obs_data_get_string(array_obj, "id");
|
std::string id = obs_data_get_string(arrayObj, "id");
|
||||||
|
|
||||||
auto newEntry = MacroConditionFactory::Create(id, this);
|
auto newEntry = MacroConditionFactory::Create(id, this);
|
||||||
if (newEntry) {
|
if (newEntry) {
|
||||||
_conditions.emplace_back(newEntry);
|
_conditions.emplace_back(newEntry);
|
||||||
auto c = _conditions.back().get();
|
auto c = _conditions.back().get();
|
||||||
c->Load(array_obj);
|
c->Load(arrayObj);
|
||||||
setValidLogic(c, root, _name);
|
setValidLogic(c, root, _name);
|
||||||
} else {
|
} else {
|
||||||
blog(LOG_WARNING,
|
blog(LOG_WARNING,
|
||||||
"discarding condition entry with unknown id (%s) for macro %s",
|
"discarding condition entry with unknown id (%s) for macro %s",
|
||||||
id.c_str(), _name.c_str());
|
id.c_str(), _name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_release(array_obj);
|
|
||||||
root = false;
|
root = false;
|
||||||
}
|
}
|
||||||
obs_data_array_release(conditions);
|
|
||||||
UpdateConditionIndices();
|
UpdateConditionIndices();
|
||||||
|
|
||||||
obs_data_array_t *actions = obs_data_get_array(obj, "actions");
|
OBSDataArrayAutoRelease actions = obs_data_get_array(obj, "actions");
|
||||||
count = obs_data_array_count(actions);
|
count = obs_data_array_count(actions);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
obs_data_t *array_obj = obs_data_array_item(actions, i);
|
OBSDataAutoRelease array_obj = obs_data_array_item(actions, i);
|
||||||
|
|
||||||
std::string id = obs_data_get_string(array_obj, "id");
|
std::string id = obs_data_get_string(array_obj, "id");
|
||||||
|
|
||||||
auto newEntry = MacroActionFactory::Create(id, this);
|
auto newEntry = MacroActionFactory::Create(id, this);
|
||||||
if (newEntry) {
|
if (newEntry) {
|
||||||
_actions.emplace_back(newEntry);
|
_actions.emplace_back(newEntry);
|
||||||
@@ -527,11 +702,27 @@ bool Macro::Load(obs_data_t *obj)
|
|||||||
"discarding action entry with unknown id (%s) for macro %s",
|
"discarding action entry with unknown id (%s) for macro %s",
|
||||||
id.c_str(), _name.c_str());
|
id.c_str(), _name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_release(array_obj);
|
|
||||||
}
|
}
|
||||||
obs_data_array_release(actions);
|
|
||||||
UpdateActionIndices();
|
UpdateActionIndices();
|
||||||
|
|
||||||
|
OBSDataArrayAutoRelease elseActions =
|
||||||
|
obs_data_get_array(obj, "elseActions");
|
||||||
|
count = obs_data_array_count(elseActions);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
OBSDataAutoRelease array_obj =
|
||||||
|
obs_data_array_item(elseActions, i);
|
||||||
|
std::string id = obs_data_get_string(array_obj, "id");
|
||||||
|
auto newEntry = MacroActionFactory::Create(id, this);
|
||||||
|
if (newEntry) {
|
||||||
|
_elseActions.emplace_back(newEntry);
|
||||||
|
_elseActions.back()->Load(array_obj);
|
||||||
|
} else {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"discarding elseAction entry with unknown id (%s) for macro %s",
|
||||||
|
id.c_str(), _name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateElseActionIndices();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,6 +734,9 @@ bool Macro::PostLoad()
|
|||||||
for (auto &a : _actions) {
|
for (auto &a : _actions) {
|
||||||
a->PostLoad();
|
a->PostLoad();
|
||||||
}
|
}
|
||||||
|
for (auto &a : _elseActions) {
|
||||||
|
a->PostLoad();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +744,12 @@ bool Macro::SwitchesScene() const
|
|||||||
{
|
{
|
||||||
MacroActionSwitchScene temp(nullptr);
|
MacroActionSwitchScene temp(nullptr);
|
||||||
auto sceneSwitchId = temp.GetId();
|
auto sceneSwitchId = temp.GetId();
|
||||||
for (auto &a : _actions) {
|
for (const auto &a : _actions) {
|
||||||
|
if (a->GetId() == sceneSwitchId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto &a : _elseActions) {
|
||||||
if (a->GetId() == sceneSwitchId) {
|
if (a->GetId() == sceneSwitchId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -558,18 +757,44 @@ bool Macro::SwitchesScene() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QList<int> &Macro::GetActionConditionSplitterPosition() const
|
||||||
|
{
|
||||||
|
return _actionConditionSplitterPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Macro::SetActionConditionSplitterPosition(const QList<int> sizes)
|
||||||
|
{
|
||||||
|
_actionConditionSplitterPosition = sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<int> &Macro::GetElseActionSplitterPosition() const
|
||||||
|
{
|
||||||
|
return _elseActionSplitterPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Macro::SetElseActionSplitterPosition(const QList<int> sizes)
|
||||||
|
{
|
||||||
|
_elseActionSplitterPosition = sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Macro::HasValidSplitterPositions() const
|
||||||
|
{
|
||||||
|
return !_actionConditionSplitterPosition.empty() &&
|
||||||
|
!_elseActionSplitterPosition.empty();
|
||||||
|
}
|
||||||
|
|
||||||
bool Macro::OnChangePreventedActionsRecently()
|
bool Macro::OnChangePreventedActionsRecently()
|
||||||
{
|
{
|
||||||
if (_onChangeTriggered) {
|
if (_onPreventedActionExecution) {
|
||||||
_onChangeTriggered = false;
|
_onPreventedActionExecution = false;
|
||||||
return true;
|
return _matched ? _actions.size() > 0 : _elseActions.size() > 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Macro::ResetUIHelpers()
|
void Macro::ResetUIHelpers()
|
||||||
{
|
{
|
||||||
_onChangeTriggered = false;
|
_onPreventedActionExecution = false;
|
||||||
for (auto c : _conditions) {
|
for (auto c : _conditions) {
|
||||||
c->Highlight();
|
c->Highlight();
|
||||||
}
|
}
|
||||||
@@ -708,7 +933,8 @@ void Macro::EnableDock(bool value)
|
|||||||
// Create new dock widget
|
// Create new dock widget
|
||||||
auto window =
|
auto window =
|
||||||
static_cast<QMainWindow *>(obs_frontend_get_main_window());
|
static_cast<QMainWindow *>(obs_frontend_get_main_window());
|
||||||
_dock = new MacroDock(this, window, _runButtonText, _pauseButtonText,
|
_dock = new MacroDock(GetWeakMacroByName(_name.c_str()), window,
|
||||||
|
_runButtonText, _pauseButtonText,
|
||||||
_unpauseButtonText, _conditionsTrueStatusText,
|
_unpauseButtonText, _conditionsTrueStatusText,
|
||||||
_conditionsFalseStatusText, _dockHighlight);
|
_conditionsFalseStatusText, _dockHighlight);
|
||||||
SetDockWidgetName(); // Used by OBS to restore position
|
SetDockWidgetName(); // Used by OBS to restore position
|
||||||
@@ -1012,7 +1238,7 @@ bool SwitcherData::CheckMacros()
|
|||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
for (auto &m : macros) {
|
for (auto &m : macros) {
|
||||||
if (m->CeckMatch()) {
|
if (m->CeckMatch() || m->ElseActions().size() > 0) {
|
||||||
ret = true;
|
ret = true;
|
||||||
// This has to be performed here for now as actions are
|
// This has to be performed here for now as actions are
|
||||||
// not performed immediately after checking conditions.
|
// not performed immediately after checking conditions.
|
||||||
@@ -1026,7 +1252,7 @@ bool SwitcherData::CheckMacros()
|
|||||||
|
|
||||||
bool SwitcherData::RunMacros()
|
bool SwitcherData::RunMacros()
|
||||||
{
|
{
|
||||||
// Create copy of macor list as elements might be removed, inserted, or
|
// Create copy of macro list as elements might be removed, inserted, or
|
||||||
// reordered while macros are currently being executed.
|
// reordered while macros are currently being executed.
|
||||||
// For example, this can happen if a macro is performing a wait action,
|
// For example, this can happen if a macro is performing a wait action,
|
||||||
// as the main lock will be unlocked during this time.
|
// as the main lock will be unlocked during this time.
|
||||||
@@ -1047,12 +1273,18 @@ bool SwitcherData::RunMacros()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto &m : runPhaseMacros) {
|
for (auto &m : runPhaseMacros) {
|
||||||
if (m && m->Matched()) {
|
if (!m || !m->ShouldRunActions()) {
|
||||||
vblog(LOG_INFO, "running macro: %s", m->Name().c_str());
|
continue;
|
||||||
if (!m->PerformActions()) {
|
}
|
||||||
blog(LOG_WARNING, "abort macro: %s",
|
if (firstInterval && m->SkipExecOnStart()) {
|
||||||
m->Name().c_str());
|
blog(LOG_INFO,
|
||||||
}
|
"skip execution of macro \"%s\" at startup",
|
||||||
|
m->Name().c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
vblog(LOG_INFO, "running macro: %s", m->Name().c_str());
|
||||||
|
if (!m->PerformActions(m->Matched())) {
|
||||||
|
blog(LOG_WARNING, "abort macro: %s", m->Name().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (GetLock()) {
|
if (GetLock()) {
|
||||||
@@ -1088,4 +1320,11 @@ std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InvalidateMacroTempVarValues()
|
||||||
|
{
|
||||||
|
for (auto &m : switcher->macros) {
|
||||||
|
m->InvalidateTempVarValues();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "macro-condition.hpp"
|
#include "macro-condition.hpp"
|
||||||
#include "macro-ref.hpp"
|
#include "macro-ref.hpp"
|
||||||
#include "variable-string.hpp"
|
#include "variable-string.hpp"
|
||||||
|
#include "temp-variable.hpp"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
@@ -25,9 +26,10 @@ public:
|
|||||||
Macro(const std::string &name = "", const bool addHotkey = false);
|
Macro(const std::string &name = "", const bool addHotkey = false);
|
||||||
virtual ~Macro();
|
virtual ~Macro();
|
||||||
bool CeckMatch();
|
bool CeckMatch();
|
||||||
bool PerformActions(bool forceParallel = false,
|
bool PerformActions(bool match, bool forceParallel = false,
|
||||||
bool ignorePause = false);
|
bool ignorePause = false);
|
||||||
bool Matched() const { return _matched; }
|
bool Matched() const { return _matched; }
|
||||||
|
bool ShouldRunActions() const;
|
||||||
int64_t MsSinceLastCheck() const;
|
int64_t MsSinceLastCheck() const;
|
||||||
std::string Name() const { return _name; }
|
std::string Name() const { return _name; }
|
||||||
void SetName(const std::string &name);
|
void SetName(const std::string &name);
|
||||||
@@ -35,8 +37,10 @@ public:
|
|||||||
bool RunInParallel() const { return _runInParallel; }
|
bool RunInParallel() const { return _runInParallel; }
|
||||||
void SetPaused(bool pause = true);
|
void SetPaused(bool pause = true);
|
||||||
bool Paused() const { return _paused; }
|
bool Paused() const { return _paused; }
|
||||||
void SetMatchOnChange(bool onChange) { _matchOnChange = onChange; }
|
void SetMatchOnChange(bool onChange);
|
||||||
bool MatchOnChange() const { return _matchOnChange; }
|
bool MatchOnChange() const { return _performActionsOnChange; }
|
||||||
|
void SetSkipExecOnStart(bool skip) { _skipExecOnStart = skip; }
|
||||||
|
bool SkipExecOnStart() const { return _skipExecOnStart; }
|
||||||
int RunCount() const { return _runCount; };
|
int RunCount() const { return _runCount; };
|
||||||
void ResetRunCount() { _runCount = 0; };
|
void ResetRunCount() { _runCount = 0; };
|
||||||
void ResetTimers();
|
void ResetTimers();
|
||||||
@@ -44,9 +48,18 @@ public:
|
|||||||
bool GetStop() const { return _stop; }
|
bool GetStop() const { return _stop; }
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
|
// Temporary variable helpers
|
||||||
|
std::vector<TempVariable> GetTempVars(MacroSegment *filter) const;
|
||||||
|
std::optional<const TempVariable>
|
||||||
|
GetTempVar(const MacroSegment *, const std::string &id) const;
|
||||||
|
void InvalidateTempVarValues() const;
|
||||||
|
|
||||||
|
// Macro segments
|
||||||
std::deque<std::shared_ptr<MacroCondition>> &Conditions();
|
std::deque<std::shared_ptr<MacroCondition>> &Conditions();
|
||||||
std::deque<std::shared_ptr<MacroAction>> &Actions();
|
std::deque<std::shared_ptr<MacroAction>> &Actions();
|
||||||
|
std::deque<std::shared_ptr<MacroAction>> &ElseActions();
|
||||||
void UpdateActionIndices();
|
void UpdateActionIndices();
|
||||||
|
void UpdateElseActionIndices();
|
||||||
void UpdateConditionIndices();
|
void UpdateConditionIndices();
|
||||||
|
|
||||||
// Group controls
|
// Group controls
|
||||||
@@ -78,6 +91,11 @@ public:
|
|||||||
bool SwitchesScene() const;
|
bool SwitchesScene() const;
|
||||||
|
|
||||||
// UI helpers
|
// UI helpers
|
||||||
|
const QList<int> &GetActionConditionSplitterPosition() const;
|
||||||
|
void SetActionConditionSplitterPosition(const QList<int>);
|
||||||
|
const QList<int> &GetElseActionSplitterPosition() const;
|
||||||
|
void SetElseActionSplitterPosition(const QList<int>);
|
||||||
|
bool HasValidSplitterPositions() const;
|
||||||
bool
|
bool
|
||||||
ExecutedSince(const std::chrono::high_resolution_clock::time_point &);
|
ExecutedSince(const std::chrono::high_resolution_clock::time_point &);
|
||||||
bool OnChangePreventedActionsRecently();
|
bool OnChangePreventedActionsRecently();
|
||||||
@@ -111,9 +129,13 @@ private:
|
|||||||
void SetupHotkeys();
|
void SetupHotkeys();
|
||||||
void ClearHotkeys() const;
|
void ClearHotkeys() const;
|
||||||
void SetHotkeysDesc() const;
|
void SetHotkeysDesc() const;
|
||||||
void RunActions(bool &ret, bool ignorePause);
|
|
||||||
void RunActions(bool ignorePause);
|
bool RunActionsHelper(
|
||||||
void SetOnChangeHighlight();
|
const std::deque<std::shared_ptr<MacroAction>> &actions,
|
||||||
|
bool ignorePause);
|
||||||
|
bool RunActions(bool ignorePause);
|
||||||
|
bool RunElseActions(bool ignorePause);
|
||||||
|
|
||||||
bool DockIsVisible() const;
|
bool DockIsVisible() const;
|
||||||
void SetDockWidgetName() const;
|
void SetDockWidgetName() const;
|
||||||
void SaveDockSettings(obs_data_t *obj) const;
|
void SaveDockSettings(obs_data_t *obj) const;
|
||||||
@@ -131,6 +153,7 @@ private:
|
|||||||
|
|
||||||
std::deque<std::shared_ptr<MacroCondition>> _conditions;
|
std::deque<std::shared_ptr<MacroCondition>> _conditions;
|
||||||
std::deque<std::shared_ptr<MacroAction>> _actions;
|
std::deque<std::shared_ptr<MacroAction>> _actions;
|
||||||
|
std::deque<std::shared_ptr<MacroAction>> _elseActions;
|
||||||
|
|
||||||
std::weak_ptr<Macro> _parent;
|
std::weak_ptr<Macro> _parent;
|
||||||
uint32_t _groupSize = 0;
|
uint32_t _groupSize = 0;
|
||||||
@@ -140,7 +163,9 @@ private:
|
|||||||
bool _runInParallel = false;
|
bool _runInParallel = false;
|
||||||
bool _matched = false;
|
bool _matched = false;
|
||||||
bool _lastMatched = false;
|
bool _lastMatched = false;
|
||||||
bool _matchOnChange = true;
|
bool _conditionSateChanged = false;
|
||||||
|
bool _performActionsOnChange = true;
|
||||||
|
bool _skipExecOnStart = false;
|
||||||
bool _paused = false;
|
bool _paused = false;
|
||||||
int _runCount = 0;
|
int _runCount = 0;
|
||||||
bool _registerHotkeys = true;
|
bool _registerHotkeys = true;
|
||||||
@@ -148,7 +173,11 @@ private:
|
|||||||
obs_hotkey_id _unpauseHotkey = OBS_INVALID_HOTKEY_ID;
|
obs_hotkey_id _unpauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||||
obs_hotkey_id _togglePauseHotkey = OBS_INVALID_HOTKEY_ID;
|
obs_hotkey_id _togglePauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||||
|
|
||||||
bool _onChangeTriggered = false;
|
// UI helpers
|
||||||
|
bool _onPreventedActionExecution = false;
|
||||||
|
|
||||||
|
QList<int> _actionConditionSplitterPosition;
|
||||||
|
QList<int> _elseActionSplitterPosition;
|
||||||
|
|
||||||
bool _registerDock = false;
|
bool _registerDock = false;
|
||||||
bool _dockHasRunButton = true;
|
bool _dockHasRunButton = true;
|
||||||
@@ -176,5 +205,6 @@ private:
|
|||||||
Macro *GetMacroByName(const char *name);
|
Macro *GetMacroByName(const char *name);
|
||||||
Macro *GetMacroByQString(const QString &name);
|
Macro *GetMacroByQString(const QString &name);
|
||||||
std::weak_ptr<Macro> GetWeakMacroByName(const char *name);
|
std::weak_ptr<Macro> GetWeakMacroByName(const char *name);
|
||||||
|
void InvalidateMacroTempVarValues();
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ if(ENABLE_OPENVR_PLUGIN)
|
|||||||
add_subdirectory(openvr)
|
add_subdirectory(openvr)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_TWITCH_PLUGIN "Enable the twitch plugin" ON)
|
||||||
|
if(ENABLE_TWITCH_PLUGIN)
|
||||||
|
add_subdirectory(twitch)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(ENABLE_VIDEO_PLUGIN "Enable the video plugin" ON)
|
option(ENABLE_VIDEO_PLUGIN "Enable the video plugin" ON)
|
||||||
if(ENABLE_VIDEO_PLUGIN)
|
if(ENABLE_VIDEO_PLUGIN)
|
||||||
add_subdirectory(video)
|
add_subdirectory(video)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ project(advanced-scene-switcher-midi)
|
|||||||
|
|
||||||
get_target_property(ADVSS_SOURCE_DIR advanced-scene-switcher-lib SOURCE_DIR)
|
get_target_property(ADVSS_SOURCE_DIR advanced-scene-switcher-lib SOURCE_DIR)
|
||||||
set(LIBREMIDI_DIR "${ADVSS_SOURCE_DIR}/deps/libremidi")
|
set(LIBREMIDI_DIR "${ADVSS_SOURCE_DIR}/deps/libremidi")
|
||||||
if(NOT EXISTS "${LIBREMIDI_DIR}")
|
if(NOT EXISTS "${LIBREMIDI_DIR}/CMakeLists.txt")
|
||||||
message(WARNING "libremidi directory \"${LIBREMIDI_DIR}\" not found!\n"
|
message(WARNING "libremidi directory \"${LIBREMIDI_DIR}\" not found!\n"
|
||||||
"MIDI support will be disabled!")
|
"MIDI support will be disabled!")
|
||||||
return()
|
return()
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace advss {
|
|||||||
static std::map<std::pair<MidiDeviceType, int>, MidiDeviceInstance *>
|
static std::map<std::pair<MidiDeviceType, int>, MidiDeviceInstance *>
|
||||||
SetupMidiMessageVector()
|
SetupMidiMessageVector()
|
||||||
{
|
{
|
||||||
GetSwitcher()->AddResetForNextIntervalFunction(
|
GetSwitcher()->AddIntervalResetStep(
|
||||||
MidiDeviceInstance::ClearMessageBuffersOfAllDevices);
|
MidiDeviceInstance::ClearMessageBuffersOfAllDevices);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -920,7 +920,6 @@ QStringList GetAllNotes()
|
|||||||
"F#", "G", "G#", "A", "A#", "B"};
|
"F#", "G", "G#", "A", "A#", "B"};
|
||||||
for (int octave = -1; octave <= 9; octave++) {
|
for (int octave = -1; octave <= 9; octave++) {
|
||||||
for (int noteIndex = 0; noteIndex < 12; noteIndex++) {
|
for (int noteIndex = 0; noteIndex < 12; noteIndex++) {
|
||||||
int midiNote = octave * 12 + noteIndex;
|
|
||||||
result << notes[noteIndex] + QString::number(octave);
|
result << notes[noteIndex] + QString::number(octave);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
90
src/macro-external/twitch/CMakeLists.txt
Normal file
90
src/macro-external/twitch/CMakeLists.txt
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
project(advanced-scene-switcher-twitch)
|
||||||
|
|
||||||
|
# --- Check requirements ---
|
||||||
|
|
||||||
|
get_target_property(ADVSS_SOURCE_DIR advanced-scene-switcher-lib SOURCE_DIR)
|
||||||
|
set(CPP_HTTPLIB_DIR "${ADVSS_SOURCE_DIR}/deps/cpp-httplib")
|
||||||
|
if(NOT EXISTS "${CPP_HTTPLIB_DIR}/CMakeLists.txt")
|
||||||
|
message(WARNING "cpp-httplib directory \"${CPP_HTTPLIB_DIR}\" not found!\n"
|
||||||
|
"Twitch support will be disabled!")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
add_subdirectory("${CPP_HTTPLIB_DIR}" "${CPP_HTTPLIB_DIR}/build"
|
||||||
|
EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
if(NOT OPENSSL_INCLUDE_DIR OR NOT OPENSSL_LIBRARIES)
|
||||||
|
find_package(OpenSSL)
|
||||||
|
if(NOT OPENSSL_FOUND)
|
||||||
|
message(WARNING "OpenSSL not found!\n"
|
||||||
|
"Twitch support will be disabled!\n\n")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(ZLIB)
|
||||||
|
|
||||||
|
# --- End of section ---
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} MODULE)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT=1
|
||||||
|
ASIO_HAS_OPENSSSL=1)
|
||||||
|
if(OS_MACOS)
|
||||||
|
target_compile_definitions(
|
||||||
|
${PROJECT_NAME} PRIVATE CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN=1)
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE "-framework CoreFoundation")
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE "-framework Security")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_sources(
|
||||||
|
${PROJECT_NAME}
|
||||||
|
PRIVATE category-selection.cpp
|
||||||
|
category-selection.hpp
|
||||||
|
channel-selection.cpp
|
||||||
|
channel-selection.hpp
|
||||||
|
chat-connection.cpp
|
||||||
|
chat-connection.hpp
|
||||||
|
event-sub.cpp
|
||||||
|
event-sub.hpp
|
||||||
|
macro-action-twitch.cpp
|
||||||
|
macro-action-twitch.hpp
|
||||||
|
macro-condition-twitch.cpp
|
||||||
|
macro-condition-twitch.hpp
|
||||||
|
points-reward-selection.cpp
|
||||||
|
points-reward-selection.hpp
|
||||||
|
token.cpp
|
||||||
|
token.hpp
|
||||||
|
twitch-helpers.cpp
|
||||||
|
twitch-helpers.hpp)
|
||||||
|
|
||||||
|
setup_advss_plugin(${PROJECT_NAME})
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE "${CPP_HTTPLIB_DIR}/"
|
||||||
|
"${OPENSSL_INCLUDE_DIR}")
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${OPENSSL_LIBRARIES} ZLIB::ZLIB)
|
||||||
|
install_advss_plugin(${PROJECT_NAME})
|
||||||
|
if(OS_WINDOWS)
|
||||||
|
# Couldn't really find a better way to install runtime dependencies for
|
||||||
|
# Windows TODO: Clean this up at some point
|
||||||
|
function(FIND_FILES_WITH_PATTERN result pattern dir)
|
||||||
|
execute_process(
|
||||||
|
COMMAND
|
||||||
|
powershell -Command
|
||||||
|
"Get-ChildItem -Path '${dir}' -Recurse -Include ${pattern} |"
|
||||||
|
"Select-Object -First 1 |"
|
||||||
|
"ForEach-Object { $_.FullName -replace '\\\\', '\\\\' }"
|
||||||
|
OUTPUT_VARIABLE files
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
set(${result}
|
||||||
|
${files}
|
||||||
|
PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
set(OPENSSL_DLL_SEARCH_DIR "${OPENSSL_INCLUDE_DIR}/..")
|
||||||
|
find_files_with_pattern(CRYPTO_DLL_FILES "libcrypto*.dll"
|
||||||
|
"${OPENSSL_DLL_SEARCH_DIR}")
|
||||||
|
find_files_with_pattern(SSL_DLL_FILES "libssl*.dll"
|
||||||
|
"${OPENSSL_DLL_SEARCH_DIR}")
|
||||||
|
install_advss_plugin_dependency(TARGET ${PROJECT_NAME} DEPENDENCIES
|
||||||
|
"${CRYPTO_DLL_FILES}" "${SSL_DLL_FILES}")
|
||||||
|
endif()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user