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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
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
|
||||||