Compare commits
388 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ada858046 | ||
|
|
51d121bda2 | ||
|
|
a7cf5769dd | ||
|
|
63ee36ddfe | ||
|
|
43967f5ded | ||
|
|
c043053b2b | ||
|
|
220f27bd0a | ||
|
|
83914d5378 | ||
|
|
57e4b1a3f1 | ||
|
|
c85e556924 | ||
|
|
8c0be8011d | ||
|
|
7914f75876 | ||
|
|
7d1253e14e | ||
|
|
d7c58b3eb3 | ||
|
|
fb664b6f08 | ||
|
|
258a6d076e | ||
|
|
32ab060153 | ||
|
|
91d3784f9b | ||
|
|
8a5aac3d31 | ||
|
|
06c6effb7d | ||
|
|
f3789c05bd | ||
|
|
c64e1f5e51 | ||
|
|
5d8e24c19a | ||
|
|
f756de05c3 | ||
|
|
574fdb496f | ||
|
|
5580da69eb | ||
|
|
35274863c9 | ||
|
|
1f31b81f0d | ||
|
|
cde111ddeb | ||
|
|
845c12c01c | ||
|
|
99a0118d31 | ||
|
|
bb7ee17362 | ||
|
|
70854ef012 | ||
|
|
053c14056d | ||
|
|
9397d50764 | ||
|
|
473e24cc42 | ||
|
|
d9394605f4 | ||
|
|
d2b9074852 | ||
|
|
b525eb7a0e | ||
|
|
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 | ||
|
|
666c52556e | ||
|
|
1c0734d1cb | ||
|
|
1304ac7336 | ||
|
|
884fb1b637 | ||
|
|
a82bce947f | ||
|
|
d5241f0700 | ||
|
|
f24f258c9c | ||
|
|
eddd9fa8ab | ||
|
|
6cc224aeec | ||
|
|
4b0a631987 | ||
|
|
dcae0e8e8b | ||
|
|
29f810a2a0 | ||
|
|
719dfa7b72 | ||
|
|
259aac8fcd | ||
|
|
5be2cd278f | ||
|
|
211eac5313 | ||
|
|
f92ed3139d | ||
|
|
bdff84c605 | ||
|
|
08e430396a | ||
|
|
df7fc7ec01 | ||
|
|
9eef581161 | ||
|
|
52811e44f4 | ||
|
|
7b1c56877e | ||
|
|
78d73af589 | ||
|
|
d9c1ef4c22 | ||
|
|
93f96ee660 | ||
|
|
d25a8d4efb | ||
|
|
1f22278496 | ||
|
|
70b705e0fd | ||
|
|
9e1dfdc3f0 | ||
|
|
47d6d4ac06 | ||
|
|
fe3586b6f4 | ||
|
|
650881204f | ||
|
|
8c0ba112e2 | ||
|
|
a17d8f7e09 | ||
|
|
371b4ae05d | ||
|
|
1d7ce510f7 | ||
|
|
d759ded64d | ||
|
|
0b2e1b88cc | ||
|
|
72a11eedfc | ||
|
|
1f02226620 | ||
|
|
ad8c29997c | ||
|
|
2c7c40c3f0 | ||
|
|
c9c0e4db2e | ||
|
|
dd880b13c0 | ||
|
|
76c759c8f4 | ||
|
|
284c8020b2 | ||
|
|
f506600b8c | ||
|
|
339418b5f3 | ||
|
|
2eca2cc2e9 | ||
|
|
4315d309f2 | ||
|
|
8d18bb363a | ||
|
|
592f31f059 | ||
|
|
300ad15ad0 | ||
|
|
91f93169eb | ||
|
|
5d95069291 | ||
|
|
e5bb9162ef | ||
|
|
6869cc8a01 | ||
|
|
55c7ac8a32 | ||
|
|
101a85b063 | ||
|
|
e7c6afbc6a | ||
|
|
18e19fb6c8 | ||
|
|
a7ccfc3282 | ||
|
|
85eb2a4235 | ||
|
|
3e3805b542 | ||
|
|
c59acd836a | ||
|
|
1e81181312 | ||
|
|
8a796efdb3 | ||
|
|
1a07a93552 | ||
|
|
bd74629420 | ||
|
|
dabb293cc0 | ||
|
|
b6031bd29a | ||
|
|
05fa3af2ac | ||
|
|
c52166bfec | ||
|
|
6d3964fa5d | ||
|
|
65545d85ba | ||
|
|
dea4ff47cd | ||
|
|
258a5f6ab7 | ||
|
|
2048ca2816 | ||
|
|
eb9e2e8062 | ||
|
|
3229bf0150 | ||
|
|
dfa12f9807 | ||
|
|
e0917a35fd | ||
|
|
686b00ffd1 | ||
|
|
78402f6546 | ||
|
|
a1b5fbb1fe | ||
|
|
b71f633fac | ||
|
|
dbb674aa8e | ||
|
|
018daf7f09 | ||
|
|
a07a84a8b1 | ||
|
|
0f36f34a4f | ||
|
|
cf2cebd0fc | ||
|
|
90dd59abe6 | ||
|
|
5332ed6bef | ||
|
|
d45d4ded99 | ||
|
|
25b5590d2c | ||
|
|
d2b2ced5bf | ||
|
|
c551953283 | ||
|
|
5ae1f38ea8 | ||
|
|
372f12de95 | ||
|
|
9cfa88dd8c | ||
|
|
7b355ebc49 | ||
|
|
43a56c8ec8 | ||
|
|
3da90bfa97 | ||
|
|
dd572a7456 | ||
|
|
8cd818b80e | ||
|
|
530bbc07c5 | ||
|
|
a992f7a0e8 | ||
|
|
ca3718594d | ||
|
|
17a66853d5 | ||
|
|
8c317c1396 | ||
|
|
20f888b991 | ||
|
|
cd0d3862c7 | ||
|
|
443ffb7906 | ||
|
|
5967c83b03 | ||
|
|
66498a03ce | ||
|
|
9ec772f723 | ||
|
|
20eb56db2d | ||
|
|
e4d064aaa3 | ||
|
|
5602dfa09a | ||
|
|
0138b412b4 | ||
|
|
20a934c9ab | ||
|
|
09d2b397dc | ||
|
|
482a99cf15 | ||
|
|
81ac45a1d4 | ||
|
|
0b8078f3bf | ||
|
|
8b6ace902c | ||
|
|
1dead9fca5 | ||
|
|
524c4b71d7 | ||
|
|
e51318768d | ||
|
|
c821bb20d0 | ||
|
|
c6b693b4ac | ||
|
|
2c5caabab0 | ||
|
|
b7479e8342 | ||
|
|
ffca124762 | ||
|
|
9bedbf6fb8 | ||
|
|
853150e458 | ||
|
|
1ddd48e008 | ||
|
|
17d24d642e | ||
|
|
87a46684cd | ||
|
|
e4c5193945 | ||
|
|
2e969bf6dd | ||
|
|
6db26d9f7b | ||
|
|
4f02c9ec36 | ||
|
|
2fdd39fba5 | ||
|
|
fe1ddc3a94 | ||
|
|
cff2d805db | ||
|
|
34425d3e47 | ||
|
|
4ac4f00620 | ||
|
|
e30a4623c5 | ||
|
|
e2f4dcaaee | ||
|
|
ebbf64ddae | ||
|
|
8b105ad22b | ||
|
|
f3416c5b1d | ||
|
|
e194fc5ee4 | ||
|
|
e465c81bf1 | ||
|
|
9dce6a99fd | ||
|
|
6f2c53d14e | ||
|
|
9044ae4ade | ||
|
|
0a422174bc | ||
|
|
c2020fe77c | ||
|
|
8beca6fcc7 | ||
|
|
18769df2ca | ||
|
|
2806fd6cdb | ||
|
|
b607940c8c | ||
|
|
dff599df4c | ||
|
|
b3cd38e019 | ||
|
|
61975e1992 | ||
|
|
1a8ad69f23 | ||
|
|
f21e40151b | ||
|
|
4e58769648 | ||
|
|
f9d6001025 | ||
|
|
ae5f5f90ff | ||
|
|
89db21d734 | ||
|
|
0e4b072650 | ||
|
|
13b0e00b27 | ||
|
|
bf5d8ca19e | ||
|
|
4a3339c09c | ||
|
|
b28c2b28b2 | ||
|
|
fcb3e648d2 | ||
|
|
5d6f08e38f | ||
|
|
b932af1c97 | ||
|
|
8874eb2b1c | ||
|
|
dcf9816a72 | ||
|
|
c8722c9f62 | ||
|
|
a82a2ccffe | ||
|
|
0bf70e443e | ||
|
|
3d6d690583 | ||
|
|
783f76d55d | ||
|
|
1dd46fb777 | ||
|
|
22bbd3a4ca | ||
|
|
3cd4b2251f | ||
|
|
9e4b003608 | ||
|
|
e66d0bc6b8 | ||
|
|
9a4abd78ed | ||
|
|
826bee8b1e | ||
|
|
143020dc27 | ||
|
|
be23065988 | ||
|
|
2cb62eae96 | ||
|
|
76c411d1e2 | ||
|
|
16fa91c2a1 | ||
|
|
b77f8717fe | ||
|
|
59ecf43c5f | ||
|
|
1fd8546354 | ||
|
|
7cb95cb3f6 | ||
|
|
160d19d6c1 | ||
|
|
a0550ca141 | ||
|
|
ac68fc016d | ||
|
|
5170307f72 | ||
|
|
3af0e51bd2 | ||
|
|
f34d1fe081 | ||
|
|
83c72ebba5 | ||
|
|
6ca8e6b3ea | ||
|
|
ba24fc2fab | ||
|
|
7f28b22599 | ||
|
|
4345db0d2e | ||
|
|
eddc10c3e2 | ||
|
|
46eaada0c4 | ||
|
|
f8b2dea270 | ||
|
|
90ebf0e0f8 | ||
|
|
1a819c807e | ||
|
|
3220809c04 | ||
|
|
72d5255c9e | ||
|
|
5995563a80 | ||
|
|
347743d93a | ||
|
|
3c067ce723 | ||
|
|
8dd2170dfa | ||
|
|
5f3a3dd5cf | ||
|
|
8ad3563963 | ||
|
|
492128ef86 | ||
|
|
b4936274f2 | ||
|
|
64ccd5ba53 |
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
@@ -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
@@ -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
|
||||||
|
|||||||
37
.github/actions/run-tests/action.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: 'Package plugin'
|
||||||
|
description: 'Packages the plugin for specified architecture and build config.'
|
||||||
|
inputs:
|
||||||
|
target:
|
||||||
|
description: 'Build target'
|
||||||
|
required: true
|
||||||
|
workingDirectory:
|
||||||
|
description: 'Working directory'
|
||||||
|
required: false
|
||||||
|
default: ${{ github.workspace }}
|
||||||
|
runs:
|
||||||
|
using: 'composite'
|
||||||
|
steps:
|
||||||
|
- name: Run macOS tests
|
||||||
|
if: ${{ runner.os == 'macOS' }}
|
||||||
|
shell: zsh {0}
|
||||||
|
run: |
|
||||||
|
if [[ '${{ inputs.target }}' != 'x86_64' ]]; then
|
||||||
|
echo tests skipped!
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
${{ inputs.workingDirectory }}/build_x86_64/tests/advanced-scene-switcher-tests
|
||||||
|
|
||||||
|
- name: Run Linux packaging
|
||||||
|
if: ${{ runner.os == 'Linux' }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ '${{ inputs.target }}' != 'x86_64' ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
${{ inputs.workingDirectory }}/build_x86_64/tests/advanced-scene-switcher-tests
|
||||||
|
|
||||||
|
- name: Run Windows packaging
|
||||||
|
if: ${{ runner.os == 'Windows' }}
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
${{ inputs.workingDirectory }}/build_x64/tests/RelWithDebInfo/advanced-scene-switcher-tests.exe
|
||||||
5
.github/scripts/.Aptfile
vendored
@@ -7,3 +7,8 @@ package 'ninja-build', bin: 'ninja'
|
|||||||
package 'pkg-config'
|
package 'pkg-config'
|
||||||
package 'clang'
|
package 'clang'
|
||||||
package 'clang-format-13'
|
package 'clang-format-13'
|
||||||
|
package 'libxtst-dev'
|
||||||
|
package 'libxss-dev'
|
||||||
|
package 'libopencv-dev'
|
||||||
|
package 'libtesseract-dev'
|
||||||
|
package 'libprocps-dev'
|
||||||
|
|||||||
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
@@ -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 ${@}
|
||||||
55
.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,39 +174,34 @@ 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)"
|
||||||
|
|
||||||
read -r product_name product_version <<< \
|
read -r product_name product_version <<< \
|
||||||
"$(jq -r '. | {name, version} | join(" ")' ${buildspec_file})"
|
"$(jq -r '. | {name, version} | join(" ")' ${buildspec_file})"
|
||||||
|
|
||||||
local opencv_dir="${project_root}/deps/opencv"
|
if [[ "${git_tag}" =~ '^([0-9]+\.){0,2}(\*|[0-9]+)$' ]] {
|
||||||
local opencv_build_dir="${opencv_dir}/build_${target##*-}"
|
log_info "Using git tag as version identifier '${git_tag}'"
|
||||||
|
product_version="${git_tag}"
|
||||||
|
} else {
|
||||||
|
log_info "Using buildspec.json version identifier '${product_version}'"
|
||||||
|
}
|
||||||
|
|
||||||
case ${host_os} {
|
case ${host_os} {
|
||||||
macos)
|
macos)
|
||||||
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"
|
||||||
|
|
||||||
# Note: IPP must be set to OFF to avoid build failures on ARM architectures
|
|
||||||
local -a opencv_cmake_args=(
|
|
||||||
-DCMAKE_BUILD_TYPE=Release
|
|
||||||
-DBUILD_LIST=core,imgproc,objdetect
|
|
||||||
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
|
||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
|
||||||
-DWITH_IPP=OFF
|
|
||||||
)
|
|
||||||
|
|
||||||
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 --prefix ${opencv_build_dir}
|
|
||||||
popd
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
linux)
|
linux)
|
||||||
sed -i'' \
|
sed -i'' \
|
||||||
@@ -219,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)
|
||||||
@@ -236,13 +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:--}"
|
||||||
-DOpenCV_DIR="${opencv_build_dir}"
|
-DOPENSSL_INCLUDE_DIR="${openssl_include_dir}"
|
||||||
|
-DOPENSSL_LIBRARIES="${openssl_lib_dir}/libcrypto.a;${openssl_lib_dir}/libssl.a"
|
||||||
)
|
)
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|||||||
9
.github/scripts/.package.zsh
vendored
@@ -128,9 +128,18 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
|
|
||||||
local product_name
|
local product_name
|
||||||
local product_version
|
local product_version
|
||||||
|
local git_tag="$(git describe --tags)"
|
||||||
|
|
||||||
read -r product_name product_version <<< \
|
read -r product_name product_version <<< \
|
||||||
"$(jq -r '. | {name, version} | join(" ")' ${project_root}/buildspec.json)"
|
"$(jq -r '. | {name, version} | join(" ")' ${project_root}/buildspec.json)"
|
||||||
|
|
||||||
|
if [[ "${git_tag}" =~ '^([0-9]+\.){0,2}(\*|[0-9]+)$' ]] {
|
||||||
|
log_info "Using git tag as version identifier '${git_tag}'"
|
||||||
|
product_version="${git_tag}"
|
||||||
|
} else {
|
||||||
|
log_info "Using buildspec.json version identifier '${product_version}'"
|
||||||
|
}
|
||||||
|
|
||||||
if [[ ${host_os} == 'macos' ]] {
|
if [[ ${host_os} == 'macos' ]] {
|
||||||
autoload -Uz check_packages read_codesign read_codesign_installer read_codesign_pass
|
autoload -Uz check_packages read_codesign read_codesign_installer read_codesign_pass
|
||||||
|
|
||||||
|
|||||||
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
|
||||||
51
.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,
|
||||||
@@ -37,7 +38,7 @@ function Build {
|
|||||||
|
|
||||||
$UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
|
$UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
|
||||||
|
|
||||||
foreach($Utility in $UtilityFunctions) {
|
foreach ($Utility in $UtilityFunctions) {
|
||||||
Write-Debug "Loading $($Utility.FullName)"
|
Write-Debug "Loading $($Utility.FullName)"
|
||||||
. $Utility.FullName
|
. $Utility.FullName
|
||||||
}
|
}
|
||||||
@@ -57,41 +58,20 @@ function Build {
|
|||||||
$CmakeGenerator = $script:VisualStudioVersion
|
$CmakeGenerator = $script:VisualStudioVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
Push-Location -Stack BuildOpenCVTemp
|
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
|
||||||
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
$DepInstallPath = "$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
||||||
Ensure-Location $ProjectRoot
|
|
||||||
|
|
||||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
if ( $ADVSSDepName -eq '' ) {
|
||||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
Log-Information "Building advss deps ..."
|
||||||
$OpenCVCmakeArgs = @(
|
$ADVSSDepName = "advss-build-dependencies"
|
||||||
'-G', $CmakeGenerator
|
invoke-expression -Command "$PSScriptRoot/Build-Deps-Windows.ps1 -Configuration $Configuration -Target $Target -CMakeGenerator `"$CMakeGenerator`" -OutDirName $ADVSSDepName -SkipDeps -SkipUnpack"
|
||||||
"-DCMAKE_SYSTEM_VERSION=${script:PlatformSDK}"
|
|
||||||
"-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release"
|
|
||||||
"-DCMAKE_PREFIX_PATH:PATH=$(Resolve-Path -Path ${ProjectRoot}/../obs-build-dependencies/${DepsPath})"
|
|
||||||
"-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 "${OpenCVBuildPath}" @OpenCVCmakeArgs
|
Log-Information "Using advss deps at $ADVSSDepPath ..."
|
||||||
|
|
||||||
(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
|
||||||
|
|
||||||
@@ -99,18 +79,13 @@ function Build {
|
|||||||
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
if ( ! ( ( $SkipAll ) -or ( $SkipBuild ) ) ) {
|
||||||
Ensure-Location $ProjectRoot
|
Ensure-Location $ProjectRoot
|
||||||
|
|
||||||
$OpenCVPath = "${ProjectRoot}/deps/opencv"
|
|
||||||
$OpenCVBuildPath = "${OpenCVPath}/build"
|
|
||||||
|
|
||||||
$DepsPath = "plugin-deps-${script:DepsVersion}-qt${script:QtVersion}-${script:Target}"
|
|
||||||
$CmakeArgs = @(
|
$CmakeArgs = @(
|
||||||
'-G', $CmakeGenerator
|
'-G', $CmakeGenerator
|
||||||
"-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=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/${DepsPath}")"
|
"-DCMAKE_PREFIX_PATH:PATH=${DepInstallPath};${ADVSSDepPath}"
|
||||||
"-DQT_VERSION=${script:QtVersion}"
|
"-DQT_VERSION=${script:QtVersion}"
|
||||||
"-DOpenCV_DIR=${OpenCVBuildPath}"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Log-Debug "Attempting to configure OBS with CMake arguments: $($CmakeArgs | Out-String)"
|
Log-Debug "Attempting to configure OBS with CMake arguments: $($CmakeArgs | Out-String)"
|
||||||
@@ -122,7 +97,7 @@ function Build {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ( $VerbosePreference -eq 'Continue' ) {
|
if ( $VerbosePreference -eq 'Continue' ) {
|
||||||
$CmakeArgs+=('--verbose')
|
$CmakeArgs += ('--verbose')
|
||||||
}
|
}
|
||||||
|
|
||||||
Log-Information "Building ${ProductName}..."
|
Log-Information "Building ${ProductName}..."
|
||||||
|
|||||||
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
@@ -0,0 +1 @@
|
|||||||
|
.build-deps.zsh
|
||||||
1
.github/scripts/build-deps-macos.zsh
vendored
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
.build-deps.zsh
|
||||||
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 ]] {
|
||||||
|
|||||||
6
.github/scripts/utils.zsh/setup_linux
vendored
@@ -34,12 +34,6 @@ if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) {
|
|||||||
|
|
||||||
log_info 'Installing obs plugin dependencies...'
|
log_info 'Installing obs plugin dependencies...'
|
||||||
|
|
||||||
sudo apt-get install -y \
|
|
||||||
libxtst-dev \
|
|
||||||
libxss-dev \
|
|
||||||
libopencv-dev \
|
|
||||||
libprocps-dev
|
|
||||||
|
|
||||||
local -a _qt_packages=()
|
local -a _qt_packages=()
|
||||||
|
|
||||||
if (( QT_VERSION == 5 )) {
|
if (( QT_VERSION == 5 )) {
|
||||||
|
|||||||
62
.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:
|
||||||
@@ -113,7 +114,8 @@ jobs:
|
|||||||
id: ccache-cache
|
id: ccache-cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ github.workspace }}/.ccache
|
path: |
|
||||||
|
${{ github.workspace }}/.ccache
|
||||||
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-
|
||||||
@@ -142,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:
|
||||||
@@ -151,6 +160,12 @@ jobs:
|
|||||||
codesign: 'true'
|
codesign: 'true'
|
||||||
codesignIdent: ${{ env.CODESIGN_IDENT }}
|
codesignIdent: ${{ env.CODESIGN_IDENT }}
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
uses: ./plugin/.github/actions/run-tests
|
||||||
|
with:
|
||||||
|
workingDirectory: ${{ github.workspace }}/plugin
|
||||||
|
target: ${{ matrix.arch }}
|
||||||
|
|
||||||
- name: Package Plugin
|
- name: Package Plugin
|
||||||
uses: ./plugin/.github/actions/package-plugin
|
uses: ./plugin/.github/actions/package-plugin
|
||||||
with:
|
with:
|
||||||
@@ -221,7 +236,8 @@ jobs:
|
|||||||
id: ccache-cache
|
id: ccache-cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ github.workspace }}/.ccache
|
path: |
|
||||||
|
${{ github.workspace }}/.ccache
|
||||||
key: linux-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
key: linux-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
linux-${{ matrix.arch }}-ccache-plugin-
|
linux-${{ matrix.arch }}-ccache-plugin-
|
||||||
@@ -237,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:
|
||||||
@@ -245,6 +268,12 @@ jobs:
|
|||||||
config: RelWithDebInfo
|
config: RelWithDebInfo
|
||||||
portable: ${{ matrix.portable }}
|
portable: ${{ matrix.portable }}
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
uses: ./plugin/.github/actions/run-tests
|
||||||
|
with:
|
||||||
|
workingDirectory: ${{ github.workspace }}/plugin
|
||||||
|
target: ${{ matrix.arch }}
|
||||||
|
|
||||||
- name: Package Plugin
|
- name: Package Plugin
|
||||||
uses: ./plugin/.github/actions/package-plugin
|
uses: ./plugin/.github/actions/package-plugin
|
||||||
with:
|
with:
|
||||||
@@ -301,9 +330,21 @@ jobs:
|
|||||||
id: setup
|
id: setup
|
||||||
run: |
|
run: |
|
||||||
## SETUP ENVIRONMENT SCRIPT
|
## SETUP ENVIRONMENT SCRIPT
|
||||||
|
$CcacheDate = (Get-Date -Format "yyyy-M-d")
|
||||||
|
"ccacheDate=${CcacheDate}" >> $env:GITHUB_OUTPUT
|
||||||
$CommitHash = (git rev-parse HEAD)[0..8] -join ''
|
$CommitHash = (git rev-parse HEAD)[0..8] -join ''
|
||||||
"commitHash=${CommitHash}" >> $env:GITHUB_OUTPUT
|
"commitHash=${CommitHash}" >> $env:GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Restore Compilation Cache
|
||||||
|
id: ccache-cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ github.workspace }}/.ccache
|
||||||
|
key: windows-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
|
||||||
|
restore-keys: |
|
||||||
|
windows-${{ matrix.arch }}-ccache-plugin-
|
||||||
|
|
||||||
- name: Check for GitHub Labels
|
- name: Check for GitHub Labels
|
||||||
id: seekingTesters
|
id: seekingTesters
|
||||||
working-directory: ${{ github.workspace }}/plugin
|
working-directory: ${{ github.workspace }}/plugin
|
||||||
@@ -325,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:
|
||||||
@@ -333,6 +382,12 @@ jobs:
|
|||||||
config: RelWithDebInfo
|
config: RelWithDebInfo
|
||||||
visualStudio: 'Visual Studio 17 2022'
|
visualStudio: 'Visual Studio 17 2022'
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
uses: ./plugin/.github/actions/run-tests
|
||||||
|
with:
|
||||||
|
workingDirectory: ${{ github.workspace }}/plugin
|
||||||
|
target: ${{ matrix.arch }}
|
||||||
|
|
||||||
- name: Package Plugin
|
- name: Package Plugin
|
||||||
uses: ./plugin/.github/actions/package-plugin
|
uses: ./plugin/.github/actions/package-plugin
|
||||||
with:
|
with:
|
||||||
@@ -387,10 +442,11 @@ jobs:
|
|||||||
for file in ${{ github.workspace }}/**/@(*.pkg|*.exe|*.deb|*.zip); do
|
for file in ${{ github.workspace }}/**/@(*.pkg|*.exe|*.deb|*.zip); do
|
||||||
echo " ${file##*/}: $(sha256sum "${file}" | cut -d " " -f 1)" >> ${{ github.workspace }}/CHECKSUMS.txt
|
echo " ${file##*/}: $(sha256sum "${file}" | cut -d " " -f 1)" >> ${{ github.workspace }}/CHECKSUMS.txt
|
||||||
done
|
done
|
||||||
|
cat ${{ github.workspace }}/CHECKSUMS.txt
|
||||||
|
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -91,6 +91,7 @@ Thumbs.db
|
|||||||
.settings
|
.settings
|
||||||
.idea
|
.idea
|
||||||
.metadata
|
.metadata
|
||||||
|
.vscode
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
*.sublime*
|
*.sublime*
|
||||||
|
|||||||
15
.gitmodules
vendored
@@ -10,3 +10,18 @@
|
|||||||
[submodule "deps/openvr"]
|
[submodule "deps/openvr"]
|
||||||
path = deps/openvr
|
path = deps/openvr
|
||||||
url = https://github.com/ValveSoftware/openvr.git
|
url = https://github.com/ValveSoftware/openvr.git
|
||||||
|
[submodule "deps/leptonica"]
|
||||||
|
path = deps/leptonica
|
||||||
|
url = https://github.com/DanBloomberg/leptonica.git
|
||||||
|
[submodule "deps/tesseract"]
|
||||||
|
path = deps/tesseract
|
||||||
|
url = https://github.com/tesseract-ocr/tesseract.git
|
||||||
|
[submodule "deps/libremidi"]
|
||||||
|
path = deps/libremidi
|
||||||
|
url = https://github.com/jcelerier/libremidi.git
|
||||||
|
[submodule "deps/cpp-httplib"]
|
||||||
|
path = deps/cpp-httplib
|
||||||
|
url = https://github.com/yhirose/cpp-httplib.git
|
||||||
|
[submodule "deps/json"]
|
||||||
|
path = deps/json
|
||||||
|
url = https://github.com/nlohmann/json.git
|
||||||
|
|||||||
127
CMakeLists.txt
@@ -42,21 +42,20 @@ target_sources(
|
|||||||
src/general.cpp
|
src/general.cpp
|
||||||
src/hotkey.cpp
|
src/hotkey.cpp
|
||||||
src/hotkey.hpp
|
src/hotkey.hpp
|
||||||
src/hotkey.hpp
|
|
||||||
src/platform-funcs.hpp
|
src/platform-funcs.hpp
|
||||||
src/scene-group.cpp
|
|
||||||
src/scene-group.hpp
|
|
||||||
src/status-control.cpp
|
src/status-control.cpp
|
||||||
src/status-control.hpp
|
src/status-control.hpp
|
||||||
src/switcher-data-structs.cpp
|
src/switcher-data.cpp
|
||||||
src/switcher-data-structs.hpp
|
src/switcher-data.hpp
|
||||||
src/version.cpp
|
src/version.cpp
|
||||||
src/version.h)
|
src/version.h)
|
||||||
|
|
||||||
# Legacy function sources
|
# Legacy function sources
|
||||||
target_sources(
|
target_sources(
|
||||||
${LIB_NAME}
|
${LIB_NAME}
|
||||||
PRIVATE src/legacy/scene-trigger.cpp
|
PRIVATE src/legacy/scene-group.cpp
|
||||||
|
src/legacy/scene-group.hpp
|
||||||
|
src/legacy/scene-trigger.cpp
|
||||||
src/legacy/scene-trigger.hpp
|
src/legacy/scene-trigger.hpp
|
||||||
src/legacy/switch-audio.cpp
|
src/legacy/switch-audio.cpp
|
||||||
src/legacy/switch-audio.hpp
|
src/legacy/switch-audio.hpp
|
||||||
@@ -74,7 +73,6 @@ target_sources(
|
|||||||
src/legacy/switch-network.hpp
|
src/legacy/switch-network.hpp
|
||||||
src/legacy/switch-pause.cpp
|
src/legacy/switch-pause.cpp
|
||||||
src/legacy/switch-pause.hpp
|
src/legacy/switch-pause.hpp
|
||||||
src/legacy/switch-priority.cpp
|
|
||||||
src/legacy/switch-random.cpp
|
src/legacy/switch-random.cpp
|
||||||
src/legacy/switch-random.hpp
|
src/legacy/switch-random.hpp
|
||||||
src/legacy/switch-screen-region.cpp
|
src/legacy/switch-screen-region.cpp
|
||||||
@@ -95,6 +93,8 @@ target_sources(
|
|||||||
${LIB_NAME}
|
${LIB_NAME}
|
||||||
PRIVATE src/macro-core/macro-action-audio.cpp
|
PRIVATE src/macro-core/macro-action-audio.cpp
|
||||||
src/macro-core/macro-action-audio.hpp
|
src/macro-core/macro-action-audio.hpp
|
||||||
|
src/macro-core/macro-action-clipboard.cpp
|
||||||
|
src/macro-core/macro-action-clipboard.hpp
|
||||||
src/macro-core/macro-action-edit.cpp
|
src/macro-core/macro-action-edit.cpp
|
||||||
src/macro-core/macro-action-edit.hpp
|
src/macro-core/macro-action-edit.hpp
|
||||||
src/macro-core/macro-action-file.cpp
|
src/macro-core/macro-action-file.cpp
|
||||||
@@ -109,10 +109,14 @@ target_sources(
|
|||||||
src/macro-core/macro-action-macro.hpp
|
src/macro-core/macro-action-macro.hpp
|
||||||
src/macro-core/macro-action-media.cpp
|
src/macro-core/macro-action-media.cpp
|
||||||
src/macro-core/macro-action-media.hpp
|
src/macro-core/macro-action-media.hpp
|
||||||
|
src/macro-core/macro-action-osc.cpp
|
||||||
|
src/macro-core/macro-action-osc.hpp
|
||||||
src/macro-core/macro-action-plugin-state.cpp
|
src/macro-core/macro-action-plugin-state.cpp
|
||||||
src/macro-core/macro-action-plugin-state.hpp
|
src/macro-core/macro-action-plugin-state.hpp
|
||||||
src/macro-core/macro-action-profile.cpp
|
src/macro-core/macro-action-profile.cpp
|
||||||
src/macro-core/macro-action-profile.hpp
|
src/macro-core/macro-action-profile.hpp
|
||||||
|
src/macro-core/macro-action-projector.cpp
|
||||||
|
src/macro-core/macro-action-projector.hpp
|
||||||
src/macro-core/macro-action-random.cpp
|
src/macro-core/macro-action-random.cpp
|
||||||
src/macro-core/macro-action-random.hpp
|
src/macro-core/macro-action-random.hpp
|
||||||
src/macro-core/macro-action-recording.cpp
|
src/macro-core/macro-action-recording.cpp
|
||||||
@@ -123,6 +127,8 @@ target_sources(
|
|||||||
src/macro-core/macro-action-run.hpp
|
src/macro-core/macro-action-run.hpp
|
||||||
src/macro-core/macro-action-scene-collection.cpp
|
src/macro-core/macro-action-scene-collection.cpp
|
||||||
src/macro-core/macro-action-scene-collection.hpp
|
src/macro-core/macro-action-scene-collection.hpp
|
||||||
|
src/macro-core/macro-action-scene-lock.cpp
|
||||||
|
src/macro-core/macro-action-scene-lock.hpp
|
||||||
src/macro-core/macro-action-scene-order.cpp
|
src/macro-core/macro-action-scene-order.cpp
|
||||||
src/macro-core/macro-action-scene-order.hpp
|
src/macro-core/macro-action-scene-order.hpp
|
||||||
src/macro-core/macro-action-scene-switch.cpp
|
src/macro-core/macro-action-scene-switch.cpp
|
||||||
@@ -163,6 +169,8 @@ target_sources(
|
|||||||
src/macro-core/macro-condition-cursor.hpp
|
src/macro-core/macro-condition-cursor.hpp
|
||||||
src/macro-core/macro-condition-date.cpp
|
src/macro-core/macro-condition-date.cpp
|
||||||
src/macro-core/macro-condition-date.hpp
|
src/macro-core/macro-condition-date.hpp
|
||||||
|
src/macro-core/macro-condition-display.cpp
|
||||||
|
src/macro-core/macro-condition-display.hpp
|
||||||
src/macro-core/macro-condition-edit.cpp
|
src/macro-core/macro-condition-edit.cpp
|
||||||
src/macro-core/macro-condition-edit.hpp
|
src/macro-core/macro-condition-edit.hpp
|
||||||
src/macro-core/macro-condition-file.cpp
|
src/macro-core/macro-condition-file.cpp
|
||||||
@@ -189,12 +197,16 @@ target_sources(
|
|||||||
src/macro-core/macro-condition-recording.hpp
|
src/macro-core/macro-condition-recording.hpp
|
||||||
src/macro-core/macro-condition-replay-buffer.cpp
|
src/macro-core/macro-condition-replay-buffer.cpp
|
||||||
src/macro-core/macro-condition-replay-buffer.hpp
|
src/macro-core/macro-condition-replay-buffer.hpp
|
||||||
|
src/macro-core/macro-condition-run.cpp
|
||||||
|
src/macro-core/macro-condition-run.hpp
|
||||||
src/macro-core/macro-condition-scene-order.cpp
|
src/macro-core/macro-condition-scene-order.cpp
|
||||||
src/macro-core/macro-condition-scene-order.hpp
|
src/macro-core/macro-condition-scene-order.hpp
|
||||||
src/macro-core/macro-condition-scene-transform.cpp
|
src/macro-core/macro-condition-scene-transform.cpp
|
||||||
src/macro-core/macro-condition-scene-transform.hpp
|
src/macro-core/macro-condition-scene-transform.hpp
|
||||||
src/macro-core/macro-condition-scene-visibility.cpp
|
src/macro-core/macro-condition-scene-visibility.cpp
|
||||||
src/macro-core/macro-condition-scene-visibility.hpp
|
src/macro-core/macro-condition-scene-visibility.hpp
|
||||||
|
src/macro-core/macro-condition-slideshow.cpp
|
||||||
|
src/macro-core/macro-condition-slideshow.hpp
|
||||||
src/macro-core/macro-condition-scene.cpp
|
src/macro-core/macro-condition-scene.cpp
|
||||||
src/macro-core/macro-condition-scene.hpp
|
src/macro-core/macro-condition-scene.hpp
|
||||||
src/macro-core/macro-condition-source.cpp
|
src/macro-core/macro-condition-source.cpp
|
||||||
@@ -203,6 +215,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
|
||||||
@@ -217,6 +231,8 @@ target_sources(
|
|||||||
src/macro-core/macro-condition-window.hpp
|
src/macro-core/macro-condition-window.hpp
|
||||||
src/macro-core/macro-condition.cpp
|
src/macro-core/macro-condition.cpp
|
||||||
src/macro-core/macro-condition.hpp
|
src/macro-core/macro-condition.hpp
|
||||||
|
src/macro-core/macro-dock.cpp
|
||||||
|
src/macro-core/macro-dock.hpp
|
||||||
src/macro-core/macro-properties.cpp
|
src/macro-core/macro-properties.cpp
|
||||||
src/macro-core/macro-properties.hpp
|
src/macro-core/macro-properties.hpp
|
||||||
src/macro-core/macro-ref.cpp
|
src/macro-core/macro-ref.cpp
|
||||||
@@ -240,16 +256,47 @@ target_sources(
|
|||||||
src/utils/connection-manager.hpp
|
src/utils/connection-manager.hpp
|
||||||
src/utils/curl-helper.cpp
|
src/utils/curl-helper.cpp
|
||||||
src/utils/curl-helper.hpp
|
src/utils/curl-helper.hpp
|
||||||
|
src/utils/duration.cpp
|
||||||
|
src/utils/duration.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/file-selection.cpp
|
src/utils/file-selection.cpp
|
||||||
src/utils/file-selection.hpp
|
src/utils/file-selection.hpp
|
||||||
|
src/utils/filter-combo-box.cpp
|
||||||
|
src/utils/filter-combo-box.hpp
|
||||||
|
src/utils/filter-selection.cpp
|
||||||
|
src/utils/filter-selection.hpp
|
||||||
|
src/utils/macro-export-import-dialog.cpp
|
||||||
|
src/utils/macro-export-import-dialog.hpp
|
||||||
src/utils/macro-list.cpp
|
src/utils/macro-list.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.hpp
|
||||||
|
src/utils/math-helpers.cpp
|
||||||
|
src/utils/math-helpers.hpp
|
||||||
|
src/utils/mouse-wheel-guard.cpp
|
||||||
|
src/utils/mouse-wheel-guard.hpp
|
||||||
src/utils/name-dialog.cpp
|
src/utils/name-dialog.cpp
|
||||||
src/utils/name-dialog.hpp
|
src/utils/name-dialog.hpp
|
||||||
|
src/utils/non-modal-dialog.cpp
|
||||||
|
src/utils/non-modal-dialog.hpp
|
||||||
|
src/utils/obs-dock.hpp
|
||||||
|
src/utils/obs-module-helper.cpp
|
||||||
|
src/utils/obs-module-helper.hpp
|
||||||
|
src/utils/osc-helpers.cpp
|
||||||
|
src/utils/osc-helpers.hpp
|
||||||
|
src/utils/plugin-state-helper.cpp
|
||||||
|
src/utils/plugin-state-helper.hpp
|
||||||
|
src/utils/priority-helper.cpp
|
||||||
|
src/utils/priority-helper.hpp
|
||||||
|
src/utils/process-config.cpp
|
||||||
|
src/utils/process-config.hpp
|
||||||
src/utils/regex-config.cpp
|
src/utils/regex-config.cpp
|
||||||
src/utils/regex-config.hpp
|
src/utils/regex-config.hpp
|
||||||
src/utils/resizing-text-edit.cpp
|
src/utils/resizing-text-edit.cpp
|
||||||
@@ -258,6 +305,8 @@ target_sources(
|
|||||||
src/utils/scene-item-selection.hpp
|
src/utils/scene-item-selection.hpp
|
||||||
src/utils/scene-selection.cpp
|
src/utils/scene-selection.cpp
|
||||||
src/utils/scene-selection.hpp
|
src/utils/scene-selection.hpp
|
||||||
|
src/utils/scene-switch-helpers.cpp
|
||||||
|
src/utils/scene-switch-helpers.hpp
|
||||||
src/utils/screenshot-helper.cpp
|
src/utils/screenshot-helper.cpp
|
||||||
src/utils/screenshot-helper.hpp
|
src/utils/screenshot-helper.hpp
|
||||||
src/utils/section.cpp
|
src/utils/section.cpp
|
||||||
@@ -266,12 +315,32 @@ 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.hpp
|
||||||
|
src/utils/striped-frame.cpp
|
||||||
|
src/utils/striped-frame.hpp
|
||||||
|
src/utils/switch-button.cpp
|
||||||
|
src/utils/switch-button.hpp
|
||||||
|
src/utils/sync-helper.cpp
|
||||||
|
src/utils/sync-helper.hpp
|
||||||
|
src/utils/temp-variable.cpp
|
||||||
|
src/utils/temp-variable.hpp
|
||||||
src/utils/transition-selection.cpp
|
src/utils/transition-selection.cpp
|
||||||
src/utils/transition-selection.hpp
|
src/utils/transition-selection.hpp
|
||||||
src/utils/utility.cpp
|
src/utils/utility.cpp
|
||||||
src/utils/utility.hpp
|
src/utils/utility.hpp
|
||||||
src/utils/variable.cpp
|
src/utils/variable.cpp
|
||||||
src/utils/variable.hpp
|
src/utils/variable.hpp
|
||||||
|
src/utils/variable-line-edit.cpp
|
||||||
|
src/utils/variable-line-edit.hpp
|
||||||
|
src/utils/variable-number.tpp
|
||||||
|
src/utils/variable-number.hpp
|
||||||
|
src/utils/variable-spinbox.cpp
|
||||||
|
src/utils/variable-spinbox.hpp
|
||||||
|
src/utils/variable-string.cpp
|
||||||
|
src/utils/variable-string.hpp
|
||||||
src/utils/variable-text-edit.cpp
|
src/utils/variable-text-edit.cpp
|
||||||
src/utils/variable-text-edit.hpp
|
src/utils/variable-text-edit.hpp
|
||||||
src/utils/volume-control.cpp
|
src/utils/volume-control.cpp
|
||||||
@@ -318,7 +387,16 @@ target_include_directories(
|
|||||||
${LIB_NAME}
|
${LIB_NAME}
|
||||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
|
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib")
|
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/deps/exprtk")
|
||||||
|
|
||||||
|
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 ---
|
||||||
|
|
||||||
@@ -329,7 +407,8 @@ if(OS_WINDOWS)
|
|||||||
|
|
||||||
target_compile_definitions(${LIB_NAME} PRIVATE UNICODE _UNICODE)
|
target_compile_definitions(${LIB_NAME} PRIVATE UNICODE _UNICODE)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267)
|
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267
|
||||||
|
/bigobj)
|
||||||
endif()
|
endif()
|
||||||
target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp)
|
target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp)
|
||||||
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
||||||
@@ -385,27 +464,24 @@ else()
|
|||||||
|
|
||||||
find_path(PROCPS_INCLUDE_DIR NAMES proc/procps.h)
|
find_path(PROCPS_INCLUDE_DIR NAMES proc/procps.h)
|
||||||
find_path(PROCPS2_INCLUDE_DIR NAMES libproc2/pids.h)
|
find_path(PROCPS2_INCLUDE_DIR NAMES libproc2/pids.h)
|
||||||
find_library(PROCPS_LIBRARY NAMES procps)
|
if(PROCPS_INCLUDE_DIR)
|
||||||
find_library(PROCPS2_LIBRARY NAMES proc2)
|
|
||||||
if(PROCPS_INCLUDE_DIR AND PROCPS_LIBRARY)
|
|
||||||
message(STATUS "${PROJECT_NAME} using procps")
|
message(STATUS "${PROJECT_NAME} using procps")
|
||||||
set(PROC_INCLUDE_DIR "${PROCPS_INCLUDE_DIR}")
|
set(PROC_INCLUDE_DIR "${PROCPS_INCLUDE_DIR}")
|
||||||
set(PROC_LIBRARY "${PROCPS_LIBRARY}")
|
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS_AVAILABLE)
|
||||||
target_compile_definitions(${LIB_NAME} PRIVATE USE_PROCPS)
|
set(PROCESS_CONDITION_SUPPORTED 1)
|
||||||
elseif(PROCPS2_INCLUDE_DIR AND PROCPS2_LIBRARY)
|
endif()
|
||||||
|
if(PROCPS2_INCLUDE_DIR)
|
||||||
message(STATUS "${PROJECT_NAME} using libproc2")
|
message(STATUS "${PROJECT_NAME} using libproc2")
|
||||||
set(PROC_INCLUDE_DIR "${PROCPS2_INCLUDE_DIR}")
|
set(PROC_INCLUDE_DIR "${PROCPS2_INCLUDE_DIR}")
|
||||||
set(PROC_LIBRARY "${PROCPS2_LIBRARY}")
|
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS2_AVAILABLE)
|
||||||
else()
|
set(PROCESS_CONDITION_SUPPORTED 1)
|
||||||
message(
|
endif()
|
||||||
FATAL_ERROR
|
if(NOT DEFINED PROCESS_CONDITION_SUPPORTED)
|
||||||
"found neither procps nor libproc2!
|
message(
|
||||||
please either set ...
|
WARNING
|
||||||
PROCPS_INCLUDE_DIR and PROCPS_LIBRARY
|
"found neither procps nor libproc2! Process condition will not be functional!"
|
||||||
... or ...
|
)
|
||||||
PROCPS2_INCLUDE_DIR and PROCPS2_LIBRARY")
|
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(${LIB_NAME} PRIVATE "${PROC_LIBRARY}")
|
|
||||||
target_include_directories(${LIB_NAME} PRIVATE "${PROC_INCLUDE_DIR}")
|
target_include_directories(${LIB_NAME} PRIVATE "${PROC_INCLUDE_DIR}")
|
||||||
|
|
||||||
find_package(CURL)
|
find_package(CURL)
|
||||||
@@ -446,3 +522,4 @@ endif()
|
|||||||
# --- End of section ---
|
# --- End of section ---
|
||||||
|
|
||||||
add_subdirectory(src/macro-external)
|
add_subdirectory(src/macro-external)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ DirExistsWarning=no
|
|||||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
[Files]
|
[Files]
|
||||||
Source: "..\release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
Source: "..\release\*"; Excludes: "*.zip"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
Source: "..\LICENSE"; Flags: dontcopy
|
Source: "..\LICENSE"; Flags: dontcopy
|
||||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
|
||||||
|
|||||||
@@ -146,18 +146,12 @@ 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.line2="{{matchText}}"
|
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{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"
|
||||||
@@ -219,14 +213,13 @@ AdvSceneSwitcher.condition.stream.state.start="Stream läuft"
|
|||||||
AdvSceneSwitcher.condition.stream.state.stop="Stream gestoppt"
|
AdvSceneSwitcher.condition.stream.state.stop="Stream gestoppt"
|
||||||
AdvSceneSwitcher.condition.stream.state.starting="Stream wird gestartet"
|
AdvSceneSwitcher.condition.stream.state.starting="Stream wird gestartet"
|
||||||
AdvSceneSwitcher.condition.stream.state.stopping="Stream wird gestoppt"
|
AdvSceneSwitcher.condition.stream.state.stopping="Stream wird gestoppt"
|
||||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||||
AdvSceneSwitcher.condition.record="Aufnahme"
|
AdvSceneSwitcher.condition.record="Aufnahme"
|
||||||
AdvSceneSwitcher.condition.record.state.start="Aufnahme läuft"
|
AdvSceneSwitcher.condition.record.state.start="Aufnahme läuft"
|
||||||
AdvSceneSwitcher.condition.record.state.pause="Aufnahme pausiert"
|
AdvSceneSwitcher.condition.record.state.pause="Aufnahme pausiert"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Aufnahme gestoppt"
|
AdvSceneSwitcher.condition.record.state.stop="Aufnahme gestoppt"
|
||||||
AdvSceneSwitcher.condition.record.entry="{{recordState}}"
|
|
||||||
AdvSceneSwitcher.condition.process="Prozess"
|
AdvSceneSwitcher.condition.process="Prozess"
|
||||||
AdvSceneSwitcher.condition.process.entry="{{processes}} läuft {{focused}} und ist fokusiert"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}läuft{{focused}}und ist fokusiert"
|
||||||
AdvSceneSwitcher.condition.process.entry.focus="Aktueller Vordergrundprozess: {{focusProcess}}"
|
AdvSceneSwitcher.condition.process.entry.focus="Aktueller Vordergrundprozess: {{focusProcess}}"
|
||||||
AdvSceneSwitcher.condition.idle="Leerlauf"
|
AdvSceneSwitcher.condition.idle="Leerlauf"
|
||||||
AdvSceneSwitcher.condition.idle.entry="Keine Tastatur- oder Mauseingaben für {{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="Keine Tastatur- oder Mauseingaben für {{duration}}"
|
||||||
@@ -328,7 +321,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 +387,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"
|
||||||
@@ -428,7 +422,7 @@ AdvSceneSwitcher.action.recording.type.unpause="Aufnahme nicht mehr pausieren"
|
|||||||
AdvSceneSwitcher.action.recording.type.split="Aufnahme-Datei teilen"
|
AdvSceneSwitcher.action.recording.type.split="Aufnahme-Datei teilen"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Bitte beachten, dass je nach Aufnahmeeinstellung die Aufnahme möglicherweise nicht unterbrochen werden kann"
|
AdvSceneSwitcher.action.recording.pause.hint="Bitte beachten, dass je nach Aufnahmeeinstellung die Aufnahme möglicherweise nicht unterbrochen werden kann"
|
||||||
AdvSceneSwitcher.action.recording.split.hint="Vergewissern, dass die automatische Dateiaufteilung in den OBS-Einstellungen aktiviert ist!"
|
AdvSceneSwitcher.action.recording.split.hint="Vergewissern, dass die automatische Dateiaufteilung in den OBS-Einstellungen aktiviert ist!"
|
||||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Replay Buffer"
|
AdvSceneSwitcher.action.replay="Replay Buffer"
|
||||||
AdvSceneSwitcher.action.replay.saveWarn="Warnung: Ein zu häufiges Speichern kann dazu führen, dass der Replay Buffer nicht gespeichert wird!"
|
AdvSceneSwitcher.action.replay.saveWarn="Warnung: Ein zu häufiges Speichern kann dazu führen, dass der Replay Buffer nicht gespeichert wird!"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Replay Buffer stoppen"
|
AdvSceneSwitcher.action.replay.type.stop="Replay Buffer stoppen"
|
||||||
@@ -438,20 +432,15 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
|||||||
AdvSceneSwitcher.action.streaming="Stream"
|
AdvSceneSwitcher.action.streaming="Stream"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Stream stoppen"
|
AdvSceneSwitcher.action.streaming.type.stop="Stream stoppen"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Stream starten"
|
AdvSceneSwitcher.action.streaming.type.start="Stream starten"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
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"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Umschalten"
|
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Umschalten"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Quelle"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Quelle"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Beliebig"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Beliebig"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.entry="Auf{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="Auf{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filter"
|
AdvSceneSwitcher.action.filter="Filter"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Aktivieren"
|
AdvSceneSwitcher.action.filter.type.enable="Aktivieren"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Deaktivieren"
|
AdvSceneSwitcher.action.filter.type.disable="Deaktivieren"
|
||||||
@@ -466,7 +455,7 @@ AdvSceneSwitcher.action.source.type.refreshSettings="Aktualisieren der Quellenei
|
|||||||
AdvSceneSwitcher.action.source.type.pressSettingsButton="Drücken der Einstellungstaste"
|
AdvSceneSwitcher.action.source.type.pressSettingsButton="Drücken der Einstellungstaste"
|
||||||
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="Kann verwendet werden, um Browser-, Medien- usw. Quellen zu aktualisieren"
|
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="Kann verwendet werden, um Browser-, Medien- usw. Quellen zu aktualisieren"
|
||||||
AdvSceneSwitcher.action.source.noSettingsButtons="Keine Buttons gefunden!"
|
AdvSceneSwitcher.action.source.noSettingsButtons="Keine Buttons gefunden!"
|
||||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||||
AdvSceneSwitcher.action.source.warning="Warnung: Das globale Aktivieren und Deaktivieren von Quellen kann nicht über die OBS-Benutzeroberfläche gesteuert werden"
|
AdvSceneSwitcher.action.source.warning="Warnung: Das globale Aktivieren und Deaktivieren von Quellen kann nicht über die OBS-Benutzeroberfläche gesteuert werden"
|
||||||
AdvSceneSwitcher.action.source.getSettings="Aktuelle Einstellungen abfragen"
|
AdvSceneSwitcher.action.source.getSettings="Aktuelle Einstellungen abfragen"
|
||||||
AdvSceneSwitcher.action.media="Medien"
|
AdvSceneSwitcher.action.media="Medien"
|
||||||
@@ -476,15 +465,14 @@ 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"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Zähler zurücksetzen"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Zähler zurücksetzen"
|
||||||
AdvSceneSwitcher.action.macro.type.run="Aktionen ausführen"
|
AdvSceneSwitcher.action.macro.type.run="Aktionen ausführen"
|
||||||
AdvSceneSwitcher.action.macro.type.stop="Aktionen stoppen"
|
AdvSceneSwitcher.action.macro.type.stop="Aktionen stoppen"
|
||||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||||
AdvSceneSwitcher.action.pluginState="Plugin-Status"
|
AdvSceneSwitcher.action.pluginState="Plugin-Status"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Erweiterten Automatischen Szenenwechsler stoppen"
|
AdvSceneSwitcher.action.pluginState.type.stop="Erweiterten Automatischen Szenenwechsler stoppen"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Ändern des Nichtübereinstimmungsverhaltens:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Ändern des Nichtübereinstimmungsverhaltens:"
|
||||||
@@ -506,7 +494,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}} Millisekunden"
|
|
||||||
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"
|
||||||
@@ -516,7 +503,7 @@ AdvSceneSwitcher.action.sceneOrder.type.movePosition="An Position verschieben"
|
|||||||
AdvSceneSwitcher.action.sceneOrder.entry="Auf{{scenes}}{{actions}}{{sources}}{{position}}"
|
AdvSceneSwitcher.action.sceneOrder.entry="Auf{{scenes}}{{actions}}{{sources}}{{position}}"
|
||||||
AdvSceneSwitcher.action.sceneTransform="Szenenelement transformieren"
|
AdvSceneSwitcher.action.sceneTransform="Szenenelement transformieren"
|
||||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Transformation erhalten"
|
AdvSceneSwitcher.action.sceneTransform.getTransform="Transformation erhalten"
|
||||||
AdvSceneSwitcher.action.sceneTransform.entry="Auf{{scenes}}transformieren{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="Auf{{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.file="Datei"
|
AdvSceneSwitcher.action.file="Datei"
|
||||||
AdvSceneSwitcher.action.file.type.write="Schreiben"
|
AdvSceneSwitcher.action.file.type.write="Schreiben"
|
||||||
AdvSceneSwitcher.action.file.type.append="Anhängen"
|
AdvSceneSwitcher.action.file.type.append="Anhängen"
|
||||||
@@ -545,7 +532,6 @@ AdvSceneSwitcher.action.random="Zufall"
|
|||||||
AdvSceneSwitcher.action.random.allowRepeat="Aufeinanderfolgende Ausführung desselben Makros zulassen"
|
AdvSceneSwitcher.action.random.allowRepeat="Aufeinanderfolgende Ausführung desselben Makros zulassen"
|
||||||
AdvSceneSwitcher.action.random.entry="Zufällige Ausführung eines der folgenden Makros (pausierte Makros werden ignoriert)"
|
AdvSceneSwitcher.action.random.entry="Zufällige Ausführung eines der folgenden Makros (pausierte Makros werden ignoriert)"
|
||||||
AdvSceneSwitcher.action.systray="Benachrichtigung im System-Tray"
|
AdvSceneSwitcher.action.systray="Benachrichtigung im System-Tray"
|
||||||
AdvSceneSwitcher.action.systray.entry="Benachrichtigung anzeigen: {{message}}"
|
|
||||||
AdvSceneSwitcher.action.screenshot="Screenshot"
|
AdvSceneSwitcher.action.screenshot="Screenshot"
|
||||||
AdvSceneSwitcher.action.screenshot.save.default="Standard"
|
AdvSceneSwitcher.action.screenshot.save.default="Standard"
|
||||||
AdvSceneSwitcher.action.screenshot.save.custom="Benutzerdefiniert"
|
AdvSceneSwitcher.action.screenshot.save.custom="Benutzerdefiniert"
|
||||||
@@ -568,8 +554,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"
|
||||||
@@ -587,7 +571,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}}"
|
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}"
|
||||||
|
|
||||||
|
|
||||||
; Transition Tab
|
; Transition Tab
|
||||||
@@ -647,7 +631,7 @@ AdvSceneSwitcher.mediaTab.states.none="Keine Auswahl"
|
|||||||
AdvSceneSwitcher.mediaTab.states.playing="Abspielen"
|
AdvSceneSwitcher.mediaTab.states.playing="Abspielen"
|
||||||
AdvSceneSwitcher.mediaTab.states.opening="Öffnen"
|
AdvSceneSwitcher.mediaTab.states.opening="Öffnen"
|
||||||
AdvSceneSwitcher.mediaTab.states.buffering="Buffern"
|
AdvSceneSwitcher.mediaTab.states.buffering="Buffern"
|
||||||
AdvSceneSwitcher.mediaTab.states.Paused="Pausiert"
|
AdvSceneSwitcher.mediaTab.states.paused="Pausiert"
|
||||||
AdvSceneSwitcher.mediaTab.states.stopped="Gestoppt"
|
AdvSceneSwitcher.mediaTab.states.stopped="Gestoppt"
|
||||||
AdvSceneSwitcher.mediaTab.states.ended="Beendet"
|
AdvSceneSwitcher.mediaTab.states.ended="Beendet"
|
||||||
AdvSceneSwitcher.mediaTab.states.error="Fehler"
|
AdvSceneSwitcher.mediaTab.states.error="Fehler"
|
||||||
@@ -725,7 +709,7 @@ AdvSceneSwitcher.sceneSequenceTab.loadFail="Laden der Einstellungen ist fehlgesc
|
|||||||
AdvSceneSwitcher.sceneSequenceTab.loadSuccess="Laden der Einstellungen war erfolgreich!"
|
AdvSceneSwitcher.sceneSequenceTab.loadSuccess="Laden der Einstellungen war erfolgreich!"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.fileType="Text Dateien (*.txt)"
|
AdvSceneSwitcher.sceneSequenceTab.fileType="Text Dateien (*.txt)"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.interruptible="kann unterbrochen werden"
|
AdvSceneSwitcher.sceneSequenceTab.interruptible="kann unterbrochen werden"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.interruptibleHint="Andere Szenenwechselmethoden können diese Sequenz unterbrechen"
|
AdvSceneSwitcher.sceneSequenceTab.interruptibleHint="Andere Szenenwechselmethoden können diese Sequenz unterbrechen"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.entry="Wenn {{startScenes}} aktiv ist wechsle zu {{scenes}} nach {{delay}} mit {{transitions}} {{interruptible}}"
|
AdvSceneSwitcher.sceneSequenceTab.entry="Wenn {{startScenes}} aktiv ist wechsle zu {{scenes}} nach {{delay}} mit {{transitions}} {{interruptible}}"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.extendEdit="Szenenfolge erweitern"
|
AdvSceneSwitcher.sceneSequenceTab.extendEdit="Szenenfolge erweitern"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.extendEntry="Nach {{delay}} wechsle zu {{scenes}} mit {{transitions}}"
|
AdvSceneSwitcher.sceneSequenceTab.extendEntry="Nach {{delay}} wechsle zu {{scenes}} mit {{transitions}}"
|
||||||
|
|||||||
@@ -41,17 +41,17 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Exportar los a
|
|||||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Importar los ajustes para Advanced Scene Switcher ..."
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Importar los ajustes para Advanced Scene Switcher ..."
|
||||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Archivos de texto (*.txt)"
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Archivos de texto (*.txt)"
|
||||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="La importacion la configuracion de escenas fallo"
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="La importacion la configuracion de escenas fallo"
|
||||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Configuración de escenas importada correctamente"
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Configuración de escenas importada correctamente"
|
||||||
AdvSceneSwitcher.generalTab.priority.fileContent="Contenido del archivo"
|
AdvSceneSwitcher.generalTab.priority.fileContent="Contenido del archivo"
|
||||||
AdvSceneSwitcher.generalTab.priority.sceneSequence="Secuencia de escenas"
|
AdvSceneSwitcher.generalTab.priority.sceneSequence="Secuencia de escenas"
|
||||||
AdvSceneSwitcher.generalTab.priority.idleDetection="Detección de inactivos"
|
AdvSceneSwitcher.generalTab.priority.idleDetection="Detección de inactivos"
|
||||||
AdvSceneSwitcher.generalTab.priority.executable="Ejecutable"
|
AdvSceneSwitcher.generalTab.priority.executable="Ejecutable"
|
||||||
AdvSceneSwitcher.generalTab.priority.screenRegion="Región de pantalla"
|
AdvSceneSwitcher.generalTab.priority.screenRegion="Región de pantalla"
|
||||||
AdvSceneSwitcher.generalTab.priority.windowTitle="Título de la ventana"
|
AdvSceneSwitcher.generalTab.priority.windowTitle="Título de la ventana"
|
||||||
AdvSceneSwitcher.generalTab.priority.media="Medios"
|
AdvSceneSwitcher.generalTab.priority.media="Medios"
|
||||||
AdvSceneSwitcher.generalTab.priority.time="Tiempo"
|
AdvSceneSwitcher.generalTab.priority.time="Tiempo"
|
||||||
AdvSceneSwitcher.generalTab.priority.audio="Audio"
|
AdvSceneSwitcher.generalTab.priority.audio="Audio"
|
||||||
AdvSceneSwitcher.generalTab.priority.video="Video"
|
AdvSceneSwitcher.generalTab.priority.video="Video"
|
||||||
AdvSceneSwitcher.generalTab.priority.macro="Macro"
|
AdvSceneSwitcher.generalTab.priority.macro="Macro"
|
||||||
AdvSceneSwitcher.generalTab.setTransitionBy="Al cambiar las transiciones:"
|
AdvSceneSwitcher.generalTab.setTransitionBy="Al cambiar las transiciones:"
|
||||||
AdvSceneSwitcher.generalTab.transitionOverride="Establecer anulaciones de transición"
|
AdvSceneSwitcher.generalTab.transitionOverride="Establecer anulaciones de transición"
|
||||||
@@ -61,38 +61,38 @@ AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="Al menos una opci
|
|||||||
; Macro Tab
|
; Macro Tab
|
||||||
AdvSceneSwitcher.macroTab.title="Macro"
|
AdvSceneSwitcher.macroTab.title="Macro"
|
||||||
AdvSceneSwitcher.macroTab.macros="Macros"
|
AdvSceneSwitcher.macroTab.macros="Macros"
|
||||||
AdvSceneSwitcher.macroTab.priorityWarning="Nota: Se recomienda configurar las macros para que sean la funcionalidad de máxima prioridad.\nEsta configuración se puede cambiar en la ficha General."
|
AdvSceneSwitcher.macroTab.priorityWarning="Nota: Se recomienda configurar las macros para que sean la funcionalidad de máxima prioridad.\nEsta configuración se puede cambiar en la ficha General."
|
||||||
AdvSceneSwitcher.macroTab.help="Las macros le permiten ejecutar una cadena de acciones en función de varias condiciones.\n\nHaga clic en el símbolo más resaltado para agregar una nueva macro."
|
AdvSceneSwitcher.macroTab.help="Las macros le permiten ejecutar una cadena de acciones en función de varias condiciones.\n\nHaga clic en el símbolo más resaltado para agregar una nueva macro."
|
||||||
AdvSceneSwitcher.macroTab.editConditionHelp="Esta sección le permite definir las condiciones de la macro.\n\nSeleccione una macro existente o agregue una nueva a la izquierda.\nLuego haga clic en el botón más a continuación para agregar una nueva condición."
|
AdvSceneSwitcher.macroTab.editConditionHelp="Esta sección le permite definir las condiciones de la macro.\n\nSeleccione una macro existente o agregue una nueva a la izquierda.\nLuego haga clic en el botón más a continuación para agregar una nueva condición."
|
||||||
AdvSceneSwitcher.macroTab.editActionHelp="Esta sección le permite definir acciones de la macro.\n\nSeleccione una macro existente o agregue una nueva a la izquierda.\nLuego haga clic en el botón más a continuación para agregar una nueva acción"
|
AdvSceneSwitcher.macroTab.editActionHelp="Esta sección le permite definir acciones de la macro.\n\nSeleccione una macro existente o agregue una nueva a la izquierda.\nLuego haga clic en el botón más a continuación para agregar una nueva acción"
|
||||||
AdvSceneSwitcher.macroTab.edit="Editar macro"
|
AdvSceneSwitcher.macroTab.edit="Editar macro"
|
||||||
AdvSceneSwitcher.macroTab.edit.logic="Tipo de lógica:"
|
AdvSceneSwitcher.macroTab.edit.logic="Tipo de lógica:"
|
||||||
AdvSceneSwitcher.macroTab.edit.condition="Tipo de condición:"
|
AdvSceneSwitcher.macroTab.edit.condition="Tipo de condición:"
|
||||||
AdvSceneSwitcher.macroTab.edit.action="Tipo de acción:"
|
AdvSceneSwitcher.macroTab.edit.action="Tipo de acción:"
|
||||||
AdvSceneSwitcher.macroTab.add="Agregar nueva macro"
|
AdvSceneSwitcher.macroTab.add="Agregar nueva macro"
|
||||||
AdvSceneSwitcher.macroTab.name="Nombre:"
|
AdvSceneSwitcher.macroTab.name="Nombre:"
|
||||||
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
||||||
AdvSceneSwitcher.macroTab.runFail="Error al ejecutar \"%1\" si se ha producido un error en una de las acciones o si la macro ya se está ejecutando."
|
AdvSceneSwitcher.macroTab.runFail="Error al ejecutar \"%1\" si se ha producido un error en una de las acciones o si la macro ya se está ejecutando."
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
||||||
AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición"
|
AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="El nombre de la macro ya existe"
|
AdvSceneSwitcher.macroTab.exists="El nombre de la macro ya existe"
|
||||||
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
||||||
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
||||||
AdvSceneSwitcher.macroTab.collapseAll="Contraer todo"
|
AdvSceneSwitcher.macroTab.collapseAll="Contraer todo"
|
||||||
AdvSceneSwitcher.macroTab.maximize="Maximizar"
|
AdvSceneSwitcher.macroTab.maximize="Maximizar"
|
||||||
AdvSceneSwitcher.macroTab.minimize="Minimizar"
|
AdvSceneSwitcher.macroTab.minimize="Minimizar"
|
||||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Resaltar macros ejecutadas recientemente"
|
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Resaltar macros ejecutadas recientemente"
|
||||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="Resaltar condiciones de la macro seleccionada, que se evaluaron como verdaderas recientemente"
|
AdvSceneSwitcher.macroTab.highlightTrueConditions="Resaltar condiciones de la macro seleccionada, que se evaluaron como verdaderas recientemente"
|
||||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
|
AdvSceneSwitcher.macroTab.highlightPerformedActions="Resaltar acciones realizadas recientemente de la macro seleccionada actualmente"
|
||||||
|
|
||||||
; Lógica de macros
|
; Lógica de macros
|
||||||
AdvSceneSwitcher.logic.none="Omitir entrada"
|
AdvSceneSwitcher.logic.none="Omitir entrada"
|
||||||
AdvSceneSwitcher.logic.and="Y"
|
AdvSceneSwitcher.logic.and="Y"
|
||||||
AdvSceneSwitcher.logic.or="O"
|
AdvSceneSwitcher.logic.or="O"
|
||||||
AdvSceneSwitcher.logic.andNot="Y no"
|
AdvSceneSwitcher.logic.andNot="Y no"
|
||||||
AdvSceneSwitcher.logic.orNot="O no"
|
AdvSceneSwitcher.logic.orNot="O no"
|
||||||
AdvSceneSwitcher.logic.rootNone="Si"
|
AdvSceneSwitcher.logic.rootNone="Si"
|
||||||
AdvSceneSwitcher.logic.not="Si no"
|
AdvSceneSwitcher.logic.not="Si no"
|
||||||
|
|
||||||
; Macro Conditions
|
; Macro Conditions
|
||||||
@@ -122,12 +122,7 @@ 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.line2="{{matchText}}"
|
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{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"
|
||||||
@@ -179,14 +174,13 @@ AdvSceneSwitcher.condition.stream.state.start="Transmisión en ejecución"
|
|||||||
AdvSceneSwitcher.condition.stream.state.stop="Transmisión detenida"
|
AdvSceneSwitcher.condition.stream.state.stop="Transmisión detenida"
|
||||||
AdvSceneSwitcher.condition.stream.state.starting="Inicio de transmisión"
|
AdvSceneSwitcher.condition.stream.state.starting="Inicio de transmisión"
|
||||||
AdvSceneSwitcher.condition.stream.state.stopping="Detener transmisión"
|
AdvSceneSwitcher.condition.stream.state.stopping="Detener transmisión"
|
||||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||||
AdvSceneSwitcher.condition.record="Grabación"
|
AdvSceneSwitcher.condition.record="Grabación"
|
||||||
AdvSceneSwitcher.condition.record.state.start="Grabación en ejecución"
|
AdvSceneSwitcher.condition.record.state.start="Grabación en ejecución"
|
||||||
AdvSceneSwitcher.condition.record.state.pause="Grabación en pausa"
|
AdvSceneSwitcher.condition.record.state.pause="Grabación en pausa"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Grabación detenida"
|
AdvSceneSwitcher.condition.record.state.stop="Grabación detenida"
|
||||||
AdvSceneSwitcher.condition.record.entry="{{recordState}}"
|
|
||||||
AdvSceneSwitcher.condition.process="Proceso"
|
AdvSceneSwitcher.condition.process="Proceso"
|
||||||
AdvSceneSwitcher.condition.process.entry="{{processes}} se está ejecutando {{focused}} y está enfocado"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}se está ejecutando{{focused}}y está enfocado"
|
||||||
AdvSceneSwitcher.condition.idle="Inactivo"
|
AdvSceneSwitcher.condition.idle="Inactivo"
|
||||||
AdvSceneSwitcher.condition.idle.entry="No hay entradas de teclado o ratón durante {{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="No hay entradas de teclado o ratón durante {{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Estado del complemento"
|
AdvSceneSwitcher.condition.pluginState="Estado del complemento"
|
||||||
@@ -277,7 +271,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 +319,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"
|
||||||
@@ -350,7 +345,7 @@ AdvSceneSwitcher.action.recording.type.start="Iniciar grabación"
|
|||||||
AdvSceneSwitcher.action.recording.type.pause="Pausar grabación"
|
AdvSceneSwitcher.action.recording.type.pause="Pausar grabación"
|
||||||
AdvSceneSwitcher.action.recording.type.unpause="Reanudar grabación"
|
AdvSceneSwitcher.action.recording.type.unpause="Reanudar grabación"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Tenga en cuenta que, dependiendo de la configuración de grabación, es posible que no pueda pausar la grabación"
|
AdvSceneSwitcher.action.recording.pause.hint="Tenga en cuenta que, dependiendo de la configuración de grabación, es posible que no pueda pausar la grabación"
|
||||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Búfer de reproducción"
|
AdvSceneSwitcher.action.replay="Búfer de reproducción"
|
||||||
AdvSceneSwitcher.action.replay.saveWarn="Advertencia: ¡Guardar con demasiada frecuencia puede hacer que el búfer de reproducción no se guarde realmente!"
|
AdvSceneSwitcher.action.replay.saveWarn="Advertencia: ¡Guardar con demasiada frecuencia puede hacer que el búfer de reproducción no se guarde realmente!"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
|
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
|
||||||
@@ -360,18 +355,14 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
|||||||
AdvSceneSwitcher.action.streaming="Transmisión"
|
AdvSceneSwitcher.action.streaming="Transmisión"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Detener transmisión"
|
AdvSceneSwitcher.action.streaming.type.stop="Detener transmisión"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión"
|
AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
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"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Fuente"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Fuente"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Cualquiera"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Cualquiera"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.entry="En{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="En{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filtro"
|
AdvSceneSwitcher.action.filter="Filtro"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Deshabilitar"
|
AdvSceneSwitcher.action.filter.type.disable="Deshabilitar"
|
||||||
@@ -382,7 +373,7 @@ AdvSceneSwitcher.action.source="Fuente"
|
|||||||
AdvSceneSwitcher.action.source.type.enable="Habilitar"
|
AdvSceneSwitcher.action.source.type.enable="Habilitar"
|
||||||
AdvSceneSwitcher.action.source.type.disable="Deshabilitar"
|
AdvSceneSwitcher.action.source.type.disable="Deshabilitar"
|
||||||
AdvSceneSwitcher.action.source.type.settings="Establecer configuración"
|
AdvSceneSwitcher.action.source.type.settings="Establecer configuración"
|
||||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||||
AdvSceneSwitcher.action.source.warning="Advertencia: la IU de OBS no puede controlar la habilitación y deshabilitación global de fuentes"
|
AdvSceneSwitcher.action.source.warning="Advertencia: la IU de OBS no puede controlar la habilitación y deshabilitación global de fuentes"
|
||||||
AdvSceneSwitcher.action.source.getSettings="Obtener la configuración actual"
|
AdvSceneSwitcher.action.source.getSettings="Obtener la configuración actual"
|
||||||
AdvSceneSwitcher.action.media="Medios"
|
AdvSceneSwitcher.action.media="Medios"
|
||||||
@@ -392,15 +383,14 @@ 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"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Reiniciar contador"
|
||||||
AdvSceneSwitcher.action.macro.type.run="Ejecutar"
|
AdvSceneSwitcher.action.macro.type.run="Ejecutar"
|
||||||
AdvSceneSwitcher.action.macro.type.stop="Detener"
|
AdvSceneSwitcher.action.macro.type.stop="Detener"
|
||||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||||
AdvSceneSwitcher.action.pluginState="Estado del complemento"
|
AdvSceneSwitcher.action.pluginState="Estado del complemento"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Detener el complemento Advanced Scene Switcher"
|
AdvSceneSwitcher.action.pluginState.type.stop="Detener el complemento Advanced Scene Switcher"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Cambiar el comportamiento de no coincidencia:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Cambiar el comportamiento de no coincidencia:"
|
||||||
@@ -422,7 +412,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}} milisegundos"
|
|
||||||
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"
|
||||||
@@ -432,7 +421,7 @@ AdvSceneSwitcher.action.sceneOrder.type.movePosition="Mover a la posición"
|
|||||||
AdvSceneSwitcher.action.sceneOrder.entry="En{{scenes}}{{actions}}{{sources}}{{position}}"
|
AdvSceneSwitcher.action.sceneOrder.entry="En{{scenes}}{{actions}}{{sources}}{{position}}"
|
||||||
AdvSceneSwitcher.action.sceneTransform="Transformar elemento de escena"
|
AdvSceneSwitcher.action.sceneTransform="Transformar elemento de escena"
|
||||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Obtener transformación"
|
AdvSceneSwitcher.action.sceneTransform.getTransform="Obtener transformación"
|
||||||
AdvSceneSwitcher.action.sceneTransform.entry="En{{scenes}}transformar{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="En{{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.file="Archivo"
|
AdvSceneSwitcher.action.file="Archivo"
|
||||||
AdvSceneSwitcher.action.file.type.write="Escribir"
|
AdvSceneSwitcher.action.file.type.write="Escribir"
|
||||||
AdvSceneSwitcher.action.file.type.append="Agregar"
|
AdvSceneSwitcher.action.file.type.append="Agregar"
|
||||||
@@ -460,7 +449,6 @@ AdvSceneSwitcher.action.timer.entry="{{timerAction}} temporizadores en {{macros}
|
|||||||
AdvSceneSwitcher.action.random="Aleatorio"
|
AdvSceneSwitcher.action.random="Aleatorio"
|
||||||
AdvSceneSwitcher.action.random.entry="Ejecute aleatoriamente cualquiera de las siguientes macros (las macros en pausa se ignoran)"
|
AdvSceneSwitcher.action.random.entry="Ejecute aleatoriamente cualquiera de las siguientes macros (las macros en pausa se ignoran)"
|
||||||
AdvSceneSwitcher.action.systray="Notificación de la bandeja del sistema"
|
AdvSceneSwitcher.action.systray="Notificación de la bandeja del sistema"
|
||||||
AdvSceneSwitcher.action.systray.entry="Mostrar notificación: {{message}}"
|
|
||||||
AdvSceneSwitcher.action.screenshot="Captura de pantalla"
|
AdvSceneSwitcher.action.screenshot="Captura de pantalla"
|
||||||
AdvSceneSwitcher.action.screenshot.mainOutput="Salida principal de OBS"
|
AdvSceneSwitcher.action.screenshot.mainOutput="Salida principal de OBS"
|
||||||
AdvSceneSwitcher.action.profile="Perfil"
|
AdvSceneSwitcher.action.profile="Perfil"
|
||||||
@@ -532,7 +520,7 @@ AdvSceneSwitcher.mediaTab.states.none="Ninguno"
|
|||||||
AdvSceneSwitcher.mediaTab.states.playing="Reproduciéndose"
|
AdvSceneSwitcher.mediaTab.states.playing="Reproduciéndose"
|
||||||
AdvSceneSwitcher.mediaTab.states.opening="Abriendo"
|
AdvSceneSwitcher.mediaTab.states.opening="Abriendo"
|
||||||
AdvSceneSwitcher.mediaTab.states.buffering="Almacenando en búfer"
|
AdvSceneSwitcher.mediaTab.states.buffering="Almacenando en búfer"
|
||||||
AdvSceneSwitcher.mediaTab.states.Paused="Pausado"
|
AdvSceneSwitcher.mediaTab.states.paused="Pausado"
|
||||||
AdvSceneSwitcher.mediaTab.states.stopped="Detenido"
|
AdvSceneSwitcher.mediaTab.states.stopped="Detenido"
|
||||||
AdvSceneSwitcher.mediaTab.states.ended="Finalizado"
|
AdvSceneSwitcher.mediaTab.states.ended="Finalizado"
|
||||||
AdvSceneSwitcher.mediaTab.states.error="Error"
|
AdvSceneSwitcher.mediaTab.states.error="Error"
|
||||||
@@ -574,7 +562,7 @@ AdvSceneSwitcher.fileTab.help="Esta pestaña te permitirá cambiar escenas autom
|
|||||||
; Random Tab
|
; Random Tab
|
||||||
AdvSceneSwitcher.randomTab.title="Aleatorio"
|
AdvSceneSwitcher.randomTab.title="Aleatorio"
|
||||||
AdvSceneSwitcher.randomTab.randomDisabledWarning="Funcionalidad deshabilitada - para activarla, selecciona \"Si no se cumple ninguna condición de cambio, cambiar a cualquier escena en la pestaña Aleatorio\" en la pestaña General"
|
AdvSceneSwitcher.randomTab.randomDisabledWarning="Funcionalidad deshabilitada - para activarla, selecciona \"Si no se cumple ninguna condición de cambio, cambiar a cualquier escena en la pestaña Aleatorio\" en la pestaña General"
|
||||||
AdvSceneSwitcher.randomTab.entry="Si no se cumple ninguna condición de cambio, cambiar a {{scenes}} usando {{transitions}} después de {{delay}}"
|
AdvSceneSwitcher.randomTab.entry="Si no se cumple ninguna condición de cambio, cambiar a {{scenes}} usando {{transitions}} después de {{delay}}"
|
||||||
AdvSceneSwitcher.randomTab.help="El selector de escenas elegirá aleatoriamente una entrada en esta pestaña para cambiar durante el tiempo configurado.\nTen en cuenta que la misma entrada no se elegirá dos veces seguidas.\n\nHaz clic en el símbolo más resaltado para continuar."
|
AdvSceneSwitcher.randomTab.help="El selector de escenas elegirá aleatoriamente una entrada en esta pestaña para cambiar durante el tiempo configurado.\nTen en cuenta que la misma entrada no se elegirá dos veces seguidas.\n\nHaz clic en el símbolo más resaltado para continuar."
|
||||||
|
|
||||||
; Time Tab
|
; Time Tab
|
||||||
|
|||||||
1201
data/locale/fr-FR.ini
Normal file
@@ -86,10 +86,7 @@ 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.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
|
||||||
AdvSceneSwitcher.condition.media="Медиа"
|
AdvSceneSwitcher.condition.media="Медиа"
|
||||||
AdvSceneSwitcher.condition.video="Видео"
|
AdvSceneSwitcher.condition.video="Видео"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
||||||
@@ -108,7 +105,7 @@ AdvSceneSwitcher.condition.record.state.start="Запись запущена"
|
|||||||
AdvSceneSwitcher.condition.record.state.pause="Запись приостановлена"
|
AdvSceneSwitcher.condition.record.state.pause="Запись приостановлена"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Запись остановлена"
|
AdvSceneSwitcher.condition.record.state.stop="Запись остановлена"
|
||||||
AdvSceneSwitcher.condition.process="Процесс"
|
AdvSceneSwitcher.condition.process="Процесс"
|
||||||
AdvSceneSwitcher.condition.process.entry="{{processes}} запущен {{focused}} и сфокусирован"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}запущен{{focused}}и сфокусирован"
|
||||||
AdvSceneSwitcher.condition.idle="Простой"
|
AdvSceneSwitcher.condition.idle="Простой"
|
||||||
AdvSceneSwitcher.condition.idle.entry="Не было ни клавиатуры, ни мыши в течении{{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="Не было ни клавиатуры, ни мыши в течении{{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Состояние плагина"
|
AdvSceneSwitcher.condition.pluginState="Состояние плагина"
|
||||||
@@ -116,8 +113,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="случайный"
|
||||||
@@ -135,7 +132,7 @@ AdvSceneSwitcher.action.recording.type.start="Начать запись"
|
|||||||
AdvSceneSwitcher.action.recording.type.pause="Пауза записи"
|
AdvSceneSwitcher.action.recording.type.pause="Пауза записи"
|
||||||
AdvSceneSwitcher.action.recording.type.unpause="Снять запись с паузы"
|
AdvSceneSwitcher.action.recording.type.unpause="Снять запись с паузы"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Обратите внимание, что в зависимости от настроек записи вы можете не иметь возможности приостановить запись"
|
AdvSceneSwitcher.action.recording.pause.hint="Обратите внимание, что в зависимости от настроек записи вы можете не иметь возможности приостановить запись"
|
||||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Буфер воспроизведения"
|
AdvSceneSwitcher.action.replay="Буфер воспроизведения"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Остановить буфер воспроизведения"
|
AdvSceneSwitcher.action.replay.type.stop="Остановить буфер воспроизведения"
|
||||||
AdvSceneSwitcher.action.replay.type.start="Начать воспроизведение буфера"
|
AdvSceneSwitcher.action.replay.type.start="Начать воспроизведение буфера"
|
||||||
@@ -144,7 +141,7 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
|||||||
AdvSceneSwitcher.action.streaming="Потоковое вещание"
|
AdvSceneSwitcher.action.streaming="Потоковое вещание"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Запустить"
|
AdvSceneSwitcher.action.run="Запустить"
|
||||||
|
|
||||||
|
|
||||||
@@ -205,7 +202,7 @@ AdvSceneSwitcher.mediaTab.states.none="Нет"
|
|||||||
AdvSceneSwitcher.mediaTab.states.playing="Играет"
|
AdvSceneSwitcher.mediaTab.states.playing="Играет"
|
||||||
AdvSceneSwitcher.mediaTab.states.opening="Открытие"
|
AdvSceneSwitcher.mediaTab.states.opening="Открытие"
|
||||||
AdvSceneSwitcher.mediaTab.states.buffering="Буферизация"
|
AdvSceneSwitcher.mediaTab.states.buffering="Буферизация"
|
||||||
AdvSceneSwitcher.mediaTab.states.Paused="Приостановлено"
|
AdvSceneSwitcher.mediaTab.states.paused="Приостановлено"
|
||||||
AdvSceneSwitcher.mediaTab.states.stopped="Остановлено"
|
AdvSceneSwitcher.mediaTab.states.stopped="Остановлено"
|
||||||
AdvSceneSwitcher.mediaTab.states.ended="Закончилось"
|
AdvSceneSwitcher.mediaTab.states.ended="Закончилось"
|
||||||
AdvSceneSwitcher.mediaTab.states.error="Ошибка"
|
AdvSceneSwitcher.mediaTab.states.error="Ошибка"
|
||||||
|
|||||||
@@ -112,12 +112,7 @@ 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.line2="{{matchText}}"
|
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{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ı "
|
||||||
@@ -156,14 +151,13 @@ AdvSceneSwitcher.condition.stream.state.start="Yayın çalışıyor"
|
|||||||
AdvSceneSwitcher.condition.stream.state.stop="Yayın durdu"
|
AdvSceneSwitcher.condition.stream.state.stop="Yayın durdu"
|
||||||
AdvSceneSwitcher.condition.stream.state.starting="Yayın başlıyor"
|
AdvSceneSwitcher.condition.stream.state.starting="Yayın başlıyor"
|
||||||
AdvSceneSwitcher.condition.stream.state.stopping="Yayın duruyor"
|
AdvSceneSwitcher.condition.stream.state.stopping="Yayın duruyor"
|
||||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||||
AdvSceneSwitcher.condition.record="Kayıt"
|
AdvSceneSwitcher.condition.record="Kayıt"
|
||||||
AdvSceneSwitcher.condition.record.state.start="Kayıt Çalışıyor"
|
AdvSceneSwitcher.condition.record.state.start="Kayıt Çalışıyor"
|
||||||
AdvSceneSwitcher.condition.record.state.pause="Kayıt durakladı"
|
AdvSceneSwitcher.condition.record.state.pause="Kayıt durakladı"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Kayıt durdu"
|
AdvSceneSwitcher.condition.record.state.stop="Kayıt durdu"
|
||||||
AdvSceneSwitcher.condition.record.entry="{{recordState}}"
|
|
||||||
AdvSceneSwitcher.condition.process="İşlem"
|
AdvSceneSwitcher.condition.process="İşlem"
|
||||||
AdvSceneSwitcher.condition.process.entry="{{processes}} çalışıyor {{focused}} ve odaklandı"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}çalışıyor{{focused}}ve odaklandı"
|
||||||
AdvSceneSwitcher.condition.idle="Boşta"
|
AdvSceneSwitcher.condition.idle="Boşta"
|
||||||
AdvSceneSwitcher.condition.idle.entry="...için klavye veya fare girişi yok {{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="...için klavye veya fare girişi yok {{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="Eklenti durumu"
|
AdvSceneSwitcher.condition.pluginState="Eklenti durumu"
|
||||||
@@ -233,7 +227,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 +256,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"
|
||||||
@@ -281,7 +276,7 @@ AdvSceneSwitcher.action.recording.type.start="Kayıt Başlat"
|
|||||||
AdvSceneSwitcher.action.recording.type.pause="Kayıt Duraklat"
|
AdvSceneSwitcher.action.recording.type.pause="Kayıt Duraklat"
|
||||||
AdvSceneSwitcher.action.recording.type.unpause="Kayıt Duraklatma"
|
AdvSceneSwitcher.action.recording.type.unpause="Kayıt Duraklatma"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="Kayıt ayarlarınıza bağlı olarak kaydı duraklatamayabileceğinizi unutmayın."
|
AdvSceneSwitcher.action.recording.pause.hint="Kayıt ayarlarınıza bağlı olarak kaydı duraklatamayabileceğinizi unutmayın."
|
||||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="Tekrar arabelleği"
|
AdvSceneSwitcher.action.replay="Tekrar arabelleği"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Tekrar arabelleğini durdur"
|
AdvSceneSwitcher.action.replay.type.stop="Tekrar arabelleğini durdur"
|
||||||
AdvSceneSwitcher.action.replay.type.start="Tekrar arabelleğini başlat"
|
AdvSceneSwitcher.action.replay.type.start="Tekrar arabelleğini başlat"
|
||||||
@@ -290,18 +285,14 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
|||||||
AdvSceneSwitcher.action.streaming="Yayın"
|
AdvSceneSwitcher.action.streaming="Yayın"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Yayın durdur"
|
AdvSceneSwitcher.action.streaming.type.stop="Yayın durdur"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Yayın başlat"
|
AdvSceneSwitcher.action.streaming.type.start="Yayın başlat"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
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"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Kayıt"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="Kayıt"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Herhangi"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Herhangi"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.entry="Açık{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="Açık{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="Filtrele"
|
AdvSceneSwitcher.action.filter="Filtrele"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="Etkin"
|
AdvSceneSwitcher.action.filter.type.enable="Etkin"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="Etkisiz"
|
AdvSceneSwitcher.action.filter.type.disable="Etkisiz"
|
||||||
@@ -312,7 +303,7 @@ AdvSceneSwitcher.action.source="Kaynak"
|
|||||||
AdvSceneSwitcher.action.source.type.enable="Etkin"
|
AdvSceneSwitcher.action.source.type.enable="Etkin"
|
||||||
AdvSceneSwitcher.action.source.type.disable="Etkisiz"
|
AdvSceneSwitcher.action.source.type.disable="Etkisiz"
|
||||||
AdvSceneSwitcher.action.source.type.settings="Ayarları yap"
|
AdvSceneSwitcher.action.source.type.settings="Ayarları yap"
|
||||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||||
AdvSceneSwitcher.action.source.warning="Uyarı: Kaynakların global olarak etkinleştirilmesi ve devre dışı bırakılması, OBS UI tarafından kontrol edilemez"
|
AdvSceneSwitcher.action.source.warning="Uyarı: Kaynakların global olarak etkinleştirilmesi ve devre dışı bırakılması, OBS UI tarafından kontrol edilemez"
|
||||||
AdvSceneSwitcher.action.source.getSettings="Mevcut Ayarları yap"
|
AdvSceneSwitcher.action.source.getSettings="Mevcut Ayarları yap"
|
||||||
AdvSceneSwitcher.action.media="Medya"
|
AdvSceneSwitcher.action.media="Medya"
|
||||||
@@ -322,13 +313,12 @@ 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"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Sayacı sıfırla"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Sayacı sıfırla"
|
||||||
AdvSceneSwitcher.action.macro.type.run="Çalıştır"
|
AdvSceneSwitcher.action.macro.type.run="Çalıştır"
|
||||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||||
AdvSceneSwitcher.action.pluginState="Eklenti durumu"
|
AdvSceneSwitcher.action.pluginState="Eklenti durumu"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Advanced Scene Switcher eklentisini durdurun"
|
AdvSceneSwitcher.action.pluginState.type.stop="Advanced Scene Switcher eklentisini durdurun"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Eşleşmeme davranışını değiştirin:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Eşleşmeme davranışını değiştirin:"
|
||||||
@@ -350,7 +340,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}} millisaniye"
|
|
||||||
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"
|
||||||
@@ -360,7 +349,7 @@ AdvSceneSwitcher.action.sceneOrder.type.movePosition="Konuma taşı"
|
|||||||
AdvSceneSwitcher.action.sceneOrder.entry="Açık{{scenes}}{{actions}}{{sources}}{{position}}"
|
AdvSceneSwitcher.action.sceneOrder.entry="Açık{{scenes}}{{actions}}{{sources}}{{position}}"
|
||||||
AdvSceneSwitcher.action.sceneTransform="Sahne öğesi dönüşümü"
|
AdvSceneSwitcher.action.sceneTransform="Sahne öğesi dönüşümü"
|
||||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Dönüşümü al"
|
AdvSceneSwitcher.action.sceneTransform.getTransform="Dönüşümü al"
|
||||||
AdvSceneSwitcher.action.sceneTransform.entry="Açık{{scenes}}transform{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="Açık{{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.file="Dosya"
|
AdvSceneSwitcher.action.file="Dosya"
|
||||||
AdvSceneSwitcher.action.file.type.write="Yaz"
|
AdvSceneSwitcher.action.file.type.write="Yaz"
|
||||||
AdvSceneSwitcher.action.file.type.append="Ekle"
|
AdvSceneSwitcher.action.file.type.append="Ekle"
|
||||||
@@ -377,7 +366,6 @@ AdvSceneSwitcher.action.timer.entry="{{timerAction}} zamanlayıcılar açık {{m
|
|||||||
AdvSceneSwitcher.action.random="Rastgele"
|
AdvSceneSwitcher.action.random="Rastgele"
|
||||||
AdvSceneSwitcher.action.random.entry="Aşağıdaki makrolardan herhangi birini rastgele çalıştırın (duraklatılmış makrolar yoksayılır)"
|
AdvSceneSwitcher.action.random.entry="Aşağıdaki makrolardan herhangi birini rastgele çalıştırın (duraklatılmış makrolar yoksayılır)"
|
||||||
AdvSceneSwitcher.action.systray="Sistem tepsisi bildirimi"
|
AdvSceneSwitcher.action.systray="Sistem tepsisi bildirimi"
|
||||||
AdvSceneSwitcher.action.systray.entry="Bildirimleri göster: {{message}}"
|
|
||||||
AdvSceneSwitcher.action.screenshot="Ekran görüntüsü"
|
AdvSceneSwitcher.action.screenshot="Ekran görüntüsü"
|
||||||
AdvSceneSwitcher.action.screenshot.mainOutput="OBS'nin ana çıkışı"
|
AdvSceneSwitcher.action.screenshot.mainOutput="OBS'nin ana çıkışı"
|
||||||
AdvSceneSwitcher.action.profile="Profil"
|
AdvSceneSwitcher.action.profile="Profil"
|
||||||
@@ -443,7 +431,7 @@ AdvSceneSwitcher.mediaTab.states.none="Yok"
|
|||||||
AdvSceneSwitcher.mediaTab.states.playing="Oynamak"
|
AdvSceneSwitcher.mediaTab.states.playing="Oynamak"
|
||||||
AdvSceneSwitcher.mediaTab.states.opening="Açmak"
|
AdvSceneSwitcher.mediaTab.states.opening="Açmak"
|
||||||
AdvSceneSwitcher.mediaTab.states.buffering="Arabelleğe alma"
|
AdvSceneSwitcher.mediaTab.states.buffering="Arabelleğe alma"
|
||||||
AdvSceneSwitcher.mediaTab.states.Paused="Duraklatıldı"
|
AdvSceneSwitcher.mediaTab.states.paused="Duraklatıldı"
|
||||||
AdvSceneSwitcher.mediaTab.states.stopped="Durduruldu"
|
AdvSceneSwitcher.mediaTab.states.stopped="Durduruldu"
|
||||||
AdvSceneSwitcher.mediaTab.states.ended="Bitti"
|
AdvSceneSwitcher.mediaTab.states.ended="Bitti"
|
||||||
AdvSceneSwitcher.mediaTab.states.error="Hata"
|
AdvSceneSwitcher.mediaTab.states.error="Hata"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ AdvSceneSwitcher.windowTitle="高级场景切换器"
|
|||||||
; General Tab
|
; General Tab
|
||||||
AdvSceneSwitcher.generalTab.title="通用"
|
AdvSceneSwitcher.generalTab.title="通用"
|
||||||
AdvSceneSwitcher.generalTab.status="状态"
|
AdvSceneSwitcher.generalTab.status="状态"
|
||||||
AdvSceneSwitcher.generalTab.status.hotkeytips="快捷键可在OBS设置中设置"
|
AdvSceneSwitcher.generalTab.status.hotkeytips="快捷键可在OBS设置中设置<br><br>汉化作者:[ 从不咕咕的阿坤 ] - 全平台统一名 - 如对你有所帮助,劳烦点个关注!"
|
||||||
AdvSceneSwitcher.generalTab.status.currentStatus="当前状态:"
|
AdvSceneSwitcher.generalTab.status.currentStatus="当前状态:"
|
||||||
AdvSceneSwitcher.generalTab.status.onStartup="在OBS启动时"
|
AdvSceneSwitcher.generalTab.status.onStartup="在OBS启动时"
|
||||||
AdvSceneSwitcher.generalTab.status.onStartup.asLastRun="按照最后运行时的状态"
|
AdvSceneSwitcher.generalTab.status.onStartup.asLastRun="按照最后运行时的状态"
|
||||||
@@ -24,11 +24,14 @@ AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip="时间精度最
|
|||||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.dontSwitch="不切换"
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.dontSwitch="不切换"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchToRandom="切换到随机场景列表中任意随机场景"
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchToRandom="切换到随机场景列表中任意随机场景"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="切换到"
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="切换到"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.cooldown="执行完操作后,跳过执行操作,为"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="在此期间,可能的匹配项将被忽略!"
|
AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="在此期间,可能的匹配项将被忽略!"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="详细日志输出"
|
AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="详细日志输出"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="保存窗口位置和大小"
|
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="保存窗口位置和大小"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="显示系统托盘通知"
|
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="显示系统托盘通知"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="禁用UI提示"
|
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="禁用UI提示"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="如果无法加载插件显示警告"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>加载以下插件库失败,这可能导致某些高级场景切换器功能不可用:%1 查看 OBS 日志了解详细信息.<br>可以在“常规”选项卡上禁用此消息.</body></html>"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="隐藏可通过宏操作的分组栏"
|
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="隐藏可通过宏操作的分组栏"
|
||||||
AdvSceneSwitcher.generalTab.matchBehavior="场景匹配设置"
|
AdvSceneSwitcher.generalTab.matchBehavior="场景匹配设置"
|
||||||
AdvSceneSwitcher.generalTab.priority="优先级"
|
AdvSceneSwitcher.generalTab.priority="优先级"
|
||||||
@@ -78,17 +81,39 @@ AdvSceneSwitcher.macroTab.runFail="运行 \"%1\" 失败!\n其中一个操作失
|
|||||||
AdvSceneSwitcher.macroTab.runInParallel="与其他宏同时运行宏"
|
AdvSceneSwitcher.macroTab.runInParallel="与其他宏同时运行宏"
|
||||||
AdvSceneSwitcher.macroTab.onChange="仅在条件更改时执行操作"
|
AdvSceneSwitcher.macroTab.onChange="仅在条件更改时执行操作"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="宏 %1"
|
AdvSceneSwitcher.macroTab.defaultname="宏 %1"
|
||||||
|
AdvSceneSwitcher.macroTab.defaultGroupName="组 %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="宏名称已存在"
|
AdvSceneSwitcher.macroTab.exists="宏名称已存在"
|
||||||
|
AdvSceneSwitcher.macroTab.groupDeleteConfirm="您确定要删除 \"%1\"及其所有元素吗?"
|
||||||
|
AdvSceneSwitcher.macroTab.deleteMultipleMacrosConfirmation="您确定要删除 %1 宏吗?"
|
||||||
|
AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation="你确定你要删除 \"%1\"?"
|
||||||
|
AdvSceneSwitcher.macroTab.contextMenuAdd="增加"
|
||||||
AdvSceneSwitcher.macroTab.copy="创建副本"
|
AdvSceneSwitcher.macroTab.copy="创建副本"
|
||||||
|
AdvSceneSwitcher.macroTab.group="对选定的宏进行分组"
|
||||||
|
AdvSceneSwitcher.macroTab.ungroup="解除选定的组的分组"
|
||||||
|
AdvSceneSwitcher.macroTab.rename="重命名"
|
||||||
|
AdvSceneSwitcher.macroTab.remove="删除"
|
||||||
AdvSceneSwitcher.macroTab.expandAll="全部展开"
|
AdvSceneSwitcher.macroTab.expandAll="全部展开"
|
||||||
AdvSceneSwitcher.macroTab.collapseAll="全部收回"
|
AdvSceneSwitcher.macroTab.collapseAll="全部收回"
|
||||||
AdvSceneSwitcher.macroTab.maximize="最大化"
|
AdvSceneSwitcher.macroTab.maximize="最大化"
|
||||||
AdvSceneSwitcher.macroTab.minimize="最小化"
|
AdvSceneSwitcher.macroTab.minimize="最小化"
|
||||||
|
AdvSceneSwitcher.macroTab.highlightSettings="显示 设置"
|
||||||
|
AdvSceneSwitcher.macroTab.hotkeySettings="热键 设置"
|
||||||
|
AdvSceneSwitcher.macroTab.dockSettings="停靠 设置"
|
||||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="突出显示最近执行的宏"
|
AdvSceneSwitcher.macroTab.highlightExecutedMacros="突出显示最近执行的宏"
|
||||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="突出显示最近运算为 真 的当前选定宏的条件"
|
AdvSceneSwitcher.macroTab.highlightTrueConditions="突出显示最近运算为 真 的当前选定宏的条件"
|
||||||
AdvSceneSwitcher.macroTab.highlightPerformedActions="突出显示当前选定宏的最近执行的操作"
|
AdvSceneSwitcher.macroTab.highlightPerformedActions="突出显示当前选定宏的最近执行的操作"
|
||||||
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="使用快捷键控制新增宏的暂停状态"
|
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="使用快捷键控制新增宏的暂停状态"
|
||||||
AdvSceneSwitcher.macroTab.currentDisableHotkeys="使用快捷键控制所选宏的暂停状态"
|
AdvSceneSwitcher.macroTab.currentDisableHotkeys="使用快捷键控制所选宏的暂停状态"
|
||||||
|
AdvSceneSwitcher.macroTab.currentRegisterDock="注册停靠小部件以控制所选宏的暂停状态或手动运行它"
|
||||||
|
AdvSceneSwitcher.macroTab.currentDockAddRunButton="添加按钮以运行宏"
|
||||||
|
AdvSceneSwitcher.macroTab.currentDockAddPauseButton="添加按钮以暂停或取消暂停宏"
|
||||||
|
AdvSceneSwitcher.macroTab.currentDockButtonText.run="运行按钮文本:"
|
||||||
|
AdvSceneSwitcher.macroTab.currentDockButtonText.pause="暂停按钮文本:"
|
||||||
|
AdvSceneSwitcher.macroTab.currentDockButtonText.unpause="取消暂停按钮文本:"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.macroDock.pause="暂停"
|
||||||
|
AdvSceneSwitcher.macroDock.unpause="取消暂停"
|
||||||
|
AdvSceneSwitcher.macroDock.run="运行"
|
||||||
|
|
||||||
; Macro List
|
; Macro List
|
||||||
AdvSceneSwitcher.macroList.deleted="删除"
|
AdvSceneSwitcher.macroList.deleted="删除"
|
||||||
@@ -112,10 +137,17 @@ AdvSceneSwitcher.condition.audio.state.mute="静音"
|
|||||||
AdvSceneSwitcher.condition.audio.state.unmute="取消静音"
|
AdvSceneSwitcher.condition.audio.state.unmute="取消静音"
|
||||||
AdvSceneSwitcher.condition.audio.type.output="输出音频"
|
AdvSceneSwitcher.condition.audio.type.output="输出音频"
|
||||||
AdvSceneSwitcher.condition.audio.type.volume="配置音量级别"
|
AdvSceneSwitcher.condition.audio.type.volume="配置音量级别"
|
||||||
|
AdvSceneSwitcher.condition.audio.type.syncOffset="同步偏移"
|
||||||
|
AdvSceneSwitcher.condition.audio.type.monitor="音频监控"
|
||||||
|
AdvSceneSwitcher.condition.audio.type.balance="音频平衡"
|
||||||
AdvSceneSwitcher.condition.audio.entry="{{checkType}} 的 {{audioSources}} 是 {{condition}}{{volume}}{{syncOffset}}{{monitorTypes}}"
|
AdvSceneSwitcher.condition.audio.entry="{{checkType}} 的 {{audioSources}} 是 {{condition}}{{volume}}{{syncOffset}}{{monitorTypes}}"
|
||||||
AdvSceneSwitcher.condition.cursor="屏幕区域"
|
AdvSceneSwitcher.condition.cursor="屏幕区域"
|
||||||
AdvSceneSwitcher.condition.cursor.type.region="当前位置"
|
AdvSceneSwitcher.condition.cursor.type.region="当前位置"
|
||||||
AdvSceneSwitcher.condition.cursor.type.moving="正在移动"
|
AdvSceneSwitcher.condition.cursor.type.moving="正在移动"
|
||||||
|
AdvSceneSwitcher.condition.cursor.type.click="点击"
|
||||||
|
AdvSceneSwitcher.condition.cursor.button.left="鼠标左键"
|
||||||
|
AdvSceneSwitcher.condition.cursor.button.middle="鼠标中键"
|
||||||
|
AdvSceneSwitcher.condition.cursor.button.right="鼠标右键"
|
||||||
AdvSceneSwitcher.condition.cursor.showFrame="显示帧率"
|
AdvSceneSwitcher.condition.cursor.showFrame="显示帧率"
|
||||||
AdvSceneSwitcher.condition.cursor.hideFrame="隐藏帧率"
|
AdvSceneSwitcher.condition.cursor.hideFrame="隐藏帧率"
|
||||||
AdvSceneSwitcher.condition.cursor.entry.line1="鼠标 处于{{conditions}}{{buttons}}{{minX}}{{minY}}{{maxX}}{{maxY}}{{toggleFrameButton}}"
|
AdvSceneSwitcher.condition.cursor.entry.line1="鼠标 处于{{conditions}}{{buttons}}{{minX}}{{minY}}{{maxX}}{{maxY}}{{toggleFrameButton}}"
|
||||||
@@ -125,36 +157,44 @@ AdvSceneSwitcher.condition.scene.type.current="当前场景是"
|
|||||||
AdvSceneSwitcher.condition.scene.type.previous="上一个场景是"
|
AdvSceneSwitcher.condition.scene.type.previous="上一个场景是"
|
||||||
AdvSceneSwitcher.condition.scene.type.changed="场景改变了"
|
AdvSceneSwitcher.condition.scene.type.changed="场景改变了"
|
||||||
AdvSceneSwitcher.condition.scene.type.notChanged="场景没有改变"
|
AdvSceneSwitcher.condition.scene.type.notChanged="场景没有改变"
|
||||||
|
AdvSceneSwitcher.condition.scene.type.currentPattern="当前场景匹配"
|
||||||
|
AdvSceneSwitcher.condition.scene.type.previousPattern="上一个场景匹配"
|
||||||
AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="在转场过程中检查转场源场景"
|
AdvSceneSwitcher.condition.scene.currentSceneTransitionBehaviour="在转场过程中检查转场源场景"
|
||||||
AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="在转场过程中检查转场源场景"
|
AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="在转场过程中检查转场源场景"
|
||||||
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="窗口"
|
AdvSceneSwitcher.condition.window="窗口"
|
||||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} 存在..."
|
AdvSceneSwitcher.condition.window.entry.window="{{checkTitle}}窗口标题匹配{{windowRegex}}{{windows}}"
|
||||||
AdvSceneSwitcher.condition.window.entry.line2="... 并且是 {{fullscreen}} 全屏 {{maximized}} 最大化 {{focused}} 获得焦点 {{windowFocusChanged}} 焦点窗口已更改"
|
AdvSceneSwitcher.condition.window.entry.fullscreen="{{fullscreen}}窗口为全屏"
|
||||||
AdvSceneSwitcher.condition.window.entry.line3="当前焦点窗口: {{focusWindow}}"
|
AdvSceneSwitcher.condition.window.entry.maximized="{{maximized}}窗口为最大化"
|
||||||
|
AdvSceneSwitcher.condition.window.entry.focused="{{focused}}窗口为焦点"
|
||||||
|
AdvSceneSwitcher.condition.window.entry.focusedChange="{{windowFocusChanged}}焦点窗口被改变"
|
||||||
|
AdvSceneSwitcher.condition.window.entry.text="{{checkText}}窗口包含文本{{textRegex}}{{windowText}}"
|
||||||
|
AdvSceneSwitcher.condition.window.entry.text.note="此选项可能不会对窗口中显示的每个文本起作用。\n如果是这种情况,您可以考虑使用视频条件OCR检查来代替。"
|
||||||
|
AdvSceneSwitcher.condition.window.entry.currentFocus="当前焦点窗口:{{focusWindow}}"
|
||||||
AdvSceneSwitcher.condition.file="文件"
|
AdvSceneSwitcher.condition.file="文件"
|
||||||
AdvSceneSwitcher.condition.file.type.match="内容完全匹配"
|
AdvSceneSwitcher.condition.file.type.match="内容完全匹配"
|
||||||
AdvSceneSwitcher.condition.file.type.contentChange="内容已更改"
|
AdvSceneSwitcher.condition.file.type.contentChange="内容已更改"
|
||||||
AdvSceneSwitcher.condition.file.type.dateChange="修改日期已更改"
|
AdvSceneSwitcher.condition.file.type.dateChange="修改日期已更改"
|
||||||
AdvSceneSwitcher.condition.file.entry.line1="文件内容来自{{fileType}}{{filePath}}{{conditions}}"
|
AdvSceneSwitcher.condition.file.remote="远程文件"
|
||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.local="本地文件"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
|
||||||
AdvSceneSwitcher.condition.media="媒体"
|
AdvSceneSwitcher.condition.media="媒体"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体来源"
|
AdvSceneSwitcher.condition.media.source="源"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="所有媒体来源"
|
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体源"
|
||||||
|
AdvSceneSwitcher.condition.media.allOnScene="所有媒体源"
|
||||||
AdvSceneSwitcher.condition.media.matchOnChange="仅在更改时匹配(注意:此选项将在未来版本中删除-请改用时间限制)"
|
AdvSceneSwitcher.condition.media.matchOnChange="仅在更改时匹配(注意:此选项将在未来版本中删除-请改用时间限制)"
|
||||||
AdvSceneSwitcher.condition.media.inconsistencyInfo="不幸的是,并非所有媒体源类型的行为都相同(例如,媒体源与VLC视频源“停止”状态)。\n所以,请尝试适合您的设置!"
|
AdvSceneSwitcher.condition.media.inconsistencyInfo="不幸的是,并非所有媒体源类型的行为都相同(例如,媒体源与VLC视频源“停止”状态)。\n所以,请尝试适合您的设置!"
|
||||||
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}的状态是{{states}}和{{timeRestrictions}}{{time}}"
|
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}} 的状态是 {{states}} 和 {{timeRestrictions}}{{time}}"
|
||||||
AdvSceneSwitcher.condition.video="视频"
|
AdvSceneSwitcher.condition.video="视频"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="完全匹配"
|
AdvSceneSwitcher.condition.video.condition.match="完全匹配"
|
||||||
AdvSceneSwitcher.condition.video.condition.differ="不匹配"
|
AdvSceneSwitcher.condition.video.condition.differ="不匹配"
|
||||||
AdvSceneSwitcher.condition.video.condition.hasChanged="改变了"
|
AdvSceneSwitcher.condition.video.condition.hasChanged="已改变"
|
||||||
AdvSceneSwitcher.condition.video.condition.hasNotChanged="没有改变"
|
AdvSceneSwitcher.condition.video.condition.hasNotChanged="未改变"
|
||||||
AdvSceneSwitcher.condition.video.condition.noImage="没有输出"
|
AdvSceneSwitcher.condition.video.condition.noImage="没有输出"
|
||||||
AdvSceneSwitcher.condition.video.condition.pattern="匹配模式"
|
AdvSceneSwitcher.condition.video.condition.pattern="匹配模式"
|
||||||
AdvSceneSwitcher.condition.video.condition.object="包含对象"
|
AdvSceneSwitcher.condition.video.condition.object="包含对象"
|
||||||
AdvSceneSwitcher.condition.video.condition.brightness="亮度"
|
AdvSceneSwitcher.condition.video.condition.brightness="亮度"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.ocr="包含文本"
|
||||||
AdvSceneSwitcher.condition.video.askFileAction="是否要使用现有文件或创建当前选定源的屏幕截图?"
|
AdvSceneSwitcher.condition.video.askFileAction="是否要使用现有文件或创建当前选定源的屏幕截图?"
|
||||||
AdvSceneSwitcher.condition.video.askFileAction.file="使用现有文件"
|
AdvSceneSwitcher.condition.video.askFileAction.file="使用现有文件"
|
||||||
AdvSceneSwitcher.condition.video.askFileAction.screenshot="创建屏幕截图"
|
AdvSceneSwitcher.condition.video.askFileAction.screenshot="创建屏幕截图"
|
||||||
@@ -164,28 +204,49 @@ AdvSceneSwitcher.condition.video.usePatternForChangedCheck="使用模式匹配"
|
|||||||
AdvSceneSwitcher.condition.video.usePatternForChangedCheck.tooltip="这将允许您控制图像必须更改多少才能使条件为真."
|
AdvSceneSwitcher.condition.video.usePatternForChangedCheck.tooltip="这将允许您控制图像必须更改多少才能使条件为真."
|
||||||
AdvSceneSwitcher.condition.video.patternThreshold="阈值: "
|
AdvSceneSwitcher.condition.video.patternThreshold="阈值: "
|
||||||
AdvSceneSwitcher.condition.video.patternThresholdDescription="较高的阈值意味着模式需要更紧密地匹配视频源."
|
AdvSceneSwitcher.condition.video.patternThresholdDescription="较高的阈值意味着模式需要更紧密地匹配视频源."
|
||||||
AdvSceneSwitcher.condition.video.patternThresholdUseAlphaAsMask="使用alpha通道作为图案的遮罩."
|
AdvSceneSwitcher.condition.video.patternThresholdUseAlphaAsMask="使用alpha通道作为模式的遮罩."
|
||||||
|
AdvSceneSwitcher.condition.video.patternMatchMode="使用模式匹配方式 {{patternMatchingModes}}"
|
||||||
|
AdvSceneSwitcher.condition.video.patternMatchMode.crossCorrelation="交叉相关"
|
||||||
|
AdvSceneSwitcher.condition.video.patternMatchMode.correlationCoefficient="相关系数"
|
||||||
|
AdvSceneSwitcher.condition.video.patternMatchMode.squaredDifference="平方差"
|
||||||
|
AdvSceneSwitcher.condition.video.patternMatchMode.tip="使用的最佳方法取决于具体问题和所涉及图像的特性。\n在实践中,通常需要使用不同的方法和参数进行实验,以找到对特定用例的最佳匹配。"
|
||||||
AdvSceneSwitcher.condition.video.brightnessThreshold="平均亮度:"
|
AdvSceneSwitcher.condition.video.brightnessThreshold="平均亮度:"
|
||||||
AdvSceneSwitcher.condition.video.brightnessThresholdDescription="较高的值表示图像较亮,较低的值表示图像较暗。"
|
AdvSceneSwitcher.condition.video.brightnessThresholdDescription="高的值表示明亮的图像,低的值表示较暗的图像。"
|
||||||
AdvSceneSwitcher.condition.video.currentBrightness="当前平均亮度: %1"
|
AdvSceneSwitcher.condition.video.currentBrightness="当前平均亮度: %1"
|
||||||
AdvSceneSwitcher.condition.video.objectScaleThreshold="模型比例: "
|
AdvSceneSwitcher.condition.video.objectScaleThreshold="模型比例: "
|
||||||
AdvSceneSwitcher.condition.video.objectScaleThresholdDescription="较低的模比例将导致更多的匹配,但会导致更高的CPU负载."
|
AdvSceneSwitcher.condition.video.objectScaleThresholdDescription="较低的模型比例会产生更多的匹配,但将导致CPU负载更高."
|
||||||
AdvSceneSwitcher.condition.video.minNeighborDescription="较高的“最小区域”值将导致较少但质量较高的匹配."
|
AdvSceneSwitcher.condition.video.minNeighborDescription="较高的“最小区域”值将导致较少但质量较高的匹配."
|
||||||
AdvSceneSwitcher.condition.video.showMatch="显示模式"
|
AdvSceneSwitcher.condition.video.showMatch="显示模式"
|
||||||
AdvSceneSwitcher.condition.video.showMatch.loading="Checking for match"
|
AdvSceneSwitcher.condition.video.showMatch.loading="检查是否匹配"
|
||||||
AdvSceneSwitcher.condition.video.screenshotFail="无法获取源的屏幕截图!"
|
AdvSceneSwitcher.condition.video.screenshotFail="无法获取源的屏幕截图!"
|
||||||
AdvSceneSwitcher.condition.video.screenshotEmpty="Screenshot is empty - Is the source visible?"
|
AdvSceneSwitcher.condition.video.screenshotEmpty="屏幕截图为空 - 源是否可见?"
|
||||||
AdvSceneSwitcher.condition.video.patternMatchFail="没有找到模式!"
|
AdvSceneSwitcher.condition.video.patternMatchFail="没有找到模式!"
|
||||||
AdvSceneSwitcher.condition.video.patternMatchSuccess="Pattern is highlighted in red"
|
AdvSceneSwitcher.condition.video.patternMatchSuccess="模式以红色突出显示"
|
||||||
AdvSceneSwitcher.condition.video.objectMatchFail="找不到对象!"
|
AdvSceneSwitcher.condition.video.objectMatchFail="找不到对象!"
|
||||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red"
|
AdvSceneSwitcher.condition.video.objectMatchSuccess="对象以红色突出显示"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMatchSuccess="检测到的文本:\n\n%1"
|
||||||
AdvSceneSwitcher.condition.video.modelLoadFail="无法加载模型数据!"
|
AdvSceneSwitcher.condition.video.modelLoadFail="无法加载模型数据!"
|
||||||
|
AdvSceneSwitcher.condition.video.selectColor="选择颜色"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.singleColumn="单列可变大小的文本"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.singleBlockVertText="垂直对齐的单个统一文本块"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.singleBlock="单个统一的文本块"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.singleLine="单个文本行"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.singleWord="单词"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.circleWord="圆圈中的单个单词"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.singleChar="单个字符"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.sparseText="不按特定顺序查找文本"
|
||||||
|
AdvSceneSwitcher.condition.video.ocrMode.sparseTextOSD="不按特定顺序查找文本(OSD)"
|
||||||
|
AdvSceneSwitcher.condition.video.type.main="OBS的主输出"
|
||||||
|
AdvSceneSwitcher.condition.video.type.source="源"
|
||||||
|
AdvSceneSwitcher.condition.video.type.scene="场景"
|
||||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||||
AdvSceneSwitcher.condition.video.entry.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
|
AdvSceneSwitcher.condition.video.entry.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
|
||||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小区域: {{minNeighbors}}"
|
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小区域: {{minNeighbors}}"
|
||||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}通过只执行每一次检查来减少CPU负载 {{throttleCount}} 毫秒"
|
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}每隔一段时间检查一次,来减少CPU负载 {{throttleCount}} 毫秒"
|
||||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="仅在区域内执行检查"
|
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="仅在区域内执行检查"
|
||||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||||
|
AdvSceneSwitcher.condition.video.entry.orcColorPick="检查文本颜色:{{textColor}}{{selectColor}}"
|
||||||
|
AdvSceneSwitcher.condition.video.entry.orcTextType="检查文本类型:{{textType}}"
|
||||||
AdvSceneSwitcher.condition.video.minSize="最小尺寸:"
|
AdvSceneSwitcher.condition.video.minSize="最小尺寸:"
|
||||||
AdvSceneSwitcher.condition.video.maxSize="最大尺寸:"
|
AdvSceneSwitcher.condition.video.maxSize="最大尺寸:"
|
||||||
AdvSceneSwitcher.condition.video.selectArea="选择区域"
|
AdvSceneSwitcher.condition.video.selectArea="选择区域"
|
||||||
@@ -197,21 +258,24 @@ AdvSceneSwitcher.condition.stream.state.start="推流启动"
|
|||||||
AdvSceneSwitcher.condition.stream.state.stop="推流停止"
|
AdvSceneSwitcher.condition.stream.state.stop="推流停止"
|
||||||
AdvSceneSwitcher.condition.stream.state.starting="推流启动中"
|
AdvSceneSwitcher.condition.stream.state.starting="推流启动中"
|
||||||
AdvSceneSwitcher.condition.stream.state.stopping="推流停止中"
|
AdvSceneSwitcher.condition.stream.state.stopping="推流停止中"
|
||||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="关键帧间隔等于"
|
||||||
|
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
|
||||||
AdvSceneSwitcher.condition.record="录制"
|
AdvSceneSwitcher.condition.record="录制"
|
||||||
AdvSceneSwitcher.condition.record.state.start="录制运行中"
|
AdvSceneSwitcher.condition.record.state.start="录制运行中"
|
||||||
AdvSceneSwitcher.condition.record.state.pause="录制暂停"
|
AdvSceneSwitcher.condition.record.state.pause="录制暂停"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="录制停止"
|
AdvSceneSwitcher.condition.record.state.stop="录制停止"
|
||||||
AdvSceneSwitcher.condition.record.entry="{{recordState}}"
|
|
||||||
AdvSceneSwitcher.condition.process="进程"
|
AdvSceneSwitcher.condition.process="进程"
|
||||||
AdvSceneSwitcher.condition.process.entry="{{processes}} 是正在运行 {{focused}} 而且是获得焦点"
|
AdvSceneSwitcher.condition.process.entry="{{processes}}{{regex}}是正在运行{{focused}}并且是获得焦点"
|
||||||
AdvSceneSwitcher.condition.process.entry.focus="当前焦点进程: {{focusProcess}}"
|
AdvSceneSwitcher.condition.process.entry.focus="当前焦点进程: {{focusProcess}}"
|
||||||
AdvSceneSwitcher.condition.idle="闲置检测"
|
AdvSceneSwitcher.condition.idle="闲置检测"
|
||||||
AdvSceneSwitcher.condition.idle.entry="没有键盘或鼠标输入{{duration}}"
|
AdvSceneSwitcher.condition.idle.entry="没有键盘或鼠标输入{{duration}}"
|
||||||
AdvSceneSwitcher.condition.pluginState="插件状态"
|
AdvSceneSwitcher.condition.pluginState="插件状态"
|
||||||
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="在此时间间隔内触发了自动场景更改"
|
AdvSceneSwitcher.condition.pluginState.state.start="插件已启动"
|
||||||
AdvSceneSwitcher.condition.pluginState.state.running="高级场景切换程序正在运行"
|
AdvSceneSwitcher.condition.pluginState.state.restart="插件已重新启动"
|
||||||
|
AdvSceneSwitcher.condition.pluginState.state.running="插件正在运行"
|
||||||
AdvSceneSwitcher.condition.pluginState.state.shutdown="OBS正在关闭"
|
AdvSceneSwitcher.condition.pluginState.state.shutdown="OBS正在关闭"
|
||||||
|
AdvSceneSwitcher.condition.pluginState.state.sceneCollection="场景集合已加载"
|
||||||
|
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="场景被上一个宏改变"
|
||||||
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
||||||
AdvSceneSwitcher.condition.timer="计时器"
|
AdvSceneSwitcher.condition.timer="计时器"
|
||||||
AdvSceneSwitcher.condition.timer.type.fixed="固定"
|
AdvSceneSwitcher.condition.timer.type.fixed="固定"
|
||||||
@@ -236,11 +300,11 @@ AdvSceneSwitcher.condition.macro.state.type.above="大于"
|
|||||||
AdvSceneSwitcher.condition.macro.state.type.equal="等于"
|
AdvSceneSwitcher.condition.macro.state.type.equal="等于"
|
||||||
AdvSceneSwitcher.condition.macro.count.reset="重置"
|
AdvSceneSwitcher.condition.macro.count.reset="重置"
|
||||||
AdvSceneSwitcher.condition.macro.pausedWarning="所选宏当前已暂停!"
|
AdvSceneSwitcher.condition.macro.pausedWarning="所选宏当前已暂停!"
|
||||||
AdvSceneSwitcher.condition.macro.state.entry="条件 {{macros}} 运行结果为真"
|
AdvSceneSwitcher.condition.macro.state.entry="{{macros}} 的条件为真"
|
||||||
AdvSceneSwitcher.condition.macro.multistate.entry="条件 {{multiStateConditions}}{{multiStateCount}} 以下宏运行结果为真:"
|
AdvSceneSwitcher.condition.macro.multistate.entry=" 以下宏的 {{multiStateConditions}}{{multiStateCount}} 的条件为真:"
|
||||||
AdvSceneSwitcher.condition.macro.count.entry.line1="{{macros}} 运行 {{conditions}} {{count}} 次(相对于下面计数匹配)"
|
AdvSceneSwitcher.condition.macro.count.entry.line1="{{macros}} 执行 {{conditions}} {{count}} 次(相对于下面计数匹配)"
|
||||||
AdvSceneSwitcher.condition.macro.count.entry.line2="当前计数: {{currentCount}} {{resetCount}}"
|
AdvSceneSwitcher.condition.macro.count.entry.line2="当前计数: {{currentCount}} {{resetCount}}"
|
||||||
AdvSceneSwitcher.condition.source="来源"
|
AdvSceneSwitcher.condition.source="源"
|
||||||
AdvSceneSwitcher.condition.source.type.active="是激活状态"
|
AdvSceneSwitcher.condition.source.type.active="是激活状态"
|
||||||
AdvSceneSwitcher.condition.source.type.showing="是显示状态"
|
AdvSceneSwitcher.condition.source.type.showing="是显示状态"
|
||||||
AdvSceneSwitcher.condition.source.type.settings="设置完全匹配"
|
AdvSceneSwitcher.condition.source.type.settings="设置完全匹配"
|
||||||
@@ -257,7 +321,7 @@ AdvSceneSwitcher.condition.filter.type.active="已启用"
|
|||||||
AdvSceneSwitcher.condition.filter.type.showing="已关闭"
|
AdvSceneSwitcher.condition.filter.type.showing="已关闭"
|
||||||
AdvSceneSwitcher.condition.filter.type.settings="设置完全匹配"
|
AdvSceneSwitcher.condition.filter.type.settings="设置完全匹配"
|
||||||
AdvSceneSwitcher.condition.filter.getSettings="获取当前设置"
|
AdvSceneSwitcher.condition.filter.getSettings="获取当前设置"
|
||||||
AdvSceneSwitcher.condition.filter.entry.line1="在 {{sources}} {{filters}} {{conditions}}"
|
AdvSceneSwitcher.condition.filter.entry.line1="在 {{sources}} 的 {{filters}} 是 {{conditions}}"
|
||||||
AdvSceneSwitcher.condition.filter.entry.line2="{{settings}}"
|
AdvSceneSwitcher.condition.filter.entry.line2="{{settings}}"
|
||||||
AdvSceneSwitcher.condition.filter.entry.line3="{{regex}} {{getSettings}}"
|
AdvSceneSwitcher.condition.filter.entry.line3="{{regex}} {{getSettings}}"
|
||||||
AdvSceneSwitcher.condition.sceneOrder="场景项目顺序"
|
AdvSceneSwitcher.condition.sceneOrder="场景项目顺序"
|
||||||
@@ -289,7 +353,8 @@ AdvSceneSwitcher.condition.date.state.at="现在"
|
|||||||
AdvSceneSwitcher.condition.date.state.after="之后"
|
AdvSceneSwitcher.condition.date.state.after="之后"
|
||||||
AdvSceneSwitcher.condition.date.state.before="之前"
|
AdvSceneSwitcher.condition.date.state.before="之前"
|
||||||
AdvSceneSwitcher.condition.date.state.between="之间"
|
AdvSceneSwitcher.condition.date.state.between="之间"
|
||||||
AdvSceneSwitcher.condition.date.separator="和"
|
AdvSceneSwitcher.condition.date.state.pattern="模式"
|
||||||
|
AdvSceneSwitcher.condition.date.separator="到"
|
||||||
AdvSceneSwitcher.condition.date.ignoreDate="如果未选中,日期组件将被忽略"
|
AdvSceneSwitcher.condition.date.ignoreDate="如果未选中,日期组件将被忽略"
|
||||||
AdvSceneSwitcher.condition.date.ignoreTime="如果未选中,时间组件将被忽略"
|
AdvSceneSwitcher.condition.date.ignoreTime="如果未选中,时间组件将被忽略"
|
||||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="显示高级设置"
|
AdvSceneSwitcher.condition.date.showAdvancedSettings="显示高级设置"
|
||||||
@@ -297,11 +362,13 @@ AdvSceneSwitcher.condition.date.showSimpleSettings="显示简单设置"
|
|||||||
AdvSceneSwitcher.condition.date.entry.simple="在 {{dayOfWeek}} {{weekCondition}} {{ignoreWeekTime}}{{weekTime}}"
|
AdvSceneSwitcher.condition.date.entry.simple="在 {{dayOfWeek}} {{weekCondition}} {{ignoreWeekTime}}{{weekTime}}"
|
||||||
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} 在匹配到日期时间后,每隔 {{duration}} 重复一次"
|
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} 在匹配到日期时间后,每隔 {{duration}} 重复一次"
|
||||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Next match at: %1"
|
AdvSceneSwitcher.condition.date.entry.pattern="当前日期 \"{{currentDate}}\" 匹配模式 {{pattern}}"
|
||||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} On repeat update selected date to repeat date"
|
AdvSceneSwitcher.condition.date.entry.nextMatchDate="下一次匹配 在: %1"
|
||||||
|
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="转场"
|
||||||
@@ -316,6 +383,7 @@ AdvSceneSwitcher.condition.transition.entry="{{conditions}}{{transitions}}{{scen
|
|||||||
AdvSceneSwitcher.condition.sceneVisibility="场景项目可见"
|
AdvSceneSwitcher.condition.sceneVisibility="场景项目可见"
|
||||||
AdvSceneSwitcher.condition.sceneVisibility.type.shown="显示的"
|
AdvSceneSwitcher.condition.sceneVisibility.type.shown="显示的"
|
||||||
AdvSceneSwitcher.condition.sceneVisibility.type.hidden="隐藏的"
|
AdvSceneSwitcher.condition.sceneVisibility.type.hidden="隐藏的"
|
||||||
|
AdvSceneSwitcher.condition.sceneVisibility.type.changed="可见性已更改"
|
||||||
AdvSceneSwitcher.condition.sceneVisibility.entry="在 {{scenes}} {{sources}} 是 {{conditions}} "
|
AdvSceneSwitcher.condition.sceneVisibility.entry="在 {{scenes}} {{sources}} 是 {{conditions}} "
|
||||||
AdvSceneSwitcher.condition.studioMode="工作室模式"
|
AdvSceneSwitcher.condition.studioMode="工作室模式"
|
||||||
AdvSceneSwitcher.condition.studioMode.state.active="工作室模式处于活动状态"
|
AdvSceneSwitcher.condition.studioMode.state.active="工作室模式处于活动状态"
|
||||||
@@ -345,7 +413,7 @@ AdvSceneSwitcher.condition.stats.condition.above="大于"
|
|||||||
AdvSceneSwitcher.condition.stats.condition.equals="等于"
|
AdvSceneSwitcher.condition.stats.condition.equals="等于"
|
||||||
AdvSceneSwitcher.condition.stats.condition.below="少于"
|
AdvSceneSwitcher.condition.stats.condition.below="少于"
|
||||||
AdvSceneSwitcher.condition.stats.dockHint="你可以打开“统计”窗口查看当前状态"
|
AdvSceneSwitcher.condition.stats.dockHint="你可以打开“统计”窗口查看当前状态"
|
||||||
AdvSceneSwitcher.condition.stats.entry="{{stats}} is {{condition}} {{value}}"
|
AdvSceneSwitcher.condition.stats.entry="{{stats}} 是 {{condition}} {{value}}"
|
||||||
AdvSceneSwitcher.condition.profile="配置文件"
|
AdvSceneSwitcher.condition.profile="配置文件"
|
||||||
AdvSceneSwitcher.condition.profile.entry="当前活动的配置文件为 {{profiles}}"
|
AdvSceneSwitcher.condition.profile.entry="当前活动的配置文件为 {{profiles}}"
|
||||||
AdvSceneSwitcher.condition.websocket="websocket"
|
AdvSceneSwitcher.condition.websocket="websocket"
|
||||||
@@ -361,12 +429,24 @@ AdvSceneSwitcher.condition.variable.type.number="是一个数字"
|
|||||||
AdvSceneSwitcher.condition.variable.type.lessThan="小于"
|
AdvSceneSwitcher.condition.variable.type.lessThan="小于"
|
||||||
AdvSceneSwitcher.condition.variable.type.greaterThan="大于"
|
AdvSceneSwitcher.condition.variable.type.greaterThan="大于"
|
||||||
AdvSceneSwitcher.condition.variable.type.valueChanged="值已更改"
|
AdvSceneSwitcher.condition.variable.type.valueChanged="值已更改"
|
||||||
AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}"
|
AdvSceneSwitcher.condition.variable.type.equalsVariable="等于变量"
|
||||||
|
AdvSceneSwitcher.condition.variable.type.lessThanVariable="小于变量"
|
||||||
|
AdvSceneSwitcher.condition.variable.type.greaterThanVariable="大于变量"
|
||||||
|
AdvSceneSwitcher.condition.run="运行"
|
||||||
|
AdvSceneSwitcher.condition.run.entry="进程在超时 {{timeout}} 秒之前退出"
|
||||||
|
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}检查退出代码{{exitCode}}"
|
||||||
|
AdvSceneSwitcher.condition.midi="MIDI"
|
||||||
|
AdvSceneSwitcher.condition.midi.entry="从{{device}} 收到的信息,符合:(从不咕咕的阿坤:这个好像是声卡工作是录音相关的功能,英文太抽象了,我就硬译过来了,如有相关设备,音乐好的,可以根据英文翻译好发给我!)"
|
||||||
|
AdvSceneSwitcher.condition.midi.entry.listen="将MIDI信息选择设置为从选定设备上接收的信息: {{listenButton}}"
|
||||||
|
AdvSceneSwitcher.condition.display="显示器"
|
||||||
|
AdvSceneSwitcher.condition.display.type.displayName="连接的显示器的名称匹配"
|
||||||
|
AdvSceneSwitcher.condition.display.type.displayCount="连接的显示器的数量为"
|
||||||
|
AdvSceneSwitcher.condition.display.entry="{{conditions}}{{displays}}{{regex}}{{displayCount}}"
|
||||||
|
|
||||||
; 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="固定数值"
|
||||||
@@ -378,6 +458,10 @@ AdvSceneSwitcher.action.audio.type.mute="静音"
|
|||||||
AdvSceneSwitcher.action.audio.type.unmute="取消静音"
|
AdvSceneSwitcher.action.audio.type.unmute="取消静音"
|
||||||
AdvSceneSwitcher.action.audio.type.sourceVolume="来源音量"
|
AdvSceneSwitcher.action.audio.type.sourceVolume="来源音量"
|
||||||
AdvSceneSwitcher.action.audio.type.masterVolume="主音量"
|
AdvSceneSwitcher.action.audio.type.masterVolume="主音量"
|
||||||
|
AdvSceneSwitcher.action.audio.type.syncOffset="设置同步偏移"
|
||||||
|
AdvSceneSwitcher.action.audio.type.monitor="设置音频监听"
|
||||||
|
AdvSceneSwitcher.action.audio.type.balance="设置平衡"
|
||||||
|
AdvSceneSwitcher.action.audio.balance.description="选择的音频源将滑块方向移动(从不咕咕的阿坤的理解:左/右声道偏侧向)"
|
||||||
AdvSceneSwitcher.action.audio.fade.type.duration="持续时间"
|
AdvSceneSwitcher.action.audio.fade.type.duration="持续时间"
|
||||||
AdvSceneSwitcher.action.audio.fade.type.rate="百分比"
|
AdvSceneSwitcher.action.audio.fade.type.rate="百分比"
|
||||||
AdvSceneSwitcher.action.audio.fade.duration="{{fade}}淡出 {{fadeTypes}} {{duration}} 秒."
|
AdvSceneSwitcher.action.audio.fade.duration="{{fade}}淡出 {{fadeTypes}} {{duration}} 秒."
|
||||||
@@ -391,43 +475,45 @@ AdvSceneSwitcher.action.recording.type.start="开始录制"
|
|||||||
AdvSceneSwitcher.action.recording.type.pause="暂停录制"
|
AdvSceneSwitcher.action.recording.type.pause="暂停录制"
|
||||||
AdvSceneSwitcher.action.recording.type.unpause="取消录制暂停"
|
AdvSceneSwitcher.action.recording.type.unpause="取消录制暂停"
|
||||||
AdvSceneSwitcher.action.recording.type.split="分割录制文件"
|
AdvSceneSwitcher.action.recording.type.split="分割录制文件"
|
||||||
|
AdvSceneSwitcher.action.recording.type.changeOutputFolder="更改输出文件夹"
|
||||||
|
AdvSceneSwitcher.action.recording.type.changeOutputFileFormat="改变文件名的格式"
|
||||||
AdvSceneSwitcher.action.recording.pause.hint="请注意,根据您的录制设置,您可能无法暂停录制"
|
AdvSceneSwitcher.action.recording.pause.hint="请注意,根据您的录制设置,您可能无法暂停录制"
|
||||||
AdvSceneSwitcher.action.recording.split.hint="确保先在OBS设置中启用自动分割文件!"
|
AdvSceneSwitcher.action.recording.split.hint="确保先在OBS设置中启用自动分割文件!"
|
||||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}{{splitHint}}"
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{pauseHint}}{{splitHint}}"
|
||||||
AdvSceneSwitcher.action.replay="回放缓冲区"
|
AdvSceneSwitcher.action.replay="回放缓存"
|
||||||
AdvSceneSwitcher.action.replay.saveWarn="警告:保存过于频繁可能会导致重播缓冲区实际上未保存!"
|
AdvSceneSwitcher.action.replay.saveWarn="警告:保存过于频繁可能会导致回放缓存实际上未保存!"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="停止回放缓冲区"
|
AdvSceneSwitcher.action.replay.type.stop="停止回放缓存"
|
||||||
AdvSceneSwitcher.action.replay.type.start="启动回放缓冲区"
|
AdvSceneSwitcher.action.replay.type.start="启动回放缓存"
|
||||||
AdvSceneSwitcher.action.replay.type.save="保存回放缓冲区"
|
AdvSceneSwitcher.action.replay.type.save="保存回放缓存"
|
||||||
AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
||||||
AdvSceneSwitcher.action.streaming="推流"
|
AdvSceneSwitcher.action.streaming="推流"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="停止推流"
|
AdvSceneSwitcher.action.streaming.type.stop="停止推流"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="开始推流"
|
AdvSceneSwitcher.action.streaming.type.start="开始推流"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
AdvSceneSwitcher.action.streaming.type.keyFrameInterval="设置关键帧间隔"
|
||||||
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="运行"
|
AdvSceneSwitcher.action.run="运行"
|
||||||
AdvSceneSwitcher.action.run.arguments="参数:"
|
|
||||||
AdvSceneSwitcher.action.run.addArgument="添加参数"
|
|
||||||
AdvSceneSwitcher.action.run.addArgumentDescription="添加新参数:"
|
|
||||||
AdvSceneSwitcher.action.run.entry="运行 {{filePath}}"
|
|
||||||
AdvSceneSwitcher.action.sceneVisibility="场景项目可见性"
|
AdvSceneSwitcher.action.sceneVisibility="场景项目可见性"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="显示"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="显示"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="隐藏"
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="隐藏"
|
||||||
|
AdvSceneSwitcher.action.sceneVisibility.type.toggle="切换"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.source="来源"
|
AdvSceneSwitcher.action.sceneVisibility.type.source="来源"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="全部"
|
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="全部"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.entry="设置{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
|
AdvSceneSwitcher.action.sceneVisibility.entry="置{{scenes}}{{actions}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.filter="滤镜"
|
AdvSceneSwitcher.action.filter="滤镜"
|
||||||
AdvSceneSwitcher.action.filter.type.enable="开启"
|
AdvSceneSwitcher.action.filter.type.enable="开启"
|
||||||
AdvSceneSwitcher.action.filter.type.disable="关闭"
|
AdvSceneSwitcher.action.filter.type.disable="关闭"
|
||||||
AdvSceneSwitcher.action.filter.type.settings="参数设置"
|
AdvSceneSwitcher.action.filter.type.settings="参数设置"
|
||||||
AdvSceneSwitcher.action.filter.entry="在 {{sources}} {{actions}} {{filters}}"
|
AdvSceneSwitcher.action.filter.entry="置 {{sources}} {{actions}} {{filters}}"
|
||||||
AdvSceneSwitcher.action.filter.getSettings="获取当前设置"
|
AdvSceneSwitcher.action.filter.getSettings="获取当前设置"
|
||||||
AdvSceneSwitcher.action.source="来源"
|
AdvSceneSwitcher.action.source="源"
|
||||||
AdvSceneSwitcher.action.source.type.enable="启用"
|
AdvSceneSwitcher.action.source.type.enable="启用"
|
||||||
AdvSceneSwitcher.action.source.type.disable="停用"
|
AdvSceneSwitcher.action.source.type.disable="停用"
|
||||||
AdvSceneSwitcher.action.source.type.settings="配置设置"
|
AdvSceneSwitcher.action.source.type.settings="配置设置"
|
||||||
AdvSceneSwitcher.action.source.type.refreshSettings="刷新源设置"
|
AdvSceneSwitcher.action.source.type.refreshSettings="刷新源设置"
|
||||||
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="可用于刷新浏览器、媒体等源"
|
AdvSceneSwitcher.action.source.type.pressSettingsButton="按下设置按钮"
|
||||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}"
|
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="可用于刷新浏览器、媒体、源、etc"
|
||||||
|
AdvSceneSwitcher.action.source.noSettingsButtons="未找到按钮!"
|
||||||
|
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}"
|
||||||
AdvSceneSwitcher.action.source.warning="警告:OBS UI无法控制全局启用和禁用源,注意,通过这个设置禁用,我测试,你必须通过这个在启用才行,不然点击小眼睛你无法显示!"
|
AdvSceneSwitcher.action.source.warning="警告:OBS UI无法控制全局启用和禁用源,注意,通过这个设置禁用,我测试,你必须通过这个在启用才行,不然点击小眼睛你无法显示!"
|
||||||
AdvSceneSwitcher.action.source.getSettings="获取当前设置"
|
AdvSceneSwitcher.action.source.getSettings="获取当前设置"
|
||||||
AdvSceneSwitcher.action.media="媒体"
|
AdvSceneSwitcher.action.media="媒体"
|
||||||
@@ -437,20 +523,21 @@ 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="取消暂停"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="复位计数器"
|
AdvSceneSwitcher.action.macro.type.resetCounter="复位计数器"
|
||||||
AdvSceneSwitcher.action.macro.type.run="运行"
|
AdvSceneSwitcher.action.macro.type.run="运行操作"
|
||||||
AdvSceneSwitcher.action.macro.type.stop="停止"
|
AdvSceneSwitcher.action.macro.type.stop="停止操作"
|
||||||
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
||||||
AdvSceneSwitcher.action.pluginState="插件状态"
|
AdvSceneSwitcher.action.pluginState="插件状态"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="停止高级场景切换插件"
|
AdvSceneSwitcher.action.pluginState.type.stop="停止高级场景切换插件"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="没有匹配项时:"
|
||||||
AdvSceneSwitcher.action.pluginState.type.import="从设置导入"
|
AdvSceneSwitcher.action.pluginState.type.import="从设置导入"
|
||||||
AdvSceneSwitcher.action.pluginState.importWarning="注意:当“设置”窗口打开时,操作将被忽略。"
|
AdvSceneSwitcher.action.pluginState.importWarning="注意:当“设置”窗口打开时,操作将被忽略。"
|
||||||
|
AdvSceneSwitcher.action.pluginState.type.terminate="关闭 OBS"
|
||||||
|
AdvSceneSwitcher.action.pluginState.terminateConfirm="OBS将在10秒后自动关闭!/n你想继续关闭OBS吗?"
|
||||||
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}{{settingsWarning}}"
|
AdvSceneSwitcher.action.pluginState.entry="{{actions}}{{values}}{{scenes}}{{settings}}{{settingsWarning}}"
|
||||||
AdvSceneSwitcher.action.virtualCamera="虚拟摄像机"
|
AdvSceneSwitcher.action.virtualCamera="虚拟摄像机"
|
||||||
AdvSceneSwitcher.action.virtualCamera.type.stop="停止虚拟摄像机"
|
AdvSceneSwitcher.action.virtualCamera.type.stop="停止虚拟摄像机"
|
||||||
@@ -467,7 +554,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}} for {{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="下移"
|
||||||
@@ -475,9 +561,9 @@ AdvSceneSwitcher.action.sceneOrder.type.moveTop="顶部"
|
|||||||
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="底部"
|
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="底部"
|
||||||
AdvSceneSwitcher.action.sceneOrder.type.movePosition="移动到数值位置"
|
AdvSceneSwitcher.action.sceneOrder.type.movePosition="移动到数值位置"
|
||||||
AdvSceneSwitcher.action.sceneOrder.entry="在 {{scenes}} {{actions}} {{sources}} {{position}}"
|
AdvSceneSwitcher.action.sceneOrder.entry="在 {{scenes}} {{actions}} {{sources}} {{position}}"
|
||||||
AdvSceneSwitcher.action.sceneTransform="场景项目变换"
|
AdvSceneSwitcher.action.sceneTransform="场景项目转换"
|
||||||
AdvSceneSwitcher.action.sceneTransform.getTransform="得到变换"
|
AdvSceneSwitcher.action.sceneTransform.getTransform="获得转换"
|
||||||
AdvSceneSwitcher.action.sceneTransform.entry="在 {{scenes}} 变换 {{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="在 {{scenes}}{{action}}{{rotation}}{{sources}}"
|
||||||
AdvSceneSwitcher.action.file="文件"
|
AdvSceneSwitcher.action.file="文件"
|
||||||
AdvSceneSwitcher.action.file.type.write="写入"
|
AdvSceneSwitcher.action.file.type.write="写入"
|
||||||
AdvSceneSwitcher.action.file.type.append="追加写入"
|
AdvSceneSwitcher.action.file.type.append="追加写入"
|
||||||
@@ -503,9 +589,13 @@ AdvSceneSwitcher.action.timer.type.reset="重置"
|
|||||||
AdvSceneSwitcher.action.timer.type.setTimeRemaining="设置剩余时间"
|
AdvSceneSwitcher.action.timer.type.setTimeRemaining="设置剩余时间"
|
||||||
AdvSceneSwitcher.action.timer.entry="{{timerAction}} 定时在 {{macros}} {{duration}}"
|
AdvSceneSwitcher.action.timer.entry="{{timerAction}} 定时在 {{macros}} {{duration}}"
|
||||||
AdvSceneSwitcher.action.random="随机"
|
AdvSceneSwitcher.action.random="随机"
|
||||||
|
AdvSceneSwitcher.action.random.allowRepeat="允许连续执行同一宏"
|
||||||
AdvSceneSwitcher.action.random.entry="随机运行以下任何宏(忽略暂停的宏)"
|
AdvSceneSwitcher.action.random.entry="随机运行以下任何宏(忽略暂停的宏)"
|
||||||
AdvSceneSwitcher.action.systray="系统托盘通知"
|
AdvSceneSwitcher.action.systray="系统托盘通知"
|
||||||
AdvSceneSwitcher.action.systray.entry="显示通知: {{message}}"
|
AdvSceneSwitcher.action.systray.title="标题:"
|
||||||
|
AdvSceneSwitcher.action.systray.message="信息:"
|
||||||
|
AdvSceneSwitcher.action.systray.icon="图标:"
|
||||||
|
AdvSceneSwitcher.action.systray.iconHint="留空以使用默认图标"
|
||||||
AdvSceneSwitcher.action.screenshot="截图"
|
AdvSceneSwitcher.action.screenshot="截图"
|
||||||
AdvSceneSwitcher.action.screenshot.save.default="默认"
|
AdvSceneSwitcher.action.screenshot.save.default="默认"
|
||||||
AdvSceneSwitcher.action.screenshot.save.custom="其他"
|
AdvSceneSwitcher.action.screenshot.save.custom="其他"
|
||||||
@@ -528,21 +618,54 @@ 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="发送场景切换器 {{type}}{{connection}}"
|
|
||||||
AdvSceneSwitcher.action.websocket.entry.event="发送场景切换器 {{type}} 到连接的客户端"
|
|
||||||
AdvSceneSwitcher.action.http="Http"
|
AdvSceneSwitcher.action.http="Http"
|
||||||
AdvSceneSwitcher.action.http.type.get="GET"
|
AdvSceneSwitcher.action.http.setHeaders="设置头信息(SET headers)"
|
||||||
AdvSceneSwitcher.action.http.type.post="POST"
|
AdvSceneSwitcher.action.http.headers="头信息(headers):"
|
||||||
|
AdvSceneSwitcher.action.http.addHeader="增加头信息(ADD headers)"
|
||||||
|
AdvSceneSwitcher.action.http.type.get="获取(GET)"
|
||||||
|
AdvSceneSwitcher.action.http.type.post="发送(POST)"
|
||||||
AdvSceneSwitcher.action.http.entry.line1="发送 {{method}} 到 {{url}}"
|
AdvSceneSwitcher.action.http.entry.line1="发送 {{method}} 到 {{url}}"
|
||||||
AdvSceneSwitcher.action.http.entry.line2="超时: {{timeout}} 秒"
|
AdvSceneSwitcher.action.http.entry.line2="超时: {{timeout}} 秒"
|
||||||
AdvSceneSwitcher.action.variable="变量"
|
AdvSceneSwitcher.action.variable="变量"
|
||||||
AdvSceneSwitcher.action.variable.type.set="设置"
|
AdvSceneSwitcher.action.variable.type.set="设置为固定值"
|
||||||
AdvSceneSwitcher.action.variable.type.append="追加"
|
AdvSceneSwitcher.action.variable.type.append="追加"
|
||||||
AdvSceneSwitcher.action.variable.type.appendVar="追加变量"
|
AdvSceneSwitcher.action.variable.type.appendVar="追加变量"
|
||||||
AdvSceneSwitcher.action.variable.type.increment="增加"
|
AdvSceneSwitcher.action.variable.type.increment="增加"
|
||||||
AdvSceneSwitcher.action.variable.type.decrement="减少"
|
AdvSceneSwitcher.action.variable.type.decrement="减少"
|
||||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}"
|
AdvSceneSwitcher.action.variable.type.setActionValue="设置为操作值"
|
||||||
|
AdvSceneSwitcher.action.variable.type.setConditionValue="设置为条件值"
|
||||||
|
AdvSceneSwitcher.action.variable.type.roundToInt="取整到最近的整数"
|
||||||
|
AdvSceneSwitcher.action.variable.type.subString="设置为当前值的子字符串"
|
||||||
|
AdvSceneSwitcher.action.variable.type.findAndReplace="在当前值中查找并替换"
|
||||||
|
AdvSceneSwitcher.action.variable.type.mathExpression="数学表达式"
|
||||||
|
AdvSceneSwitcher.action.variable.mathExpression.example="( 1 + 2 * 3 ) / 4"
|
||||||
|
AdvSceneSwitcher.action.variable.findAndReplace.find="要查找的文本"
|
||||||
|
AdvSceneSwitcher.action.variable.findAndReplace.replace="要替换为的文本"
|
||||||
|
AdvSceneSwitcher.action.variable.subString.begin="开始"
|
||||||
|
AdvSceneSwitcher.action.variable.subString.all="全部"
|
||||||
|
AdvSceneSwitcher.action.variable.invalidSelection="无效选择!"
|
||||||
|
AdvSceneSwitcher.action.variable.actionNoVariableSupport="不支持从 %1 个操作获取变量值!"
|
||||||
|
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="不支持从 %1 条件中获取变量值!"
|
||||||
|
AdvSceneSwitcher.action.variable.currentSegmentValue="当前值:"
|
||||||
|
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}"
|
||||||
|
AdvSceneSwitcher.action.variable.entry.substringIndex="子字符串开始:{{subStringStart}} 子字符串大小:{{subStringSize}}"
|
||||||
|
AdvSceneSwitcher.action.variable.entry.substringRegex="使用正则表达式为 {{regexMatchIdx}} 匹配的值:"
|
||||||
|
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{replaceStr}}"
|
||||||
|
AdvSceneSwitcher.action.projector="投影仪"
|
||||||
|
AdvSceneSwitcher.action.projector.type.source="源"
|
||||||
|
AdvSceneSwitcher.action.projector.type.scene="场景"
|
||||||
|
AdvSceneSwitcher.action.projector.type.preview="预览"
|
||||||
|
AdvSceneSwitcher.action.projector.type.program="程序"
|
||||||
|
AdvSceneSwitcher.action.projector.type.multiview="多视图"
|
||||||
|
AdvSceneSwitcher.action.projector.display="显示"
|
||||||
|
AdvSceneSwitcher.action.projector.windowed="窗口"
|
||||||
|
AdvSceneSwitcher.action.projector.fullscreen="全屏"
|
||||||
|
AdvSceneSwitcher.action.projector.entry="打开为{{windowTypes}} 的 {{types}}{{scenes}}{{sources}}投影"
|
||||||
|
AdvSceneSwitcher.action.projector.entry.monitor="在 {{monitors}} 上 (从不咕咕的阿坤说:谨慎开启!)"
|
||||||
|
AdvSceneSwitcher.action.midi="MIDI"
|
||||||
|
AdvSceneSwitcher.action.midi.entry="发送消息到 {{device}}:"
|
||||||
|
AdvSceneSwitcher.action.midi.entry.listen="将MIDI消息选择设置为 {{listenDevices}} 上传入的消息: {{listenButton}}"
|
||||||
|
AdvSceneSwitcher.action.osc="打开声音控制"
|
||||||
|
|
||||||
; Transition Tab
|
; Transition Tab
|
||||||
AdvSceneSwitcher.transitionTab.title="转场特效"
|
AdvSceneSwitcher.transitionTab.title="转场特效"
|
||||||
@@ -601,7 +724,7 @@ AdvSceneSwitcher.mediaTab.states.none="无"
|
|||||||
AdvSceneSwitcher.mediaTab.states.playing="播放中"
|
AdvSceneSwitcher.mediaTab.states.playing="播放中"
|
||||||
AdvSceneSwitcher.mediaTab.states.opening="打开中"
|
AdvSceneSwitcher.mediaTab.states.opening="打开中"
|
||||||
AdvSceneSwitcher.mediaTab.states.buffering="缓冲中"
|
AdvSceneSwitcher.mediaTab.states.buffering="缓冲中"
|
||||||
AdvSceneSwitcher.mediaTab.states.Paused="暂停"
|
AdvSceneSwitcher.mediaTab.states.paused="暂停"
|
||||||
AdvSceneSwitcher.mediaTab.states.stopped="停止"
|
AdvSceneSwitcher.mediaTab.states.stopped="停止"
|
||||||
AdvSceneSwitcher.mediaTab.states.ended="结束"
|
AdvSceneSwitcher.mediaTab.states.ended="结束"
|
||||||
AdvSceneSwitcher.mediaTab.states.error="错误"
|
AdvSceneSwitcher.mediaTab.states.error="错误"
|
||||||
@@ -822,6 +945,7 @@ AdvSceneSwitcher.connection.password="密码:"
|
|||||||
AdvSceneSwitcher.connection.reconnect="自动重新连接:"
|
AdvSceneSwitcher.connection.reconnect="自动重新连接:"
|
||||||
AdvSceneSwitcher.connection.reconnectDelay="自动重新连接延迟:"
|
AdvSceneSwitcher.connection.reconnectDelay="自动重新连接延迟:"
|
||||||
AdvSceneSwitcher.connection.connectOnStart="启动时自动连接:"
|
AdvSceneSwitcher.connection.connectOnStart="启动时自动连接:"
|
||||||
|
AdvSceneSwitcher.connection.useOBSWebsocketProtocol="<html><head/><body><p>如何使用 obs-websocket <a href=\"https://github.com/obsproject/obs-websocket/blob/master/docs/generated/protocol.md\"><span style=\" text-decoration: underline; color:#268bd2;\">protocol</span></a></p></body></html>"
|
||||||
AdvSceneSwitcher.connection.test="测试连接"
|
AdvSceneSwitcher.connection.test="测试连接"
|
||||||
AdvSceneSwitcher.connection.status.disconnected="断开"
|
AdvSceneSwitcher.connection.status.disconnected="断开"
|
||||||
AdvSceneSwitcher.connection.status.connecting="连接"
|
AdvSceneSwitcher.connection.status.connecting="连接"
|
||||||
@@ -835,6 +959,68 @@ AdvSceneSwitcher.regex.dotMatchNewline=". 匹配换行符"
|
|||||||
AdvSceneSwitcher.regex.multiLine="^ 和 $ 是匹配行的开始/结束"
|
AdvSceneSwitcher.regex.multiLine="^ 和 $ 是匹配行的开始/结束"
|
||||||
AdvSceneSwitcher.regex.extendedPattern="启用Qt的扩展模式语法"
|
AdvSceneSwitcher.regex.extendedPattern="启用Qt的扩展模式语法"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.process.showAdvanced="显示高级设置"
|
||||||
|
AdvSceneSwitcher.process.arguments="参数:"
|
||||||
|
AdvSceneSwitcher.process.addArgument="增加参数"
|
||||||
|
AdvSceneSwitcher.process.addArgumentDescription="添加新参数:"
|
||||||
|
AdvSceneSwitcher.process.entry="运行{{filePath}}{{advancedSettings}}"
|
||||||
|
AdvSceneSwitcher.process.entry.workingDirectory="工作目录:{{workingDirectory}}"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.math.expressionFail="计算表达式失败"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.midi.deviceNamePattern="[端口 #%1] %2"
|
||||||
|
AdvSceneSwitcher.midi.message.type="类型:"
|
||||||
|
AdvSceneSwitcher.midi.message.type.optional="任意"
|
||||||
|
AdvSceneSwitcher.midi.message.type.invalid="无效"
|
||||||
|
AdvSceneSwitcher.midi.message.type.noteOff="关闭音符"
|
||||||
|
AdvSceneSwitcher.midi.message.type.noteOn="打开音符"
|
||||||
|
AdvSceneSwitcher.midi.message.type.polyphonicPressure="合成音压力"
|
||||||
|
AdvSceneSwitcher.midi.message.type.controlChange="控制更改"
|
||||||
|
AdvSceneSwitcher.midi.message.type.programChange="程序更改"
|
||||||
|
AdvSceneSwitcher.midi.message.type.channelAftertouch="频道余音"
|
||||||
|
AdvSceneSwitcher.midi.message.type.pitchBend="音高弯曲"
|
||||||
|
AdvSceneSwitcher.midi.message.type.systemExclusive="系统独占"
|
||||||
|
AdvSceneSwitcher.midi.message.type.timeCode="时间码"
|
||||||
|
AdvSceneSwitcher.midi.message.type.songPositionPointer="歌曲位置指针"
|
||||||
|
AdvSceneSwitcher.midi.message.type.songSelect="歌曲选择"
|
||||||
|
AdvSceneSwitcher.midi.message.type.reserved1="保留 (1)"
|
||||||
|
AdvSceneSwitcher.midi.message.type.reserved2="保留 (2)"
|
||||||
|
AdvSceneSwitcher.midi.message.type.tuneRequest="调音请求"
|
||||||
|
AdvSceneSwitcher.midi.message.type.endOfSystemExclusive="系统独占结束"
|
||||||
|
AdvSceneSwitcher.midi.message.type.timeClock="时间时钟"
|
||||||
|
AdvSceneSwitcher.midi.message.type.reserved3="保留 (3)"
|
||||||
|
AdvSceneSwitcher.midi.message.type.startFile="开始文件"
|
||||||
|
AdvSceneSwitcher.midi.message.type.continueFile="继续文件"
|
||||||
|
AdvSceneSwitcher.midi.message.type.stopFile="停止文件"
|
||||||
|
AdvSceneSwitcher.midi.message.type.reserved4="保留 (4)"
|
||||||
|
AdvSceneSwitcher.midi.message.type.activeSensing="主动感应"
|
||||||
|
AdvSceneSwitcher.midi.message.type.systemReset="系统充值"
|
||||||
|
AdvSceneSwitcher.midi.message.type.unknown="未知"
|
||||||
|
AdvSceneSwitcher.midi.message.channel="频道 :"
|
||||||
|
AdvSceneSwitcher.midi.message.note="音符 / 值(1):"
|
||||||
|
AdvSceneSwitcher.midi.message.value="值(2):"
|
||||||
|
AdvSceneSwitcher.midi.message.placeholder="任意"
|
||||||
|
AdvSceneSwitcher.midi.resetDevices="重新连接所有 MIDI 设备"
|
||||||
|
AdvSceneSwitcher.midi.startListen="开始监听"
|
||||||
|
AdvSceneSwitcher.midi.stopListen="停止监听"
|
||||||
|
AdvSceneSwitcher.midi.startListenFail="设备正忙!\n其他设备已经在监听!"
|
||||||
|
AdvSceneSwitcher.midi.deviceOpenFail="初始化 MIDI 设备失败!"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.osc.network="网络"
|
||||||
|
AdvSceneSwitcher.osc.network.protocol="协议:"
|
||||||
|
AdvSceneSwitcher.osc.network.address="地址:"
|
||||||
|
AdvSceneSwitcher.osc.network.port="端口:"
|
||||||
|
AdvSceneSwitcher.osc.message="信息"
|
||||||
|
AdvSceneSwitcher.osc.message.type.none="无"
|
||||||
|
AdvSceneSwitcher.osc.message.type.float="浮点数哦"
|
||||||
|
AdvSceneSwitcher.osc.message.type.int="整数"
|
||||||
|
AdvSceneSwitcher.osc.message.type.string="字符串"
|
||||||
|
AdvSceneSwitcher.osc.message.type.binaryBlob="二进制"
|
||||||
|
AdvSceneSwitcher.osc.message.type.true="真"
|
||||||
|
AdvSceneSwitcher.osc.message.type.false="假"
|
||||||
|
AdvSceneSwitcher.osc.message.type.infinity="无限"
|
||||||
|
AdvSceneSwitcher.osc.message.type.null="无"
|
||||||
|
|
||||||
AdvSceneSwitcher.selectScene="--选择场景--"
|
AdvSceneSwitcher.selectScene="--选择场景--"
|
||||||
AdvSceneSwitcher.selectPreviousScene="上个场景"
|
AdvSceneSwitcher.selectPreviousScene="上个场景"
|
||||||
AdvSceneSwitcher.selectCurrentScene="当前场景"
|
AdvSceneSwitcher.selectCurrentScene="当前场景"
|
||||||
@@ -844,7 +1030,7 @@ AdvSceneSwitcher.currentTransition="当前转场特效"
|
|||||||
AdvSceneSwitcher.anyTransition="任何转场特效"
|
AdvSceneSwitcher.anyTransition="任何转场特效"
|
||||||
AdvSceneSwitcher.selectTransition="--选择转场特效--"
|
AdvSceneSwitcher.selectTransition="--选择转场特效--"
|
||||||
AdvSceneSwitcher.selectWindow="--选择窗口--"
|
AdvSceneSwitcher.selectWindow="--选择窗口--"
|
||||||
AdvSceneSwitcher.selectSource="--选择来源--"
|
AdvSceneSwitcher.selectSource="--选择源--"
|
||||||
AdvSceneSwitcher.selectAudioSource="--选择音频源--"
|
AdvSceneSwitcher.selectAudioSource="--选择音频源--"
|
||||||
AdvSceneSwitcher.selectVideoSource="--选择视频源--"
|
AdvSceneSwitcher.selectVideoSource="--选择视频源--"
|
||||||
AdvSceneSwitcher.OBSVideoOutput="OBS的主要输出"
|
AdvSceneSwitcher.OBSVideoOutput="OBS的主要输出"
|
||||||
@@ -865,8 +1051,8 @@ AdvSceneSwitcher.sceneItemSelection.any="任何"
|
|||||||
|
|
||||||
AdvSceneSwitcher.status.active="运行中"
|
AdvSceneSwitcher.status.active="运行中"
|
||||||
AdvSceneSwitcher.status.inactive="已停止"
|
AdvSceneSwitcher.status.inactive="已停止"
|
||||||
AdvSceneSwitcher.running="插件运行"
|
AdvSceneSwitcher.running="插件正在运行"
|
||||||
AdvSceneSwitcher.stopped="插件停止"
|
AdvSceneSwitcher.stopped="插件已停止"
|
||||||
|
|
||||||
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>这似乎是第一次启动高级场景切换程序.<br>请看一下 <a href=\"https://github.com/WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> 查看指南和示例列表.<br>如果有问题,在在OBS论坛插件帖子内提问 <a href=\"https://obsproject.com/forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:#268bd2;\">thread</span></a></p></body></html>"
|
AdvSceneSwitcher.firstBootMessage="<html><head/><body><p>这似乎是第一次启动高级场景切换程序.<br>请看一下 <a href=\"https://github.com/WarmUpTill/SceneSwitcher/wiki\"><span style=\" text-decoration: underline; color:#268bd2;\">Wiki</span></a> 查看指南和示例列表.<br>如果有问题,在在OBS论坛插件帖子内提问 <a href=\"https://obsproject.com/forum/threads/advanced-scene-switcher.48264\"><span style=\" text-decoration: underline; color:#268bd2;\">thread</span></a></p></body></html>"
|
||||||
|
|
||||||
@@ -880,4 +1066,8 @@ AdvSceneSwitcher.duration.condition.none="没有时间限制"
|
|||||||
AdvSceneSwitcher.duration.condition.more="时间少于"
|
AdvSceneSwitcher.duration.condition.more="时间少于"
|
||||||
AdvSceneSwitcher.duration.condition.equal="时间等于"
|
AdvSceneSwitcher.duration.condition.equal="时间等于"
|
||||||
AdvSceneSwitcher.duration.condition.less="时间大于"
|
AdvSceneSwitcher.duration.condition.less="时间大于"
|
||||||
AdvSceneSwitcher.duration.condition.within="保留结果后余存"
|
AdvSceneSwitcher.duration.condition.within="在最后"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.audio.monitor.none="关闭监听"
|
||||||
|
AdvSceneSwitcher.audio.monitor.monitorOnly="仅监听(输出静音)"
|
||||||
|
AdvSceneSwitcher.audio.monitor.both="监听并输出"
|
||||||
|
|||||||
4
data/res/images/DarkAdvanced.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m 13.855469 0 l -1.539063 1.4375 c -0.453125 0.421875 -0.53125 1.148438 -0.269531 1.707031 l -5.886719 5.996094 c -0.011718 0 -0.019531 0 -0.03125 0 c -0.257812 -0.128906 -0.550781 -0.183594 -0.839844 -0.148437 c -0.328124 0.046874 -0.632812 0.199218 -0.867187 0.441406 l -3.945313 3.996094 c -0.3906245 0.375 -0.5468745 0.933593 -0.4062495 1.457031 c 0.1406255 0.523437 0.5546875 0.929687 1.0820315 1.058593 c 0.527344 0.132813 1.082031 -0.03125 1.453125 -0.425781 l 3.945312 -3.996093 c 0.472657 -0.453126 0.59375 -1.15625 0.296875 -1.738282 l 5.890625 -5.964844 c 0.558594 0.25 1.273438 0.148438 1.707031 -0.289062 l 1.414063 -1.5625 z m -10.308594 0.0898438 c -0.398437 0 -0.785156 0.0937502 -1.140625 0.2187502 l 1.882812 1.878906 c 0.390626 0.382812 0.390626 1 0 1.386719 l -0.710937 0.707031 c -0.386719 0.386719 -1 0.386719 -1.390625 0 l -1.882812 -1.878906 c -0.125 0.355468 -0.2187505 0.742187 -0.2187505 1.140625 c 0 1.90625 1.5507815 3.453125 3.4609375 3.453125 c 0.402344 0 0.789063 -0.09375 1.144531 -0.21875 l 1.175782 1.171875 h 0.058593 l 2.070313 -2.0625 l -1.203125 -1.203125 c 0.125 -0.359375 0.214843 -0.742188 0.214843 -1.140625 c 0 -1.90625 -1.546874 -3.4531252 -3.460937 -3.4531252 z m 6.550781 7.8906252 l -2.070312 2.066406 c 0.011718 0.027344 0.023437 0.058594 0.03125 0.089844 l 1.144531 1.140625 c -0.125 0.355468 -0.21875 0.742187 -0.21875 1.140625 c 0 1.902343 1.550781 3.449219 3.460937 3.449219 c 0.433594 0 0.855469 -0.101563 1.238282 -0.246094 l -2.007813 -2 c -0.386719 -0.386719 -0.386719 -1.035156 0 -1.417969 l 0.679688 -0.679687 c 0.195312 -0.191407 0.457031 -0.308594 0.710937 -0.308594 s 0.515625 0.117187 0.710938 0.308594 l 1.945312 1.941406 c 0.105469 -0.328125 0.183594 -0.683594 0.183594 -1.046875 c 0 -1.90625 -1.546875 -3.453125 -3.460938 -3.453125 c -0.398437 0 -0.785156 0.09375 -1.140624 0.21875 z m 0 0" fill="#fefefe"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
9
data/res/images/DarkDoubleDown.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path d="m1,2c0,-0.27 0.11,-0.52 0.29,-0.71c0.39,-0.39 1.03,-0.39 1.42,0l5.29,5.3l5.29,-5.3c0.39,-0.39 1.03,-0.39 1.42,0c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71l-6,6c-0.39,0.39 -1.03,0.39 -1.42,0l-6,-6c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#fefefe" id="svg_1" transform="matrix(1, 0, 0, 1, 0, 0)"/>
|
||||||
|
<path d="m1,8c0,-0.27 0.09,-0.52 0.28,-0.71c0.38,-0.39 1.03,-0.39 1.41,0l5.31,5.3l5.28,-5.3c0.38,-0.39 1.03,-0.39 1.41,0c0.19,0.19 0.31,0.44 0.31,0.71s-0.13,0.52 -0.31,0.71l-6,6c-0.38,0.39 -1.03,0.39 -1.41,0l-6,-6c-0.19,-0.19 -0.28,-0.44 -0.28,-0.71zm0,0" fill="#fefefe" id="svg_2"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 791 B |
9
data/res/images/DarkDoubleUp.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path d="m1,8c0,-0.27 0.11,-0.52 0.29,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.29,-5.3l-5.29,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#fefefe" id="svg_1"/>
|
||||||
|
<path d="m1,14c0,-0.27 0.11,-0.52 0.28,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.19,0.19 0.3,0.44 0.3,0.71s-0.11,0.52 -0.3,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.28,-5.3l-5.3,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.17,-0.19 -0.28,-0.44 -0.28,-0.71zm0,0" fill="#fefefe" id="svg_2"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 753 B |
7
data/res/images/DarkGroup.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="#fefefe">
|
||||||
|
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8.882812 c 0.832032 0 1.578126 -0.402344 2.054688 -0.9375 c 0.472656 -0.53125 0.738281 -1.167969 0.910156 -1.800781 l 0.972656 -2.609375 c 0.390626 -1.449219 -0.09375 -2.652344 -0.820312 -3.167969 c -0.484375 -0.34375 -0.714844 -0.292969 -1 -0.324219 v -1.160156 c 0 -0.855469 -0.558594 -1.589844 -1.09375 -1.828125 c -0.53125 -0.238281 -1.011719 -0.167969 -1.011719 -0.167969 l 0.105469 -0.003906 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 2.585938 l 1.707031 1.707031 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 h 4 c 0.035156 0 0.070312 -0.003906 0.105469 -0.007812 c 0 0 0.019531 0.019531 -0.011719 0.003906 c -0.035156 -0.011719 -0.09375 -0.25 -0.09375 0.003906 v 2 c 0 0.550781 0.449219 1 1 1 c 1 0 1.046875 0.703125 0.886719 1.128906 l -0.972657 2.609375 c -0.117187 0.4375 -0.296874 0.800781 -0.472656 0.996094 c -0.175781 0.199219 -0.285156 0.265625 -0.558594 0.265625 h -8.882812 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.46875 -0.792969 1 -1 z m 0 0"/>
|
||||||
|
<path d="m 7 6 l 0.042969 0.003906 c -0.914063 -0.042968 -1.75 0.390625 -2.195313 0.96875 c -0.710937 1.222656 -1.15625 2.277344 -1.800781 3.71875 c -0.171875 0.523438 0.117187 1.089844 0.640625 1.261719 c 0.527344 0.171875 1.09375 -0.117187 1.261719 -0.640625 c 0.488281 -1.011719 0.921875 -1.816406 1.339843 -2.808594 c 0.210938 -0.503906 0.703126 -0.492187 0.898438 -0.503906 h 5.8125 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
11
data/res/images/DarkNotEqual.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||||
|
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
|
||||||
|
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<rect fill="#fefefe" height="2.25" id="svg_1" stroke="#fefefe" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="13" x="1.5" y="4"/>
|
||||||
|
<rect fill="#fefefe" height="2.25" id="svg_2" stroke="#fefefe" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="13" x="1.5" y="10"/>
|
||||||
|
<rect fill="#fefefe" height="1" id="svg_4" stroke="#fefefe" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(0.341951, -0.926734, 0.939718, 0.337226, -1.948, 13.2448)" width="14" x="1" y="7"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 931 B |
24
data/res/images/DarkNote.svg
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="640" height="640" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||||
|
<defs>
|
||||||
|
<path d="m599.62,325.49c0,151.77 -123.21,274.98 -274.98,274.98c-151.76,0 -274.97,-123.21 -274.97,-274.98c0,-151.76 123.21,-274.97 274.97,-274.97c151.77,0 274.98,123.21 274.98,274.97z" id="c3Wyq0kfYS"/>
|
||||||
|
<mask height="689.95" id="maskanTyyngos" maskUnits="userSpaceOnUse" width="689.95" x="-20.33" y="-19.48">
|
||||||
|
<rect fill="white" height="689.95" id="svg_1" width="689.95" x="-20.33" y="-19.48"/>
|
||||||
|
<use fill="black" id="svg_2" xlink:href="#c3Wyq0kfYS"/>
|
||||||
|
</mask>
|
||||||
|
<path d="m334.97,96.07c4.54,0 8.23,3.68 8.23,8.23c0,46.94 0,179.54 0,226.48c0,4.54 -3.69,8.22 -8.23,8.22c-5.77,0 -14.88,0 -20.66,0c-4.54,0 -8.22,-3.68 -8.22,-8.22c0,-46.94 0,-179.54 0,-226.48c0,-4.55 3.68,-8.23 8.22,-8.23c5.78,0 14.89,0 20.66,0z" id="fxMeu932c"/>
|
||||||
|
<path d="m471.96,338.21c0.01,3.1 -2.5,5.62 -5.59,5.63c-32.02,0.09 -122.45,0.37 -154.46,0.47c-3.1,0.01 -5.61,-2.49 -5.62,-5.59c-0.02,-6.3 -0.06,-19.59 -0.08,-25.89c-0.01,-3.1 2.49,-5.62 5.59,-5.63c32.01,-0.09 122.44,-0.37 154.45,-0.47c3.1,-0.01 5.62,2.5 5.63,5.59c0.02,6.3 0.06,19.59 0.08,25.89z" id="h65nGmP2BL"/>
|
||||||
|
</defs>
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path fill="none" fill-opacity="null" id="svg_11" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02"/>
|
||||||
|
<ellipse cx="103.84" cy="562.04" fill="#fefefe" id="svg_3" rx="80" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 103.843, 562.038)"/>
|
||||||
|
<ellipse cx="506" cy="554" fill="#fefefe" id="svg_4" rx="77" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 506, 554)"/>
|
||||||
|
<rect fill="#fefefe" height="359" id="svg_7" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" stroke-width="0" width="58" x="122" y="185"/>
|
||||||
|
<rect fill="#fefefe" height="453" id="svg_8" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="58" x="522" y="84.5"/>
|
||||||
|
<rect fill="#fefefe" height="37" id="svg_9" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-14.1985, 351.556, 146.245)" width="463.07" x="120.02" y="127.74"/>
|
||||||
|
<rect fill="none" fill-opacity="null" height="0" id="svg_10" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="538.25" y="107.12"/>
|
||||||
|
<path d="m537.42,112.06l0,-67.88l17.58,67.88z" fill="#fefefe" id="svg_16" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-90, 546.203, 78.1248)"/>
|
||||||
|
<rect fill="#fefefe" height="0" id="svg_18" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="82.12" y="287.56"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.1 KiB |
10
data/res/images/DarkRegex.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||||
|
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
|
||||||
|
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<text fill="#fefefe" font-family="Serif" font-size="24" id="svg_1" stroke="#fefefe" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="null" stroke-width="0" text-anchor="middle" transform="matrix(1.0974, 0, 0, 1.0974, -4.98544, 4.97639)" x="14" xml:space="preserve" y="13">*</text>
|
||||||
|
<rect fill="#fefefe" height="3.3" id="svg_2" stroke="#fefefe" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="5" x="1" y="12"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 815 B |
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 |
@@ -1,3 +1,2 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#fefefe" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#fefefe" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#fefefe" fill-opacity="1"></use></g></g></g></svg>
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#d2d2d2" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
4
data/res/images/LightAdvanced.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m 13.855469 0 l -1.539063 1.4375 c -0.453125 0.421875 -0.53125 1.148438 -0.269531 1.707031 l -5.886719 5.996094 c -0.011718 0 -0.019531 0 -0.03125 0 c -0.257812 -0.128906 -0.550781 -0.183594 -0.839844 -0.148437 c -0.328124 0.046874 -0.632812 0.199218 -0.867187 0.441406 l -3.945313 3.996094 c -0.3906245 0.375 -0.5468745 0.933593 -0.4062495 1.457031 c 0.1406255 0.523437 0.5546875 0.929687 1.0820315 1.058593 c 0.527344 0.132813 1.082031 -0.03125 1.453125 -0.425781 l 3.945312 -3.996093 c 0.472657 -0.453126 0.59375 -1.15625 0.296875 -1.738282 l 5.890625 -5.964844 c 0.558594 0.25 1.273438 0.148438 1.707031 -0.289062 l 1.414063 -1.5625 z m -10.308594 0.0898438 c -0.398437 0 -0.785156 0.0937502 -1.140625 0.2187502 l 1.882812 1.878906 c 0.390626 0.382812 0.390626 1 0 1.386719 l -0.710937 0.707031 c -0.386719 0.386719 -1 0.386719 -1.390625 0 l -1.882812 -1.878906 c -0.125 0.355468 -0.2187505 0.742187 -0.2187505 1.140625 c 0 1.90625 1.5507815 3.453125 3.4609375 3.453125 c 0.402344 0 0.789063 -0.09375 1.144531 -0.21875 l 1.175782 1.171875 h 0.058593 l 2.070313 -2.0625 l -1.203125 -1.203125 c 0.125 -0.359375 0.214843 -0.742188 0.214843 -1.140625 c 0 -1.90625 -1.546874 -3.4531252 -3.460937 -3.4531252 z m 6.550781 7.8906252 l -2.070312 2.066406 c 0.011718 0.027344 0.023437 0.058594 0.03125 0.089844 l 1.144531 1.140625 c -0.125 0.355468 -0.21875 0.742187 -0.21875 1.140625 c 0 1.902343 1.550781 3.449219 3.460937 3.449219 c 0.433594 0 0.855469 -0.101563 1.238282 -0.246094 l -2.007813 -2 c -0.386719 -0.386719 -0.386719 -1.035156 0 -1.417969 l 0.679688 -0.679687 c 0.195312 -0.191407 0.457031 -0.308594 0.710937 -0.308594 s 0.515625 0.117187 0.710938 0.308594 l 1.945312 1.941406 c 0.105469 -0.328125 0.183594 -0.683594 0.183594 -1.046875 c 0 -1.90625 -1.546875 -3.453125 -3.460938 -3.453125 c -0.398437 0 -0.785156 0.09375 -1.140624 0.21875 z m 0 0" fill="#202020"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
9
data/res/images/LightDoubleDown.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path d="m1,2c0,-0.27 0.11,-0.52 0.29,-0.71c0.39,-0.39 1.03,-0.39 1.42,0l5.29,5.3l5.29,-5.3c0.39,-0.39 1.03,-0.39 1.42,0c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71l-6,6c-0.39,0.39 -1.03,0.39 -1.42,0l-6,-6c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_1"/>
|
||||||
|
<path d="m1,8c0,-0.27 0.11,-0.52 0.29,-0.71c0.39,-0.39 1.03,-0.39 1.42,0l5.29,5.3l5.29,-5.3c0.39,-0.39 1.03,-0.39 1.42,0c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71l-6,6c-0.39,0.39 -1.03,0.39 -1.42,0l-6,-6c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_4" transform="matrix(1, 0, 0, 1, 0, 0)"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 791 B |
9
data/res/images/LightDoubleUp.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path d="m1,8c0,-0.27 0.11,-0.52 0.29,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.29,-5.3l-5.29,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_1"/>
|
||||||
|
<path d="m1,14c0,-0.27 0.11,-0.52 0.29,-0.71l6,-6c0.39,-0.39 1.03,-0.39 1.42,0l6,6c0.18,0.19 0.29,0.44 0.29,0.71s-0.11,0.52 -0.29,0.71c-0.39,0.39 -1.03,0.39 -1.42,0l-5.29,-5.3l-5.29,5.3c-0.39,0.39 -1.03,0.39 -1.42,0c-0.18,-0.19 -0.29,-0.44 -0.29,-0.71zm0,0" fill="#202020" id="svg_2"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 757 B |
7
data/res/images/LightGroup.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="#202020">
|
||||||
|
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8.882812 c 0.832032 0 1.578126 -0.402344 2.054688 -0.9375 c 0.472656 -0.53125 0.738281 -1.167969 0.910156 -1.800781 l 0.972656 -2.609375 c 0.390626 -1.449219 -0.09375 -2.652344 -0.820312 -3.167969 c -0.484375 -0.34375 -0.714844 -0.292969 -1 -0.324219 v -1.160156 c 0 -0.855469 -0.558594 -1.589844 -1.09375 -1.828125 c -0.53125 -0.238281 -1.011719 -0.167969 -1.011719 -0.167969 l 0.105469 -0.003906 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 2.585938 l 1.707031 1.707031 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 h 4 c 0.035156 0 0.070312 -0.003906 0.105469 -0.007812 c 0 0 0.019531 0.019531 -0.011719 0.003906 c -0.035156 -0.011719 -0.09375 -0.25 -0.09375 0.003906 v 2 c 0 0.550781 0.449219 1 1 1 c 1 0 1.046875 0.703125 0.886719 1.128906 l -0.972657 2.609375 c -0.117187 0.4375 -0.296874 0.800781 -0.472656 0.996094 c -0.175781 0.199219 -0.285156 0.265625 -0.558594 0.265625 h -8.882812 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.46875 -0.792969 1 -1 z m 0 0"/>
|
||||||
|
<path d="m 7 6 l 0.042969 0.003906 c -0.914063 -0.042968 -1.75 0.390625 -2.195313 0.96875 c -0.710937 1.222656 -1.15625 2.277344 -1.800781 3.71875 c -0.171875 0.523438 0.117187 1.089844 0.640625 1.261719 c 0.527344 0.171875 1.09375 -0.117187 1.261719 -0.640625 c 0.488281 -1.011719 0.921875 -1.816406 1.339843 -2.808594 c 0.210938 -0.503906 0.703126 -0.492187 0.898438 -0.503906 h 5.8125 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
11
data/res/images/LightNotEqual.svg
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||||
|
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
|
||||||
|
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<rect fill="#202020" height="2.25" id="svg_1" stroke="#202020" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="13" x="1.5" y="4"/>
|
||||||
|
<rect fill="#202020" height="2.25" id="svg_2" stroke="#202020" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="13" x="1.5" y="10"/>
|
||||||
|
<rect fill="#202020" height="1" id="svg_4" stroke="#202020" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(0.341951, -0.926734, 0.939718, 0.337226, -1.948, 13.2448)" width="14" x="1" y="7"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 931 B |
24
data/res/images/LightNote.svg
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="640" height="640" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||||
|
<defs>
|
||||||
|
<path d="m599.62,325.49c0,151.77 -123.21,274.98 -274.98,274.98c-151.76,0 -274.97,-123.21 -274.97,-274.98c0,-151.76 123.21,-274.97 274.97,-274.97c151.77,0 274.98,123.21 274.98,274.97z" id="c3Wyq0kfYS"/>
|
||||||
|
<mask height="689.95" id="maskanTyyngos" maskUnits="userSpaceOnUse" width="689.95" x="-20.33" y="-19.48">
|
||||||
|
<rect fill="white" height="689.95" id="svg_1" width="689.95" x="-20.33" y="-19.48"/>
|
||||||
|
<use fill="black" id="svg_2" xlink:href="#c3Wyq0kfYS"/>
|
||||||
|
</mask>
|
||||||
|
<path d="m334.97,96.07c4.54,0 8.23,3.68 8.23,8.23c0,46.94 0,179.54 0,226.48c0,4.54 -3.69,8.22 -8.23,8.22c-5.77,0 -14.88,0 -20.66,0c-4.54,0 -8.22,-3.68 -8.22,-8.22c0,-46.94 0,-179.54 0,-226.48c0,-4.55 3.68,-8.23 8.22,-8.23c5.78,0 14.89,0 20.66,0z" id="fxMeu932c"/>
|
||||||
|
<path d="m471.96,338.21c0.01,3.1 -2.5,5.62 -5.59,5.63c-32.02,0.09 -122.45,0.37 -154.46,0.47c-3.1,0.01 -5.61,-2.49 -5.62,-5.59c-0.02,-6.3 -0.06,-19.59 -0.08,-25.89c-0.01,-3.1 2.49,-5.62 5.59,-5.63c32.01,-0.09 122.44,-0.37 154.45,-0.47c3.1,-0.01 5.62,2.5 5.63,5.59c0.02,6.3 0.06,19.59 0.08,25.89z" id="h65nGmP2BL"/>
|
||||||
|
</defs>
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path fill="none" fill-opacity="null" id="svg_11" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02"/>
|
||||||
|
<ellipse cx="103.84" cy="562.04" fill="#202020" id="svg_3" rx="80" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 103.843, 562.038)"/>
|
||||||
|
<ellipse cx="506" cy="554" fill="#202020" id="svg_4" rx="77" ry="45" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-18.699, 506, 554)"/>
|
||||||
|
<rect fill="#202020" height="359" id="svg_7" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" stroke-width="0" width="58" x="122" y="185"/>
|
||||||
|
<rect fill="#202020" height="453" id="svg_8" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="58" x="522" y="84.5"/>
|
||||||
|
<rect fill="#202020" height="37" id="svg_9" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-14.1985, 351.556, 146.245)" width="463.07" x="120.02" y="127.74"/>
|
||||||
|
<rect fill="none" fill-opacity="null" height="0" id="svg_10" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="538.25" y="107.12"/>
|
||||||
|
<path d="m537.42,112.06l0,-67.88l17.58,67.88z" fill="#202020" id="svg_16" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" transform="rotate(-90, 546.203, 78.1248)"/>
|
||||||
|
<rect fill="#202020" height="0" id="svg_18" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="0.02" width="0" x="82.12" y="287.56"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.1 KiB |
10
data/res/images/LightRegex.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" version="1.1">
|
||||||
|
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
|
||||||
|
|
||||||
|
<g class="layer">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<text fill="#202020" font-family="Serif" font-size="24" id="svg_1" stroke="#000000" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="null" stroke-width="0" text-anchor="middle" transform="matrix(1.0974, 0, 0, 1.0974, -4.98544, 4.97639)" x="14" xml:space="preserve" y="13">*</text>
|
||||||
|
<rect fill="#202020" height="3.3" id="svg_2" stroke="#202020" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" transform="matrix(1, 0, 0, 1, 0, 0)" width="5" x="1" y="12"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 815 B |
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
data/res/images/LightTime.svg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#202020" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#202020" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#202020" fill-opacity="1"></use></g></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
BIN
data/res/ocr/eng.traineddata
Normal file
2
deps/asio
vendored
1
deps/cpp-httplib
vendored
Submodule
41032
deps/exprtk/exprtk.hpp
vendored
Normal file
1
deps/json
vendored
Submodule
1
deps/leptonica
vendored
Submodule
1
deps/libremidi
vendored
Submodule
1
deps/tesseract
vendored
Submodule
2
deps/websocketpp
vendored
@@ -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,54 @@
|
|||||||
</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>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="warnPluginLoadFailure">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_19">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_24">
|
<layout class="QHBoxLayout" name="horizontalLayout_24">
|
||||||
<item>
|
<item>
|
||||||
@@ -634,7 +682,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="MacroTree" name="macros">
|
<widget class="advss::MacroTree" name="macros">
|
||||||
<property name="showDropIndicator" stdset="0">
|
<property name="showDropIndicator" stdset="0">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@@ -781,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>
|
||||||
@@ -795,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>
|
||||||
@@ -888,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">
|
||||||
@@ -964,6 +1022,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="conditionTop">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>22</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="conditionUp">
|
<widget class="QPushButton" name="conditionUp">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
@@ -999,6 +1070,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="conditionBottom">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>22</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_15">
|
<spacer name="horizontalSpacer_15">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -1016,144 +1100,376 @@
|
|||||||
</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="actionUp">
|
<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>
|
||||||
<property name="themeID" stdset="0">
|
</property>
|
||||||
<string notr="true">upArrowIconSmall</string>
|
</spacer>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="actionTop">
|
||||||
<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>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="themeID" stdset="0">
|
<item>
|
||||||
<string notr="true">downArrowIconSmall</string>
|
<widget class="QPushButton" name="actionUp">
|
||||||
</property>
|
<property name="maximumSize">
|
||||||
</widget>
|
<size>
|
||||||
</item>
|
<width>22</width>
|
||||||
<item>
|
<height>16777215</height>
|
||||||
<spacer name="horizontalSpacer_14">
|
</size>
|
||||||
<property name="orientation">
|
</property>
|
||||||
<enum>Qt::Horizontal</enum>
|
<property name="flat">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="sizeHint" stdset="0">
|
</property>
|
||||||
<size>
|
<property name="themeID" stdset="0">
|
||||||
<width>40</width>
|
<string notr="true">upArrowIconSmall</string>
|
||||||
<height>20</height>
|
</property>
|
||||||
</size>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</spacer>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="actionDown">
|
||||||
</layout>
|
<property name="maximumSize">
|
||||||
</item>
|
<size>
|
||||||
</layout>
|
<width>22</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="themeID" stdset="0">
|
||||||
|
<string notr="true">downArrowIconSmall</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="actionBottom">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>22</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_14">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="toggleElseActions">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>22</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="macroElseActions" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="macroElseActionsLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="advss::MacroSegmentList" name="elseActionsList">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>1</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="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>
|
||||||
@@ -4539,10 +4855,21 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>MacroTree</class>
|
<class>advss::MacroTree</class>
|
||||||
<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,34 +1,22 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "status-control.hpp"
|
||||||
|
#include "scene-switch-helpers.hpp"
|
||||||
|
#include "curl-helper.hpp"
|
||||||
|
#include "platform-funcs.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "status-control.hpp"
|
|
||||||
#include "curl-helper.hpp"
|
|
||||||
#include "utility.hpp"
|
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
const char *obs_module_text(const char *text)
|
|
||||||
{
|
|
||||||
return switcher->translate(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_module_t *obs_current_module()
|
|
||||||
{
|
|
||||||
return switcher->modulePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwitcherData *switcher = nullptr;
|
|
||||||
SwitcherData *GetSwitcher()
|
|
||||||
{
|
|
||||||
return switcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
AdvSceneSwitcher *AdvSceneSwitcher::window = nullptr;
|
AdvSceneSwitcher *AdvSceneSwitcher::window = nullptr;
|
||||||
|
|
||||||
@@ -40,11 +28,9 @@ AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent)
|
|||||||
{
|
{
|
||||||
switcher->settingsWindowOpened = true;
|
switcher->settingsWindowOpened = true;
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
|
|
||||||
switcher->Prune();
|
switcher->Prune();
|
||||||
loadUI();
|
LoadUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvSceneSwitcher::~AdvSceneSwitcher()
|
AdvSceneSwitcher::~AdvSceneSwitcher()
|
||||||
@@ -55,65 +41,113 @@ AdvSceneSwitcher::~AdvSceneSwitcher()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool translationAvailable()
|
static bool translationAvailable()
|
||||||
{
|
{
|
||||||
return !!strcmp(obs_module_text("AdvSceneSwitcher.pluginName"),
|
return !!strcmp(obs_module_text("AdvSceneSwitcher.pluginName"),
|
||||||
"AdvSceneSwitcher.pluginName");
|
"AdvSceneSwitcher.pluginName");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::loadUI()
|
static void DisplayMissingDependencyWarning()
|
||||||
{
|
{
|
||||||
if (!translationAvailable()) {
|
if (!switcher->warnPluginLoadFailure ||
|
||||||
QString msg = "Failed to find plug-in's 'data' directory.\n"
|
switcher->loadFailureLibs.isEmpty()) {
|
||||||
"Please check installation instructions!\n\n"
|
return;
|
||||||
"Data most likely expected at:\n\n";
|
|
||||||
#ifdef _WIN32
|
|
||||||
msg += QString::fromStdString(
|
|
||||||
(std::filesystem::current_path().string()));
|
|
||||||
msg += "/";
|
|
||||||
#endif
|
|
||||||
msg += obs_get_module_data_path(obs_current_module());
|
|
||||||
(void)DisplayMessage(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupGeneralTab();
|
QString failedLibsString = "<ul>";
|
||||||
setupTitleTab();
|
for (const auto &lib : switcher->loadFailureLibs) {
|
||||||
setupExecutableTab();
|
failedLibsString += "<li>" + lib + "</li>";
|
||||||
setupRegionTab();
|
}
|
||||||
setupPauseTab();
|
failedLibsString += "</ul>";
|
||||||
setupSequenceTab();
|
QString warning(obs_module_text(
|
||||||
setupTransitionsTab();
|
"AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage"));
|
||||||
setupIdleTab();
|
DisplayMessage(warning.arg(failedLibsString));
|
||||||
setupRandomTab();
|
}
|
||||||
setupMediaTab();
|
|
||||||
setupFileTab();
|
|
||||||
setupTimeTab();
|
|
||||||
setupAudioTab();
|
|
||||||
setupVideoTab();
|
|
||||||
setupNetworkTab();
|
|
||||||
setupSceneGroupTab();
|
|
||||||
setupTriggerTab();
|
|
||||||
setupMacroTab();
|
|
||||||
|
|
||||||
setDeprecationWarnings();
|
static void DisplayMissingDataDirWarning()
|
||||||
setTabOrder();
|
{
|
||||||
setCurrentTab();
|
if (translationAvailable()) {
|
||||||
restoreWindowGeo();
|
return;
|
||||||
checkFirstTimeSetup();
|
}
|
||||||
|
|
||||||
|
QString msg = "Failed to find plug-in's 'data' directory.\n"
|
||||||
|
"Please check installation instructions!\n\n"
|
||||||
|
"Data most likely expected at:\n\n";
|
||||||
|
#ifdef _WIN32
|
||||||
|
msg += QString::fromStdString(
|
||||||
|
(std::filesystem::current_path().string()));
|
||||||
|
msg += "/";
|
||||||
|
#endif
|
||||||
|
msg += obs_get_module_data_path(obs_current_module());
|
||||||
|
DisplayMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::LoadUI()
|
||||||
|
{
|
||||||
|
DisplayMissingDataDirWarning();
|
||||||
|
DisplayMissingDependencyWarning();
|
||||||
|
|
||||||
|
SetupGeneralTab();
|
||||||
|
SetupTitleTab();
|
||||||
|
SetupExecutableTab();
|
||||||
|
SetupRegionTab();
|
||||||
|
SetupPauseTab();
|
||||||
|
SetupSequenceTab();
|
||||||
|
SetupTransitionsTab();
|
||||||
|
SetupIdleTab();
|
||||||
|
SetupRandomTab();
|
||||||
|
SetupMediaTab();
|
||||||
|
SetupFileTab();
|
||||||
|
SetupTimeTab();
|
||||||
|
SetupAudioTab();
|
||||||
|
SetupVideoTab();
|
||||||
|
SetupNetworkTab();
|
||||||
|
SetupSceneGroupTab();
|
||||||
|
SetupTriggerTab();
|
||||||
|
SetupMacroTab();
|
||||||
|
|
||||||
|
SetDeprecationWarnings();
|
||||||
|
SetTabOrder();
|
||||||
|
SetCurrentTab();
|
||||||
|
RestoreWindowGeo();
|
||||||
|
CheckFirstTimeSetup();
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
auto eventType = event->type();
|
||||||
|
if (obj == ui->macroElseActions && eventType == QEvent::Resize) {
|
||||||
|
QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event);
|
||||||
|
|
||||||
|
if (resizeEvent->size().height() == 0) {
|
||||||
|
SetElseActionsStateToHidden();
|
||||||
|
return QDialog::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetElseActionsStateToVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QDialog::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Saving and loading
|
* Saving and loading
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
static void AskForBackup(obs_data_t *obj);
|
||||||
|
|
||||||
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||||
{
|
{
|
||||||
|
if (!switcher) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (saving) {
|
if (saving) {
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->Prune();
|
switcher->Prune();
|
||||||
obs_data_t *obj = obs_data_create();
|
obs_data_t *obj = obs_data_create();
|
||||||
switcher->saveSettings(obj);
|
switcher->SaveSettings(obj);
|
||||||
obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
|
obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
|
||||||
obs_data_release(obj);
|
obs_data_release(obj);
|
||||||
} else {
|
} else {
|
||||||
@@ -127,10 +161,10 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||||||
if (!obj) {
|
if (!obj) {
|
||||||
obj = obs_data_create();
|
obj = obs_data_create();
|
||||||
}
|
}
|
||||||
if (switcher->versionChanged(obj, g_GIT_SHA1)) {
|
if (switcher->VersionChanged(obj, g_GIT_SHA1)) {
|
||||||
AskForBackup(obj);
|
AskForBackup(obj);
|
||||||
}
|
}
|
||||||
switcher->loadSettings(obj);
|
switcher->LoadSettings(obj);
|
||||||
obs_data_release(obj);
|
obs_data_release(obj);
|
||||||
switcher->m.unlock();
|
switcher->m.unlock();
|
||||||
|
|
||||||
@@ -140,6 +174,34 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AskForBackup(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
bool backupSettings = DisplayMessage(
|
||||||
|
obs_module_text("AdvSceneSwitcher.askBackup"), true);
|
||||||
|
|
||||||
|
if (!backupSettings) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString path = QFileDialog::getSaveFileName(
|
||||||
|
nullptr,
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle"),
|
||||||
|
GetDefaultSettingsSaveLocation(),
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType"));
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile file(path);
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Main switcher thread
|
* Main switcher thread
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -183,7 +245,7 @@ void SwitcherData::Thread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
vblog(LOG_INFO, "try to sleep for %ld", duration.count());
|
vblog(LOG_INFO, "try to sleep for %ld", duration.count());
|
||||||
setWaitScene();
|
SetWaitScene();
|
||||||
cv.wait_for(lock, duration);
|
cv.wait_for(lock, duration);
|
||||||
|
|
||||||
startTime = std::chrono::high_resolution_clock::now();
|
startTime = std::chrono::high_resolution_clock::now();
|
||||||
@@ -197,13 +259,13 @@ void SwitcherData::Thread()
|
|||||||
if (checkPause()) {
|
if (checkPause()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
setPreconditions();
|
SetPreconditions();
|
||||||
match = checkForMatch(scene, transition, linger,
|
match = CheckForMatch(scene, transition, linger,
|
||||||
setPrevSceneAfterLinger, macroMatch);
|
setPrevSceneAfterLinger, macroMatch);
|
||||||
if (stop) {
|
if (stop) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
checkNoMatchSwitch(match, scene, transition, sleep);
|
CheckNoMatchSwitch(match, scene, transition, sleep);
|
||||||
checkSwitchCooldown(match);
|
checkSwitchCooldown(match);
|
||||||
|
|
||||||
if (linger) {
|
if (linger) {
|
||||||
@@ -211,14 +273,14 @@ void SwitcherData::Thread()
|
|||||||
vblog(LOG_INFO, "sleep for %ld before switching scene",
|
vblog(LOG_INFO, "sleep for %ld before switching scene",
|
||||||
duration.count());
|
duration.count());
|
||||||
|
|
||||||
setWaitScene();
|
SetWaitScene();
|
||||||
cv.wait_for(lock, duration);
|
cv.wait_for(lock, duration);
|
||||||
|
|
||||||
if (stop) {
|
if (stop) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneChangedDuringWait()) {
|
if (SceneChangedDuringWait()) {
|
||||||
vblog(LOG_INFO,
|
vblog(LOG_INFO,
|
||||||
"scene was changed manually - ignoring match");
|
"scene was changed manually - ignoring match");
|
||||||
|
|
||||||
@@ -229,13 +291,13 @@ void SwitcherData::Thread()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearWebsocketMessages();
|
ResetForNextInterval();
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
if (macroMatch) {
|
if (macroMatch) {
|
||||||
runMacros();
|
RunMacros();
|
||||||
} else {
|
} else {
|
||||||
switchScene({scene, transition, 0});
|
SwitchScene({scene, transition, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,10 +306,11 @@ void SwitcherData::Thread()
|
|||||||
switcher->firstIntervalAfterStop = false;
|
switcher->firstIntervalAfterStop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mainLoopLock = nullptr;
|
||||||
blog(LOG_INFO, "stopped");
|
blog(LOG_INFO, "stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::setPreconditions()
|
void SwitcherData::SetPreconditions()
|
||||||
{
|
{
|
||||||
// Window title
|
// Window title
|
||||||
lastTitle = currentTitle;
|
lastTitle = currentTitle;
|
||||||
@@ -275,13 +338,24 @@ void SwitcherData::setPreconditions()
|
|||||||
GetForegroundProcessName(currentForegroundProcess);
|
GetForegroundProcessName(currentForegroundProcess);
|
||||||
|
|
||||||
// Cursor
|
// Cursor
|
||||||
std::pair<int, int> cursorPos = getCursorPos();
|
std::pair<int, int> cursorPos = GetCursorPos();
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwitcherData::checkForMatch(OBSWeakSource &scene,
|
void SwitcherData::ResetForNextInterval()
|
||||||
|
{
|
||||||
|
// Plugin reset functions
|
||||||
|
for (const auto &func : resetIntervalSteps) {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SwitcherData::CheckForMatch(OBSWeakSource &scene,
|
||||||
OBSWeakSource &transition, int &linger,
|
OBSWeakSource &transition, int &linger,
|
||||||
bool &setPrevSceneAfterLinger,
|
bool &setPrevSceneAfterLinger,
|
||||||
bool ¯oMatch)
|
bool ¯oMatch)
|
||||||
@@ -331,7 +405,7 @@ bool SwitcherData::checkForMatch(OBSWeakSource &scene,
|
|||||||
match = checkVideoSwitch(scene, transition);
|
match = checkVideoSwitch(scene, transition);
|
||||||
break;
|
break;
|
||||||
case macro_func:
|
case macro_func:
|
||||||
if (checkMacros()) {
|
if (CheckMacros()) {
|
||||||
match = true;
|
match = true;
|
||||||
macroMatch = true;
|
macroMatch = true;
|
||||||
}
|
}
|
||||||
@@ -348,48 +422,20 @@ bool SwitcherData::checkForMatch(OBSWeakSource &scene,
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchScene(const sceneSwitchInfo &sceneSwitch, bool force)
|
static void ResetMacros()
|
||||||
{
|
{
|
||||||
if (!sceneSwitch.scene && switcher->verbose) {
|
for (auto &m : switcher->macros) {
|
||||||
blog(LOG_INFO, "nothing to switch to");
|
m->ResetRunCount();
|
||||||
return;
|
m->ResetTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_t *source = obs_weak_source_get_source(sceneSwitch.scene);
|
|
||||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
|
||||||
|
|
||||||
if (source && (source != currentSource || force)) {
|
|
||||||
transitionData currentTransitionData;
|
|
||||||
setNextTransition(sceneSwitch, currentSource,
|
|
||||||
currentTransitionData);
|
|
||||||
obs_frontend_set_current_scene(source);
|
|
||||||
if (switcher->transitionOverrideOverride) {
|
|
||||||
restoreTransitionOverride(source,
|
|
||||||
currentTransitionData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switcher->verbose) {
|
|
||||||
blog(LOG_INFO, "switched scene");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switcher->networkConfig.ShouldSendSceneChange()) {
|
|
||||||
switcher->server.sendMessage(sceneSwitch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
obs_source_release(currentSource);
|
|
||||||
obs_source_release(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
void switchPreviewScene(const OBSWeakSource &ws)
|
|
||||||
{
|
|
||||||
auto source = obs_weak_source_get_source(ws);
|
|
||||||
obs_frontend_set_current_preview_scene(source);
|
|
||||||
obs_source_release(source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::Start()
|
void SwitcherData::Start()
|
||||||
{
|
{
|
||||||
if (!(th && th->isRunning())) {
|
if (!(th && th->isRunning())) {
|
||||||
|
ResetForNextInterval();
|
||||||
|
ResetMacros();
|
||||||
|
|
||||||
stop = false;
|
stop = false;
|
||||||
th = new SwitcherThread();
|
th = new SwitcherThread();
|
||||||
th->start((QThread::Priority)threadPriority);
|
th->start((QThread::Priority)threadPriority);
|
||||||
@@ -414,13 +460,7 @@ void SwitcherData::Start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetMacros()
|
bool CloseAllInputDialogs();
|
||||||
{
|
|
||||||
for (auto &m : switcher->macros) {
|
|
||||||
m->ResetRunCount();
|
|
||||||
m->ResetTimers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SwitcherData::Stop()
|
void SwitcherData::Stop()
|
||||||
{
|
{
|
||||||
@@ -430,12 +470,24 @@ void SwitcherData::Stop()
|
|||||||
abortMacroWait = true;
|
abortMacroWait = true;
|
||||||
macroWaitCv.notify_all();
|
macroWaitCv.notify_all();
|
||||||
macroTransitionCv.notify_all();
|
macroTransitionCv.notify_all();
|
||||||
th->wait();
|
|
||||||
delete th;
|
|
||||||
th = nullptr;
|
|
||||||
|
|
||||||
|
// Not waiting if a dialog was closed is a workaround to avoid
|
||||||
|
// deadlocks when a variable input dialog is opened while Stop()
|
||||||
|
// is called.
|
||||||
|
//
|
||||||
|
// The QEventLoop handling the dialog would not exit until Stop()
|
||||||
|
// would return, which itself would wait for the switcher thread
|
||||||
|
// to complete, which itself is blocked by the variable input
|
||||||
|
// dialog.
|
||||||
|
//
|
||||||
|
// Must be reworked in the future, as this will not go well when
|
||||||
|
// OBS is shutting down and a dialog is still opened.
|
||||||
|
if (!CloseAllInputDialogs()) {
|
||||||
|
th->wait();
|
||||||
|
delete th;
|
||||||
|
th = nullptr;
|
||||||
|
}
|
||||||
writeToStatusFile("Advanced Scene Switcher stopped");
|
writeToStatusFile("Advanced Scene Switcher stopped");
|
||||||
ResetMacros();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
server.stop();
|
server.stop();
|
||||||
@@ -448,13 +500,13 @@ void SwitcherData::Stop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::setWaitScene()
|
void SwitcherData::SetWaitScene()
|
||||||
{
|
{
|
||||||
waitScene = obs_frontend_get_current_scene();
|
waitScene = obs_frontend_get_current_scene();
|
||||||
obs_source_release(waitScene);
|
obs_source_release(waitScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwitcherData::sceneChangedDuringWait()
|
bool SwitcherData::SceneChangedDuringWait()
|
||||||
{
|
{
|
||||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
||||||
if (!currentSource) {
|
if (!currentSource) {
|
||||||
@@ -467,7 +519,7 @@ bool SwitcherData::sceneChangedDuringWait()
|
|||||||
// Relies on the fact that switcher->currentScene will only be updated on event
|
// Relies on the fact that switcher->currentScene will only be updated on event
|
||||||
// OBS_FRONTEND_EVENT_SCENE_CHANGED but obs_frontend_get_current_scene() will
|
// OBS_FRONTEND_EVENT_SCENE_CHANGED but obs_frontend_get_current_scene() will
|
||||||
// already return the scene to be transitioned to.
|
// already return the scene to be transitioned to.
|
||||||
bool SwitcherData::anySceneTransitionStarted()
|
bool SwitcherData::AnySceneTransitionStarted()
|
||||||
{
|
{
|
||||||
auto currentSceneSrouce = obs_frontend_get_current_scene();
|
auto currentSceneSrouce = obs_frontend_get_current_scene();
|
||||||
auto currentScene = obs_source_get_weak_source(currentSceneSrouce);
|
auto currentScene = obs_source_get_weak_source(currentSceneSrouce);
|
||||||
@@ -488,13 +540,13 @@ extern "C" void FreeSceneSwitcher()
|
|||||||
switcher = nullptr;
|
switcher = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleSceneChange()
|
static void handleSceneChange()
|
||||||
{
|
{
|
||||||
switcher->lastSceneChangeTime =
|
switcher->lastSceneChangeTime =
|
||||||
std::chrono::high_resolution_clock::now();
|
std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
// Stop waiting if scene was changed
|
// Stop waiting if scene was changed
|
||||||
if (switcher->sceneChangedDuringWait()) {
|
if (switcher->SceneChangedDuringWait()) {
|
||||||
switcher->cv.notify_one();
|
switcher->cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,31 +574,33 @@ void handleSceneChange()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLiveTime()
|
static void setLiveTime()
|
||||||
{
|
{
|
||||||
switcher->liveTime = QDateTime::currentDateTime();
|
switcher->liveTime = QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetLiveTime()
|
static void resetLiveTime()
|
||||||
{
|
{
|
||||||
switcher->liveTime = QDateTime();
|
switcher->liveTime = QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAutoStartRecording()
|
static void checkAutoStartRecording()
|
||||||
{
|
{
|
||||||
if (switcher->autoStartEvent == AutoStartEvent::RECORDING ||
|
if (switcher->autoStartEvent == SwitcherData::AutoStart::RECORDING ||
|
||||||
switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
switcher->autoStartEvent ==
|
||||||
|
SwitcherData::AutoStart::RECORINDG_OR_STREAMING)
|
||||||
switcher->Start();
|
switcher->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAutoStartStreaming()
|
static void checkAutoStartStreaming()
|
||||||
{
|
{
|
||||||
if (switcher->autoStartEvent == AutoStartEvent::STREAMING ||
|
if (switcher->autoStartEvent == SwitcherData::AutoStart::STREAMING ||
|
||||||
switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
switcher->autoStartEvent ==
|
||||||
|
SwitcherData::AutoStart::RECORINDG_OR_STREAMING)
|
||||||
switcher->Start();
|
switcher->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlePeviewSceneChange()
|
static void handlePeviewSceneChange()
|
||||||
{
|
{
|
||||||
if (switcher->networkConfig.ShouldSendPrviewSceneChange()) {
|
if (switcher->networkConfig.ShouldSendPrviewSceneChange()) {
|
||||||
auto source = obs_frontend_get_current_preview_scene();
|
auto source = obs_frontend_get_current_preview_scene();
|
||||||
@@ -557,43 +611,51 @@ void handlePeviewSceneChange()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setReplayBufferSaved()
|
static void setReplayBufferSaved()
|
||||||
{
|
{
|
||||||
switcher->replayBufferSaved = true;
|
switcher->replayBufferSaved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTranstionEnd()
|
static void setTranstionEnd()
|
||||||
{
|
{
|
||||||
switcher->lastTransitionEndTime =
|
switcher->lastTransitionEndTime =
|
||||||
std::chrono::high_resolution_clock::now();
|
std::chrono::high_resolution_clock::now();
|
||||||
switcher->macroTransitionCv.notify_all();
|
switcher->macroTransitionCv.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStreamStarting()
|
static void setStreamStarting()
|
||||||
{
|
{
|
||||||
switcher->lastStreamStartingTime =
|
switcher->lastStreamStartingTime =
|
||||||
std::chrono::high_resolution_clock::now();
|
std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStreamStopping()
|
static void setStreamStopping()
|
||||||
{
|
{
|
||||||
switcher->lastStreamStoppingTime =
|
switcher->lastStreamStoppingTime =
|
||||||
std::chrono::high_resolution_clock::now();
|
std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleExit()
|
static void handleShutdown()
|
||||||
{
|
{
|
||||||
switcher->obsIsShuttingDown = true;
|
if (!switcher) {
|
||||||
if (switcher && switcher->obsIsShuttingDown &&
|
return;
|
||||||
switcher->shutdownConditionCount) {
|
}
|
||||||
switcher->Stop();
|
switcher->obsIsShuttingDown = true;
|
||||||
switcher->checkMacros();
|
if (switcher->shutdownConditionCount) {
|
||||||
switcher->runMacros();
|
switcher->Stop();
|
||||||
|
switcher->CheckMacros();
|
||||||
|
switcher->RunMacros();
|
||||||
|
|
||||||
|
// Unfortunately this will not work as OBS will now allow saving
|
||||||
|
// the scene collection data at this point, So any OBS specific
|
||||||
|
// changes done during shutdown will be lost
|
||||||
|
//
|
||||||
|
// TODO: Look for a way to possibly resolve this
|
||||||
|
obs_frontend_save();
|
||||||
}
|
}
|
||||||
FreeSceneSwitcher();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleSceneCollectionChanging()
|
static void handleSceneCollectionChanging()
|
||||||
{
|
{
|
||||||
if (switcher->settingsWindowOpened) {
|
if (switcher->settingsWindowOpened) {
|
||||||
AdvSceneSwitcher::window->close();
|
AdvSceneSwitcher::window->close();
|
||||||
@@ -614,8 +676,12 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case OBS_FRONTEND_EVENT_EXIT:
|
case OBS_FRONTEND_EVENT_SCRIPTING_SHUTDOWN:
|
||||||
handleExit();
|
// Note: We are intentionally not listening for
|
||||||
|
// OBS_FRONTEND_EVENT_EXIT here as at that point all scene
|
||||||
|
// collection data will already have been cleared and thus all
|
||||||
|
// macros will have already been cleared
|
||||||
|
handleShutdown();
|
||||||
break;
|
break;
|
||||||
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
|
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
|
||||||
handleSceneChange();
|
handleSceneChange();
|
||||||
@@ -653,13 +719,16 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
|||||||
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGING:
|
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGING:
|
||||||
handleSceneCollectionChanging();
|
handleSceneCollectionChanging();
|
||||||
break;
|
break;
|
||||||
|
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP:
|
||||||
|
SaveSceneSwitcher(nullptr, false, nullptr);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadPlugins()
|
static void LoadPlugins()
|
||||||
{
|
{
|
||||||
QFileInfo libPath(
|
QFileInfo libPath(
|
||||||
QString(obs_get_module_binary_path(obs_current_module())));
|
QString(obs_get_module_binary_path(obs_current_module())));
|
||||||
@@ -683,6 +752,7 @@ void LoadPlugins()
|
|||||||
blog(LOG_WARNING, "failed to load \"%s\": %s",
|
blog(LOG_WARNING, "failed to load \"%s\": %s",
|
||||||
file.toStdString().c_str(),
|
file.toStdString().c_str(),
|
||||||
lib->errorString().toStdString().c_str());
|
lib->errorString().toStdString().c_str());
|
||||||
|
switcher->loadFailureLibs << file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -702,18 +772,21 @@ void OpenSettingsWindow()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void InitSceneSwitcher(obs_module_t *m, translateFunc t)
|
void SetupConnectionManager();
|
||||||
|
void SetupWebsocketHelpers();
|
||||||
|
|
||||||
|
extern "C" void InitSceneSwitcher(obs_module_t *module, translateFunc translate)
|
||||||
{
|
{
|
||||||
blog(LOG_INFO, "version: %s", g_GIT_TAG);
|
blog(LOG_INFO, "version: %s", g_GIT_TAG);
|
||||||
blog(LOG_INFO, "version: %s", g_GIT_SHA1);
|
blog(LOG_INFO, "version: %s", g_GIT_SHA1);
|
||||||
|
|
||||||
switcher = new SwitcherData;
|
switcher = new SwitcherData(module, translate);
|
||||||
switcher->modulePtr = m;
|
|
||||||
switcher->translate = t;
|
|
||||||
|
|
||||||
PlatformInit();
|
PlatformInit();
|
||||||
LoadPlugins();
|
LoadPlugins();
|
||||||
SetupDock();
|
SetupDock();
|
||||||
|
SetupConnectionManager();
|
||||||
|
SetupWebsocketHelpers();
|
||||||
|
|
||||||
obs_frontend_add_save_callback(SaveSceneSwitcher, nullptr);
|
obs_frontend_add_save_callback(SaveSceneSwitcher, nullptr);
|
||||||
obs_frontend_add_event_callback(OBSEvent, switcher);
|
obs_frontend_add_event_callback(OBSEvent, switcher);
|
||||||
@@ -722,3 +795,5 @@ extern "C" void InitSceneSwitcher(obs_module_t *m, translateFunc t)
|
|||||||
obs_module_text("AdvSceneSwitcher.pluginName"));
|
obs_module_text("AdvSceneSwitcher.pluginName"));
|
||||||
action->connect(action, &QAction::triggered, OpenSettingsWindow);
|
action->connect(action, &QAction::triggered, OpenSettingsWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "switcher-data-structs.hpp"
|
#include "macro-segment-list.hpp"
|
||||||
#include "platform-funcs.hpp"
|
#include "log-helper.hpp"
|
||||||
|
|
||||||
#include <macro-segment-list.hpp>
|
|
||||||
#include <ui_advanced-scene-switcher.h>
|
#include <ui_advanced-scene-switcher.h>
|
||||||
|
|
||||||
#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__)
|
|
||||||
#define vblog(level, msg, ...) \
|
|
||||||
if (switcher->verbose) { \
|
|
||||||
blog(level, msg, ##__VA_ARGS__); \
|
|
||||||
}
|
|
||||||
|
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
class MacroActionEdit;
|
class MacroActionEdit;
|
||||||
class MacroConditionEdit;
|
class MacroConditionEdit;
|
||||||
|
class Duration;
|
||||||
|
class SequenceWidget;
|
||||||
|
struct SceneGroup;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Advanced Scene Switcher window
|
* Advanced Scene Switcher window
|
||||||
@@ -33,130 +32,139 @@ public:
|
|||||||
void reject() override;
|
void reject() override;
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
void SetShowFrames();
|
void LoadUI();
|
||||||
void SetHideFrames();
|
|
||||||
void clearFrames(QListWidget *list);
|
|
||||||
|
|
||||||
int IgnoreWindowsFindByData(const QString &window);
|
void SetTabOrder();
|
||||||
int IgnoreIdleWindowsFindByData(const QString &window);
|
void SetCurrentTab();
|
||||||
|
void RestoreWindowGeo();
|
||||||
|
void CheckFirstTimeSetup();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
|
/* --- Begin of general tab section --- */
|
||||||
|
public:
|
||||||
|
void SetupGeneralTab();
|
||||||
void UpdateNonMatchingScene(const QString &name);
|
void UpdateNonMatchingScene(const QString &name);
|
||||||
void OpenSequenceExtendEdit(SequenceWidget *sw);
|
void SetDeprecationWarnings();
|
||||||
void SetEditSceneGroup(SceneGroup &sg);
|
|
||||||
|
|
||||||
bool addNewMacro(std::shared_ptr<Macro> &res, std::string &name,
|
|
||||||
std::string format = "");
|
|
||||||
std::shared_ptr<Macro> getSelectedMacro();
|
|
||||||
void SetEditMacro(Macro &m);
|
|
||||||
void SetMacroEditAreaDisabled(bool);
|
|
||||||
void HighlightAction(int idx, QColor color = QColor(Qt::green));
|
|
||||||
void HighlightCondition(int idx, QColor color = QColor(Qt::green));
|
|
||||||
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
|
|
||||||
void PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
|
|
||||||
void SetActionData(Macro &m);
|
|
||||||
void SetConditionData(Macro &m);
|
|
||||||
void SwapActions(Macro *m, int pos1, int pos2);
|
|
||||||
void SwapConditions(Macro *m, int pos1, int pos2);
|
|
||||||
|
|
||||||
void loadUI();
|
|
||||||
void setupGeneralTab();
|
|
||||||
void setupTitleTab();
|
|
||||||
void setupExecutableTab();
|
|
||||||
void setupRegionTab();
|
|
||||||
void setupPauseTab();
|
|
||||||
void setupSequenceTab();
|
|
||||||
void setupTransitionsTab();
|
|
||||||
void setupIdleTab();
|
|
||||||
void setupRandomTab();
|
|
||||||
void setupMediaTab();
|
|
||||||
void setupFileTab();
|
|
||||||
void setupTimeTab();
|
|
||||||
void setupAudioTab();
|
|
||||||
void setupSceneGroupTab();
|
|
||||||
void setupTriggerTab();
|
|
||||||
void setupVideoTab();
|
|
||||||
void setupNetworkTab();
|
|
||||||
void setupMacroTab();
|
|
||||||
void setDeprecationWarnings();
|
|
||||||
void setTabOrder();
|
|
||||||
void setCurrentTab();
|
|
||||||
void restoreWindowGeo();
|
|
||||||
void checkFirstTimeSetup();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void MacroAdded(const QString &name);
|
|
||||||
void MacroRemoved(const QString &name);
|
|
||||||
void MacroRenamed(const QString &oldName, const QString &newName);
|
|
||||||
void MacroSegmentOrderChanged();
|
|
||||||
void HighlightMacrosChanged(bool value);
|
|
||||||
void HighlightActionsChanged(bool value);
|
|
||||||
void HighlightConditionsChanged(bool value);
|
|
||||||
void SceneGroupAdded(const QString &name);
|
|
||||||
void SceneGroupRemoved(const QString &name);
|
|
||||||
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
|
||||||
void ConnectionAdded(const QString &);
|
|
||||||
void ConnectionRenamed(const QString &oldName, const QString &newName);
|
|
||||||
void ConnectionRemoved(const QString &);
|
|
||||||
void VariableAdded(const QString &);
|
|
||||||
void VariableRenamed(const QString &oldName, const QString &newName);
|
|
||||||
void VariableRemoved(const QString &);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void on_windowUp_clicked();
|
|
||||||
void on_windowDown_clicked();
|
|
||||||
void on_windowAdd_clicked();
|
|
||||||
void on_windowRemove_clicked();
|
|
||||||
void on_noMatchDontSwitch_clicked();
|
void on_noMatchDontSwitch_clicked();
|
||||||
void on_noMatchSwitch_clicked();
|
void on_noMatchSwitch_clicked();
|
||||||
void on_noMatchRandomSwitch_clicked();
|
void on_noMatchRandomSwitch_clicked();
|
||||||
void NoMatchDelayDurationChanged(double);
|
void NoMatchDelayDurationChanged(const Duration &);
|
||||||
void NoMatchDelayUnitChanged(DurationUnit);
|
void CooldownDurationChanged(const Duration &);
|
||||||
void CooldownDurationChanged(double);
|
|
||||||
void CooldownUnitChanged(DurationUnit);
|
|
||||||
void on_startupBehavior_currentIndexChanged(int index);
|
void on_startupBehavior_currentIndexChanged(int index);
|
||||||
void on_autoStartEvent_currentIndexChanged(int index);
|
void on_autoStartEvent_currentIndexChanged(int index);
|
||||||
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
|
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
|
||||||
void on_checkInterval_valueChanged(int value);
|
void on_checkInterval_valueChanged(int value);
|
||||||
void on_tabMoved(int from, int to);
|
void on_tabMoved(int from, int to);
|
||||||
void on_tabWidget_currentChanged(int index);
|
void on_tabWidget_currentChanged(int index);
|
||||||
|
void on_exportSettings_clicked();
|
||||||
|
void on_importSettings_clicked();
|
||||||
|
void on_verboseLogging_stateChanged(int state);
|
||||||
|
void on_saveWindowGeo_stateChanged(int state);
|
||||||
|
void on_showTrayNotifications_stateChanged(int state);
|
||||||
|
void on_uiHintsDisable_stateChanged(int state);
|
||||||
|
void on_disableComboBoxFilter_stateChanged(int state);
|
||||||
|
void on_warnPluginLoadFailure_stateChanged(int state);
|
||||||
|
void on_hideLegacyTabs_stateChanged(int state);
|
||||||
|
void on_priorityUp_clicked();
|
||||||
|
void on_priorityDown_clicked();
|
||||||
|
void on_threadPriority_currentTextChanged(const QString &text);
|
||||||
|
|
||||||
|
/* --- End of legacy tab section --- */
|
||||||
|
|
||||||
|
/* --- Begin of macro tab section --- */
|
||||||
|
public:
|
||||||
|
void SetupMacroTab();
|
||||||
|
bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name,
|
||||||
|
std::string format = "");
|
||||||
|
void RemoveMacro(std::shared_ptr<Macro> &);
|
||||||
|
void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
|
||||||
|
std::shared_ptr<Macro> GetSelectedMacro();
|
||||||
|
std::vector<std::shared_ptr<Macro>> GetSelectedMacros();
|
||||||
|
void SetEditMacro(Macro &m);
|
||||||
|
void SetMacroEditAreaDisabled(bool);
|
||||||
|
void HighlightAction(int idx, QColor color = QColor(Qt::green));
|
||||||
|
void HighlightElseAction(int idx, QColor color = QColor(Qt::green));
|
||||||
|
void HighlightCondition(int idx, QColor color = QColor(Qt::green));
|
||||||
|
void PopulateMacroActions(Macro &m, uint32_t afterIdx = 0);
|
||||||
|
void PopulateMacroElseActions(Macro &m, uint32_t afterIdx = 0);
|
||||||
|
void PopulateMacroConditions(Macro &m, uint32_t afterIdx = 0);
|
||||||
|
void SetActionData(Macro &m);
|
||||||
|
void SetElseActionData(Macro &m);
|
||||||
|
void SetConditionData(Macro &m);
|
||||||
|
void SwapActions(Macro *m, int pos1, int pos2);
|
||||||
|
void SwapConditions(Macro *m, int pos1, int pos2);
|
||||||
|
|
||||||
|
public slots:
|
||||||
void on_macroAdd_clicked();
|
void on_macroAdd_clicked();
|
||||||
void on_macroRemove_clicked();
|
void on_macroRemove_clicked();
|
||||||
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();
|
||||||
void on_conditionRemove_clicked();
|
void on_conditionRemove_clicked();
|
||||||
|
void on_conditionTop_clicked();
|
||||||
void on_conditionUp_clicked();
|
void on_conditionUp_clicked();
|
||||||
void on_conditionDown_clicked();
|
void on_conditionDown_clicked();
|
||||||
|
void on_conditionBottom_clicked();
|
||||||
void on_actionAdd_clicked();
|
void on_actionAdd_clicked();
|
||||||
void on_actionRemove_clicked();
|
void on_actionRemove_clicked();
|
||||||
|
void on_actionTop_clicked();
|
||||||
void on_actionUp_clicked();
|
void on_actionUp_clicked();
|
||||||
void on_actionDown_clicked();
|
void on_actionDown_clicked();
|
||||||
void MacroSelectionChanged(const QItemSelection &,
|
void on_actionBottom_clicked();
|
||||||
const QItemSelection &);
|
void on_toggleElseActions_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 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 ExportMacros();
|
||||||
|
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 SetElseActionsStateToHidden();
|
||||||
|
void SetElseActionsStateToVisible();
|
||||||
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);
|
||||||
@@ -171,22 +179,84 @@ public slots:
|
|||||||
void HighlightOnChange();
|
void HighlightOnChange();
|
||||||
void on_macroProperties_clicked();
|
void on_macroProperties_clicked();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void MacroAdded(const QString &name);
|
||||||
|
void MacroRemoved(const QString &name);
|
||||||
|
void MacroRenamed(const QString &oldName, const QString &newName);
|
||||||
|
void MacroSegmentOrderChanged();
|
||||||
|
void SegmentTempVarsChanged();
|
||||||
|
void HighlightMacrosChanged(bool value);
|
||||||
|
void HighlightActionsChanged(bool value);
|
||||||
|
void HighlightElseActionsChanged(bool value);
|
||||||
|
void HighlightConditionsChanged(bool value);
|
||||||
|
|
||||||
|
void ConnectionAdded(const QString &);
|
||||||
|
void ConnectionRenamed(const QString &oldName, const QString &newName);
|
||||||
|
void ConnectionRemoved(const QString &);
|
||||||
|
void VariableAdded(const QString &);
|
||||||
|
void VariableRenamed(const QString &oldName, const QString &newName);
|
||||||
|
void VariableRemoved(const QString &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class MacroSection { CONDITIONS, ACTIONS, ELSE_ACTIONS };
|
||||||
|
|
||||||
|
void SetupMacroSegmentSelection(MacroSection type, int idx);
|
||||||
|
bool ResolveMacroImportNameConflict(std::shared_ptr<Macro> &);
|
||||||
|
bool MacroTabIsInFocus();
|
||||||
|
|
||||||
|
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
||||||
|
int currentConditionIdx = -1;
|
||||||
|
int currentActionIdx = -1;
|
||||||
|
int currentElseActionIdx = -1;
|
||||||
|
|
||||||
|
/* --- End of macro tab section --- */
|
||||||
|
|
||||||
|
/* --- Begin of legacy tab section --- */
|
||||||
|
public:
|
||||||
|
void ClearFrames(QListWidget *list);
|
||||||
|
int IgnoreWindowsFindByData(const QString &window);
|
||||||
|
int IgnoreIdleWindowsFindByData(const QString &window);
|
||||||
|
void OpenSequenceExtendEdit(SequenceWidget *sw);
|
||||||
|
|
||||||
|
// Window tab
|
||||||
|
public:
|
||||||
|
void SetupTitleTab();
|
||||||
|
public slots:
|
||||||
|
void on_windowUp_clicked();
|
||||||
|
void on_windowDown_clicked();
|
||||||
|
void on_windowAdd_clicked();
|
||||||
|
void on_windowRemove_clicked();
|
||||||
|
void on_ignoreWindows_currentRowChanged(int idx);
|
||||||
|
void on_ignoreWindowsAdd_clicked();
|
||||||
|
void on_ignoreWindowsRemove_clicked();
|
||||||
|
|
||||||
|
// Screen region tab
|
||||||
|
public:
|
||||||
|
void SetupRegionTab();
|
||||||
|
public slots:
|
||||||
|
void SetShowFrames();
|
||||||
|
void SetHideFrames();
|
||||||
void on_screenRegionSwitches_currentRowChanged(int idx);
|
void on_screenRegionSwitches_currentRowChanged(int idx);
|
||||||
void on_showFrame_clicked();
|
void on_showFrame_clicked();
|
||||||
void on_screenRegionAdd_clicked();
|
void on_screenRegionAdd_clicked();
|
||||||
void on_screenRegionRemove_clicked();
|
void on_screenRegionRemove_clicked();
|
||||||
void on_screenRegionUp_clicked();
|
void on_screenRegionUp_clicked();
|
||||||
void on_screenRegionDown_clicked();
|
void on_screenRegionDown_clicked();
|
||||||
|
void updateScreenRegionCursorPos();
|
||||||
|
|
||||||
|
// Pause tab
|
||||||
|
public:
|
||||||
|
void SetupPauseTab();
|
||||||
|
public slots:
|
||||||
void on_pauseUp_clicked();
|
void on_pauseUp_clicked();
|
||||||
void on_pauseDown_clicked();
|
void on_pauseDown_clicked();
|
||||||
void on_pauseAdd_clicked();
|
void on_pauseAdd_clicked();
|
||||||
void on_pauseRemove_clicked();
|
void on_pauseRemove_clicked();
|
||||||
|
|
||||||
void on_ignoreWindows_currentRowChanged(int idx);
|
// Sequence tab
|
||||||
void on_ignoreWindowsAdd_clicked();
|
public:
|
||||||
void on_ignoreWindowsRemove_clicked();
|
void SetupSequenceTab();
|
||||||
|
public slots:
|
||||||
void on_sceneSequenceAdd_clicked();
|
void on_sceneSequenceAdd_clicked();
|
||||||
void on_sceneSequenceRemove_clicked();
|
void on_sceneSequenceRemove_clicked();
|
||||||
void on_sceneSequenceUp_clicked();
|
void on_sceneSequenceUp_clicked();
|
||||||
@@ -196,15 +266,10 @@ public slots:
|
|||||||
void on_sequenceEdit_clicked();
|
void on_sequenceEdit_clicked();
|
||||||
void on_sceneSequenceSwitches_itemDoubleClicked(QListWidgetItem *item);
|
void on_sceneSequenceSwitches_itemDoubleClicked(QListWidgetItem *item);
|
||||||
|
|
||||||
void on_verboseLogging_stateChanged(int state);
|
// Transition tab
|
||||||
void on_saveWindowGeo_stateChanged(int state);
|
public:
|
||||||
void on_showTrayNotifications_stateChanged(int state);
|
void SetupTransitionsTab();
|
||||||
void on_uiHintsDisable_stateChanged(int state);
|
public slots:
|
||||||
void on_hideLegacyTabs_stateChanged(int state);
|
|
||||||
|
|
||||||
void on_exportSettings_clicked();
|
|
||||||
void on_importSettings_clicked();
|
|
||||||
|
|
||||||
void on_transitionsAdd_clicked();
|
void on_transitionsAdd_clicked();
|
||||||
void on_transitionsRemove_clicked();
|
void on_transitionsRemove_clicked();
|
||||||
void on_transitionsUp_clicked();
|
void on_transitionsUp_clicked();
|
||||||
@@ -215,60 +280,95 @@ public slots:
|
|||||||
void on_defaultTransitionsDown_clicked();
|
void on_defaultTransitionsDown_clicked();
|
||||||
void on_transitionOverridecheckBox_stateChanged(int state);
|
void on_transitionOverridecheckBox_stateChanged(int state);
|
||||||
void on_adjustActiveTransitionType_stateChanged(int state);
|
void on_adjustActiveTransitionType_stateChanged(int state);
|
||||||
void defTransitionDelayValueChanged(int value);
|
void DefTransitionDelayValueChanged(int value);
|
||||||
|
|
||||||
|
// Executable tab
|
||||||
|
public:
|
||||||
|
void SetupExecutableTab();
|
||||||
|
public slots:
|
||||||
|
void on_executableUp_clicked();
|
||||||
|
void on_executableDown_clicked();
|
||||||
|
void on_executableAdd_clicked();
|
||||||
|
void on_executableRemove_clicked();
|
||||||
|
|
||||||
|
// Idle tab
|
||||||
|
public:
|
||||||
|
void SetupIdleTab();
|
||||||
|
public slots:
|
||||||
|
void on_idleCheckBox_stateChanged(int state);
|
||||||
|
void on_ignoreIdleWindows_currentRowChanged(int idx);
|
||||||
|
void on_ignoreIdleAdd_clicked();
|
||||||
|
void on_ignoreIdleRemove_clicked();
|
||||||
|
|
||||||
|
// Random tab
|
||||||
|
public:
|
||||||
|
void SetupRandomTab();
|
||||||
|
public slots:
|
||||||
|
void on_randomAdd_clicked();
|
||||||
|
void on_randomRemove_clicked();
|
||||||
|
|
||||||
|
// File tab
|
||||||
|
public:
|
||||||
|
void SetupFileTab();
|
||||||
|
public slots:
|
||||||
|
void on_fileAdd_clicked();
|
||||||
|
void on_fileRemove_clicked();
|
||||||
|
void on_fileSwitches_currentRowChanged(int idx);
|
||||||
|
void on_fileUp_clicked();
|
||||||
|
void on_fileDown_clicked();
|
||||||
void on_browseButton_clicked();
|
void on_browseButton_clicked();
|
||||||
void on_readFileCheckBox_stateChanged(int state);
|
void on_readFileCheckBox_stateChanged(int state);
|
||||||
void on_readPathLineEdit_textChanged(const QString &text);
|
void on_readPathLineEdit_textChanged(const QString &text);
|
||||||
void on_writePathLineEdit_textChanged(const QString &text);
|
void on_writePathLineEdit_textChanged(const QString &text);
|
||||||
void on_browseButton_2_clicked();
|
void on_browseButton_2_clicked();
|
||||||
|
|
||||||
void on_executableUp_clicked();
|
// Media tab
|
||||||
void on_executableDown_clicked();
|
public:
|
||||||
void on_executableAdd_clicked();
|
void SetupMediaTab();
|
||||||
void on_executableRemove_clicked();
|
public slots:
|
||||||
|
|
||||||
void on_idleCheckBox_stateChanged(int state);
|
|
||||||
void on_ignoreIdleWindows_currentRowChanged(int idx);
|
|
||||||
void on_ignoreIdleAdd_clicked();
|
|
||||||
void on_ignoreIdleRemove_clicked();
|
|
||||||
|
|
||||||
void on_randomAdd_clicked();
|
|
||||||
void on_randomRemove_clicked();
|
|
||||||
|
|
||||||
void on_fileAdd_clicked();
|
|
||||||
void on_fileRemove_clicked();
|
|
||||||
void on_fileSwitches_currentRowChanged(int idx);
|
|
||||||
void on_fileUp_clicked();
|
|
||||||
void on_fileDown_clicked();
|
|
||||||
|
|
||||||
void on_mediaAdd_clicked();
|
void on_mediaAdd_clicked();
|
||||||
void on_mediaRemove_clicked();
|
void on_mediaRemove_clicked();
|
||||||
void on_mediaUp_clicked();
|
void on_mediaUp_clicked();
|
||||||
void on_mediaDown_clicked();
|
void on_mediaDown_clicked();
|
||||||
|
|
||||||
|
// Time tab
|
||||||
|
public:
|
||||||
|
void SetupTimeTab();
|
||||||
|
public slots:
|
||||||
void on_timeAdd_clicked();
|
void on_timeAdd_clicked();
|
||||||
void on_timeRemove_clicked();
|
void on_timeRemove_clicked();
|
||||||
void on_timeUp_clicked();
|
void on_timeUp_clicked();
|
||||||
void on_timeDown_clicked();
|
void on_timeDown_clicked();
|
||||||
|
|
||||||
|
// Audio tab
|
||||||
|
public:
|
||||||
|
void SetupAudioTab();
|
||||||
|
public slots:
|
||||||
void on_audioAdd_clicked();
|
void on_audioAdd_clicked();
|
||||||
void on_audioRemove_clicked();
|
void on_audioRemove_clicked();
|
||||||
void on_audioUp_clicked();
|
void on_audioUp_clicked();
|
||||||
void on_audioDown_clicked();
|
void on_audioDown_clicked();
|
||||||
void on_audioFallback_toggled(bool on);
|
void on_audioFallback_toggled(bool on);
|
||||||
|
|
||||||
|
// Video tab
|
||||||
|
public:
|
||||||
|
void SetupVideoTab();
|
||||||
|
public slots:
|
||||||
void on_videoAdd_clicked();
|
void on_videoAdd_clicked();
|
||||||
void on_videoRemove_clicked();
|
void on_videoRemove_clicked();
|
||||||
void on_videoUp_clicked();
|
void on_videoUp_clicked();
|
||||||
void on_videoDown_clicked();
|
void on_videoDown_clicked();
|
||||||
void on_getScreenshot_clicked();
|
void on_getScreenshot_clicked();
|
||||||
|
|
||||||
|
// Scene group tab
|
||||||
|
public:
|
||||||
|
void SetupNetworkTab();
|
||||||
|
public slots:
|
||||||
void on_serverSettings_toggled(bool on);
|
void on_serverSettings_toggled(bool on);
|
||||||
void on_serverPort_valueChanged(int value);
|
void on_serverPort_valueChanged(int value);
|
||||||
void on_lockToIPv4_stateChanged(int state);
|
void on_lockToIPv4_stateChanged(int state);
|
||||||
void on_serverRestart_clicked();
|
void on_serverRestart_clicked();
|
||||||
void updateServerStatus();
|
void UpdateServerStatus();
|
||||||
void on_clientSettings_toggled(bool on);
|
void on_clientSettings_toggled(bool on);
|
||||||
void on_clientHostname_textChanged(const QString &text);
|
void on_clientHostname_textChanged(const QString &text);
|
||||||
void on_clientPort_valueChanged(int value);
|
void on_clientPort_valueChanged(int value);
|
||||||
@@ -276,67 +376,41 @@ public slots:
|
|||||||
void on_restrictSend_stateChanged(int state);
|
void on_restrictSend_stateChanged(int state);
|
||||||
void on_sendPreview_stateChanged(int state);
|
void on_sendPreview_stateChanged(int state);
|
||||||
void on_clientReconnect_clicked();
|
void on_clientReconnect_clicked();
|
||||||
void updateClientStatus();
|
void UpdateClientStatus();
|
||||||
|
|
||||||
|
// Scene group tab
|
||||||
|
public:
|
||||||
|
void SetupSceneGroupTab();
|
||||||
|
void SetEditSceneGroup(SceneGroup &sg);
|
||||||
|
public slots:
|
||||||
void on_sceneGroupAdd_clicked();
|
void on_sceneGroupAdd_clicked();
|
||||||
void on_sceneGroupRemove_clicked();
|
void on_sceneGroupRemove_clicked();
|
||||||
void on_sceneGroupUp_clicked();
|
void on_sceneGroupUp_clicked();
|
||||||
void on_sceneGroupDown_clicked();
|
void on_sceneGroupDown_clicked();
|
||||||
void on_sceneGroupName_editingFinished();
|
void on_sceneGroupName_editingFinished();
|
||||||
void on_sceneGroups_currentRowChanged(int idx);
|
void on_sceneGroups_currentRowChanged(int idx);
|
||||||
|
|
||||||
void on_sceneGroupSceneAdd_clicked();
|
void on_sceneGroupSceneAdd_clicked();
|
||||||
void on_sceneGroupSceneRemove_clicked();
|
void on_sceneGroupSceneRemove_clicked();
|
||||||
void on_sceneGroupSceneUp_clicked();
|
void on_sceneGroupSceneUp_clicked();
|
||||||
void on_sceneGroupSceneDown_clicked();
|
void on_sceneGroupSceneDown_clicked();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void SceneGroupAdded(const QString &name);
|
||||||
|
void SceneGroupRemoved(const QString &name);
|
||||||
|
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||||
|
|
||||||
|
// Trigger tab
|
||||||
|
public:
|
||||||
|
void SetupTriggerTab();
|
||||||
|
public slots:
|
||||||
void on_triggerAdd_clicked();
|
void on_triggerAdd_clicked();
|
||||||
void on_triggerRemove_clicked();
|
void on_triggerRemove_clicked();
|
||||||
void on_triggerUp_clicked();
|
void on_triggerUp_clicked();
|
||||||
void on_triggerDown_clicked();
|
void on_triggerDown_clicked();
|
||||||
|
|
||||||
void on_priorityUp_clicked();
|
/* --- End of legacy tab section --- */
|
||||||
void on_priorityDown_clicked();
|
|
||||||
void on_threadPriority_currentTextChanged(const QString &text);
|
|
||||||
|
|
||||||
void updateScreenRegionCursorPos();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool MacroTabIsInFocus();
|
|
||||||
|
|
||||||
MacroSegmentList *conditionsList = nullptr;
|
|
||||||
MacroSegmentList *actionsList = nullptr;
|
|
||||||
|
|
||||||
enum class MacroSection {
|
|
||||||
CONDITIONS,
|
|
||||||
ACTIONS,
|
|
||||||
};
|
|
||||||
MacroSection lastInteracted = MacroSection::CONDITIONS;
|
|
||||||
int currentConditionIdx = -1;
|
|
||||||
int currentActionIdx = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void OpenSettingsWindow();
|
void OpenSettingsWindow();
|
||||||
|
|
||||||
/******************************************************************************
|
} // namespace advss
|
||||||
* Sceneswitch helper
|
|
||||||
******************************************************************************/
|
|
||||||
void setNextTransition(const sceneSwitchInfo &ssi, obs_source_t *currentSource,
|
|
||||||
transitionData &td);
|
|
||||||
void overwriteTransitionOverride(const sceneSwitchInfo &ssi,
|
|
||||||
transitionData &td);
|
|
||||||
void restoreTransitionOverride(obs_source_t *scene, const transitionData &td);
|
|
||||||
void switchScene(const sceneSwitchInfo &ssi, bool force = false);
|
|
||||||
void switchPreviewScene(const OBSWeakSource &ws);
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Settings helper
|
|
||||||
******************************************************************************/
|
|
||||||
void AskForBackup(obs_data_t *obj);
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Main SwitcherData
|
|
||||||
******************************************************************************/
|
|
||||||
struct SwitcherData;
|
|
||||||
extern SwitcherData *switcher;
|
|
||||||
SwitcherData *GetSwitcher();
|
|
||||||
|
|||||||
504
src/general.cpp
@@ -1,11 +1,14 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.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"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QStandardPaths>
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
void AdvSceneSwitcher::reject()
|
void AdvSceneSwitcher::reject()
|
||||||
{
|
{
|
||||||
@@ -30,7 +33,7 @@ void AdvSceneSwitcher::on_noMatchDontSwitch_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->switchIfNotMatching = NO_SWITCH;
|
switcher->switchIfNotMatching = NoMatchBehavior::NO_SWITCH;
|
||||||
ui->noMatchSwitchScene->setEnabled(false);
|
ui->noMatchSwitchScene->setEnabled(false);
|
||||||
ui->randomDisabledWarning->setVisible(true);
|
ui->randomDisabledWarning->setVisible(true);
|
||||||
}
|
}
|
||||||
@@ -42,7 +45,7 @@ void AdvSceneSwitcher::on_noMatchSwitch_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->switchIfNotMatching = SWITCH;
|
switcher->switchIfNotMatching = NoMatchBehavior::SWITCH;
|
||||||
ui->noMatchSwitchScene->setEnabled(true);
|
ui->noMatchSwitchScene->setEnabled(true);
|
||||||
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
|
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
|
||||||
ui->randomDisabledWarning->setVisible(true);
|
ui->randomDisabledWarning->setVisible(true);
|
||||||
@@ -55,49 +58,29 @@ void AdvSceneSwitcher::on_noMatchRandomSwitch_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->switchIfNotMatching = RANDOM_SWITCH;
|
switcher->switchIfNotMatching = NoMatchBehavior::RANDOM_SWITCH;
|
||||||
ui->noMatchSwitchScene->setEnabled(false);
|
ui->noMatchSwitchScene->setEnabled(false);
|
||||||
ui->randomDisabledWarning->setVisible(false);
|
ui->randomDisabledWarning->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::NoMatchDelayDurationChanged(double sec)
|
void AdvSceneSwitcher::NoMatchDelayDurationChanged(const Duration &dur)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->noMatchDelay.seconds = sec;
|
switcher->noMatchDelay = dur;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::NoMatchDelayUnitChanged(DurationUnit unit)
|
void AdvSceneSwitcher::CooldownDurationChanged(const Duration &dur)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->noMatchDelay.displayUnit = unit;
|
switcher->cooldown = dur;
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::CooldownDurationChanged(double sec)
|
|
||||||
{
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switcher->cooldown.seconds = sec;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::CooldownUnitChanged(DurationUnit unit)
|
|
||||||
{
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switcher->cooldown.displayUnit = unit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
||||||
@@ -107,7 +90,8 @@ void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->startupBehavior = (StartupBehavior)index;
|
switcher->startupBehavior =
|
||||||
|
static_cast<SwitcherData::StartupBehavior>(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
||||||
@@ -117,7 +101,7 @@ void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->autoStartEvent = static_cast<AutoStartEvent>(index);
|
switcher->autoStartEvent = static_cast<SwitcherData::AutoStart>(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
|
void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
|
||||||
@@ -148,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();
|
||||||
}
|
}
|
||||||
@@ -192,7 +175,26 @@ void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
|
|||||||
switcher->disableHints = state;
|
switcher->disableHints = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isLegacyTab(const QString &name)
|
void AdvSceneSwitcher::on_disableComboBoxFilter_stateChanged(int state)
|
||||||
|
{
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switcher->disableFilterComboboxFilter = state;
|
||||||
|
FilterComboBox::SetFilterBehaviourEnabled(!state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
||||||
|
{
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switcher->warnPluginLoadFailure = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isLegacyTab(const QString &name)
|
||||||
{
|
{
|
||||||
return name == obs_module_text(
|
return name == obs_module_text(
|
||||||
"AdvSceneSwitcher.sceneGroupTab.title") ||
|
"AdvSceneSwitcher.sceneGroupTab.title") ||
|
||||||
@@ -237,7 +239,7 @@ void AdvSceneSwitcher::on_hideLegacyTabs_stateChanged(int state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setDeprecationWarnings()
|
void AdvSceneSwitcher::SetDeprecationWarnings()
|
||||||
{
|
{
|
||||||
QString toolTip =
|
QString toolTip =
|
||||||
switcher->disableHints
|
switcher->disableHints
|
||||||
@@ -251,70 +253,13 @@ void AdvSceneSwitcher::setDeprecationWarnings()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString getDefaultSaveLocation()
|
|
||||||
{
|
|
||||||
QString desktopPath = QStandardPaths::writableLocation(
|
|
||||||
QStandardPaths::DesktopLocation);
|
|
||||||
|
|
||||||
auto scName = obs_frontend_get_current_scene_collection();
|
|
||||||
QString sceneCollectionName(scName);
|
|
||||||
bfree(scName);
|
|
||||||
|
|
||||||
auto timestamp = QDateTime::currentDateTime();
|
|
||||||
auto path = desktopPath + "/adv-ss-" + sceneCollectionName + "-" +
|
|
||||||
timestamp.toString("yyyy.MM.dd.hh.mm.ss");
|
|
||||||
|
|
||||||
// Check if scene collection name contains invalid path characters
|
|
||||||
QFile file(path);
|
|
||||||
if (file.exists()) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validPath = file.open(QIODevice::WriteOnly);
|
|
||||||
if (validPath) {
|
|
||||||
file.remove();
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return desktopPath + "/adv-ss-" +
|
|
||||||
timestamp.toString("yyyy.MM.dd.hh.mm.ss");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AskForBackup(obs_data_t *obj)
|
|
||||||
{
|
|
||||||
bool backupSettings = DisplayMessage(
|
|
||||||
obs_module_text("AdvSceneSwitcher.askBackup"), true);
|
|
||||||
|
|
||||||
if (!backupSettings) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString path = QFileDialog::getSaveFileName(
|
|
||||||
nullptr,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle"),
|
|
||||||
getDefaultSaveLocation(),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType"));
|
|
||||||
if (path.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(path);
|
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_exportSettings_clicked()
|
void AdvSceneSwitcher::on_exportSettings_clicked()
|
||||||
{
|
{
|
||||||
QString directory = QFileDialog::getSaveFileName(
|
QString directory = QFileDialog::getSaveFileName(
|
||||||
this,
|
this,
|
||||||
tr(obs_module_text(
|
tr(obs_module_text(
|
||||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle")),
|
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle")),
|
||||||
getDefaultSaveLocation(),
|
GetDefaultSettingsSaveLocation(),
|
||||||
tr(obs_module_text(
|
tr(obs_module_text(
|
||||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType")));
|
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType")));
|
||||||
if (directory.isEmpty()) {
|
if (directory.isEmpty()) {
|
||||||
@@ -327,7 +272,7 @@ void AdvSceneSwitcher::on_exportSettings_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
obs_data_t *obj = obs_data_create();
|
obs_data_t *obj = obs_data_create();
|
||||||
switcher->saveSettings(obj);
|
switcher->SaveSettings(obj);
|
||||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||||
obs_data_release(obj);
|
obs_data_release(obj);
|
||||||
}
|
}
|
||||||
@@ -367,7 +312,7 @@ void AdvSceneSwitcher::on_importSettings_clicked()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->loadSettings(obj);
|
switcher->LoadSettings(obj);
|
||||||
obs_data_release(obj);
|
obs_data_release(obj);
|
||||||
switcher->lastImportPath = path.toStdString();
|
switcher->lastImportPath = path.toStdString();
|
||||||
|
|
||||||
@@ -383,7 +328,7 @@ void AdvSceneSwitcher::on_importSettings_clicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int findTabIndex(QTabWidget *tabWidget, int pos)
|
static int findTabIndex(QTabWidget *tabWidget, int pos)
|
||||||
{
|
{
|
||||||
int at = -1;
|
int at = -1;
|
||||||
|
|
||||||
@@ -457,10 +402,10 @@ int findTabIndex(QTabWidget *tabWidget, int pos)
|
|||||||
return at;
|
return at;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setTabOrder()
|
void AdvSceneSwitcher::SetTabOrder()
|
||||||
{
|
{
|
||||||
if (!switcher->tabOrderValid()) {
|
if (!switcher->TabOrderValid()) {
|
||||||
switcher->resetTabOrder();
|
switcher->ResetTabOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
QTabBar *bar = ui->tabWidget->tabBar();
|
QTabBar *bar = ui->tabWidget->tabBar();
|
||||||
@@ -475,22 +420,22 @@ void AdvSceneSwitcher::setTabOrder()
|
|||||||
connect(bar, &QTabBar::tabMoved, this, &AdvSceneSwitcher::on_tabMoved);
|
connect(bar, &QTabBar::tabMoved, this, &AdvSceneSwitcher::on_tabMoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setCurrentTab()
|
void AdvSceneSwitcher::SetCurrentTab()
|
||||||
{
|
{
|
||||||
if (switcher->lastOpenedTab >= 0) {
|
if (switcher->lastOpenedTab >= 0) {
|
||||||
ui->tabWidget->setCurrentIndex(switcher->lastOpenedTab);
|
ui->tabWidget->setCurrentIndex(switcher->lastOpenedTab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::restoreWindowGeo()
|
void AdvSceneSwitcher::RestoreWindowGeo()
|
||||||
{
|
{
|
||||||
if (switcher->saveWindowGeo && windowPosValid(switcher->windowPos)) {
|
if (switcher->saveWindowGeo && WindowPosValid(switcher->windowPos)) {
|
||||||
this->resize(switcher->windowSize);
|
this->resize(switcher->windowSize);
|
||||||
this->move(switcher->windowPos);
|
this->move(switcher->windowPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::checkFirstTimeSetup()
|
void AdvSceneSwitcher::CheckFirstTimeSetup()
|
||||||
{
|
{
|
||||||
if (switcher->firstBoot && !switcher->disableHints) {
|
if (switcher->firstBoot && !switcher->disableHints) {
|
||||||
switcher->firstBoot = false;
|
switcher->firstBoot = false;
|
||||||
@@ -511,7 +456,7 @@ void AdvSceneSwitcher::on_tabMoved(int from, int to)
|
|||||||
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
|
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
|
||||||
{
|
{
|
||||||
switcher->showFrame = false;
|
switcher->showFrame = false;
|
||||||
clearFrames(ui->screenRegionSwitches);
|
ClearFrames(ui->screenRegionSwitches);
|
||||||
SetShowFrames();
|
SetShowFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,18 +493,25 @@ void AdvSceneSwitcher::on_adjustActiveTransitionType_stateChanged(int state)
|
|||||||
switcher->adjustActiveTransitionType = state;
|
switcher->adjustActiveTransitionType = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::loadSettings(obs_data_t *obj)
|
void SwitcherData::LoadSettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
if (!obj) {
|
if (!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);
|
||||||
loadMacros(obj);
|
|
||||||
loadConnections(obj);
|
for (const auto &func : loadSteps) {
|
||||||
|
func(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadMacros(obj);
|
||||||
loadWindowTitleSwitches(obj);
|
loadWindowTitleSwitches(obj);
|
||||||
loadScreenRegionSwitches(obj);
|
loadScreenRegionSwitches(obj);
|
||||||
loadPauseSwitches(obj);
|
loadPauseSwitches(obj);
|
||||||
@@ -575,24 +527,28 @@ void SwitcherData::loadSettings(obs_data_t *obj)
|
|||||||
loadVideoSwitches(obj);
|
loadVideoSwitches(obj);
|
||||||
loadNetworkSettings(obj);
|
loadNetworkSettings(obj);
|
||||||
loadSceneTriggers(obj);
|
loadSceneTriggers(obj);
|
||||||
loadGeneralSettings(obj);
|
LoadGeneralSettings(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::saveSettings(obs_data_t *obj)
|
void SwitcherData::SaveSettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSceneGroups(obj);
|
saveSceneGroups(obj);
|
||||||
saveMacros(obj);
|
SaveMacros(obj);
|
||||||
saveConnections(obj);
|
SaveVariables(obj);
|
||||||
saveVariables(obj);
|
|
||||||
saveWindowTitleSwitches(obj);
|
saveWindowTitleSwitches(obj);
|
||||||
saveScreenRegionSwitches(obj);
|
saveScreenRegionSwitches(obj);
|
||||||
savePauseSwitches(obj);
|
savePauseSwitches(obj);
|
||||||
@@ -608,27 +564,33 @@ void SwitcherData::saveSettings(obs_data_t *obj)
|
|||||||
saveVideoSwitches(obj);
|
saveVideoSwitches(obj);
|
||||||
saveNetworkSwitches(obj);
|
saveNetworkSwitches(obj);
|
||||||
saveSceneTriggers(obj);
|
saveSceneTriggers(obj);
|
||||||
saveGeneralSettings(obj);
|
SaveGeneralSettings(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)
|
||||||
{
|
{
|
||||||
obs_data_set_int(obj, "interval", interval);
|
obs_data_set_int(obj, "interval", interval);
|
||||||
|
|
||||||
std::string nonMatchingSceneName = GetWeakSourceName(nonMatchingScene);
|
std::string nonMatchingSceneName = GetWeakSourceName(nonMatchingScene);
|
||||||
obs_data_set_string(obj, "non_matching_scene",
|
obs_data_set_string(obj, "non_matching_scene",
|
||||||
nonMatchingSceneName.c_str());
|
nonMatchingSceneName.c_str());
|
||||||
obs_data_set_int(obj, "switch_if_not_matching", switchIfNotMatching);
|
obs_data_set_int(obj, "switch_if_not_matching",
|
||||||
noMatchDelay.Save(obj, "noMatchDelay", "noMatchDelayUnit");
|
static_cast<int>(switchIfNotMatching));
|
||||||
|
noMatchDelay.Save(obj, "noMatchDelay");
|
||||||
|
|
||||||
cooldown.Save(obj, "cooldown", "cooldownUnit");
|
cooldown.Save(obj, "cooldown");
|
||||||
|
|
||||||
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
|
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
|
||||||
sceneColletionStop = false;
|
sceneColletionStop = false;
|
||||||
obs_data_set_int(obj, "startup_behavior", startupBehavior);
|
obs_data_set_int(obj, "startup_behavior",
|
||||||
|
static_cast<int>(startupBehavior));
|
||||||
|
|
||||||
obs_data_set_int(obj, "autoStartEvent",
|
obs_data_set_int(obj, "autoStartEvent",
|
||||||
static_cast<int>(autoStartEvent));
|
static_cast<int>(autoStartEvent));
|
||||||
@@ -637,23 +599,16 @@ 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, "hideLegacyTabs", hideLegacyTabs);
|
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
||||||
|
|
||||||
obs_data_set_int(obj, "priority0", functionNamesByPriority[0]);
|
SaveFunctionPriorities(obj, functionNamesByPriority);
|
||||||
obs_data_set_int(obj, "priority1", functionNamesByPriority[1]);
|
|
||||||
obs_data_set_int(obj, "priority2", functionNamesByPriority[2]);
|
|
||||||
obs_data_set_int(obj, "priority3", functionNamesByPriority[3]);
|
|
||||||
obs_data_set_int(obj, "priority4", functionNamesByPriority[4]);
|
|
||||||
obs_data_set_int(obj, "priority5", functionNamesByPriority[5]);
|
|
||||||
obs_data_set_int(obj, "priority6", functionNamesByPriority[6]);
|
|
||||||
obs_data_set_int(obj, "priority7", functionNamesByPriority[7]);
|
|
||||||
obs_data_set_int(obj, "priority8", functionNamesByPriority[8]);
|
|
||||||
obs_data_set_int(obj, "priority9", functionNamesByPriority[9]);
|
|
||||||
obs_data_set_int(obj, "priority10", functionNamesByPriority[10]);
|
|
||||||
|
|
||||||
obs_data_set_int(obj, "threadPriority", threadPriority);
|
obs_data_set_int(obj, "threadPriority", threadPriority);
|
||||||
|
|
||||||
obs_data_set_bool(obj, "tansitionOverrideOverride",
|
obs_data_set_bool(obj, "transitionOverrideOverride",
|
||||||
transitionOverrideOverride);
|
transitionOverrideOverride);
|
||||||
obs_data_set_bool(obj, "adjustActiveTransitionType",
|
obs_data_set_bool(obj, "adjustActiveTransitionType",
|
||||||
adjustActiveTransitionType);
|
adjustActiveTransitionType);
|
||||||
@@ -661,74 +616,50 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
|||||||
obs_data_set_string(obj, "lastImportPath", lastImportPath.c_str());
|
obs_data_set_string(obj, "lastImportPath", lastImportPath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
obs_data_set_default_int(obj, "interval", default_interval);
|
obs_data_set_default_int(obj, "interval", default_interval);
|
||||||
interval = obs_data_get_int(obj, "interval");
|
interval = obs_data_get_int(obj, "interval");
|
||||||
|
|
||||||
obs_data_set_default_int(obj, "switch_if_not_matching", NO_SWITCH);
|
obs_data_set_default_int(obj, "switch_if_not_matching",
|
||||||
switchIfNotMatching =
|
static_cast<int>(NoMatchBehavior::NO_SWITCH));
|
||||||
(NoMatch)obs_data_get_int(obj, "switch_if_not_matching");
|
switchIfNotMatching = static_cast<NoMatchBehavior>(
|
||||||
|
obs_data_get_int(obj, "switch_if_not_matching"));
|
||||||
std::string nonMatchingSceneName =
|
std::string nonMatchingSceneName =
|
||||||
obs_data_get_string(obj, "non_matching_scene");
|
obs_data_get_string(obj, "non_matching_scene");
|
||||||
nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str());
|
nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str());
|
||||||
noMatchDelay.Load(obj, "noMatchDelay", "noMatchDelayUnit");
|
noMatchDelay.Load(obj, "noMatchDelay");
|
||||||
|
|
||||||
cooldown.Load(obj, "cooldown", "cooldownUnit");
|
cooldown.Load(obj, "cooldown");
|
||||||
|
|
||||||
stop = !obs_data_get_bool(obj, "active");
|
stop = !obs_data_get_bool(obj, "active");
|
||||||
startupBehavior =
|
startupBehavior =
|
||||||
(StartupBehavior)obs_data_get_int(obj, "startup_behavior");
|
(StartupBehavior)obs_data_get_int(obj, "startup_behavior");
|
||||||
if (startupBehavior == START) {
|
if (startupBehavior == StartupBehavior::START) {
|
||||||
stop = false;
|
stop = false;
|
||||||
}
|
}
|
||||||
if (startupBehavior == STOP) {
|
if (startupBehavior == StartupBehavior::STOP) {
|
||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
autoStartEvent = static_cast<AutoStartEvent>(
|
autoStartEvent =
|
||||||
obs_data_get_int(obj, "autoStartEvent"));
|
static_cast<AutoStart>(obs_data_get_int(obj, "autoStartEvent"));
|
||||||
|
|
||||||
verbose = obs_data_get_bool(obj, "verbose");
|
verbose = obs_data_get_bool(obj, "verbose");
|
||||||
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);
|
||||||
|
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
|
||||||
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
||||||
hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs");
|
hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs");
|
||||||
|
|
||||||
obs_data_set_default_int(obj, "priority0", default_priority_0);
|
SetDefaultFunctionPriorities(obj);
|
||||||
obs_data_set_default_int(obj, "priority1", default_priority_1);
|
LoadFunctionPriorities(obj, functionNamesByPriority);
|
||||||
obs_data_set_default_int(obj, "priority2", default_priority_2);
|
if (!PrioFuncsValid()) {
|
||||||
obs_data_set_default_int(obj, "priority3", default_priority_3);
|
functionNamesByPriority = GetDefaultFunctionPriorityList();
|
||||||
obs_data_set_default_int(obj, "priority4", default_priority_4);
|
|
||||||
obs_data_set_default_int(obj, "priority5", default_priority_5);
|
|
||||||
obs_data_set_default_int(obj, "priority6", default_priority_6);
|
|
||||||
obs_data_set_default_int(obj, "priority7", default_priority_7);
|
|
||||||
obs_data_set_default_int(obj, "priority8", default_priority_8);
|
|
||||||
|
|
||||||
functionNamesByPriority[0] = (obs_data_get_int(obj, "priority0"));
|
|
||||||
functionNamesByPriority[1] = (obs_data_get_int(obj, "priority1"));
|
|
||||||
functionNamesByPriority[2] = (obs_data_get_int(obj, "priority2"));
|
|
||||||
functionNamesByPriority[3] = (obs_data_get_int(obj, "priority3"));
|
|
||||||
functionNamesByPriority[4] = (obs_data_get_int(obj, "priority4"));
|
|
||||||
functionNamesByPriority[5] = (obs_data_get_int(obj, "priority5"));
|
|
||||||
functionNamesByPriority[6] = (obs_data_get_int(obj, "priority6"));
|
|
||||||
functionNamesByPriority[7] = (obs_data_get_int(obj, "priority7"));
|
|
||||||
functionNamesByPriority[8] = (obs_data_get_int(obj, "priority8"));
|
|
||||||
functionNamesByPriority[9] = (obs_data_get_int(obj, "priority9"));
|
|
||||||
functionNamesByPriority[10] = (obs_data_get_int(obj, "priority10"));
|
|
||||||
if (!prioFuncsValid()) {
|
|
||||||
functionNamesByPriority[0] = (default_priority_0);
|
|
||||||
functionNamesByPriority[1] = (default_priority_1);
|
|
||||||
functionNamesByPriority[2] = (default_priority_2);
|
|
||||||
functionNamesByPriority[3] = (default_priority_3);
|
|
||||||
functionNamesByPriority[4] = (default_priority_4);
|
|
||||||
functionNamesByPriority[5] = (default_priority_5);
|
|
||||||
functionNamesByPriority[6] = (default_priority_6);
|
|
||||||
functionNamesByPriority[7] = (default_priority_7);
|
|
||||||
functionNamesByPriority[8] = (default_priority_8);
|
|
||||||
functionNamesByPriority[9] = (default_priority_9);
|
|
||||||
functionNamesByPriority[10] = (default_priority_10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_data_set_default_int(obj, "threadPriority",
|
obs_data_set_default_int(obj, "threadPriority",
|
||||||
@@ -736,7 +667,7 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
|||||||
threadPriority = obs_data_get_int(obj, "threadPriority");
|
threadPriority = obs_data_get_int(obj, "threadPriority");
|
||||||
|
|
||||||
transitionOverrideOverride =
|
transitionOverrideOverride =
|
||||||
obs_data_get_bool(obj, "tansitionOverrideOverride");
|
obs_data_get_bool(obj, "transitionOverrideOverride");
|
||||||
adjustActiveTransitionType =
|
adjustActiveTransitionType =
|
||||||
obs_data_get_bool(obj, "adjustActiveTransitionType");
|
obs_data_get_bool(obj, "adjustActiveTransitionType");
|
||||||
|
|
||||||
@@ -749,33 +680,7 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
|||||||
lastImportPath = obs_data_get_string(obj, "lastImportPath");
|
lastImportPath = obs_data_get_string(obj, "lastImportPath");
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveSplitterPos(QList<int> &sizes, obs_data_t *obj, const std::string name)
|
void SwitcherData::SaveUISettings(obs_data_t *obj)
|
||||||
{
|
|
||||||
auto array = obs_data_array_create();
|
|
||||||
for (int i = 0; i < sizes.count(); ++i) {
|
|
||||||
obs_data_t *array_obj = obs_data_create();
|
|
||||||
obs_data_set_int(array_obj, "pos", sizes[i]);
|
|
||||||
obs_data_array_push_back(array, array_obj);
|
|
||||||
obs_data_release(array_obj);
|
|
||||||
}
|
|
||||||
obs_data_set_array(obj, name.c_str(), array);
|
|
||||||
obs_data_array_release(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadSplitterPos(QList<int> &sizes, obs_data_t *obj, const std::string name)
|
|
||||||
{
|
|
||||||
sizes.clear();
|
|
||||||
obs_data_array_t *array = obs_data_get_array(obj, name.c_str());
|
|
||||||
size_t count = obs_data_array_count(array);
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
|
||||||
obs_data_t *item = obs_data_array_item(array, i);
|
|
||||||
sizes << obs_data_get_int(item, "pos");
|
|
||||||
obs_data_release(item);
|
|
||||||
}
|
|
||||||
obs_data_array_release(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SwitcherData::saveUISettings(obs_data_t *obj)
|
|
||||||
{
|
{
|
||||||
obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
|
obs_data_set_int(obj, "generalTabPos", tabOrder[0]);
|
||||||
obs_data_set_int(obj, "macroTabPos", tabOrder[1]);
|
obs_data_set_int(obj, "macroTabPos", tabOrder[1]);
|
||||||
@@ -802,13 +707,11 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::loadUISettings(obs_data_t *obj)
|
void SwitcherData::LoadUISettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
obs_data_set_default_int(obj, "generalTabPos", 0);
|
obs_data_set_default_int(obj, "generalTabPos", 0);
|
||||||
obs_data_set_default_int(obj, "macroTabPos", 1);
|
obs_data_set_default_int(obj, "macroTabPos", 1);
|
||||||
@@ -849,8 +752,8 @@ void SwitcherData::loadUISettings(obs_data_t *obj)
|
|||||||
tabOrder.emplace_back((int)(obs_data_get_int(obj, "sceneGroupTabPos")));
|
tabOrder.emplace_back((int)(obs_data_get_int(obj, "sceneGroupTabPos")));
|
||||||
tabOrder.emplace_back((int)(obs_data_get_int(obj, "triggerTabPos")));
|
tabOrder.emplace_back((int)(obs_data_get_int(obj, "triggerTabPos")));
|
||||||
|
|
||||||
if (!tabOrderValid()) {
|
if (!TabOrderValid()) {
|
||||||
resetTabOrder();
|
ResetTabOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
saveWindowGeo = obs_data_get_bool(obj, "saveWindowGeo");
|
saveWindowGeo = obs_data_get_bool(obj, "saveWindowGeo");
|
||||||
@@ -858,13 +761,12 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwitcherData::tabOrderValid()
|
bool SwitcherData::TabOrderValid()
|
||||||
{
|
{
|
||||||
auto tmp = std::vector<int>(tab_count);
|
auto tmp = std::vector<int>(tab_count);
|
||||||
std::iota(tmp.begin(), tmp.end(), 0);
|
std::iota(tmp.begin(), tmp.end(), 0);
|
||||||
@@ -878,13 +780,13 @@ bool SwitcherData::tabOrderValid()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::resetTabOrder()
|
void SwitcherData::ResetTabOrder()
|
||||||
{
|
{
|
||||||
tabOrder = std::vector<int>(tab_count);
|
tabOrder = std::vector<int>(tab_count);
|
||||||
std::iota(tabOrder.begin(), tabOrder.end(), 0);
|
std::iota(tabOrder.begin(), tabOrder.end(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
void SwitcherData::CheckNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
||||||
OBSWeakSource &transition, int &sleep)
|
OBSWeakSource &transition, int &sleep)
|
||||||
{
|
{
|
||||||
if (match) {
|
if (match) {
|
||||||
@@ -896,12 +798,13 @@ void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switchIfNotMatching == SWITCH && nonMatchingScene) {
|
if (switchIfNotMatching == NoMatchBehavior::SWITCH &&
|
||||||
|
nonMatchingScene) {
|
||||||
match = true;
|
match = true;
|
||||||
scene = nonMatchingScene;
|
scene = nonMatchingScene;
|
||||||
transition = nullptr;
|
transition = nullptr;
|
||||||
}
|
}
|
||||||
if (switchIfNotMatching == RANDOM_SWITCH) {
|
if (switchIfNotMatching == NoMatchBehavior::RANDOM_SWITCH) {
|
||||||
match = checkRandom(scene, transition, sleep);
|
match = checkRandom(scene, transition, sleep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -920,7 +823,7 @@ void SwitcherData::checkSwitchCooldown(bool &match)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateStartupBehavior(QComboBox *cb)
|
static void populateStartupBehavior(QComboBox *cb)
|
||||||
{
|
{
|
||||||
cb->addItem(obs_module_text(
|
cb->addItem(obs_module_text(
|
||||||
"AdvSceneSwitcher.generalTab.status.onStartup.asLastRun"));
|
"AdvSceneSwitcher.generalTab.status.onStartup.asLastRun"));
|
||||||
@@ -930,7 +833,7 @@ void populateStartupBehavior(QComboBox *cb)
|
|||||||
"AdvSceneSwitcher.generalTab.status.onStartup.doNotStart"));
|
"AdvSceneSwitcher.generalTab.status.onStartup.doNotStart"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateAutoStartEventSelection(QComboBox *cb)
|
static void populateAutoStartEventSelection(QComboBox *cb)
|
||||||
{
|
{
|
||||||
cb->addItem(obs_module_text(
|
cb->addItem(obs_module_text(
|
||||||
"AdvSceneSwitcher.generalTab.status.autoStart.never"));
|
"AdvSceneSwitcher.generalTab.status.autoStart.never"));
|
||||||
@@ -942,53 +845,8 @@ void populateAutoStartEventSelection(QComboBox *cb)
|
|||||||
"AdvSceneSwitcher.generalTab.status.autoStart.recordingAndStreaming"));
|
"AdvSceneSwitcher.generalTab.status.autoStart.recordingAndStreaming"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupGeneralTab()
|
static void populatePriorityFunctionList(QListWidget *list)
|
||||||
{
|
{
|
||||||
populateSceneSelection(ui->noMatchSwitchScene, false);
|
|
||||||
|
|
||||||
if (switcher->switchIfNotMatching == SWITCH) {
|
|
||||||
ui->noMatchSwitch->setChecked(true);
|
|
||||||
ui->noMatchSwitchScene->setEnabled(true);
|
|
||||||
} else if (switcher->switchIfNotMatching == NO_SWITCH) {
|
|
||||||
ui->noMatchDontSwitch->setChecked(true);
|
|
||||||
ui->noMatchSwitchScene->setEnabled(false);
|
|
||||||
} else {
|
|
||||||
ui->noMatchRandomSwitch->setChecked(true);
|
|
||||||
ui->noMatchSwitchScene->setEnabled(false);
|
|
||||||
}
|
|
||||||
ui->noMatchSwitchScene->setCurrentText(
|
|
||||||
GetWeakSourceName(switcher->nonMatchingScene).c_str());
|
|
||||||
|
|
||||||
DurationSelection *noMatchDelay = new DurationSelection();
|
|
||||||
noMatchDelay->SetDuration(switcher->noMatchDelay);
|
|
||||||
noMatchDelay->setToolTip(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip"));
|
|
||||||
ui->noMatchLayout->addWidget(noMatchDelay);
|
|
||||||
QWidget::connect(noMatchDelay, SIGNAL(DurationChanged(double)), this,
|
|
||||||
SLOT(NoMatchDelayDurationChanged(double)));
|
|
||||||
QWidget::connect(noMatchDelay, SIGNAL(UnitChanged(DurationUnit)), this,
|
|
||||||
SLOT(NoMatchDelayUnitChanged(DurationUnit)));
|
|
||||||
|
|
||||||
ui->checkInterval->setValue(switcher->interval);
|
|
||||||
|
|
||||||
DurationSelection *cooldownTime = new DurationSelection();
|
|
||||||
cooldownTime->SetDuration(switcher->cooldown);
|
|
||||||
cooldownTime->setToolTip(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
|
|
||||||
ui->cooldownLayout->addWidget(cooldownTime);
|
|
||||||
ui->cooldownLayout->addStretch();
|
|
||||||
QWidget::connect(cooldownTime, SIGNAL(DurationChanged(double)), this,
|
|
||||||
SLOT(CooldownDurationChanged(double)));
|
|
||||||
QWidget::connect(cooldownTime, SIGNAL(UnitChanged(DurationUnit)), this,
|
|
||||||
SLOT(CooldownUnitChanged(DurationUnit)));
|
|
||||||
|
|
||||||
ui->verboseLogging->setChecked(switcher->verbose);
|
|
||||||
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
|
|
||||||
ui->showTrayNotifications->setChecked(
|
|
||||||
switcher->showSystemTrayNotifications);
|
|
||||||
ui->uiHintsDisable->setChecked(switcher->disableHints);
|
|
||||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
|
||||||
|
|
||||||
for (int p : switcher->functionNamesByPriority) {
|
for (int p : switcher->functionNamesByPriority) {
|
||||||
std::string s = "";
|
std::string s = "";
|
||||||
switch (p) {
|
switch (p) {
|
||||||
@@ -1038,26 +896,118 @@ void AdvSceneSwitcher::setupGeneralTab()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
QString text(s.c_str());
|
QString text(s.c_str());
|
||||||
QListWidgetItem *item =
|
QListWidgetItem *item = new QListWidgetItem(text, list);
|
||||||
new QListWidgetItem(text, ui->priorityList);
|
|
||||||
item->setData(Qt::UserRole, text);
|
item->setData(Qt::UserRole, text);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void populateThreadPriorityList(QComboBox *list)
|
||||||
|
{
|
||||||
for (int i = 0; i < (int)switcher->threadPriorities.size(); ++i) {
|
for (int i = 0; i < (int)switcher->threadPriorities.size(); ++i) {
|
||||||
ui->threadPriority->addItem(
|
list->addItem(switcher->threadPriorities[i].name.c_str());
|
||||||
switcher->threadPriorities[i].name.c_str());
|
list->setItemData(
|
||||||
ui->threadPriority->setItemData(
|
|
||||||
i, switcher->threadPriorities[i].description.c_str(),
|
i, switcher->threadPriorities[i].description.c_str(),
|
||||||
Qt::ToolTipRole);
|
Qt::ToolTipRole);
|
||||||
if (switcher->threadPriority ==
|
if (switcher->threadPriority ==
|
||||||
switcher->threadPriorities[i].value) {
|
switcher->threadPriorities[i].value) {
|
||||||
ui->threadPriority->setCurrentText(
|
list->setCurrentText(
|
||||||
switcher->threadPriorities[i].name.c_str());
|
switcher->threadPriorities[i].name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isGeneralTab(const QString &name)
|
||||||
|
{
|
||||||
|
return name == obs_module_text("AdvSceneSwitcher.generalTab.title");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getGeneralTabIdx(QTabWidget *tabWidget)
|
||||||
|
{
|
||||||
|
for (int idx = 0; idx < tabWidget->count(); idx++) {
|
||||||
|
if (isGeneralTab(tabWidget->tabText(idx))) {
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setupGeneralTabInactiveWarning(QTabWidget *tabs)
|
||||||
|
{
|
||||||
|
auto callback = [tabs]() {
|
||||||
|
const bool isRunning = switcher && switcher->th &&
|
||||||
|
switcher->th->isRunning();
|
||||||
|
auto idx = getGeneralTabIdx(tabs);
|
||||||
|
tabs->setTabIcon(
|
||||||
|
idx,
|
||||||
|
isRunning ? QIcon()
|
||||||
|
: QIcon::fromTheme(
|
||||||
|
"obs",
|
||||||
|
QIcon(":/res/images/warning.svg")));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto inactiveTimer = new QTimer(tabs);
|
||||||
|
inactiveTimer->setInterval(1000);
|
||||||
|
QObject::connect(inactiveTimer, &QTimer::timeout, callback);
|
||||||
|
inactiveTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::SetupGeneralTab()
|
||||||
|
{
|
||||||
|
PopulateSceneSelection(ui->noMatchSwitchScene, false);
|
||||||
|
|
||||||
|
if (switcher->switchIfNotMatching == NoMatchBehavior::SWITCH) {
|
||||||
|
ui->noMatchSwitch->setChecked(true);
|
||||||
|
ui->noMatchSwitchScene->setEnabled(true);
|
||||||
|
} else if (switcher->switchIfNotMatching ==
|
||||||
|
NoMatchBehavior::NO_SWITCH) {
|
||||||
|
ui->noMatchDontSwitch->setChecked(true);
|
||||||
|
ui->noMatchSwitchScene->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
ui->noMatchRandomSwitch->setChecked(true);
|
||||||
|
ui->noMatchSwitchScene->setEnabled(false);
|
||||||
|
}
|
||||||
|
ui->noMatchSwitchScene->setCurrentText(
|
||||||
|
GetWeakSourceName(switcher->nonMatchingScene).c_str());
|
||||||
|
|
||||||
|
DurationSelection *noMatchDelay = new DurationSelection();
|
||||||
|
noMatchDelay->SetDuration(switcher->noMatchDelay);
|
||||||
|
noMatchDelay->setToolTip(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip"));
|
||||||
|
ui->noMatchLayout->addWidget(noMatchDelay);
|
||||||
|
QWidget::connect(noMatchDelay,
|
||||||
|
SIGNAL(DurationChanged(const Duration &)), this,
|
||||||
|
SLOT(NoMatchDelayDurationChanged(const Duration &)));
|
||||||
|
|
||||||
|
ui->checkInterval->setValue(switcher->interval);
|
||||||
|
|
||||||
|
DurationSelection *cooldownTime = new DurationSelection();
|
||||||
|
cooldownTime->SetDuration(switcher->cooldown);
|
||||||
|
cooldownTime->setToolTip(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
|
||||||
|
ui->cooldownLayout->addWidget(cooldownTime);
|
||||||
|
ui->cooldownLayout->addStretch();
|
||||||
|
QWidget::connect(cooldownTime,
|
||||||
|
SIGNAL(DurationChanged(const Duration &)), this,
|
||||||
|
SLOT(CooldownDurationChanged(const Duration &)));
|
||||||
|
|
||||||
|
ui->verboseLogging->setChecked(switcher->verbose);
|
||||||
|
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
|
||||||
|
ui->showTrayNotifications->setChecked(
|
||||||
|
switcher->showSystemTrayNotifications);
|
||||||
|
ui->uiHintsDisable->setChecked(switcher->disableHints);
|
||||||
|
ui->disableComboBoxFilter->setChecked(
|
||||||
|
switcher->disableFilterComboboxFilter);
|
||||||
|
FilterComboBox::SetFilterBehaviourEnabled(
|
||||||
|
!switcher->disableFilterComboboxFilter);
|
||||||
|
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
||||||
|
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||||
|
|
||||||
|
populatePriorityFunctionList(ui->priorityList);
|
||||||
|
populateThreadPriorityList(ui->threadPriority);
|
||||||
|
|
||||||
populateStartupBehavior(ui->startupBehavior);
|
populateStartupBehavior(ui->startupBehavior);
|
||||||
ui->startupBehavior->setCurrentIndex(switcher->startupBehavior);
|
ui->startupBehavior->setCurrentIndex(
|
||||||
|
static_cast<int>(switcher->startupBehavior));
|
||||||
|
|
||||||
populateAutoStartEventSelection(ui->autoStartEvent);
|
populateAutoStartEventSelection(ui->autoStartEvent);
|
||||||
ui->autoStartEvent->setCurrentIndex(
|
ui->autoStartEvent->setCurrentIndex(
|
||||||
@@ -1074,6 +1024,10 @@ void AdvSceneSwitcher::setupGeneralTab()
|
|||||||
// Hide the now empty invisible shell of the statusControl widget
|
// Hide the now empty invisible shell of the statusControl widget
|
||||||
// as otherwise it could block user input
|
// as otherwise it could block user input
|
||||||
statusControl->hide();
|
statusControl->hide();
|
||||||
|
setupGeneralTabInactiveWarning(ui->tabWidget);
|
||||||
|
|
||||||
|
MinimizeSizeOfColumn(ui->statusLayout, 0);
|
||||||
setWindowTitle(windowTitle() + " - " + g_GIT_TAG);
|
setWindowTitle(windowTitle() + " - " + g_GIT_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#include "hotkey.hpp"
|
#include "hotkey.hpp"
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
std::vector<std::weak_ptr<Hotkey>> Hotkey::_registeredHotkeys = {};
|
std::vector<std::weak_ptr<Hotkey>> Hotkey::_registeredHotkeys = {};
|
||||||
uint32_t Hotkey::_hotkeyCounter = 1;
|
uint32_t Hotkey::_hotkeyCounter = 1;
|
||||||
|
|
||||||
@@ -117,7 +120,7 @@ void Hotkey::ClearAllHotkeys()
|
|||||||
_registeredHotkeys.clear();
|
_registeredHotkeys.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void startHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
static void startHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||||
{
|
{
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
if (!(switcher->th && switcher->th->isRunning())) {
|
if (!(switcher->th && switcher->th->isRunning())) {
|
||||||
@@ -126,7 +129,7 @@ void startHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
static void stopHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
||||||
{
|
{
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
if (switcher->th && switcher->th->isRunning()) {
|
if (switcher->th && switcher->th->isRunning()) {
|
||||||
@@ -135,8 +138,8 @@ void stopHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *, bool pressed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
static void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
if (pressed) {
|
if (pressed) {
|
||||||
if (switcher->th && switcher->th->isRunning()) {
|
if (switcher->th && switcher->th->isRunning()) {
|
||||||
@@ -147,8 +150,8 @@ void startStopToggleHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void upMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
static void upMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
if (pressed && switcher->settingsWindowOpened &&
|
if (pressed && switcher->settingsWindowOpened &&
|
||||||
AdvSceneSwitcher::window) {
|
AdvSceneSwitcher::window) {
|
||||||
@@ -158,8 +161,8 @@ void upMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void downMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
static void downMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
if (pressed && switcher->settingsWindowOpened &&
|
if (pressed && switcher->settingsWindowOpened &&
|
||||||
AdvSceneSwitcher::window) {
|
AdvSceneSwitcher::window) {
|
||||||
@@ -169,8 +172,8 @@ void downMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
static void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||||
bool pressed)
|
bool pressed)
|
||||||
{
|
{
|
||||||
if (pressed && switcher->settingsWindowOpened &&
|
if (pressed && switcher->settingsWindowOpened &&
|
||||||
AdvSceneSwitcher::window) {
|
AdvSceneSwitcher::window) {
|
||||||
@@ -180,7 +183,7 @@ void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerHotkeys()
|
static void registerHotkeys()
|
||||||
{
|
{
|
||||||
switcher->startHotkey = obs_hotkey_register_frontend(
|
switcher->startHotkey = obs_hotkey_register_frontend(
|
||||||
"startSwitcherHotkey",
|
"startSwitcherHotkey",
|
||||||
@@ -213,14 +216,14 @@ void registerHotkeys()
|
|||||||
switcher->hotkeysRegistered = true;
|
switcher->hotkeysRegistered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
static void saveHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
||||||
{
|
{
|
||||||
obs_data_array_t *a = obs_hotkey_save(id);
|
obs_data_array_t *a = obs_hotkey_save(id);
|
||||||
obs_data_set_array(obj, name, a);
|
obs_data_set_array(obj, name, a);
|
||||||
obs_data_array_release(a);
|
obs_data_array_release(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::saveHotkeys(obs_data_t *obj)
|
void SwitcherData::SaveHotkeys(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
saveHotkey(obj, startHotkey, "startHotkey");
|
saveHotkey(obj, startHotkey, "startHotkey");
|
||||||
saveHotkey(obj, stopHotkey, "stopHotkey");
|
saveHotkey(obj, stopHotkey, "stopHotkey");
|
||||||
@@ -230,14 +233,14 @@ void SwitcherData::saveHotkeys(obs_data_t *obj)
|
|||||||
saveHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
saveHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
static void loadHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
||||||
{
|
{
|
||||||
obs_data_array_t *a = obs_data_get_array(obj, name);
|
obs_data_array_t *a = obs_data_get_array(obj, name);
|
||||||
obs_hotkey_load(id, a);
|
obs_hotkey_load(id, a);
|
||||||
obs_data_array_release(a);
|
obs_data_array_release(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwitcherData::loadHotkeys(obs_data_t *obj)
|
void SwitcherData::LoadHotkeys(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
if (!hotkeysRegistered) {
|
if (!hotkeysRegistered) {
|
||||||
registerHotkeys();
|
registerHotkeys();
|
||||||
@@ -249,3 +252,5 @@ void SwitcherData::loadHotkeys(obs_data_t *obj)
|
|||||||
loadHotkey(obj, downMacroSegment, "downMacroSegmentHotkey");
|
loadHotkey(obj, downMacroSegment, "downMacroSegmentHotkey");
|
||||||
loadHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
loadHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
extern bool canSimulateKeyPresses;
|
extern bool canSimulateKeyPresses;
|
||||||
|
|
||||||
class Hotkey {
|
class Hotkey {
|
||||||
@@ -161,4 +163,4 @@ enum class HotkeyType {
|
|||||||
Key_NumpadEnter
|
Key_NumpadEnter
|
||||||
};
|
};
|
||||||
|
|
||||||
void registerHotkeys();
|
} // namespace advss
|
||||||
|
|||||||
@@ -3,9 +3,12 @@
|
|||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
#include "name-dialog.hpp"
|
#include "name-dialog.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
SceneGroupEditWidget *typeEdit = nullptr;
|
SceneGroupEditWidget *typeEdit = nullptr;
|
||||||
|
|
||||||
@@ -487,9 +490,9 @@ void SwitcherData::loadSceneGroups(obs_data_t *obj)
|
|||||||
obs_data_array_release(sceneGroupArray);
|
obs_data_array_release(sceneGroupArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupSceneGroupTab()
|
void AdvSceneSwitcher::SetupSceneGroupTab()
|
||||||
{
|
{
|
||||||
populateSceneSelection(ui->sceneGroupSceneSelection);
|
PopulateSceneSelection(ui->sceneGroupSceneSelection);
|
||||||
|
|
||||||
for (auto &sg : switcher->sceneGroups) {
|
for (auto &sg : switcher->sceneGroups) {
|
||||||
QString text = QString::fromStdString(sg.name);
|
QString text = QString::fromStdString(sg.name);
|
||||||
@@ -538,7 +541,7 @@ SceneGroupEditWidget::SceneGroupEditWidget()
|
|||||||
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{type}}", type}};
|
{"{{type}}", type}};
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.type"),
|
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.type"),
|
||||||
typeLayout, widgetPlaceholders);
|
typeLayout, widgetPlaceholders);
|
||||||
|
|
||||||
@@ -555,7 +558,7 @@ SceneGroupEditWidget::SceneGroupEditWidget()
|
|||||||
countLayout->setContentsMargins(0, 0, 0, 0);
|
countLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
widgetPlaceholders = {{"{{count}}", count}};
|
widgetPlaceholders = {{"{{count}}", count}};
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.count"),
|
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.count"),
|
||||||
countLayout, widgetPlaceholders);
|
countLayout, widgetPlaceholders);
|
||||||
|
|
||||||
@@ -573,7 +576,7 @@ SceneGroupEditWidget::SceneGroupEditWidget()
|
|||||||
timeLayout->setContentsMargins(0, 0, 0, 0);
|
timeLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
widgetPlaceholders = {{"{{time}}", time}};
|
widgetPlaceholders = {{"{{time}}", time}};
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.time"),
|
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.time"),
|
||||||
timeLayout, widgetPlaceholders);
|
timeLayout, widgetPlaceholders);
|
||||||
|
|
||||||
@@ -705,3 +708,5 @@ SceneGroup *GetSceneGroupByQString(const QString &name)
|
|||||||
{
|
{
|
||||||
return GetSceneGroupByName(name.toUtf8().constData());
|
return GetSceneGroupByName(name.toUtf8().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <obs.hpp>
|
#include <obs.hpp>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
auto constexpr invalid_scene_group_name = "invalid-scene-group";
|
auto constexpr invalid_scene_group_name = "invalid-scene-group";
|
||||||
|
|
||||||
enum class AdvanceCondition {
|
enum class AdvanceCondition {
|
||||||
@@ -85,3 +87,5 @@ private:
|
|||||||
|
|
||||||
SceneGroup *GetSceneGroupByName(const char *name);
|
SceneGroup *GetSceneGroupByName(const char *name);
|
||||||
SceneGroup *GetSceneGroupByQString(const QString &name);
|
SceneGroup *GetSceneGroupByQString(const QString &name);
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
bool SceneTrigger::pause = false;
|
bool SceneTrigger::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
@@ -156,7 +159,7 @@ void SceneTrigger::logMatch()
|
|||||||
blog(LOG_INFO,
|
blog(LOG_INFO,
|
||||||
"scene '%s' in status '%s' triggering action '%s' after %f seconds",
|
"scene '%s' in status '%s' triggering action '%s' after %f seconds",
|
||||||
GetWeakSourceName(scene).c_str(), statusName.c_str(),
|
GetWeakSourceName(scene).c_str(), statusName.c_str(),
|
||||||
actionName.c_str(), duration.seconds);
|
actionName.c_str(), duration.Seconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
void frontEndActionThread(sceneTriggerAction action, double delay)
|
void frontEndActionThread(sceneTriggerAction action, double delay)
|
||||||
@@ -266,14 +269,14 @@ void SceneTrigger::performAction()
|
|||||||
|
|
||||||
if (isFrontendAction(triggerAction)) {
|
if (isFrontendAction(triggerAction)) {
|
||||||
t = std::thread(frontEndActionThread, triggerAction,
|
t = std::thread(frontEndActionThread, triggerAction,
|
||||||
duration.seconds);
|
duration.Seconds());
|
||||||
} else if (isAudioAction(triggerAction)) {
|
} else if (isAudioAction(triggerAction)) {
|
||||||
bool mute = triggerAction == sceneTriggerAction::MUTE_SOURCE;
|
bool mute = triggerAction == sceneTriggerAction::MUTE_SOURCE;
|
||||||
t = std::thread(muteThread, audioSource, duration.seconds,
|
t = std::thread(muteThread, audioSource, duration.Seconds(),
|
||||||
mute);
|
mute);
|
||||||
} else if (isSwitcherStatusAction(triggerAction)) {
|
} else if (isSwitcherStatusAction(triggerAction)) {
|
||||||
bool stop = triggerAction == sceneTriggerAction::STOP_SWITCHER;
|
bool stop = triggerAction == sceneTriggerAction::STOP_SWITCHER;
|
||||||
t = std::thread(statusThread, duration.seconds, stop);
|
t = std::thread(statusThread, duration.Seconds(), stop);
|
||||||
} else {
|
} else {
|
||||||
blog(LOG_WARNING, "ignoring unknown action '%d'",
|
blog(LOG_WARNING, "ignoring unknown action '%d'",
|
||||||
static_cast<int>(triggerAction));
|
static_cast<int>(triggerAction));
|
||||||
@@ -349,7 +352,7 @@ void SwitcherData::loadSceneTriggers(obs_data_t *obj)
|
|||||||
obs_data_array_release(triggerArray);
|
obs_data_array_release(triggerArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupTriggerTab()
|
void AdvSceneSwitcher::SetupTriggerTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->sceneTriggers) {
|
for (auto &s : switcher->sceneTriggers) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -398,7 +401,7 @@ void SceneTrigger::load(obs_data_t *obj)
|
|||||||
|
|
||||||
static inline void populateTriggers(QComboBox *list)
|
static inline void populateTriggers(QComboBox *list)
|
||||||
{
|
{
|
||||||
addSelectionEntry(
|
AddSelectionEntry(
|
||||||
list,
|
list,
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none"));
|
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none"));
|
||||||
@@ -413,7 +416,7 @@ static inline void populateTriggers(QComboBox *list)
|
|||||||
|
|
||||||
inline void populateActions(QComboBox *list)
|
inline void populateActions(QComboBox *list)
|
||||||
{
|
{
|
||||||
addSelectionEntry(
|
AddSelectionEntry(
|
||||||
list,
|
list,
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.none"));
|
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.none"));
|
||||||
@@ -460,17 +463,15 @@ SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
|
|||||||
SLOT(TriggerTypeChanged(int)));
|
SLOT(TriggerTypeChanged(int)));
|
||||||
QWidget::connect(actions, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(actions, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(TriggerActionChanged(int)));
|
SLOT(TriggerActionChanged(int)));
|
||||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||||
SLOT(DurationChanged(double)));
|
this, SLOT(DurationChanged(const Duration &)));
|
||||||
QWidget::connect(duration, SIGNAL(UnitChanged(DurationUnit)), this,
|
|
||||||
SLOT(DurationUnitChanged(DurationUnit)));
|
|
||||||
QWidget::connect(audioSources,
|
QWidget::connect(audioSources,
|
||||||
SIGNAL(currentTextChanged(const QString &)), this,
|
SIGNAL(currentTextChanged(const QString &)), this,
|
||||||
SLOT(AudioSourceChanged(const QString &)));
|
SLOT(AudioSourceChanged(const QString &)));
|
||||||
|
|
||||||
populateTriggers(triggers);
|
populateTriggers(triggers);
|
||||||
populateActions(actions);
|
populateActions(actions);
|
||||||
populateAudioSelection(audioSources);
|
PopulateAudioSelection(audioSources);
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
triggers->setCurrentIndex(static_cast<int>(s->triggerType));
|
triggers->setCurrentIndex(static_cast<int>(s->triggerType));
|
||||||
@@ -494,7 +495,7 @@ SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
|
|||||||
{"{{audioSources}}", audioSources},
|
{"{{audioSources}}", audioSources},
|
||||||
{"{{duration}}", duration},
|
{"{{duration}}", duration},
|
||||||
{"{{scenes}}", scenes}};
|
{"{{scenes}}", scenes}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.sceneTriggerTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.sceneTriggerTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -552,24 +553,14 @@ void SceneTriggerWidget::TriggerActionChanged(int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneTriggerWidget::DurationChanged(double seconds)
|
void SceneTriggerWidget::DurationChanged(const Duration &duration)
|
||||||
{
|
{
|
||||||
if (loading || !switchData) {
|
if (loading || !switchData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->duration.seconds = seconds;
|
switchData->duration = duration;
|
||||||
}
|
|
||||||
|
|
||||||
void SceneTriggerWidget::DurationUnitChanged(DurationUnit unit)
|
|
||||||
{
|
|
||||||
if (loading || !switchData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switchData->duration.displayUnit = unit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneTriggerWidget::AudioSourceChanged(const QString &text)
|
void SceneTriggerWidget::AudioSourceChanged(const QString &text)
|
||||||
@@ -581,3 +572,5 @@ void SceneTriggerWidget::AudioSourceChanged(const QString &text)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->audioSource = GetWeakSourceByQString(text);
|
switchData->audioSource = GetWeakSourceByQString(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
enum class sceneTriggerType {
|
enum class sceneTriggerType {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
SCENE_ACTIVE = 1,
|
SCENE_ACTIVE = 1,
|
||||||
@@ -71,8 +73,7 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void TriggerTypeChanged(int index);
|
void TriggerTypeChanged(int index);
|
||||||
void TriggerActionChanged(int index);
|
void TriggerActionChanged(int index);
|
||||||
void DurationChanged(double seconds);
|
void DurationChanged(const Duration &);
|
||||||
void DurationUnitChanged(DurationUnit unit);
|
|
||||||
void AudioSourceChanged(const QString &text);
|
void AudioSourceChanged(const QString &text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -83,3 +84,5 @@ private:
|
|||||||
|
|
||||||
SceneTrigger *switchData;
|
SceneTrigger *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#include <float.h>
|
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
#include "volume-control.hpp"
|
#include "volume-control.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
bool AudioSwitch::pause = false;
|
bool AudioSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
|
|
||||||
@@ -212,7 +215,7 @@ void SwitcherData::loadAudioSwitches(obs_data_t *obj)
|
|||||||
audioFallback.load(obj);
|
audioFallback.load(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupAudioTab()
|
void AdvSceneSwitcher::SetupAudioTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->audioSwitches) {
|
for (auto &s : switcher->audioSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -438,15 +441,15 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
|||||||
SLOT(VolumeThresholdChanged(int)));
|
SLOT(VolumeThresholdChanged(int)));
|
||||||
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(ConditionChanged(int)));
|
SLOT(ConditionChanged(int)));
|
||||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||||
SLOT(DurationChanged(double)));
|
this, SLOT(DurationChanged(const Duration &)));
|
||||||
QWidget::connect(audioSources,
|
QWidget::connect(audioSources,
|
||||||
SIGNAL(currentTextChanged(const QString &)), this,
|
SIGNAL(currentTextChanged(const QString &)), this,
|
||||||
SLOT(SourceChanged(const QString &)));
|
SLOT(SourceChanged(const QString &)));
|
||||||
QWidget::connect(ignoreInactiveSource, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(ignoreInactiveSource, SIGNAL(stateChanged(int)), this,
|
||||||
SLOT(IgnoreInactiveChanged(int)));
|
SLOT(IgnoreInactiveChanged(int)));
|
||||||
|
|
||||||
populateAudioSelection(audioSources);
|
PopulateAudioSelection(audioSources);
|
||||||
populateConditionSelection(condition);
|
populateConditionSelection(condition);
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
@@ -467,7 +470,7 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
|||||||
{"{{ignoreInactiveSource}}", ignoreInactiveSource},
|
{"{{ignoreInactiveSource}}", ignoreInactiveSource},
|
||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.audioTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.audioTab.entry"),
|
||||||
switchLayout, widgetPlaceholders);
|
switchLayout, widgetPlaceholders);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
@@ -554,14 +557,14 @@ void AudioSwitchWidget::ConditionChanged(int cond)
|
|||||||
switchData->condition = (audioCondition)cond;
|
switchData->condition = (audioCondition)cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSwitchWidget::DurationChanged(double sec)
|
void AudioSwitchWidget::DurationChanged(const Duration &dur)
|
||||||
{
|
{
|
||||||
if (loading || !switchData) {
|
if (loading || !switchData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->duration.seconds = sec;
|
switchData->duration = dur;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSwitchWidget::IgnoreInactiveChanged(int state)
|
void AudioSwitchWidget::IgnoreInactiveChanged(int state)
|
||||||
@@ -580,8 +583,8 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
|||||||
{
|
{
|
||||||
duration = new DurationSelection(this, false);
|
duration = new DurationSelection(this, false);
|
||||||
|
|
||||||
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
|
QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
|
||||||
SLOT(DurationChanged(double)));
|
this, SLOT(DurationChanged(const Duration &)));
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
duration->SetDuration(s->duration);
|
duration->SetDuration(s->duration);
|
||||||
@@ -592,7 +595,7 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
|||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{duration}}", duration},
|
{"{{duration}}", duration},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text("AdvSceneSwitcher.audioTab.multiMatchfallback"),
|
obs_module_text("AdvSceneSwitcher.audioTab.multiMatchfallback"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
@@ -602,12 +605,14 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
|||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSwitchFallbackWidget::DurationChanged(double sec)
|
void AudioSwitchFallbackWidget::DurationChanged(const Duration &dur)
|
||||||
{
|
{
|
||||||
if (loading || !switchData) {
|
if (loading || !switchData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->duration.seconds = sec;
|
switchData->duration = dur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
#include "volume-control.hpp"
|
#include "volume-control.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto audio_func = 8;
|
constexpr auto audio_func = 8;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -75,7 +77,7 @@ private slots:
|
|||||||
void SourceChanged(const QString &text);
|
void SourceChanged(const QString &text);
|
||||||
void VolumeThresholdChanged(int vol);
|
void VolumeThresholdChanged(int vol);
|
||||||
void ConditionChanged(int cond);
|
void ConditionChanged(int cond);
|
||||||
void DurationChanged(double dur);
|
void DurationChanged(const Duration &);
|
||||||
void IgnoreInactiveChanged(int state);
|
void IgnoreInactiveChanged(int state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -96,10 +98,12 @@ public:
|
|||||||
AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s);
|
AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void DurationChanged(double dur);
|
void DurationChanged(const Duration &dur);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DurationSelection *duration;
|
DurationSelection *duration;
|
||||||
|
|
||||||
AudioSwitchFallback *switchData;
|
AudioSwitchFallback *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "platform-funcs.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
bool ExecutableSwitch::pause = false;
|
bool ExecutableSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
|
|
||||||
@@ -99,7 +103,7 @@ bool SwitcherData::checkExeSwitch(OBSWeakSource &scene,
|
|||||||
bool equals = runningProcesses.contains(s.exe);
|
bool equals = runningProcesses.contains(s.exe);
|
||||||
bool matches = (runningProcesses.indexOf(
|
bool matches = (runningProcesses.indexOf(
|
||||||
QRegularExpression(s.exe)) != -1);
|
QRegularExpression(s.exe)) != -1);
|
||||||
bool focus = (!s.inFocus || isInFocus(s.exe));
|
bool focus = (!s.inFocus || IsInFocus(s.exe));
|
||||||
|
|
||||||
// True if current window is ignored AND switch equals OR matches last window
|
// True if current window is ignored AND switch equals OR matches last window
|
||||||
bool ignore =
|
bool ignore =
|
||||||
@@ -156,7 +160,7 @@ void SwitcherData::loadExecutableSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(executableArray);
|
obs_data_array_release(executableArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupExecutableTab()
|
void AdvSceneSwitcher::SetupExecutableTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->executableSwitches) {
|
for (auto &s : switcher->executableSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -208,7 +212,7 @@ ExecutableSwitchWidget::ExecutableSwitchWidget(QWidget *parent,
|
|||||||
QWidget::connect(requiresFocus, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(requiresFocus, SIGNAL(stateChanged(int)), this,
|
||||||
SLOT(FocusChanged(int)));
|
SLOT(FocusChanged(int)));
|
||||||
|
|
||||||
populateProcessSelection(processes);
|
PopulateProcessSelection(processes);
|
||||||
|
|
||||||
processes->setEditable(true);
|
processes->setEditable(true);
|
||||||
processes->setMaxVisibleItems(20);
|
processes->setMaxVisibleItems(20);
|
||||||
@@ -224,7 +228,7 @@ ExecutableSwitchWidget::ExecutableSwitchWidget(QWidget *parent,
|
|||||||
{"{{requiresFocus}}", requiresFocus},
|
{"{{requiresFocus}}", requiresFocus},
|
||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.executableTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.executableTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -272,3 +276,5 @@ void ExecutableSwitchWidget::FocusChanged(int state)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->inFocus = state;
|
switchData->inFocus = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto exe_func = 3;
|
constexpr auto exe_func = 3;
|
||||||
|
|
||||||
struct ExecutableSwitch : SceneSwitcherEntry {
|
struct ExecutableSwitch : SceneSwitcherEntry {
|
||||||
@@ -42,3 +44,5 @@ private:
|
|||||||
|
|
||||||
ExecutableSwitch *switchData;
|
ExecutableSwitch *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "curl-helper.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
@@ -6,9 +11,7 @@
|
|||||||
#include <regex>
|
#include <regex>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "curl-helper.hpp"
|
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
bool FileSwitch::pause = false;
|
bool FileSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
@@ -116,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
|
||||||
@@ -209,7 +212,7 @@ bool matchFileContent(QString &filedata, FileSwitch &s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString text = QString::fromStdString(s.text);
|
QString text = QString::fromStdString(s.text);
|
||||||
return compareIgnoringLineEnding(text, filedata);
|
return CompareIgnoringLineEnding(text, filedata);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkRemoteFileContent(FileSwitch &s)
|
bool checkRemoteFileContent(FileSwitch &s)
|
||||||
@@ -411,7 +414,7 @@ void SwitcherData::loadFileSwitches(obs_data_t *obj)
|
|||||||
fileIO.writePath = obs_data_get_string(obj, "writePath");
|
fileIO.writePath = obs_data_get_string(obj, "writePath");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupFileTab()
|
void AdvSceneSwitcher::SetupFileTab()
|
||||||
{
|
{
|
||||||
ui->remoteFileWarningLabel->setText(
|
ui->remoteFileWarningLabel->setText(
|
||||||
obs_module_text("AdvSceneSwitcher.fileTab.remoteFileWarning1") +
|
obs_module_text("AdvSceneSwitcher.fileTab.remoteFileWarning1") +
|
||||||
@@ -542,11 +545,11 @@ FileSwitchWidget::FileSwitchWidget(QWidget *parent, FileSwitch *s)
|
|||||||
QHBoxLayout *line1Layout = new QHBoxLayout;
|
QHBoxLayout *line1Layout = new QHBoxLayout;
|
||||||
QHBoxLayout *line2Layout = new QHBoxLayout;
|
QHBoxLayout *line2Layout = new QHBoxLayout;
|
||||||
QHBoxLayout *line3Layout = new QHBoxLayout;
|
QHBoxLayout *line3Layout = new QHBoxLayout;
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry"),
|
||||||
line1Layout, widgetPlaceholders);
|
line1Layout, widgetPlaceholders);
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry2"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry2"),
|
||||||
line2Layout, widgetPlaceholders, false);
|
line2Layout, widgetPlaceholders, false);
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry3"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.fileTab.entry3"),
|
||||||
line3Layout, widgetPlaceholders);
|
line3Layout, widgetPlaceholders);
|
||||||
mainLayout->addLayout(line1Layout);
|
mainLayout->addLayout(line1Layout);
|
||||||
mainLayout->addLayout(line2Layout);
|
mainLayout->addLayout(line2Layout);
|
||||||
@@ -665,3 +668,5 @@ void FileSwitchWidget::CheckFileContentChanged(int state)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->onlyMatchIfChanged = state;
|
switchData->onlyMatchIfChanged = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -8,8 +8,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
#include <QDateTime>
|
||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto read_file_func = 0;
|
constexpr auto read_file_func = 0;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -77,3 +80,5 @@ static inline QString MakeFileSwitchName(const QString &scene,
|
|||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
const QString &text, bool useRegex,
|
const QString &text, bool useRegex,
|
||||||
bool useTime, bool onlyMatchIfChanged);
|
bool useTime, bool onlyMatchIfChanged);
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
constexpr auto previous_scene_name = "Previous Scene";
|
||||||
|
constexpr auto current_transition_name = "Current Transition";
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
static inline bool SceneGroupValid(SceneGroup *group)
|
static inline bool SceneGroupValid(SceneGroup *group)
|
||||||
{
|
{
|
||||||
if (group) {
|
if (group) {
|
||||||
@@ -208,9 +214,9 @@ SwitchWidget::SwitchWidget(QWidget *parent, SceneSwitcherEntry *s,
|
|||||||
SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
|
SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
|
||||||
this, SLOT(SceneGroupRename(const QString &, const QString &)));
|
this, SLOT(SceneGroupRename(const QString &, const QString &)));
|
||||||
|
|
||||||
populateSceneSelection(scenes, usePreviousScene, false, false,
|
PopulateSceneSelection(scenes, usePreviousScene, false, false,
|
||||||
addSceneGroup, &switcher->sceneGroups);
|
addSceneGroup, &switcher->sceneGroups);
|
||||||
populateTransitionSelection(transitions, addCurrentTransition);
|
PopulateTransitionSelection(transitions, addCurrentTransition);
|
||||||
|
|
||||||
switchData = s;
|
switchData = s;
|
||||||
showSwitchData();
|
showSwitchData();
|
||||||
@@ -300,3 +306,5 @@ void SwitchWidget::TransitionChanged(const QString &text)
|
|||||||
switchData->transition = GetWeakTransitionByQString(text);
|
switchData->transition = GetWeakTransitionByQString(text);
|
||||||
switchData->useCurrentTransition = switchData->transition == nullptr;
|
switchData->useCurrentTransition = switchData->transition == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "scene-group.hpp"
|
#include "scene-group.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
enum class SwitchTargetType {
|
enum class SwitchTargetType {
|
||||||
Scene,
|
Scene,
|
||||||
SceneGroup,
|
SceneGroup,
|
||||||
@@ -95,3 +97,5 @@ protected:
|
|||||||
|
|
||||||
SceneSwitcherEntry *switchData;
|
SceneSwitcherEntry *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "platform-funcs.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
bool IdleData::pause = false;
|
bool IdleData::pause = false;
|
||||||
IdleWidget *idleWidget = nullptr;
|
IdleWidget *idleWidget = nullptr;
|
||||||
@@ -38,7 +42,7 @@ bool SwitcherData::checkIdleSwitch(OBSWeakSource &scene,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ignoreIdle && secondsSinceLastInput() > idleData.time) {
|
if (!ignoreIdle && SecondsSinceLastInput() > idleData.time) {
|
||||||
if (idleData.alreadySwitched) {
|
if (idleData.alreadySwitched) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -205,9 +209,9 @@ void SwitcherData::loadIdleSwitches(obs_data_t *obj)
|
|||||||
idleData.load(obj);
|
idleData.load(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupIdleTab()
|
void AdvSceneSwitcher::SetupIdleTab()
|
||||||
{
|
{
|
||||||
populateWindowSelection(ui->ignoreIdleWindowsWindows);
|
PopulateWindowSelection(ui->ignoreIdleWindowsWindows);
|
||||||
|
|
||||||
for (auto &window : switcher->ignoreIdleWindows) {
|
for (auto &window : switcher->ignoreIdleWindows) {
|
||||||
QString text = QString::fromStdString(window);
|
QString text = QString::fromStdString(window);
|
||||||
@@ -267,7 +271,7 @@ IdleWidget::IdleWidget(QWidget *parent, IdleData *s)
|
|||||||
{"{{duration}}", duration},
|
{"{{duration}}", duration},
|
||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.idleTab.idleswitch"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.idleTab.idleswitch"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -285,3 +289,5 @@ void IdleWidget::DurationChanged(int dur)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switcher->idleData.time = dur;
|
switcher->idleData.time = dur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto default_idle_time = 60;
|
constexpr auto default_idle_time = 60;
|
||||||
constexpr auto idle_func = 2;
|
constexpr auto idle_func = 2;
|
||||||
|
|
||||||
@@ -36,3 +38,5 @@ private:
|
|||||||
|
|
||||||
IdleData *switchData;
|
IdleData *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
bool MediaSwitch::pause = false;
|
bool MediaSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
|
|
||||||
@@ -232,7 +235,7 @@ void SwitcherData::loadMediaSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(mediaArray);
|
obs_data_array_release(mediaArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupMediaTab()
|
void AdvSceneSwitcher::SetupMediaTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->mediaSwitches) {
|
for (auto &s : switcher->mediaSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -460,7 +463,7 @@ MediaSwitchWidget::MediaSwitchWidget(QWidget *parent, MediaSwitch *s)
|
|||||||
QWidget::connect(time, SIGNAL(valueChanged(int)), this,
|
QWidget::connect(time, SIGNAL(valueChanged(int)), this,
|
||||||
SLOT(TimeChanged(int)));
|
SLOT(TimeChanged(int)));
|
||||||
|
|
||||||
populateMediaSelection(mediaSources);
|
PopulateMediaSelection(mediaSources);
|
||||||
populateMediaStates(states);
|
populateMediaStates(states);
|
||||||
populateTimeRestrictions(timeRestrictions);
|
populateTimeRestrictions(timeRestrictions);
|
||||||
|
|
||||||
@@ -483,7 +486,7 @@ MediaSwitchWidget::MediaSwitchWidget(QWidget *parent, MediaSwitch *s)
|
|||||||
{"{{time}}", time},
|
{"{{time}}", time},
|
||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.mediaTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.mediaTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -560,3 +563,5 @@ void MediaSwitchWidget::TimeChanged(int time)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->time = time;
|
switchData->time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto media_func = 6;
|
constexpr auto media_func = 6;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -83,3 +85,5 @@ private:
|
|||||||
|
|
||||||
MediaSwitch *switchData;
|
MediaSwitch *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -7,8 +7,12 @@ Most of this code is based on https://github.com/Palakis/obs-websocket
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "scene-switch-helpers.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
#define PARAM_SERVER_ENABLE "ServerEnabled"
|
#define PARAM_SERVER_ENABLE "ServerEnabled"
|
||||||
#define PARAM_SERVER_PORT "ServerPort"
|
#define PARAM_SERVER_PORT "ServerPort"
|
||||||
#define PARAM_LOCKTOIPV4 "LockToIPv4"
|
#define PARAM_LOCKTOIPV4 "LockToIPv4"
|
||||||
@@ -124,10 +128,9 @@ WSServer::WSServer() : QObject(nullptr), _connections(), _clMutex()
|
|||||||
_server.set_reuse_addr(true);
|
_server.set_reuse_addr(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_server.set_open_handler(bind(&WSServer::onOpen, this, ::_1));
|
_server.set_open_handler(bind(&WSServer::onOpen, this, _1));
|
||||||
_server.set_close_handler(bind(&WSServer::onClose, this, ::_1));
|
_server.set_close_handler(bind(&WSServer::onClose, this, _1));
|
||||||
_server.set_message_handler(
|
_server.set_message_handler(bind(&WSServer::onMessage, this, _1, _2));
|
||||||
bind(&WSServer::onMessage, this, ::_1, ::_2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WSServer::~WSServer()
|
WSServer::~WSServer()
|
||||||
@@ -221,7 +224,7 @@ void WSServer::stop()
|
|||||||
blog(LOG_INFO, "server stopped successfully");
|
blog(LOG_INFO, "server stopped successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSServer::sendMessage(sceneSwitchInfo sceneSwitch, bool preview)
|
void WSServer::sendMessage(SceneSwitchInfo sceneSwitch, bool preview)
|
||||||
{
|
{
|
||||||
if (!sceneSwitch.scene) {
|
if (!sceneSwitch.scene) {
|
||||||
return;
|
return;
|
||||||
@@ -305,9 +308,9 @@ std::string processMessage(std::string payload)
|
|||||||
"'";
|
"'";
|
||||||
}
|
}
|
||||||
if (preview) {
|
if (preview) {
|
||||||
switchPreviewScene(scene);
|
SwitchPreviewScene(scene);
|
||||||
} else {
|
} else {
|
||||||
switchScene({scene, transition, duration});
|
SwitchScene({scene, transition, duration});
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -361,11 +364,10 @@ WSClient::WSClient() : QObject(nullptr)
|
|||||||
_client.set_reuse_addr(true);
|
_client.set_reuse_addr(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_client.set_open_handler(bind(&WSClient::onOpen, this, ::_1));
|
_client.set_open_handler(bind(&WSClient::onOpen, this, _1));
|
||||||
_client.set_fail_handler(bind(&WSClient::onFail, this, ::_1));
|
_client.set_fail_handler(bind(&WSClient::onFail, this, _1));
|
||||||
_client.set_message_handler(
|
_client.set_message_handler(bind(&WSClient::onMessage, this, _1, _2));
|
||||||
bind(&WSClient::onMessage, this, ::_1, ::_2));
|
_client.set_close_handler(bind(&WSClient::onClose, this, _1));
|
||||||
_client.set_close_handler(bind(&WSClient::onClose, this, ::_1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WSClient::~WSClient()
|
WSClient::~WSClient()
|
||||||
@@ -501,7 +503,7 @@ void SwitcherData::saveNetworkSwitches(obs_data_t *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupNetworkTab()
|
void AdvSceneSwitcher::SetupNetworkTab()
|
||||||
{
|
{
|
||||||
ui->serverSettings->setChecked(switcher->networkConfig.ServerEnabled);
|
ui->serverSettings->setChecked(switcher->networkConfig.ServerEnabled);
|
||||||
ui->serverPort->setValue(switcher->networkConfig.ServerPort);
|
ui->serverPort->setValue(switcher->networkConfig.ServerPort);
|
||||||
@@ -519,9 +521,9 @@ void AdvSceneSwitcher::setupNetworkTab()
|
|||||||
|
|
||||||
QTimer *statusTimer = new QTimer(this);
|
QTimer *statusTimer = new QTimer(this);
|
||||||
connect(statusTimer, SIGNAL(timeout()), this,
|
connect(statusTimer, SIGNAL(timeout()), this,
|
||||||
SLOT(updateClientStatus()));
|
SLOT(UpdateClientStatus()));
|
||||||
connect(statusTimer, SIGNAL(timeout()), this,
|
connect(statusTimer, SIGNAL(timeout()), this,
|
||||||
SLOT(updateServerStatus()));
|
SLOT(UpdateServerStatus()));
|
||||||
statusTimer->start(500);
|
statusTimer->start(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,7 +574,7 @@ void AdvSceneSwitcher::on_serverRestart_clicked()
|
|||||||
switcher->networkConfig.LockToIPv4);
|
switcher->networkConfig.LockToIPv4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::updateServerStatus()
|
void AdvSceneSwitcher::UpdateServerStatus()
|
||||||
{
|
{
|
||||||
switch (switcher->serverStatus) {
|
switch (switcher->serverStatus) {
|
||||||
case ServerStatus::NOT_RUNNING:
|
case ServerStatus::NOT_RUNNING:
|
||||||
@@ -670,7 +672,7 @@ void AdvSceneSwitcher::on_clientReconnect_clicked()
|
|||||||
switcher->client.connect(switcher->networkConfig.GetClientUri());
|
switcher->client.connect(switcher->networkConfig.GetClientUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::updateClientStatus()
|
void AdvSceneSwitcher::UpdateClientStatus()
|
||||||
{
|
{
|
||||||
switch (switcher->clientStatus) {
|
switch (switcher->clientStatus) {
|
||||||
case ClientStatus::DISCONNECTED:
|
case ClientStatus::DISCONNECTED:
|
||||||
@@ -709,3 +711,5 @@ Compatability::StdFunctionRunnable::StdFunctionRunnable(
|
|||||||
: cb(std::move(func))
|
: cb(std::move(func))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ Most of this code is based on https://github.com/Palakis/obs-websocket
|
|||||||
#include <websocketpp/server.hpp>
|
#include <websocketpp/server.hpp>
|
||||||
#include <websocketpp/client.hpp>
|
#include <websocketpp/client.hpp>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
using websocketpp::connection_hdl;
|
using websocketpp::connection_hdl;
|
||||||
typedef websocketpp::server<websocketpp::config::asio> server;
|
typedef websocketpp::server<websocketpp::config::asio> server;
|
||||||
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
typedef websocketpp::client<websocketpp::config::asio_client> client;
|
||||||
|
|
||||||
struct sceneSwitchInfo;
|
struct SceneSwitchInfo;
|
||||||
|
|
||||||
class NetworkConfig {
|
class NetworkConfig {
|
||||||
public:
|
public:
|
||||||
@@ -60,7 +62,7 @@ public:
|
|||||||
virtual ~WSServer();
|
virtual ~WSServer();
|
||||||
void start(quint16 port, bool lockToIPv4);
|
void start(quint16 port, bool lockToIPv4);
|
||||||
void stop();
|
void stop();
|
||||||
void sendMessage(sceneSwitchInfo sceneSwitch, bool preview = false);
|
void sendMessage(SceneSwitchInfo sceneSwitch, bool preview = false);
|
||||||
QThreadPool *threadPool() { return &_threadPool; }
|
QThreadPool *threadPool() { return &_threadPool; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -131,3 +133,5 @@ public:
|
|||||||
|
|
||||||
QRunnable *CreateFunctionRunnable(std::function<void()> func);
|
QRunnable *CreateFunctionRunnable(std::function<void()> func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
|
|
||||||
@@ -244,7 +247,7 @@ void SwitcherData::loadPauseSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(pauseArray);
|
obs_data_array_release(pauseArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupPauseTab()
|
void AdvSceneSwitcher::SetupPauseTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->pauseEntries) {
|
for (auto &s : switcher->pauseEntries) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -309,7 +312,7 @@ PauseEntryWidget::PauseEntryWidget(QWidget *parent, PauseEntry *s)
|
|||||||
|
|
||||||
populatePauseTypes(pauseTypes);
|
populatePauseTypes(pauseTypes);
|
||||||
populatePauseTargets(pauseTargets);
|
populatePauseTargets(pauseTargets);
|
||||||
populateWindowSelection(windows);
|
PopulateWindowSelection(windows);
|
||||||
|
|
||||||
windows->setEditable(true);
|
windows->setEditable(true);
|
||||||
windows->setMaxVisibleItems(20);
|
windows->setMaxVisibleItems(20);
|
||||||
@@ -335,7 +338,7 @@ PauseEntryWidget::PauseEntryWidget(QWidget *parent, PauseEntry *s)
|
|||||||
{"{{pauseTargets}}", pauseTargets},
|
{"{{pauseTargets}}", pauseTargets},
|
||||||
{"{{windows}}", windows}};
|
{"{{windows}}", windows}};
|
||||||
|
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.pauseTab.pauseEntry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.pauseTab.pauseEntry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -410,3 +413,5 @@ bool PauseEntry::valid()
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
enum class PauseType {
|
enum class PauseType {
|
||||||
Scene,
|
Scene,
|
||||||
Window,
|
Window,
|
||||||
@@ -70,3 +72,5 @@ private:
|
|||||||
|
|
||||||
PauseEntry *switchData;
|
PauseEntry *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_threadPriority_currentTextChanged(const QString &text)
|
|
||||||
{
|
|
||||||
if (loading || ui->threadPriority->count() !=
|
|
||||||
(int)switcher->threadPriorities.size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
|
|
||||||
for (auto p : switcher->threadPriorities) {
|
|
||||||
if (p.name == text.toUtf8().constData()) {
|
|
||||||
switcher->threadPriority = p.value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_priorityUp_clicked()
|
|
||||||
{
|
|
||||||
int currentIndex = ui->priorityList->currentRow();
|
|
||||||
if (currentIndex != -1 && currentIndex != 0) {
|
|
||||||
ui->priorityList->insertItem(
|
|
||||||
currentIndex - 1,
|
|
||||||
ui->priorityList->takeItem(currentIndex));
|
|
||||||
ui->priorityList->setCurrentRow(currentIndex - 1);
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
|
|
||||||
iter_swap(switcher->functionNamesByPriority.begin() +
|
|
||||||
currentIndex,
|
|
||||||
switcher->functionNamesByPriority.begin() +
|
|
||||||
currentIndex - 1);
|
|
||||||
}
|
|
||||||
ui->macroPriorityWarning->setVisible(
|
|
||||||
switcher->functionNamesByPriority[0] != macro_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_priorityDown_clicked()
|
|
||||||
{
|
|
||||||
int currentIndex = ui->priorityList->currentRow();
|
|
||||||
if (currentIndex != -1 &&
|
|
||||||
currentIndex != ui->priorityList->count() - 1) {
|
|
||||||
ui->priorityList->insertItem(
|
|
||||||
currentIndex + 1,
|
|
||||||
ui->priorityList->takeItem(currentIndex));
|
|
||||||
ui->priorityList->setCurrentRow(currentIndex + 1);
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
|
|
||||||
iter_swap(switcher->functionNamesByPriority.begin() +
|
|
||||||
currentIndex,
|
|
||||||
switcher->functionNamesByPriority.begin() +
|
|
||||||
currentIndex + 1);
|
|
||||||
}
|
|
||||||
ui->macroPriorityWarning->setVisible(
|
|
||||||
switcher->functionNamesByPriority[0] != macro_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SwitcherData::prioFuncsValid()
|
|
||||||
{
|
|
||||||
auto fNBPCopy = functionNamesByPriority;
|
|
||||||
|
|
||||||
std::sort(fNBPCopy.begin(), fNBPCopy.end());
|
|
||||||
auto it = std::unique(fNBPCopy.begin(), fNBPCopy.end());
|
|
||||||
bool wasUnique = (it == fNBPCopy.end());
|
|
||||||
|
|
||||||
if (!wasUnique) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int p : functionNamesByPriority) {
|
|
||||||
if (p < 0 || p > 10) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
bool RandomSwitch::pause = false;
|
bool RandomSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
@@ -113,7 +116,7 @@ void SwitcherData::loadRandomSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(randomArray);
|
obs_data_array_release(randomArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupRandomTab()
|
void AdvSceneSwitcher::SetupRandomTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->randomSwitches) {
|
for (auto &s : switcher->randomSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -140,7 +143,7 @@ void AdvSceneSwitcher::setupRandomTab()
|
|||||||
border-radius: 7px; \
|
border-radius: 7px; \
|
||||||
border-color: rgb(0,0,0,0) \
|
border-color: rgb(0,0,0,0) \
|
||||||
}");
|
}");
|
||||||
if (switcher->switchIfNotMatching != RANDOM_SWITCH) {
|
if (switcher->switchIfNotMatching != NoMatchBehavior::RANDOM_SWITCH) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
PulseWidget(ui->randomDisabledWarning, QColor(Qt::red),
|
PulseWidget(ui->randomDisabledWarning, QColor(Qt::red),
|
||||||
QColor(0, 0, 0, 0));
|
QColor(0, 0, 0, 0));
|
||||||
@@ -182,7 +185,7 @@ RandomSwitchWidget::RandomSwitchWidget(QWidget *parent, RandomSwitch *s)
|
|||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions},
|
{"{{transitions}}", transitions},
|
||||||
{"{{delay}}", delay}};
|
{"{{delay}}", delay}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.randomTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.randomTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -220,3 +223,5 @@ void RandomSwitchWidget::DelayChanged(double d)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->delay = d;
|
switchData->delay = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
struct RandomSwitch : SceneSwitcherEntry {
|
struct RandomSwitch : SceneSwitcherEntry {
|
||||||
static bool pause;
|
static bool pause;
|
||||||
double delay = 0.0;
|
double delay = 0.0;
|
||||||
@@ -36,3 +38,5 @@ private:
|
|||||||
|
|
||||||
RandomSwitch *switchData;
|
RandomSwitch *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
bool ScreenRegionSwitch::pause = false;
|
bool ScreenRegionSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
|
|
||||||
void AdvSceneSwitcher::clearFrames(QListWidget *list)
|
void AdvSceneSwitcher::ClearFrames(QListWidget *list)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < list->count(); ++i) {
|
for (int i = 0; i < list->count(); ++i) {
|
||||||
ScreenRegionWidget *sw =
|
ScreenRegionWidget *sw =
|
||||||
@@ -48,7 +51,7 @@ void AdvSceneSwitcher::on_showFrame_clicked()
|
|||||||
showCurrentFrame(ui->screenRegionSwitches);
|
showCurrentFrame(ui->screenRegionSwitches);
|
||||||
} else {
|
} else {
|
||||||
SetShowFrames();
|
SetShowFrames();
|
||||||
clearFrames(ui->screenRegionSwitches);
|
ClearFrames(ui->screenRegionSwitches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +62,7 @@ void AdvSceneSwitcher::on_screenRegionSwitches_currentRowChanged(int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (switcher->showFrame) {
|
if (switcher->showFrame) {
|
||||||
clearFrames(ui->screenRegionSwitches);
|
ClearFrames(ui->screenRegionSwitches);
|
||||||
showCurrentFrame(ui->screenRegionSwitches);
|
showCurrentFrame(ui->screenRegionSwitches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +156,7 @@ bool SwitcherData::checkScreenRegionSwitch(OBSWeakSource &scene,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int> cursorPos = getCursorPos();
|
std::pair<int, int> cursorPos = GetCursorPos();
|
||||||
int minRegionSize = 99999;
|
int minRegionSize = 99999;
|
||||||
bool match = false;
|
bool match = false;
|
||||||
|
|
||||||
@@ -188,7 +191,7 @@ bool SwitcherData::checkScreenRegionSwitch(OBSWeakSource &scene,
|
|||||||
|
|
||||||
void AdvSceneSwitcher::updateScreenRegionCursorPos()
|
void AdvSceneSwitcher::updateScreenRegionCursorPos()
|
||||||
{
|
{
|
||||||
std::pair<int, int> position = getCursorPos();
|
std::pair<int, int> position = GetCursorPos();
|
||||||
ui->cursorXPosition->setText(QString::number(position.first));
|
ui->cursorXPosition->setText(QString::number(position.first));
|
||||||
ui->cursorYPosition->setText(QString::number(position.second));
|
ui->cursorYPosition->setText(QString::number(position.second));
|
||||||
}
|
}
|
||||||
@@ -228,7 +231,7 @@ void SwitcherData::loadScreenRegionSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(screenRegionArray);
|
obs_data_array_release(screenRegionArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupRegionTab()
|
void AdvSceneSwitcher::SetupRegionTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->screenRegionSwitches) {
|
for (auto &s : switcher->screenRegionSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -318,7 +321,7 @@ ScreenRegionWidget::ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s)
|
|||||||
QWidget::connect(maxY, SIGNAL(valueChanged(int)), this,
|
QWidget::connect(maxY, SIGNAL(valueChanged(int)), this,
|
||||||
SLOT(MaxYChanged(int)));
|
SLOT(MaxYChanged(int)));
|
||||||
|
|
||||||
populateSceneSelection(
|
PopulateSceneSelection(
|
||||||
excludeScenes, false, false, false, false, nullptr, true,
|
excludeScenes, false, false, false, false, nullptr, true,
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.screenRegionTab.excludeScenes.None"),
|
"AdvSceneSwitcher.screenRegionTab.excludeScenes.None"),
|
||||||
@@ -342,7 +345,7 @@ ScreenRegionWidget::ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s)
|
|||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions},
|
{"{{transitions}}", transitions},
|
||||||
{"{{excludeScenes}}", excludeScenes}};
|
{"{{excludeScenes}}", excludeScenes}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.screenRegionTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.screenRegionTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -455,3 +458,5 @@ void ScreenRegionWidget::drawFrame()
|
|||||||
switchData->maxY - switchData->minY);
|
switchData->maxY - switchData->minY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto screen_region_func = 4;
|
constexpr auto screen_region_func = 4;
|
||||||
|
|
||||||
struct ScreenRegionSwitch : SceneSwitcherEntry {
|
struct ScreenRegionSwitch : SceneSwitcherEntry {
|
||||||
@@ -55,3 +57,5 @@ private:
|
|||||||
|
|
||||||
void drawFrame();
|
void drawFrame();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
constexpr auto max_extend_text_size = 150;
|
constexpr auto max_extend_text_size = 150;
|
||||||
|
|
||||||
@@ -278,7 +281,7 @@ void SwitcherData::loadSceneSequenceSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(sceneSequenceArray);
|
obs_data_array_release(sceneSequenceArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupSequenceTab()
|
void AdvSceneSwitcher::SetupSequenceTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->sceneSequenceSwitches) {
|
for (auto &s : switcher->sceneSequenceSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -455,7 +458,7 @@ bool SceneSequenceSwitch::checkDurationMatchInterruptible()
|
|||||||
|
|
||||||
void SceneSequenceSwitch::prepareUninterruptibleMatch(int &linger)
|
void SceneSequenceSwitch::prepareUninterruptibleMatch(int &linger)
|
||||||
{
|
{
|
||||||
int dur = delay.seconds * 1000;
|
int dur = delay.Milliseconds();
|
||||||
if (dur > 0) {
|
if (dur > 0) {
|
||||||
linger = dur;
|
linger = dur;
|
||||||
}
|
}
|
||||||
@@ -588,10 +591,8 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
|||||||
QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)),
|
QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)),
|
||||||
this, SLOT(SceneChanged(const QString &)));
|
this, SLOT(SceneChanged(const QString &)));
|
||||||
|
|
||||||
QWidget::connect(delay, SIGNAL(DurationChanged(double)), this,
|
QWidget::connect(delay, SIGNAL(DurationChanged(const Duration &)), this,
|
||||||
SLOT(DelayChanged(double)));
|
SLOT(DelayChanged(const Duration &)));
|
||||||
QWidget::connect(delay, SIGNAL(UnitChanged(DurationUnit)), this,
|
|
||||||
SLOT(DelayUnitsChanged(DurationUnit)));
|
|
||||||
QWidget::connect(startScenes,
|
QWidget::connect(startScenes,
|
||||||
SIGNAL(currentTextChanged(const QString &)), this,
|
SIGNAL(currentTextChanged(const QString &)), this,
|
||||||
SLOT(StartSceneChanged(const QString &)));
|
SLOT(StartSceneChanged(const QString &)));
|
||||||
@@ -603,7 +604,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
|||||||
QWidget::connect(reduce, SIGNAL(clicked()), this,
|
QWidget::connect(reduce, SIGNAL(clicked()), this,
|
||||||
SLOT(ReduceClicked()));
|
SLOT(ReduceClicked()));
|
||||||
|
|
||||||
populateSceneSelection(startScenes);
|
PopulateSceneSelection(startScenes);
|
||||||
interruptible->setToolTip(obs_module_text(
|
interruptible->setToolTip(obs_module_text(
|
||||||
"AdvSceneSwitcher.sceneSequenceTab.interruptibleHint"));
|
"AdvSceneSwitcher.sceneSequenceTab.interruptibleHint"));
|
||||||
|
|
||||||
@@ -615,7 +616,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
|||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{delay}}", delay},
|
{"{{delay}}", delay},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.sceneSequenceTab.extendEntry"),
|
"AdvSceneSwitcher.sceneSequenceTab.extendEntry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
@@ -628,7 +629,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
|
|||||||
{"{{delay}}", delay},
|
{"{{delay}}", delay},
|
||||||
{"{{transitions}}", transitions},
|
{"{{transitions}}", transitions},
|
||||||
{"{{interruptible}}", interruptible}};
|
{"{{interruptible}}", interruptible}};
|
||||||
placeWidgets(obs_module_text(
|
PlaceWidgets(obs_module_text(
|
||||||
"AdvSceneSwitcher.sceneSequenceTab.entry"),
|
"AdvSceneSwitcher.sceneSequenceTab.entry"),
|
||||||
startSequence, widgetPlaceholders);
|
startSequence, widgetPlaceholders);
|
||||||
|
|
||||||
@@ -689,24 +690,14 @@ void SequenceWidget::swapSwitchData(SequenceWidget *s1, SequenceWidget *s2)
|
|||||||
s2->setSwitchData(t);
|
s2->setSwitchData(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequenceWidget::DelayChanged(double sec)
|
void SequenceWidget::DelayChanged(const Duration &delay)
|
||||||
{
|
{
|
||||||
if (loading || !switchData) {
|
if (loading || !switchData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->delay.seconds = sec;
|
switchData->delay = delay;
|
||||||
}
|
|
||||||
|
|
||||||
void SequenceWidget::DelayUnitsChanged(DurationUnit unit)
|
|
||||||
{
|
|
||||||
if (loading || !switchData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
|
||||||
switchData->delay.displayUnit = unit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequenceWidget::setExtendedSequenceStartScene()
|
void SequenceWidget::setExtendedSequenceStartScene()
|
||||||
@@ -805,3 +796,5 @@ void SequenceWidget::ReduceClicked()
|
|||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto round_trip_func = 1;
|
constexpr auto round_trip_func = 1;
|
||||||
|
|
||||||
struct SceneSequenceSwitch : SceneSwitcherEntry {
|
struct SceneSequenceSwitch : SceneSwitcherEntry {
|
||||||
@@ -59,8 +61,7 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void SceneChanged(const QString &text);
|
void SceneChanged(const QString &text);
|
||||||
void DelayChanged(double delay);
|
void DelayChanged(const Duration &delay);
|
||||||
void DelayUnitsChanged(DurationUnit);
|
|
||||||
void StartSceneChanged(const QString &text);
|
void StartSceneChanged(const QString &text);
|
||||||
void InterruptibleChanged(int state);
|
void InterruptibleChanged(int state);
|
||||||
void ExtendClicked();
|
void ExtendClicked();
|
||||||
@@ -83,3 +84,5 @@ protected:
|
|||||||
|
|
||||||
SceneSequenceSwitch *switchData;
|
SceneSequenceSwitch *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
bool TimeSwitch::pause = false;
|
bool TimeSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
|
|
||||||
@@ -179,7 +182,7 @@ void SwitcherData::loadTimeSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(timeArray);
|
obs_data_array_release(timeArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupTimeTab()
|
void AdvSceneSwitcher::SetupTimeTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->timeSwitches) {
|
for (auto &s : switcher->timeSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -258,7 +261,7 @@ TimeSwitchWidget::TimeSwitchWidget(QWidget *parent, TimeSwitch *s)
|
|||||||
{"{{time}}", time},
|
{"{{time}}", time},
|
||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.timeTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.timeTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -306,3 +309,5 @@ void TimeSwitchWidget::TimeChanged(const QTime &time)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->time = time;
|
switchData->time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto time_func = 7;
|
constexpr auto time_func = 7;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -54,3 +56,5 @@ private:
|
|||||||
|
|
||||||
TimeSwitch *switchData;
|
TimeSwitch *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
constexpr auto default_def_transition_dealy = 300;
|
constexpr auto default_def_transition_dealy = 300;
|
||||||
bool DefaultSceneTransition::pause = false;
|
bool DefaultSceneTransition::pause = false;
|
||||||
@@ -169,7 +172,7 @@ void SwitcherData::checkDefaultSceneTransitions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::defTransitionDelayValueChanged(int value)
|
void AdvSceneSwitcher::DefTransitionDelayValueChanged(int value)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return;
|
return;
|
||||||
@@ -179,104 +182,6 @@ void AdvSceneSwitcher::defTransitionDelayValueChanged(int value)
|
|||||||
DefaultSceneTransition::delay = value;
|
DefaultSceneTransition::delay = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<obs_weak_source_t *, int> getNextTransition(obs_weak_source_t *scene1,
|
|
||||||
obs_weak_source_t *scene2)
|
|
||||||
{
|
|
||||||
obs_weak_source_t *ws = nullptr;
|
|
||||||
int duration = 0;
|
|
||||||
if (scene1 && scene2) {
|
|
||||||
for (SceneTransition &t : switcher->sceneTransitions) {
|
|
||||||
if (!t.initialized()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t.scene == scene1 && t.scene2 == scene2) {
|
|
||||||
ws = t.transition;
|
|
||||||
duration = t.duration * 1000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std::make_pair(ws, duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void overwriteTransitionOverride(const sceneSwitchInfo &ssi, transitionData &td)
|
|
||||||
{
|
|
||||||
obs_source_t *scene = obs_weak_source_get_source(ssi.scene);
|
|
||||||
obs_data_t *data = obs_source_get_private_settings(scene);
|
|
||||||
|
|
||||||
td.name = obs_data_get_string(data, "transition");
|
|
||||||
td.duration = obs_data_get_int(data, "transition_duration");
|
|
||||||
|
|
||||||
std::string name = GetWeakSourceName(ssi.transition);
|
|
||||||
|
|
||||||
obs_data_set_string(data, "transition", name.c_str());
|
|
||||||
obs_data_set_int(data, "transition_duration", ssi.duration);
|
|
||||||
|
|
||||||
obs_data_release(data);
|
|
||||||
obs_source_release(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
void restoreTransitionOverride(obs_source_t *scene, const transitionData &td)
|
|
||||||
{
|
|
||||||
obs_data_t *data = obs_source_get_private_settings(scene);
|
|
||||||
|
|
||||||
obs_data_set_string(data, "transition", td.name.c_str());
|
|
||||||
obs_data_set_int(data, "transition_duration", td.duration);
|
|
||||||
|
|
||||||
obs_data_release(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setNextTransition(const sceneSwitchInfo &sceneSwitch,
|
|
||||||
obs_source_t *currentSource, transitionData &td)
|
|
||||||
{
|
|
||||||
// Priority:
|
|
||||||
// 1. Transition tab
|
|
||||||
// 2. Individual switcher entry
|
|
||||||
// 3. Current transition settings
|
|
||||||
|
|
||||||
// Transition Tab
|
|
||||||
obs_weak_source_t *currentScene =
|
|
||||||
obs_source_get_weak_source(currentSource);
|
|
||||||
auto tinfo = getNextTransition(currentScene, sceneSwitch.scene);
|
|
||||||
obs_weak_source_release(currentScene);
|
|
||||||
|
|
||||||
OBSWeakSource nextTransition = tinfo.first;
|
|
||||||
int nextTransitionDuration = tinfo.second;
|
|
||||||
|
|
||||||
// Individual switcher entry
|
|
||||||
if (!nextTransition) {
|
|
||||||
nextTransition = sceneSwitch.transition;
|
|
||||||
}
|
|
||||||
if (!nextTransitionDuration) {
|
|
||||||
nextTransitionDuration = sceneSwitch.duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current transition settings
|
|
||||||
if (!nextTransition) {
|
|
||||||
auto ct = obs_frontend_get_current_transition();
|
|
||||||
nextTransition = obs_source_get_weak_source(ct);
|
|
||||||
obs_weak_source_release(nextTransition);
|
|
||||||
obs_source_release(ct);
|
|
||||||
}
|
|
||||||
if (!nextTransitionDuration) {
|
|
||||||
nextTransitionDuration = obs_frontend_get_transition_duration();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switcher->adjustActiveTransitionType) {
|
|
||||||
obs_frontend_set_transition_duration(nextTransitionDuration);
|
|
||||||
auto t = obs_weak_source_get_source(nextTransition);
|
|
||||||
obs_frontend_set_current_transition(t);
|
|
||||||
obs_source_release(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (switcher->transitionOverrideOverride) {
|
|
||||||
overwriteTransitionOverride({sceneSwitch.scene, nextTransition,
|
|
||||||
nextTransitionDuration},
|
|
||||||
td);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SwitcherData::saveSceneTransitions(obs_data_t *obj)
|
void SwitcherData::saveSceneTransitions(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
obs_data_array_t *sceneTransitionsArray = obs_data_array_create();
|
obs_data_array_t *sceneTransitionsArray = obs_data_array_create();
|
||||||
@@ -349,7 +254,7 @@ void SwitcherData::loadSceneTransitions(obs_data_t *obj)
|
|||||||
obs_data_get_int(obj, "defTransitionDelay");
|
obs_data_get_int(obj, "defTransitionDelay");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupTransitionsTab()
|
void AdvSceneSwitcher::SetupTransitionsTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->sceneTransitions) {
|
for (auto &s : switcher->sceneTransitions) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -397,11 +302,11 @@ void AdvSceneSwitcher::setupTransitionsTab()
|
|||||||
"AdvSceneSwitcher.transitionTab.defaultTransition.delay.help"));
|
"AdvSceneSwitcher.transitionTab.defaultTransition.delay.help"));
|
||||||
|
|
||||||
QWidget::connect(defTransitionDelay, SIGNAL(valueChanged(int)), this,
|
QWidget::connect(defTransitionDelay, SIGNAL(valueChanged(int)), this,
|
||||||
SLOT(defTransitionDelayValueChanged(int)));
|
SLOT(DefTransitionDelayValueChanged(int)));
|
||||||
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{defTransitionDelay}}", defTransitionDelay}};
|
{"{{defTransitionDelay}}", defTransitionDelay}};
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.transitionTab.defaultTransition.delay"),
|
"AdvSceneSwitcher.transitionTab.defaultTransition.delay"),
|
||||||
ui->defTransitionDelayLayout, widgetPlaceholders);
|
ui->defTransitionDelayLayout, widgetPlaceholders);
|
||||||
@@ -449,7 +354,7 @@ TransitionSwitchWidget::TransitionSwitchWidget(QWidget *parent,
|
|||||||
QWidget::connect(duration, SIGNAL(valueChanged(double)), this,
|
QWidget::connect(duration, SIGNAL(valueChanged(double)), this,
|
||||||
SLOT(DurationChanged(double)));
|
SLOT(DurationChanged(double)));
|
||||||
|
|
||||||
populateSceneSelection(scenes2);
|
PopulateSceneSelection(scenes2);
|
||||||
|
|
||||||
if (s) {
|
if (s) {
|
||||||
scenes2->setCurrentText(GetWeakSourceName(s->scene2).c_str());
|
scenes2->setCurrentText(GetWeakSourceName(s->scene2).c_str());
|
||||||
@@ -462,7 +367,7 @@ TransitionSwitchWidget::TransitionSwitchWidget(QWidget *parent,
|
|||||||
{"{{scenes2}}", scenes2},
|
{"{{scenes2}}", scenes2},
|
||||||
{"{{duration}}", duration},
|
{"{{duration}}", duration},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.transitionTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.transitionTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -518,7 +423,7 @@ DefTransitionSwitchWidget::DefTransitionSwitchWidget(QWidget *parent,
|
|||||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{scenes}}", scenes}, {"{{transitions}}", transitions}};
|
{"{{scenes}}", scenes}, {"{{transitions}}", transitions}};
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.transitionTab.defaultTransitionEntry"),
|
"AdvSceneSwitcher.transitionTab.defaultTransitionEntry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
@@ -592,3 +497,5 @@ void DefaultSceneTransition::setTransition()
|
|||||||
t = std::thread(setTransitionDelayed, transition, delay);
|
t = std::thread(setTransitionDelayed, transition, delay);
|
||||||
t.detach();
|
t.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
struct SceneTransition : SceneSwitcherEntry {
|
struct SceneTransition : SceneSwitcherEntry {
|
||||||
OBSWeakSource scene2 = nullptr;
|
OBSWeakSource scene2 = nullptr;
|
||||||
double duration = 0.3;
|
double duration = 0.3;
|
||||||
@@ -77,3 +79,5 @@ public:
|
|||||||
private:
|
private:
|
||||||
DefaultSceneTransition *switchData;
|
DefaultSceneTransition *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QToolTip>
|
#include <QToolTip>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
bool VideoSwitch::pause = false;
|
bool VideoSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
@@ -182,7 +185,7 @@ void SwitcherData::loadVideoSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(videoArray);
|
obs_data_array_release(videoArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupVideoTab()
|
void AdvSceneSwitcher::SetupVideoTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->videoSwitches) {
|
for (auto &s : switcher->videoSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -428,7 +431,7 @@ VideoSwitchWidget::VideoSwitchWidget(QWidget *parent, VideoSwitch *s)
|
|||||||
{"{{ignoreInactiveSource}}", ignoreInactiveSource},
|
{"{{ignoreInactiveSource}}", ignoreInactiveSource},
|
||||||
{"{{scenes}}", scenes},
|
{"{{scenes}}", scenes},
|
||||||
{"{{transitions}}", transitions}};
|
{"{{transitions}}", transitions}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.videoTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.videoTab.entry"),
|
||||||
switchLayout, widgetPlaceholders);
|
switchLayout, widgetPlaceholders);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
@@ -577,3 +580,5 @@ void VideoSwitchWidget::IgnoreInactiveChanged(int state)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->ignoreInactiveSource = state;
|
switchData->ignoreInactiveSource = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
#include "screenshot-helper.hpp"
|
#include "screenshot-helper.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto video_func = 9;
|
constexpr auto video_func = 9;
|
||||||
|
|
||||||
enum class videoSwitchType {
|
enum class videoSwitchType {
|
||||||
@@ -80,3 +82,5 @@ private:
|
|||||||
|
|
||||||
VideoSwitch *switchData;
|
VideoSwitch *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
#include "platform-funcs.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
namespace advss {
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
bool WindowSwitch::pause = false;
|
bool WindowSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QMetaObject::Connection addPulse;
|
||||||
@@ -177,8 +181,8 @@ void checkWindowTitleSwitchDirect(WindowSwitch &s,
|
|||||||
OBSWeakSource &transition)
|
OBSWeakSource &transition)
|
||||||
{
|
{
|
||||||
bool focus = (!s.focus || s.window == currentWindowTitle);
|
bool focus = (!s.focus || s.window == currentWindowTitle);
|
||||||
bool fullscreen = (!s.fullscreen || isFullscreen(s.window));
|
bool fullscreen = (!s.fullscreen || IsFullscreen(s.window));
|
||||||
bool max = (!s.maximized || isMaximized(s.window));
|
bool max = (!s.maximized || IsMaximized(s.window));
|
||||||
|
|
||||||
if (focus && fullscreen && max) {
|
if (focus && fullscreen && max) {
|
||||||
match = true;
|
match = true;
|
||||||
@@ -203,8 +207,8 @@ void checkWindowTitleSwitchRegex(WindowSwitch &s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool focus = (!s.focus || window == currentWindowTitle);
|
bool focus = (!s.focus || window == currentWindowTitle);
|
||||||
bool fullscreen = (!s.fullscreen || isFullscreen(window));
|
bool fullscreen = (!s.fullscreen || IsFullscreen(window));
|
||||||
bool max = (!s.maximized || isMaximized(window));
|
bool max = (!s.maximized || IsMaximized(window));
|
||||||
|
|
||||||
if (focus && fullscreen && max) {
|
if (focus && fullscreen && max) {
|
||||||
match = true;
|
match = true;
|
||||||
@@ -315,7 +319,7 @@ void SwitcherData::loadWindowTitleSwitches(obs_data_t *obj)
|
|||||||
obs_data_array_release(ignoreWindowsArray);
|
obs_data_array_release(ignoreWindowsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::setupTitleTab()
|
void AdvSceneSwitcher::SetupTitleTab()
|
||||||
{
|
{
|
||||||
for (auto &s : switcher->windowSwitches) {
|
for (auto &s : switcher->windowSwitches) {
|
||||||
QListWidgetItem *item;
|
QListWidgetItem *item;
|
||||||
@@ -336,7 +340,7 @@ void AdvSceneSwitcher::setupTitleTab()
|
|||||||
ui->windowHelp->setVisible(false);
|
ui->windowHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
populateWindowSelection(ui->ignoreWindowsWindows);
|
PopulateWindowSelection(ui->ignoreWindowsWindows);
|
||||||
|
|
||||||
for (auto &window : switcher->ignoreWindowsSwitches) {
|
for (auto &window : switcher->ignoreWindowsSwitches) {
|
||||||
QString text = QString::fromStdString(window);
|
QString text = QString::fromStdString(window);
|
||||||
@@ -394,7 +398,7 @@ WindowSwitchWidget::WindowSwitchWidget(QWidget *parent, WindowSwitch *s)
|
|||||||
QWidget::connect(focused, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(focused, SIGNAL(stateChanged(int)), this,
|
||||||
SLOT(FocusChanged(int)));
|
SLOT(FocusChanged(int)));
|
||||||
|
|
||||||
populateWindowSelection(windows);
|
PopulateWindowSelection(windows);
|
||||||
|
|
||||||
windows->setEditable(true);
|
windows->setEditable(true);
|
||||||
windows->setMaxVisibleItems(20);
|
windows->setMaxVisibleItems(20);
|
||||||
@@ -414,7 +418,7 @@ WindowSwitchWidget::WindowSwitchWidget(QWidget *parent, WindowSwitch *s)
|
|||||||
{"{{fullscreen}}", fullscreen},
|
{"{{fullscreen}}", fullscreen},
|
||||||
{"{{maximized}}", maximized},
|
{"{{maximized}}", maximized},
|
||||||
{"{{focused}}", focused}};
|
{"{{focused}}", focused}};
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.windowTitleTab.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.windowTitleTab.entry"),
|
||||||
mainLayout, widgetPlaceholders);
|
mainLayout, widgetPlaceholders);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -482,3 +486,5 @@ void WindowSwitchWidget::FocusChanged(int state)
|
|||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
switchData->focus = state;
|
switchData->focus = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto window_title_func = 5;
|
constexpr auto window_title_func = 5;
|
||||||
|
|
||||||
struct WindowSwitch : SceneSwitcherEntry {
|
struct WindowSwitch : SceneSwitcherEntry {
|
||||||
@@ -47,3 +49,5 @@ private:
|
|||||||
|
|
||||||
WindowSwitch *switchData;
|
WindowSwitch *switchData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "platform-funcs.hpp"
|
#include "platform-funcs.hpp"
|
||||||
#include "hotkey.hpp"
|
#include "hotkey.hpp"
|
||||||
|
#include "log-helper.hpp"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
@@ -25,14 +26,17 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#ifdef USE_PROCPS
|
#ifdef PROCPS_AVAILABLE
|
||||||
#include <proc/readproc.h>
|
#include <proc/readproc.h>
|
||||||
#else
|
#endif
|
||||||
|
#ifdef PROCPS2_AVAILABLE
|
||||||
#include <libproc2/pids.h>
|
#include <libproc2/pids.h>
|
||||||
#endif
|
#endif
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
static Display *xdisplay = 0;
|
static Display *xdisplay = 0;
|
||||||
|
|
||||||
static QLibrary *libXtstHandle = nullptr;
|
static QLibrary *libXtstHandle = nullptr;
|
||||||
@@ -51,6 +55,31 @@ std::chrono::high_resolution_clock::time_point lastMouseLeftClickTime{};
|
|||||||
std::chrono::high_resolution_clock::time_point lastMouseMiddleClickTime{};
|
std::chrono::high_resolution_clock::time_point lastMouseMiddleClickTime{};
|
||||||
std::chrono::high_resolution_clock::time_point lastMouseRightClickTime{};
|
std::chrono::high_resolution_clock::time_point lastMouseRightClickTime{};
|
||||||
|
|
||||||
|
static QLibrary *libprocps = nullptr;
|
||||||
|
#ifdef PROCPS_AVAILABLE
|
||||||
|
typedef PROCTAB *(*openproc_func)(int flags);
|
||||||
|
typedef void (*closeproc_func)(PROCTAB *PT);
|
||||||
|
typedef proc_t *(*readproc_func)(PROCTAB *__restrict const PT,
|
||||||
|
proc_t *__restrict p);
|
||||||
|
static openproc_func openproc_ = nullptr;
|
||||||
|
static closeproc_func closeproc_ = nullptr;
|
||||||
|
static readproc_func readproc_ = nullptr;
|
||||||
|
#endif
|
||||||
|
static bool libprocpsSupported = false;
|
||||||
|
|
||||||
|
static QLibrary *libproc2 = nullptr;
|
||||||
|
#ifdef PROCPS2_AVAILABLE
|
||||||
|
typedef int (*procps_pids_new_func)(struct pids_info **info,
|
||||||
|
enum pids_item *items, int numitems);
|
||||||
|
typedef struct pids_stack *(*procps_pids_get_func)(struct pids_info *info,
|
||||||
|
enum pids_fetch_type which);
|
||||||
|
typedef int (*procps_pids_unref_func)(struct pids_info **info);
|
||||||
|
static procps_pids_new_func procps_pids_new_ = nullptr;
|
||||||
|
static procps_pids_get_func procps_pids_get_ = nullptr;
|
||||||
|
static procps_pids_unref_func procps_pids_unref_ = nullptr;
|
||||||
|
#endif
|
||||||
|
static bool libprocps2Supported = false;
|
||||||
|
|
||||||
Display *disp()
|
Display *disp()
|
||||||
{
|
{
|
||||||
if (!xdisplay) {
|
if (!xdisplay) {
|
||||||
@@ -315,7 +344,7 @@ bool windowStatesAreSet(const std::string &windowTitle,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMaximized(const std::string &title)
|
bool IsMaximized(const std::string &title)
|
||||||
{
|
{
|
||||||
std::vector<QString> states;
|
std::vector<QString> states;
|
||||||
states.emplace_back("_NET_WM_STATE_MAXIMIZED_VERT");
|
states.emplace_back("_NET_WM_STATE_MAXIMIZED_VERT");
|
||||||
@@ -323,53 +352,70 @@ bool isMaximized(const std::string &title)
|
|||||||
return windowStatesAreSet(title, states);
|
return windowStatesAreSet(title, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFullscreen(const std::string &title)
|
bool IsFullscreen(const std::string &title)
|
||||||
{
|
{
|
||||||
std::vector<QString> states;
|
std::vector<QString> states;
|
||||||
states.emplace_back("_NET_WM_STATE_FULLSCREEN");
|
states.emplace_back("_NET_WM_STATE_FULLSCREEN");
|
||||||
return windowStatesAreSet(title, states);
|
return windowStatesAreSet(title, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_PROCPS
|
std::optional<std::string> GetTextInWindow(const std::string &)
|
||||||
void GetProcessList(QStringList &processes)
|
|
||||||
{
|
{
|
||||||
processes.clear();
|
// Not implemented
|
||||||
PROCTAB *proc = openproc(PROC_FILLSTAT);
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getProcessListProcps(QStringList &processes)
|
||||||
|
{
|
||||||
|
#ifdef PROCPS_AVAILABLE
|
||||||
|
PROCTAB *proc = openproc_(PROC_FILLSTAT);
|
||||||
proc_t proc_info;
|
proc_t proc_info;
|
||||||
memset(&proc_info, 0, sizeof(proc_info));
|
memset(&proc_info, 0, sizeof(proc_info));
|
||||||
while (readproc(proc, &proc_info) != NULL) {
|
while (readproc_(proc, &proc_info) != NULL) {
|
||||||
QString procName(proc_info.cmd);
|
QString procName(proc_info.cmd);
|
||||||
if (!procName.isEmpty() && !processes.contains(procName)) {
|
if (!procName.isEmpty() && !processes.contains(procName)) {
|
||||||
processes << procName;
|
processes << procName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closeproc(proc);
|
closeproc_(proc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
void GetProcessList(QStringList &processes)
|
static void getProcessListProcps2(QStringList &processes)
|
||||||
{
|
{
|
||||||
processes.clear();
|
#ifdef PROCPS2_AVAILABLE
|
||||||
struct pids_info *info = NULL;
|
struct pids_info *info = NULL;
|
||||||
struct pids_stack *stack;
|
struct pids_stack *stack;
|
||||||
enum pids_item Items[] = {
|
enum pids_item Items[] = {
|
||||||
PIDS_CMD,
|
PIDS_CMD,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (procps_pids_new(&info, Items, sizeof(Items) / sizeof(Items[0])) <
|
if (procps_pids_new_(&info, Items, sizeof(Items) / sizeof(Items[0])) <
|
||||||
0) {
|
0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
while ((stack = procps_pids_get_(info, PIDS_FETCH_TASKS_ONLY))) {
|
||||||
while ((stack = procps_pids_get(info, PIDS_FETCH_TASKS_ONLY))) {
|
|
||||||
auto cmd = PIDS_VAL(0, str, stack, info);
|
auto cmd = PIDS_VAL(0, str, stack, info);
|
||||||
QString procName(cmd);
|
QString procName(cmd);
|
||||||
if (!procName.isEmpty() && !processes.contains(procName)) {
|
if (!procName.isEmpty() && !processes.contains(procName)) {
|
||||||
processes << procName;
|
processes << procName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
procps_pids_unref(&info);
|
procps_pids_unref_(&info);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetProcessList(QStringList &processes)
|
||||||
|
{
|
||||||
|
processes.clear();
|
||||||
|
if (libprocpsSupported) {
|
||||||
|
getProcessListProcps(processes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (libprocps2Supported) {
|
||||||
|
getProcessListProcps2(processes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long getForegroundProcessPid()
|
long getForegroundProcessPid()
|
||||||
{
|
{
|
||||||
@@ -428,7 +474,7 @@ void GetForegroundProcessName(std::string &proc)
|
|||||||
proc = getProcNameFromPid(pid);
|
proc = getProcNameFromPid(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInFocus(const QString &executable)
|
bool IsInFocus(const QString &executable)
|
||||||
{
|
{
|
||||||
std::string current;
|
std::string current;
|
||||||
GetForegroundProcessName(current);
|
GetForegroundProcessName(current);
|
||||||
@@ -442,7 +488,7 @@ bool isInFocus(const QString &executable)
|
|||||||
return (equals || matches);
|
return (equals || matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
int secondsSinceLastInput()
|
int SecondsSinceLastInput()
|
||||||
{
|
{
|
||||||
if (!canGetIdleTime) {
|
if (!canGetIdleTime) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -625,6 +671,58 @@ void PressKeys(const std::vector<HotkeyType> keys, int duration)
|
|||||||
XFlush(display);
|
XFlush(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void initXtst()
|
||||||
|
{
|
||||||
|
libXtstHandle = new QLibrary("libXtst", nullptr);
|
||||||
|
pressFunc = (keyPressFunc)libXtstHandle->resolve("XTestFakeKeyEvent");
|
||||||
|
int _;
|
||||||
|
canSimulateKeyPresses = pressFunc &&
|
||||||
|
XQueryExtension(disp(), "XTEST", &_, &_, &_);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initXss()
|
||||||
|
{
|
||||||
|
libXssHandle = new QLibrary("libXss", nullptr);
|
||||||
|
allocSSFunc = (XScreenSaverAllocInfoFunc)libXssHandle->resolve(
|
||||||
|
"XScreenSaverAllocInfo");
|
||||||
|
querySSFunc = (XScreenSaverQueryInfoFunc)libXssHandle->resolve(
|
||||||
|
"XScreenSaverQueryInfo");
|
||||||
|
int _;
|
||||||
|
canGetIdleTime = allocSSFunc && querySSFunc &&
|
||||||
|
XQueryExtension(disp(), ScreenSaverName, &_, &_, &_);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initProcps()
|
||||||
|
{
|
||||||
|
#ifdef PROCPS_AVAILABLE
|
||||||
|
libprocps = new QLibrary("libprocps", nullptr);
|
||||||
|
openproc_ = (openproc_func)libprocps->resolve("openproc");
|
||||||
|
closeproc_ = (closeproc_func)libprocps->resolve("closeproc");
|
||||||
|
readproc_ = (readproc_func)libprocps->resolve("readproc");
|
||||||
|
if (openproc_ && closeproc_ && readproc_) {
|
||||||
|
libprocpsSupported = true;
|
||||||
|
blog(LOG_INFO, "libprocps symbols resolved successfully!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initProc2()
|
||||||
|
{
|
||||||
|
#ifdef PROCPS2_AVAILABLE
|
||||||
|
libproc2 = new QLibrary("libproc2", nullptr);
|
||||||
|
procps_pids_new_ =
|
||||||
|
(procps_pids_new_func)libproc2->resolve("procps_pids_new");
|
||||||
|
procps_pids_get_ =
|
||||||
|
(procps_pids_get_func)libproc2->resolve("procps_pids_get");
|
||||||
|
procps_pids_unref_ =
|
||||||
|
(procps_pids_unref_func)libproc2->resolve("procps_pids_unref");
|
||||||
|
if (procps_pids_new_ && procps_pids_get_ && procps_pids_unref_) {
|
||||||
|
libprocps2Supported = true;
|
||||||
|
blog(LOG_INFO, "libproc2 symbols resolved successfully!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void PlatformInit()
|
void PlatformInit()
|
||||||
{
|
{
|
||||||
auto display = disp();
|
auto display = disp();
|
||||||
@@ -632,30 +730,27 @@ void PlatformInit()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
libXtstHandle = new QLibrary("libXtst", nullptr);
|
initXtst();
|
||||||
pressFunc = (keyPressFunc)libXtstHandle->resolve("XTestFakeKeyEvent");
|
initXss();
|
||||||
int _;
|
initProcps();
|
||||||
canSimulateKeyPresses = pressFunc &&
|
initProc2();
|
||||||
XQueryExtension(disp(), "XTEST", &_, &_, &_);
|
}
|
||||||
|
|
||||||
libXssHandle = new QLibrary("libXss", nullptr);
|
static void cleanupHelper(QLibrary *lib)
|
||||||
allocSSFunc = (XScreenSaverAllocInfoFunc)libXssHandle->resolve(
|
{
|
||||||
"XScreenSaverAllocInfo");
|
if (lib) {
|
||||||
querySSFunc = (XScreenSaverQueryInfoFunc)libXssHandle->resolve(
|
delete lib;
|
||||||
"XScreenSaverQueryInfo");
|
lib = nullptr;
|
||||||
canGetIdleTime = allocSSFunc && querySSFunc &&
|
}
|
||||||
XQueryExtension(disp(), ScreenSaverName, &_, &_, &_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlatformCleanup()
|
void PlatformCleanup()
|
||||||
{
|
{
|
||||||
if (libXtstHandle) {
|
cleanupHelper(libXtstHandle);
|
||||||
delete libXtstHandle;
|
cleanupHelper(libXssHandle);
|
||||||
libXtstHandle = nullptr;
|
cleanupHelper(libprocps);
|
||||||
}
|
cleanupHelper(libproc2);
|
||||||
if (libXssHandle) {
|
|
||||||
delete libXssHandle;
|
|
||||||
libXssHandle = nullptr;
|
|
||||||
}
|
|
||||||
cleanupDisplay();
|
cleanupDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#include "macro-action-audio.hpp"
|
#include "macro-action-audio.hpp"
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "switcher-data.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
constexpr int64_t nsPerMs = 1000000;
|
constexpr int64_t nsPerMs = 1000000;
|
||||||
const std::string MacroActionAudio::id = "audio";
|
const std::string MacroActionAudio::id = "audio";
|
||||||
|
|
||||||
@@ -37,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) {
|
||||||
@@ -85,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,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;
|
||||||
}
|
}
|
||||||
@@ -114,7 +132,7 @@ void MacroActionAudio::FadeVolume()
|
|||||||
int nrSteps = 0;
|
int nrSteps = 0;
|
||||||
float volStep = 0.;
|
float volStep = 0.;
|
||||||
if (_fadeType == FadeType::DURATION) {
|
if (_fadeType == FadeType::DURATION) {
|
||||||
nrSteps = _duration.seconds * 1000 / fadeInterval.count();
|
nrSteps = _duration.Milliseconds() / fadeInterval.count();
|
||||||
volStep = volDiff / nrSteps;
|
volStep = volDiff / nrSteps;
|
||||||
} else {
|
} else {
|
||||||
volStep = _rate / 1000.0f;
|
volStep = _rate / 1000.0f;
|
||||||
@@ -212,7 +230,7 @@ void MacroActionAudio::LogAction() const
|
|||||||
vblog(LOG_INFO,
|
vblog(LOG_INFO,
|
||||||
"performed action \"%s\" for source \"%s\" with volume %d with fade %d %f",
|
"performed action \"%s\" for source \"%s\" with volume %d with fade %d %f",
|
||||||
it->second.c_str(), _audioSource.ToString(true).c_str(),
|
it->second.c_str(), _audioSource.ToString(true).c_str(),
|
||||||
_volume, _fade, _duration.seconds);
|
_volume.GetValue(), _fade, _duration.Seconds());
|
||||||
} else {
|
} else {
|
||||||
blog(LOG_WARNING, "ignored unknown audio action %d",
|
blog(LOG_WARNING, "ignored unknown audio action %d",
|
||||||
static_cast<int>(_action));
|
static_cast<int>(_action));
|
||||||
@@ -225,15 +243,16 @@ bool MacroActionAudio::Save(obs_data_t *obj) const
|
|||||||
_duration.Save(obj);
|
_duration.Save(obj);
|
||||||
_audioSource.Save(obj, "audioSource");
|
_audioSource.Save(obj, "audioSource");
|
||||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||||
obs_data_set_int(obj, "syncOffset", _syncOffset);
|
|
||||||
obs_data_set_int(obj, "monitor", _monitorType);
|
obs_data_set_int(obj, "monitor", _monitorType);
|
||||||
obs_data_set_double(obj, "balance", _balance);
|
_syncOffset.Save(obj, "syncOffset");
|
||||||
obs_data_set_int(obj, "volume", _volume);
|
_balance.Save(obj, "balance");
|
||||||
obs_data_set_double(obj, "rate", _rate);
|
_volume.Save(obj, "volume");
|
||||||
|
_rate.Save(obj, "rate");
|
||||||
obs_data_set_bool(obj, "fade", _fade);
|
obs_data_set_bool(obj, "fade", _fade);
|
||||||
obs_data_set_int(obj, "fadeType", static_cast<int>(_fadeType));
|
obs_data_set_int(obj, "fadeType", static_cast<int>(_fadeType));
|
||||||
obs_data_set_bool(obj, "wait", _wait);
|
obs_data_set_bool(obj, "wait", _wait);
|
||||||
obs_data_set_bool(obj, "abortActiveFade", _abortActiveFade);
|
obs_data_set_bool(obj, "abortActiveFade", _abortActiveFade);
|
||||||
|
obs_data_set_int(obj, "version", 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,12 +262,19 @@ bool MacroActionAudio::Load(obs_data_t *obj)
|
|||||||
_duration.Load(obj);
|
_duration.Load(obj);
|
||||||
_audioSource.Load(obj, "audioSource");
|
_audioSource.Load(obj, "audioSource");
|
||||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||||
_syncOffset = obs_data_get_int(obj, "syncOffset");
|
|
||||||
_monitorType = static_cast<obs_monitoring_type>(
|
_monitorType = static_cast<obs_monitoring_type>(
|
||||||
obs_data_get_int(obj, "monitor"));
|
obs_data_get_int(obj, "monitor"));
|
||||||
_balance = obs_data_get_double(obj, "balance");
|
if (!obs_data_has_user_value(obj, "version")) {
|
||||||
_volume = obs_data_get_int(obj, "volume");
|
_syncOffset = obs_data_get_int(obj, "syncOffset");
|
||||||
_rate = obs_data_get_double(obj, "rate");
|
_balance = obs_data_get_double(obj, "balance");
|
||||||
|
_volume = obs_data_get_int(obj, "volume");
|
||||||
|
_rate = obs_data_get_double(obj, "rate");
|
||||||
|
} else {
|
||||||
|
_syncOffset.Load(obj, "syncOffset");
|
||||||
|
_balance.Load(obj, "balance");
|
||||||
|
_volume.Load(obj, "volume");
|
||||||
|
_rate.Load(obj, "rate");
|
||||||
|
}
|
||||||
_fade = obs_data_get_bool(obj, "fade");
|
_fade = obs_data_get_bool(obj, "fade");
|
||||||
if (obs_data_has_user_value(obj, "wait")) {
|
if (obs_data_has_user_value(obj, "wait")) {
|
||||||
_wait = obs_data_get_bool(obj, "wait");
|
_wait = obs_data_get_bool(obj, "wait");
|
||||||
@@ -277,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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,16 +326,16 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
|||||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||||
_actions(new QComboBox),
|
_actions(new QComboBox),
|
||||||
_fadeTypes(new QComboBox),
|
_fadeTypes(new QComboBox),
|
||||||
_syncOffset(new QSpinBox),
|
_syncOffset(new VariableSpinBox),
|
||||||
_monitorTypes(new QComboBox),
|
_monitorTypes(new QComboBox),
|
||||||
_balance(new SliderSpinBox(
|
_balance(new SliderSpinBox(
|
||||||
0., 1., "",
|
0., 1., "",
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.action.audio.balance.description"))),
|
"AdvSceneSwitcher.action.audio.balance.description"))),
|
||||||
_volumePercent(new QSpinBox),
|
_volumePercent(new VariableSpinBox),
|
||||||
_fade(new QCheckBox),
|
_fade(new QCheckBox),
|
||||||
_duration(new DurationSelection(parent, false)),
|
_duration(new DurationSelection(parent, false)),
|
||||||
_rate(new QDoubleSpinBox),
|
_rate(new VariableDoubleSpinBox),
|
||||||
_wait(new QCheckBox(
|
_wait(new QCheckBox(
|
||||||
obs_module_text("AdvSceneSwitcher.action.audio.fade.wait"))),
|
obs_module_text("AdvSceneSwitcher.action.audio.fade.wait"))),
|
||||||
_abortActiveFade(new QCheckBox(
|
_abortActiveFade(new QCheckBox(
|
||||||
@@ -336,27 +360,35 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
|||||||
sources.sort();
|
sources.sort();
|
||||||
_sources->SetSourceNameList(sources);
|
_sources->SetSourceNameList(sources);
|
||||||
populateFadeTypeSelection(_fadeTypes);
|
populateFadeTypeSelection(_fadeTypes);
|
||||||
populateMonitorTypeSelection(_monitorTypes);
|
PopulateMonitorTypeSelection(_monitorTypes);
|
||||||
|
|
||||||
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,
|
||||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||||
SLOT(SourceChanged(const SourceSelection &)));
|
SLOT(SourceChanged(const SourceSelection &)));
|
||||||
QWidget::connect(_syncOffset, SIGNAL(valueChanged(int)), this,
|
QWidget::connect(
|
||||||
SLOT(SyncOffsetChanged(int)));
|
_syncOffset,
|
||||||
QWidget::connect(_balance, SIGNAL(DoubleValueChanged(double)), this,
|
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||||
SLOT(BalanceChanged(double)));
|
this, SLOT(SyncOffsetChanged(const NumberVariable<int> &)));
|
||||||
|
QWidget::connect(
|
||||||
|
_balance,
|
||||||
|
SIGNAL(DoubleValueChanged(const NumberVariable<double> &)),
|
||||||
|
this, SLOT(BalanceChanged(const NumberVariable<double> &)));
|
||||||
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(MonitorTypeChanged(int)));
|
SLOT(MonitorTypeChanged(int)));
|
||||||
QWidget::connect(_volumePercent, SIGNAL(valueChanged(int)), this,
|
QWidget::connect(
|
||||||
SLOT(VolumeChanged(int)));
|
_volumePercent,
|
||||||
|
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||||
|
this, SLOT(VolumeChanged(const NumberVariable<int> &)));
|
||||||
QWidget::connect(_fade, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(_fade, SIGNAL(stateChanged(int)), this,
|
||||||
SLOT(FadeChanged(int)));
|
SLOT(FadeChanged(int)));
|
||||||
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
|
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||||
SLOT(DurationChanged(double)));
|
this, SLOT(DurationChanged(const Duration &)));
|
||||||
QWidget::connect(_rate, SIGNAL(valueChanged(double)), this,
|
QWidget::connect(
|
||||||
SLOT(RateChanged(double)));
|
_rate,
|
||||||
|
SIGNAL(NumberVariableChanged(const NumberVariable<double> &)),
|
||||||
|
this, SLOT(RateChanged(const NumberVariable<double> &)));
|
||||||
QWidget::connect(_wait, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(_wait, SIGNAL(stateChanged(int)), this,
|
||||||
SLOT(WaitChanged(int)));
|
SLOT(WaitChanged(int)));
|
||||||
QWidget::connect(_abortActiveFade, SIGNAL(stateChanged(int)), this,
|
QWidget::connect(_abortActiveFade, SIGNAL(stateChanged(int)), this,
|
||||||
@@ -379,10 +411,10 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
|||||||
{"{{fadeTypes}}", _fadeTypes},
|
{"{{fadeTypes}}", _fadeTypes},
|
||||||
};
|
};
|
||||||
QHBoxLayout *entryLayout = new QHBoxLayout;
|
QHBoxLayout *entryLayout = new QHBoxLayout;
|
||||||
placeWidgets(obs_module_text("AdvSceneSwitcher.action.audio.entry"),
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.audio.entry"),
|
||||||
entryLayout, widgetPlaceholders);
|
entryLayout, widgetPlaceholders);
|
||||||
_fadeTypeLayout = new QHBoxLayout;
|
_fadeTypeLayout = new QHBoxLayout;
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text("AdvSceneSwitcher.action.audio.fade.duration"),
|
obs_module_text("AdvSceneSwitcher.action.audio.fade.duration"),
|
||||||
_fadeTypeLayout, widgetPlaceholders);
|
_fadeTypeLayout, widgetPlaceholders);
|
||||||
|
|
||||||
@@ -401,7 +433,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
|||||||
_loading = false;
|
_loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasVolumeControl(MacroActionAudio::Action action)
|
static bool hasVolumeControl(MacroActionAudio::Action action)
|
||||||
{
|
{
|
||||||
return action == MacroActionAudio::Action::SOURCE_VOLUME ||
|
return action == MacroActionAudio::Action::SOURCE_VOLUME ||
|
||||||
action == MacroActionAudio::Action::MASTER_VOLUME;
|
action == MacroActionAudio::Action::MASTER_VOLUME;
|
||||||
@@ -419,17 +451,11 @@ void MacroActionAudioEdit::SetWidgetVisibility()
|
|||||||
_balance->setVisible(_entryData->_action ==
|
_balance->setVisible(_entryData->_action ==
|
||||||
MacroActionAudio::Action::BALANCE);
|
MacroActionAudio::Action::BALANCE);
|
||||||
|
|
||||||
_fadeTypes->setDisabled(!_entryData->_fade);
|
|
||||||
_wait->setDisabled(!_entryData->_fade);
|
|
||||||
_abortActiveFade->setDisabled(!_entryData->_fade);
|
|
||||||
_duration->setDisabled(!_entryData->_fade);
|
|
||||||
_rate->setDisabled(!_entryData->_fade);
|
|
||||||
|
|
||||||
_fadeTypeLayout->removeWidget(_fade);
|
_fadeTypeLayout->removeWidget(_fade);
|
||||||
_fadeTypeLayout->removeWidget(_fadeTypes);
|
_fadeTypeLayout->removeWidget(_fadeTypes);
|
||||||
_fadeTypeLayout->removeWidget(_duration);
|
_fadeTypeLayout->removeWidget(_duration);
|
||||||
_fadeTypeLayout->removeWidget(_rate);
|
_fadeTypeLayout->removeWidget(_rate);
|
||||||
clearLayout(_fadeTypeLayout);
|
ClearLayout(_fadeTypeLayout);
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{fade}}", _fade},
|
{"{{fade}}", _fade},
|
||||||
{"{{duration}}", _duration},
|
{"{{duration}}", _duration},
|
||||||
@@ -437,12 +463,12 @@ void MacroActionAudioEdit::SetWidgetVisibility()
|
|||||||
{"{{fadeTypes}}", _fadeTypes},
|
{"{{fadeTypes}}", _fadeTypes},
|
||||||
};
|
};
|
||||||
if (_entryData->_fadeType == MacroActionAudio::FadeType::DURATION) {
|
if (_entryData->_fadeType == MacroActionAudio::FadeType::DURATION) {
|
||||||
placeWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.action.audio.fade.duration"),
|
"AdvSceneSwitcher.action.audio.fade.duration"),
|
||||||
_fadeTypeLayout, widgetPlaceholders);
|
_fadeTypeLayout, widgetPlaceholders);
|
||||||
} else {
|
} else {
|
||||||
placeWidgets(obs_module_text(
|
PlaceWidgets(obs_module_text(
|
||||||
"AdvSceneSwitcher.action.audio.fade.rate"),
|
"AdvSceneSwitcher.action.audio.fade.rate"),
|
||||||
_fadeTypeLayout, widgetPlaceholders);
|
_fadeTypeLayout, widgetPlaceholders);
|
||||||
}
|
}
|
||||||
@@ -452,10 +478,24 @@ void MacroActionAudioEdit::SetWidgetVisibility()
|
|||||||
_rate->setVisible(_entryData->_fadeType ==
|
_rate->setVisible(_entryData->_fadeType ==
|
||||||
MacroActionAudio::FadeType::RATE);
|
MacroActionAudio::FadeType::RATE);
|
||||||
|
|
||||||
setLayoutVisible(_fadeTypeLayout,
|
SetLayoutVisible(_fadeTypeLayout,
|
||||||
hasVolumeControl(_entryData->_action));
|
hasVolumeControl(_entryData->_action));
|
||||||
setLayoutVisible(_fadeOptionsLayout,
|
SetLayoutVisible(_fadeOptionsLayout,
|
||||||
hasVolumeControl(_entryData->_action));
|
hasVolumeControl(_entryData->_action));
|
||||||
|
_abortActiveFade->setVisible(hasVolumeControl(_entryData->_action) &&
|
||||||
|
_entryData->_fade);
|
||||||
|
_wait->setVisible(hasVolumeControl(_entryData->_action) &&
|
||||||
|
_entryData->_fade);
|
||||||
|
|
||||||
|
// TODO: Remove this in a future version:
|
||||||
|
if (_entryData->_action != MacroActionAudio::Action::MASTER_VOLUME &&
|
||||||
|
obs_get_version() >= MAKE_SEMANTIC_VERSION(29, 0, 0)) {
|
||||||
|
_actions->removeItem(_actions->findText(obs_module_text(
|
||||||
|
actionTypes.at(MacroActionAudio::Action::MASTER_VOLUME)
|
||||||
|
.c_str())));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGeometry();
|
||||||
adjustSize();
|
adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,13 +508,13 @@ void MacroActionAudioEdit::UpdateEntryData()
|
|||||||
_sources->SetSource(_entryData->_audioSource);
|
_sources->SetSource(_entryData->_audioSource);
|
||||||
_actions->setCurrentIndex(
|
_actions->setCurrentIndex(
|
||||||
_actions->findData(static_cast<int>(_entryData->_action)));
|
_actions->findData(static_cast<int>(_entryData->_action)));
|
||||||
_syncOffset->setValue(_entryData->_syncOffset);
|
_syncOffset->SetValue(_entryData->_syncOffset);
|
||||||
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
||||||
_balance->SetDoubleValue(_entryData->_balance);
|
_balance->SetDoubleValue(_entryData->_balance);
|
||||||
_volumePercent->setValue(_entryData->_volume);
|
_volumePercent->SetValue(_entryData->_volume);
|
||||||
_fade->setChecked(_entryData->_fade);
|
_fade->setChecked(_entryData->_fade);
|
||||||
_duration->SetDuration(_entryData->_duration);
|
_duration->SetDuration(_entryData->_duration);
|
||||||
_rate->setValue(_entryData->_rate);
|
_rate->SetValue(_entryData->_rate);
|
||||||
_wait->setChecked(_entryData->_wait);
|
_wait->setChecked(_entryData->_wait);
|
||||||
_abortActiveFade->setChecked(_entryData->_abortActiveFade);
|
_abortActiveFade->setChecked(_entryData->_abortActiveFade);
|
||||||
_fadeTypes->setCurrentIndex(static_cast<int>(_entryData->_fadeType));
|
_fadeTypes->setCurrentIndex(static_cast<int>(_entryData->_fadeType));
|
||||||
@@ -487,7 +527,7 @@ void MacroActionAudioEdit::SourceChanged(const SourceSelection &source)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_audioSource = source;
|
_entryData->_audioSource = source;
|
||||||
emit HeaderInfoChanged(
|
emit HeaderInfoChanged(
|
||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
@@ -499,19 +539,19 @@ void MacroActionAudioEdit::ActionChanged(int idx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_action = static_cast<MacroActionAudio::Action>(
|
_entryData->_action = static_cast<MacroActionAudio::Action>(
|
||||||
_actions->itemData(idx).toInt());
|
_actions->itemData(idx).toInt());
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionAudioEdit::SyncOffsetChanged(int value)
|
void MacroActionAudioEdit::SyncOffsetChanged(const NumberVariable<int> &value)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_syncOffset = value;
|
_entryData->_syncOffset = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,27 +561,27 @@ void MacroActionAudioEdit::MonitorTypeChanged(int value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_monitorType = static_cast<obs_monitoring_type>(value);
|
_entryData->_monitorType = static_cast<obs_monitoring_type>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionAudioEdit::BalanceChanged(double value)
|
void MacroActionAudioEdit::BalanceChanged(const NumberVariable<double> &value)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_balance = value;
|
_entryData->_balance = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionAudioEdit::VolumeChanged(int value)
|
void MacroActionAudioEdit::VolumeChanged(const NumberVariable<int> &value)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_volume = value;
|
_entryData->_volume = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,28 +591,28 @@ void MacroActionAudioEdit::FadeChanged(int value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_fade = value;
|
_entryData->_fade = value;
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionAudioEdit::DurationChanged(double seconds)
|
void MacroActionAudioEdit::DurationChanged(const Duration &dur)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_duration.seconds = seconds;
|
_entryData->_duration = dur;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionAudioEdit::RateChanged(double value)
|
void MacroActionAudioEdit::RateChanged(const NumberVariable<double> &value)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
if (_loading || !_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_rate = value;
|
_entryData->_rate = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,7 +622,7 @@ void MacroActionAudioEdit::WaitChanged(int value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_wait = value;
|
_entryData->_wait = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +632,7 @@ void MacroActionAudioEdit::AbortActiveFadeChanged(int value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_abortActiveFade = value;
|
_entryData->_abortActiveFade = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +642,9 @@ void MacroActionAudioEdit::FadeTypeChanged(int value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
auto lock = LockContext();
|
||||||
_entryData->_fadeType = static_cast<MacroActionAudio::FadeType>(value);
|
_entryData->_fadeType = static_cast<MacroActionAudio::FadeType>(value);
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
class MacroActionAudio : public MacroAction {
|
class MacroActionAudio : public MacroAction {
|
||||||
public:
|
public:
|
||||||
MacroActionAudio(Macro *m) : MacroAction(m) {}
|
MacroActionAudio(Macro *m) : MacroAction(m) {}
|
||||||
@@ -42,13 +44,13 @@ public:
|
|||||||
|
|
||||||
Action _action = Action::MUTE;
|
Action _action = Action::MUTE;
|
||||||
FadeType _fadeType = FadeType::DURATION;
|
FadeType _fadeType = FadeType::DURATION;
|
||||||
int64_t _syncOffset = 0;
|
NumberVariable<int> _syncOffset = 0;
|
||||||
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
||||||
double _balance = 0.5;
|
NumberVariable<double> _balance = 0.5;
|
||||||
int _volume = 0;
|
NumberVariable<int> _volume = 0;
|
||||||
bool _fade = false;
|
bool _fade = false;
|
||||||
Duration _duration;
|
Duration _duration;
|
||||||
double _rate = 100.;
|
NumberVariable<double> _rate = 100.;
|
||||||
bool _wait = false;
|
bool _wait = false;
|
||||||
bool _abortActiveFade = false;
|
bool _abortActiveFade = false;
|
||||||
|
|
||||||
@@ -84,13 +86,13 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void SourceChanged(const SourceSelection &);
|
void SourceChanged(const SourceSelection &);
|
||||||
void ActionChanged(int value);
|
void ActionChanged(int value);
|
||||||
void SyncOffsetChanged(int value);
|
void SyncOffsetChanged(const NumberVariable<int> &value);
|
||||||
void MonitorTypeChanged(int value);
|
void MonitorTypeChanged(int value);
|
||||||
void BalanceChanged(double value);
|
void BalanceChanged(const NumberVariable<double> &value);
|
||||||
void VolumeChanged(int value);
|
void VolumeChanged(const NumberVariable<int> &value);
|
||||||
void FadeChanged(int value);
|
void FadeChanged(int value);
|
||||||
void DurationChanged(double seconds);
|
void DurationChanged(const Duration &seconds);
|
||||||
void RateChanged(double value);
|
void RateChanged(const NumberVariable<double> &value);
|
||||||
void WaitChanged(int value);
|
void WaitChanged(int value);
|
||||||
void AbortActiveFadeChanged(int value);
|
void AbortActiveFadeChanged(int value);
|
||||||
void FadeTypeChanged(int value);
|
void FadeTypeChanged(int value);
|
||||||
@@ -101,13 +103,13 @@ protected:
|
|||||||
SourceSelectionWidget *_sources;
|
SourceSelectionWidget *_sources;
|
||||||
QComboBox *_actions;
|
QComboBox *_actions;
|
||||||
QComboBox *_fadeTypes;
|
QComboBox *_fadeTypes;
|
||||||
QSpinBox *_syncOffset;
|
VariableSpinBox *_syncOffset;
|
||||||
QComboBox *_monitorTypes;
|
QComboBox *_monitorTypes;
|
||||||
SliderSpinBox *_balance;
|
SliderSpinBox *_balance;
|
||||||
QSpinBox *_volumePercent;
|
VariableSpinBox *_volumePercent;
|
||||||
QCheckBox *_fade;
|
QCheckBox *_fade;
|
||||||
DurationSelection *_duration;
|
DurationSelection *_duration;
|
||||||
QDoubleSpinBox *_rate;
|
VariableDoubleSpinBox *_rate;
|
||||||
QCheckBox *_wait;
|
QCheckBox *_wait;
|
||||||
QCheckBox *_abortActiveFade;
|
QCheckBox *_abortActiveFade;
|
||||||
QHBoxLayout *_fadeTypeLayout;
|
QHBoxLayout *_fadeTypeLayout;
|
||||||
@@ -119,3 +121,5 @@ private:
|
|||||||
|
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
|
|||||||
257
src/macro-core/macro-action-clipboard.cpp
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
#include "macro-action-clipboard.hpp"
|
||||||
|
#include "curl-helper.hpp"
|
||||||
|
#include "switcher-data.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QMimeData>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
const std::string MacroActionClipboard::id = "clipboard";
|
||||||
|
|
||||||
|
bool MacroActionClipboard::_registered = MacroActionFactory::Register(
|
||||||
|
MacroActionClipboard::id,
|
||||||
|
{MacroActionClipboard::Create, MacroActionClipboardEdit::Create,
|
||||||
|
"AdvSceneSwitcher.action.clipboard"});
|
||||||
|
|
||||||
|
const static std::map<MacroActionClipboard::Action, std::string> actionTypes = {
|
||||||
|
{MacroActionClipboard::Action::COPY_TEXT,
|
||||||
|
"AdvSceneSwitcher.action.clipboard.type.copy.text"},
|
||||||
|
{MacroActionClipboard::Action::COPY_IMAGE,
|
||||||
|
"AdvSceneSwitcher.action.clipboard.type.copy.image"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static size_t writeCallback(void *ptr, size_t size, size_t nmemb,
|
||||||
|
QByteArray *buffer)
|
||||||
|
{
|
||||||
|
buffer->append((char *)ptr, nmemb);
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::optional<QImage> getImageFromUrl(const char *url)
|
||||||
|
{
|
||||||
|
QByteArray response;
|
||||||
|
|
||||||
|
switcher->curl.SetOpt(CURLOPT_URL, url);
|
||||||
|
switcher->curl.SetOpt(CURLOPT_HTTPGET, 1L);
|
||||||
|
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, 30000);
|
||||||
|
switcher->curl.SetOpt(CURLOPT_WRITEFUNCTION, writeCallback);
|
||||||
|
switcher->curl.SetOpt(CURLOPT_WRITEDATA, &response);
|
||||||
|
auto code = switcher->curl.Perform();
|
||||||
|
|
||||||
|
if (code != CURLE_OK) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"Retrieving image failed in %s with error: %s", __func__,
|
||||||
|
switcher->curl.GetError(code));
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return QImage::fromData(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setMimeTypeParams(ClipboardQueueParams *params,
|
||||||
|
QClipboard *clipboard)
|
||||||
|
{
|
||||||
|
auto mimeData = clipboard->mimeData();
|
||||||
|
if (!mimeData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto mimeTypeList = mimeData->formats();
|
||||||
|
if (mimeTypeList.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
params->mimeTypePrimary = mimeTypeList.first().toStdString();
|
||||||
|
params->mimeTypeAll = mimeTypeList.join(" ").toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyText(void *param)
|
||||||
|
{
|
||||||
|
auto params = static_cast<ClipboardTextQueueParams *>(param);
|
||||||
|
QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
|
clipboard->setText(params->text.c_str());
|
||||||
|
|
||||||
|
setMimeTypeParams(params, clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copyImageFromUrl(void *param)
|
||||||
|
{
|
||||||
|
auto params = static_cast<ClipboardImageQueueParams *>(param);
|
||||||
|
auto url = params->url.c_str();
|
||||||
|
auto image = getImageFromUrl(url);
|
||||||
|
|
||||||
|
if (!image || (*image).isNull()) {
|
||||||
|
blog(LOG_WARNING, "Failed to convert %s URL to image!", url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QClipboard *clipboard = QApplication::clipboard();
|
||||||
|
clipboard->setImage(*image);
|
||||||
|
|
||||||
|
setMimeTypeParams(params, clipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionClipboard::PerformAction()
|
||||||
|
{
|
||||||
|
switch (_action) {
|
||||||
|
case Action::COPY_TEXT: {
|
||||||
|
ClipboardTextQueueParams params{"", "", _text};
|
||||||
|
obs_queue_task(OBS_TASK_UI, copyText, ¶ms, true);
|
||||||
|
SetTempVarValues(params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Action::COPY_IMAGE: {
|
||||||
|
ClipboardImageQueueParams params{"", "", _url};
|
||||||
|
obs_queue_task(OBS_TASK_UI, copyImageFromUrl, ¶ms, true);
|
||||||
|
SetTempVarValues(params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionClipboard::SetupTempVars()
|
||||||
|
{
|
||||||
|
MacroAction::SetupTempVars();
|
||||||
|
|
||||||
|
AddTempvar(
|
||||||
|
"mimeType.primary",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.clipboard.mimeType.primary"),
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.clipboard.mimeType.primary.description"));
|
||||||
|
AddTempvar(
|
||||||
|
"mimeType.all",
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.clipboard.mimeType.all"),
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.tempVar.clipboard.mimeType.all.description"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionClipboard::SetTempVarValues(const ClipboardQueueParams ¶ms)
|
||||||
|
{
|
||||||
|
SetTempVarValue("mimeType.primary", params.mimeTypePrimary);
|
||||||
|
SetTempVarValue("mimeType.all", params.mimeTypeAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionClipboard::Save(obs_data_t *obj) const
|
||||||
|
{
|
||||||
|
MacroAction::Save(obj);
|
||||||
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||||
|
_text.Save(obj, "text");
|
||||||
|
_url.Save(obj, "url");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionClipboard::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
MacroAction::Load(obj);
|
||||||
|
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||||
|
_text.Load(obj, "text");
|
||||||
|
_url.Load(obj, "url");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void populateActionSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
for (const auto &[action, name] : actionTypes) {
|
||||||
|
list->addItem(obs_module_text(name.c_str()),
|
||||||
|
static_cast<int>(action));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroActionClipboardEdit::MacroActionClipboardEdit(
|
||||||
|
QWidget *parent, std::shared_ptr<MacroActionClipboard> entryData)
|
||||||
|
: QWidget(parent),
|
||||||
|
_actions(new FilterComboBox(this)),
|
||||||
|
_text(new VariableLineEdit(this)),
|
||||||
|
_url(new VariableLineEdit(this))
|
||||||
|
{
|
||||||
|
populateActionSelection(_actions);
|
||||||
|
_url->setToolTip(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.clipboard.copy.image.url.tooltip"));
|
||||||
|
|
||||||
|
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(ActionChanged(int)));
|
||||||
|
QWidget::connect(_text, SIGNAL(editingFinished()), this,
|
||||||
|
SLOT(TextChanged()));
|
||||||
|
QWidget::connect(_url, SIGNAL(editingFinished()), this,
|
||||||
|
SLOT(UrlChanged()));
|
||||||
|
|
||||||
|
auto mainLayout = new QHBoxLayout();
|
||||||
|
mainLayout->addWidget(_actions);
|
||||||
|
mainLayout->addWidget(_text);
|
||||||
|
mainLayout->addWidget(_url);
|
||||||
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
_entryData = entryData;
|
||||||
|
UpdateEntryData();
|
||||||
|
_loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionClipboardEdit::ActionChanged(int index)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_action = static_cast<MacroActionClipboard::Action>(
|
||||||
|
_actions->itemData(index).toInt());
|
||||||
|
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionClipboardEdit::TextChanged()
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_text = _text->text().toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionClipboardEdit::UrlChanged()
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_url = _url->text().toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionClipboardEdit::SetWidgetVisibility()
|
||||||
|
{
|
||||||
|
_text->setVisible(_entryData->_action ==
|
||||||
|
MacroActionClipboard::Action::COPY_TEXT);
|
||||||
|
_url->setVisible(_entryData->_action ==
|
||||||
|
MacroActionClipboard::Action::COPY_IMAGE);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionClipboardEdit::UpdateEntryData()
|
||||||
|
{
|
||||||
|
if (!_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_actions->setCurrentIndex(
|
||||||
|
_actions->findData(static_cast<int>(_entryData->_action)));
|
||||||
|
_text->setText(_entryData->_text);
|
||||||
|
_url->setText(_entryData->_url);
|
||||||
|
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||