mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-06 16:46:11 -05:00
Compare commits
200 Commits
1.25.0-bet
...
1.27.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b561a20dde | ||
|
|
835722af34 | ||
|
|
93efc7cab3 | ||
|
|
d69364ec19 | ||
|
|
d75066df5f | ||
|
|
863c84026e | ||
|
|
a523081d77 | ||
|
|
66534519d6 | ||
|
|
b3b2114c45 | ||
|
|
510f83246e | ||
|
|
c969b21f93 | ||
|
|
6ec40ef8e9 | ||
|
|
27859e83b3 | ||
|
|
263565700a | ||
|
|
5bb10a4aef | ||
|
|
ee72bb192c | ||
|
|
1a1028cbaa | ||
|
|
2f4f8bcc74 | ||
|
|
4113615cd6 | ||
|
|
9522d7c0b4 | ||
|
|
cc3ea79836 | ||
|
|
f72e802d00 | ||
|
|
36201cbfb4 | ||
|
|
685e28d161 | ||
|
|
82d23dcf0e | ||
|
|
ad322d54f0 | ||
|
|
8bac6fe829 | ||
|
|
ac7531decb | ||
|
|
7af4969ec6 | ||
|
|
a088325968 | ||
|
|
57bc58be8e | ||
|
|
f9730b1bc2 | ||
|
|
d4025214e5 | ||
|
|
c431e6c31d | ||
|
|
9941cfe9b5 | ||
|
|
15998012e5 | ||
|
|
bcb043f997 | ||
|
|
74116382b1 | ||
|
|
24f33fb0d2 | ||
|
|
d80df57ef8 | ||
|
|
240c47975c | ||
|
|
bedb3b8dc6 | ||
|
|
8032dde045 | ||
|
|
bfc51b2df5 | ||
|
|
2160da59f3 | ||
|
|
d3164e3ed6 | ||
|
|
17c72b772d | ||
|
|
3ff9a1f270 | ||
|
|
7d120d8b6a | ||
|
|
53cfe4b030 | ||
|
|
4dcd748a1f | ||
|
|
223ce0d0a0 | ||
|
|
5bd3341681 | ||
|
|
bb527d6910 | ||
|
|
dfedbcf31a | ||
|
|
1bbfd16b3f | ||
|
|
7f5737d03f | ||
|
|
7702541d81 | ||
|
|
3bc15e585c | ||
|
|
d77101b6aa | ||
|
|
c1e23f9c7a | ||
|
|
70415cd8f4 | ||
|
|
f50cd76493 | ||
|
|
e4af698881 | ||
|
|
33120a359c | ||
|
|
091a364097 | ||
|
|
e3ff6f34fc | ||
|
|
ed75a221fe | ||
|
|
7b48cb2b8d | ||
|
|
9d4c8ab475 | ||
|
|
3d61ea7d25 | ||
|
|
99c8a46296 | ||
|
|
7e1d20031c | ||
|
|
0e4b000fb1 | ||
|
|
fc2451ae08 | ||
|
|
be44577967 | ||
|
|
3480ff238e | ||
|
|
ee68427036 | ||
|
|
37c32dd1ed | ||
|
|
c05a92d417 | ||
|
|
d72a0c0d38 | ||
|
|
235b31fccc | ||
|
|
286f781f4d | ||
|
|
b7516cac5b | ||
|
|
45967a090f | ||
|
|
687fb4623e | ||
|
|
4157ae4ed2 | ||
|
|
5e1469b0d8 | ||
|
|
b3bde6c59f | ||
|
|
032f5e2fe9 | ||
|
|
91c053dfd8 | ||
|
|
1f1ef4ca03 | ||
|
|
7cc44b4470 | ||
|
|
54356d9410 | ||
|
|
defbdf8b7a | ||
|
|
a01af6cfc3 | ||
|
|
4d9c7f1054 | ||
|
|
ced36e2b5b | ||
|
|
d2749f29b0 | ||
|
|
b78c8bc1de | ||
|
|
cc4a3560d8 | ||
|
|
3ab2ea9e66 | ||
|
|
69b82ee2a3 | ||
|
|
f14e6bf252 | ||
|
|
e51ae79b4c | ||
|
|
8f55856fd5 | ||
|
|
a360d53419 | ||
|
|
d28164d02f | ||
|
|
f723212394 | ||
|
|
a0cb08d18f | ||
|
|
d18044b764 | ||
|
|
406b5d61f5 | ||
|
|
9a4eef4a83 | ||
|
|
efaf9a2ef3 | ||
|
|
edb2952fd6 | ||
|
|
088828a351 | ||
|
|
e359b7fa00 | ||
|
|
44fc5177d6 | ||
|
|
604a27141f | ||
|
|
fd65a84d7d | ||
|
|
966b389807 | ||
|
|
a6bcce5a63 | ||
|
|
530fbdd282 | ||
|
|
54f1051456 | ||
|
|
d136bf5561 | ||
|
|
5cba948e02 | ||
|
|
ab922f6735 | ||
|
|
d71c87535f | ||
|
|
ce501bd972 | ||
|
|
ec5944f53c | ||
|
|
5e64e0bbaa | ||
|
|
e16f1d732d | ||
|
|
cdacfc946c | ||
|
|
26e854f0a3 | ||
|
|
2bc89364b2 | ||
|
|
e080d2de9b | ||
|
|
ca1262aeb7 | ||
|
|
cbc95e2095 | ||
|
|
9c5051cbf8 | ||
|
|
e6ca3390a2 | ||
|
|
e74b531905 | ||
|
|
01437183ac | ||
|
|
e5ab2ceca3 | ||
|
|
e19f4ddf7c | ||
|
|
4e3a062084 | ||
|
|
96db0ad507 | ||
|
|
6b4bcc074a | ||
|
|
14dd390680 | ||
|
|
3fe8ea8961 | ||
|
|
3ee913ea98 | ||
|
|
d18277653c | ||
|
|
8c478cc330 | ||
|
|
003ffc161b | ||
|
|
74dc0c871b | ||
|
|
c8545dea4d | ||
|
|
e1b8edd444 | ||
|
|
f3996855c3 | ||
|
|
ea17e8ea08 | ||
|
|
00fc313609 | ||
|
|
c72f9abc2b | ||
|
|
6df818503e | ||
|
|
b17a6cc109 | ||
|
|
82d1aed472 | ||
|
|
eb6fc6c140 | ||
|
|
2710406f5f | ||
|
|
a634499423 | ||
|
|
71b3fbaa19 | ||
|
|
c656bb4571 | ||
|
|
6c4e4b8cd8 | ||
|
|
7b1a256f8a | ||
|
|
66f9eaf8c2 | ||
|
|
7fa0ba3355 | ||
|
|
eec9244e4c | ||
|
|
e265e4828e | ||
|
|
ad6e720912 | ||
|
|
70dad8ebb4 | ||
|
|
497b3b3e04 | ||
|
|
891811aa47 | ||
|
|
be9ddaa4c9 | ||
|
|
03494c2915 | ||
|
|
bcf7c247bf | ||
|
|
132d89b350 | ||
|
|
daf16357c9 | ||
|
|
8080abc93c | ||
|
|
902715bd3e | ||
|
|
8271a6e8db | ||
|
|
6c121a093b | ||
|
|
ab0cce9eaa | ||
|
|
9acbead87b | ||
|
|
03e71e9183 | ||
|
|
f8dadd38b4 | ||
|
|
2928775f5b | ||
|
|
673ac8078b | ||
|
|
234ae27205 | ||
|
|
a740a29798 | ||
|
|
341a58b8e4 | ||
|
|
ba9a16e718 | ||
|
|
2b2bab8fbc | ||
|
|
f50f31ec4c | ||
|
|
3a1c353ea3 |
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/build-aux/*.zsh eol=lf
|
||||||
|
/build-aux/.functions/* eol=lf
|
||||||
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Logs**
|
|
||||||
Please provide a log of your issue with verbose logging enabled (See General tab of the plugin).
|
|
||||||
In case of a crash, please also include the corresponding crash log.
|
|
||||||
See [here](https://obsproject.com/forum/threads/please-post-a-log-with-your-issue-heres-how.23074/) for a description where to find the log files and how to share them.
|
|
||||||
Please share the currently used plugin settings by exporting them them to a file (See General tab of the plugin).
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
**Version information**
|
|
||||||
- OS: [e.g. Windows 10]
|
|
||||||
- OBS Version [e.g. 27.1.3]
|
|
||||||
- Plugin Version [e.g. 1.17.1]
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
||||||
111
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
111
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# Based on the OBS issue templates
|
||||||
|
# https://github.com/obsproject/.github/tree/master/.github/ISSUE_TEMPLATE
|
||||||
|
|
||||||
|
name: Bug Report
|
||||||
|
description: Report a bug or crash
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: md_welcome
|
||||||
|
attributes:
|
||||||
|
value: This form is for reporting bugs for Advanced Scene Switcher!
|
||||||
|
- type: dropdown
|
||||||
|
id: os_info
|
||||||
|
attributes:
|
||||||
|
label: Operating System Info
|
||||||
|
description: What Operating System are you running?
|
||||||
|
options:
|
||||||
|
- Windows 11
|
||||||
|
- Windows 10
|
||||||
|
- macOS 14
|
||||||
|
- macOS 13
|
||||||
|
- macOS 12
|
||||||
|
- macOS 11
|
||||||
|
- Ubuntu 23.10
|
||||||
|
- Ubuntu 22.04
|
||||||
|
- Other
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: os_info_other
|
||||||
|
attributes:
|
||||||
|
label: Other OS
|
||||||
|
description: "If \"Other\" was selected above, what OS are you using?"
|
||||||
|
placeholder: "e.g., Arch Linux, FreeBSD"
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: obs_version
|
||||||
|
attributes:
|
||||||
|
label: OBS Studio Version
|
||||||
|
description: What version of OBS Studio are you using?
|
||||||
|
placeholder: 30.2.2
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: advss_version
|
||||||
|
attributes:
|
||||||
|
label: Advanced Scene Switcher Version
|
||||||
|
description: What version of the Advanced Scene Switcher are you using?
|
||||||
|
placeholder: 1.27.2
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: settings
|
||||||
|
attributes:
|
||||||
|
label: Plugin settings
|
||||||
|
description: |
|
||||||
|
Please provide the plugin settings used.
|
||||||
|
Either only [export the macros](https://github.com/WarmUpTill/SceneSwitcher/wiki/Exporting-and-importing-individual-macros) relevant to this issue or [export all settings](https://github.com/WarmUpTill/SceneSwitcher/wiki/Saving-and-loading-settings#how-to-create-and-import-a-backup-of-your-settings) on the General tab of the plugin.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: obs_log_url
|
||||||
|
attributes:
|
||||||
|
label: OBS Studio Log URL
|
||||||
|
description: Please provide the obsproject.com URL (from Help menu > Log Files > Upload Current/Previous Log File) to the OBS log file where this issue occurred.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: input
|
||||||
|
id: obs_crash_log_url
|
||||||
|
attributes:
|
||||||
|
label: OBS Studio Crash Log URL
|
||||||
|
description: If this is a crash report, please provide the obsproject.com URL to the OBS crash log file where this issue occurred.
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: expected_behavior
|
||||||
|
attributes:
|
||||||
|
label: Expected Behavior
|
||||||
|
description: "What did you expect to happen?"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: current_behavior
|
||||||
|
attributes:
|
||||||
|
label: Current Behavior
|
||||||
|
description: "What actually happened?"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: steps_to_reproduce
|
||||||
|
attributes:
|
||||||
|
label: Steps to Reproduce
|
||||||
|
description: "How do you trigger this bug? Please walk us through it step by step."
|
||||||
|
placeholder: |
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
...
|
||||||
|
value: |
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: additional_notes
|
||||||
|
attributes:
|
||||||
|
label: Anything else we should know?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,8 @@
|
|||||||
blank_issues_enabled: true
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Help/Support
|
- name: 📚 Wiki
|
||||||
url: https://github.com/WarmUpTill/SceneSwitcher/wiki
|
url: https://github.com/WarmUpTill/SceneSwitcher/wiki
|
||||||
about: For general questions about how to use and configure the plugin please have a look at the wiki (https://github.com/WarmUpTill/SceneSwitcher/wiki) or ask questions in the OBS forum (https://obsproject.com/forum/threads/advanced-scene-switcher.48264/)
|
about: For explanations on how the plugin works or to see example guides, check out the wiki.
|
||||||
|
- name: 💬 OBS Forum Thread
|
||||||
|
url: https://obsproject.com/forum/threads/advanced-scene-switcher.48264
|
||||||
|
about: To discuss the plugin or get assistance, feel free to use the OBS forum thread or the GitHub discussions page.
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
||||||
|
|
||||||
**Describe the solution you'd like**
|
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
||||||
37
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
37
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Based on the OBS issue templates
|
||||||
|
# https://github.com/obsproject/.github/tree/master/.github/ISSUE_TEMPLATE
|
||||||
|
|
||||||
|
name: Feature request
|
||||||
|
description: Suggest an idea for this projectReport a bug or crash
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
id: md_welcome
|
||||||
|
attributes:
|
||||||
|
value: This form is for requesting new features for Advanced Scene Switcher!
|
||||||
|
- type: textarea
|
||||||
|
id: background
|
||||||
|
attributes:
|
||||||
|
label: Background
|
||||||
|
description: "Is your feature request related to a problem? Please describe."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: solution
|
||||||
|
attributes:
|
||||||
|
label: Solution
|
||||||
|
description: "Describe the solution you'd like."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: Alternatives
|
||||||
|
description: "Describe alternatives you've considered."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
id: additional_notes
|
||||||
|
attributes:
|
||||||
|
label: Anything else we should know?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
3
.github/scripts/.Aptfile
vendored
3
.github/scripts/.Aptfile
vendored
@@ -9,4 +9,5 @@ package 'libxtst-dev'
|
|||||||
package 'libxss-dev'
|
package 'libxss-dev'
|
||||||
package 'libopencv-dev'
|
package 'libopencv-dev'
|
||||||
package 'libtesseract-dev'
|
package 'libtesseract-dev'
|
||||||
package 'libprocps-dev'
|
package 'libprocps-dev'
|
||||||
|
package 'libusb-1.0-0-dev'
|
||||||
2
.github/scripts/.Brewfile
vendored
2
.github/scripts/.Brewfile
vendored
@@ -1,6 +1,6 @@
|
|||||||
brew "ccache"
|
brew "ccache"
|
||||||
brew "coreutils"
|
brew "coreutils"
|
||||||
brew "cmake"
|
brew "cmake"
|
||||||
brew "git"
|
|
||||||
brew "jq"
|
brew "jq"
|
||||||
brew "xcbeautify"
|
brew "xcbeautify"
|
||||||
|
brew "automake"
|
||||||
|
|||||||
3
.github/scripts/.Wingetfile
vendored
3
.github/scripts/.Wingetfile
vendored
@@ -1,3 +1,4 @@
|
|||||||
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'
|
package 'OpenSSL', path: 'OpenSSL', bin: 'openssl'
|
||||||
|
package 'Microsoft.VisualStudio.Locator', path: 'vswhere', bin: 'vswhere'
|
||||||
58
.github/scripts/.build-deps.zsh
vendored
58
.github/scripts/.build-deps.zsh
vendored
@@ -380,7 +380,7 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
pushd ${advss_dep_path}
|
pushd ${advss_dep_path}
|
||||||
log_info "Prepare openssl ..."
|
log_info "Prepare openssl ..."
|
||||||
rm -rf openssl
|
rm -rf openssl
|
||||||
git clone git://git.openssl.org/openssl.git --branch openssl-3.1.2 --depth 1
|
git clone https://github.com/openssl/openssl.git --branch openssl-3.1.2 --depth 1
|
||||||
mv openssl openssl_x86
|
mv openssl openssl_x86
|
||||||
cp -r openssl_x86 openssl_arm
|
cp -r openssl_x86 openssl_arm
|
||||||
|
|
||||||
@@ -405,9 +405,63 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
|||||||
log_info "Clean up openssl dir..."
|
log_info "Clean up openssl dir..."
|
||||||
mv openssl_x86 openssl
|
mv openssl_x86 openssl
|
||||||
rm -rf openssl_arm
|
rm -rf openssl_arm
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd ${project_root}/deps/libusb
|
||||||
|
log_info "Prepare libusb ..."
|
||||||
|
|
||||||
|
log_info "Building libusb x86 (deps) ..."
|
||||||
|
export MACOSX_DEPLOYMENT_TARGET=10.9
|
||||||
|
mkdir ${project_root}/deps/libusb/out_x86
|
||||||
|
./autogen.sh
|
||||||
|
./configure --host=x86_64-apple-darwin --prefix=${advss_dep_path}
|
||||||
|
make && make install
|
||||||
|
|
||||||
|
log_info "Building libusb x86 ..."
|
||||||
|
make clean
|
||||||
|
rm -r ${project_root}/deps/libusb/out_x86
|
||||||
|
mkdir ${project_root}/deps/libusb/out_x86
|
||||||
|
./configure --host=aarch64-apple-darwin --prefix=${project_root}/deps/libusb/out_x86
|
||||||
|
make && make install
|
||||||
|
|
||||||
|
log_info "Building libusb arm ..."
|
||||||
|
make clean
|
||||||
|
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
|
||||||
|
export CC=$(xcrun --sdk macosx --find clang)
|
||||||
|
export CXX=$(xcrun --sdk macosx --find clang++)
|
||||||
|
export CFLAGS="-arch arm64 -isysroot $SDKROOT"
|
||||||
|
export CXXFLAGS="-arch arm64 -isysroot $SDKROOT"
|
||||||
|
export LDFLAGS="-arch arm64 -isysroot $SDKROOT"
|
||||||
|
export MACOSX_DEPLOYMENT_TARGET=10.15
|
||||||
|
mkdir ${project_root}/deps/libusb/out_arm
|
||||||
|
./configure --host=aarch64-apple-darwin --prefix=${project_root}/deps/libusb/out_arm
|
||||||
|
make && make install
|
||||||
|
|
||||||
|
log_info "Combine arm and x86 libusb binaries ..."
|
||||||
|
lipo -create ${project_root}/deps/libusb/out_x86/lib/libusb-1.0.0.dylib \
|
||||||
|
${project_root}/deps/libusb/out_arm/lib/libusb-1.0.0.dylib \
|
||||||
|
-output ${advss_dep_path}/lib/temp-libusb-1.0.0.dylib
|
||||||
|
mv ${advss_dep_path}/lib/temp-libusb-1.0.0.dylib ${advss_dep_path}/lib/libusb-1.0.0.dylib
|
||||||
|
install_name_tool -id @rpath/libusb-1.0.0.dylib ${advss_dep_path}/lib/libusb-1.0.0.dylib
|
||||||
|
log_info "Clean up libusb ..."
|
||||||
|
|
||||||
|
unset SDKROOT
|
||||||
|
unset CC
|
||||||
|
unset CXX
|
||||||
|
unset CFLAGS
|
||||||
|
unset CXXFLAGS
|
||||||
|
unset LDFLAGS
|
||||||
|
unset MACOSX_DEPLOYMENT_TARGET
|
||||||
|
|
||||||
|
popd
|
||||||
;;
|
;;
|
||||||
linux)
|
linux)
|
||||||
# Nothing to do for now
|
# Hacky workaround to support libproc2 with Ubuntu 22 build environment
|
||||||
|
local lsb_version=$(lsb_release -r | cut -f 2 || true)
|
||||||
|
if [[ "${lsb_version}" == '22.04' ]] {
|
||||||
|
sudo apt install ${project_root}/build-aux/CI/linux/ubuntu22/libproc2-0_4.0.2-3_amd64.deb
|
||||||
|
sudo apt install ${project_root}/build-aux/CI/linux/ubuntu22/libproc2-dev_4.0.2-3_amd64.deb
|
||||||
|
}
|
||||||
;;
|
;;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
.github/scripts/.package.zsh
vendored
12
.github/scripts/.package.zsh
vendored
@@ -163,9 +163,13 @@ ${_usage_host:-}"
|
|||||||
|
|
||||||
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})"
|
||||||
|
|
||||||
|
log_info "Using git tag as version identifier '${git_tag}'"
|
||||||
|
product_version="${git_tag}"
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@@ -247,15 +251,21 @@ ${_usage_host:-}"
|
|||||||
cmake --build build_${target##*-} --config ${config} -t package_source ${cmake_args}
|
cmake --build build_${target##*-} --config ${config} -t package_source ${cmake_args}
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
local output_name="${product_name}-${product_version}-${target##*-}-linux-gnu"
|
||||||
|
|
||||||
if (( package )) {
|
if (( package )) {
|
||||||
log_group "Packaging ${product_name}..."
|
log_group "Packaging ${product_name}..."
|
||||||
pushd ${project_root}
|
pushd ${project_root}
|
||||||
cmake --build build_${target##*-} --config ${config} -t package ${cmake_args}
|
cmake --build build_${target##*-} --config ${config} -t package ${cmake_args}
|
||||||
|
|
||||||
|
if [ ! -e ${project_root}/release/${output_name}.deb ]; then
|
||||||
|
mv ${project_root}/release/*.deb ${project_root}/release/${output_name}.deb
|
||||||
|
mv ${project_root}/release/*.ddeb ${project_root}/release/${output_name}.ddeb
|
||||||
|
fi
|
||||||
popd
|
popd
|
||||||
}
|
}
|
||||||
|
|
||||||
log_group "Archiving ${product_name}..."
|
log_group "Archiving ${product_name}..."
|
||||||
local output_name="${product_name}-${product_version}-${target##*-}-linux-gnu"
|
|
||||||
local _tarflags='cJf'
|
local _tarflags='cJf'
|
||||||
if (( _loglevel > 1 || ${+CI} )) _tarflags="v${_tarflags}"
|
if (( _loglevel > 1 || ${+CI} )) _tarflags="v${_tarflags}"
|
||||||
|
|
||||||
|
|||||||
20
.github/scripts/Build-Deps-Windows.ps1
vendored
20
.github/scripts/Build-Deps-Windows.ps1
vendored
@@ -199,6 +199,26 @@ function Build {
|
|||||||
|
|
||||||
Log-Information "Install tesseract..."
|
Log-Information "Install tesseract..."
|
||||||
Invoke-External cmake --install "${TesseractBuildPath}" --prefix "${ADVSSDepPath}" @TesseractCmakeArgs
|
Invoke-External cmake --install "${TesseractBuildPath}" --prefix "${ADVSSDepPath}" @TesseractCmakeArgs
|
||||||
|
|
||||||
|
Push-Location -Stack BuildLibusbTemp
|
||||||
|
Ensure-Location $ProjectRoot
|
||||||
|
|
||||||
|
$LibusbPath = "${ProjectRoot}/deps/libusb"
|
||||||
|
|
||||||
|
Log-Information "Building libusb..."
|
||||||
|
$msbuildExe = vswhere -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe | select-object -first 1
|
||||||
|
|
||||||
|
if ($msbuildExe) {
|
||||||
|
Invoke-External $msbuildExe "${LibusbPath}/msvc/libusb.sln" /property:Configuration=Release /property:Platform=x64
|
||||||
|
|
||||||
|
$libusbBuildResultDirectory = "${LibusbPath}/build/v143/x64/Release"
|
||||||
|
if (-not (Test-Path -Path $libusbBuildResultDirectory)) {
|
||||||
|
$libusbBuildResultDirectory = "${LibusbPath}/x64/Release/dll"
|
||||||
|
}
|
||||||
|
Copy-Item -Path "${libusbBuildResultDirectory}/*" -Destination ${ADVSSDepPath} -Recurse -Force
|
||||||
|
} else {
|
||||||
|
Log-Information "Failed to locate msbuild.exe - skipping libusb build"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Build
|
Build
|
||||||
|
|||||||
4
.github/scripts/Package-Windows.ps1
vendored
4
.github/scripts/Package-Windows.ps1
vendored
@@ -48,6 +48,10 @@ function Package {
|
|||||||
$ProductName = $BuildSpec.name
|
$ProductName = $BuildSpec.name
|
||||||
$ProductVersion = $BuildSpec.version
|
$ProductVersion = $BuildSpec.version
|
||||||
|
|
||||||
|
$GitOutput = git describe --tags
|
||||||
|
Log-Information "Using git tag as version identifier '${GitOutput}'"
|
||||||
|
$ProductVersion = $GitOutput
|
||||||
|
|
||||||
$OutputName = "${ProductName}-${ProductVersion}-windows-${Target}"
|
$OutputName = "${ProductName}-${ProductVersion}-windows-${Target}"
|
||||||
|
|
||||||
if ( ! $SkipDeps ) {
|
if ( ! $SkipDeps ) {
|
||||||
|
|||||||
0
.github/test
vendored
Normal file
0
.github/test
vendored
Normal file
11
.gitignore
vendored
11
.gitignore
vendored
@@ -7,6 +7,7 @@
|
|||||||
!/cmake
|
!/cmake
|
||||||
!/data
|
!/data
|
||||||
!/deps
|
!/deps
|
||||||
|
!/scripting
|
||||||
!/forms
|
!/forms
|
||||||
!/lib
|
!/lib
|
||||||
!/module
|
!/module
|
||||||
@@ -14,7 +15,9 @@
|
|||||||
!/tests
|
!/tests
|
||||||
!.clang-format
|
!.clang-format
|
||||||
!.cmake-format.json
|
!.cmake-format.json
|
||||||
|
!.gitattributes
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
!.pre-commit-config.yaml
|
||||||
!BUILDING.md
|
!BUILDING.md
|
||||||
!buildspec.json
|
!buildspec.json
|
||||||
!CMakeLists.txt
|
!CMakeLists.txt
|
||||||
@@ -22,6 +25,9 @@
|
|||||||
!LICENSE
|
!LICENSE
|
||||||
!README.md
|
!README.md
|
||||||
|
|
||||||
|
# Exclude .orig leftovers
|
||||||
|
*.orig
|
||||||
|
|
||||||
# Exclude lock files
|
# Exclude lock files
|
||||||
*.lock.json
|
*.lock.json
|
||||||
|
|
||||||
@@ -29,4 +35,7 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# Exclude CMake build number cache
|
# Exclude CMake build number cache
|
||||||
/cmake/.CMakeBuildNumber
|
/cmake/.CMakeBuildNumber
|
||||||
|
|
||||||
|
# Exclude python caches
|
||||||
|
/**/__pycache__
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -25,3 +25,6 @@
|
|||||||
[submodule "deps/json"]
|
[submodule "deps/json"]
|
||||||
path = deps/json
|
path = deps/json
|
||||||
url = https://github.com/nlohmann/json.git
|
url = https://github.com/nlohmann/json.git
|
||||||
|
[submodule "deps/libusb"]
|
||||||
|
path = deps/libusb
|
||||||
|
url = https://github.com/libusb/libusb.git
|
||||||
|
|||||||
24
.pre-commit-config.yaml
Normal file
24
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: v16.0.6
|
||||||
|
hooks:
|
||||||
|
- id: clang-format
|
||||||
|
args: [-fallback-style=none]
|
||||||
|
types_or: [c++, c]
|
||||||
|
exclude: |
|
||||||
|
(?x)^(
|
||||||
|
deps/.*|
|
||||||
|
tests/catch\.hpp|
|
||||||
|
.*\.mm
|
||||||
|
)$
|
||||||
|
|
||||||
|
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
||||||
|
rev: v0.6.13
|
||||||
|
hooks:
|
||||||
|
- id: cmake-format
|
||||||
|
|
||||||
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
|
rev: v0.3.2
|
||||||
|
hooks:
|
||||||
|
- id: ruff-format
|
||||||
|
types_or: [python]
|
||||||
48
BUILDING.md
48
BUILDING.md
@@ -4,11 +4,13 @@ You have the option to ...
|
|||||||
- either add the plugin to the OBS source tree directly and build the plugin while building OBS itself. (**in tree**)
|
- either add the plugin to the OBS source tree directly and build the plugin while building OBS itself. (**in tree**)
|
||||||
- or you can move the sources of this plugin outside of the OBS source tree and build it separately from OBS. (**out of tree**)
|
- or you can move the sources of this plugin outside of the OBS source tree and build it separately from OBS. (**out of tree**)
|
||||||
|
|
||||||
As both methods require you to have a working [OBS Studio development environment](https://obsproject.com/wiki/Building-OBS-Studio) and [CMake](https://cmake.org/download/) it is recommended to build the plugin in tree as it is easier to set up and will enable straightforward debugging.
|
Both methods require [CMake](https://cmake.org/download/).
|
||||||
|
|
||||||
The plugin can be compiled for OBS 25 and above, although using the latest version of OBS is recommended to support all features.
|
The plugin can be compiled for OBS 27 and above, although using the latest version of OBS is recommended to support all features.
|
||||||
|
|
||||||
## Compiling in tree (recommended for development)
|
## Compiling in tree (recommended for development)
|
||||||
|
This section assumes that you have a working [OBS Studio development environment](https://obsproject.com/wiki/Building-OBS-Studio).
|
||||||
|
|
||||||
Add the "SceneSwitcher" source directory to your obs-studio source directory under obs-studio/UI/frontend-plugins/:
|
Add the "SceneSwitcher" source directory to your obs-studio source directory under obs-studio/UI/frontend-plugins/:
|
||||||
```
|
```
|
||||||
cd obs-studio/UI/frontend-plugins/
|
cd obs-studio/UI/frontend-plugins/
|
||||||
@@ -46,12 +48,12 @@ cmake -DOpenCV_DIR="C:/Users/BuildUser/Documents/OBS/opencv/build/" -DLeptonica_
|
|||||||
First you will need to clone the plugin sources by running the following command:
|
First you will need to clone the plugin sources by running the following command:
|
||||||
```
|
```
|
||||||
git clone --recursive https://github.com/WarmUpTill/SceneSwitcher.git
|
git clone --recursive https://github.com/WarmUpTill/SceneSwitcher.git
|
||||||
cd SceneSwitcher
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Next you will need [CMake](https://cmake.org/download/) and run the command with suitable arguments for your particular platform.
|
Next you will need [CMake](https://cmake.org/download/) and run it with suitable arguments for your particular platform.
|
||||||
For example, on Windows you might want to run this command:
|
For example, on Windows you might want to run this command:
|
||||||
```
|
```
|
||||||
|
cd SceneSwitcher
|
||||||
cmake --preset windows-x64
|
cmake --preset windows-x64
|
||||||
```
|
```
|
||||||
Next, you can build the plugin and install the files into a folder named release using the following commands:
|
Next, you can build the plugin and install the files into a folder named release using the following commands:
|
||||||
@@ -72,7 +74,7 @@ cd SceneSwitcher
|
|||||||
cmake -DOpenCV_DIR="C:/Users/BuildUser/Documents/OBS/opencv/build/" -DLeptonica_DIR="C:/Users/BuildUser/Documents/OBS/leptonica/build" -DTesseract_DIR="C:/Users/BuildUser/Documents/OBS/tesseract/build/lib/cmake/tesseract" --preset windows-x64
|
cmake -DOpenCV_DIR="C:/Users/BuildUser/Documents/OBS/opencv/build/" -DLeptonica_DIR="C:/Users/BuildUser/Documents/OBS/leptonica/build" -DTesseract_DIR="C:/Users/BuildUser/Documents/OBS/tesseract/build/lib/cmake/tesseract" --preset windows-x64
|
||||||
```
|
```
|
||||||
|
|
||||||
You can rely on the CI scripts to build the dependencies for you, although it is not guaranteed that they will work in every environment:
|
You can rely on the CI scripts to build the dependencies for you, although it is not guaranteed that they will function in every environment:
|
||||||
|
|
||||||
| Platform | Command |
|
| Platform | Command |
|
||||||
| ----------- | ----------- |
|
| ----------- | ----------- |
|
||||||
@@ -83,10 +85,10 @@ You can rely on the CI scripts to build the dependencies for you, although it is
|
|||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Contributions to the plugin are always welcome and if you need any assistance do not hesitate to reach out.
|
Contributions to the plugin are always welcome and if you need any assistance do not hesitate to reach out!
|
||||||
|
|
||||||
If you would like to expand upon the macro system by adding a new condition or action type have a look at the examples in `plugins/base`.
|
If you would like to expand upon the macro system by adding a new condition or action type have a look at the examples in `plugins/base`.
|
||||||
In general changes in the `lib/legacy` folder should be avoided.
|
In general changes in the `lib/legacy` folder should be avoided, if possible.
|
||||||
|
|
||||||
## Macro condition
|
## Macro condition
|
||||||
Macro conditions should inherit from the `MacroCondition` class and must implement the following functions:
|
Macro conditions should inherit from the `MacroCondition` class and must implement the following functions:
|
||||||
@@ -97,12 +99,12 @@ public:
|
|||||||
MacroConditionExample(Macro *m) : MacroCondition(m) {}
|
MacroConditionExample(Macro *m) : MacroCondition(m) {}
|
||||||
// This function should perform the condition check
|
// This function should perform the condition check
|
||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
// This function should store the required condition data to "obj"
|
// This function should store the required condition data to "data"
|
||||||
// For example called on OBS shutdown
|
// For example called on OBS shutdown
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *data);
|
||||||
// This function should load the condition data from "obj"
|
// This function should load the condition data from "data"
|
||||||
// For example called on OBS startup
|
// For example called on OBS startup
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *data);
|
||||||
// This function should return a unique id for this condition type
|
// This function should return a unique id for this condition type
|
||||||
// The _id is defined below
|
// The _id is defined below
|
||||||
std::string GetId() { return _id; };
|
std::string GetId() { return _id; };
|
||||||
@@ -120,7 +122,7 @@ private:
|
|||||||
static const std::string _id;
|
static const std::string _id;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
When defining the widget used to control the settings of the condition type, it is important to add a static `Create()` method.
|
When defining the widget used to control the settings of the condition type, a static `Create()` method is required.
|
||||||
It will be called whenever a new condition MacroConditionExample is created. (See `MacroConditionFactory::Register()`)
|
It will be called whenever a new condition MacroConditionExample is created. (See `MacroConditionFactory::Register()`)
|
||||||
```
|
```
|
||||||
class MacroConditionExampleEdit : public QWidget {
|
class MacroConditionExampleEdit : public QWidget {
|
||||||
@@ -151,7 +153,7 @@ bool MacroConditionExample::_registered = MacroConditionFactory::Register(
|
|||||||
MacroConditionExample::id, // Unique string identifying this condition type
|
MacroConditionExample::id, // Unique string identifying this condition type
|
||||||
{
|
{
|
||||||
MacroConditionExample::Create, // Function called to create the object performing the condition
|
MacroConditionExample::Create, // Function called to create the object performing the condition
|
||||||
MacroConditionExampleEdit::Create, // Function called to create the widget configure the condition
|
MacroConditionExampleEdit::Create, // Function called to create the widget to configure the settings
|
||||||
"AdvSceneSwitcher.condition.example", // User facing name of the condition type (will be translated)
|
"AdvSceneSwitcher.condition.example", // User facing name of the condition type (will be translated)
|
||||||
true // Condition type supports duration modifiers (default true)
|
true // Condition type supports duration modifiers (default true)
|
||||||
}
|
}
|
||||||
@@ -167,16 +169,18 @@ The differences are highlighted in the comments below.
|
|||||||
class MacroActionExample : public MacroAction {
|
class MacroActionExample : public MacroAction {
|
||||||
public:
|
public:
|
||||||
MacroActionExample(Macro *m) : MacroAction(m) {}
|
MacroActionExample(Macro *m) : MacroAction(m) {}
|
||||||
|
static std::shared_ptr<MacroAction> Create(Macro *m);
|
||||||
|
// Used to create a copy of the action (used for action queues)
|
||||||
|
std::shared_ptr<MacroAction> Copy() const;
|
||||||
// This function should perform the action
|
// This function should perform the action
|
||||||
// If false is returned the macro will aborted
|
// If false is returned the macro will aborted
|
||||||
bool PerformAction();
|
bool PerformAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *data);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *data);
|
||||||
std::string GetId() { return _id; };
|
std::string GetId() { return _id; };
|
||||||
static std::shared_ptr<MacroAction> Create(Macro *m)
|
// Optional:
|
||||||
{
|
// Might be called when action is inserted to action queue
|
||||||
return std::make_shared<MacroActionExample>(m);
|
void ResolveVariablesToFixedValues();
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
@@ -207,11 +211,11 @@ MacroActionFactory::Register(
|
|||||||
MacroActionExample::id, // Unique string identifying this action type
|
MacroActionExample::id, // Unique string identifying this action type
|
||||||
{
|
{
|
||||||
MacroActionExample::Create, // Function called to create the object performing the action
|
MacroActionExample::Create, // Function called to create the object performing the action
|
||||||
MacroActionExampleEdit::Create, // Function called to create the widget configure the action
|
MacroActionExampleEdit::Create, // Function called to create the widget to configure the settings
|
||||||
"AdvSceneSwitcher.action.example" // User facing name of the action type
|
"AdvSceneSwitcher.action.example" // User facing name of the action type
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
## External dependencies
|
## External dependencies
|
||||||
If your intention is to add macro functionality which depends on external libraries, which is likely not to exist on all user setups, have a look at the folders in the `plugins/` directory, which are not named base.
|
If your intention is to add macro functionality which depends on external libraries, which might not exist on all user environments, have a look at the folders in the `plugins/` directory, which are not named `base`.
|
||||||
For example `plugins/video` will only be loaded if the `OpenCV` dependencies are met.
|
For example, `plugins/video` will only be loaded if the `OpenCV` dependencies are met.
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ target_sources(
|
|||||||
lib/macro/macro-action-macro.hpp
|
lib/macro/macro-action-macro.hpp
|
||||||
lib/macro/macro-action-queue.cpp
|
lib/macro/macro-action-queue.cpp
|
||||||
lib/macro/macro-action-queue.hpp
|
lib/macro/macro-action-queue.hpp
|
||||||
|
lib/macro/macro-action-script.cpp
|
||||||
|
lib/macro/macro-action-script.hpp
|
||||||
lib/macro/macro-action-variable.cpp
|
lib/macro/macro-action-variable.cpp
|
||||||
lib/macro/macro-action-variable.hpp
|
lib/macro/macro-action-variable.hpp
|
||||||
lib/macro/macro-action.cpp
|
lib/macro/macro-action.cpp
|
||||||
@@ -108,6 +110,8 @@ target_sources(
|
|||||||
lib/macro/macro-condition-macro.hpp
|
lib/macro/macro-condition-macro.hpp
|
||||||
lib/macro/macro-condition-queue.cpp
|
lib/macro/macro-condition-queue.cpp
|
||||||
lib/macro/macro-condition-queue.hpp
|
lib/macro/macro-condition-queue.hpp
|
||||||
|
lib/macro/macro-condition-script.cpp
|
||||||
|
lib/macro/macro-condition-script.hpp
|
||||||
lib/macro/macro-condition-tempvar.cpp
|
lib/macro/macro-condition-tempvar.cpp
|
||||||
lib/macro/macro-condition-tempvar.hpp
|
lib/macro/macro-condition-tempvar.hpp
|
||||||
lib/macro/macro-condition-variable.cpp
|
lib/macro/macro-condition-variable.cpp
|
||||||
@@ -120,22 +124,30 @@ target_sources(
|
|||||||
lib/macro/macro-export-import-dialog.hpp
|
lib/macro/macro-export-import-dialog.hpp
|
||||||
lib/macro/macro-helpers.cpp
|
lib/macro/macro-helpers.cpp
|
||||||
lib/macro/macro-helpers.hpp
|
lib/macro/macro-helpers.hpp
|
||||||
|
lib/macro/macro-input.cpp
|
||||||
|
lib/macro/macro-input.hpp
|
||||||
lib/macro/macro-list.cpp
|
lib/macro/macro-list.cpp
|
||||||
lib/macro/macro-list.hpp
|
lib/macro/macro-list.hpp
|
||||||
lib/macro/macro-properties.cpp
|
|
||||||
lib/macro/macro-properties.hpp
|
|
||||||
lib/macro/macro-ref.cpp
|
lib/macro/macro-ref.cpp
|
||||||
lib/macro/macro-ref.hpp
|
lib/macro/macro-ref.hpp
|
||||||
lib/macro/macro-run-button.cpp
|
lib/macro/macro-run-button.cpp
|
||||||
lib/macro/macro-run-button.hpp
|
lib/macro/macro-run-button.hpp
|
||||||
|
lib/macro/macro-script-handler.cpp
|
||||||
|
lib/macro/macro-script-handler.hpp
|
||||||
|
lib/macro/macro-segment-copy-paste.cpp
|
||||||
|
lib/macro/macro-segment-copy-paste.hpp
|
||||||
lib/macro/macro-segment-list.cpp
|
lib/macro/macro-segment-list.cpp
|
||||||
lib/macro/macro-segment-list.hpp
|
lib/macro/macro-segment-list.hpp
|
||||||
|
lib/macro/macro-segment-script.cpp
|
||||||
|
lib/macro/macro-segment-script.hpp
|
||||||
lib/macro/macro-segment-selection.cpp
|
lib/macro/macro-segment-selection.cpp
|
||||||
lib/macro/macro-segment-selection.hpp
|
lib/macro/macro-segment-selection.hpp
|
||||||
lib/macro/macro-segment.cpp
|
lib/macro/macro-segment.cpp
|
||||||
lib/macro/macro-segment.hpp
|
lib/macro/macro-segment.hpp
|
||||||
lib/macro/macro-selection.cpp
|
lib/macro/macro-selection.cpp
|
||||||
lib/macro/macro-selection.hpp
|
lib/macro/macro-selection.hpp
|
||||||
|
lib/macro/macro-settings.cpp
|
||||||
|
lib/macro/macro-settings.hpp
|
||||||
lib/macro/macro-tab.cpp
|
lib/macro/macro-tab.cpp
|
||||||
lib/macro/macro-tree.cpp
|
lib/macro/macro-tree.cpp
|
||||||
lib/macro/macro-tree.hpp
|
lib/macro/macro-tree.hpp
|
||||||
@@ -145,12 +157,24 @@ target_sources(
|
|||||||
# Utility function sources
|
# Utility function sources
|
||||||
target_sources(
|
target_sources(
|
||||||
${LIB_NAME}
|
${LIB_NAME}
|
||||||
PRIVATE lib/utils/action-queue.cpp
|
PRIVATE lib/queue/action-queue.cpp
|
||||||
lib/utils/action-queue.hpp
|
lib/queue/action-queue.hpp
|
||||||
|
lib/queue/action-queue-tab.cpp
|
||||||
|
lib/queue/action-queue-tab.hpp
|
||||||
|
lib/utils/backup.cpp
|
||||||
|
lib/utils/backup.hpp
|
||||||
|
lib/utils/condition-logic.cpp
|
||||||
|
lib/utils/condition-logic.hpp
|
||||||
lib/utils/curl-helper.cpp
|
lib/utils/curl-helper.cpp
|
||||||
lib/utils/curl-helper.hpp
|
lib/utils/curl-helper.hpp
|
||||||
|
lib/utils/cursor-shape-changer.cpp
|
||||||
|
lib/utils/cursor-shape-changer.hpp
|
||||||
|
lib/utils/double-slider.cpp
|
||||||
|
lib/utils/double-slider.hpp
|
||||||
lib/utils/duration-control.cpp
|
lib/utils/duration-control.cpp
|
||||||
lib/utils/duration-control.hpp
|
lib/utils/duration-control.hpp
|
||||||
|
lib/utils/duration-modifier.cpp
|
||||||
|
lib/utils/duration-modifier.hpp
|
||||||
lib/utils/duration.cpp
|
lib/utils/duration.cpp
|
||||||
lib/utils/duration.hpp
|
lib/utils/duration.hpp
|
||||||
lib/utils/export-symbol-helper.hpp
|
lib/utils/export-symbol-helper.hpp
|
||||||
@@ -158,10 +182,16 @@ target_sources(
|
|||||||
lib/utils/file-selection.hpp
|
lib/utils/file-selection.hpp
|
||||||
lib/utils/filter-combo-box.cpp
|
lib/utils/filter-combo-box.cpp
|
||||||
lib/utils/filter-combo-box.hpp
|
lib/utils/filter-combo-box.hpp
|
||||||
|
lib/utils/help-icon.hpp
|
||||||
|
lib/utils/help-icon.cpp
|
||||||
lib/utils/item-selection-helpers.cpp
|
lib/utils/item-selection-helpers.cpp
|
||||||
lib/utils/item-selection-helpers.hpp
|
lib/utils/item-selection-helpers.hpp
|
||||||
lib/utils/layout-helpers.cpp
|
lib/utils/layout-helpers.cpp
|
||||||
lib/utils/layout-helpers.hpp
|
lib/utils/layout-helpers.hpp
|
||||||
|
lib/utils/list-controls.cpp
|
||||||
|
lib/utils/list-controls.hpp
|
||||||
|
lib/utils/list-editor.cpp
|
||||||
|
lib/utils/list-editor.hpp
|
||||||
lib/utils/log-helper.cpp
|
lib/utils/log-helper.cpp
|
||||||
lib/utils/log-helper.hpp
|
lib/utils/log-helper.hpp
|
||||||
lib/utils/math-helpers.cpp
|
lib/utils/math-helpers.cpp
|
||||||
@@ -174,7 +204,6 @@ target_sources(
|
|||||||
lib/utils/name-dialog.hpp
|
lib/utils/name-dialog.hpp
|
||||||
lib/utils/non-modal-dialog.cpp
|
lib/utils/non-modal-dialog.cpp
|
||||||
lib/utils/non-modal-dialog.hpp
|
lib/utils/non-modal-dialog.hpp
|
||||||
lib/utils/obs-dock.hpp
|
|
||||||
lib/utils/obs-module-helper.cpp
|
lib/utils/obs-module-helper.cpp
|
||||||
lib/utils/obs-module-helper.hpp
|
lib/utils/obs-module-helper.hpp
|
||||||
lib/utils/path-helpers.cpp
|
lib/utils/path-helpers.cpp
|
||||||
@@ -183,10 +212,17 @@ target_sources(
|
|||||||
lib/utils/plugin-state-helpers.hpp
|
lib/utils/plugin-state-helpers.hpp
|
||||||
lib/utils/priority-helper.cpp
|
lib/utils/priority-helper.cpp
|
||||||
lib/utils/priority-helper.hpp
|
lib/utils/priority-helper.hpp
|
||||||
|
lib/utils/properties-view.cpp
|
||||||
|
lib/utils/properties-view.hpp
|
||||||
|
lib/utils/properties-view.moc.hpp
|
||||||
lib/utils/regex-config.cpp
|
lib/utils/regex-config.cpp
|
||||||
lib/utils/regex-config.hpp
|
lib/utils/regex-config.hpp
|
||||||
lib/utils/resizing-text-edit.cpp
|
lib/utils/resizing-text-edit.cpp
|
||||||
lib/utils/resizing-text-edit.hpp
|
lib/utils/resizing-text-edit.hpp
|
||||||
|
lib/utils/resource-table.cpp
|
||||||
|
lib/utils/resource-table.hpp
|
||||||
|
lib/utils/resource-table-hotkey-handler.cpp
|
||||||
|
lib/utils/resource-table-hotkey-handler.hpp
|
||||||
lib/utils/scene-selection.cpp
|
lib/utils/scene-selection.cpp
|
||||||
lib/utils/scene-selection.hpp
|
lib/utils/scene-selection.hpp
|
||||||
lib/utils/scene-switch-helpers.cpp
|
lib/utils/scene-switch-helpers.cpp
|
||||||
@@ -197,6 +233,8 @@ target_sources(
|
|||||||
lib/utils/section.hpp
|
lib/utils/section.hpp
|
||||||
lib/utils/selection-helpers.cpp
|
lib/utils/selection-helpers.cpp
|
||||||
lib/utils/selection-helpers.hpp
|
lib/utils/selection-helpers.hpp
|
||||||
|
lib/utils/single-char-selection.cpp
|
||||||
|
lib/utils/single-char-selection.hpp
|
||||||
lib/utils/slider-spinbox.cpp
|
lib/utils/slider-spinbox.cpp
|
||||||
lib/utils/slider-spinbox.hpp
|
lib/utils/slider-spinbox.hpp
|
||||||
lib/utils/source-helpers.cpp
|
lib/utils/source-helpers.cpp
|
||||||
@@ -207,10 +245,14 @@ target_sources(
|
|||||||
lib/utils/splitter-helpers.hpp
|
lib/utils/splitter-helpers.hpp
|
||||||
lib/utils/status-control.cpp
|
lib/utils/status-control.cpp
|
||||||
lib/utils/status-control.hpp
|
lib/utils/status-control.hpp
|
||||||
|
lib/utils/string-list.cpp
|
||||||
|
lib/utils/string-list.hpp
|
||||||
lib/utils/switch-button.cpp
|
lib/utils/switch-button.cpp
|
||||||
lib/utils/switch-button.hpp
|
lib/utils/switch-button.hpp
|
||||||
lib/utils/sync-helpers.cpp
|
lib/utils/sync-helpers.cpp
|
||||||
lib/utils/sync-helpers.hpp
|
lib/utils/sync-helpers.hpp
|
||||||
|
lib/utils/tab-helpers.cpp
|
||||||
|
lib/utils/tab-helpers.hpp
|
||||||
lib/utils/temp-variable.cpp
|
lib/utils/temp-variable.cpp
|
||||||
lib/utils/temp-variable.hpp
|
lib/utils/temp-variable.hpp
|
||||||
lib/utils/ui-helpers.cpp
|
lib/utils/ui-helpers.cpp
|
||||||
@@ -228,6 +270,7 @@ target_sources(
|
|||||||
lib/variables/variable-string.cpp
|
lib/variables/variable-string.cpp
|
||||||
lib/variables/variable-string.hpp
|
lib/variables/variable-string.hpp
|
||||||
lib/variables/variable-tab.cpp
|
lib/variables/variable-tab.cpp
|
||||||
|
lib/variables/variable-tab.hpp
|
||||||
lib/variables/variable-text-edit.cpp
|
lib/variables/variable-text-edit.cpp
|
||||||
lib/variables/variable-text-edit.hpp
|
lib/variables/variable-text-edit.hpp
|
||||||
lib/variables/variable.cpp
|
lib/variables/variable.cpp
|
||||||
@@ -235,6 +278,11 @@ target_sources(
|
|||||||
|
|
||||||
# --- End of section ---
|
# --- End of section ---
|
||||||
|
|
||||||
|
# Subfolder for advanced scene switcher plugins
|
||||||
|
set(ADVSS_PLUGIN_FOLDER "advanced-scene-switcher-plugins")
|
||||||
|
target_compile_definitions(
|
||||||
|
${LIB_NAME} PRIVATE ADVSS_PLUGIN_FOLDER=\"${ADVSS_PLUGIN_FOLDER}\")
|
||||||
|
|
||||||
include(cmake/common/advss_helpers.cmake)
|
include(cmake/common/advss_helpers.cmake)
|
||||||
setup_obs_lib_dependency(${LIB_NAME})
|
setup_obs_lib_dependency(${LIB_NAME})
|
||||||
setup_obs_lib_dependency(${PROJECT_NAME})
|
setup_obs_lib_dependency(${PROJECT_NAME})
|
||||||
@@ -262,6 +310,7 @@ target_include_directories(
|
|||||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/lib"
|
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/lib"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/legacy"
|
"${CMAKE_CURRENT_SOURCE_DIR}/lib/legacy"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/macro"
|
"${CMAKE_CURRENT_SOURCE_DIR}/lib/macro"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/lib/queue"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/utils"
|
"${CMAKE_CURRENT_SOURCE_DIR}/lib/utils"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/variables"
|
"${CMAKE_CURRENT_SOURCE_DIR}/lib/variables"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/forms")
|
"${CMAKE_CURRENT_BINARY_DIR}/forms")
|
||||||
@@ -319,6 +368,9 @@ if(OS_WINDOWS)
|
|||||||
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)
|
/bigobj)
|
||||||
|
|
||||||
|
# Workaround for MSVC incompatibility in CI environment
|
||||||
|
add_compile_definitions(${target_name} _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)
|
||||||
endif()
|
endif()
|
||||||
target_sources(${LIB_NAME} PRIVATE lib/win/advanced-scene-switcher-win.cpp)
|
target_sources(${LIB_NAME} PRIVATE lib/win/advanced-scene-switcher-win.cpp)
|
||||||
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
||||||
|
|||||||
@@ -22,4 +22,6 @@ sudo snap install obs-studio
|
|||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
- If you wish to contribute code to the project, have a look at this [section](BUILDING.md) describing how to compile the plugin.
|
- If you wish to contribute code to the project, have a look at this [section](BUILDING.md) describing how to compile the plugin.
|
||||||
|
- You can add custom conditions and actions at runtime using the API described [here](https://github.com/WarmUpTill/SceneSwitcher/wiki/Scripting).
|
||||||
|
- You can optionally use [pre-commit](https://pre-commit.com) to automatically handle formatting.
|
||||||
- If you wish to contribute translations, feel free to submit pull requests for the corresponding files under `data/locale`.
|
- If you wish to contribute translations, feel free to submit pull requests for the corresponding files under `data/locale`.
|
||||||
|
|||||||
@@ -49,7 +49,16 @@ invoke_formatter() {
|
|||||||
exit 2
|
exit 2
|
||||||
}
|
}
|
||||||
|
|
||||||
local -a source_files=(src/**/*.(c|cpp|h|hpp|m|mm)(.N))
|
local -a source_files=()
|
||||||
|
for folder ("lib" "module" "plugins" "tests") {
|
||||||
|
source_files+=(${folder}/**/*.(c|cpp|h|hpp)(.N))
|
||||||
|
}
|
||||||
|
|
||||||
|
for file (${source_files}) {
|
||||||
|
if [[ $file == *"catch.hpp" ]]; then
|
||||||
|
source_files=("${source_files[@]/$file}")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
local -a format_args=(-style=file -fallback-style=none)
|
local -a format_args=(-style=file -fallback-style=none)
|
||||||
if (( _loglevel > 2 )) format_args+=(--verbose)
|
if (( _loglevel > 2 )) format_args+=(--verbose)
|
||||||
|
|||||||
@@ -1,19 +1,24 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
defaultLocaleFile = "en-US.ini"
|
defaultLocaleFile = "en-US.ini"
|
||||||
|
|
||||||
|
|
||||||
class localeEntry:
|
class localeEntry:
|
||||||
locale = ""
|
locale = ""
|
||||||
placeholders = []
|
widgetPlaceholders = []
|
||||||
|
qStringArgs = []
|
||||||
|
lineNum = -1
|
||||||
|
|
||||||
def __init__(self, locale, widgets) -> None:
|
def __init__(self, locale, widgetPlaceholders, qStringArgs, lineNum) -> None:
|
||||||
self.locale = locale
|
self.locale = locale
|
||||||
self.placeholders = widgets
|
self.widgetPlaceholders = widgetPlaceholders
|
||||||
|
self.qStringArgs = qStringArgs
|
||||||
|
self.lineNum = lineNum
|
||||||
|
|
||||||
|
|
||||||
def getNonDefaultLocales(dir):
|
def getNonDefaultLocales(dir):
|
||||||
@@ -22,21 +27,35 @@ def getNonDefaultLocales(dir):
|
|||||||
f = os.path.join(dir, filename)
|
f = os.path.join(dir, filename)
|
||||||
if os.path.isfile(f) and not f.endswith(defaultLocaleFile):
|
if os.path.isfile(f) and not f.endswith(defaultLocaleFile):
|
||||||
files.append(f)
|
files.append(f)
|
||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
||||||
def getAllLocaleEntriesWithWidgetPlaceholders(file):
|
def getAllLocaleEntries(file):
|
||||||
localeEntries = []
|
localeEntries = []
|
||||||
with open(file, 'r', encoding='UTF-8') as f:
|
with open(file, "r", encoding="UTF-8") as f:
|
||||||
for line in f.readlines():
|
for lineNum, line in enumerate(f):
|
||||||
widgetPlaceholders = []
|
widgetPlaceholders = []
|
||||||
|
qStringArgs = []
|
||||||
|
|
||||||
|
if line.startswith(";"):
|
||||||
|
continue
|
||||||
|
|
||||||
for word in line.split("{{"):
|
for word in line.split("{{"):
|
||||||
if not "}}" in word:
|
if not "}}" in word:
|
||||||
continue
|
continue
|
||||||
word = "{{" + word[:word.rfind("}}")] + "}}"
|
placeholder = "{{" + word[: word.rfind("}}")] + "}}"
|
||||||
widgetPlaceholders.append(word)
|
widgetPlaceholders.append(placeholder)
|
||||||
localeEntries.append(localeEntry(
|
|
||||||
line.split("=")[0], widgetPlaceholders))
|
for match in re.finditer(r"%\d+", line):
|
||||||
|
qStringArgs.append(match.group(0))
|
||||||
|
|
||||||
|
localeEntries.append(
|
||||||
|
localeEntry(
|
||||||
|
line.split("=")[0], widgetPlaceholders, qStringArgs, lineNum + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return localeEntries
|
return localeEntries
|
||||||
|
|
||||||
|
|
||||||
@@ -44,47 +63,95 @@ def getLocaleEntryFrom(entry, list):
|
|||||||
for element in list:
|
for element in list:
|
||||||
if element.locale == entry.locale:
|
if element.locale == entry.locale:
|
||||||
return element
|
return element
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def checkWidgetPlacehodlers(file, expectedPlaceholders):
|
def checkLocaleEntries(file, expectedLocaleEntries):
|
||||||
localeEntries = getAllLocaleEntriesWithWidgetPlaceholders(file)
|
localeEntries = getAllLocaleEntries(file)
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
for localeEntry in localeEntries:
|
for localeEntry in localeEntries:
|
||||||
expectedEntry = getLocaleEntryFrom(localeEntry, expectedPlaceholders)
|
expectedLocaleEntry = getLocaleEntryFrom(localeEntry, expectedLocaleEntries)
|
||||||
if expectedEntry is None:
|
|
||||||
|
if expectedLocaleEntry is None:
|
||||||
|
result = False
|
||||||
print(
|
print(
|
||||||
"WARNING: Locale entry \"{}\" from \"{}\" not found in \"{}\"".format(localeEntry.locale, file, defaultLocaleFile))
|
'ERROR: Locale entry "{}" from "{}:{}" not found in "{}"'.format(
|
||||||
|
localeEntry.locale, file, localeEntry.lineNum, defaultLocaleFile
|
||||||
|
)
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
for p in localeEntry.placeholders:
|
|
||||||
if p not in expectedEntry.placeholders:
|
for placeholder in localeEntry.widgetPlaceholders:
|
||||||
print("WARNING: Locale entry \"{}\" from \"{}\" does contain \"{}\" while \"{}\" does not".format(
|
if placeholder not in expectedLocaleEntry.widgetPlaceholders:
|
||||||
localeEntry.locale, file, p, defaultLocaleFile))
|
|
||||||
for p in expectedEntry.placeholders:
|
|
||||||
if p not in localeEntry.placeholders:
|
|
||||||
result = False
|
result = False
|
||||||
print("ERROR: Locale entry \"{}\" from \"{}\" does not contain \"{}\"".format(
|
print(
|
||||||
localeEntry.locale, file, p))
|
'ERROR: Locale entry "{}" from "{}:{}" does contain "{}" widget placeholder while "{}:{}" does not'.format(
|
||||||
|
localeEntry.locale,
|
||||||
|
file,
|
||||||
|
localeEntry.lineNum,
|
||||||
|
placeholder,
|
||||||
|
defaultLocaleFile,
|
||||||
|
expectedLocaleEntry.lineNum,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for placeholder in expectedLocaleEntry.widgetPlaceholders:
|
||||||
|
if placeholder not in localeEntry.widgetPlaceholders:
|
||||||
|
result = False
|
||||||
|
print(
|
||||||
|
'ERROR: Locale entry "{}" from "{}:{}" does not contain "{}" widget placeholder'.format(
|
||||||
|
localeEntry.locale, file, localeEntry.lineNum, placeholder
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for arg in localeEntry.qStringArgs:
|
||||||
|
if arg not in expectedLocaleEntry.qStringArgs:
|
||||||
|
result = False
|
||||||
|
print(
|
||||||
|
'ERROR: Locale entry "{}" from "{}:{}" does contain "{}" QString arg while "{}:{}" does not'.format(
|
||||||
|
localeEntry.locale,
|
||||||
|
file,
|
||||||
|
localeEntry.lineNum,
|
||||||
|
arg,
|
||||||
|
defaultLocaleFile,
|
||||||
|
expectedLocaleEntry.lineNum,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for arg in expectedLocaleEntry.qStringArgs:
|
||||||
|
if arg not in localeEntry.qStringArgs:
|
||||||
|
result = False
|
||||||
|
print(
|
||||||
|
'ERROR: Locale entry "{}" from "{}:{}" does not contain "{}" QString arg'.format(
|
||||||
|
localeEntry.locale, file, localeEntry.lineNum, arg
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description='Checks for inconsistencies regarding widget placeholders in the different locale files.')
|
description="Checks for inconsistencies regarding widget placeholders in the different locale files."
|
||||||
parser.add_argument(
|
)
|
||||||
'-p', '--path', help='Path to locale folder', required=True)
|
parser.add_argument("-p", "--path", help="Path to locale folder", required=True)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
placeholders = getAllLocaleEntriesWithWidgetPlaceholders(
|
defaultLocaleEntries = getAllLocaleEntries(
|
||||||
os.path.join(args.path, defaultLocaleFile))
|
os.path.join(args.path, defaultLocaleFile)
|
||||||
|
)
|
||||||
nonDefaultLocales = getNonDefaultLocales(args.path)
|
nonDefaultLocales = getNonDefaultLocales(args.path)
|
||||||
|
|
||||||
result = True
|
result = True
|
||||||
for f in nonDefaultLocales:
|
for file in nonDefaultLocales:
|
||||||
if checkWidgetPlacehodlers(f, placeholders) == False:
|
if checkLocaleEntries(file, defaultLocaleEntries) == False:
|
||||||
result = False
|
result = False
|
||||||
|
|
||||||
if result == False:
|
if result == False:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print("SUCCESS: No issues found!")
|
print("SUCCESS: No issues found!")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|||||||
BIN
build-aux/CI/linux/ubuntu22/libproc2-0_4.0.2-3_amd64.deb
Normal file
BIN
build-aux/CI/linux/ubuntu22/libproc2-0_4.0.2-3_amd64.deb
Normal file
Binary file not shown.
BIN
build-aux/CI/linux/ubuntu22/libproc2-dev_4.0.2-3_amd64.deb
Normal file
BIN
build-aux/CI/linux/ubuntu22/libproc2-dev_4.0.2-3_amd64.deb
Normal file
Binary file not shown.
@@ -1,33 +1,33 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"obs-studio": {
|
"obs-studio": {
|
||||||
"version": "29.1.2",
|
"version": "30.0.2",
|
||||||
"baseUrl": "https://github.com/obsproject/obs-studio/archive/refs/tags",
|
"baseUrl": "https://github.com/obsproject/obs-studio/archive/refs/tags",
|
||||||
"label": "OBS sources",
|
"label": "OBS sources",
|
||||||
"hashes": {
|
"hashes": {
|
||||||
"macos": "215f1fa5772c5dd9f3d6e35b0cb573912b00320149666a77864f9d305525504b",
|
"macos": "be12c3ad0a85713750d8325e4b1db75086223402d7080d0e3c2833d7c5e83c27",
|
||||||
"windows-x64": "46d451f3f42b9d2c59339ec268165849c7b7904cdf1cc2a8d44c015815a9e37d"
|
"windows-x64": "970058c49322cfa9cd6d620abb393fed89743ba7e74bd9dbb6ebe0ea8141d9c7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prebuilt": {
|
"prebuilt": {
|
||||||
"version": "2023-04-12",
|
"version": "2023-11-03",
|
||||||
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
|
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
|
||||||
"label": "Pre-Built obs-deps",
|
"label": "Pre-Built obs-deps",
|
||||||
"hashes": {
|
"hashes": {
|
||||||
"macos": "9535c6e1ad96f7d49960251e85a245774088d48da1d602bb82f734b10219125a",
|
"macos": "90c2fc069847ec2768dcc867c1c63b112c615ed845a907dc44acab7a97181974",
|
||||||
"windows-x64": "c13a14a1acc4224b21304d97b63da4121de1ed6981297e50496fbc474abc0503"
|
"windows-x64": "d0825a6fb65822c993a3059edfba70d72d2e632ef74893588cf12b1f0d329ce6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"qt6": {
|
"qt6": {
|
||||||
"version": "2023-04-12",
|
"version": "2023-11-03",
|
||||||
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
|
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
|
||||||
"label": "Pre-Built Qt6",
|
"label": "Pre-Built Qt6",
|
||||||
"hashes": {
|
"hashes": {
|
||||||
"macos": "eb7614544ab4f3d2c6052c797635602280ca5b028a6b987523d8484222ce45d1",
|
"macos": "ba4a7152848da0053f63427a2a2cb0a199af3992997c0db08564df6f48c9db98",
|
||||||
"windows-x64": "4d39364b8a8dee5aa24fcebd8440d5c22bb4551c6b440ffeacce7d61f2ed1add"
|
"windows-x64": "bc57dedf76b47119a6dce0435a2f21b35b08c8f2948b1cb34a157320f77732d1"
|
||||||
},
|
},
|
||||||
"debugSymbols": {
|
"debugSymbols": {
|
||||||
"windows-x64": "f34ee5067be19ed370268b15c53684b7b8aaa867dc800b68931df905d679e31f"
|
"windows-x64": "fd8ecd1d8cd2ef049d9f4d7fb5c134f784836d6020758094855dfa98bd025036"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,14 +8,11 @@ if(BUILD_OUT_OF_TREE)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Subfolder for advanced scene switcher plugins
|
|
||||||
set(_PLUGIN_FOLDER "adv-ss-plugins")
|
|
||||||
|
|
||||||
# --- MACOS section ---
|
# --- MACOS section ---
|
||||||
if(OS_MACOS)
|
if(OS_MACOS)
|
||||||
set(ADVSS_BUNDLE_DIR "advanced-scene-switcher.plugin")
|
set(ADVSS_BUNDLE_DIR "advanced-scene-switcher.plugin")
|
||||||
set(ADVSS_BUNDLE_MODULE_DIR "${ADVSS_BUNDLE_DIR}/Contents/MacOS")
|
set(ADVSS_BUNDLE_MODULE_DIR "${ADVSS_BUNDLE_DIR}/Contents/MacOS")
|
||||||
set(ADVSS_BUNDLE_PLUGIN_DIR ${ADVSS_BUNDLE_MODULE_DIR}/${_PLUGIN_FOLDER})
|
set(ADVSS_BUNDLE_PLUGIN_DIR ${ADVSS_BUNDLE_MODULE_DIR}/${ADVSS_PLUGIN_FOLDER})
|
||||||
|
|
||||||
function(install_advss_lib_helper target where)
|
function(install_advss_lib_helper target where)
|
||||||
install(
|
install(
|
||||||
@@ -60,10 +57,36 @@ if(OS_MACOS)
|
|||||||
${dep}_Development)
|
${dep}_Development)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(install_advss_plugin_dependency_file ${target} dep)
|
function(install_advss_plugin_dependency_file target dep)
|
||||||
target_sources(advanced-scene-switcher PRIVATE ${dep})
|
get_filename_component(_FILENAME ${dep} NAME)
|
||||||
set_source_files_properties(${dep} PROPERTIES MACOSX_PACKAGE_LOCATION
|
string(REGEX REPLACE "\\.[^.]*$" "" _FILENAMENOEXT ${_FILENAME})
|
||||||
${ADVSS_BUNDLE_PLUGIN_DIR})
|
set(_DEP_NAME "${target}-${_FILENAMENOEXT}")
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES "${dep}"
|
||||||
|
DESTINATION "${ADVSS_BUNDLE_PLUGIN_DIR}"
|
||||||
|
COMPONENT ${_DEP_NAME}_Runtime
|
||||||
|
DESTINATION "${ADVSS_BUNDLE_PLUGIN_DIR}"
|
||||||
|
COMPONENT ${_DEP_NAME}_Runtime
|
||||||
|
NAMELINK_COMPONENT ${_DEP_NAME}_Development)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES "${dep}"
|
||||||
|
DESTINATION "${ADVSS_BUNDLE_PLUGIN_DIR}"
|
||||||
|
COMPONENT obs_${_DEP_NAME}
|
||||||
|
EXCLUDE_FROM_ALL
|
||||||
|
DESTINATION "${ADVSS_BUNDLE_PLUGIN_DIR}"
|
||||||
|
COMPONENT obs_${_DEP_NAME}
|
||||||
|
EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${target}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND
|
||||||
|
"${CMAKE_COMMAND}" --install ${CMAKE_CURRENT_BINARY_DIR} --config
|
||||||
|
$<CONFIG> --prefix ${CMAKE_INSTALL_PREFIX} --component obs_${_DEP_NAME}
|
||||||
|
COMMENT "Installing ${_DEP_NAME} to OBS rundir\n"
|
||||||
|
VERBATIM)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# --- End of section ---
|
# --- End of section ---
|
||||||
@@ -128,8 +151,8 @@ else()
|
|||||||
|
|
||||||
function(install_advss_plugin target)
|
function(install_advss_plugin target)
|
||||||
plugin_install_helper(
|
plugin_install_helper(
|
||||||
"${target}" "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
"${target}" "${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
"${_PLUGIN_FOLDER}")
|
"${ADVSS_PLUGIN_FOLDER}")
|
||||||
if(NOT OS_WINDOWS)
|
if(NOT OS_WINDOWS)
|
||||||
set_target_properties(${target} PROPERTIES INSTALL_RPATH
|
set_target_properties(${target} PROPERTIES INSTALL_RPATH
|
||||||
"$ORIGIN:$ORIGIN/..")
|
"$ORIGIN:$ORIGIN/..")
|
||||||
@@ -143,12 +166,12 @@ else()
|
|||||||
${dep}
|
${dep}
|
||||||
RUNTIME
|
RUNTIME
|
||||||
DESTINATION
|
DESTINATION
|
||||||
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
"${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT
|
COMPONENT
|
||||||
${dep}_Runtime
|
${dep}_Runtime
|
||||||
LIBRARY
|
LIBRARY
|
||||||
DESTINATION
|
DESTINATION
|
||||||
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
"${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT
|
COMPONENT
|
||||||
${dep}_Runtime
|
${dep}_Runtime
|
||||||
NAMELINK_COMPONENT
|
NAMELINK_COMPONENT
|
||||||
@@ -159,13 +182,13 @@ else()
|
|||||||
${dep}
|
${dep}
|
||||||
RUNTIME
|
RUNTIME
|
||||||
DESTINATION
|
DESTINATION
|
||||||
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
"${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT
|
COMPONENT
|
||||||
obs_${dep}
|
obs_${dep}
|
||||||
EXCLUDE_FROM_ALL
|
EXCLUDE_FROM_ALL
|
||||||
LIBRARY
|
LIBRARY
|
||||||
DESTINATION
|
DESTINATION
|
||||||
"${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
"${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT
|
COMPONENT
|
||||||
obs_${dep}
|
obs_${dep}
|
||||||
EXCLUDE_FROM_ALL)
|
EXCLUDE_FROM_ALL)
|
||||||
@@ -188,18 +211,18 @@ else()
|
|||||||
|
|
||||||
install(
|
install(
|
||||||
FILES "${dep}"
|
FILES "${dep}"
|
||||||
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
DESTINATION "${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT ${_DEP_NAME}_Runtime
|
COMPONENT ${_DEP_NAME}_Runtime
|
||||||
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
DESTINATION "${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT ${_DEP_NAME}_Runtime
|
COMPONENT ${_DEP_NAME}_Runtime
|
||||||
NAMELINK_COMPONENT ${_DEP_NAME}_Development)
|
NAMELINK_COMPONENT ${_DEP_NAME}_Development)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
FILES "${dep}"
|
FILES "${dep}"
|
||||||
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
DESTINATION "${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT obs_${_DEP_NAME}
|
COMPONENT obs_${_DEP_NAME}
|
||||||
EXCLUDE_FROM_ALL
|
EXCLUDE_FROM_ALL
|
||||||
DESTINATION "${OBS_PLUGIN_DESTINATION}/${_PLUGIN_FOLDER}"
|
DESTINATION "${OBS_PLUGIN_DESTINATION}/${ADVSS_PLUGIN_FOLDER}"
|
||||||
COMPONENT obs_${_DEP_NAME}
|
COMPONENT obs_${_DEP_NAME}
|
||||||
EXCLUDE_FROM_ALL)
|
EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
@@ -309,7 +332,6 @@ function(install_advss_plugin_dependency)
|
|||||||
if(NOT PARSED_ARGS_TARGET)
|
if(NOT PARSED_ARGS_TARGET)
|
||||||
message(FATAL_ERROR "You must provide a target")
|
message(FATAL_ERROR "You must provide a target")
|
||||||
endif()
|
endif()
|
||||||
set(_PLUGIN_FOLDER "adv-ss-plugins")
|
|
||||||
foreach(_DEPENDENCY ${PARSED_ARGS_DEPENDENCIES})
|
foreach(_DEPENDENCY ${PARSED_ARGS_DEPENDENCIES})
|
||||||
if(EXISTS ${_DEPENDENCY})
|
if(EXISTS ${_DEPENDENCY})
|
||||||
install_advss_plugin_dependency_file(${PARSED_ARGS_TARGET} ${_DEPENDENCY})
|
install_advss_plugin_dependency_file(${PARSED_ARGS_TARGET} ${_DEPENDENCY})
|
||||||
|
|||||||
@@ -12,8 +12,14 @@ if(NOT DEFINED PLUGIN_BUILD_NUMBER AND EXISTS "${_BUILD_NUMBER_CACHE}")
|
|||||||
file(READ "${_BUILD_NUMBER_CACHE}" PLUGIN_BUILD_NUMBER)
|
file(READ "${_BUILD_NUMBER_CACHE}" PLUGIN_BUILD_NUMBER)
|
||||||
math(EXPR PLUGIN_BUILD_NUMBER "${PLUGIN_BUILD_NUMBER}+1")
|
math(EXPR PLUGIN_BUILD_NUMBER "${PLUGIN_BUILD_NUMBER}+1")
|
||||||
elseif(NOT DEFINED PLUGIN_BUILD_NUMBER)
|
elseif(NOT DEFINED PLUGIN_BUILD_NUMBER)
|
||||||
if($ENV{CI} AND $ENV{GITHUB_RUN_ID})
|
if($ENV{CI})
|
||||||
set(PLUGIN_BUILD_NUMBER "$ENV{GITHUB_RUN_ID}")
|
if($ENV{GITHUB_RUN_ID})
|
||||||
|
set(PLUGIN_BUILD_NUMBER "$ENV{GITHUB_RUN_ID}")
|
||||||
|
elseif($ENV{GITLAB_RUN_ID})
|
||||||
|
set(PLUGIN_BUILD_NUMBER "$ENV{GITLAB_RUN_ID}")
|
||||||
|
else()
|
||||||
|
set(PLUGIN_BUILD_NUMBER "1")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
set(PLUGIN_BUILD_NUMBER "1")
|
set(PLUGIN_BUILD_NUMBER "1")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -68,13 +68,21 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
||||||
|
# Disable warning for https://github.com/WarmUpTill/SceneSwitcher/issues/1091
|
||||||
|
add_compile_options(-Wno-error=psabi)
|
||||||
|
|
||||||
# Disable false-positive warning in GCC 12.1.0 and later
|
# Disable false-positive warning in GCC 12.1.0 and later
|
||||||
add_compile_options(-Wno-error=maybe-uninitialized)
|
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.1.0)
|
||||||
|
add_compile_options(-Wno-error=maybe-uninitialized)
|
||||||
|
add_compile_options(-Wno-error=stringop-overflow)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add warning for infinite recursion (added in GCC 12)
|
# Add warning for infinite recursion (added in GCC 12)
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0.0)
|
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0.0)
|
||||||
add_compile_options(-Winfinite-recursion)
|
add_compile_options(-Winfinite-recursion)
|
||||||
endif()
|
endif()
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||||
|
add_compile_options(-Wno-error=null-pointer-subtraction)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Enable compiler and build tracing (requires Ninja generator)
|
# Enable compiler and build tracing (requires Ninja generator)
|
||||||
|
|||||||
@@ -75,13 +75,12 @@ AdvSceneSwitcher.macroTab.edit.action="Aktions-Typ:"
|
|||||||
AdvSceneSwitcher.macroTab.add="Neues Makro hinzufügen"
|
AdvSceneSwitcher.macroTab.add="Neues Makro hinzufügen"
|
||||||
AdvSceneSwitcher.macroTab.name="Name:"
|
AdvSceneSwitcher.macroTab.name="Name:"
|
||||||
AdvSceneSwitcher.macroTab.run="Makro ausführen"
|
AdvSceneSwitcher.macroTab.run="Makro ausführen"
|
||||||
AdvSceneSwitcher.macroTab.runFail="Ausführen von \"%1\" fehlgeschlagen!\nEntweder ist eine der Aktionen fehlgeschlagen oder das Makro wird bereits ausgeführt."
|
AdvSceneSwitcher.macroTab.runFail="Ausführen von \"%1\" fehlgeschlagen!\nEntweder ist eine der Aktionen fehlgeschlagen oder das Makro wird bereits ausgeführt.\nSoll die aktuelle Ausführung gestoppt werden?"
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Parallel zu anderen Makros ausführen"
|
AdvSceneSwitcher.macroTab.runInParallel="Parallel zu anderen Makros ausführen"
|
||||||
AdvSceneSwitcher.macroTab.onChange="Nur bei Änderung ausführen"
|
AdvSceneSwitcher.macroTab.onChange="Nur bei Änderung ausführen"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
||||||
AdvSceneSwitcher.macroTab.defaultGroupName="Gruppe %1"
|
AdvSceneSwitcher.macroTab.defaultGroupName="Gruppe %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="Makro-Name existiert bereits"
|
AdvSceneSwitcher.macroTab.removeGroupPopup.text="Sicher, dass \"%1\" und alle zugehörigen Elemente gelöscht werden?"
|
||||||
AdvSceneSwitcher.macroTab.groupDeleteConfirm="Sicher, dass \"%1\" und alle zugehörigen Elemente gelöscht werden?"
|
|
||||||
AdvSceneSwitcher.macroTab.copy="Kopie des aktuellen Makros erstellen"
|
AdvSceneSwitcher.macroTab.copy="Kopie des aktuellen Makros erstellen"
|
||||||
AdvSceneSwitcher.macroTab.group="Ausgewählte Elemente gruppieren"
|
AdvSceneSwitcher.macroTab.group="Ausgewählte Elemente gruppieren"
|
||||||
AdvSceneSwitcher.macroTab.ungroup="Gruppierung ausgewählter Gruppen aufheben"
|
AdvSceneSwitcher.macroTab.ungroup="Gruppierung ausgewählter Gruppen aufheben"
|
||||||
@@ -160,7 +159,7 @@ AdvSceneSwitcher.condition.media.source="Quelle"
|
|||||||
AdvSceneSwitcher.condition.media.anyOnScene="Beliebige Medienquelle in"
|
AdvSceneSwitcher.condition.media.anyOnScene="Beliebige Medienquelle in"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="Alle Medienquellen in"
|
AdvSceneSwitcher.condition.media.allOnScene="Alle Medienquellen in"
|
||||||
AdvSceneSwitcher.condition.media.inconsistencyInfo="Leider verhalten sich nicht alle Medien-Quell-Typen gleich (z.B. Medien-Quelle vs. VLC-Video-Quelle \"Gestoppt\"-Status).\nBitte experimentieren, was in eurem Setup funktioniert!"
|
AdvSceneSwitcher.condition.media.inconsistencyInfo="Leider verhalten sich nicht alle Medien-Quell-Typen gleich (z.B. Medien-Quelle vs. VLC-Video-Quelle \"Gestoppt\"-Status).\nBitte experimentieren, was in eurem Setup funktioniert!"
|
||||||
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}Status ist{{states}}und{{timeRestrictions}}{{time}}"
|
AdvSceneSwitcher.condition.media.layout.legacy="{{sourceTypes}}{{mediaSources}}{{scenes}}{{checkTypes}}Status ist{{states}}und{{timeRestrictions}}{{time}}"
|
||||||
AdvSceneSwitcher.condition.video="Video"
|
AdvSceneSwitcher.condition.video="Video"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="entspricht genau"
|
AdvSceneSwitcher.condition.video.condition.match="entspricht genau"
|
||||||
AdvSceneSwitcher.condition.video.condition.differ="stimmt nicht überein"
|
AdvSceneSwitcher.condition.video.condition.differ="stimmt nicht überein"
|
||||||
@@ -288,8 +287,8 @@ AdvSceneSwitcher.condition.sceneOrder.entry="Auf{{scenes}}{{sources}}{{condition
|
|||||||
AdvSceneSwitcher.condition.hotkey="Hotkey"
|
AdvSceneSwitcher.condition.hotkey="Hotkey"
|
||||||
AdvSceneSwitcher.condition.hotkey.name="Makro-Trigger-Hotkey"
|
AdvSceneSwitcher.condition.hotkey.name="Makro-Trigger-Hotkey"
|
||||||
AdvSceneSwitcher.condition.hotkey.tip="Hinweis: Die Tastenkombinationen für diesen Hotkey können in den OBS-Einstellungen konfiguriert werden"
|
AdvSceneSwitcher.condition.hotkey.tip="Hinweis: Die Tastenkombinationen für diesen Hotkey können in den OBS-Einstellungen konfiguriert werden"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line1="Hotkey ist gedrückt"
|
AdvSceneSwitcher.condition.hotkey.entry.keyState="Hotkey ist{{keyState}}"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line2="Name: {{name}}"
|
AdvSceneSwitcher.condition.hotkey.entry.name="Name:{{name}}"
|
||||||
AdvSceneSwitcher.condition.replay="Replay Buffer"
|
AdvSceneSwitcher.condition.replay="Replay Buffer"
|
||||||
AdvSceneSwitcher.condition.replay.state.stopped="Replay Buffer gestoppt"
|
AdvSceneSwitcher.condition.replay.state.stopped="Replay Buffer gestoppt"
|
||||||
AdvSceneSwitcher.condition.replay.state.started="Replay Buffer gestartet"
|
AdvSceneSwitcher.condition.replay.state.started="Replay Buffer gestartet"
|
||||||
@@ -322,11 +321,8 @@ 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}}{{types}}"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="entspricht Transformation"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="entspricht Transformation"
|
AdvSceneSwitcher.condition.sceneTransform.condition.changed="hat sich geändert"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.changed="hat sich geändert"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
|
||||||
AdvSceneSwitcher.condition.transition="Übergang"
|
AdvSceneSwitcher.condition.transition="Übergang"
|
||||||
AdvSceneSwitcher.condition.transition.type.current="Aktueller Übergangstyp ist"
|
AdvSceneSwitcher.condition.transition.type.current="Aktueller Übergangstyp ist"
|
||||||
AdvSceneSwitcher.condition.transition.type.duration="Aktuelle Übergangsdauer beträgt"
|
AdvSceneSwitcher.condition.transition.type.duration="Aktuelle Übergangsdauer beträgt"
|
||||||
@@ -428,7 +424,6 @@ AdvSceneSwitcher.action.replay.saveWarn="Warnung: Ein zu häufiges Speichern kan
|
|||||||
AdvSceneSwitcher.action.replay.type.stop="Replay Buffer stoppen"
|
AdvSceneSwitcher.action.replay.type.stop="Replay Buffer stoppen"
|
||||||
AdvSceneSwitcher.action.replay.type.start="Replay Buffer starten"
|
AdvSceneSwitcher.action.replay.type.start="Replay Buffer starten"
|
||||||
AdvSceneSwitcher.action.replay.type.save="Replay Buffer speichern"
|
AdvSceneSwitcher.action.replay.type.save="Replay Buffer speichern"
|
||||||
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"
|
||||||
@@ -445,7 +440,7 @@ 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"
|
||||||
AdvSceneSwitcher.action.filter.type.settings="Einstellungen festlegen"
|
AdvSceneSwitcher.action.filter.type.settings="Einstellungen festlegen"
|
||||||
AdvSceneSwitcher.action.filter.entry="Auf{{sources}}{{actions}}{{filters}}{{filters}}{{refresh}}"
|
AdvSceneSwitcher.action.filter.entry="Auf{{sources}}{{actions}}{{filters}}{{filters}}{{refresh}}{{settingsButtons}}"
|
||||||
AdvSceneSwitcher.action.filter.getSettings="Aktuelle Einstellungen abfragen"
|
AdvSceneSwitcher.action.filter.getSettings="Aktuelle Einstellungen abfragen"
|
||||||
AdvSceneSwitcher.action.source="Quelle"
|
AdvSceneSwitcher.action.source="Quelle"
|
||||||
AdvSceneSwitcher.action.source.type.enable="Aktivieren"
|
AdvSceneSwitcher.action.source.type.enable="Aktivieren"
|
||||||
@@ -454,7 +449,6 @@ AdvSceneSwitcher.action.source.type.settings="Einstellungen festlegen"
|
|||||||
AdvSceneSwitcher.action.source.type.refreshSettings="Aktualisieren der Quelleneinstellungen"
|
AdvSceneSwitcher.action.source.type.refreshSettings="Aktualisieren der Quelleneinstellungen"
|
||||||
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.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"
|
||||||
@@ -471,7 +465,6 @@ 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}}{{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:"
|
||||||
@@ -502,7 +495,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}}{{action}}{{rotation}}{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="Auf{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"
|
||||||
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 +538,7 @@ AdvSceneSwitcher.action.sceneCollection="Szenensammlung"
|
|||||||
AdvSceneSwitcher.action.sceneCollection.entry="Aktive Szenensammlung umschalten auf {{sceneCollections}}"
|
AdvSceneSwitcher.action.sceneCollection.entry="Aktive Szenensammlung umschalten auf {{sceneCollections}}"
|
||||||
AdvSceneSwitcher.action.sceneCollection.warning="Hinweis: Alle danach folgenden Aktionen werden nicht ausgeführt, da durch die Änderung der Szenensammlung auch die Einstellungen des Szenenwechslers neu geladen werden.\nDie Szenensammlungsaktion wird ignoriert, solange das Einstellungsfenster geöffnet ist."
|
AdvSceneSwitcher.action.sceneCollection.warning="Hinweis: Alle danach folgenden Aktionen werden nicht ausgeführt, da durch die Änderung der Szenensammlung auch die Einstellungen des Szenenwechslers neu geladen werden.\nDie Szenensammlungsaktion wird ignoriert, solange das Einstellungsfenster geöffnet ist."
|
||||||
AdvSceneSwitcher.action.sequence="Sequenz"
|
AdvSceneSwitcher.action.sequence="Sequenz"
|
||||||
AdvSceneSwitcher.action.sequence.entry="Jedes Mal, wenn diese Aktion ausgeführt wird, wird das nächste Makro in der Liste ausgeführt (pausierte Makros werden ignoriert)"
|
; AdvSceneSwitcher.action.sequence.entry="Jedes Mal, wenn diese Aktion ausgeführt wird, wird das nächste Makro in der Liste ausgeführt (pausierte Makros werden ignoriert)"
|
||||||
AdvSceneSwitcher.action.sequence.status="Zuletzt ausgeführtes Makro: %1 - Nächstes auszuführendes Makro: %2"
|
AdvSceneSwitcher.action.sequence.status="Zuletzt ausgeführtes Makro: %1 - Nächstes auszuführendes Makro: %2"
|
||||||
AdvSceneSwitcher.action.sequence.status.none="keines"
|
AdvSceneSwitcher.action.sequence.status.none="keines"
|
||||||
AdvSceneSwitcher.action.sequence.restart="Neustart am Anfang, wenn das Ende der Liste erreicht ist"
|
AdvSceneSwitcher.action.sequence.restart="Neustart am Anfang, wenn das Ende der Liste erreicht ist"
|
||||||
@@ -571,6 +564,7 @@ AdvSceneSwitcher.action.variable.actionNoVariableSupport="Das Abrufen von Variab
|
|||||||
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.noSettingsButtons="Keine Buttons gefunden!"
|
||||||
|
|
||||||
; Transition Tab
|
; Transition Tab
|
||||||
AdvSceneSwitcher.transitionTab.title="Szenenübergänge"
|
AdvSceneSwitcher.transitionTab.title="Szenenübergänge"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
AdvSceneSwitcher.pluginName="Advanced Scene Switcher"
|
AdvSceneSwitcher.pluginName="Advanced Scene Switcher"
|
||||||
AdvSceneSwitcher.windowTitle="Advanced Scene Switcher"
|
AdvSceneSwitcher.windowTitle="Advanced Scene Switcher"
|
||||||
|
|
||||||
; General Tab
|
# General Tab
|
||||||
AdvSceneSwitcher.generalTab.title="General"
|
AdvSceneSwitcher.generalTab.title="General"
|
||||||
AdvSceneSwitcher.generalTab.status="Status"
|
AdvSceneSwitcher.generalTab.status="Status"
|
||||||
AdvSceneSwitcher.generalTab.status.hotkeytips="Hotkeys can be defined in the OBS settings"
|
AdvSceneSwitcher.generalTab.status.hotkeytips="Hotkeys can be defined in the OBS settings"
|
||||||
@@ -26,6 +26,10 @@ AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchToRandom="Switch to an
|
|||||||
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="Switch to:"
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="Switch to:"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.cooldown="After performing actions skip performing actions for"
|
AdvSceneSwitcher.generalTab.generalBehavior.cooldown="After performing actions skip performing actions for"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="During this time potential matches will be ignored!"
|
AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="During this time potential matches will be ignored!"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.logLevel="Log level:"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.logLevel.default="Default"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.logLevel.printActions="Log performed actions"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.logLevel.verbose="Verbose logging"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Enable verbose logging"
|
AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Enable verbose logging"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Save window position and size"
|
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Save window position and size"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="Show system tray notifications"
|
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="Show system tray notifications"
|
||||||
@@ -33,6 +37,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints"
|
|||||||
AdvSceneSwitcher.generalTab.generalBehavior.comboBoxFilterDisable="Disable filtering by typing in drop down menus"
|
AdvSceneSwitcher.generalTab.generalBehavior.comboBoxFilterDisable="Disable filtering by typing in drop down menus"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="Display warning if plugins cannot be loaded"
|
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="Display warning if plugins cannot be loaded"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
|
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="The plugin installation seems to be corrupted and might crash!\nPlease make sure the plugin was installed correctly!"
|
||||||
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
|
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
|
||||||
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
|
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
|
||||||
AdvSceneSwitcher.generalTab.priority="Priority"
|
AdvSceneSwitcher.generalTab.priority="Priority"
|
||||||
@@ -65,19 +70,67 @@ AdvSceneSwitcher.generalTab.transitionOverride="Set transition overrides"
|
|||||||
AdvSceneSwitcher.generalTab.adjustActiveTransitionType="Change active transition type"
|
AdvSceneSwitcher.generalTab.adjustActiveTransitionType="Change active transition type"
|
||||||
AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="At least one option must be enabled:\n\n - Use transition overrides\n\n - Change active transition type"
|
AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="At least one option must be enabled:\n\n - Use transition overrides\n\n - Change active transition type"
|
||||||
|
|
||||||
; Variables Tab
|
# Variables Tab
|
||||||
AdvSceneSwitcher.variableTab.title="Variables"
|
AdvSceneSwitcher.variableTab.title="Variables"
|
||||||
AdvSceneSwitcher.variableTab.help="Variables can be used in many places throughout the plugin.\n\nClick on the highlighted plus symbol to add a new variable."
|
AdvSceneSwitcher.variableTab.help="Variables can be used in many places throughout the plugin.\n\nClick on the highlighted plus symbol to add a new variable."
|
||||||
AdvSceneSwitcher.variableTab.tooltip.variableAddButton="Add new variable"
|
AdvSceneSwitcher.variableTab.variableAddButton.tooltip="Add new variable"
|
||||||
AdvSceneSwitcher.variableTab.tooltip.variableRemoveButton="Remove selected variables"
|
AdvSceneSwitcher.variableTab.variableRemoveButton.tooltip="Remove selected variables"
|
||||||
AdvSceneSwitcher.variableTab.header.name="Name"
|
AdvSceneSwitcher.variableTab.removeSingleVariablePopup.text="Are you sure you want to remove \"%1\"?"
|
||||||
AdvSceneSwitcher.variableTab.header.value="Value"
|
AdvSceneSwitcher.variableTab.removeMultipleVariablesPopup.text="Are you sure you want to remove %1 variables?"
|
||||||
AdvSceneSwitcher.variableTab.header.saveLoadBehavior="Save/Load behavior"
|
AdvSceneSwitcher.variableTab.name.header="Name"
|
||||||
AdvSceneSwitcher.variableTab.header.lastUse="Last used"
|
AdvSceneSwitcher.variableTab.value.header="Value"
|
||||||
AdvSceneSwitcher.variableTab.neverNused="Never"
|
AdvSceneSwitcher.variableTab.saveLoadBehavior.header="Save/Load behavior"
|
||||||
AdvSceneSwitcher.variableTab.lastUsed="%1 seconds ago"
|
AdvSceneSwitcher.variableTab.saveLoadBehavior.text.default="Default to \"%1\""
|
||||||
|
AdvSceneSwitcher.variableTab.lastUsed.header="Last used"
|
||||||
|
AdvSceneSwitcher.variableTab.lastUsed.text="%1 seconds ago"
|
||||||
|
AdvSceneSwitcher.variableTab.lastUsed.text.never="Never"
|
||||||
|
AdvSceneSwitcher.variableTab.lastChanged.header="Last changed"
|
||||||
|
AdvSceneSwitcher.variableTab.lastChanged.text="%1 seconds ago"
|
||||||
|
AdvSceneSwitcher.variableTab.lastChanged.text.none="No change since launch"
|
||||||
|
AdvSceneSwitcher.variableTab.lastChanged.tooltip="Times changed: %1\n\nPrevious value: %2"
|
||||||
|
|
||||||
; Macro Tab
|
# Action Queue Tab
|
||||||
|
AdvSceneSwitcher.actionQueueTab.title="Action Queues"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.help="Action queues are executed sequentially but in parallel to the reset of the macro system.\nThe first action added to the queue will be the first one to be processed.\n\nClick on the highlighted plus symbol to add a new queue."
|
||||||
|
AdvSceneSwitcher.actionQueueTab.queueAddButton.tooltip="Add new action queue"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.queueRemoveButton.tooltip="Remove selected action queues"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.name.header="Name"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.size.header="Size"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.isRunning.header="Is running"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.runOnStartup.header="Run on startup"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.yes="Yes"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.no="No"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.removeSingleQueuePopup.text="Are you sure you want to remove \"%1\"?"
|
||||||
|
AdvSceneSwitcher.actionQueueTab.removeMultipleQueuesPopup.text="Are you sure you want to remove %1 action queues?"
|
||||||
|
|
||||||
|
# Websocket Connections Tab
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.title="Websocket Connections"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.help="Websocket connections can be used to communicate with other OBS instances or programs.\n\nClick on the highlighted plus symbol to add a new connection."
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.websocketConnectionAddButton.tooltip="Add new webscoket connection"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.websocketConnectionRemoveButton.tooltip="Remove selected websocket connections"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.name.header="Name"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.address.header="Address"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.port.header="Port"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.protocol.header="Is using OBS protocol?"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.protocol.yes="Yes"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.protocol.no="No"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.removeSingleConnectionPopup.text="Are you sure you want to remove \"%1\"?"
|
||||||
|
AdvSceneSwitcher.websocketConnectionTab.removeMultipleConnectionsPopup.text="Are you sure you want to remove %1 connections?"
|
||||||
|
|
||||||
|
# Twitch Connections Tab
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.title="Twitch Connections"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.help="Twitch connections can be used to use Twitch events as triggers to execute actions or perform actions on the linked Twitch account.\n\nClick on the highlighted plus symbol to add a new connection."
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.twitchConnectionAddButton.tooltip.tooltip="Add new Twitch connection"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.twitchConnectionRemoveButton.tooltip="Remove selected Twitch connections"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.name.header="Name"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.isValid.header="Is valid?"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.permissionCount.header="Number of permissions"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.yes="Yes"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.no="No"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.removeSingleConnectionPopup.text="Are you sure you want to remove \"%1\"?"
|
||||||
|
AdvSceneSwitcher.twitchConnectionTab.removeMultipleConnectionsPopup.text="Are you sure you want to remove %1 Twitch connections?"
|
||||||
|
|
||||||
|
# Macro Tab
|
||||||
AdvSceneSwitcher.macroTab.title="Macro"
|
AdvSceneSwitcher.macroTab.title="Macro"
|
||||||
AdvSceneSwitcher.macroTab.macros="Macros"
|
AdvSceneSwitcher.macroTab.macros="Macros"
|
||||||
AdvSceneSwitcher.macroTab.priorityWarning="Note: It is recommended to configure macros to be the highest priority functionality.\nThis setting can be changed on the General tab."
|
AdvSceneSwitcher.macroTab.priorityWarning="Note: It is recommended to configure macros to be the highest priority functionality.\nThis setting can be changed on the General tab."
|
||||||
@@ -90,19 +143,21 @@ AdvSceneSwitcher.macroTab.edit.logic="Logic type:"
|
|||||||
AdvSceneSwitcher.macroTab.edit.condition="Condition type:"
|
AdvSceneSwitcher.macroTab.edit.condition="Condition type:"
|
||||||
AdvSceneSwitcher.macroTab.edit.action="Action type:"
|
AdvSceneSwitcher.macroTab.edit.action="Action type:"
|
||||||
AdvSceneSwitcher.macroTab.add="Add new macro"
|
AdvSceneSwitcher.macroTab.add="Add new macro"
|
||||||
|
AdvSceneSwitcher.macroTab.addGroup="Add new macro group"
|
||||||
AdvSceneSwitcher.macroTab.name="Name:"
|
AdvSceneSwitcher.macroTab.name="Name:"
|
||||||
AdvSceneSwitcher.macroTab.run="Run macro"
|
AdvSceneSwitcher.macroTab.run="Run macro"
|
||||||
AdvSceneSwitcher.macroTab.run.tooltip="Run all macro actions regardless of condition.\nIf else actions are available, hold Shift and click the button to execute them instead."
|
AdvSceneSwitcher.macroTab.run.tooltip="Run all macro actions regardless of condition.\nIf else actions are available, hold Shift and click the button to execute them instead."
|
||||||
AdvSceneSwitcher.macroTab.runElse="Run macro (else)"
|
AdvSceneSwitcher.macroTab.runElse="Run macro (else)"
|
||||||
AdvSceneSwitcher.macroTab.runFail="Running \"%1\" failed!\nEither one of the actions failed or the macro is running already."
|
AdvSceneSwitcher.macroTab.runFail="Running \"%1\" failed!\nEither one of the actions failed or the macro is running already.\nDo you want to stop it?"
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Run macro in parallel to other macros"
|
AdvSceneSwitcher.macroTab.runInParallel="Run macro in parallel to other macros"
|
||||||
AdvSceneSwitcher.macroTab.onChange="Perform actions only on condition change"
|
AdvSceneSwitcher.macroTab.onChange="Perform actions only on condition change"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.defaultGroupName="Group %1"
|
AdvSceneSwitcher.macroTab.defaultGroupName="Group %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="Macro name exists already"
|
AdvSceneSwitcher.macroTab.macroNameExists="The name \"%1\" is already used by a macro."
|
||||||
AdvSceneSwitcher.macroTab.groupDeleteConfirm="Are you sure you want to delete \"%1\" and all its elements?"
|
AdvSceneSwitcher.macroTab.groupNameExists="The name \"%1\" is already used by a macro group."
|
||||||
AdvSceneSwitcher.macroTab.deleteMultipleMacrosConfirmation="Are you sure you want to delete %1 macros?"
|
AdvSceneSwitcher.macroTab.removeSingleMacroPopup.text="Are you sure you want to remove \"%1\"?"
|
||||||
AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation="Are you sure you want to delete \"%1\"?"
|
AdvSceneSwitcher.macroTab.removeMultipleMacrosPopup.text="Are you sure you want to remove %1 macros/groups?"
|
||||||
|
AdvSceneSwitcher.macroTab.removeGroupPopup.text="Are you sure you want to remove \"%1\" group and all its elements?"
|
||||||
AdvSceneSwitcher.macroTab.contextMenuAdd="Add"
|
AdvSceneSwitcher.macroTab.contextMenuAdd="Add"
|
||||||
AdvSceneSwitcher.macroTab.copy="Duplicate Macro"
|
AdvSceneSwitcher.macroTab.copy="Duplicate Macro"
|
||||||
AdvSceneSwitcher.macroTab.group="Group Selected Macros"
|
AdvSceneSwitcher.macroTab.group="Group Selected Macros"
|
||||||
@@ -111,17 +166,30 @@ AdvSceneSwitcher.macroTab.rename="Rename"
|
|||||||
AdvSceneSwitcher.macroTab.remove="Remove"
|
AdvSceneSwitcher.macroTab.remove="Remove"
|
||||||
AdvSceneSwitcher.macroTab.export="Export"
|
AdvSceneSwitcher.macroTab.export="Export"
|
||||||
AdvSceneSwitcher.macroTab.export.info="Paste the string below into the import dialog to import the selected macros:"
|
AdvSceneSwitcher.macroTab.export.info="Paste the string below into the import dialog to import the selected macros:"
|
||||||
|
AdvSceneSwitcher.macroTab.export.usePlainText="Use plain text"
|
||||||
AdvSceneSwitcher.macroTab.import="Import"
|
AdvSceneSwitcher.macroTab.import="Import"
|
||||||
AdvSceneSwitcher.macroTab.import.info="Paste the export string into the below text box to import macros:"
|
AdvSceneSwitcher.macroTab.import.info="Paste the export string into the below text box to import macros:"
|
||||||
AdvSceneSwitcher.macroTab.import.invalid="Invalid import data provided!"
|
AdvSceneSwitcher.macroTab.import.invalid="Invalid import data provided!"
|
||||||
AdvSceneSwitcher.macroTab.import.nameConflict="Cannot continue importing macro \"%1\" as a macro with the same name already exists!\nDo you want to continue with the import of \"%2\" and choose a new name? (Will be skipped otherwise)"
|
AdvSceneSwitcher.macroTab.import.nameConflict="Cannot continue with import of \"%1\" as the name is already in use!\nDo want to choose a new name for the imported \"%2\"? (It will be skipped otherwise)"
|
||||||
AdvSceneSwitcher.macroTab.expandAll="Expand all"
|
AdvSceneSwitcher.macroTab.expandAll="Expand all"
|
||||||
AdvSceneSwitcher.macroTab.collapseAll="Collapse all"
|
AdvSceneSwitcher.macroTab.collapseAll="Collapse all"
|
||||||
AdvSceneSwitcher.macroTab.maximize="Maximize"
|
AdvSceneSwitcher.macroTab.maximize="Maximize"
|
||||||
AdvSceneSwitcher.macroTab.minimize="Minimize"
|
AdvSceneSwitcher.macroTab.minimize="Minimize"
|
||||||
|
AdvSceneSwitcher.macroTab.segment.useCustomLabel="Use custom label"
|
||||||
|
AdvSceneSwitcher.macroTab.segment.customLabelRename="Rename custom label"
|
||||||
|
AdvSceneSwitcher.macroTab.segment.defaultCustomLabel="My label"
|
||||||
|
AdvSceneSwitcher.macroTab.segment.setCustomLabel="Set label ..."
|
||||||
|
AdvSceneSwitcher.macroTab.segment.copy="Copy"
|
||||||
|
AdvSceneSwitcher.macroTab.segment.paste="Paste"
|
||||||
|
AdvSceneSwitcher.macroTab.segment.pasteAction="Paste as action"
|
||||||
|
AdvSceneSwitcher.macroTab.segment.pasteElseAction="Paste as else-action"
|
||||||
AdvSceneSwitcher.macroTab.highlightSettings="Visual settings"
|
AdvSceneSwitcher.macroTab.highlightSettings="Visual settings"
|
||||||
AdvSceneSwitcher.macroTab.hotkeySettings="Hotkey settings"
|
AdvSceneSwitcher.macroTab.hotkeySettings="Hotkey settings"
|
||||||
AdvSceneSwitcher.macroTab.generalSettings="General settings"
|
AdvSceneSwitcher.macroTab.generalSettings="General settings"
|
||||||
|
AdvSceneSwitcher.macroTab.inputSettings="Input settings"
|
||||||
|
AdvSceneSwitcher.macroTab.inputSettings.description="This section will allow you to specify variables, which will be treated as input parameters for the selected macro.\nWhen executing the macro using the \"Macro\" action type, you will have the option to set the values for those variables."
|
||||||
|
AdvSceneSwitcher.macroTab.inputSettings.invalid="<Invalid selection>"
|
||||||
|
AdvSceneSwitcher.macroTab.inputSettings.noInputs="No inputs are defined for the selected macro!\nOpen the settings of the macro to define inputs.\nThe settings button is highlighted above."
|
||||||
AdvSceneSwitcher.macroTab.dockSettings="Dock settings"
|
AdvSceneSwitcher.macroTab.dockSettings="Dock settings"
|
||||||
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros"
|
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros"
|
||||||
AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently"
|
AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently"
|
||||||
@@ -129,6 +197,7 @@ AdvSceneSwitcher.macroTab.highlightPerformedActions="Highlight recently performe
|
|||||||
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="Register hotkeys to control the pause state of new macros"
|
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="Register hotkeys to control the pause state of new macros"
|
||||||
AdvSceneSwitcher.macroTab.currentDisableHotkeys="Register hotkeys to control the pause state of selected macro"
|
AdvSceneSwitcher.macroTab.currentDisableHotkeys="Register hotkeys to control the pause state of selected macro"
|
||||||
AdvSceneSwitcher.macroTab.currentSkipExecutionOnStartup="Skip execution of actions of current macro on startup"
|
AdvSceneSwitcher.macroTab.currentSkipExecutionOnStartup="Skip execution of actions of current macro on startup"
|
||||||
|
AdvSceneSwitcher.macroTab.currentStopActionsIfNotDone="Stop and rerun actions of the currently selected macro, if the actions are still running, when a new execution is triggered"
|
||||||
AdvSceneSwitcher.macroTab.currentRegisterDock="Register dock widget to control the pause state of selected macro or run it manually"
|
AdvSceneSwitcher.macroTab.currentRegisterDock="Register dock widget to control the pause state of selected macro or run it manually"
|
||||||
AdvSceneSwitcher.macroTab.currentDockAddRunButton="Add button to run the macro"
|
AdvSceneSwitcher.macroTab.currentDockAddRunButton="Add button to run the macro"
|
||||||
AdvSceneSwitcher.macroTab.currentDockAddPauseButton="Add button to pause or unpause the macro"
|
AdvSceneSwitcher.macroTab.currentDockAddPauseButton="Add button to pause or unpause the macro"
|
||||||
@@ -165,7 +234,7 @@ AdvSceneSwitcher.macroTab.tooltip.elseActionTopButton="Move selected action to t
|
|||||||
AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton="Move selected action up in the else section"
|
AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton="Move selected action up in the else section"
|
||||||
AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton="Move selected action down in the else section"
|
AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton="Move selected action down in the else section"
|
||||||
AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton="Move selected action to the bottom in the else section"
|
AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton="Move selected action to the bottom in the else section"
|
||||||
AdvSceneSwitcher.macroTab.tooltip.openMacroPropertiesButton="Open macro properties"
|
AdvSceneSwitcher.macroTab.tooltip.openMacroSettingsButton="Open macro settings"
|
||||||
|
|
||||||
AdvSceneSwitcher.macroDock.pause="Pause"
|
AdvSceneSwitcher.macroDock.pause="Pause"
|
||||||
AdvSceneSwitcher.macroDock.unpause="Unpause"
|
AdvSceneSwitcher.macroDock.unpause="Unpause"
|
||||||
@@ -173,11 +242,11 @@ AdvSceneSwitcher.macroDock.run="Run"
|
|||||||
AdvSceneSwitcher.macroDock.statusLabel.true="Conditions are true."
|
AdvSceneSwitcher.macroDock.statusLabel.true="Conditions are true."
|
||||||
AdvSceneSwitcher.macroDock.statusLabel.false="Conditions are false."
|
AdvSceneSwitcher.macroDock.statusLabel.false="Conditions are false."
|
||||||
|
|
||||||
; Macro List
|
# Macro List
|
||||||
AdvSceneSwitcher.macroList.deleted="deleted"
|
AdvSceneSwitcher.macroList.deleted="deleted"
|
||||||
AdvSceneSwitcher.macroList.duplicate="\"%1\" is alreay selected!"
|
AdvSceneSwitcher.macroList.duplicate="\"%1\" is alreay selected!"
|
||||||
|
|
||||||
; Macro Logic
|
# Macro Logic
|
||||||
AdvSceneSwitcher.logic.none="Ignore entry"
|
AdvSceneSwitcher.logic.none="Ignore entry"
|
||||||
AdvSceneSwitcher.logic.and="And"
|
AdvSceneSwitcher.logic.and="And"
|
||||||
AdvSceneSwitcher.logic.or="Or"
|
AdvSceneSwitcher.logic.or="Or"
|
||||||
@@ -186,7 +255,8 @@ AdvSceneSwitcher.logic.orNot="Or not"
|
|||||||
AdvSceneSwitcher.logic.rootNone="If"
|
AdvSceneSwitcher.logic.rootNone="If"
|
||||||
AdvSceneSwitcher.logic.not="If not"
|
AdvSceneSwitcher.logic.not="If not"
|
||||||
|
|
||||||
; Macro Conditions
|
# Macro Conditions
|
||||||
|
AdvSceneSwitcher.condition.unknown="Unknown condition"
|
||||||
AdvSceneSwitcher.condition.audio="Audio"
|
AdvSceneSwitcher.condition.audio="Audio"
|
||||||
AdvSceneSwitcher.condition.audio.state.below="below"
|
AdvSceneSwitcher.condition.audio.state.below="below"
|
||||||
AdvSceneSwitcher.condition.audio.state.exact="exactly"
|
AdvSceneSwitcher.condition.audio.state.exact="exactly"
|
||||||
@@ -242,11 +312,14 @@ AdvSceneSwitcher.condition.file.entry.line1="{{fileType}}{{filePath}}{{condition
|
|||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Media"
|
AdvSceneSwitcher.condition.media="Media"
|
||||||
|
AdvSceneSwitcher.condition.media.checkType.state="State matches"
|
||||||
|
AdvSceneSwitcher.condition.media.checkType.time="Time restriction matches"
|
||||||
AdvSceneSwitcher.condition.media.source="Source"
|
AdvSceneSwitcher.condition.media.source="Source"
|
||||||
AdvSceneSwitcher.condition.media.anyOnScene="Any media source on"
|
AdvSceneSwitcher.condition.media.anyOnScene="Any media source on"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="All media sources on"
|
AdvSceneSwitcher.condition.media.allOnScene="All media sources on"
|
||||||
AdvSceneSwitcher.condition.media.inconsistencyInfo="Unfortunately not all media source types behave the same (e.g. Media Source vs. VLC Video Source \"Stopped\" state).\nSo please experiment what works for your setup!"
|
AdvSceneSwitcher.condition.media.inconsistencyInfo="Unfortunately not all media source types behave the same (e.g. Media Source vs. VLC Video Source \"Stopped\" state).\nSo please experiment what works for your setup!"
|
||||||
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}state is{{states}}and{{timeRestrictions}}{{time}}"
|
AdvSceneSwitcher.condition.media.layout="{{sourceTypes}}{{mediaSources}}{{scenes}}{{checkTypes}}{{states}}{{timeRestrictions}}{{time}}"
|
||||||
|
AdvSceneSwitcher.condition.media.layout.legacy="{{sourceTypes}}{{mediaSources}}{{scenes}}{{checkTypes}}state is{{states}}and{{timeRestrictions}}{{time}}"
|
||||||
AdvSceneSwitcher.condition.video="Video"
|
AdvSceneSwitcher.condition.video="Video"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="exactly matches"
|
AdvSceneSwitcher.condition.video.condition.match="exactly matches"
|
||||||
AdvSceneSwitcher.condition.video.condition.differ="does not match"
|
AdvSceneSwitcher.condition.video.condition.differ="does not match"
|
||||||
@@ -392,11 +465,16 @@ AdvSceneSwitcher.condition.source.type.settingsMatch="Settings match"
|
|||||||
AdvSceneSwitcher.condition.source.type.settingsChanged="Settings changed"
|
AdvSceneSwitcher.condition.source.type.settingsChanged="Settings changed"
|
||||||
AdvSceneSwitcher.condition.source.type.individualSettingMatches="Setting value matches"
|
AdvSceneSwitcher.condition.source.type.individualSettingMatches="Setting value matches"
|
||||||
AdvSceneSwitcher.condition.source.type.individualSettingChanged="Setting value changed"
|
AdvSceneSwitcher.condition.source.type.individualSettingChanged="Setting value changed"
|
||||||
|
AdvSceneSwitcher.condition.source.type.width="Width"
|
||||||
|
AdvSceneSwitcher.condition.source.type.height="Height"
|
||||||
|
AdvSceneSwitcher.condition.source.sizeCompare.less="Smaller than"
|
||||||
|
AdvSceneSwitcher.condition.source.sizeCompare.equal="Equals"
|
||||||
|
AdvSceneSwitcher.condition.source.sizeCompare.more="Bigger than"
|
||||||
AdvSceneSwitcher.condition.source.refresh="Refresh"
|
AdvSceneSwitcher.condition.source.refresh="Refresh"
|
||||||
AdvSceneSwitcher.condition.source.refreshTooltip="Repopulate the source settings selection with the settings of the source which's name matches the variable value."
|
AdvSceneSwitcher.condition.source.refreshTooltip="Repopulate the source settings selection with the settings of the source which's name matches the variable value."
|
||||||
AdvSceneSwitcher.condition.source.sceneVisibilityHint="Scene specific visibility can be checked using the \"Scene item visibility\" condition"
|
AdvSceneSwitcher.condition.source.sceneVisibilityHint="Scene specific visibility can be checked using the \"Scene item visibility\" condition"
|
||||||
AdvSceneSwitcher.condition.source.getSettings="Get current settings"
|
AdvSceneSwitcher.condition.source.getSettings="Get current settings"
|
||||||
AdvSceneSwitcher.condition.source.entry.line1="{{sources}}{{conditions}}{{settingSelection}}{{refresh}}"
|
AdvSceneSwitcher.condition.source.entry.line1="{{sources}}{{conditions}}{{settingSelection}}{{refresh}}{{sizeCompareMethods}}{{size}}"
|
||||||
AdvSceneSwitcher.condition.source.entry.line2="{{settings}}"
|
AdvSceneSwitcher.condition.source.entry.line2="{{settings}}"
|
||||||
AdvSceneSwitcher.condition.source.entry.line3="{{regex}}{{getSettings}}"
|
AdvSceneSwitcher.condition.source.entry.line3="{{regex}}{{getSettings}}"
|
||||||
AdvSceneSwitcher.condition.virtualCamera="Virtual camera"
|
AdvSceneSwitcher.condition.virtualCamera="Virtual camera"
|
||||||
@@ -423,10 +501,12 @@ AdvSceneSwitcher.condition.sceneOrder.type.position="Is at position"
|
|||||||
AdvSceneSwitcher.condition.sceneOrder.positionInfo="The position value starts at the bottom with 0 and increases by one for each scene item including the ones in scene groups"
|
AdvSceneSwitcher.condition.sceneOrder.positionInfo="The position value starts at the bottom with 0 and increases by one for each scene item including the ones in scene groups"
|
||||||
AdvSceneSwitcher.condition.sceneOrder.entry="On{{scenes}}{{sources}}{{conditions}}{{sources2}}{{position}}"
|
AdvSceneSwitcher.condition.sceneOrder.entry="On{{scenes}}{{sources}}{{conditions}}{{sources2}}{{position}}"
|
||||||
AdvSceneSwitcher.condition.hotkey="Hotkey"
|
AdvSceneSwitcher.condition.hotkey="Hotkey"
|
||||||
|
AdvSceneSwitcher.condition.hotkey.pressed="pressed"
|
||||||
|
AdvSceneSwitcher.condition.hotkey.released="released"
|
||||||
AdvSceneSwitcher.condition.hotkey.name="Macro trigger hotkey"
|
AdvSceneSwitcher.condition.hotkey.name="Macro trigger hotkey"
|
||||||
AdvSceneSwitcher.condition.hotkey.tip="Note: You can configure the keybindings for this hotkey in the OBS settings window"
|
AdvSceneSwitcher.condition.hotkey.tip="Note: You can configure the keybindings for this hotkey in the OBS settings window"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line1="Hotkey is pressed"
|
AdvSceneSwitcher.condition.hotkey.entry.keyState="Hotkey is{{keyState}}"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line2="Name:{{name}}"
|
AdvSceneSwitcher.condition.hotkey.entry.name="Name:{{name}}"
|
||||||
AdvSceneSwitcher.condition.replay="Replay buffer"
|
AdvSceneSwitcher.condition.replay="Replay buffer"
|
||||||
AdvSceneSwitcher.condition.replay.state.stopped="Replay buffer stopped"
|
AdvSceneSwitcher.condition.replay.state.stopped="Replay buffer stopped"
|
||||||
AdvSceneSwitcher.condition.replay.state.started="Replay buffer started"
|
AdvSceneSwitcher.condition.replay.state.started="Replay buffer started"
|
||||||
@@ -459,11 +539,17 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Next match at: %1"
|
|||||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}On repeat update selected date to repeat date"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}On repeat update selected date to repeat date"
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Scene item transform"
|
AdvSceneSwitcher.condition.sceneTransform="Scene item transform"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="On{{scenes}}{{sources}}{{types}}"
|
AdvSceneSwitcher.condition.sceneTransform.getCurrentValue="Get current value"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="matches transform"
|
AdvSceneSwitcher.condition.sceneTransform.settingsType.all="All"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.changed="has changed"
|
AdvSceneSwitcher.condition.sceneTransform.settingsType.single="Single"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="matches"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}}{{getSettings}}"
|
AdvSceneSwitcher.condition.sceneTransform.condition.changed="has changed"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.compare.less="less"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.compare.equal="equal"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.compare.more="larger than"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.entry="On{{scenes}}{{settingsType}}transform setting of{{sources}}{{conditions}}"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.entry.singleSettingCompare="{{setting}}{{compare}}{{singleSettingValue}}"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.entry.options="{{regex}}{{getSettings}}{{getCurrentValue}}"
|
||||||
AdvSceneSwitcher.condition.transition="Transition"
|
AdvSceneSwitcher.condition.transition="Transition"
|
||||||
AdvSceneSwitcher.condition.transition.type.current="Current transition type is"
|
AdvSceneSwitcher.condition.transition.type.current="Current transition type is"
|
||||||
AdvSceneSwitcher.condition.transition.type.duration="Current transition duration is"
|
AdvSceneSwitcher.condition.transition.type.duration="Current transition duration is"
|
||||||
@@ -531,7 +617,7 @@ AdvSceneSwitcher.condition.run="Run"
|
|||||||
AdvSceneSwitcher.condition.run.entry="Process exits before timeout of{{timeout}}seconds"
|
AdvSceneSwitcher.condition.run.entry="Process exits before timeout of{{timeout}}seconds"
|
||||||
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}Check for exit code{{exitCode}}"
|
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}Check for exit code{{exitCode}}"
|
||||||
AdvSceneSwitcher.condition.midi="MIDI"
|
AdvSceneSwitcher.condition.midi="MIDI"
|
||||||
AdvSceneSwitcher.condition.midi.entry="Mesasge was received from{{device}}which matches:"
|
AdvSceneSwitcher.condition.midi.entry="Message was received from{{device}}which matches:"
|
||||||
AdvSceneSwitcher.condition.midi.entry.listen="Set MIDI message selection to messages incoming on selected device:{{listenButton}}"
|
AdvSceneSwitcher.condition.midi.entry.listen="Set MIDI message selection to messages incoming on selected device:{{listenButton}}"
|
||||||
AdvSceneSwitcher.condition.display="Display"
|
AdvSceneSwitcher.condition.display="Display"
|
||||||
AdvSceneSwitcher.condition.display.type.displayName="Name of connected displays matches"
|
AdvSceneSwitcher.condition.display.type.displayName="Name of connected displays matches"
|
||||||
@@ -548,7 +634,7 @@ AdvSceneSwitcher.condition.slideshow.condition.slideChanged="Slide changed"
|
|||||||
AdvSceneSwitcher.condition.slideshow.condition.slideIndex="Current slide number is"
|
AdvSceneSwitcher.condition.slideshow.condition.slideIndex="Current slide number is"
|
||||||
AdvSceneSwitcher.condition.slideshow.condition.slidePath="Current slide path is"
|
AdvSceneSwitcher.condition.slideshow.condition.slidePath="Current slide path is"
|
||||||
AdvSceneSwitcher.condition.slideshow.updateIntervalTooltip="Information about the slide show status will only be updated based on the configured time between slides"
|
AdvSceneSwitcher.condition.slideshow.updateIntervalTooltip="Information about the slide show status will only be updated based on the configured time between slides"
|
||||||
AdvSceneSwitcher.condition.slideshow.entry="{{sources}}{{conditions}}{{index}}{{path}}"
|
AdvSceneSwitcher.condition.slideshow.entry="{{sources}}{{conditions}}{{index}}{{path}}{{regex}}"
|
||||||
AdvSceneSwitcher.condition.twitch="Twitch"
|
AdvSceneSwitcher.condition.twitch="Twitch"
|
||||||
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online="Stream went online"
|
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.online="Stream went online"
|
||||||
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.offline="Stream went offline"
|
AdvSceneSwitcher.condition.twitch.type.event.channel.stream.offline="Stream went offline"
|
||||||
@@ -600,6 +686,16 @@ AdvSceneSwitcher.condition.twitch.type.polling.channel.live="Stream is currently
|
|||||||
AdvSceneSwitcher.condition.twitch.type.polling.channel.title="Current title matches"
|
AdvSceneSwitcher.condition.twitch.type.polling.channel.title="Current title matches"
|
||||||
AdvSceneSwitcher.condition.twitch.type.polling.channel.category="Current category is"
|
AdvSceneSwitcher.condition.twitch.type.polling.channel.category="Current category is"
|
||||||
AdvSceneSwitcher.condition.twitch.type.chat.message="Chat message received"
|
AdvSceneSwitcher.condition.twitch.type.chat.message="Chat message received"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties="Chat message properties:"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.select="Select chat message property:"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.firstMessage="Is first message"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.emoteOnly="Is only using emotes"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.mod="Is moderator"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.subscriber="Is subscriber"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.turbo="Is Turbo user"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.displayName="Display name matches"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.loginName="User name matches"
|
||||||
|
AdvSceneSwitcher.condition.twitch.type.chat.properties.badge="User has badge"
|
||||||
AdvSceneSwitcher.condition.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!"
|
AdvSceneSwitcher.condition.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!"
|
||||||
AdvSceneSwitcher.condition.twitch.entry="Channel{{channel}}{{conditions}}{{pointsReward}}{{streamTitle}}{{regex}}{{category}}"
|
AdvSceneSwitcher.condition.twitch.entry="Channel{{channel}}{{conditions}}{{pointsReward}}{{streamTitle}}{{regex}}{{category}}"
|
||||||
AdvSceneSwitcher.condition.twitch.entry.account="Check using account{{account}}"
|
AdvSceneSwitcher.condition.twitch.entry.account="Check using account{{account}}"
|
||||||
@@ -611,8 +707,39 @@ AdvSceneSwitcher.condition.queue.type.stopped="Stopped"
|
|||||||
AdvSceneSwitcher.condition.queue.type.size="Size"
|
AdvSceneSwitcher.condition.queue.type.size="Size"
|
||||||
AdvSceneSwitcher.condition.queue.entry.startStop="Queue{{queues}}is{{conditions}}"
|
AdvSceneSwitcher.condition.queue.entry.startStop="Queue{{queues}}is{{conditions}}"
|
||||||
AdvSceneSwitcher.condition.queue.entry.size="Queue{{queues}}{{conditions}}is less than{{size}}"
|
AdvSceneSwitcher.condition.queue.entry.size="Queue{{queues}}{{conditions}}is less than{{size}}"
|
||||||
|
AdvSceneSwitcher.condition.clipboard="Clipboard"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.placeholder="Clipboard text"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.urlTooltip="Depending on the OS files might be represented as URLs also!"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.condition.changed="Clipboard content changed"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.condition.isText="Clipboard contains text"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.condition.isImage="Clipboard contains an image"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.condition.isURL="Clipboard contains an URL"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.condition.matches="Clipboard content matches"
|
||||||
|
AdvSceneSwitcher.condition.clipboard.condition.entry="{{conditions}}{{regex}}{{urlInfo}}"
|
||||||
|
AdvSceneSwitcher.condition.folder="Folder watch"
|
||||||
|
AdvSceneSwitcher.condition.folder.tooltip="This condition type will allow you to monitor the contents of a folder.\nNote that the monitoring will *not* recursively scan for changes in sub directories within directories of the selected folder!\nNote that if there are several changes during a short period of time, some of the changes might not emit this signal.\nHowever, the last change in the sequence of changes always will."
|
||||||
|
AdvSceneSwitcher.condition.folder.condition.any="Any change happened"
|
||||||
|
AdvSceneSwitcher.condition.folder.condition.fileAdd="A file was added"
|
||||||
|
AdvSceneSwitcher.condition.folder.condition.fileChange="A file was modified"
|
||||||
|
AdvSceneSwitcher.condition.folder.condition.fileRemove="A file was removed"
|
||||||
|
AdvSceneSwitcher.condition.folder.condition.folderAdd="A directory was added"
|
||||||
|
AdvSceneSwitcher.condition.folder.condition.folderRemove="A directory was removed"
|
||||||
|
AdvSceneSwitcher.condition.folder.entry="{{conditions}}in{{folder}}{{tooltip}}"
|
||||||
|
AdvSceneSwitcher.condition.folder.enableFilter="Only evaluate to true, if the changed path matches a patern"
|
||||||
|
AdvSceneSwitcher.condition.folder.entry.filter="{{filter}}{{regex}}"
|
||||||
|
AdvSceneSwitcher.condition.usb="USB"
|
||||||
|
AdvSceneSwitcher.condition.usb.description="A USB device matching the following properties is connected:"
|
||||||
|
AdvSceneSwitcher.condition.usb.vendorID="Vendor ID:"
|
||||||
|
AdvSceneSwitcher.condition.usb.productID="Product ID:"
|
||||||
|
AdvSceneSwitcher.condition.usb.busNumber="Bus Number:"
|
||||||
|
AdvSceneSwitcher.condition.usb.deviceAddress="Device Address:"
|
||||||
|
AdvSceneSwitcher.condition.usb.vendorName="Vendor Name:"
|
||||||
|
AdvSceneSwitcher.condition.usb.productName="Product Name:"
|
||||||
|
AdvSceneSwitcher.condition.usb.serialNumber="Serial Number:"
|
||||||
|
AdvSceneSwitcher.condition.noDevicesFoundWarning="No USB devices detected!\nThe plugin might not have the required permissions to check for USB devices."
|
||||||
|
|
||||||
; Macro Actions
|
# Macro Actions
|
||||||
|
AdvSceneSwitcher.action.unknown="Unknown action"
|
||||||
AdvSceneSwitcher.action.scene="Switch scene"
|
AdvSceneSwitcher.action.scene="Switch scene"
|
||||||
AdvSceneSwitcher.action.scene.type.program="Program"
|
AdvSceneSwitcher.action.scene.type.program="Program"
|
||||||
AdvSceneSwitcher.action.scene.type.preview="Preview"
|
AdvSceneSwitcher.action.scene.type.preview="Preview"
|
||||||
@@ -632,6 +759,8 @@ AdvSceneSwitcher.action.audio.type.sourceVolume="Set source volume"
|
|||||||
AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume"
|
AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume"
|
||||||
AdvSceneSwitcher.action.audio.type.syncOffset="Set sync offset"
|
AdvSceneSwitcher.action.audio.type.syncOffset="Set sync offset"
|
||||||
AdvSceneSwitcher.action.audio.type.monitor="Set audio monitoring"
|
AdvSceneSwitcher.action.audio.type.monitor="Set audio monitoring"
|
||||||
|
AdvSceneSwitcher.action.audio.type.enableOnTrack="Enable on audio track"
|
||||||
|
AdvSceneSwitcher.action.audio.type.disableOnTrack="Disable on audio track"
|
||||||
AdvSceneSwitcher.action.audio.type.balance="Set balance"
|
AdvSceneSwitcher.action.audio.type.balance="Set balance"
|
||||||
AdvSceneSwitcher.action.audio.balance.description="Move the slider in the direction of the audio channel you want to focus on."
|
AdvSceneSwitcher.action.audio.balance.description="Move the slider in the direction of the audio channel you want to focus on."
|
||||||
AdvSceneSwitcher.action.audio.fade.type.duration="over a duration of"
|
AdvSceneSwitcher.action.audio.fade.type.duration="over a duration of"
|
||||||
@@ -640,7 +769,7 @@ AdvSceneSwitcher.action.audio.fade.duration="{{fade}}Fade{{fadeTypes}}{{duration
|
|||||||
AdvSceneSwitcher.action.audio.fade.rate="{{fade}}Fade{{fadeTypes}}{{rate}}per second."
|
AdvSceneSwitcher.action.audio.fade.rate="{{fade}}Fade{{fadeTypes}}{{rate}}per second."
|
||||||
AdvSceneSwitcher.action.audio.fade.wait="Wait for fade to complete."
|
AdvSceneSwitcher.action.audio.fade.wait="Wait for fade to complete."
|
||||||
AdvSceneSwitcher.action.audio.fade.abort="Abort already active fade."
|
AdvSceneSwitcher.action.audio.fade.abort="Abort already active fade."
|
||||||
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{volumeDB}}{{percentDBToggle}}{{syncOffset}}{{monitorTypes}}"
|
AdvSceneSwitcher.action.audio.entry="{{actions}}{{audioSources}}{{volume}}{{volumeDB}}{{percentDBToggle}}{{syncOffset}}{{monitorTypes}}{{track}}"
|
||||||
AdvSceneSwitcher.action.recording="Recording"
|
AdvSceneSwitcher.action.recording="Recording"
|
||||||
AdvSceneSwitcher.action.recording.type.stop="Stop recording"
|
AdvSceneSwitcher.action.recording.type.stop="Stop recording"
|
||||||
AdvSceneSwitcher.action.recording.type.start="Start recording"
|
AdvSceneSwitcher.action.recording.type.start="Start recording"
|
||||||
@@ -654,10 +783,12 @@ AdvSceneSwitcher.action.recording.split.hint="Make sure to enable automatic file
|
|||||||
AdvSceneSwitcher.action.recording.entry="{{actions}}{{recordFolder}}{{recordFileFormat}}{{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="Warning: Saving too frequently might result in the replay buffer not actually being saved!"
|
AdvSceneSwitcher.action.replay.saveWarn="Warning: Saving too frequently might result in the replay buffer not actually being saved!"
|
||||||
|
AdvSceneSwitcher.action.replay.durationWarn="Warning: Changing the maximum replay time will only apply the next time the replay buffer is started!"
|
||||||
AdvSceneSwitcher.action.replay.type.stop="Stop replay buffer"
|
AdvSceneSwitcher.action.replay.type.stop="Stop replay buffer"
|
||||||
AdvSceneSwitcher.action.replay.type.start="Start replay buffer"
|
AdvSceneSwitcher.action.replay.type.start="Start replay buffer"
|
||||||
AdvSceneSwitcher.action.replay.type.save="Save replay buffer"
|
AdvSceneSwitcher.action.replay.type.save="Save replay buffer"
|
||||||
AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
AdvSceneSwitcher.action.replay.type.duration="Set maximum replay time"
|
||||||
|
AdvSceneSwitcher.action.replay.entry="{{actions}}{{duration}}"
|
||||||
AdvSceneSwitcher.action.streaming="Streaming"
|
AdvSceneSwitcher.action.streaming="Streaming"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Stop streaming"
|
AdvSceneSwitcher.action.streaming.type.stop="Stop streaming"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Start streaming"
|
AdvSceneSwitcher.action.streaming.type.start="Start streaming"
|
||||||
@@ -668,7 +799,8 @@ AdvSceneSwitcher.action.streaming.type.username="Set username"
|
|||||||
AdvSceneSwitcher.action.streaming.type.password="Set password"
|
AdvSceneSwitcher.action.streaming.type.password="Set password"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}"
|
||||||
AdvSceneSwitcher.action.run="Run"
|
AdvSceneSwitcher.action.run="Run"
|
||||||
AdvSceneSwitcher.action.run.entry.wait="{{wait}}Wait for process exit or at most {{timeout}}"
|
AdvSceneSwitcher.action.run.wait.entry="{{wait}}Wait for process exit or at most {{timeout}}{{waitHelp}}"
|
||||||
|
AdvSceneSwitcher.action.run.wait.help.tooltip="Note that macro properties won't work if you leave this unticked, as the process spawns detached from the rest of logic and there's no control over it."
|
||||||
AdvSceneSwitcher.action.sceneVisibility="Scene item visibility"
|
AdvSceneSwitcher.action.sceneVisibility="Scene item visibility"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.show="Show"
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Show"
|
||||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
|
||||||
@@ -681,9 +813,10 @@ AdvSceneSwitcher.action.filter.type.enable="Enable"
|
|||||||
AdvSceneSwitcher.action.filter.type.disable="Disable"
|
AdvSceneSwitcher.action.filter.type.disable="Disable"
|
||||||
AdvSceneSwitcher.action.filter.type.toggle="Toggle"
|
AdvSceneSwitcher.action.filter.type.toggle="Toggle"
|
||||||
AdvSceneSwitcher.action.filter.type.settings="Set settings"
|
AdvSceneSwitcher.action.filter.type.settings="Set settings"
|
||||||
|
AdvSceneSwitcher.action.filter.type.pressSettingsButton="Press settings button"
|
||||||
AdvSceneSwitcher.action.filter.refresh="Refresh"
|
AdvSceneSwitcher.action.filter.refresh="Refresh"
|
||||||
AdvSceneSwitcher.action.filter.refreshTooltip="Repopulate the filter settings selection with the settings of the filter which's name matches the variable value."
|
AdvSceneSwitcher.action.filter.refreshTooltip="Repopulate the filter settings selection with the settings of the filter which's name matches the variable value."
|
||||||
AdvSceneSwitcher.action.filter.entry="On{{sources}}{{actions}}{{filters}}{{refresh}}"
|
AdvSceneSwitcher.action.filter.entry="On{{sources}}{{actions}}{{filters}}{{refresh}}{{settingsButtons}}"
|
||||||
AdvSceneSwitcher.action.filter.entry.settings="{{settings}}{{settingsInputMethod}}{{settingValue}}{{tempVar}}"
|
AdvSceneSwitcher.action.filter.entry.settings="{{settings}}{{settingsInputMethod}}{{settingValue}}{{tempVar}}"
|
||||||
AdvSceneSwitcher.action.filter.getSettings="Get current settings"
|
AdvSceneSwitcher.action.filter.getSettings="Get current settings"
|
||||||
AdvSceneSwitcher.action.filter.inputMethod.individualManual="Set to fixed value"
|
AdvSceneSwitcher.action.filter.inputMethod.individualManual="Set to fixed value"
|
||||||
@@ -701,7 +834,6 @@ AdvSceneSwitcher.action.source.type.deinterlaceOrder="Set deinterlace field orde
|
|||||||
AdvSceneSwitcher.action.source.type.openInteractionDialog="Open interaction dialog"
|
AdvSceneSwitcher.action.source.type.openInteractionDialog="Open interaction dialog"
|
||||||
AdvSceneSwitcher.action.source.type.openFilterDialog="Open filter dialog"
|
AdvSceneSwitcher.action.source.type.openFilterDialog="Open filter dialog"
|
||||||
AdvSceneSwitcher.action.source.type.openPropertiesDialog="Open properties dialog"
|
AdvSceneSwitcher.action.source.type.openPropertiesDialog="Open properties dialog"
|
||||||
AdvSceneSwitcher.action.source.noSettingsButtons="No buttons found!"
|
|
||||||
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}{{refresh}}"
|
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}{{refresh}}"
|
||||||
AdvSceneSwitcher.action.source.entry.settings="{{settings}}{{settingsInputMethod}}{{settingValue}}{{tempVar}}"
|
AdvSceneSwitcher.action.source.entry.settings="{{settings}}{{settingsInputMethod}}{{settingValue}}{{tempVar}}"
|
||||||
AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI\nYou might be looking for \"Scene item visibility\""
|
AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI\nYou might be looking for \"Scene item visibility\""
|
||||||
@@ -739,12 +871,24 @@ AdvSceneSwitcher.action.macro="Macro"
|
|||||||
AdvSceneSwitcher.action.macro.type.pause="Pause"
|
AdvSceneSwitcher.action.macro.type.pause="Pause"
|
||||||
AdvSceneSwitcher.action.macro.type.unpause="Unpause"
|
AdvSceneSwitcher.action.macro.type.unpause="Unpause"
|
||||||
AdvSceneSwitcher.action.macro.type.resetCounter="Reset counter"
|
AdvSceneSwitcher.action.macro.type.resetCounter="Reset counter"
|
||||||
AdvSceneSwitcher.action.macro.type.run="Run actions"
|
AdvSceneSwitcher.action.macro.type.run="Run macro"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.conditions.ignore="Do not consider condition state"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.conditions.true="Only if conditions evaluate to true"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.conditions.false="Only if conditions evaluate to false"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.updateConditionMatchState="Reevaluate the condition state before executing this action"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.updateConditionMatchState.help="The plugin operates in phases:\n * The phase evaluating the macro conditions\n * The phase running macro actions\nMacros executed before this particular action might have side effects on the condition state of macros.\nCheck this option if you want those side effects to be taken into account when evaluating the condition state."
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.actionType.regular="actions"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.actionType.else="else-actions"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.skipWhenPaused="Skip execution when macro is paused"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.setInputs="Set inputs"
|
||||||
|
AdvSceneSwitcher.action.macro.type.run.setInputs.description="Input variables can be defined in the macro settings.\nDefining input variables will allow you to modify the values of variables before an action is executed."
|
||||||
AdvSceneSwitcher.action.macro.type.stop="Stop actions"
|
AdvSceneSwitcher.action.macro.type.stop="Stop actions"
|
||||||
AdvSceneSwitcher.action.macro.type.disableAction="Disable action"
|
AdvSceneSwitcher.action.macro.type.disableAction="Disable action"
|
||||||
AdvSceneSwitcher.action.macro.type.enableAction="Enable action"
|
AdvSceneSwitcher.action.macro.type.enableAction="Enable action"
|
||||||
AdvSceneSwitcher.action.macro.type.toggleAction="Toggle action"
|
AdvSceneSwitcher.action.macro.type.toggleAction="Toggle action"
|
||||||
AdvSceneSwitcher.action.macro.entry="{{actions}}{{actionIndex}}{{macros}}"
|
AdvSceneSwitcher.action.macro.entry.run="{{actions}}{{actionTypes}}of{{macros}}"
|
||||||
|
AdvSceneSwitcher.action.macro.entry.run.condition="{{conditionBehaviors}}of{{conditionMacros}}"
|
||||||
|
AdvSceneSwitcher.action.macro.entry.other="{{actions}}{{actionIndex}}{{macros}}"
|
||||||
AdvSceneSwitcher.action.pluginState="Plugin state"
|
AdvSceneSwitcher.action.pluginState="Plugin state"
|
||||||
AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin"
|
AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin"
|
||||||
AdvSceneSwitcher.action.pluginState.type.noMatch="Change the no-match behaviour:"
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Change the no-match behaviour:"
|
||||||
@@ -785,7 +929,8 @@ AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom"
|
|||||||
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position"
|
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position"
|
||||||
AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}"
|
AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}"
|
||||||
AdvSceneSwitcher.action.sceneTransform="Scene item transform"
|
AdvSceneSwitcher.action.sceneTransform="Scene item transform"
|
||||||
AdvSceneSwitcher.action.sceneTransform.type.manual="Transform"
|
AdvSceneSwitcher.action.sceneTransform.type.manual="Set transform string"
|
||||||
|
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="Set transform setting"
|
||||||
AdvSceneSwitcher.action.sceneTransform.type.reset="Reset transform"
|
AdvSceneSwitcher.action.sceneTransform.type.reset="Reset transform"
|
||||||
AdvSceneSwitcher.action.sceneTransform.type.rotate="Rotate by"
|
AdvSceneSwitcher.action.sceneTransform.type.rotate="Rotate by"
|
||||||
AdvSceneSwitcher.action.sceneTransform.type.flipHorizontal="Flip horizontally"
|
AdvSceneSwitcher.action.sceneTransform.type.flipHorizontal="Flip horizontally"
|
||||||
@@ -796,7 +941,8 @@ AdvSceneSwitcher.action.sceneTransform.type.centerToScreen="Center to screen"
|
|||||||
AdvSceneSwitcher.action.sceneTransform.type.centerVertically="Center vertically"
|
AdvSceneSwitcher.action.sceneTransform.type.centerVertically="Center vertically"
|
||||||
AdvSceneSwitcher.action.sceneTransform.type.centerHorizontally="Center horizontally"
|
AdvSceneSwitcher.action.sceneTransform.type.centerHorizontally="Center horizontally"
|
||||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Get transform"
|
AdvSceneSwitcher.action.sceneTransform.getTransform="Get transform"
|
||||||
AdvSceneSwitcher.action.sceneTransform.entry="On{{scenes}}{{action}}{{rotation}}{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.getCurrentValue="Get current value"
|
||||||
|
AdvSceneSwitcher.action.sceneTransform.entry="On{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"
|
||||||
AdvSceneSwitcher.action.file="File"
|
AdvSceneSwitcher.action.file="File"
|
||||||
AdvSceneSwitcher.action.file.type.write="Write"
|
AdvSceneSwitcher.action.file.type.write="Write"
|
||||||
AdvSceneSwitcher.action.file.type.append="Append"
|
AdvSceneSwitcher.action.file.type.append="Append"
|
||||||
@@ -829,6 +975,7 @@ AdvSceneSwitcher.action.systray.title="Title:"
|
|||||||
AdvSceneSwitcher.action.systray.message="Message:"
|
AdvSceneSwitcher.action.systray.message="Message:"
|
||||||
AdvSceneSwitcher.action.systray.icon="Icon:"
|
AdvSceneSwitcher.action.systray.icon="Icon:"
|
||||||
AdvSceneSwitcher.action.systray.iconHint="Leave blank to use the default icon"
|
AdvSceneSwitcher.action.systray.iconHint="Leave blank to use the default icon"
|
||||||
|
AdvSceneSwitcher.action.systray.disabled="System tray notifications seem to be disabled in the OBS settings!"
|
||||||
AdvSceneSwitcher.action.screenshot="Screenshot"
|
AdvSceneSwitcher.action.screenshot="Screenshot"
|
||||||
AdvSceneSwitcher.action.screenshot.save.default="Default"
|
AdvSceneSwitcher.action.screenshot.save.default="Default"
|
||||||
AdvSceneSwitcher.action.screenshot.save.custom="Custom"
|
AdvSceneSwitcher.action.screenshot.save.custom="Custom"
|
||||||
@@ -888,7 +1035,13 @@ AdvSceneSwitcher.action.variable.type.sceneItemCount="Set to scene item count of
|
|||||||
AdvSceneSwitcher.action.variable.type.stringLength="Set to length of string"
|
AdvSceneSwitcher.action.variable.type.stringLength="Set to length of string"
|
||||||
AdvSceneSwitcher.action.variable.type.extractJson="Extract json field with name"
|
AdvSceneSwitcher.action.variable.type.extractJson="Extract json field with name"
|
||||||
AdvSceneSwitcher.action.variable.type.setToTempvar="Set to macro property"
|
AdvSceneSwitcher.action.variable.type.setToTempvar="Set to macro property"
|
||||||
|
AdvSceneSwitcher.action.variable.type.setToTempvar.help="This action type will allow you to extract values out of segments of the current macro and assign those values to the selected variable.\nFor example, you can get the current scene name from a scene condition and assign this name to a variable."
|
||||||
AdvSceneSwitcher.action.variable.type.sceneItemName="Set to scene item name at index"
|
AdvSceneSwitcher.action.variable.type.sceneItemName="Set to scene item name at index"
|
||||||
|
AdvSceneSwitcher.action.variable.type.padValue="Pad current value"
|
||||||
|
AdvSceneSwitcher.action.variable.type.truncateValue="Truncate current value"
|
||||||
|
AdvSceneSwitcher.action.variable.type.swapValues="Swap variable values"
|
||||||
|
AdvSceneSwitcher.action.variable.truncateOrPadDirection.left="Left"
|
||||||
|
AdvSceneSwitcher.action.variable.truncateOrPadDirection.right="Right"
|
||||||
AdvSceneSwitcher.action.variable.askForValuePromptDefault="Assign value to variable \"%1\":"
|
AdvSceneSwitcher.action.variable.askForValuePromptDefault="Assign value to variable \"%1\":"
|
||||||
AdvSceneSwitcher.action.variable.askForValuePrompt="Assign value to variable:"
|
AdvSceneSwitcher.action.variable.askForValuePrompt="Assign value to variable:"
|
||||||
AdvSceneSwitcher.action.variable.mathExpression.example="( 1 + 2 * 3 ) / 4"
|
AdvSceneSwitcher.action.variable.mathExpression.example="( 1 + 2 * 3 ) / 4"
|
||||||
@@ -900,7 +1053,9 @@ AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!"
|
|||||||
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!"
|
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!"
|
||||||
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!"
|
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!"
|
||||||
AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:"
|
AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:"
|
||||||
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}{{sceneItemIndex}}"
|
AdvSceneSwitcher.action.variable.entry.other="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}{{envVariableName}}{{scenes}}{{tempVars}}{{tempVarsHelp}}{{sceneItemIndex}}{{direction}}{{stringLength}}{{paddingCharSelection}}"
|
||||||
|
AdvSceneSwitcher.action.variable.entry.pad="{{actions}}of{{variables}}to length{{stringLength}}by adding{{paddingCharSelection}}to the{{direction}}"
|
||||||
|
AdvSceneSwitcher.action.variable.entry.truncate="{{actions}}of{{variables}}to length{{stringLength}}by removing characters from the{{direction}}"
|
||||||
AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}}Substring size:{{subStringSize}}"
|
AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}}Substring size:{{subStringSize}}"
|
||||||
AdvSceneSwitcher.action.variable.entry.substringRegex="Assign value of{{regexMatchIdx}}match using regular expression:"
|
AdvSceneSwitcher.action.variable.entry.substringRegex="Assign value of{{regexMatchIdx}}match using regular expression:"
|
||||||
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{findRegex}}{{replaceStr}}"
|
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{findRegex}}{{replaceStr}}"
|
||||||
@@ -962,8 +1117,19 @@ AdvSceneSwitcher.action.queue.type.start="Start"
|
|||||||
AdvSceneSwitcher.action.queue.type.stop="Stop"
|
AdvSceneSwitcher.action.queue.type.stop="Stop"
|
||||||
AdvSceneSwitcher.action.queue.entry.add="{{actions}}actions of macro{{macros}}to queue{{queues}}"
|
AdvSceneSwitcher.action.queue.entry.add="{{actions}}actions of macro{{macros}}to queue{{queues}}"
|
||||||
AdvSceneSwitcher.action.queue.entry.other="{{actions}}queue{{queues}}"
|
AdvSceneSwitcher.action.queue.entry.other="{{actions}}queue{{queues}}"
|
||||||
|
AdvSceneSwitcher.action.window="Window"
|
||||||
|
AdvSceneSwitcher.action.window.type.setFocusWindow="Focus window"
|
||||||
|
AdvSceneSwitcher.action.window.type.setFocusWindow.limitation="The focus action can only be performed under certain circumstances"
|
||||||
|
AdvSceneSwitcher.action.window.type.setFocusWindow.limitation.details="At least one of the following conditions must be true:\n OBS is the foreground process.\n There is currently no foreground window, and thus no foreground process.\n OBS received the last input event."
|
||||||
|
AdvSceneSwitcher.action.window.type.maximizeWindow="Maximize window"
|
||||||
|
AdvSceneSwitcher.action.window.type.minimizeWindow="Minimize window"
|
||||||
|
AdvSceneSwitcher.action.window.type.closeWindow="Close window"
|
||||||
|
AdvSceneSwitcher.action.window.entry="{{actions}}{{windows}}{{regex}}"
|
||||||
|
AdvSceneSwitcher.action.log="Log"
|
||||||
|
AdvSceneSwitcher.action.log.placeholder="My log message!"
|
||||||
|
AdvSceneSwitcher.action.log.entry="Write to OBS log:{{logMessage}}"
|
||||||
|
|
||||||
; Hotkey
|
# Hotkey
|
||||||
AdvSceneSwitcher.hotkey.startSwitcherHotkey="Start the Advanced Scene Switcher"
|
AdvSceneSwitcher.hotkey.startSwitcherHotkey="Start the Advanced Scene Switcher"
|
||||||
AdvSceneSwitcher.hotkey.stopSwitcherHotkey="Stop the Advanced Scene Switcher"
|
AdvSceneSwitcher.hotkey.stopSwitcherHotkey="Stop the Advanced Scene Switcher"
|
||||||
AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Toggle Start/Stop for the Advanced Scene Switcher"
|
AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Toggle Start/Stop for the Advanced Scene Switcher"
|
||||||
@@ -990,6 +1156,11 @@ AdvSceneSwitcher.item.emptyName="Empty name not allowed!"
|
|||||||
AdvSceneSwitcher.item.nameNotAvailable="Name not available!"
|
AdvSceneSwitcher.item.nameNotAvailable="Name not available!"
|
||||||
AdvSceneSwitcher.item.nameReserved="Name reserved!"
|
AdvSceneSwitcher.item.nameReserved="Name reserved!"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.listControls.add="Add"
|
||||||
|
AdvSceneSwitcher.listControls.remove="Remove"
|
||||||
|
AdvSceneSwitcher.listControls.up="Up"
|
||||||
|
AdvSceneSwitcher.listControls.down="Down"
|
||||||
|
|
||||||
AdvSceneSwitcher.macroSegmentSelection.invalid="Invalid selection!"
|
AdvSceneSwitcher.macroSegmentSelection.invalid="Invalid selection!"
|
||||||
|
|
||||||
AdvSceneSwitcher.validation.text.maxLength="Only %1 characters are allowed in this field!"
|
AdvSceneSwitcher.validation.text.maxLength="Only %1 characters are allowed in this field!"
|
||||||
@@ -1004,6 +1175,7 @@ AdvSceneSwitcher.variable.save="Save / load behavior"
|
|||||||
AdvSceneSwitcher.variable.save.dontSave="Don't save variable value"
|
AdvSceneSwitcher.variable.save.dontSave="Don't save variable value"
|
||||||
AdvSceneSwitcher.variable.save.save="Save variable value"
|
AdvSceneSwitcher.variable.save.save="Save variable value"
|
||||||
AdvSceneSwitcher.variable.save.default="Set to value"
|
AdvSceneSwitcher.variable.save.default="Set to value"
|
||||||
|
AdvSceneSwitcher.variable.selectionDialog="Select variable:"
|
||||||
|
|
||||||
AdvSceneSwitcher.tooltip.availableVariables="Variables are supported, use ${VarName} to retrieve the value of VarName"
|
AdvSceneSwitcher.tooltip.availableVariables="Variables are supported, use ${VarName} to retrieve the value of VarName"
|
||||||
|
|
||||||
@@ -1034,6 +1206,7 @@ AdvSceneSwitcher.actionQueues.configure="Configure action queue settings"
|
|||||||
AdvSceneSwitcher.actionQueues.invalid="Invalid action queue selection"
|
AdvSceneSwitcher.actionQueues.invalid="Invalid action queue selection"
|
||||||
AdvSceneSwitcher.actionQueues.name="Name:"
|
AdvSceneSwitcher.actionQueues.name="Name:"
|
||||||
AdvSceneSwitcher.actionQueues.runOnStartup="Run action queue when starting the plugin"
|
AdvSceneSwitcher.actionQueues.runOnStartup="Run action queue when starting the plugin"
|
||||||
|
AdvSceneSwitcher.actionQueues.resolveVariablesOnAdd="Resolve variables when action is inserted into the queue"
|
||||||
AdvSceneSwitcher.actionQueues.running="Queue is running"
|
AdvSceneSwitcher.actionQueues.running="Queue is running"
|
||||||
AdvSceneSwitcher.actionQueues.stopped="Queue is stopped"
|
AdvSceneSwitcher.actionQueues.stopped="Queue is stopped"
|
||||||
AdvSceneSwitcher.actionQueues.start="Start action queue"
|
AdvSceneSwitcher.actionQueues.start="Start action queue"
|
||||||
@@ -1311,24 +1484,13 @@ AdvSceneSwitcher.tempVar.twitch.status.prediction.description="The status of the
|
|||||||
|
|
||||||
AdvSceneSwitcher.tempVar.twitch.id.goal="Goal ID"
|
AdvSceneSwitcher.tempVar.twitch.id.goal="Goal ID"
|
||||||
AdvSceneSwitcher.tempVar.twitch.type.goal="Goal type"
|
AdvSceneSwitcher.tempVar.twitch.type.goal="Goal type"
|
||||||
AdvSceneSwitcher.tempVar.twitch.type.goal.description="The type of goal. Possible values are:\n
|
AdvSceneSwitcher.tempVar.twitch.type.goal.description="The type of goal. Possible values are:\n follow — The goal is to increase followers.\n subscription — The goal is to increase subscriptions. This type shows the net increase or decrease in tier points associated with the subscriptions.\n subscription_count — The goal is to increase subscriptions. This type shows the net increase or decrease in the number of subscriptions.\n new_subscription — The goal is to increase subscriptions. This type shows only the net increase in tier points associated with the subscriptions (it does not account for users that unsubscribed since the goal started).\n new_subscription_count — The goal is to increase subscriptions. This type shows only the net increase in the number of subscriptions (it does not account for users that unsubscribed since the goal started)."
|
||||||
follow — The goal is to increase followers.\n
|
|
||||||
subscription — The goal is to increase subscriptions. This type shows the net increase or decrease in tier points associated with the subscriptions.\n
|
|
||||||
subscription_count — The goal is to increase subscriptions. This type shows the net increase or decrease in the number of subscriptions.\n
|
|
||||||
new_subscription — The goal is to increase subscriptions. This type shows only the net increase in tier points associated with the subscriptions (it does not account for users that unsubscribed since the goal started).\n
|
|
||||||
new_subscription_count — The goal is to increase subscriptions. This type shows only the net increase in the number of subscriptions (it does not account for users that unsubscribed since the goal started)."
|
|
||||||
AdvSceneSwitcher.tempVar.twitch.description.goal="Goal description"
|
AdvSceneSwitcher.tempVar.twitch.description.goal="Goal description"
|
||||||
AdvSceneSwitcher.tempVar.twitch.description.goal.description="A description of the goal, if specified. The description may contain a maximum of 40 characters."
|
AdvSceneSwitcher.tempVar.twitch.description.goal.description="A description of the goal, if specified. The description may contain a maximum of 40 characters."
|
||||||
AdvSceneSwitcher.tempVar.twitch.is_achieved.goal="Goal is achieved"
|
AdvSceneSwitcher.tempVar.twitch.is_achieved.goal="Goal is achieved"
|
||||||
AdvSceneSwitcher.tempVar.twitch.is_achieved.goal.description="A Boolean value that indicates whether the broadcaster achieved their goal. Is true if the goal was achieved; otherwise, false."
|
AdvSceneSwitcher.tempVar.twitch.is_achieved.goal.description="A Boolean value that indicates whether the broadcaster achieved their goal. Is true if the goal was achieved; otherwise, false."
|
||||||
AdvSceneSwitcher.tempVar.twitch.current_amount.goal="Goal current amount"
|
AdvSceneSwitcher.tempVar.twitch.current_amount.goal="Goal current amount"
|
||||||
AdvSceneSwitcher.tempVar.twitch.current_amount.goal.description="The goal's current value.\n
|
AdvSceneSwitcher.tempVar.twitch.current_amount.goal.description="The goal's current value.\nThe goal's type determines how this value is increased or decreased.\n If type is follow, this field is set to the broadcaster's current number of followers. This number increases with new followers and decreases when users unfollow the broadcaster.\n If type is subscription, this field is increased and decreased by the points value associated with the subscription tier. For example, if a tier-two subscription is worth 2 points, this field is increased or decreased by 2, not 1.\n If type is subscription_count, this field is increased by 1 for each new subscription and decreased by 1 for each user that unsubscribes.\n If type is new_subscription, this field is increased by the points value associated with the subscription tier. For example, if a tier-two subscription is worth 2 points, this field is increased by 2, not 1.\n If type is new_subscription_count, this field is increased by 1 for each new subscription."
|
||||||
The goal's type determines how this value is increased or decreased.\n
|
|
||||||
If type is follow, this field is set to the broadcaster's current number of followers. This number increases with new followers and decreases when users unfollow the broadcaster.\n
|
|
||||||
If type is subscription, this field is increased and decreased by the points value associated with the subscription tier. For example, if a tier-two subscription is worth 2 points, this field is increased or decreased by 2, not 1.\n
|
|
||||||
If type is subscription_count, this field is increased by 1 for each new subscription and decreased by 1 for each user that unsubscribes.\n
|
|
||||||
If type is new_subscription, this field is increased by the points value associated with the subscription tier. For example, if a tier-two subscription is worth 2 points, this field is increased by 2, not 1.\n
|
|
||||||
If type is new_subscription_count, this field is increased by 1 for each new subscription."
|
|
||||||
AdvSceneSwitcher.tempVar.twitch.target_amount.goal="Goal target amount"
|
AdvSceneSwitcher.tempVar.twitch.target_amount.goal="Goal target amount"
|
||||||
AdvSceneSwitcher.tempVar.twitch.target_amount.goal.description="The goal's target value. For example, if the broadcaster has 200 followers before creating the goal, and their goal is to double that number, this field is set to 400."
|
AdvSceneSwitcher.tempVar.twitch.target_amount.goal.description="The goal's target value. For example, if the broadcaster has 200 followers before creating the goal, and their goal is to double that number, this field is set to 400."
|
||||||
AdvSceneSwitcher.tempVar.twitch.started_at.goal="Goal start time"
|
AdvSceneSwitcher.tempVar.twitch.started_at.goal="Goal start time"
|
||||||
@@ -1518,9 +1680,13 @@ AdvSceneSwitcher.tempVar.twitch.user_login.removeMod.description="The user login
|
|||||||
AdvSceneSwitcher.tempVar.twitch.user_name.removeMod="User name"
|
AdvSceneSwitcher.tempVar.twitch.user_name.removeMod="User name"
|
||||||
AdvSceneSwitcher.tempVar.twitch.user_name.removeMod.description="The display name of the removed moderator."
|
AdvSceneSwitcher.tempVar.twitch.user_name.removeMod.description="The display name of the removed moderator."
|
||||||
|
|
||||||
AdvSceneSwitcher.tempVar.twitch.chatter="User login"
|
AdvSceneSwitcher.tempVar.twitch.user_login.chatReceive="User login"
|
||||||
AdvSceneSwitcher.tempVar.twitch.chatter.description="The user login of the person who sent the chat message."
|
AdvSceneSwitcher.tempVar.twitch.user_login.chatReceive.description="The user login of the person who sent the chat message."
|
||||||
AdvSceneSwitcher.tempVar.twitch.chat_message="Chat message"
|
AdvSceneSwitcher.tempVar.twitch.user_name.chatReceive="User name"
|
||||||
|
AdvSceneSwitcher.tempVar.twitch.user_name.chatReceive.description="The display name of the person who sent the chat message."
|
||||||
|
AdvSceneSwitcher.tempVar.twitch.chat_message.chatReceive="Chat message"
|
||||||
|
AdvSceneSwitcher.tempVar.twitch.badges.chatReceive="Chatter Badges"
|
||||||
|
AdvSceneSwitcher.tempVar.twitch.badges.chatReceive.description="A string describing the badges available to this user and their state.\nFor example: vip/1,subscriber/42,hype-train/1"
|
||||||
|
|
||||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_id.raid="Raid creator user ID"
|
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_id.raid="Raid creator user ID"
|
||||||
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_id.raid.description="The broadcaster ID that created the raid."
|
AdvSceneSwitcher.tempVar.twitch.from_broadcaster_user_id.raid.description="The broadcaster ID that created the raid."
|
||||||
@@ -1586,6 +1752,15 @@ AdvSceneSwitcher.tempVar.macro.matchedCount.description="The number of macros of
|
|||||||
|
|
||||||
AdvSceneSwitcher.tempVar.process.name="Process name"
|
AdvSceneSwitcher.tempVar.process.name="Process name"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.id="Process ID"
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.id.description="PID of the process assigned by the system."
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.exitCode="Process exit code"
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.exitCode.description="Numeric code with which the process exited. Usually 0 is positive and other values are error codes."
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.stream.output="Process standard output stream"
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.stream.output.description="Full standard output stream, usually numbered 1 and what you see in CLI after running the command."
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.stream.error="Process standard error stream"
|
||||||
|
AdvSceneSwitcher.tempVar.run.process.stream.error.description="Full standard error stream, usually numbered 2."
|
||||||
|
|
||||||
AdvSceneSwitcher.tempVar.recording.durationSeconds="Recording duration"
|
AdvSceneSwitcher.tempVar.recording.durationSeconds="Recording duration"
|
||||||
AdvSceneSwitcher.tempVar.recording.durationSeconds.description="Recording duration in seconds.\nThis value does not change while the recording is paused and will be reset to zero if the recording is stopped."
|
AdvSceneSwitcher.tempVar.recording.durationSeconds.description="Recording duration in seconds.\nThis value does not change while the recording is paused and will be reset to zero if the recording is stopped."
|
||||||
|
|
||||||
@@ -1617,6 +1792,44 @@ AdvSceneSwitcher.tempVar.streaming.keyframeInterval.description="Stream keyframe
|
|||||||
AdvSceneSwitcher.tempVar.streaming.durationSeconds="Stream duration"
|
AdvSceneSwitcher.tempVar.streaming.durationSeconds="Stream duration"
|
||||||
AdvSceneSwitcher.tempVar.streaming.durationSeconds.description="Seconds passed since the stream was started.\nThis value will be zero if the stream is stopped."
|
AdvSceneSwitcher.tempVar.streaming.durationSeconds.description="Seconds passed since the stream was started.\nThis value will be zero if the stream is stopped."
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.clipboard.text="Clipboard text"
|
||||||
|
AdvSceneSwitcher.tempVar.clipboard.text.description="The text contained in the clipboard.\nWill be empty if the clipboard does not contain text."
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.file.content="File content"
|
||||||
|
AdvSceneSwitcher.tempVar.file.date="File modification date"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.folder.newFiles="New files"
|
||||||
|
AdvSceneSwitcher.tempVar.folder.changedFiles="Changed files"
|
||||||
|
AdvSceneSwitcher.tempVar.folder.removedFiles="Removed files"
|
||||||
|
AdvSceneSwitcher.tempVar.folder.newDirs="New directories"
|
||||||
|
AdvSceneSwitcher.tempVar.folder.removedDirs="Removed directories"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.source.width="Source width"
|
||||||
|
AdvSceneSwitcher.tempVar.source.height="Source height"
|
||||||
|
AdvSceneSwitcher.tempVar.source.setting="Setting value"
|
||||||
|
AdvSceneSwitcher.tempVar.source.settings="Settings string"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.filter.setting="Setting value"
|
||||||
|
AdvSceneSwitcher.tempVar.filter.settings="Settings string"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.slideShow.index="Slide index"
|
||||||
|
AdvSceneSwitcher.tempVar.slideShow.index.description="The index of the slide currently being displayed.\nIf the index cannot be determined, -1 is returned."
|
||||||
|
AdvSceneSwitcher.tempVar.slideShow.path="Slide path"
|
||||||
|
AdvSceneSwitcher.tempVar.slideShow.path.description="The filesystem path of the slide currently being displayed."
|
||||||
|
AdvSceneSwitcher.tempVar.slideShow.fileName="Slide file name"
|
||||||
|
AdvSceneSwitcher.tempVar.slideShow.fileName.description="The name of file of the slide currently being displayed."
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.usb.vendorID="Vendor ID"
|
||||||
|
AdvSceneSwitcher.tempVar.usb.productID="Product ID"
|
||||||
|
AdvSceneSwitcher.tempVar.usb.busNumber="Bus Number"
|
||||||
|
AdvSceneSwitcher.tempVar.usb.deviceAddress="Device Address"
|
||||||
|
AdvSceneSwitcher.tempVar.usb.vendorName="Vendor Name"
|
||||||
|
AdvSceneSwitcher.tempVar.usb.productName="Product Name"
|
||||||
|
AdvSceneSwitcher.tempVar.usb.serialNumber="Serial Number"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.tempVar.transform.setting="Setting value"
|
||||||
|
AdvSceneSwitcher.tempVar.transform.settings="Settings string"
|
||||||
|
|
||||||
AdvSceneSwitcher.selectScene="--select scene--"
|
AdvSceneSwitcher.selectScene="--select scene--"
|
||||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||||
@@ -1642,10 +1855,41 @@ AdvSceneSwitcher.enterText="--enter text--"
|
|||||||
AdvSceneSwitcher.enterURL="--enter URL--"
|
AdvSceneSwitcher.enterURL="--enter URL--"
|
||||||
AdvSceneSwitcher.selectHotkey="--select hotkey--"
|
AdvSceneSwitcher.selectHotkey="--select hotkey--"
|
||||||
AdvSceneSwitcher.selectDisplay="--select display--"
|
AdvSceneSwitcher.selectDisplay="--select display--"
|
||||||
AdvSceneSwitcher.selectSetting="--select setting--"
|
|
||||||
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="invalid entries will not be saved"
|
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="invalid entries will not be saved"
|
||||||
AdvSceneSwitcher.selectWindowTip="Use \"OBS\" to specify OBS window\nUse \"Task Switching\"to specify ALT + TAB"
|
AdvSceneSwitcher.selectWindowTip="Use \"OBS\" to specify OBS window\nUse \"Task Switching\"to specify ALT + TAB"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.invalid=" (Invalid)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.bool=" (Bool)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.int=" (Int)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.float=" (Float)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.text=" (Text)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.path=" (Path)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.list=" (List)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.color=" (Color)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.button=" (Button)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.font=" (Font)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.font=" (Font)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.editableList=" (Editable list)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.frameRate=" (Frame rate)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.group=" (Group)"
|
||||||
|
AdvSceneSwitcher.settings.suffix.type.colorAlpha=" (Color alpha)"
|
||||||
|
AdvSceneSwitcher.setting.select="--select setting--"
|
||||||
|
AdvSceneSwitcher.setting.transform.alignment="Positional Alignment"
|
||||||
|
AdvSceneSwitcher.setting.transform.cropBottom="[Crop]Bottom"
|
||||||
|
AdvSceneSwitcher.setting.transform.cropLeft="[Crop]Left"
|
||||||
|
AdvSceneSwitcher.setting.transform.cropRight="[Crop]Right"
|
||||||
|
AdvSceneSwitcher.setting.transform.cropTop="[Crop]Top"
|
||||||
|
AdvSceneSwitcher.setting.transform.boundingBoxType="Bounding Box Type"
|
||||||
|
AdvSceneSwitcher.setting.transform.boundingBoxAlign="Alignment in Bounding Box"
|
||||||
|
AdvSceneSwitcher.setting.transform.boundingBoxSize="Bounding Box Size"
|
||||||
|
AdvSceneSwitcher.setting.transform.rotation="Rotation"
|
||||||
|
AdvSceneSwitcher.setting.transform.scale="Scale"
|
||||||
|
AdvSceneSwitcher.setting.transform.size="Size"
|
||||||
|
AdvSceneSwitcher.setting.transform.position="Position"
|
||||||
|
AdvSceneSwitcher.setting.transform.height="Height"
|
||||||
|
AdvSceneSwitcher.setting.transform.width="Width"
|
||||||
|
|
||||||
|
|
||||||
AdvSceneSwitcher.sceneItemSelection.configure="Configure scene item selection type"
|
AdvSceneSwitcher.sceneItemSelection.configure="Configure scene item selection type"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceName="Source name"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceName="Source name"
|
||||||
AdvSceneSwitcher.sceneItemSelection.type.sourceName.entry="{{nameConflictIndex}}{{sourceName}}"
|
AdvSceneSwitcher.sceneItemSelection.type.sourceName.entry="{{nameConflictIndex}}{{sourceName}}"
|
||||||
@@ -1689,8 +1933,48 @@ AdvSceneSwitcher.audio.monitor.none="Monitor Off"
|
|||||||
AdvSceneSwitcher.audio.monitor.monitorOnly="Monitor Only (mute output)"
|
AdvSceneSwitcher.audio.monitor.monitorOnly="Monitor Only (mute output)"
|
||||||
AdvSceneSwitcher.audio.monitor.both="Monitor and Output"
|
AdvSceneSwitcher.audio.monitor.both="Monitor and Output"
|
||||||
|
|
||||||
; Legacy tabs below - please don't waste your time adding translations for these :)
|
AdvSceneSwitcher.noSettingsButtons="No buttons found!"
|
||||||
; Transition Tab
|
|
||||||
|
AdvSceneSwitcher.clearBufferOnMatch="Clear message buffer when matching message was found"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.script.settings="Settings"
|
||||||
|
AdvSceneSwitcher.script.timeout="Script timeout:{{timeout}}"
|
||||||
|
|
||||||
|
# This secion is copied from the OBS locale files
|
||||||
|
|
||||||
|
# commonly shared locale
|
||||||
|
Browse="Browse"
|
||||||
|
Show="Show"
|
||||||
|
Hide="Hide"
|
||||||
|
|
||||||
|
|
||||||
|
# properties window
|
||||||
|
Basic.PropertiesWindow="Properties for '%1'"
|
||||||
|
Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselect: %2)"
|
||||||
|
Basic.PropertiesWindow.SelectColor="Select color"
|
||||||
|
Basic.PropertiesWindow.SelectFont="Select font"
|
||||||
|
Basic.PropertiesWindow.SelectFont.WindowTitle="Pick a Font"
|
||||||
|
Basic.PropertiesWindow.ConfirmTitle="Settings Changed"
|
||||||
|
Basic.PropertiesWindow.Confirm="There are unsaved changes. Do you want to keep them?"
|
||||||
|
Basic.PropertiesWindow.NoProperties="No properties available"
|
||||||
|
Basic.PropertiesWindow.AddFiles="Add Files"
|
||||||
|
Basic.PropertiesWindow.AddDir="Add Directory"
|
||||||
|
Basic.PropertiesWindow.AddURL="Add Path/URL"
|
||||||
|
Basic.PropertiesWindow.AddEditableListDir="Add directory to '%1'"
|
||||||
|
Basic.PropertiesWindow.AddEditableListFiles="Add files to '%1'"
|
||||||
|
Basic.PropertiesWindow.AddEditableListEntry="Add entry to '%1'"
|
||||||
|
Basic.PropertiesWindow.EditEditableListEntry="Edit entry from '%1'"
|
||||||
|
|
||||||
|
# properties view
|
||||||
|
Basic.PropertiesView.FPS.Simple="Simple FPS Values"
|
||||||
|
Basic.PropertiesView.FPS.Rational="Rational FPS Values"
|
||||||
|
Basic.PropertiesView.FPS.ValidFPSRanges="Valid FPS Ranges:"
|
||||||
|
Basic.PropertiesView.UrlButton.Text="Open this link in your default web browser?"
|
||||||
|
Basic.PropertiesView.UrlButton.Text.Url="URL: %1"
|
||||||
|
Basic.PropertiesView.UrlButton.OpenUrl="Open URL"
|
||||||
|
|
||||||
|
# Legacy tabs below - please don't waste your time adding translations for these :)
|
||||||
|
# Transition Tab
|
||||||
AdvSceneSwitcher.transitionTab.title="Transition"
|
AdvSceneSwitcher.transitionTab.title="Transition"
|
||||||
AdvSceneSwitcher.transitionTab.transitionForAToB="Use transition for automated scene switch from scene A to scene B"
|
AdvSceneSwitcher.transitionTab.transitionForAToB="Use transition for automated scene switch from scene A to scene B"
|
||||||
AdvSceneSwitcher.transitionTab.transitionsHelp="<html><head/><body><p>These settings <span style=\"font-style:italic;\">only</span> affect transitions caused by the scene switcher - Check out <a href=\"https://obsproject.com/forum/resources/transition-table.1174/\"><span style=\" text-decoration: underline; color:#268bd2;\">Transition Table</span></a> if you want to configure this for manual scene changes.<br/>Settings defined here take priority over transition settings configured elsewhere in the scene switcher.<br/><br/>Click the plus symbol below to add a new entry.</p></body></html>"
|
AdvSceneSwitcher.transitionTab.transitionsHelp="<html><head/><body><p>These settings <span style=\"font-style:italic;\">only</span> affect transitions caused by the scene switcher - Check out <a href=\"https://obsproject.com/forum/resources/transition-table.1174/\"><span style=\" text-decoration: underline; color:#268bd2;\">Transition Table</span></a> if you want to configure this for manual scene changes.<br/>Settings defined here take priority over transition settings configured elsewhere in the scene switcher.<br/><br/>Click the plus symbol below to add a new entry.</p></body></html>"
|
||||||
@@ -1701,7 +1985,7 @@ AdvSceneSwitcher.transitionTab.defaultTransitionsHelp="Click on the plus symbol
|
|||||||
AdvSceneSwitcher.transitionTab.defaultTransition.delay="Switch transition{{defTransitionDelay}}after scene change."
|
AdvSceneSwitcher.transitionTab.defaultTransition.delay="Switch transition{{defTransitionDelay}}after scene change."
|
||||||
AdvSceneSwitcher.transitionTab.defaultTransition.delay.help="The delay is used to avoid cancelled scene switches, which can happen if the transition type is changed while a transition is still ongoing."
|
AdvSceneSwitcher.transitionTab.defaultTransition.delay.help="The delay is used to avoid cancelled scene switches, which can happen if the transition type is changed while a transition is still ongoing."
|
||||||
|
|
||||||
; Pause Scenes Tab
|
# Pause Scenes Tab
|
||||||
AdvSceneSwitcher.pauseTab.title="Pause"
|
AdvSceneSwitcher.pauseTab.title="Pause"
|
||||||
AdvSceneSwitcher.pauseTab.pauseOnScene="Pause the Scene Switcher on scene"
|
AdvSceneSwitcher.pauseTab.pauseOnScene="Pause the Scene Switcher on scene"
|
||||||
AdvSceneSwitcher.pauseTab.pauseInFocus1="Pause the Scene Switcher when "
|
AdvSceneSwitcher.pauseTab.pauseInFocus1="Pause the Scene Switcher when "
|
||||||
@@ -1712,7 +1996,7 @@ AdvSceneSwitcher.pauseTab.pauseTargetAll="all"
|
|||||||
AdvSceneSwitcher.pauseTab.pauseEntry="Pause{{pauseTargets}}checks when{{pauseTypes}}{{scenes}}{{windows}}"
|
AdvSceneSwitcher.pauseTab.pauseEntry="Pause{{pauseTargets}}checks when{{pauseTypes}}{{scenes}}{{windows}}"
|
||||||
AdvSceneSwitcher.pauseTab.help="On this tab you can configure to pause individual switching methods if a scene is active or window is in focus.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.pauseTab.help="On this tab you can configure to pause individual switching methods if a scene is active or window is in focus.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Window Title Tab
|
# Window Title Tab
|
||||||
AdvSceneSwitcher.windowTitleTab.title="Title"
|
AdvSceneSwitcher.windowTitleTab.title="Title"
|
||||||
AdvSceneSwitcher.windowTitleTab.regexrDescription="<html><head/><body><p>Enter either direct window titles or valid regex. You can check syntax and matches for regular expressions using <a href=\"https://regexr.com\"><span style=\" text-decoration: underline; color:#268bd2;\">RegExr</span></a></p></body></html>"
|
AdvSceneSwitcher.windowTitleTab.regexrDescription="<html><head/><body><p>Enter either direct window titles or valid regex. You can check syntax and matches for regular expressions using <a href=\"https://regexr.com\"><span style=\" text-decoration: underline; color:#268bd2;\">RegExr</span></a></p></body></html>"
|
||||||
AdvSceneSwitcher.windowTitleTab.stayInFocus1="Ignore this window name"
|
AdvSceneSwitcher.windowTitleTab.stayInFocus1="Ignore this window name"
|
||||||
@@ -1724,14 +2008,14 @@ AdvSceneSwitcher.windowTitleTab.entry="{{windows}}{{scenes}}{{transitions}}{{ful
|
|||||||
AdvSceneSwitcher.windowTitleTab.windowsHelp="Switch scenes based on the window title of running applications.\nThe following additional conditions can be selected:\nThe window is Fullscreen\nThe window is maximized\nThe window is focused\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.windowTitleTab.windowsHelp="Switch scenes based on the window title of running applications.\nThe following additional conditions can be selected:\nThe window is Fullscreen\nThe window is maximized\nThe window is focused\n\nClick on the highlighted plus symbol to continue."
|
||||||
AdvSceneSwitcher.windowTitleTab.ignoreWindowsHelp="If a window title is ignored the scene switcher will act as if the previously selected window is still in focus.\nThis will allow you to avoid scene switches, if you frequently switch to a different window, which shall not trigger a scene change.\n\nChoose a window or enter a window title above and click on the plus symbol below to add it to the list."
|
AdvSceneSwitcher.windowTitleTab.ignoreWindowsHelp="If a window title is ignored the scene switcher will act as if the previously selected window is still in focus.\nThis will allow you to avoid scene switches, if you frequently switch to a different window, which shall not trigger a scene change.\n\nChoose a window or enter a window title above and click on the plus symbol below to add it to the list."
|
||||||
|
|
||||||
; Executable Tab
|
# Executable Tab
|
||||||
AdvSceneSwitcher.executableTab.title="Executable"
|
AdvSceneSwitcher.executableTab.title="Executable"
|
||||||
AdvSceneSwitcher.executableTab.implemented="Implemented by dasOven"
|
AdvSceneSwitcher.executableTab.implemented="Implemented by dasOven"
|
||||||
AdvSceneSwitcher.executableTab.requiresFocus="only if focused"
|
AdvSceneSwitcher.executableTab.requiresFocus="only if focused"
|
||||||
AdvSceneSwitcher.executableTab.entry="When{{processes}}is running switch to{{scenes}}using{{transitions}}{{requiresFocus}}"
|
AdvSceneSwitcher.executableTab.entry="When{{processes}}is running switch to{{scenes}}using{{transitions}}{{requiresFocus}}"
|
||||||
AdvSceneSwitcher.executableTab.help="This tab will allow you to automatically switch scenes if a process is running.\nThis can be useful in situations where the window name could change or is not known.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.executableTab.help="This tab will allow you to automatically switch scenes if a process is running.\nThis can be useful in situations where the window name could change or is not known.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Screen Region Tab
|
# Screen Region Tab
|
||||||
AdvSceneSwitcher.screenRegionTab.title="Region"
|
AdvSceneSwitcher.screenRegionTab.title="Region"
|
||||||
AdvSceneSwitcher.screenRegionTab.currentPosition="Cursor is currently at:"
|
AdvSceneSwitcher.screenRegionTab.currentPosition="Cursor is currently at:"
|
||||||
AdvSceneSwitcher.screenRegionTab.showGuideFrames="Show guide frames"
|
AdvSceneSwitcher.screenRegionTab.showGuideFrames="Show guide frames"
|
||||||
@@ -1740,7 +2024,7 @@ AdvSceneSwitcher.screenRegionTab.excludeScenes.None="No selection"
|
|||||||
AdvSceneSwitcher.screenRegionTab.entry="If cursor is in{{minX}}{{minY}}x{{maxX}}{{maxY}}switch to{{scenes}}using{{transitions}}unless in{{excludeScenes}}"
|
AdvSceneSwitcher.screenRegionTab.entry="If cursor is in{{minX}}{{minY}}x{{maxX}}{{maxY}}switch to{{scenes}}using{{transitions}}unless in{{excludeScenes}}"
|
||||||
AdvSceneSwitcher.screenRegionTab.help="This tab will allow you to automatically switch scenes based on the current position of your mouse cursor.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.screenRegionTab.help="This tab will allow you to automatically switch scenes based on the current position of your mouse cursor.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Media Tab
|
# Media Tab
|
||||||
AdvSceneSwitcher.mediaTab.title="Media"
|
AdvSceneSwitcher.mediaTab.title="Media"
|
||||||
AdvSceneSwitcher.mediaTab.implemented="Implemented by Exeldro"
|
AdvSceneSwitcher.mediaTab.implemented="Implemented by Exeldro"
|
||||||
AdvSceneSwitcher.mediaTab.states.none="None"
|
AdvSceneSwitcher.mediaTab.states.none="None"
|
||||||
@@ -1761,7 +2045,7 @@ AdvSceneSwitcher.mediaTab.timeRestriction.remainLonger="Time remaining longer"
|
|||||||
AdvSceneSwitcher.mediaTab.entry="When{{mediaSources}}state is{{states}}and{{timeRestrictions}}{{time}}switch to{{scenes}}using{{transitions}}"
|
AdvSceneSwitcher.mediaTab.entry="When{{mediaSources}}state is{{states}}and{{timeRestrictions}}{{time}}switch to{{scenes}}using{{transitions}}"
|
||||||
AdvSceneSwitcher.mediaTab.help="This tab will allow you to switch scenes based on the states of media sources.\nFor example, you can automatically switch back to the previous scene once the selected media sourced ended its playback.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.mediaTab.help="This tab will allow you to switch scenes based on the states of media sources.\nFor example, you can automatically switch back to the previous scene once the selected media sourced ended its playback.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; File Tab
|
# File Tab
|
||||||
AdvSceneSwitcher.fileTab.title="File"
|
AdvSceneSwitcher.fileTab.title="File"
|
||||||
AdvSceneSwitcher.fileTab.readWriteSceneFile="Read / write scene from / to file"
|
AdvSceneSwitcher.fileTab.readWriteSceneFile="Read / write scene from / to file"
|
||||||
AdvSceneSwitcher.fileTab.currentSceneOutputFile="Write the name of the current scene to this file:"
|
AdvSceneSwitcher.fileTab.currentSceneOutputFile="Write the name of the current scene to this file:"
|
||||||
@@ -1786,13 +2070,13 @@ AdvSceneSwitcher.fileTab.entry2="{{matchText}}"
|
|||||||
AdvSceneSwitcher.fileTab.entry3="{{useRegex}}{{checkModificationDate}}{{checkFileContent}}"
|
AdvSceneSwitcher.fileTab.entry3="{{useRegex}}{{checkModificationDate}}{{checkFileContent}}"
|
||||||
AdvSceneSwitcher.fileTab.help="This tab will allow you to automatically switch scenes based on the content of remote or local files.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.fileTab.help="This tab will allow you to automatically switch scenes based on the content of remote or local files.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Random Tab
|
# Random Tab
|
||||||
AdvSceneSwitcher.randomTab.title="Random"
|
AdvSceneSwitcher.randomTab.title="Random"
|
||||||
AdvSceneSwitcher.randomTab.randomDisabledWarning="Functionality disabled - To activate select \"If no switch condition is met switch to any scene in Random tab\" on General tab"
|
AdvSceneSwitcher.randomTab.randomDisabledWarning="Functionality disabled - To activate select \"If no switch condition is met switch to any scene in Random tab\" on General tab"
|
||||||
AdvSceneSwitcher.randomTab.entry="If no switch condition is met switch to{{scenes}}using{{transitions}}for{{delay}}"
|
AdvSceneSwitcher.randomTab.entry="If no switch condition is met switch to{{scenes}}using{{transitions}}for{{delay}}"
|
||||||
AdvSceneSwitcher.randomTab.help="The scene switcher will randomly choose an entry on this tab to switch to for the configured time.\nNote that the same entry will not be chosen twice in a row.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.randomTab.help="The scene switcher will randomly choose an entry on this tab to switch to for the configured time.\nNote that the same entry will not be chosen twice in a row.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Time Tab
|
# Time Tab
|
||||||
AdvSceneSwitcher.timeTab.title="Time"
|
AdvSceneSwitcher.timeTab.title="Time"
|
||||||
AdvSceneSwitcher.timeTab.anyDay="On any day"
|
AdvSceneSwitcher.timeTab.anyDay="On any day"
|
||||||
AdvSceneSwitcher.timeTab.mondays="Mondays"
|
AdvSceneSwitcher.timeTab.mondays="Mondays"
|
||||||
@@ -1807,14 +2091,14 @@ AdvSceneSwitcher.timeTab.afterstart.tip="The time relative to the start of strea
|
|||||||
AdvSceneSwitcher.timeTab.entry="{{triggers}}at{{time}}switch to{{scenes}}using{{transitions}}"
|
AdvSceneSwitcher.timeTab.entry="{{triggers}}at{{time}}switch to{{scenes}}using{{transitions}}"
|
||||||
AdvSceneSwitcher.timeTab.help="This tab will allow you to automatically switch to a different scene based on the current local time.\n\nNote that the scene switcher will only switch scenes at the exact time you specified.\nMake sure you have configured the priority settings on the General tab to your liking so the selected time point will not be missed due to other switching methods having a higher priority.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.timeTab.help="This tab will allow you to automatically switch to a different scene based on the current local time.\n\nNote that the scene switcher will only switch scenes at the exact time you specified.\nMake sure you have configured the priority settings on the General tab to your liking so the selected time point will not be missed due to other switching methods having a higher priority.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Idle Tab
|
# Idle Tab
|
||||||
AdvSceneSwitcher.idleTab.title="Idle"
|
AdvSceneSwitcher.idleTab.title="Idle"
|
||||||
AdvSceneSwitcher.idleTab.enable="Enable Idle Detection"
|
AdvSceneSwitcher.idleTab.enable="Enable Idle Detection"
|
||||||
AdvSceneSwitcher.idleTab.idleswitch="After{{duration}}of no keyboard or mouse inputs switch to scene{{scenes}}using the{{transitions}}"
|
AdvSceneSwitcher.idleTab.idleswitch="After{{duration}}of no keyboard or mouse inputs switch to scene{{scenes}}using the{{transitions}}"
|
||||||
AdvSceneSwitcher.idleTab.dontSwitchIfFocus1="Do not switch if"
|
AdvSceneSwitcher.idleTab.dontSwitchIfFocus1="Do not switch if"
|
||||||
AdvSceneSwitcher.idleTab.dontSwitchIfFocus2="is in focus"
|
AdvSceneSwitcher.idleTab.dontSwitchIfFocus2="is in focus"
|
||||||
|
|
||||||
; Scene Sequence Tab
|
# Scene Sequence Tab
|
||||||
AdvSceneSwitcher.sceneSequenceTab.title="Sequence"
|
AdvSceneSwitcher.sceneSequenceTab.title="Sequence"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.description="A sequence of automatic scene switches can be cancelled by either pausing/stopping the scene switcher or manually switching to a different scene"
|
AdvSceneSwitcher.sceneSequenceTab.description="A sequence of automatic scene switches can be cancelled by either pausing/stopping the scene switcher or manually switching to a different scene"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.save="Save scene sequences to file"
|
AdvSceneSwitcher.sceneSequenceTab.save="Save scene sequences to file"
|
||||||
@@ -1831,7 +2115,7 @@ AdvSceneSwitcher.sceneSequenceTab.extendEdit="Extend Sequence"
|
|||||||
AdvSceneSwitcher.sceneSequenceTab.extendEntry="After{{delay}}switch to{{scenes}}using{{transitions}}"
|
AdvSceneSwitcher.sceneSequenceTab.extendEntry="After{{delay}}switch to{{scenes}}using{{transitions}}"
|
||||||
AdvSceneSwitcher.sceneSequenceTab.help="This tab will allow you to automatically switch to a different scene if a scene was active for a configured period of time.\nFor example, you could automatically cycle back and forth between two scenes automatically.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.sceneSequenceTab.help="This tab will allow you to automatically switch to a different scene if a scene was active for a configured period of time.\nFor example, you could automatically cycle back and forth between two scenes automatically.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Audio Tab
|
# Audio Tab
|
||||||
AdvSceneSwitcher.audioTab.title="Audio"
|
AdvSceneSwitcher.audioTab.title="Audio"
|
||||||
AdvSceneSwitcher.audioTab.condition.above="above"
|
AdvSceneSwitcher.audioTab.condition.above="above"
|
||||||
AdvSceneSwitcher.audioTab.condition.below="below"
|
AdvSceneSwitcher.audioTab.condition.below="below"
|
||||||
@@ -1841,7 +2125,7 @@ AdvSceneSwitcher.audioTab.multiMatchfallbackCondition="If multiple entries match
|
|||||||
AdvSceneSwitcher.audioTab.multiMatchfallback="... for{{duration}}seconds switch to{{scenes}}using{{transitions}}"
|
AdvSceneSwitcher.audioTab.multiMatchfallback="... for{{duration}}seconds switch to{{scenes}}using{{transitions}}"
|
||||||
AdvSceneSwitcher.audioTab.help="This tab will allow you to switch scenes based on the volume of sources.\nFor example, you could automatically switch to a different scene if the volume of your microphone reaches a certain threshold.\n\nClick on the highlighted plus symbol to continue."
|
AdvSceneSwitcher.audioTab.help="This tab will allow you to switch scenes based on the volume of sources.\nFor example, you could automatically switch to a different scene if the volume of your microphone reaches a certain threshold.\n\nClick on the highlighted plus symbol to continue."
|
||||||
|
|
||||||
; Video Tab
|
# Video Tab
|
||||||
AdvSceneSwitcher.videoTab.title="Video"
|
AdvSceneSwitcher.videoTab.title="Video"
|
||||||
AdvSceneSwitcher.videoTab.getScreenshot="Get screenshot for selected entry"
|
AdvSceneSwitcher.videoTab.getScreenshot="Get screenshot for selected entry"
|
||||||
AdvSceneSwitcher.videoTab.getScreenshotHelp="Get Screenshot of the currently selected entry's video source and automatically set it as the target image"
|
AdvSceneSwitcher.videoTab.getScreenshotHelp="Get Screenshot of the currently selected entry's video source and automatically set it as the target image"
|
||||||
@@ -1854,7 +2138,7 @@ AdvSceneSwitcher.videoTab.ignoreInactiveSource="unless source is inactive"
|
|||||||
AdvSceneSwitcher.videoTab.entry="When{{videoSources}}{{condition}}{{filePath}}{{browseButton}}for{{duration}}switch to{{scenes}}using{{transitions}}{{ignoreInactiveSource}}"
|
AdvSceneSwitcher.videoTab.entry="When{{videoSources}}{{condition}}{{filePath}}{{browseButton}}for{{duration}}switch to{{scenes}}using{{transitions}}{{ignoreInactiveSource}}"
|
||||||
AdvSceneSwitcher.videoTab.help="<html><head/><body><p>This tab will allow you to switch scenes based on the current video output of selected sources.<br/>Make sure to check out <a href=\"https://obsproject.com/forum/resources/pixel-match-switcher.1202/\"><span style=\" text-decoration: underline; color:#268bd2;\">Pixel Match Switcher</span></a> for an even better implementation of this functionality.<br/><br/> Click on the highlighted plus symbol to continue.</p></body></html>"
|
AdvSceneSwitcher.videoTab.help="<html><head/><body><p>This tab will allow you to switch scenes based on the current video output of selected sources.<br/>Make sure to check out <a href=\"https://obsproject.com/forum/resources/pixel-match-switcher.1202/\"><span style=\" text-decoration: underline; color:#268bd2;\">Pixel Match Switcher</span></a> for an even better implementation of this functionality.<br/><br/> Click on the highlighted plus symbol to continue.</p></body></html>"
|
||||||
|
|
||||||
; Network Tab
|
# Network Tab
|
||||||
AdvSceneSwitcher.networkTab.title="Network"
|
AdvSceneSwitcher.networkTab.title="Network"
|
||||||
AdvSceneSwitcher.networkTab.description="This tab will allow you to remotely control the active scene of another OBS instance.\nPlease note that the scene names have to match exactly on all OBS instances."
|
AdvSceneSwitcher.networkTab.description="This tab will allow you to remotely control the active scene of another OBS instance.\nPlease note that the scene names have to match exactly on all OBS instances."
|
||||||
AdvSceneSwitcher.networkTab.warning="Running the server outside of a local network will allow third parties to read the active scene."
|
AdvSceneSwitcher.networkTab.warning="Running the server outside of a local network will allow third parties to read the active scene."
|
||||||
@@ -1879,7 +2163,7 @@ AdvSceneSwitcher.networkTab.client.status.connecting="Connecting"
|
|||||||
AdvSceneSwitcher.networkTab.client.status.connected="Connected"
|
AdvSceneSwitcher.networkTab.client.status.connected="Connected"
|
||||||
AdvSceneSwitcher.networkTab.client.reconnect="Force reconnect"
|
AdvSceneSwitcher.networkTab.client.reconnect="Force reconnect"
|
||||||
|
|
||||||
; Scene Group Tab
|
# Scene Group Tab
|
||||||
AdvSceneSwitcher.sceneGroupTab.title="Scene Group"
|
AdvSceneSwitcher.sceneGroupTab.title="Scene Group"
|
||||||
AdvSceneSwitcher.sceneGroupTab.list="Scene Groups"
|
AdvSceneSwitcher.sceneGroupTab.list="Scene Groups"
|
||||||
AdvSceneSwitcher.sceneGroupTab.edit="Edit Scene Groups"
|
AdvSceneSwitcher.sceneGroupTab.edit="Edit Scene Groups"
|
||||||
@@ -1899,7 +2183,7 @@ AdvSceneSwitcher.sceneGroupTab.exists="Scene Group or Scene name exists already"
|
|||||||
AdvSceneSwitcher.sceneGroupTab.help="Scene Groups can be selected as a target just like a regular scene.\n\nAs the name suggests a scene group is a collection of multiple scenes.\nThe scene group will advance through the list of its assigned scenes depending on the configured settings, which can be found on the right side.\n\nYou can configure the scene group to advance to the next scene in the list:\nAfter a number of times the scene group is selected as a target.\nAfter a certain amount of time has passed.\nOr randomly.\n\nFor example, a scene group containing the scenes ...\nScene 1\nScene 2\nScene 3 \n... will activate \"Scene 1\" the first time it is selected as a target.\nThe second time it will activate \"Scene 2\".\nThe remaining times \"Scene 3\" will be activated.\n\nClick the highlighted plus symbol below to add a new scene group."
|
AdvSceneSwitcher.sceneGroupTab.help="Scene Groups can be selected as a target just like a regular scene.\n\nAs the name suggests a scene group is a collection of multiple scenes.\nThe scene group will advance through the list of its assigned scenes depending on the configured settings, which can be found on the right side.\n\nYou can configure the scene group to advance to the next scene in the list:\nAfter a number of times the scene group is selected as a target.\nAfter a certain amount of time has passed.\nOr randomly.\n\nFor example, a scene group containing the scenes ...\nScene 1\nScene 2\nScene 3 \n... will activate \"Scene 1\" the first time it is selected as a target.\nThe second time it will activate \"Scene 2\".\nThe remaining times \"Scene 3\" will be activated.\n\nClick the highlighted plus symbol below to add a new scene group."
|
||||||
AdvSceneSwitcher.sceneGroupTab.scenes.help="Select the scene group you want to modify on the left.\n\nSelect a scene to add to this scene group by selecting the scene above and clicking the plus symbol below.\n\nA scene can be added multiple times to the same scene group."
|
AdvSceneSwitcher.sceneGroupTab.scenes.help="Select the scene group you want to modify on the left.\n\nSelect a scene to add to this scene group by selecting the scene above and clicking the plus symbol below.\n\nA scene can be added multiple times to the same scene group."
|
||||||
|
|
||||||
; Scene Trigger Tab
|
# Scene Trigger Tab
|
||||||
AdvSceneSwitcher.sceneTriggerTab.title="Scene Triggers"
|
AdvSceneSwitcher.sceneTriggerTab.title="Scene Triggers"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none="--select trigger--"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none="--select trigger--"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneActive="is active"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneActive="is active"
|
||||||
|
|||||||
@@ -72,11 +72,9 @@ AdvSceneSwitcher.macroTab.edit.action="Tipo de acción:"
|
|||||||
AdvSceneSwitcher.macroTab.add="Agregar nueva macro"
|
AdvSceneSwitcher.macroTab.add="Agregar nueva macro"
|
||||||
AdvSceneSwitcher.macroTab.name="Nombre:"
|
AdvSceneSwitcher.macroTab.name="Nombre:"
|
||||||
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
AdvSceneSwitcher.macroTab.run="Ejecutar macro"
|
||||||
AdvSceneSwitcher.macroTab.runFail="Error al ejecutar \"%1\" si se ha producido un error en una de las acciones o si la macro ya se está ejecutando."
|
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
AdvSceneSwitcher.macroTab.runInParallel="Ejecutar macro en paralelo a otras macros"
|
||||||
AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición"
|
AdvSceneSwitcher.macroTab.onChange="Realizar acciones solo en el cambio de condición"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="El nombre de la macro ya existe"
|
|
||||||
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
AdvSceneSwitcher.macroTab.copy="Crear copia"
|
||||||
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
AdvSceneSwitcher.macroTab.expandAll="Expandir todo"
|
||||||
AdvSceneSwitcher.macroTab.collapseAll="Contraer todo"
|
AdvSceneSwitcher.macroTab.collapseAll="Contraer todo"
|
||||||
@@ -130,7 +128,7 @@ 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"
|
||||||
AdvSceneSwitcher.condition.media.inconsistencyInfo="Desafortunadamente, no todos los tipos de fuentes de medios se comportan de la misma manera (p. ej., fuente de medios frente a estado \"Detenido\" de fuente de video VLC).\n¡Así que experimente lo que funciona para su configuración!"
|
AdvSceneSwitcher.condition.media.inconsistencyInfo="Desafortunadamente, no todos los tipos de fuentes de medios se comportan de la misma manera (p. ej., fuente de medios frente a estado \"Detenido\" de fuente de video VLC).\n¡Así que experimente lo que funciona para su configuración!"
|
||||||
AdvSceneSwitcher.condition.media.entry="El estado de{{sourceTypes}}{{mediaSources}}{{scenes}}es{{states}}y{{timeRestrictions}}{{time}}"
|
AdvSceneSwitcher.condition.media.layout.legacy="El estado de{{sourceTypes}}{{mediaSources}}{{scenes}}{{checkTypes}}es{{states}}y{{timeRestrictions}}{{time}}"
|
||||||
AdvSceneSwitcher.condition.video="Video"
|
AdvSceneSwitcher.condition.video="Video"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="coincide exactamente"
|
AdvSceneSwitcher.condition.video.condition.match="coincide exactamente"
|
||||||
AdvSceneSwitcher.condition.video.condition.differ="no coincide"
|
AdvSceneSwitcher.condition.video.condition.differ="no coincide"
|
||||||
@@ -240,8 +238,7 @@ AdvSceneSwitcher.condition.sceneOrder.entry="En{{scenes}}{{sources}}{{conditions
|
|||||||
AdvSceneSwitcher.condition.hotkey="Tecla de acceso rápido"
|
AdvSceneSwitcher.condition.hotkey="Tecla de acceso rápido"
|
||||||
AdvSceneSwitcher.condition.hotkey.name="Tecla de acceso directo de activación de macro"
|
AdvSceneSwitcher.condition.hotkey.name="Tecla de acceso directo de activación de macro"
|
||||||
AdvSceneSwitcher.condition.hotkey.tip="Nota: puede configurar las combinaciones de teclas para esta tecla de acceso rápido en la ventana de configuración de OBS"
|
AdvSceneSwitcher.condition.hotkey.tip="Nota: puede configurar las combinaciones de teclas para esta tecla de acceso rápido en la ventana de configuración de OBS"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line1="Se presiona la tecla de acceso rápido"
|
AdvSceneSwitcher.condition.hotkey.entry.name="Nombre:{{name}}"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line2="Nombre: {{name}}"
|
|
||||||
AdvSceneSwitcher.condition.replay="Búfer de reproducción"
|
AdvSceneSwitcher.condition.replay="Búfer de reproducción"
|
||||||
AdvSceneSwitcher.condition.replay.state.stopped="Búfer de reproducción detenido"
|
AdvSceneSwitcher.condition.replay.state.stopped="Búfer de reproducción detenido"
|
||||||
AdvSceneSwitcher.condition.replay.state.started="Búfer de reproducción iniciado"
|
AdvSceneSwitcher.condition.replay.state.started="Búfer de reproducción iniciado"
|
||||||
@@ -272,10 +269,7 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Próxima coincidencia en: %
|
|||||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha"
|
AdvSceneSwitcher.condition.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}}{{types}}"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="coincide con la transformación"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="coincide con la transformación"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
|
||||||
AdvSceneSwitcher.condition.transition="Transición"
|
AdvSceneSwitcher.condition.transition="Transición"
|
||||||
AdvSceneSwitcher.condition.transition.type.current="El tipo de transición actual es"
|
AdvSceneSwitcher.condition.transition.type.current="El tipo de transición actual es"
|
||||||
AdvSceneSwitcher.condition.transition.type.duration="La duración de la transición actual es"
|
AdvSceneSwitcher.condition.transition.type.duration="La duración de la transición actual es"
|
||||||
@@ -351,7 +345,6 @@ AdvSceneSwitcher.action.replay.saveWarn="Advertencia: ¡Guardar con demasiada fr
|
|||||||
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
|
AdvSceneSwitcher.action.replay.type.stop="Detener el búfer de reproducción"
|
||||||
AdvSceneSwitcher.action.replay.type.start="Iniciar búfer de reproducción"
|
AdvSceneSwitcher.action.replay.type.start="Iniciar búfer de reproducción"
|
||||||
AdvSceneSwitcher.action.replay.type.save="Guardar búfer de reproducción"
|
AdvSceneSwitcher.action.replay.type.save="Guardar búfer de reproducción"
|
||||||
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"
|
||||||
@@ -367,7 +360,7 @@ 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"
|
||||||
AdvSceneSwitcher.action.filter.type.settings="Establecer configuración"
|
AdvSceneSwitcher.action.filter.type.settings="Establecer configuración"
|
||||||
AdvSceneSwitcher.action.filter.entry="En{{sources}}{{actions}}{{filters}}{{refresh}}"
|
AdvSceneSwitcher.action.filter.entry="En{{sources}}{{actions}}{{filters}}{{refresh}}{{settingsButtons}}"
|
||||||
AdvSceneSwitcher.action.filter.getSettings="Obtener la configuración actual"
|
AdvSceneSwitcher.action.filter.getSettings="Obtener la configuración actual"
|
||||||
AdvSceneSwitcher.action.source="Fuente"
|
AdvSceneSwitcher.action.source="Fuente"
|
||||||
AdvSceneSwitcher.action.source.type.enable="Habilitar"
|
AdvSceneSwitcher.action.source.type.enable="Habilitar"
|
||||||
@@ -389,7 +382,6 @@ 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}}{{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:"
|
||||||
@@ -420,7 +412,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}}{{action}}{{rotation}}{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="En{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"
|
||||||
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"
|
||||||
@@ -456,7 +448,7 @@ AdvSceneSwitcher.action.sceneCollection="Colección de escenas"
|
|||||||
AdvSceneSwitcher.action.sceneCollection.entry="Cambiar la colección de escenas activa a {{sceneCollections}}"
|
AdvSceneSwitcher.action.sceneCollection.entry="Cambiar la colección de escenas activa a {{sceneCollections}}"
|
||||||
AdvSceneSwitcher.action.sceneCollection.warning="Nota: Cualquier acción posterior a esta no se ejecutará, ya que la colección de escenas cambiante también volverá a cargar la configuración del conmutador de escenas.\nLa acción de la colección de escenas se ignorará mientras se abra la ventana de configuración".
|
AdvSceneSwitcher.action.sceneCollection.warning="Nota: Cualquier acción posterior a esta no se ejecutará, ya que la colección de escenas cambiante también volverá a cargar la configuración del conmutador de escenas.\nLa acción de la colección de escenas se ignorará mientras se abra la ventana de configuración".
|
||||||
AdvSceneSwitcher.action.sequence="Secuencia"
|
AdvSceneSwitcher.action.sequence="Secuencia"
|
||||||
AdvSceneSwitcher.action.sequence.entry="Cada vez que se realiza esta acción, ejecute la siguiente macro de la lista (las macros en pausa se ignoran)"
|
; AdvSceneSwitcher.action.sequence.entry="Cada vez que se realiza esta acción, ejecute la siguiente macro de la lista (las macros en pausa se ignoran)"
|
||||||
AdvSceneSwitcher.action.sequence.status="Última macro ejecutada: %1 - Siguiente macro a ejecutar: %2"
|
AdvSceneSwitcher.action.sequence.status="Última macro ejecutada: %1 - Siguiente macro a ejecutar: %2"
|
||||||
AdvSceneSwitcher.action.sequence.status.none="ninguno"
|
AdvSceneSwitcher.action.sequence.status.none="ninguno"
|
||||||
AdvSceneSwitcher.action.sequence.restart="Reiniciar desde el principio una vez que se alcance el final de la lista"
|
AdvSceneSwitcher.action.sequence.restart="Reiniciar desde el principio una vez que se alcance el final de la lista"
|
||||||
|
|||||||
@@ -78,15 +78,13 @@ AdvSceneSwitcher.macroTab.edit.action="Type d'action :"
|
|||||||
AdvSceneSwitcher.macroTab.add="Ajouter une nouvelle macro"
|
AdvSceneSwitcher.macroTab.add="Ajouter une nouvelle macro"
|
||||||
AdvSceneSwitcher.macroTab.name="Nom :"
|
AdvSceneSwitcher.macroTab.name="Nom :"
|
||||||
AdvSceneSwitcher.macroTab.run="Exécuter la macro"
|
AdvSceneSwitcher.macroTab.run="Exécuter la macro"
|
||||||
AdvSceneSwitcher.macroTab.runFail="Échec de l'exécution de \"%1\" !\nSoit l'une des actions a échoué, soit la macro est déjà en cours d'exécution."
|
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Exécuter la macro en parallèle avec d'autres macros"
|
AdvSceneSwitcher.macroTab.runInParallel="Exécuter la macro en parallèle avec d'autres macros"
|
||||||
AdvSceneSwitcher.macroTab.onChange="Exécuter des actions uniquement en cas de changement de condition"
|
AdvSceneSwitcher.macroTab.onChange="Exécuter des actions uniquement en cas de changement de condition"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.defaultGroupName="Groupe %1"
|
AdvSceneSwitcher.macroTab.defaultGroupName="Groupe %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="Le nom de la macro existe déjà"
|
AdvSceneSwitcher.macroTab.removeSingleMacroPopup.text="Êtes-vous sûr de vouloir supprimer \"%1\" ?"
|
||||||
AdvSceneSwitcher.macroTab.groupDeleteConfirm="Êtes-vous sûr de vouloir supprimer \"%1\" et tous ses éléments ?"
|
AdvSceneSwitcher.macroTab.removeMultipleMacrosPopup.text="Êtes-vous sûr de vouloir supprimer %1 macros ?"
|
||||||
AdvSceneSwitcher.macroTab.deleteMultipleMacrosConfirmation="Êtes-vous sûr de vouloir supprimer %1 macros ?"
|
AdvSceneSwitcher.macroTab.removeGroupPopup.text="Êtes-vous sûr de vouloir supprimer \"%1\" et tous ses éléments ?"
|
||||||
AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation="Êtes-vous sûr de vouloir supprimer \"%1\" ?"
|
|
||||||
AdvSceneSwitcher.macroTab.contextMenuAdd="Ajouter"
|
AdvSceneSwitcher.macroTab.contextMenuAdd="Ajouter"
|
||||||
AdvSceneSwitcher.macroTab.copy="Dupliquer la macro"
|
AdvSceneSwitcher.macroTab.copy="Dupliquer la macro"
|
||||||
AdvSceneSwitcher.macroTab.group="Grouper les macros sélectionnées"
|
AdvSceneSwitcher.macroTab.group="Grouper les macros sélectionnées"
|
||||||
@@ -198,7 +196,7 @@ AdvSceneSwitcher.condition.media.source="Source"
|
|||||||
AdvSceneSwitcher.condition.media.anyOnScene="Toute source média sur la scène"
|
AdvSceneSwitcher.condition.media.anyOnScene="Toute source média sur la scène"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="Toutes les sources média sur la scène"
|
AdvSceneSwitcher.condition.media.allOnScene="Toutes les sources média sur la scène"
|
||||||
AdvSceneSwitcher.condition.media.inconsistencyInfo="Malheureusement, toutes les sources média ne se comportent pas de la même manière (par exemple, l'état \"Arrêté\" de la source Media par rapport à la source Vidéo VLC).\nPar conséquent, veuillez expérimenter ce qui fonctionne le mieux pour votre configuration !"
|
AdvSceneSwitcher.condition.media.inconsistencyInfo="Malheureusement, toutes les sources média ne se comportent pas de la même manière (par exemple, l'état \"Arrêté\" de la source Media par rapport à la source Vidéo VLC).\nPar conséquent, veuillez expérimenter ce qui fonctionne le mieux pour votre configuration !"
|
||||||
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}l'état est{{states}}et{{timeRestrictions}}{{time}}"
|
AdvSceneSwitcher.condition.media.layout.legacy="{{sourceTypes}}{{mediaSources}}{{scenes}}{{checkTypes}}l'état est{{states}}et{{timeRestrictions}}{{time}}"
|
||||||
AdvSceneSwitcher.condition.video="Vidéo"
|
AdvSceneSwitcher.condition.video="Vidéo"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="correspond exactement à"
|
AdvSceneSwitcher.condition.video.condition.match="correspond exactement à"
|
||||||
AdvSceneSwitcher.condition.video.condition.differ="ne correspond pas à"
|
AdvSceneSwitcher.condition.video.condition.differ="ne correspond pas à"
|
||||||
@@ -353,8 +351,7 @@ AdvSceneSwitcher.condition.sceneOrder.entry="Sur{{scenes}}{{sources}}{{condition
|
|||||||
AdvSceneSwitcher.condition.hotkey="Raccourci clavier"
|
AdvSceneSwitcher.condition.hotkey="Raccourci clavier"
|
||||||
AdvSceneSwitcher.condition.hotkey.name="Raccourci clavier de déclenchement de macro"
|
AdvSceneSwitcher.condition.hotkey.name="Raccourci clavier de déclenchement de macro"
|
||||||
AdvSceneSwitcher.condition.hotkey.tip="Remarque : Vous pouvez configurer les raccourcis clavier pour ce raccourci dans la fenêtre de paramètres d'OBS"
|
AdvSceneSwitcher.condition.hotkey.tip="Remarque : Vous pouvez configurer les raccourcis clavier pour ce raccourci dans la fenêtre de paramètres d'OBS"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line1="Raccourci clavier est enfoncé"
|
AdvSceneSwitcher.condition.hotkey.entry.name="Nom:{{name}}"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line2="Nom :{{name}}"
|
|
||||||
AdvSceneSwitcher.condition.replay="Tampon de répétition"
|
AdvSceneSwitcher.condition.replay="Tampon de répétition"
|
||||||
AdvSceneSwitcher.condition.replay.state.stopped="Tampon de répétition arrêté"
|
AdvSceneSwitcher.condition.replay.state.stopped="Tampon de répétition arrêté"
|
||||||
AdvSceneSwitcher.condition.replay.state.started="Tampon de répétition démarré"
|
AdvSceneSwitcher.condition.replay.state.started="Tampon de répétition démarré"
|
||||||
@@ -385,8 +382,7 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="Prochaine correspondance à
|
|||||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}À la répétition, mettre à jour la date sélectionnée pour la date de répétition"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}À la répétition, mettre à jour la date sélectionnée pour la date de répétition"
|
||||||
AdvSceneSwitcher.condition.sceneTransform="Transformation de l'élément de la scène"
|
AdvSceneSwitcher.condition.sceneTransform="Transformation de l'élément de la scène"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtenir la transformation"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtenir la transformation"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="Sur{{scenes}}{{sources}}{{types}}"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="correspond à la transformation"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="correspond à la transformation"
|
|
||||||
AdvSceneSwitcher.condition.transition="Transition"
|
AdvSceneSwitcher.condition.transition="Transition"
|
||||||
AdvSceneSwitcher.condition.transition.type.current="Le type de transition actuel est"
|
AdvSceneSwitcher.condition.transition.type.current="Le type de transition actuel est"
|
||||||
AdvSceneSwitcher.condition.transition.type.duration="La durée de la transition actuelle est"
|
AdvSceneSwitcher.condition.transition.type.duration="La durée de la transition actuelle est"
|
||||||
@@ -523,7 +519,7 @@ AdvSceneSwitcher.action.filter.type.enable="Activer"
|
|||||||
AdvSceneSwitcher.action.filter.type.disable="Désactiver"
|
AdvSceneSwitcher.action.filter.type.disable="Désactiver"
|
||||||
AdvSceneSwitcher.action.filter.type.toggle="Basculer"
|
AdvSceneSwitcher.action.filter.type.toggle="Basculer"
|
||||||
AdvSceneSwitcher.action.filter.type.settings="Définir les paramètres"
|
AdvSceneSwitcher.action.filter.type.settings="Définir les paramètres"
|
||||||
AdvSceneSwitcher.action.filter.entry="Sur{{sources}}{{actions}}{{filters}}{{refresh}}"
|
AdvSceneSwitcher.action.filter.entry="Sur{{sources}}{{actions}}{{filters}}{{refresh}}{{settingsButtons}}"
|
||||||
AdvSceneSwitcher.action.filter.getSettings="Obtenir les paramètres actuels"
|
AdvSceneSwitcher.action.filter.getSettings="Obtenir les paramètres actuels"
|
||||||
AdvSceneSwitcher.action.source="Source"
|
AdvSceneSwitcher.action.source="Source"
|
||||||
AdvSceneSwitcher.action.source.type.enable="Activer"
|
AdvSceneSwitcher.action.source.type.enable="Activer"
|
||||||
@@ -535,7 +531,6 @@ AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="Peut être utilisé
|
|||||||
AdvSceneSwitcher.action.source.type.deinterlaceMode="Définir le mode de désentrelacement"
|
AdvSceneSwitcher.action.source.type.deinterlaceMode="Définir le mode de désentrelacement"
|
||||||
AdvSceneSwitcher.action.source.type.deinterlaceOrder="Définir l'ordre de désentrelacement des champs"
|
AdvSceneSwitcher.action.source.type.deinterlaceOrder="Définir l'ordre de désentrelacement des champs"
|
||||||
AdvSceneSwitcher.action.source.type.openInteractionDialog="Ouvrir la boîte de dialogue d'interaction"
|
AdvSceneSwitcher.action.source.type.openInteractionDialog="Ouvrir la boîte de dialogue d'interaction"
|
||||||
AdvSceneSwitcher.action.source.noSettingsButtons="Aucun bouton trouvé !"
|
|
||||||
AdvSceneSwitcher.action.source.warning="Avertissement : Activer et désactiver les sources globalement ne peut pas être contrôlé par l'interface utilisateur d'OBS\nVous pourriez rechercher \"Visibilité de l'élément de scène\""
|
AdvSceneSwitcher.action.source.warning="Avertissement : Activer et désactiver les sources globalement ne peut pas être contrôlé par l'interface utilisateur d'OBS\nVous pourriez rechercher \"Visibilité de l'élément de scène\""
|
||||||
AdvSceneSwitcher.action.source.getSettings="Obtenir les paramètres actuels"
|
AdvSceneSwitcher.action.source.getSettings="Obtenir les paramètres actuels"
|
||||||
AdvSceneSwitcher.action.source.deinterlaceMode.disable="Désactiver"
|
AdvSceneSwitcher.action.source.deinterlaceMode.disable="Désactiver"
|
||||||
@@ -615,7 +610,7 @@ AdvSceneSwitcher.action.sceneTransform.type.centerToScreen="Centrer à l'écran"
|
|||||||
AdvSceneSwitcher.action.sceneTransform.type.centerVertically="Centrer verticalement"
|
AdvSceneSwitcher.action.sceneTransform.type.centerVertically="Centrer verticalement"
|
||||||
AdvSceneSwitcher.action.sceneTransform.type.centerHorizontally="Centrer horizontalement"
|
AdvSceneSwitcher.action.sceneTransform.type.centerHorizontally="Centrer horizontalement"
|
||||||
AdvSceneSwitcher.action.sceneTransform.getTransform="Obtenir la transformation"
|
AdvSceneSwitcher.action.sceneTransform.getTransform="Obtenir la transformation"
|
||||||
AdvSceneSwitcher.action.sceneTransform.entry="Sur{{scenes}}{{action}}{{rotation}}{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="Sur{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"
|
||||||
AdvSceneSwitcher.action.file="Fichier"
|
AdvSceneSwitcher.action.file="Fichier"
|
||||||
AdvSceneSwitcher.action.file.type.write="Écrire"
|
AdvSceneSwitcher.action.file.type.write="Écrire"
|
||||||
AdvSceneSwitcher.action.file.type.append="Ajouter"
|
AdvSceneSwitcher.action.file.type.append="Ajouter"
|
||||||
@@ -661,7 +656,7 @@ AdvSceneSwitcher.action.sceneCollection="Collection de scènes"
|
|||||||
AdvSceneSwitcher.action.sceneCollection.entry="Changer la collection de scènes active vers{{sceneCollections}}"
|
AdvSceneSwitcher.action.sceneCollection.entry="Changer la collection de scènes active vers{{sceneCollections}}"
|
||||||
AdvSceneSwitcher.action.sceneCollection.warning="Note : Toutes les actions suivantes ne seront pas exécutées car le changement de collection de scènes rechargera également les paramètres du commutateur de scènes. L'action de collection de scènes sera ignorée lorsque la fenêtre des paramètres est ouverte."
|
AdvSceneSwitcher.action.sceneCollection.warning="Note : Toutes les actions suivantes ne seront pas exécutées car le changement de collection de scènes rechargera également les paramètres du commutateur de scènes. L'action de collection de scènes sera ignorée lorsque la fenêtre des paramètres est ouverte."
|
||||||
AdvSceneSwitcher.action.sequence="Séquence"
|
AdvSceneSwitcher.action.sequence="Séquence"
|
||||||
AdvSceneSwitcher.action.sequence.entry="Chaque fois que cette action est effectuée, exécutez le macro suivant dans la liste (les macros en pause sont ignorés)"
|
; AdvSceneSwitcher.action.sequence.entry="Chaque fois que cette action est effectuée, exécutez le macro suivant dans la liste (les macros en pause sont ignorés)"
|
||||||
AdvSceneSwitcher.action.sequence.status="Dernier macro exécuté : %1 - Prochain macro à exécuter : %2"
|
AdvSceneSwitcher.action.sequence.status="Dernier macro exécuté : %1 - Prochain macro à exécuter : %2"
|
||||||
AdvSceneSwitcher.action.sequence.status.none="aucun"
|
AdvSceneSwitcher.action.sequence.status.none="aucun"
|
||||||
AdvSceneSwitcher.action.sequence.restart="Recommencer depuis le début une fois la fin de la liste atteinte"
|
AdvSceneSwitcher.action.sequence.restart="Recommencer depuis le début une fois la fin de la liste atteinte"
|
||||||
@@ -740,6 +735,8 @@ AdvSceneSwitcher.action.twitch.type.channel.info.category.set="Définir la caté
|
|||||||
AdvSceneSwitcher.action.twitch.type.commercial.start="Démarrer une publicité d'une durée de"
|
AdvSceneSwitcher.action.twitch.type.commercial.start="Démarrer une publicité d'une durée de"
|
||||||
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Impossible de sélectionner une catégorie sans avoir d'abord sélectionné un compte Twitch !"
|
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Impossible de sélectionner une catégorie sans avoir d'abord sélectionné un compte Twitch !"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.noSettingsButtons="Aucun bouton trouvé !"
|
||||||
|
|
||||||
; Transition Tab
|
; Transition Tab
|
||||||
AdvSceneSwitcher.transitionTab.title="Transition"
|
AdvSceneSwitcher.transitionTab.title="Transition"
|
||||||
AdvSceneSwitcher.transitionTab.transitionForAToB="Utiliser une transition pour le passage automatisé de la scène A à la scène B"
|
AdvSceneSwitcher.transitionTab.transitionForAToB="Utiliser une transition pour le passage automatisé de la scène A à la scène B"
|
||||||
|
|||||||
2086
data/locale/ja-JP.ini
Normal file
2086
data/locale/ja-JP.ini
Normal file
File diff suppressed because it is too large
Load Diff
2139
data/locale/pt-BR.ini
Normal file
2139
data/locale/pt-BR.ini
Normal file
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,6 @@ AdvSceneSwitcher.macroTab.edit.action="Тип действия:"
|
|||||||
AdvSceneSwitcher.macroTab.add="Добавить новый макрос"
|
AdvSceneSwitcher.macroTab.add="Добавить новый макрос"
|
||||||
AdvSceneSwitcher.macroTab.name="Имя:"
|
AdvSceneSwitcher.macroTab.name="Имя:"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Макрос %1"
|
AdvSceneSwitcher.macroTab.defaultname="Макрос %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="Имя макроса уже существует"
|
|
||||||
AdvSceneSwitcher.macroTab.copy="Создать копию"
|
AdvSceneSwitcher.macroTab.copy="Создать копию"
|
||||||
; Macro Logic
|
; Macro Logic
|
||||||
AdvSceneSwitcher.logic.none="Игнорировать вход"
|
AdvSceneSwitcher.logic.none="Игнорировать вход"
|
||||||
@@ -138,7 +137,6 @@ AdvSceneSwitcher.action.replay="Буфер воспроизведения"
|
|||||||
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.streaming="Потоковое вещание"
|
AdvSceneSwitcher.action.streaming="Потоковое вещание"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
||||||
|
|||||||
@@ -72,11 +72,9 @@ AdvSceneSwitcher.macroTab.edit.action="Eylem türü:"
|
|||||||
AdvSceneSwitcher.macroTab.add="Yeni Makro ekle"
|
AdvSceneSwitcher.macroTab.add="Yeni Makro ekle"
|
||||||
AdvSceneSwitcher.macroTab.name="İsim:"
|
AdvSceneSwitcher.macroTab.name="İsim:"
|
||||||
AdvSceneSwitcher.macroTab.run="Makro Çalıştırma"
|
AdvSceneSwitcher.macroTab.run="Makro Çalıştırma"
|
||||||
AdvSceneSwitcher.macroTab.runFail="\"%1\" çalıştırılamadı!\n Eylemlerden biri başarısız oldu veya makro zaten çalışıyor."
|
|
||||||
AdvSceneSwitcher.macroTab.runInParallel="Makroyu diğer makrolara paralel olarak çalıştırın"
|
AdvSceneSwitcher.macroTab.runInParallel="Makroyu diğer makrolara paralel olarak çalıştırın"
|
||||||
AdvSceneSwitcher.macroTab.onChange="Eylemleri yalnızca koşul değişikliğinde gerçekleştirin"
|
AdvSceneSwitcher.macroTab.onChange="Eylemleri yalnızca koşul değişikliğinde gerçekleştirin"
|
||||||
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Makro %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="Macro adı zaten mevcut"
|
|
||||||
AdvSceneSwitcher.macroTab.copy="Kopya oluştur"
|
AdvSceneSwitcher.macroTab.copy="Kopya oluştur"
|
||||||
AdvSceneSwitcher.macroTab.expandAll="Hepsini Genişlet"
|
AdvSceneSwitcher.macroTab.expandAll="Hepsini Genişlet"
|
||||||
AdvSceneSwitcher.macroTab.collapseAll="Hepsini Küçült"
|
AdvSceneSwitcher.macroTab.collapseAll="Hepsini Küçült"
|
||||||
@@ -119,7 +117,7 @@ AdvSceneSwitcher.condition.file.entry.line3="{{checkModificationDate}}{{checkFil
|
|||||||
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ı "
|
||||||
AdvSceneSwitcher.condition.media.entry="{{sourceTypes}}{{mediaSources}}{{scenes}}durumu{{states}}ve{{timeRestrictions}}{{time}}"
|
AdvSceneSwitcher.condition.media.layout.legacy="{{sourceTypes}}{{mediaSources}}{{scenes}}{{checkTypes}}durumu{{states}}ve{{timeRestrictions}}{{time}}"
|
||||||
AdvSceneSwitcher.condition.video="Video"
|
AdvSceneSwitcher.condition.video="Video"
|
||||||
AdvSceneSwitcher.condition.video.condition.match="Tam olarak eşleşir"
|
AdvSceneSwitcher.condition.video.condition.match="Tam olarak eşleşir"
|
||||||
AdvSceneSwitcher.condition.video.condition.differ="Eşleştirme"
|
AdvSceneSwitcher.condition.video.condition.differ="Eşleştirme"
|
||||||
@@ -228,10 +226,7 @@ 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}}{{types}}"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="dönüşümle eşleşir"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="dönüşümle eşleşir"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
|
||||||
AdvSceneSwitcher.condition.transition="Geçiş"
|
AdvSceneSwitcher.condition.transition="Geçiş"
|
||||||
AdvSceneSwitcher.condition.transition.type.current="Geçerli geçiş türü"
|
AdvSceneSwitcher.condition.transition.type.current="Geçerli geçiş türü"
|
||||||
AdvSceneSwitcher.condition.transition.type.duration="Mevcut geçiş süresi"
|
AdvSceneSwitcher.condition.transition.type.duration="Mevcut geçiş süresi"
|
||||||
@@ -281,7 +276,6 @@ 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"
|
||||||
AdvSceneSwitcher.action.replay.type.save="Tekrar arabelleğini kaydet"
|
AdvSceneSwitcher.action.replay.type.save="Tekrar arabelleğini kaydet"
|
||||||
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"
|
||||||
@@ -297,7 +291,7 @@ 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"
|
||||||
AdvSceneSwitcher.action.filter.type.settings="Ayarları yap"
|
AdvSceneSwitcher.action.filter.type.settings="Ayarları yap"
|
||||||
AdvSceneSwitcher.action.filter.entry="Açık{{sources}}{{actions}}{{filters}}{{refresh}}"
|
AdvSceneSwitcher.action.filter.entry="Açık{{sources}}{{actions}}{{filters}}{{refresh}}{{settingsButtons}}"
|
||||||
AdvSceneSwitcher.action.filter.getSettings="Mevcut ayarları al"
|
AdvSceneSwitcher.action.filter.getSettings="Mevcut ayarları al"
|
||||||
AdvSceneSwitcher.action.source="Kaynak"
|
AdvSceneSwitcher.action.source="Kaynak"
|
||||||
AdvSceneSwitcher.action.source.type.enable="Etkin"
|
AdvSceneSwitcher.action.source.type.enable="Etkin"
|
||||||
@@ -317,7 +311,6 @@ 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}}{{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:"
|
||||||
@@ -348,7 +341,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}}{{action}}{{rotation}}{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="Açık{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"
|
||||||
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"
|
||||||
|
|||||||
@@ -77,15 +77,13 @@ AdvSceneSwitcher.macroTab.edit.action="动作类型:"
|
|||||||
AdvSceneSwitcher.macroTab.add="添加新宏"
|
AdvSceneSwitcher.macroTab.add="添加新宏"
|
||||||
AdvSceneSwitcher.macroTab.name="名称:"
|
AdvSceneSwitcher.macroTab.name="名称:"
|
||||||
AdvSceneSwitcher.macroTab.run="运行宏"
|
AdvSceneSwitcher.macroTab.run="运行宏"
|
||||||
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.defaultGroupName="组 %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="宏名称已存在"
|
AdvSceneSwitcher.macroTab.removeSingleMacroPopup.text="你确定你要删除 \"%1\"?"
|
||||||
AdvSceneSwitcher.macroTab.groupDeleteConfirm="您确定要删除 \"%1\"及其所有元素吗?"
|
AdvSceneSwitcher.macroTab.removeMultipleMacrosPopup.text="您确定要删除 %1 宏吗?"
|
||||||
AdvSceneSwitcher.macroTab.deleteMultipleMacrosConfirmation="您确定要删除 %1 宏吗?"
|
AdvSceneSwitcher.macroTab.removeGroupPopup.text="您确定要删除 \"%1\"及其所有元素吗?"
|
||||||
AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation="你确定你要删除 \"%1\"?"
|
|
||||||
AdvSceneSwitcher.macroTab.contextMenuAdd="增加"
|
AdvSceneSwitcher.macroTab.contextMenuAdd="增加"
|
||||||
AdvSceneSwitcher.macroTab.copy="创建副本"
|
AdvSceneSwitcher.macroTab.copy="创建副本"
|
||||||
AdvSceneSwitcher.macroTab.group="对选定的宏进行分组"
|
AdvSceneSwitcher.macroTab.group="对选定的宏进行分组"
|
||||||
@@ -186,7 +184,7 @@ AdvSceneSwitcher.condition.media.source="源"
|
|||||||
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体源"
|
AdvSceneSwitcher.condition.media.anyOnScene="任何媒体源"
|
||||||
AdvSceneSwitcher.condition.media.allOnScene="所有媒体源"
|
AdvSceneSwitcher.condition.media.allOnScene="所有媒体源"
|
||||||
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.layout.legacy="{{sourceTypes}}{{mediaSources}}{{scenes}}{{checkTypes}}的状态是{{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="不匹配"
|
||||||
@@ -334,8 +332,7 @@ AdvSceneSwitcher.condition.sceneOrder.entry="在 {{scenes}} {{sources}} {{condit
|
|||||||
AdvSceneSwitcher.condition.hotkey="热键"
|
AdvSceneSwitcher.condition.hotkey="热键"
|
||||||
AdvSceneSwitcher.condition.hotkey.name="宏触发热键"
|
AdvSceneSwitcher.condition.hotkey.name="宏触发热键"
|
||||||
AdvSceneSwitcher.condition.hotkey.tip="注意:您可以在OBS设置窗口中为此热键配置按键绑定"
|
AdvSceneSwitcher.condition.hotkey.tip="注意:您可以在OBS设置窗口中为此热键配置按键绑定"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line1="热键被按下"
|
AdvSceneSwitcher.condition.hotkey.entry.name="名称:{{name}}"
|
||||||
AdvSceneSwitcher.condition.hotkey.entry.line2="名称: {{name}}"
|
|
||||||
AdvSceneSwitcher.condition.replay="回放缓存"
|
AdvSceneSwitcher.condition.replay="回放缓存"
|
||||||
AdvSceneSwitcher.condition.replay.state.stopped="回放缓存已停止"
|
AdvSceneSwitcher.condition.replay.state.stopped="回放缓存已停止"
|
||||||
AdvSceneSwitcher.condition.replay.state.started="回放缓存已启动"
|
AdvSceneSwitcher.condition.replay.state.started="回放缓存已启动"
|
||||||
@@ -368,10 +365,7 @@ AdvSceneSwitcher.condition.date.entry.nextMatchDate="下一次匹配 在: %1"
|
|||||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} 重复时,将选定的日期更新为重复日期"
|
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} 重复时,将选定的日期更新为重复日期"
|
||||||
AdvSceneSwitcher.condition.sceneTransform="场景项目被改变"
|
AdvSceneSwitcher.condition.sceneTransform="场景项目被改变"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="内容或者设置被改变了"
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="内容或者设置被改变了"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line1="在 {{scenes}} {{sources}} {{types}}"
|
AdvSceneSwitcher.condition.sceneTransform.condition.match="匹配变换"
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.type.matches="匹配变换"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
|
||||||
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
|
||||||
AdvSceneSwitcher.condition.transition="转场"
|
AdvSceneSwitcher.condition.transition="转场"
|
||||||
AdvSceneSwitcher.condition.transition.type.current="当前转场特效类型为"
|
AdvSceneSwitcher.condition.transition.type.current="当前转场特效类型为"
|
||||||
AdvSceneSwitcher.condition.transition.type.duration="当前转场特效持续时间为"
|
AdvSceneSwitcher.condition.transition.type.duration="当前转场特效持续时间为"
|
||||||
@@ -484,7 +478,6 @@ 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.streaming="推流"
|
AdvSceneSwitcher.action.streaming="推流"
|
||||||
AdvSceneSwitcher.action.streaming.type.stop="停止推流"
|
AdvSceneSwitcher.action.streaming.type.stop="停止推流"
|
||||||
AdvSceneSwitcher.action.streaming.type.start="开始推流"
|
AdvSceneSwitcher.action.streaming.type.start="开始推流"
|
||||||
@@ -502,7 +495,7 @@ 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}}{{refresh}}"
|
AdvSceneSwitcher.action.filter.entry="置{{sources}}{{actions}}{{filters}}{{refresh}}{{settingsButtons}}"
|
||||||
AdvSceneSwitcher.action.filter.getSettings="获取当前设置"
|
AdvSceneSwitcher.action.filter.getSettings="获取当前设置"
|
||||||
AdvSceneSwitcher.action.source="源"
|
AdvSceneSwitcher.action.source="源"
|
||||||
AdvSceneSwitcher.action.source.type.enable="启用"
|
AdvSceneSwitcher.action.source.type.enable="启用"
|
||||||
@@ -511,7 +504,6 @@ AdvSceneSwitcher.action.source.type.settings="配置设置"
|
|||||||
AdvSceneSwitcher.action.source.type.refreshSettings="刷新源设置"
|
AdvSceneSwitcher.action.source.type.refreshSettings="刷新源设置"
|
||||||
AdvSceneSwitcher.action.source.type.pressSettingsButton="按下设置按钮"
|
AdvSceneSwitcher.action.source.type.pressSettingsButton="按下设置按钮"
|
||||||
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="可用于刷新浏览器、媒体、源、etc"
|
AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="可用于刷新浏览器、媒体、源、etc"
|
||||||
AdvSceneSwitcher.action.source.noSettingsButtons="未找到按钮!"
|
|
||||||
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="媒体"
|
||||||
@@ -528,7 +520,6 @@ 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}}{{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="没有匹配项时:"
|
||||||
@@ -561,7 +552,7 @@ 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}}{{action}}{{rotation}}{{sources}}"
|
AdvSceneSwitcher.action.sceneTransform.entry="在{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"
|
||||||
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="追加写入"
|
||||||
@@ -608,7 +599,7 @@ AdvSceneSwitcher.action.sceneCollection="场景集合"
|
|||||||
AdvSceneSwitcher.action.sceneCollection.entry="将活动场景集合切换到 {{sceneCollections}}"
|
AdvSceneSwitcher.action.sceneCollection.entry="将活动场景集合切换到 {{sceneCollections}}"
|
||||||
AdvSceneSwitcher.action.sceneCollection.warning="注意:在此之后的任何操作都不会执行,因为更改场景集合也会重新加载场景切换器设置。\n打开“设置”窗口时,场景采集操作将被忽略."
|
AdvSceneSwitcher.action.sceneCollection.warning="注意:在此之后的任何操作都不会执行,因为更改场景集合也会重新加载场景切换器设置。\n打开“设置”窗口时,场景采集操作将被忽略."
|
||||||
AdvSceneSwitcher.action.sequence="场景序列"
|
AdvSceneSwitcher.action.sequence="场景序列"
|
||||||
AdvSceneSwitcher.action.sequence.entry="每次执行此操作时,运行列表中的下一个宏(暂停的宏将被忽略)"
|
; AdvSceneSwitcher.action.sequence.entry="每次执行此操作时,运行列表中的下一个宏(暂停的宏将被忽略)"
|
||||||
AdvSceneSwitcher.action.sequence.status="上次执行的宏:%1 - 要执行的下一个宏: %2"
|
AdvSceneSwitcher.action.sequence.status="上次执行的宏:%1 - 要执行的下一个宏: %2"
|
||||||
AdvSceneSwitcher.action.sequence.status.none="无"
|
AdvSceneSwitcher.action.sequence.status.none="无"
|
||||||
AdvSceneSwitcher.action.sequence.restart="到达列表末尾后,从开头重新启动"
|
AdvSceneSwitcher.action.sequence.restart="到达列表末尾后,从开头重新启动"
|
||||||
@@ -663,6 +654,8 @@ AdvSceneSwitcher.action.midi.entry="发送消息到 {{device}}:"
|
|||||||
AdvSceneSwitcher.action.midi.entry.listen="将MIDI消息选择设置为 {{listenDevices}} 上传入的消息: {{listenButton}}"
|
AdvSceneSwitcher.action.midi.entry.listen="将MIDI消息选择设置为 {{listenDevices}} 上传入的消息: {{listenButton}}"
|
||||||
AdvSceneSwitcher.action.osc="打开声音控制"
|
AdvSceneSwitcher.action.osc="打开声音控制"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.noSettingsButtons="未找到按钮!"
|
||||||
|
|
||||||
; Transition Tab
|
; Transition Tab
|
||||||
AdvSceneSwitcher.transitionTab.title="转场特效"
|
AdvSceneSwitcher.transitionTab.title="转场特效"
|
||||||
AdvSceneSwitcher.transitionTab.transitionForAToB="当自动从场景A切换到场景B时使用的转场特效"
|
AdvSceneSwitcher.transitionTab.transitionForAToB="当自动从场景A切换到场景B时使用的转场特效"
|
||||||
|
|||||||
1
deps/libusb
vendored
Submodule
1
deps/libusb
vendored
Submodule
Submodule deps/libusb added at d52e355daa
2
deps/opencv
vendored
2
deps/opencv
vendored
Submodule deps/opencv updated: b0dc474160...71d3237a09
@@ -68,7 +68,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>962</width>
|
<width>962</width>
|
||||||
<height>1033</height>
|
<height>1040</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||||
@@ -163,12 +163,31 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_52">
|
<layout class="QHBoxLayout" name="horizontalLayout_52">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="verboseLogging">
|
<widget class="QLabel" name="label_21">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging</string>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="logLevel">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel.default</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel.printActions</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel.verbose</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_49">
|
<spacer name="horizontalSpacer_49">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -371,7 +390,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="cooldownLayout">
|
<layout class="QHBoxLayout" name="cooldownLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QCheckBox" name="enableCooldown">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.cooldown</string>
|
<string>AdvSceneSwitcher.generalTab.generalBehavior.cooldown</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -553,40 +572,22 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_32">
|
<layout class="QHBoxLayout" name="horizontalLayout_32">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="priorityUp">
|
<widget class="QToolButton" name="priorityUp">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>22</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>../../../forms/images/up.png</normaloff>../../../forms/images/up.png</iconset>
|
<normaloff>../../../forms/images/up.png</normaloff>../../../forms/images/up.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">upArrowIconSmall</string>
|
<string notr="true">upArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="priorityDown">
|
<widget class="QToolButton" name="priorityDown">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>22</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset>
|
<iconset>
|
||||||
<normaloff>../../../forms/images/down.png</normaloff>../../../forms/images/down.png</iconset>
|
<normaloff>../../../forms/images/down.png</normaloff>../../../forms/images/down.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">downArrowIconSmall</string>
|
<string notr="true">downArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -720,135 +721,47 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_61">
|
<layout class="QHBoxLayout" name="macroControlLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="macroAdd">
|
<widget class="QToolButton" name="macroAdd">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroAddButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.macroAddButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">addIconSmall</string>
|
<string notr="true">addIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="macroRemove">
|
<widget class="QToolButton" name="macroRemove">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroRemoveButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.macroRemoveButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">removeIconSmall</string>
|
<string notr="true">removeIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_130">
|
<widget class="QToolButton" name="macroUp">
|
||||||
<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_46">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_131">
|
|
||||||
<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="macroUp">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroUpButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.macroUpButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">upArrowIconSmall</string>
|
<string notr="true">upArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="macroDown">
|
<widget class="QToolButton" name="macroDown">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroDownButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.macroDownButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">downArrowIconSmall</string>
|
<string notr="true">downArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_65">
|
|
||||||
<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>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -883,6 +796,9 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="runMacroInParallel">
|
<widget class="QCheckBox" name="runMacroInParallel">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>AdvSceneSwitcher.macroTab.runInParallel</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -903,6 +819,9 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="runMacroOnChange">
|
<widget class="QCheckBox" name="runMacroOnChange">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>AdvSceneSwitcher.macroTab.onChange</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -935,22 +854,13 @@
|
|||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="macroProperties">
|
<widget class="QToolButton" name="macroSettings">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.openMacroPropertiesButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.openMacroSettingsButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">propertiesIconSmall</string>
|
<string notr="true">propertiesIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -988,173 +898,67 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
<layout class="QHBoxLayout" name="conditionControlsLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>9</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="conditionAdd">
|
<widget class="QToolButton" name="conditionAdd">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionAddButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.conditionAddButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">addIconSmall</string>
|
<string notr="true">addIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="conditionRemove">
|
<widget class="QToolButton" name="conditionRemove">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionRemoveButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.conditionRemoveButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">removeIconSmall</string>
|
<string notr="true">removeIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_135">
|
<widget class="QToolButton" name="conditionTop">
|
||||||
<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_48">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_134">
|
|
||||||
<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="conditionTop">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionTopButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.conditionTopButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="conditionUp">
|
<widget class="QToolButton" name="conditionUp">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionUpButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.conditionUpButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">upArrowIconSmall</string>
|
<string notr="true">upArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="conditionDown">
|
<widget class="QToolButton" name="conditionDown">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionDownButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.conditionDownButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">downArrowIconSmall</string>
|
<string notr="true">downArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="conditionBottom">
|
<widget class="QToolButton" name="conditionBottom">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.conditionBottomButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.conditionBottomButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_15">
|
|
||||||
<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>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -1188,155 +992,62 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
<layout class="QHBoxLayout" name="actionControlsLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>9</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="actionAdd">
|
<widget class="QToolButton" name="actionAdd">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionAddButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.actionAddButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">addIconSmall</string>
|
<string notr="true">addIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="actionRemove">
|
<widget class="QToolButton" name="actionRemove">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionRemoveButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.actionRemoveButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">removeIconSmall</string>
|
<string notr="true">removeIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_133">
|
<widget class="QToolButton" name="actionTop">
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>5</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line_47">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_132">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>5</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="actionTop">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionTopButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.actionTopButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="actionUp">
|
<widget class="QToolButton" name="actionUp">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionUpButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.actionUpButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">upArrowIconSmall</string>
|
<string notr="true">upArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="actionDown">
|
<widget class="QToolButton" name="actionDown">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionDownButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.actionDownButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">downArrowIconSmall</string>
|
<string notr="true">downArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="actionBottom">
|
<widget class="QToolButton" name="actionBottom">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.actionBottomButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.actionBottomButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@@ -1353,22 +1064,13 @@
|
|||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="toggleElseActions">
|
<widget class="QToolButton" name="toggleElseActions">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.toggleShowElseSection</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.toggleShowElseSection</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -1400,170 +1102,64 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_33">
|
<layout class="QHBoxLayout" name="elseActionControlsLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>9</number>
|
<number>9</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="elseActionAdd">
|
<widget class="QToolButton" name="elseActionAdd">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionAddButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionAddButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">addIconSmall</string>
|
<string notr="true">addIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="elseActionRemove">
|
<widget class="QToolButton" name="elseActionRemove">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionRemoveButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionRemoveButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">removeIconSmall</string>
|
<string notr="true">removeIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_138">
|
<widget class="QToolButton" name="elseActionTop">
|
||||||
<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="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionTopButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionTopButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="elseActionUp">
|
<widget class="QToolButton" name="elseActionUp">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">upArrowIconSmall</string>
|
<string notr="true">upArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="elseActionDown">
|
<widget class="QToolButton" name="elseActionDown">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">downArrowIconSmall</string>
|
<string notr="true">downArrowIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="elseActionBottom">
|
<widget class="QToolButton" name="elseActionBottom">
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton</string>
|
<string>AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -1577,104 +1173,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="variableTab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>AdvSceneSwitcher.variableTab.title</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_33">
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_25">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QTableWidget" name="variables">
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
<property name="selectionBehavior">
|
|
||||||
<enum>QAbstractItemView::SelectRows</enum>
|
|
||||||
</property>
|
|
||||||
<property name="showGrid">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="cornerButtonEnabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="verticalHeaderVisible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="variablesHelp">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.variableTab.help</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_30">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="variableAdd">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>22</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.variableTab.tooltip.variableAddButton</string>
|
|
||||||
</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="variableRemove">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>22</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>AdvSceneSwitcher.variableTab.tooltip.variableRemoveButton</string>
|
|
||||||
</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_211">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="networkTab">
|
<widget class="QWidget" name="networkTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>AdvSceneSwitcher.networkTab.title</string>
|
<string>AdvSceneSwitcher.networkTab.title</string>
|
||||||
@@ -5078,7 +4576,7 @@
|
|||||||
<tabstop>checkInterval</tabstop>
|
<tabstop>checkInterval</tabstop>
|
||||||
<tabstop>startupBehavior</tabstop>
|
<tabstop>startupBehavior</tabstop>
|
||||||
<tabstop>autoStartEvent</tabstop>
|
<tabstop>autoStartEvent</tabstop>
|
||||||
<tabstop>verboseLogging</tabstop>
|
<tabstop>logLevel</tabstop>
|
||||||
<tabstop>saveWindowGeo</tabstop>
|
<tabstop>saveWindowGeo</tabstop>
|
||||||
<tabstop>showTrayNotifications</tabstop>
|
<tabstop>showTrayNotifications</tabstop>
|
||||||
<tabstop>uiHintsDisable</tabstop>
|
<tabstop>uiHintsDisable</tabstop>
|
||||||
@@ -5106,7 +4604,7 @@
|
|||||||
<tabstop>runMacro</tabstop>
|
<tabstop>runMacro</tabstop>
|
||||||
<tabstop>runMacroInParallel</tabstop>
|
<tabstop>runMacroInParallel</tabstop>
|
||||||
<tabstop>runMacroOnChange</tabstop>
|
<tabstop>runMacroOnChange</tabstop>
|
||||||
<tabstop>macroProperties</tabstop>
|
<tabstop>macroSettings</tabstop>
|
||||||
<tabstop>conditionsList</tabstop>
|
<tabstop>conditionsList</tabstop>
|
||||||
<tabstop>conditionAdd</tabstop>
|
<tabstop>conditionAdd</tabstop>
|
||||||
<tabstop>conditionRemove</tabstop>
|
<tabstop>conditionRemove</tabstop>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "backup.hpp"
|
||||||
#include "curl-helper.hpp"
|
#include "curl-helper.hpp"
|
||||||
#include "log-helper.hpp"
|
#include "log-helper.hpp"
|
||||||
#include "macro-helpers.hpp"
|
#include "macro-helpers.hpp"
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
#include "status-control.hpp"
|
#include "status-control.hpp"
|
||||||
#include "switcher-data.hpp"
|
#include "switcher-data.hpp"
|
||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
|
#include "tab-helpers.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
@@ -17,7 +19,6 @@
|
|||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
@@ -44,7 +45,7 @@ AdvSceneSwitcher::~AdvSceneSwitcher()
|
|||||||
{
|
{
|
||||||
if (switcher) {
|
if (switcher) {
|
||||||
switcher->settingsWindowOpened = false;
|
switcher->settingsWindowOpened = false;
|
||||||
switcher->lastOpenedTab = ui->tabWidget->currentIndex();
|
SaveLastOpenedTab(ui->tabWidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +70,9 @@ static void DisplayMissingDependencyWarning()
|
|||||||
QString warning(obs_module_text(
|
QString warning(obs_module_text(
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage"));
|
"AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage"));
|
||||||
DisplayMessage(warning.arg(failedLibsString));
|
DisplayMessage(warning.arg(failedLibsString));
|
||||||
|
|
||||||
|
// Only display the warning once per plugin load
|
||||||
|
switcher->loadFailureLibs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DisplayMissingDataDirWarning()
|
static void DisplayMissingDataDirWarning()
|
||||||
@@ -89,10 +93,24 @@ static void DisplayMissingDataDirWarning()
|
|||||||
DisplayMessage(msg);
|
DisplayMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanCreateDefaultAction();
|
||||||
|
bool CanCreateDefaultCondition();
|
||||||
|
|
||||||
|
static void DisplayCorruptedInstallWarning()
|
||||||
|
{
|
||||||
|
if (CanCreateDefaultAction() && CanCreateDefaultCondition()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayMessage(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage"));
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::LoadUI()
|
void AdvSceneSwitcher::LoadUI()
|
||||||
{
|
{
|
||||||
DisplayMissingDataDirWarning();
|
DisplayMissingDataDirWarning();
|
||||||
DisplayMissingDependencyWarning();
|
DisplayMissingDependencyWarning();
|
||||||
|
DisplayCorruptedInstallWarning();
|
||||||
|
|
||||||
SetupGeneralTab();
|
SetupGeneralTab();
|
||||||
SetupTitleTab();
|
SetupTitleTab();
|
||||||
@@ -112,11 +130,11 @@ void AdvSceneSwitcher::LoadUI()
|
|||||||
SetupSceneGroupTab();
|
SetupSceneGroupTab();
|
||||||
SetupTriggerTab();
|
SetupTriggerTab();
|
||||||
SetupMacroTab();
|
SetupMacroTab();
|
||||||
SetupVariableTab();
|
SetupOtherTabs(ui->tabWidget);
|
||||||
|
|
||||||
SetDeprecationWarnings();
|
SetDeprecationWarnings();
|
||||||
SetTabOrder();
|
SetTabOrder(ui->tabWidget);
|
||||||
SetCurrentTab();
|
SetCurrentTab(ui->tabWidget);
|
||||||
RestoreWindowGeo();
|
RestoreWindowGeo();
|
||||||
CheckFirstTimeSetup();
|
CheckFirstTimeSetup();
|
||||||
|
|
||||||
@@ -135,6 +153,17 @@ bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetElseActionsStateToVisible();
|
SetElseActionsStateToVisible();
|
||||||
|
} else if (eventType == QEvent::KeyPress) {
|
||||||
|
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||||
|
auto pressedKey = keyEvent->key();
|
||||||
|
|
||||||
|
if (obj == ui->macros && ui->macros->isVisible()) {
|
||||||
|
if (pressedKey == Qt::Key_F2) {
|
||||||
|
RenameSelectedMacro();
|
||||||
|
} else if (pressedKey == Qt::Key_Delete) {
|
||||||
|
RemoveSelectedMacros();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QDialog::eventFilter(obj, event);
|
return QDialog::eventFilter(obj, event);
|
||||||
@@ -143,7 +172,6 @@ bool AdvSceneSwitcher::eventFilter(QObject *obj, QEvent *event)
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Saving and loading
|
* Saving and loading
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static void AskForBackup(const QString &json);
|
|
||||||
|
|
||||||
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||||
{
|
{
|
||||||
@@ -192,34 +220,6 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AskForBackup(const QString &json)
|
|
||||||
{
|
|
||||||
const bool backupWasConfirmed = DisplayMessage(
|
|
||||||
obs_module_text("AdvSceneSwitcher.askBackup"), true, false);
|
|
||||||
|
|
||||||
if (!backupWasConfirmed) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
auto out = QTextStream(&file);
|
|
||||||
out << json;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Main switcher thread
|
* Main switcher thread
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -255,9 +255,9 @@ void SwitcherData::Thread()
|
|||||||
duration = std::chrono::milliseconds(interval) +
|
duration = std::chrono::milliseconds(interval) +
|
||||||
std::chrono::milliseconds(linger) - runTime;
|
std::chrono::milliseconds(linger) - runTime;
|
||||||
if (duration.count() < 1) {
|
if (duration.count() < 1) {
|
||||||
blog(LOG_INFO,
|
vblog(LOG_INFO,
|
||||||
"detected busy loop - refusing to sleep less than 1ms");
|
"detected busy loop - refusing to sleep less than 1ms");
|
||||||
duration = std::chrono::milliseconds(50);
|
duration = std::chrono::milliseconds(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,9 +539,7 @@ bool SwitcherData::AnySceneTransitionStarted()
|
|||||||
extern "C" EXPORT void FreeSceneSwitcher()
|
extern "C" EXPORT void FreeSceneSwitcher()
|
||||||
{
|
{
|
||||||
PlatformCleanup();
|
PlatformCleanup();
|
||||||
for (const auto &cleanupStep : switcher->pluginCleanupSteps) {
|
RunPluginCleanupSteps();
|
||||||
cleanupStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
delete switcher;
|
delete switcher;
|
||||||
switcher = nullptr;
|
switcher = nullptr;
|
||||||
@@ -635,6 +633,8 @@ static void handleShutdown()
|
|||||||
// TODO: Look for a way to possibly resolve this
|
// TODO: Look for a way to possibly resolve this
|
||||||
obs_frontend_save();
|
obs_frontend_save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BackupSettingsOfCurrentVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleSceneCollectionChanging()
|
static void handleSceneCollectionChanging()
|
||||||
@@ -722,7 +722,7 @@ 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())));
|
||||||
QString pluginDir(libPath.absolutePath() + "/adv-ss-plugins");
|
QString pluginDir(libPath.absolutePath() + "/" ADVSS_PLUGIN_FOLDER);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
QString libPattern = "*.dll";
|
QString libPattern = "*.dll";
|
||||||
SetDllDirectory(pluginDir.toStdWString().c_str());
|
SetDllDirectory(pluginDir.toStdWString().c_str());
|
||||||
@@ -762,20 +762,38 @@ void OpenSettingsWindow()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *GetSettingsWindow()
|
void AdvSceneSwitcher::HighligthMacroSettingsButton(bool enable)
|
||||||
{
|
{
|
||||||
return SettingsWindowIsOpened() ? AdvSceneSwitcher::window : nullptr;
|
static QObject *highlight = nullptr;
|
||||||
|
if ((highlight && enable) || (!highlight && !enable)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highlight && !enable) {
|
||||||
|
highlight->deleteLater();
|
||||||
|
highlight = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!HighlightUIElementsEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight = HighlightWidget(ui->macroSettings, Qt::green);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighligthMacroSettingsButton(bool enable)
|
||||||
|
{
|
||||||
|
auto window = GetSettingsWindow();
|
||||||
|
if (!window) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static_cast<AdvSceneSwitcher *>(window)->HighligthMacroSettingsButton(
|
||||||
|
enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupActionQueues();
|
void SetupActionQueues();
|
||||||
|
|
||||||
extern "C" EXPORT void RunPluginPostLoadSteps()
|
|
||||||
{
|
|
||||||
for (const auto &postLoadStep : switcher->pluginPostLoadSteps) {
|
|
||||||
postLoadStep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" EXPORT void InitSceneSwitcher(obs_module_t *module,
|
extern "C" EXPORT void InitSceneSwitcher(obs_module_t *module,
|
||||||
translateFunc translate)
|
translateFunc translate)
|
||||||
{
|
{
|
||||||
@@ -789,9 +807,7 @@ extern "C" EXPORT void InitSceneSwitcher(obs_module_t *module,
|
|||||||
SetupDock();
|
SetupDock();
|
||||||
SetupActionQueues();
|
SetupActionQueues();
|
||||||
|
|
||||||
for (const auto &initStep : switcher->pluginInitSteps) {
|
RunPluginInitSteps();
|
||||||
initStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro-segment-list.hpp"
|
#include "macro-segment-list.hpp"
|
||||||
|
#include "condition-logic.hpp"
|
||||||
#include "log-helper.hpp"
|
#include "log-helper.hpp"
|
||||||
|
|
||||||
#include <ui_advanced-scene-switcher.h>
|
#include <ui_advanced-scene-switcher.h>
|
||||||
@@ -34,8 +35,6 @@ public:
|
|||||||
|
|
||||||
void LoadUI();
|
void LoadUI();
|
||||||
|
|
||||||
void SetTabOrder();
|
|
||||||
void SetCurrentTab();
|
|
||||||
void RestoreWindowGeo();
|
void RestoreWindowGeo();
|
||||||
void CheckFirstTimeSetup();
|
void CheckFirstTimeSetup();
|
||||||
|
|
||||||
@@ -54,15 +53,15 @@ public slots:
|
|||||||
void on_noMatchRandomSwitch_clicked();
|
void on_noMatchRandomSwitch_clicked();
|
||||||
void NoMatchDelayDurationChanged(const Duration &);
|
void NoMatchDelayDurationChanged(const Duration &);
|
||||||
void CooldownDurationChanged(const Duration &);
|
void CooldownDurationChanged(const Duration &);
|
||||||
|
void on_enableCooldown_stateChanged(int state);
|
||||||
void on_startupBehavior_currentIndexChanged(int index);
|
void on_startupBehavior_currentIndexChanged(int index);
|
||||||
|
void on_logLevel_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_tabWidget_currentChanged(int index);
|
void on_tabWidget_currentChanged(int index);
|
||||||
void on_exportSettings_clicked();
|
void on_exportSettings_clicked();
|
||||||
void on_importSettings_clicked();
|
void on_importSettings_clicked();
|
||||||
void on_verboseLogging_stateChanged(int state);
|
|
||||||
void on_saveWindowGeo_stateChanged(int state);
|
void on_saveWindowGeo_stateChanged(int state);
|
||||||
void on_showTrayNotifications_stateChanged(int state);
|
void on_showTrayNotifications_stateChanged(int state);
|
||||||
void on_uiHintsDisable_stateChanged(int state);
|
void on_uiHintsDisable_stateChanged(int state);
|
||||||
@@ -81,6 +80,7 @@ public:
|
|||||||
bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name,
|
bool AddNewMacro(std::shared_ptr<Macro> &res, std::string &name,
|
||||||
std::string format = "");
|
std::string format = "");
|
||||||
void RemoveMacro(std::shared_ptr<Macro> &);
|
void RemoveMacro(std::shared_ptr<Macro> &);
|
||||||
|
void RemoveSelectedMacros();
|
||||||
void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
|
void RenameMacro(std::shared_ptr<Macro> &, const QString &name);
|
||||||
std::shared_ptr<Macro> GetSelectedMacro();
|
std::shared_ptr<Macro> GetSelectedMacro();
|
||||||
std::vector<std::shared_ptr<Macro>> GetSelectedMacros();
|
std::vector<std::shared_ptr<Macro>> GetSelectedMacros();
|
||||||
@@ -97,6 +97,7 @@ public:
|
|||||||
void SetConditionData(Macro &m);
|
void SetConditionData(Macro &m);
|
||||||
void SwapActions(Macro *m, int pos1, int pos2);
|
void SwapActions(Macro *m, int pos1, int pos2);
|
||||||
void SwapConditions(Macro *m, int pos1, int pos2);
|
void SwapConditions(Macro *m, int pos1, int pos2);
|
||||||
|
void HighligthMacroSettingsButton(bool enable = true);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void on_macroAdd_clicked();
|
void on_macroAdd_clicked();
|
||||||
@@ -135,7 +136,7 @@ public slots:
|
|||||||
void ShowMacroElseActionsContextMenu(const QPoint &);
|
void ShowMacroElseActionsContextMenu(const QPoint &);
|
||||||
void ShowMacroConditionsContextMenu(const QPoint &);
|
void ShowMacroConditionsContextMenu(const QPoint &);
|
||||||
void CopyMacro();
|
void CopyMacro();
|
||||||
void RenameCurrentMacro();
|
void RenameSelectedMacro();
|
||||||
void ExportMacros();
|
void ExportMacros();
|
||||||
void ImportMacros();
|
void ImportMacros();
|
||||||
void ExpandAllActions();
|
void ExpandAllActions();
|
||||||
@@ -154,12 +155,16 @@ public slots:
|
|||||||
void SetElseActionsStateToVisible();
|
void SetElseActionsStateToVisible();
|
||||||
void MacroActionSelectionChanged(int idx);
|
void MacroActionSelectionChanged(int idx);
|
||||||
void MacroActionReorder(int to, int target);
|
void MacroActionReorder(int to, int target);
|
||||||
|
void AddMacroAction(Macro *macro, int idx, const std::string &id,
|
||||||
|
obs_data_t *data);
|
||||||
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 MacroElseActionSelectionChanged(int idx);
|
||||||
void MacroElseActionReorder(int to, int target);
|
void MacroElseActionReorder(int to, int target);
|
||||||
|
void AddMacroElseAction(Macro *macro, int idx, const std::string &id,
|
||||||
|
obs_data_t *data);
|
||||||
void AddMacroElseAction(int idx);
|
void AddMacroElseAction(int idx);
|
||||||
void RemoveMacroElseAction(int idx);
|
void RemoveMacroElseAction(int idx);
|
||||||
void SwapElseActions(Macro *m, int pos1, int pos2);
|
void SwapElseActions(Macro *m, int pos1, int pos2);
|
||||||
@@ -168,16 +173,16 @@ public slots:
|
|||||||
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);
|
||||||
|
void AddMacroCondition(Macro *macro, int idx, const std::string &id,
|
||||||
|
obs_data_t *data, Logic::Type logic);
|
||||||
void RemoveMacroCondition(int idx);
|
void RemoveMacroCondition(int idx);
|
||||||
void MoveMacroConditionUp(int idx);
|
void MoveMacroConditionUp(int idx);
|
||||||
void MoveMacroConditionDown(int idx);
|
void MoveMacroConditionDown(int idx);
|
||||||
void FadeOutActionControls();
|
|
||||||
void FadeOutConditionControls();
|
|
||||||
void ResetOpacityActionControls();
|
|
||||||
void ResetOpacityConditionControls();
|
|
||||||
void HighlightControls();
|
void HighlightControls();
|
||||||
void HighlightOnChange();
|
void HighlightOnChange();
|
||||||
void on_macroProperties_clicked();
|
void on_macroSettings_clicked();
|
||||||
|
void CopyMacroSegment();
|
||||||
|
void PasteMacroSegment();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void MacroAdded(const QString &name);
|
void MacroAdded(const QString &name);
|
||||||
@@ -186,9 +191,6 @@ signals:
|
|||||||
void MacroSegmentOrderChanged();
|
void MacroSegmentOrderChanged();
|
||||||
void SegmentTempVarsChanged();
|
void SegmentTempVarsChanged();
|
||||||
void HighlightMacrosChanged(bool value);
|
void HighlightMacrosChanged(bool value);
|
||||||
void HighlightActionsChanged(bool value);
|
|
||||||
void HighlightElseActionsChanged(bool value);
|
|
||||||
void HighlightConditionsChanged(bool value);
|
|
||||||
|
|
||||||
void ConnectionAdded(const QString &);
|
void ConnectionAdded(const QString &);
|
||||||
void ConnectionRenamed(const QString &oldName, const QString &newName);
|
void ConnectionRenamed(const QString &oldName, const QString &newName);
|
||||||
@@ -208,16 +210,6 @@ private:
|
|||||||
|
|
||||||
/* --- End of macro tab section --- */
|
/* --- End of macro tab section --- */
|
||||||
|
|
||||||
/* --- Begin of variable tab section --- */
|
|
||||||
public:
|
|
||||||
void SetupVariableTab();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void on_variableAdd_clicked();
|
|
||||||
void on_variableRemove_clicked();
|
|
||||||
|
|
||||||
/* --- End of variable tab section --- */
|
|
||||||
|
|
||||||
/* --- Begin of legacy tab section --- */
|
/* --- Begin of legacy tab section --- */
|
||||||
public:
|
public:
|
||||||
void ClearFrames(QListWidget *list);
|
void ClearFrames(QListWidget *list);
|
||||||
@@ -419,6 +411,6 @@ public slots:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void OpenSettingsWindow();
|
void OpenSettingsWindow();
|
||||||
QWidget *GetSettingsWindow();
|
void HighligthMacroSettingsButton(bool enable);
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
169
lib/general.cpp
169
lib/general.cpp
@@ -9,6 +9,7 @@
|
|||||||
#include "splitter-helpers.hpp"
|
#include "splitter-helpers.hpp"
|
||||||
#include "status-control.hpp"
|
#include "status-control.hpp"
|
||||||
#include "switcher-data.hpp"
|
#include "switcher-data.hpp"
|
||||||
|
#include "tab-helpers.hpp"
|
||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
#include "variable.hpp"
|
#include "variable.hpp"
|
||||||
@@ -19,17 +20,6 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
static constexpr std::array<const char *, 19> tabNames = {
|
|
||||||
"generalTab", "macroTab", "variableTab",
|
|
||||||
"windowTitleTab", "executableTab", "screenRegionTab",
|
|
||||||
"mediaTab", "fileTab", "randomTab",
|
|
||||||
"timeTab", "idleTab", "sceneSequenceTab",
|
|
||||||
"audioTab", "videoTab", "networkTab",
|
|
||||||
"sceneGroupTab", "transitionsTab", "pauseTab",
|
|
||||||
"sceneTriggerTab"};
|
|
||||||
|
|
||||||
static std::vector<int> tabOrder = std::vector<int>(tabNames.size());
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::reject()
|
void AdvSceneSwitcher::reject()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
@@ -101,6 +91,17 @@ void AdvSceneSwitcher::CooldownDurationChanged(const Duration &dur)
|
|||||||
switcher->cooldown = dur;
|
switcher->cooldown = dur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_enableCooldown_stateChanged(int state)
|
||||||
|
{
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
|
switcher->enableCooldown = state;
|
||||||
|
ui->cooldownTime->setEnabled(state);
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -112,6 +113,14 @@ void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
|
|||||||
static_cast<SwitcherData::StartupBehavior>(index);
|
static_cast<SwitcherData::StartupBehavior>(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::on_logLevel_currentIndexChanged(int value)
|
||||||
|
{
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switcher->logLevel = static_cast<SwitcherData::LogLevel>(value);
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
void AdvSceneSwitcher::on_autoStartEvent_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -157,15 +166,6 @@ void AdvSceneSwitcher::closeEvent(QCloseEvent *)
|
|||||||
obs_frontend_save();
|
obs_frontend_save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_verboseLogging_stateChanged(int state)
|
|
||||||
{
|
|
||||||
if (loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switcher->verbose = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_saveWindowGeo_stateChanged(int state)
|
void AdvSceneSwitcher::on_saveWindowGeo_stateChanged(int state)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@@ -245,14 +245,7 @@ void AdvSceneSwitcher::on_hideLegacyTabs_stateChanged(int state)
|
|||||||
|
|
||||||
for (int idx = 0; idx < ui->tabWidget->count(); idx++) {
|
for (int idx = 0; idx < ui->tabWidget->count(); idx++) {
|
||||||
if (isLegacyTab(ui->tabWidget->tabText(idx))) {
|
if (isLegacyTab(ui->tabWidget->tabText(idx))) {
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
// TODO: Switch to setTabVisible() once QT 5.15 is more wide spread
|
|
||||||
ui->tabWidget->setTabEnabled(idx, !state);
|
|
||||||
ui->tabWidget->setStyleSheet(
|
|
||||||
"QTabBar::tab::disabled {width: 0; height: 0; margin: 0; padding: 0; border: none;} ");
|
|
||||||
#else
|
|
||||||
ui->tabWidget->setTabVisible(idx, !state);
|
ui->tabWidget->setTabVisible(idx, !state);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,67 +357,6 @@ void AdvSceneSwitcher::on_importSettings_clicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findTabIndex(QTabWidget *tabWidget, int pos)
|
|
||||||
{
|
|
||||||
int at = -1;
|
|
||||||
QString tabName = tabNames.at(pos);
|
|
||||||
QWidget *page = tabWidget->findChild<QWidget *>(tabName);
|
|
||||||
if (page) {
|
|
||||||
at = tabWidget->indexOf(page);
|
|
||||||
}
|
|
||||||
if (at == -1) {
|
|
||||||
blog(LOG_INFO, "failed to find tab %s",
|
|
||||||
tabName.toUtf8().constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
return at;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool tabWidgetOrderValid()
|
|
||||||
{
|
|
||||||
auto tmp = std::vector<int>(tabNames.size());
|
|
||||||
std::iota(tmp.begin(), tmp.end(), 0);
|
|
||||||
|
|
||||||
for (auto &p : tmp) {
|
|
||||||
auto it = std::find(tabOrder.begin(), tabOrder.end(), p);
|
|
||||||
if (it == tabOrder.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void resetTabWidgetOrder()
|
|
||||||
{
|
|
||||||
tabOrder = std::vector<int>(tabNames.size());
|
|
||||||
std::iota(tabOrder.begin(), tabOrder.end(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::SetTabOrder()
|
|
||||||
{
|
|
||||||
if (!tabWidgetOrderValid()) {
|
|
||||||
resetTabWidgetOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
QTabBar *bar = ui->tabWidget->tabBar();
|
|
||||||
for (int i = 0; i < bar->count(); ++i) {
|
|
||||||
int curPos = findTabIndex(ui->tabWidget, tabOrder[i]);
|
|
||||||
|
|
||||||
if (i != curPos && curPos != -1) {
|
|
||||||
bar->moveTab(curPos, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(bar, &QTabBar::tabMoved, this, &AdvSceneSwitcher::on_tabMoved);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::SetCurrentTab()
|
|
||||||
{
|
|
||||||
if (switcher->lastOpenedTab >= 0) {
|
|
||||||
ui->tabWidget->setCurrentIndex(switcher->lastOpenedTab);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool windowPosValid(QPoint pos)
|
static bool windowPosValid(QPoint pos)
|
||||||
{
|
{
|
||||||
return !!QGuiApplication::screenAt(pos);
|
return !!QGuiApplication::screenAt(pos);
|
||||||
@@ -447,17 +379,12 @@ void AdvSceneSwitcher::CheckFirstTimeSetup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_tabMoved(int from, int to)
|
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
|
||||||
{
|
{
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::swap(tabOrder[from], tabOrder[to]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_tabWidget_currentChanged(int)
|
|
||||||
{
|
|
||||||
switcher->showFrame = false;
|
switcher->showFrame = false;
|
||||||
ClearFrames(ui->screenRegionSwitches);
|
ClearFrames(ui->screenRegionSwitches);
|
||||||
SetShowFrames();
|
SetShowFrames();
|
||||||
@@ -515,7 +442,7 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LoadMacros(obj);
|
LoadMacros(obj);
|
||||||
LoadGlobalMacroProperties(obj);
|
LoadGlobalMacroSettings(obj);
|
||||||
loadWindowTitleSwitches(obj);
|
loadWindowTitleSwitches(obj);
|
||||||
loadScreenRegionSwitches(obj);
|
loadScreenRegionSwitches(obj);
|
||||||
loadPauseSwitches(obj);
|
loadPauseSwitches(obj);
|
||||||
@@ -538,7 +465,7 @@ void SwitcherData::LoadSettings(obs_data_t *obj)
|
|||||||
RunPostLoadSteps();
|
RunPostLoadSteps();
|
||||||
|
|
||||||
// Reset on startup and scene collection change
|
// Reset on startup and scene collection change
|
||||||
switcher->lastOpenedTab = -1;
|
ResetLastOpenedTab();
|
||||||
startupLoadDone = true;
|
startupLoadDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +477,7 @@ void SwitcherData::SaveSettings(obs_data_t *obj)
|
|||||||
|
|
||||||
saveSceneGroups(obj);
|
saveSceneGroups(obj);
|
||||||
SaveMacros(obj);
|
SaveMacros(obj);
|
||||||
SaveGlobalMacroProperties(obj);
|
SaveGlobalMacroSettings(obj);
|
||||||
SaveVariables(obj);
|
SaveVariables(obj);
|
||||||
saveWindowTitleSwitches(obj);
|
saveWindowTitleSwitches(obj);
|
||||||
saveScreenRegionSwitches(obj);
|
saveScreenRegionSwitches(obj);
|
||||||
@@ -589,6 +516,7 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
|||||||
noMatchDelay.Save(obj, "noMatchDelay");
|
noMatchDelay.Save(obj, "noMatchDelay");
|
||||||
|
|
||||||
cooldown.Save(obj, "cooldown");
|
cooldown.Save(obj, "cooldown");
|
||||||
|
obs_data_set_bool(obj, "enableCooldown", enableCooldown);
|
||||||
|
|
||||||
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
|
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
|
||||||
sceneColletionStop = false;
|
sceneColletionStop = false;
|
||||||
@@ -598,7 +526,7 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
|||||||
obs_data_set_int(obj, "autoStartEvent",
|
obs_data_set_int(obj, "autoStartEvent",
|
||||||
static_cast<int>(autoStartEvent));
|
static_cast<int>(autoStartEvent));
|
||||||
|
|
||||||
obs_data_set_bool(obj, "verbose", verbose);
|
obs_data_set_int(obj, "logLevel", static_cast<int>(logLevel));
|
||||||
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);
|
||||||
@@ -634,6 +562,11 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
noMatchDelay.Load(obj, "noMatchDelay");
|
noMatchDelay.Load(obj, "noMatchDelay");
|
||||||
|
|
||||||
cooldown.Load(obj, "cooldown");
|
cooldown.Load(obj, "cooldown");
|
||||||
|
if (!obs_data_has_user_value(obj, "enableCooldown")) {
|
||||||
|
enableCooldown = cooldown.Seconds() != 0;
|
||||||
|
} else {
|
||||||
|
enableCooldown = obs_data_get_bool(obj, "enableCooldown");
|
||||||
|
}
|
||||||
|
|
||||||
obs_data_set_default_bool(obj, "active", true);
|
obs_data_set_default_bool(obj, "active", true);
|
||||||
stop = !obs_data_get_bool(obj, "active");
|
stop = !obs_data_get_bool(obj, "active");
|
||||||
@@ -649,7 +582,7 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
autoStartEvent =
|
autoStartEvent =
|
||||||
static_cast<AutoStart>(obs_data_get_int(obj, "autoStartEvent"));
|
static_cast<AutoStart>(obs_data_get_int(obj, "autoStartEvent"));
|
||||||
|
|
||||||
verbose = obs_data_get_bool(obj, "verbose");
|
logLevel = static_cast<LogLevel>(obs_data_get_int(obj, "logLevel"));
|
||||||
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");
|
||||||
@@ -686,13 +619,7 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
|||||||
|
|
||||||
void SwitcherData::SaveUISettings(obs_data_t *obj)
|
void SwitcherData::SaveUISettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
OBSDataArrayAutoRelease tabWidgetOrder = obs_data_array_create();
|
SaveTabOrder(obj);
|
||||||
for (size_t i = 0; i < tabNames.size(); i++) {
|
|
||||||
OBSDataAutoRelease entry = obs_data_create();
|
|
||||||
obs_data_set_int(entry, tabNames[i], tabOrder[i]);
|
|
||||||
obs_data_array_push_back(tabWidgetOrder, entry);
|
|
||||||
}
|
|
||||||
obs_data_set_array(obj, "tabWidgetOrder", tabWidgetOrder);
|
|
||||||
|
|
||||||
obs_data_set_bool(obj, "saveWindowGeo", saveWindowGeo);
|
obs_data_set_bool(obj, "saveWindowGeo", saveWindowGeo);
|
||||||
obs_data_set_int(obj, "windowPosX", windowPos.x());
|
obs_data_set_int(obj, "windowPosX", windowPos.x());
|
||||||
@@ -706,28 +633,7 @@ void SwitcherData::SaveUISettings(obs_data_t *obj)
|
|||||||
|
|
||||||
void SwitcherData::LoadUISettings(obs_data_t *obj)
|
void SwitcherData::LoadUISettings(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
OBSDataArrayAutoRelease defaultTabWidgetOrder = obs_data_array_create();
|
LoadTabOrder(obj);
|
||||||
for (size_t i = 0; i < tabNames.size(); i++) {
|
|
||||||
OBSDataAutoRelease entry = obs_data_create();
|
|
||||||
obs_data_set_default_int(entry, tabNames[i], i);
|
|
||||||
obs_data_array_push_back(defaultTabWidgetOrder, entry);
|
|
||||||
}
|
|
||||||
obs_data_set_default_array(obj, "tabWidgetOrder",
|
|
||||||
defaultTabWidgetOrder);
|
|
||||||
|
|
||||||
tabOrder.clear();
|
|
||||||
OBSDataArrayAutoRelease tabWidgetOrder =
|
|
||||||
obs_data_get_array(obj, "tabWidgetOrder");
|
|
||||||
for (size_t i = 0; i < tabNames.size(); i++) {
|
|
||||||
OBSDataAutoRelease entry =
|
|
||||||
obs_data_array_item(tabWidgetOrder, i);
|
|
||||||
tabOrder.emplace_back(
|
|
||||||
(int)(obs_data_get_int(entry, tabNames[i])));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tabWidgetOrderValid()) {
|
|
||||||
resetTabWidgetOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
saveWindowGeo = obs_data_get_bool(obj, "saveWindowGeo");
|
saveWindowGeo = obs_data_get_bool(obj, "saveWindowGeo");
|
||||||
windowPos = {(int)obs_data_get_int(obj, "windowPosX"),
|
windowPos = {(int)obs_data_get_int(obj, "windowPosX"),
|
||||||
@@ -764,7 +670,7 @@ void SwitcherData::CheckNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
|||||||
|
|
||||||
void SwitcherData::checkSwitchCooldown(bool &match)
|
void SwitcherData::checkSwitchCooldown(bool &match)
|
||||||
{
|
{
|
||||||
if (!match) {
|
if (!match || !enableCooldown) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,6 +839,8 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
|
|
||||||
ui->checkInterval->setValue(switcher->interval);
|
ui->checkInterval->setValue(switcher->interval);
|
||||||
|
|
||||||
|
ui->enableCooldown->setChecked(switcher->enableCooldown);
|
||||||
|
ui->cooldownTime->setEnabled(switcher->enableCooldown);
|
||||||
ui->cooldownTime->SetDuration(switcher->cooldown);
|
ui->cooldownTime->SetDuration(switcher->cooldown);
|
||||||
ui->cooldownTime->setToolTip(obs_module_text(
|
ui->cooldownTime->setToolTip(obs_module_text(
|
||||||
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
|
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
|
||||||
@@ -940,7 +848,8 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
|||||||
SIGNAL(DurationChanged(const Duration &)), this,
|
SIGNAL(DurationChanged(const Duration &)), this,
|
||||||
SLOT(CooldownDurationChanged(const Duration &)));
|
SLOT(CooldownDurationChanged(const Duration &)));
|
||||||
|
|
||||||
ui->verboseLogging->setChecked(switcher->verbose);
|
ui->logLevel->setCurrentIndex(static_cast<int>(switcher->logLevel));
|
||||||
|
|
||||||
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
|
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
|
||||||
ui->showTrayNotifications->setChecked(
|
ui->showTrayNotifications->setChecked(
|
||||||
switcher->showSystemTrayNotifications);
|
switcher->showSystemTrayNotifications);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
SceneGroupEditWidget *typeEdit = nullptr;
|
SceneGroupEditWidget *typeEdit = nullptr;
|
||||||
|
|
||||||
std::deque<SceneGroup> &GetSceneGroups()
|
std::deque<SceneGroup> &GetSceneGroups()
|
||||||
@@ -141,7 +141,7 @@ void AdvSceneSwitcher::on_sceneGroupAdd_clicked()
|
|||||||
placeHolderText = format.arg(++i);
|
placeHolderText = format.arg(++i);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool accepted = AdvSSNameDialog::AskForName(
|
bool accepted = NameDialog::AskForName(
|
||||||
this, obs_module_text("AdvSceneSwitcher.sceneGroupTab.add"),
|
this, obs_module_text("AdvSceneSwitcher.sceneGroupTab.add"),
|
||||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.add"), name,
|
obs_module_text("AdvSceneSwitcher.sceneGroupTab.add"), name,
|
||||||
placeHolderText);
|
placeHolderText);
|
||||||
@@ -170,7 +170,10 @@ void AdvSceneSwitcher::on_sceneGroupAdd_clicked()
|
|||||||
item->setData(Qt::UserRole, text);
|
item->setData(Qt::UserRole, text);
|
||||||
ui->sceneGroups->setCurrentItem(item);
|
ui->sceneGroups->setCurrentItem(item);
|
||||||
|
|
||||||
ui->sceneGroupAdd->disconnect(addPulse);
|
if (addPulse) {
|
||||||
|
addPulse->deleteLater();
|
||||||
|
addPulse = nullptr;
|
||||||
|
}
|
||||||
ui->sceneGroupHelp->setVisible(false);
|
ui->sceneGroupHelp->setVisible(false);
|
||||||
|
|
||||||
emit SceneGroupAdded(QString::fromStdString(name));
|
emit SceneGroupAdded(QString::fromStdString(name));
|
||||||
@@ -512,8 +515,8 @@ void AdvSceneSwitcher::SetupSceneGroupTab()
|
|||||||
|
|
||||||
if (switcher->sceneGroups.size() == 0) {
|
if (switcher->sceneGroups.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->sceneGroupAdd,
|
addPulse = HighlightWidget(ui->sceneGroupAdd,
|
||||||
QColor(Qt::green));
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->sceneGroupHelp->setVisible(true);
|
ui->sceneGroupHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool SceneTrigger::pause = false;
|
bool SceneTrigger::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_triggerAdd_clicked()
|
void AdvSceneSwitcher::on_triggerAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -22,7 +22,7 @@ void AdvSceneSwitcher::on_triggerAdd_clicked()
|
|||||||
listAddClicked(ui->sceneTriggers,
|
listAddClicked(ui->sceneTriggers,
|
||||||
new SceneTriggerWidget(this,
|
new SceneTriggerWidget(this,
|
||||||
&switcher->sceneTriggers.back()),
|
&switcher->sceneTriggers.back()),
|
||||||
ui->triggerAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->triggerHelp->setVisible(false);
|
ui->triggerHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -370,8 +370,8 @@ void AdvSceneSwitcher::SetupTriggerTab()
|
|||||||
|
|
||||||
if (switcher->sceneTriggers.size() == 0) {
|
if (switcher->sceneTriggers.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse =
|
addPulse = HighlightWidget(ui->triggerAdd,
|
||||||
PulseWidget(ui->triggerAdd, QColor(Qt::green));
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->triggerHelp->setVisible(true);
|
ui->triggerHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool AudioSwitch::pause = false;
|
bool AudioSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_audioAdd_clicked()
|
void AdvSceneSwitcher::on_audioAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -22,7 +22,7 @@ void AdvSceneSwitcher::on_audioAdd_clicked()
|
|||||||
AudioSwitchWidget *sw =
|
AudioSwitchWidget *sw =
|
||||||
new AudioSwitchWidget(this, &switcher->audioSwitches.back());
|
new AudioSwitchWidget(this, &switcher->audioSwitches.back());
|
||||||
|
|
||||||
listAddClicked(ui->audioSwitches, sw, ui->audioAdd, &addPulse);
|
listAddClicked(ui->audioSwitches, sw, &addPulse);
|
||||||
|
|
||||||
ui->audioHelp->setVisible(false);
|
ui->audioHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ void SwitcherData::checkAudioSwitchFallback(OBSWeakSource &scene,
|
|||||||
scene = audioFallback.getScene();
|
scene = audioFallback.getScene();
|
||||||
transition = audioFallback.transition;
|
transition = audioFallback.transition;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
audioFallback.logMatch();
|
audioFallback.logMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ bool SwitcherData::checkAudioSwitch(OBSWeakSource &scene,
|
|||||||
transition = s.transition;
|
transition = s.transition;
|
||||||
match = true;
|
match = true;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +232,8 @@ void AdvSceneSwitcher::SetupAudioTab()
|
|||||||
|
|
||||||
if (switcher->audioSwitches.size() == 0) {
|
if (switcher->audioSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->audioAdd, QColor(Qt::green));
|
addPulse = HighlightWidget(ui->audioAdd,
|
||||||
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->audioHelp->setVisible(true);
|
ui->audioHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
@@ -437,10 +438,8 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
|||||||
audioVolumeThreshold->setMaximum(100);
|
audioVolumeThreshold->setMaximum(100);
|
||||||
audioVolumeThreshold->setMinimum(0);
|
audioVolumeThreshold->setMinimum(0);
|
||||||
|
|
||||||
QWidget::connect(volMeter->GetSlider(), SIGNAL(valueChanged(int)),
|
QWidget::connect(volMeter->GetSlider(), &DoubleSlider::DoubleValChanged,
|
||||||
audioVolumeThreshold, SLOT(setValue(int)));
|
[=](double) { SyncSliderAndValueSelection(true); });
|
||||||
QWidget::connect(audioVolumeThreshold, SIGNAL(valueChanged(int)),
|
|
||||||
volMeter->GetSlider(), SLOT(setValue(int)));
|
|
||||||
QWidget::connect(audioVolumeThreshold, SIGNAL(valueChanged(int)), this,
|
QWidget::connect(audioVolumeThreshold, SIGNAL(valueChanged(int)), this,
|
||||||
SLOT(VolumeThresholdChanged(int)));
|
SLOT(VolumeThresholdChanged(int)));
|
||||||
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
|
||||||
@@ -487,6 +486,7 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
|||||||
switchData = s;
|
switchData = s;
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
|
SyncSliderAndValueSelection(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioSwitch *AudioSwitchWidget::getSwitchData()
|
AudioSwitch *AudioSwitchWidget::getSwitchData()
|
||||||
@@ -509,6 +509,21 @@ void AudioSwitchWidget::swapSwitchData(AudioSwitchWidget *s1,
|
|||||||
s2->setSwitchData(t);
|
s2->setSwitchData(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioSwitchWidget::SyncSliderAndValueSelection(bool sliderMoved)
|
||||||
|
{
|
||||||
|
if (loading || !switchData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sliderMoved) {
|
||||||
|
auto sliderPosition = volMeter->GetSlider()->DoubleValue();
|
||||||
|
audioVolumeThreshold->setValue(sliderPosition);
|
||||||
|
} else {
|
||||||
|
volMeter->GetSlider()->SetDoubleVal(
|
||||||
|
switchData->volumeThreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AudioSwitchWidget::UpdateVolmeterSource()
|
void AudioSwitchWidget::UpdateVolmeterSource()
|
||||||
{
|
{
|
||||||
delete volMeter;
|
delete volMeter;
|
||||||
@@ -520,10 +535,8 @@ void AudioSwitchWidget::UpdateVolmeterSource()
|
|||||||
QLayout *layout = this->layout();
|
QLayout *layout = this->layout();
|
||||||
layout->addWidget(volMeter);
|
layout->addWidget(volMeter);
|
||||||
|
|
||||||
QWidget::connect(volMeter->GetSlider(), SIGNAL(valueChanged(int)),
|
QWidget::connect(volMeter->GetSlider(), &DoubleSlider::DoubleValChanged,
|
||||||
audioVolumeThreshold, SLOT(setValue(int)));
|
[=](double) { SyncSliderAndValueSelection(true); });
|
||||||
QWidget::connect(audioVolumeThreshold, SIGNAL(valueChanged(int)),
|
|
||||||
volMeter->GetSlider(), SLOT(setValue(int)));
|
|
||||||
|
|
||||||
// Slider will default to 0 so set it manually once
|
// Slider will default to 0 so set it manually once
|
||||||
volMeter->GetSlider()->setValue(switchData->volumeThreshold);
|
volMeter->GetSlider()->setValue(switchData->volumeThreshold);
|
||||||
@@ -547,8 +560,11 @@ void AudioSwitchWidget::VolumeThresholdChanged(int vol)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(switcher->m);
|
{
|
||||||
switchData->volumeThreshold = vol;
|
std::lock_guard<std::mutex> lock(switcher->m);
|
||||||
|
switchData->volumeThreshold = vol;
|
||||||
|
}
|
||||||
|
SyncSliderAndValueSelection(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSwitchWidget::ConditionChanged(int cond)
|
void AudioSwitchWidget::ConditionChanged(int cond)
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ private slots:
|
|||||||
void ConditionChanged(int cond);
|
void ConditionChanged(int cond);
|
||||||
void DurationChanged(const Duration &);
|
void DurationChanged(const Duration &);
|
||||||
void IgnoreInactiveChanged(int state);
|
void IgnoreInactiveChanged(int state);
|
||||||
|
void SyncSliderAndValueSelection(bool sliderMoved);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QComboBox *audioSources;
|
QComboBox *audioSources;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool ExecutableSwitch::pause = false;
|
bool ExecutableSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_executableAdd_clicked()
|
void AdvSceneSwitcher::on_executableAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -19,7 +19,7 @@ void AdvSceneSwitcher::on_executableAdd_clicked()
|
|||||||
listAddClicked(ui->executables,
|
listAddClicked(ui->executables,
|
||||||
new ExecutableSwitchWidget(
|
new ExecutableSwitchWidget(
|
||||||
this, &switcher->executableSwitches.back()),
|
this, &switcher->executableSwitches.back()),
|
||||||
ui->executableAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->exeHelp->setVisible(false);
|
ui->exeHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ bool SwitcherData::checkExeSwitch(OBSWeakSource &scene,
|
|||||||
scene = s.getScene();
|
scene = s.getScene();
|
||||||
transition = s.transition;
|
transition = s.transition;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -177,8 +177,8 @@ void AdvSceneSwitcher::SetupExecutableTab()
|
|||||||
|
|
||||||
if (switcher->executableSwitches.size() == 0) {
|
if (switcher->executableSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->executableAdd,
|
addPulse = HighlightWidget(ui->executableAdd,
|
||||||
QColor(Qt::green));
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->exeHelp->setVisible(true);
|
ui->exeHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool FileSwitch::pause = false;
|
bool FileSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
static std::hash<std::string> strHash;
|
static std::hash<std::string> strHash;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_browseButton_clicked()
|
void AdvSceneSwitcher::on_browseButton_clicked()
|
||||||
@@ -274,7 +274,7 @@ bool SwitcherData::checkFileContent(OBSWeakSource &scene,
|
|||||||
transition = s.transition;
|
transition = s.transition;
|
||||||
match = true;
|
match = true;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -291,7 +291,7 @@ void AdvSceneSwitcher::on_fileAdd_clicked()
|
|||||||
listAddClicked(ui->fileSwitches,
|
listAddClicked(ui->fileSwitches,
|
||||||
new FileSwitchWidget(this,
|
new FileSwitchWidget(this,
|
||||||
&switcher->fileSwitches.back()),
|
&switcher->fileSwitches.back()),
|
||||||
ui->fileAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->fileHelp->setVisible(false);
|
ui->fileHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -441,7 +441,8 @@ void AdvSceneSwitcher::SetupFileTab()
|
|||||||
|
|
||||||
if (switcher->fileSwitches.size() == 0) {
|
if (switcher->fileSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->fileAdd, QColor(Qt::green));
|
addPulse =
|
||||||
|
HighlightWidget(ui->fileAdd, QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->fileHelp->setVisible(true);
|
ui->fileHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ bool SwitcherData::checkIdleSwitch(OBSWeakSource &scene,
|
|||||||
match = true;
|
match = true;
|
||||||
idleData.alreadySwitched = true;
|
idleData.alreadySwitched = true;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
idleData.logMatch();
|
idleData.logMatch();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool MediaSwitch::pause = false;
|
bool MediaSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
constexpr auto media_played_to_end_idx = 8;
|
constexpr auto media_played_to_end_idx = 8;
|
||||||
constexpr auto media_any_idx = 9;
|
constexpr auto media_any_idx = 9;
|
||||||
@@ -22,7 +22,7 @@ void AdvSceneSwitcher::on_mediaAdd_clicked()
|
|||||||
listAddClicked(ui->mediaSwitches,
|
listAddClicked(ui->mediaSwitches,
|
||||||
new MediaSwitchWidget(this,
|
new MediaSwitchWidget(this,
|
||||||
&switcher->mediaSwitches.back()),
|
&switcher->mediaSwitches.back()),
|
||||||
ui->mediaAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->mediaHelp->setVisible(false);
|
ui->mediaHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ bool SwitcherData::checkMediaSwitch(OBSWeakSource &scene,
|
|||||||
scene = mediaSwitch.getScene();
|
scene = mediaSwitch.getScene();
|
||||||
transition = mediaSwitch.transition;
|
transition = mediaSwitch.transition;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
mediaSwitch.logMatch();
|
mediaSwitch.logMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,7 +252,8 @@ void AdvSceneSwitcher::SetupMediaTab()
|
|||||||
|
|
||||||
if (switcher->mediaSwitches.size() == 0) {
|
if (switcher->mediaSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->mediaAdd, QColor(Qt::green));
|
addPulse = HighlightWidget(ui->mediaAdd,
|
||||||
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->mediaHelp->setVisible(true);
|
ui->mediaHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ void WSServer::sendMessage(SceneSwitchInfo sceneSwitch, bool preview)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switcher->verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
blog(LOG_INFO, "server sent message:\n%s", message.c_str());
|
blog(LOG_INFO, "server sent message:\n%s", message.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,7 +305,7 @@ std::string processMessage(std::string payload)
|
|||||||
std::string ret = "message ok";
|
std::string ret = "message ok";
|
||||||
|
|
||||||
auto transition = GetWeakTransitionByName(transitionName.c_str());
|
auto transition = GetWeakTransitionByName(transitionName.c_str());
|
||||||
if (switcher->verbose && !transition) {
|
if (VerboseLoggingEnabled() && !transition) {
|
||||||
ret += " - ignoring invalid transition: '" + transitionName +
|
ret += " - ignoring invalid transition: '" + transitionName +
|
||||||
"'";
|
"'";
|
||||||
}
|
}
|
||||||
@@ -481,7 +481,7 @@ void WSClient::onMessage(connection_hdl hdl, client::message_ptr message)
|
|||||||
errorCodeMessage.c_str());
|
errorCodeMessage.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switcher->verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
blog(LOG_INFO, "client sent message:\n%s", response.c_str());
|
blog(LOG_INFO, "client sent message:\n%s", response.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,6 +132,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
QRunnable *CreateFunctionRunnable(std::function<void()> func);
|
QRunnable *CreateFunctionRunnable(std::function<void()> func);
|
||||||
}
|
} // namespace Compatability
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_pauseAdd_clicked()
|
void AdvSceneSwitcher::on_pauseAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -20,7 +20,7 @@ void AdvSceneSwitcher::on_pauseAdd_clicked()
|
|||||||
listAddClicked(ui->pauseEntries,
|
listAddClicked(ui->pauseEntries,
|
||||||
new PauseEntryWidget(this,
|
new PauseEntryWidget(this,
|
||||||
&switcher->pauseEntries.back()),
|
&switcher->pauseEntries.back()),
|
||||||
ui->pauseAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->pauseHelp->setVisible(false);
|
ui->pauseHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,8 @@ void AdvSceneSwitcher::SetupPauseTab()
|
|||||||
|
|
||||||
if (switcher->pauseEntries.size() == 0) {
|
if (switcher->pauseEntries.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->pauseAdd, QColor(Qt::green));
|
addPulse = HighlightWidget(ui->pauseAdd,
|
||||||
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->pauseHelp->setVisible(true);
|
ui->pauseHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool RandomSwitch::pause = false;
|
bool RandomSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_randomAdd_clicked()
|
void AdvSceneSwitcher::on_randomAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -19,7 +19,7 @@ void AdvSceneSwitcher::on_randomAdd_clicked()
|
|||||||
listAddClicked(ui->randomSwitches,
|
listAddClicked(ui->randomSwitches,
|
||||||
new RandomSwitchWidget(this,
|
new RandomSwitchWidget(this,
|
||||||
&switcher->randomSwitches.back()),
|
&switcher->randomSwitches.back()),
|
||||||
ui->randomAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->randomHelp->setVisible(false);
|
ui->randomHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ bool SwitcherData::checkRandom(OBSWeakSource &scene, OBSWeakSource &transition,
|
|||||||
lastRandomScene = r.scene;
|
lastRandomScene = r.scene;
|
||||||
lastRandomSceneGroup = r.group;
|
lastRandomSceneGroup = r.group;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
r.logMatch();
|
r.logMatch();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -131,8 +131,8 @@ void AdvSceneSwitcher::SetupRandomTab()
|
|||||||
|
|
||||||
if (switcher->randomSwitches.size() == 0) {
|
if (switcher->randomSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse =
|
addPulse = HighlightWidget(ui->randomAdd,
|
||||||
PulseWidget(ui->randomAdd, QColor(Qt::green));
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->randomHelp->setVisible(true);
|
ui->randomHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
@@ -147,8 +147,8 @@ void AdvSceneSwitcher::SetupRandomTab()
|
|||||||
}");
|
}");
|
||||||
if (switcher->switchIfNotMatching != NoMatchBehavior::RANDOM_SWITCH) {
|
if (switcher->switchIfNotMatching != NoMatchBehavior::RANDOM_SWITCH) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
PulseWidget(ui->randomDisabledWarning, QColor(Qt::red),
|
HighlightWidget(ui->randomDisabledWarning,
|
||||||
QColor(0, 0, 0, 0));
|
QColor(Qt::red), QColor(0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ui->randomDisabledWarning->setVisible(false);
|
ui->randomDisabledWarning->setVisible(false);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool ScreenRegionSwitch::pause = false;
|
bool ScreenRegionSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::ClearFrames(QListWidget *list)
|
void AdvSceneSwitcher::ClearFrames(QListWidget *list)
|
||||||
{
|
{
|
||||||
@@ -79,7 +79,7 @@ void AdvSceneSwitcher::on_screenRegionAdd_clicked()
|
|||||||
listAddClicked(ui->screenRegionSwitches,
|
listAddClicked(ui->screenRegionSwitches,
|
||||||
new ScreenRegionWidget(
|
new ScreenRegionWidget(
|
||||||
this, &switcher->screenRegionSwitches.back()),
|
this, &switcher->screenRegionSwitches.back()),
|
||||||
ui->screenRegionAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->regionHelp->setVisible(false);
|
ui->regionHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ bool SwitcherData::checkScreenRegionSwitch(OBSWeakSource &scene,
|
|||||||
transition = s.transition;
|
transition = s.transition;
|
||||||
minRegionSize = regionSize;
|
minRegionSize = regionSize;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -248,8 +248,8 @@ void AdvSceneSwitcher::SetupRegionTab()
|
|||||||
|
|
||||||
if (switcher->screenRegionSwitches.size() == 0) {
|
if (switcher->screenRegionSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->screenRegionAdd,
|
addPulse = HighlightWidget(ui->screenRegionAdd,
|
||||||
QColor(Qt::green));
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->regionHelp->setVisible(true);
|
ui->regionHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace advss {
|
|||||||
constexpr auto max_extend_text_size = 150;
|
constexpr auto max_extend_text_size = 150;
|
||||||
|
|
||||||
bool SceneSequenceSwitch::pause = false;
|
bool SceneSequenceSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_sceneSequenceAdd_clicked()
|
void AdvSceneSwitcher::on_sceneSequenceAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -26,7 +26,7 @@ void AdvSceneSwitcher::on_sceneSequenceAdd_clicked()
|
|||||||
listAddClicked(ui->sceneSequenceSwitches,
|
listAddClicked(ui->sceneSequenceSwitches,
|
||||||
new SequenceWidget(
|
new SequenceWidget(
|
||||||
this, &switcher->sceneSequenceSwitches.back()),
|
this, &switcher->sceneSequenceSwitches.back()),
|
||||||
ui->sceneSequenceAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->sequenceHelp->setVisible(false);
|
ui->sequenceHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -225,13 +225,13 @@ bool SwitcherData::checkSceneSequence(OBSWeakSource &scene,
|
|||||||
scene = s.getScene();
|
scene = s.getScene();
|
||||||
transition = s.transition;
|
transition = s.transition;
|
||||||
setPrevSceneAfterLinger = s.usePreviousScene;
|
setPrevSceneAfterLinger = s.usePreviousScene;
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.advanceActiveSequence();
|
s.advanceActiveSequence();
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logAdvanceSequence();
|
s.logAdvanceSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,8 +299,8 @@ void AdvSceneSwitcher::SetupSequenceTab()
|
|||||||
|
|
||||||
if (switcher->sceneSequenceSwitches.size() == 0) {
|
if (switcher->sceneSequenceSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->sceneSequenceAdd,
|
addPulse = HighlightWidget(ui->sceneSequenceAdd,
|
||||||
QColor(Qt::green));
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->sequenceHelp->setVisible(true);
|
ui->sequenceHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool TimeSwitch::pause = false;
|
bool TimeSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_timeAdd_clicked()
|
void AdvSceneSwitcher::on_timeAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -17,7 +17,7 @@ void AdvSceneSwitcher::on_timeAdd_clicked()
|
|||||||
listAddClicked(ui->timeSwitches,
|
listAddClicked(ui->timeSwitches,
|
||||||
new TimeSwitchWidget(this,
|
new TimeSwitchWidget(this,
|
||||||
&switcher->timeSwitches.back()),
|
&switcher->timeSwitches.back()),
|
||||||
ui->timeAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->timeHelp->setVisible(false);
|
ui->timeHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ bool SwitcherData::checkTimeSwitch(OBSWeakSource &scene,
|
|||||||
transition = s.transition;
|
transition = s.transition;
|
||||||
match = true;
|
match = true;
|
||||||
|
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -197,7 +197,8 @@ void AdvSceneSwitcher::SetupTimeTab()
|
|||||||
|
|
||||||
if (switcher->timeSwitches.size() == 0) {
|
if (switcher->timeSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->timeAdd, QColor(Qt::green));
|
addPulse =
|
||||||
|
HighlightWidget(ui->timeAdd, QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->timeHelp->setVisible(true);
|
ui->timeHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ void SwitcherData::checkDefaultSceneTransitions()
|
|||||||
|
|
||||||
for (auto &t : defaultSceneTransitions) {
|
for (auto &t : defaultSceneTransitions) {
|
||||||
if (t.checkMatch(currentScene)) {
|
if (t.checkMatch(currentScene)) {
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
t.logMatch();
|
t.logMatch();
|
||||||
}
|
}
|
||||||
t.setTransition();
|
t.setTransition();
|
||||||
@@ -427,7 +427,8 @@ 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"),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool VideoSwitch::pause = false;
|
bool VideoSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_videoAdd_clicked()
|
void AdvSceneSwitcher::on_videoAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -24,7 +24,7 @@ void AdvSceneSwitcher::on_videoAdd_clicked()
|
|||||||
VideoSwitchWidget *sw =
|
VideoSwitchWidget *sw =
|
||||||
new VideoSwitchWidget(this, &switcher->videoSwitches.back());
|
new VideoSwitchWidget(this, &switcher->videoSwitches.back());
|
||||||
|
|
||||||
listAddClicked(ui->videoSwitches, sw, ui->videoAdd, &addPulse);
|
listAddClicked(ui->videoSwitches, sw, &addPulse);
|
||||||
|
|
||||||
ui->videoHelp->setVisible(false);
|
ui->videoHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ bool SwitcherData::checkVideoSwitch(OBSWeakSource &scene,
|
|||||||
match = true;
|
match = true;
|
||||||
scene = s.getScene();
|
scene = s.getScene();
|
||||||
transition = s.transition;
|
transition = s.transition;
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,8 @@ void AdvSceneSwitcher::SetupVideoTab()
|
|||||||
|
|
||||||
if (switcher->videoSwitches.size() == 0) {
|
if (switcher->videoSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse = PulseWidget(ui->videoAdd, QColor(Qt::green));
|
addPulse = HighlightWidget(ui->videoAdd,
|
||||||
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->videoHelp->setVisible(true);
|
ui->videoHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
bool WindowSwitch::pause = false;
|
bool WindowSwitch::pause = false;
|
||||||
static QMetaObject::Connection addPulse;
|
static QObject *addPulse = nullptr;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_windowAdd_clicked()
|
void AdvSceneSwitcher::on_windowAdd_clicked()
|
||||||
{
|
{
|
||||||
@@ -21,7 +21,7 @@ void AdvSceneSwitcher::on_windowAdd_clicked()
|
|||||||
listAddClicked(ui->windowSwitches,
|
listAddClicked(ui->windowSwitches,
|
||||||
new WindowSwitchWidget(this,
|
new WindowSwitchWidget(this,
|
||||||
&switcher->windowSwitches.back()),
|
&switcher->windowSwitches.back()),
|
||||||
ui->windowAdd, &addPulse);
|
&addPulse);
|
||||||
|
|
||||||
ui->windowHelp->setVisible(false);
|
ui->windowHelp->setVisible(false);
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ bool SwitcherData::checkWindowTitleSwitch(OBSWeakSource &scene,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
if (verbose) {
|
if (VerboseLoggingEnabled()) {
|
||||||
s.logMatch();
|
s.logMatch();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -335,8 +335,8 @@ void AdvSceneSwitcher::SetupTitleTab()
|
|||||||
|
|
||||||
if (switcher->windowSwitches.size() == 0) {
|
if (switcher->windowSwitches.size() == 0) {
|
||||||
if (!switcher->disableHints) {
|
if (!switcher->disableHints) {
|
||||||
addPulse =
|
addPulse = HighlightWidget(ui->windowAdd,
|
||||||
PulseWidget(ui->windowAdd, QColor(Qt::green));
|
QColor(Qt::green));
|
||||||
}
|
}
|
||||||
ui->windowHelp->setVisible(true);
|
ui->windowHelp->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
#include "macro-helpers.hpp"
|
#include "macro-helpers.hpp"
|
||||||
#include "macro-properties.hpp"
|
#include "macro-settings.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
#include "plugin-state-helpers.hpp"
|
||||||
#include "section.hpp"
|
#include "section.hpp"
|
||||||
#include "switch-button.hpp"
|
#include "switch-button.hpp"
|
||||||
|
|
||||||
@@ -28,8 +29,7 @@ static inline void populateActionSelection(QComboBox *list)
|
|||||||
MacroActionEdit::MacroActionEdit(QWidget *parent,
|
MacroActionEdit::MacroActionEdit(QWidget *parent,
|
||||||
std::shared_ptr<MacroAction> *entryData,
|
std::shared_ptr<MacroAction> *entryData,
|
||||||
const std::string &id)
|
const std::string &id)
|
||||||
: MacroSegmentEdit(GetGlobalMacroProperties()._highlightActions,
|
: MacroSegmentEdit(parent),
|
||||||
parent),
|
|
||||||
_actionSelection(new FilterComboBox()),
|
_actionSelection(new FilterComboBox()),
|
||||||
_enable(new SwitchButton()),
|
_enable(new SwitchButton()),
|
||||||
_entryData(entryData)
|
_entryData(entryData)
|
||||||
@@ -39,8 +39,6 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
|||||||
SLOT(ActionSelectionChanged(const QString &)));
|
SLOT(ActionSelectionChanged(const QString &)));
|
||||||
QWidget::connect(_enable, SIGNAL(checked(bool)), this,
|
QWidget::connect(_enable, SIGNAL(checked(bool)), this,
|
||||||
SLOT(ActionEnableChanged(bool)));
|
SLOT(ActionEnableChanged(bool)));
|
||||||
QWidget::connect(window(), SIGNAL(HighlightActionsChanged(bool)), this,
|
|
||||||
SLOT(EnableHighlight(bool)));
|
|
||||||
QWidget::connect(&_actionStateTimer, SIGNAL(timeout()), this,
|
QWidget::connect(&_actionStateTimer, SIGNAL(timeout()), this,
|
||||||
SLOT(UpdateActionState()));
|
SLOT(UpdateActionState()));
|
||||||
|
|
||||||
@@ -88,6 +86,7 @@ void MacroActionEdit::ActionSelectionChanged(const QString &text)
|
|||||||
*_entryData = MacroActionFactory::Create(id, macro);
|
*_entryData = MacroActionFactory::Create(id, macro);
|
||||||
(*_entryData)->SetIndex(idx);
|
(*_entryData)->SetIndex(idx);
|
||||||
(*_entryData)->PostLoad();
|
(*_entryData)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
}
|
}
|
||||||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||||
@@ -159,6 +158,34 @@ std::shared_ptr<MacroSegment> MacroActionEdit::Data() const
|
|||||||
return *_entryData;
|
return *_entryData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::AddMacroAction(Macro *macro, int idx,
|
||||||
|
const std::string &id, obs_data_t *data)
|
||||||
|
{
|
||||||
|
if (idx < 0 || idx > (int)macro->Actions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
macro->Actions().emplace(macro->Actions().begin() + idx,
|
||||||
|
MacroActionFactory::Create(id, macro));
|
||||||
|
if (data) {
|
||||||
|
macro->Actions().at(idx)->Load(data);
|
||||||
|
}
|
||||||
|
macro->Actions().at(idx)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
|
macro->UpdateActionIndices();
|
||||||
|
ui->actionsList->Insert(
|
||||||
|
idx,
|
||||||
|
new MacroActionEdit(this, ¯o->Actions()[idx], id));
|
||||||
|
SetActionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightAction(idx);
|
||||||
|
ui->actionsList->SetHelpMsgVisible(false);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::AddMacroAction(int idx)
|
void AdvSceneSwitcher::AddMacroAction(int idx)
|
||||||
{
|
{
|
||||||
auto macro = GetSelectedMacro();
|
auto macro = GetSelectedMacro();
|
||||||
@@ -167,6 +194,7 @@ void AdvSceneSwitcher::AddMacroAction(int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (idx < 0 || idx > (int)macro->Actions().size()) {
|
if (idx < 0 || idx > (int)macro->Actions().size()) {
|
||||||
|
assert(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,26 +204,13 @@ void AdvSceneSwitcher::AddMacroAction(int idx)
|
|||||||
} else {
|
} else {
|
||||||
id = MacroAction::GetDefaultID();
|
id = MacroAction::GetDefaultID();
|
||||||
}
|
}
|
||||||
{
|
|
||||||
auto lock = LockContext();
|
OBSDataAutoRelease data;
|
||||||
macro->Actions().emplace(
|
if (idx - 1 >= 0) {
|
||||||
macro->Actions().begin() + idx,
|
data = obs_data_create();
|
||||||
MacroActionFactory::Create(id, macro.get()));
|
macro->Actions().at(idx - 1)->Save(data);
|
||||||
if (idx - 1 >= 0) {
|
|
||||||
auto data = obs_data_create();
|
|
||||||
macro->Actions().at(idx - 1)->Save(data);
|
|
||||||
macro->Actions().at(idx)->Load(data);
|
|
||||||
macro->Actions().at(idx)->PostLoad();
|
|
||||||
obs_data_release(data);
|
|
||||||
}
|
|
||||||
macro->UpdateActionIndices();
|
|
||||||
ui->actionsList->Insert(
|
|
||||||
idx,
|
|
||||||
new MacroActionEdit(this, ¯o->Actions()[idx], id));
|
|
||||||
SetActionData(*macro);
|
|
||||||
}
|
}
|
||||||
HighlightAction(idx);
|
AddMacroAction(macro.get(), idx, id, data);
|
||||||
emit(MacroSegmentOrderChanged());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_actionAdd_clicked()
|
void AdvSceneSwitcher::on_actionAdd_clicked()
|
||||||
@@ -213,7 +228,6 @@ void AdvSceneSwitcher::on_actionAdd_clicked()
|
|||||||
if (currentActionIdx != -1) {
|
if (currentActionIdx != -1) {
|
||||||
MacroActionSelectionChanged(currentActionIdx + 1);
|
MacroActionSelectionChanged(currentActionIdx + 1);
|
||||||
}
|
}
|
||||||
ui->actionsList->SetHelpMsgVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
void AdvSceneSwitcher::RemoveMacroAction(int idx)
|
||||||
@@ -308,7 +322,6 @@ void AdvSceneSwitcher::on_elseActionAdd_clicked()
|
|||||||
if (currentElseActionIdx != -1) {
|
if (currentElseActionIdx != -1) {
|
||||||
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
|
MacroElseActionSelectionChanged(currentElseActionIdx + 1);
|
||||||
}
|
}
|
||||||
ui->elseActionsList->SetHelpMsgVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_elseActionRemove_clicked()
|
void AdvSceneSwitcher::on_elseActionRemove_clicked()
|
||||||
@@ -447,6 +460,36 @@ void AdvSceneSwitcher::MacroElseActionReorder(int to, int from)
|
|||||||
emit(MacroSegmentOrderChanged());
|
emit(MacroSegmentOrderChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::AddMacroElseAction(Macro *macro, int idx,
|
||||||
|
const std::string &id,
|
||||||
|
obs_data_t *data)
|
||||||
|
{
|
||||||
|
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto lock = LockContext();
|
||||||
|
macro->ElseActions().emplace(macro->ElseActions().begin() + idx,
|
||||||
|
MacroActionFactory::Create(id,
|
||||||
|
macro));
|
||||||
|
if (data) {
|
||||||
|
macro->ElseActions().at(idx)->Load(data);
|
||||||
|
}
|
||||||
|
macro->ElseActions().at(idx)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
|
macro->UpdateElseActionIndices();
|
||||||
|
ui->elseActionsList->Insert(
|
||||||
|
idx, new MacroActionEdit(
|
||||||
|
this, ¯o->ElseActions()[idx], id));
|
||||||
|
SetElseActionData(*macro);
|
||||||
|
}
|
||||||
|
HighlightElseAction(idx);
|
||||||
|
ui->elseActionsList->SetHelpMsgVisible(false);
|
||||||
|
emit(MacroSegmentOrderChanged());
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::AddMacroElseAction(int idx)
|
void AdvSceneSwitcher::AddMacroElseAction(int idx)
|
||||||
{
|
{
|
||||||
auto macro = GetSelectedMacro();
|
auto macro = GetSelectedMacro();
|
||||||
@@ -455,6 +498,7 @@ void AdvSceneSwitcher::AddMacroElseAction(int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
|
if (idx < 0 || idx > (int)macro->ElseActions().size()) {
|
||||||
|
assert(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,25 +508,13 @@ void AdvSceneSwitcher::AddMacroElseAction(int idx)
|
|||||||
} else {
|
} else {
|
||||||
id = MacroAction::GetDefaultID();
|
id = MacroAction::GetDefaultID();
|
||||||
}
|
}
|
||||||
{
|
|
||||||
auto lock = LockContext();
|
OBSDataAutoRelease data;
|
||||||
macro->ElseActions().emplace(
|
if (idx - 1 >= 0) {
|
||||||
macro->ElseActions().begin() + idx,
|
data = obs_data_create();
|
||||||
MacroActionFactory::Create(id, macro.get()));
|
macro->ElseActions().at(idx - 1)->Save(data);
|
||||||
if (idx - 1 >= 0) {
|
|
||||||
OBSDataAutoRelease data = obs_data_create();
|
|
||||||
macro->ElseActions().at(idx - 1)->Save(data);
|
|
||||||
macro->ElseActions().at(idx)->Load(data);
|
|
||||||
}
|
|
||||||
macro->ElseActions().at(idx)->PostLoad();
|
|
||||||
macro->UpdateElseActionIndices();
|
|
||||||
ui->elseActionsList->Insert(
|
|
||||||
idx, new MacroActionEdit(
|
|
||||||
this, ¯o->ElseActions()[idx], id));
|
|
||||||
SetElseActionData(*macro);
|
|
||||||
}
|
}
|
||||||
HighlightElseAction(idx);
|
AddMacroElseAction(macro.get(), idx, id, data);
|
||||||
emit(MacroSegmentOrderChanged());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::RemoveMacroElseAction(int idx)
|
void AdvSceneSwitcher::RemoveMacroElseAction(int idx)
|
||||||
@@ -503,7 +535,7 @@ void AdvSceneSwitcher::RemoveMacroElseAction(int idx)
|
|||||||
SetMacroAbortWait(true);
|
SetMacroAbortWait(true);
|
||||||
GetMacroWaitCV().notify_all();
|
GetMacroWaitCV().notify_all();
|
||||||
macro->UpdateElseActionIndices();
|
macro->UpdateElseActionIndices();
|
||||||
SetActionData(*macro);
|
SetElseActionData(*macro);
|
||||||
}
|
}
|
||||||
MacroElseActionSelectionChanged(-1);
|
MacroElseActionSelectionChanged(-1);
|
||||||
lastInteracted = MacroSection::ELSE_ACTIONS;
|
lastInteracted = MacroSection::ELSE_ACTIONS;
|
||||||
|
|||||||
@@ -1,7 +1,28 @@
|
|||||||
#include "macro-action-factory.hpp"
|
#include "macro-action-factory.hpp"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class MacroActionUnknown : public MacroAction {
|
||||||
|
public:
|
||||||
|
MacroActionUnknown(Macro *m) : MacroAction(m) {}
|
||||||
|
std::shared_ptr<MacroAction> Copy() const
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionUnknown>(GetMacro());
|
||||||
|
}
|
||||||
|
bool PerformAction() { return true; };
|
||||||
|
bool Save(obs_data_t *obj) const { return MacroAction::Save(obj); };
|
||||||
|
bool Load(obs_data_t *obj) { return MacroAction::Load(obj); };
|
||||||
|
std::string GetId() const { return "unknown"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
static std::recursive_mutex mutex;
|
||||||
|
|
||||||
std::map<std::string, MacroActionInfo> &MacroActionFactory::GetMap()
|
std::map<std::string, MacroActionInfo> &MacroActionFactory::GetMap()
|
||||||
{
|
{
|
||||||
static std::map<std::string, MacroActionInfo> _methods;
|
static std::map<std::string, MacroActionInfo> _methods;
|
||||||
@@ -10,6 +31,7 @@ std::map<std::string, MacroActionInfo> &MacroActionFactory::GetMap()
|
|||||||
|
|
||||||
bool MacroActionFactory::Register(const std::string &id, MacroActionInfo info)
|
bool MacroActionFactory::Register(const std::string &id, MacroActionInfo info)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (auto it = GetMap().find(id); it == GetMap().end()) {
|
if (auto it = GetMap().find(id); it == GetMap().end()) {
|
||||||
GetMap()[id] = info;
|
GetMap()[id] = info;
|
||||||
return true;
|
return true;
|
||||||
@@ -17,35 +39,61 @@ bool MacroActionFactory::Register(const std::string &id, MacroActionInfo info)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MacroActionFactory::Deregister(const std::string &id)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
|
if (GetMap().count(id) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GetMap().erase(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<MacroAction> createUnknownAction(Macro *m)
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionUnknown>(m);
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<MacroAction> MacroActionFactory::Create(const std::string &id,
|
std::shared_ptr<MacroAction> MacroActionFactory::Create(const std::string &id,
|
||||||
Macro *m)
|
Macro *m)
|
||||||
{
|
{
|
||||||
if (auto it = GetMap().find(id); it != GetMap().end())
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._create(m);
|
return it->second._create(m);
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return createUnknownAction(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QWidget *createUnknownActionWidget()
|
||||||
|
{
|
||||||
|
return new QLabel(obs_module_text("AdvSceneSwitcher.action.unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *MacroActionFactory::CreateWidget(const std::string &id,
|
QWidget *MacroActionFactory::CreateWidget(const std::string &id,
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
std::shared_ptr<MacroAction> action)
|
std::shared_ptr<MacroAction> action)
|
||||||
{
|
{
|
||||||
if (auto it = GetMap().find(id); it != GetMap().end())
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._createWidget(parent, action);
|
return it->second._createWidget(parent, action);
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return createUnknownActionWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MacroActionFactory::GetActionName(const std::string &id)
|
std::string MacroActionFactory::GetActionName(const std::string &id)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._name;
|
return it->second._name;
|
||||||
}
|
}
|
||||||
return "unknown action";
|
return obs_module_text("AdvSceneSwitcher.action.unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MacroActionFactory::GetIdByName(const QString &name)
|
std::string MacroActionFactory::GetIdByName(const QString &name)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
for (auto it : GetMap()) {
|
for (auto it : GetMap()) {
|
||||||
if (name == obs_module_text(it.second._name.c_str())) {
|
if (name == obs_module_text(it.second._name.c_str())) {
|
||||||
return it.first;
|
return it.first;
|
||||||
@@ -54,4 +102,14 @@ std::string MacroActionFactory::GetIdByName(const QString &name)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanCreateDefaultAction()
|
||||||
|
{
|
||||||
|
const auto action = MacroActionFactory::Create(
|
||||||
|
MacroAction::GetDefaultID().data(), nullptr);
|
||||||
|
if (!action) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return action->GetId() == MacroAction::GetDefaultID().data();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
struct MacroActionInfo {
|
struct MacroActionInfo {
|
||||||
using CreateAction = std::shared_ptr<MacroAction> (*)(Macro *m);
|
|
||||||
using CreateActionWidget = QWidget *(*)(QWidget *parent,
|
using CreateActionWidget = QWidget *(*)(QWidget *parent,
|
||||||
std::shared_ptr<MacroAction>);
|
std::shared_ptr<MacroAction>);
|
||||||
CreateAction _create = nullptr;
|
|
||||||
|
std::function<std::shared_ptr<MacroAction>(Macro *m)> _create = nullptr;
|
||||||
CreateActionWidget _createWidget = nullptr;
|
CreateActionWidget _createWidget = nullptr;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
};
|
};
|
||||||
@@ -19,6 +19,7 @@ public:
|
|||||||
MacroActionFactory() = delete;
|
MacroActionFactory() = delete;
|
||||||
|
|
||||||
EXPORT static bool Register(const std::string &id, MacroActionInfo);
|
EXPORT static bool Register(const std::string &id, MacroActionInfo);
|
||||||
|
static bool Deregister(const std::string &id);
|
||||||
static std::shared_ptr<MacroAction> Create(const std::string &id,
|
static std::shared_ptr<MacroAction> Create(const std::string &id,
|
||||||
Macro *m);
|
Macro *m);
|
||||||
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
||||||
@@ -31,4 +32,6 @@ private:
|
|||||||
static std::map<std::string, MacroActionInfo> &GetMap();
|
static std::map<std::string, MacroActionInfo> &GetMap();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool CanCreateDefaultAction();
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "macro-action-macro.hpp"
|
#include "macro-action-macro.hpp"
|
||||||
|
#include "help-icon.hpp"
|
||||||
#include "layout-helpers.hpp"
|
#include "layout-helpers.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
|
||||||
@@ -48,9 +49,7 @@ bool MacroActionMacro::PerformAction()
|
|||||||
macro->ResetRunCount();
|
macro->ResetRunCount();
|
||||||
break;
|
break;
|
||||||
case Action::RUN:
|
case Action::RUN:
|
||||||
if (!macro->Paused()) {
|
RunActions(macro.get());
|
||||||
macro->PerformActions(true, false, true);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Action::STOP:
|
case Action::STOP:
|
||||||
macro->Stop();
|
macro->Stop();
|
||||||
@@ -88,32 +87,32 @@ void MacroActionMacro::LogAction() const
|
|||||||
}
|
}
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case Action::PAUSE:
|
case Action::PAUSE:
|
||||||
vblog(LOG_INFO, "paused \"%s\"", macro->Name().c_str());
|
ablog(LOG_INFO, "paused \"%s\"", macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::UNPAUSE:
|
case Action::UNPAUSE:
|
||||||
vblog(LOG_INFO, "unpaused \"%s\"", macro->Name().c_str());
|
ablog(LOG_INFO, "unpaused \"%s\"", macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::RESET_COUNTER:
|
case Action::RESET_COUNTER:
|
||||||
vblog(LOG_INFO, "reset counter for \"%s\"",
|
ablog(LOG_INFO, "reset counter for \"%s\"",
|
||||||
macro->Name().c_str());
|
macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::RUN:
|
case Action::RUN:
|
||||||
vblog(LOG_INFO, "run nested macro \"%s\"",
|
ablog(LOG_INFO, "run nested macro \"%s\"",
|
||||||
macro->Name().c_str());
|
macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::STOP:
|
case Action::STOP:
|
||||||
vblog(LOG_INFO, "stopped macro \"%s\"", macro->Name().c_str());
|
ablog(LOG_INFO, "stopped macro \"%s\"", macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::DISABLE_ACTION:
|
case Action::DISABLE_ACTION:
|
||||||
vblog(LOG_INFO, "disabled action %d of macro \"%s\"",
|
ablog(LOG_INFO, "disabled action %d of macro \"%s\"",
|
||||||
_actionIndex.GetValue(), macro->Name().c_str());
|
_actionIndex.GetValue(), macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::ENABLE_ACTION:
|
case Action::ENABLE_ACTION:
|
||||||
vblog(LOG_INFO, "enabled action %d of macro \"%s\"",
|
ablog(LOG_INFO, "enabled action %d of macro \"%s\"",
|
||||||
_actionIndex.GetValue(), macro->Name().c_str());
|
_actionIndex.GetValue(), macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
case Action::TOGGLE_ACTION:
|
case Action::TOGGLE_ACTION:
|
||||||
vblog(LOG_INFO, "toggled action %d of macro \"%s\"",
|
ablog(LOG_INFO, "toggled action %d of macro \"%s\"",
|
||||||
_actionIndex.GetValue(), macro->Name().c_str());
|
_actionIndex.GetValue(), macro->Name().c_str());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -127,6 +126,7 @@ bool MacroActionMacro::Save(obs_data_t *obj) const
|
|||||||
_macro.Save(obj);
|
_macro.Save(obj);
|
||||||
_actionIndex.Save(obj, "actionIndex");
|
_actionIndex.Save(obj, "actionIndex");
|
||||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||||
|
_runOptions.Save(obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +137,15 @@ bool MacroActionMacro::Load(obs_data_t *obj)
|
|||||||
_actionIndex.Load(obj, "actionIndex");
|
_actionIndex.Load(obj, "actionIndex");
|
||||||
_action = static_cast<MacroActionMacro::Action>(
|
_action = static_cast<MacroActionMacro::Action>(
|
||||||
obs_data_get_int(obj, "action"));
|
obs_data_get_int(obj, "action"));
|
||||||
|
_runOptions.Load(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionMacro::PostLoad()
|
||||||
|
{
|
||||||
|
MacroRefAction::PostLoad();
|
||||||
|
MacroAction::PostLoad();
|
||||||
|
_runOptions.macro.PostLoad();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,11 +154,83 @@ std::string MacroActionMacro::GetShortDesc() const
|
|||||||
return _macro.Name();
|
return _macro.Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void populateActionSelection(QComboBox *list)
|
std::shared_ptr<MacroAction> MacroActionMacro::Create(Macro *m)
|
||||||
{
|
{
|
||||||
for (auto entry : actionTypes) {
|
return std::make_shared<MacroActionMacro>(m);
|
||||||
list->addItem(obs_module_text(entry.second.c_str()));
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MacroAction> MacroActionMacro::Copy() const
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionMacro>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacro::ResolveVariablesToFixedValues()
|
||||||
|
{
|
||||||
|
_actionIndex.ResolveVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void runActionsHelper(Macro *macro, bool runElseActions, bool setInputs,
|
||||||
|
const StringList &inputs)
|
||||||
|
{
|
||||||
|
if (setInputs) {
|
||||||
|
macro->GetInputVariables().SetValues(inputs);
|
||||||
}
|
}
|
||||||
|
macro->PerformActions(!runElseActions, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacro::RunActions(Macro *actionMacro) const
|
||||||
|
{
|
||||||
|
if (_runOptions.skipWhenPaused && actionMacro->Paused()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_runOptions.logic == RunOptions::Logic::IGNORE_CONDITIONS) {
|
||||||
|
runActionsHelper(actionMacro, _runOptions.runElseActions,
|
||||||
|
_runOptions.setInputs, _runOptions.inputs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto conditionMacro = _runOptions.macro.GetMacro();
|
||||||
|
if (!conditionMacro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_runOptions.reevaluateConditionState) {
|
||||||
|
conditionMacro->CeckMatch(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_runOptions.logic == RunOptions::Logic::CONDITIONS &&
|
||||||
|
conditionMacro->Matched()) ||
|
||||||
|
(_runOptions.logic == RunOptions::Logic::INVERT_CONDITIONS &&
|
||||||
|
!conditionMacro->Matched())) {
|
||||||
|
runActionsHelper(actionMacro, _runOptions.runElseActions,
|
||||||
|
_runOptions.setInputs, _runOptions.inputs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void populateActionSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
for (const auto &[_, name] : actionTypes) {
|
||||||
|
list->addItem(obs_module_text(name.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void populateConditionBehaviorSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
list->addItem(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.conditions.ignore"));
|
||||||
|
list->addItem(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.conditions.true"));
|
||||||
|
list->addItem(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.conditions.false"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void populateActionTypeSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
list->addItem(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.actionType.regular"));
|
||||||
|
list->addItem(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.actionType.else"));
|
||||||
}
|
}
|
||||||
|
|
||||||
MacroActionMacroEdit::MacroActionMacroEdit(
|
MacroActionMacroEdit::MacroActionMacroEdit(
|
||||||
@@ -158,9 +239,28 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
|||||||
_macros(new MacroSelection(parent)),
|
_macros(new MacroSelection(parent)),
|
||||||
_actionIndex(new MacroSegmentSelection(
|
_actionIndex(new MacroSegmentSelection(
|
||||||
this, MacroSegmentSelection::Type::ACTION)),
|
this, MacroSegmentSelection::Type::ACTION)),
|
||||||
_actions(new QComboBox())
|
_actions(new QComboBox()),
|
||||||
|
_conditionMacros(new MacroSelection(parent)),
|
||||||
|
_conditionBehaviors(new QComboBox()),
|
||||||
|
_reevaluateConditionState(new QCheckBox(
|
||||||
|
obs_module_text("AdvSceneSwitcher.action.macro.type.run."
|
||||||
|
"updateConditionMatchState"))),
|
||||||
|
_actionTypes(new QComboBox()),
|
||||||
|
_skipWhenPaused(new QCheckBox(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.skipWhenPaused"))),
|
||||||
|
_setInputs(new QCheckBox(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.setInputs"))),
|
||||||
|
_inputs(new MacroInputEdit()),
|
||||||
|
_entryLayout(new QHBoxLayout()),
|
||||||
|
_conditionLayout(new QHBoxLayout()),
|
||||||
|
_reevaluateConditionStateLayout(new QHBoxLayout()),
|
||||||
|
_setInputsLayout(new QHBoxLayout())
|
||||||
{
|
{
|
||||||
populateActionSelection(_actions);
|
populateActionSelection(_actions);
|
||||||
|
populateConditionBehaviorSelection(_conditionBehaviors);
|
||||||
|
populateActionTypeSelection(_actionTypes);
|
||||||
|
|
||||||
|
_conditionMacros->HideSelectedMacro();
|
||||||
|
|
||||||
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
|
||||||
this, SLOT(MacroChanged(const QString &)));
|
this, SLOT(MacroChanged(const QString &)));
|
||||||
@@ -169,20 +269,53 @@ MacroActionMacroEdit::MacroActionMacroEdit(
|
|||||||
QWidget::connect(_actionIndex,
|
QWidget::connect(_actionIndex,
|
||||||
SIGNAL(SelectionChanged(const IntVariable &)), this,
|
SIGNAL(SelectionChanged(const IntVariable &)), this,
|
||||||
SLOT(ActionIndexChanged(const IntVariable &)));
|
SLOT(ActionIndexChanged(const IntVariable &)));
|
||||||
|
QWidget::connect(_conditionMacros,
|
||||||
|
SIGNAL(currentTextChanged(const QString &)), this,
|
||||||
|
SLOT(ConditionMacroChanged(const QString &)));
|
||||||
|
QWidget::connect(_conditionBehaviors, SIGNAL(currentIndexChanged(int)),
|
||||||
|
this, SLOT(ConditionBehaviorChanged(int)));
|
||||||
|
QWidget::connect(_actionTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(ActionTypeChanged(int)));
|
||||||
|
QWidget::connect(_skipWhenPaused, SIGNAL(stateChanged(int)), this,
|
||||||
|
SLOT(SkipWhenPausedChanged(int)));
|
||||||
|
QWidget::connect(_setInputs, SIGNAL(stateChanged(int)), this,
|
||||||
|
SLOT(SetInputsChanged(int)));
|
||||||
|
QWidget::connect(_inputs,
|
||||||
|
SIGNAL(MacroInputValuesChanged(const StringList &)),
|
||||||
|
this, SLOT(InputsChanged(const StringList &)));
|
||||||
|
QWidget::connect(_reevaluateConditionState, SIGNAL(stateChanged(int)),
|
||||||
|
this, SLOT(ReevaluateConditionStateChanged(int)));
|
||||||
|
|
||||||
auto mainLayout = new QHBoxLayout;
|
_setInputsLayout->addWidget(_setInputs);
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.macro.entry"),
|
_setInputsLayout->addWidget(new HelpIcon(obs_module_text(
|
||||||
mainLayout,
|
"AdvSceneSwitcher.action.macro.type.run.setInputs.description")));
|
||||||
{{"{{actions}}", _actions},
|
_setInputsLayout->addStretch();
|
||||||
{"{{actionIndex}}", _actionIndex},
|
|
||||||
{"{{macros}}", _macros}});
|
|
||||||
setLayout(mainLayout);
|
|
||||||
|
|
||||||
|
_reevaluateConditionStateLayout->addWidget(_reevaluateConditionState);
|
||||||
|
_reevaluateConditionStateLayout->addWidget(new HelpIcon(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.type.run.updateConditionMatchState.help")));
|
||||||
|
_reevaluateConditionStateLayout->addStretch();
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout();
|
||||||
|
layout->addLayout(_entryLayout);
|
||||||
|
layout->addLayout(_conditionLayout);
|
||||||
|
layout->addLayout(_reevaluateConditionStateLayout);
|
||||||
|
layout->addLayout(_setInputsLayout);
|
||||||
|
layout->addWidget(_inputs);
|
||||||
|
layout->addWidget(_skipWhenPaused);
|
||||||
|
setLayout(layout);
|
||||||
_entryData = entryData;
|
_entryData = entryData;
|
||||||
UpdateEntryData();
|
UpdateEntryData();
|
||||||
_loading = false;
|
_loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HighligthMacroSettingsButton(bool enable);
|
||||||
|
|
||||||
|
MacroActionMacroEdit::~MacroActionMacroEdit()
|
||||||
|
{
|
||||||
|
HighligthMacroSettingsButton(false);
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::UpdateEntryData()
|
void MacroActionMacroEdit::UpdateEntryData()
|
||||||
{
|
{
|
||||||
if (!_entryData) {
|
if (!_entryData) {
|
||||||
@@ -192,45 +325,132 @@ void MacroActionMacroEdit::UpdateEntryData()
|
|||||||
_actionIndex->SetValue(_entryData->_actionIndex);
|
_actionIndex->SetValue(_entryData->_actionIndex);
|
||||||
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
|
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
|
||||||
_macros->SetCurrentMacro(_entryData->_macro);
|
_macros->SetCurrentMacro(_entryData->_macro);
|
||||||
|
_conditionMacros->SetCurrentMacro(_entryData->_runOptions.macro);
|
||||||
|
_conditionBehaviors->setCurrentIndex(
|
||||||
|
static_cast<int>(_entryData->_runOptions.logic));
|
||||||
|
_reevaluateConditionState->setChecked(
|
||||||
|
_entryData->_runOptions.reevaluateConditionState);
|
||||||
|
_actionTypes->setCurrentIndex(
|
||||||
|
_entryData->_runOptions.runElseActions ? 1 : 0);
|
||||||
|
_skipWhenPaused->setChecked(_entryData->_runOptions.skipWhenPaused);
|
||||||
|
_setInputs->setChecked(_entryData->_runOptions.setInputs);
|
||||||
|
SetupMacroInput(_entryData->_macro.GetMacro().get());
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::MacroChanged(const QString &text)
|
void MacroActionMacroEdit::MacroChanged(const QString &text)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
GUARD_LOADING_AND_LOCK();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
|
||||||
_entryData->_macro = text;
|
_entryData->_macro = text;
|
||||||
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
|
const auto ¯o = _entryData->_macro.GetMacro();
|
||||||
|
_actionIndex->SetMacro(macro);
|
||||||
|
SetupMacroInput(macro.get());
|
||||||
emit HeaderInfoChanged(
|
emit HeaderInfoChanged(
|
||||||
QString::fromStdString(_entryData->GetShortDesc()));
|
QString::fromStdString(_entryData->GetShortDesc()));
|
||||||
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::ActionChanged(int value)
|
void MacroActionMacroEdit::ActionChanged(int value)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
GUARD_LOADING_AND_LOCK();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
|
||||||
_entryData->_action = static_cast<MacroActionMacro::Action>(value);
|
_entryData->_action = static_cast<MacroActionMacro::Action>(value);
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::ActionIndexChanged(const IntVariable &value)
|
void MacroActionMacroEdit::ActionIndexChanged(const IntVariable &value)
|
||||||
{
|
{
|
||||||
if (_loading || !_entryData) {
|
GUARD_LOADING_AND_LOCK();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
|
||||||
_entryData->_actionIndex = value;
|
_entryData->_actionIndex = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::ConditionMacroChanged(const QString &text)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_runOptions.macro = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::ConditionBehaviorChanged(int value)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_runOptions.logic =
|
||||||
|
static_cast<MacroActionMacro::RunOptions::Logic>(value);
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::ReevaluateConditionStateChanged(int value)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_runOptions.reevaluateConditionState = value;
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::ActionTypeChanged(int value)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_runOptions.runElseActions = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::SkipWhenPausedChanged(int value)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_runOptions.skipWhenPaused = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::SetInputsChanged(int value)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_runOptions.setInputs = value;
|
||||||
|
SetWidgetVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::InputsChanged(const StringList &inputs)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_runOptions.inputs = inputs;
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionMacroEdit::SetWidgetVisibility()
|
void MacroActionMacroEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
|
_entryLayout->removeWidget(_actions);
|
||||||
|
_entryLayout->removeWidget(_actionIndex);
|
||||||
|
_entryLayout->removeWidget(_macros);
|
||||||
|
_entryLayout->removeWidget(_actionTypes);
|
||||||
|
_conditionLayout->removeWidget(_conditionBehaviors);
|
||||||
|
_conditionLayout->removeWidget(_conditionMacros);
|
||||||
|
|
||||||
|
ClearLayout(_entryLayout);
|
||||||
|
ClearLayout(_conditionLayout);
|
||||||
|
|
||||||
|
const std::unordered_map<std::string, QWidget *> placeholders = {
|
||||||
|
{"{{actions}}", _actions},
|
||||||
|
{"{{actionIndex}}", _actionIndex},
|
||||||
|
{"{{macros}}", _macros},
|
||||||
|
{"{{actionTypes}}", _actionTypes},
|
||||||
|
{"{{conditionBehaviors}}", _conditionBehaviors},
|
||||||
|
{"{{conditionMacros}}", _conditionMacros},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
PlaceWidgets(
|
||||||
|
obs_module_text(
|
||||||
|
_entryData->_action == MacroActionMacro::Action::RUN
|
||||||
|
? "AdvSceneSwitcher.action.macro.entry.run"
|
||||||
|
: "AdvSceneSwitcher.action.macro.entry.other"),
|
||||||
|
_entryLayout, placeholders);
|
||||||
|
|
||||||
|
if (_entryData->_runOptions.logic ==
|
||||||
|
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS) {
|
||||||
|
_conditionLayout->addWidget(_conditionBehaviors);
|
||||||
|
_conditionLayout->addStretch();
|
||||||
|
} else {
|
||||||
|
PlaceWidgets(
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.macro.entry.run.condition"),
|
||||||
|
_conditionLayout, placeholders);
|
||||||
|
}
|
||||||
|
|
||||||
if (_entryData->_action == MacroActionMacro::Action::RUN ||
|
if (_entryData->_action == MacroActionMacro::Action::RUN ||
|
||||||
_entryData->_action == MacroActionMacro::Action::STOP) {
|
_entryData->_action == MacroActionMacro::Action::STOP) {
|
||||||
_macros->HideSelectedMacro();
|
_macros->HideSelectedMacro();
|
||||||
@@ -245,6 +465,73 @@ void MacroActionMacroEdit::SetWidgetVisibility()
|
|||||||
MacroActionMacro::Action::ENABLE_ACTION ||
|
MacroActionMacro::Action::ENABLE_ACTION ||
|
||||||
_entryData->_action == MacroActionMacro::Action::TOGGLE_ACTION;
|
_entryData->_action == MacroActionMacro::Action::TOGGLE_ACTION;
|
||||||
_actionIndex->setVisible(isModifyingActionState);
|
_actionIndex->setVisible(isModifyingActionState);
|
||||||
|
|
||||||
|
SetLayoutVisible(_conditionLayout,
|
||||||
|
_entryData->_action == MacroActionMacro::Action::RUN);
|
||||||
|
const bool needsAdditionalConditionWidgets =
|
||||||
|
_entryData->_action == MacroActionMacro::Action::RUN &&
|
||||||
|
_entryData->_runOptions.logic !=
|
||||||
|
MacroActionMacro::RunOptions::Logic::IGNORE_CONDITIONS;
|
||||||
|
_conditionMacros->setVisible(needsAdditionalConditionWidgets);
|
||||||
|
SetLayoutVisible(_reevaluateConditionStateLayout,
|
||||||
|
needsAdditionalConditionWidgets);
|
||||||
|
SetLayoutVisible(_setInputsLayout,
|
||||||
|
_entryData->_action == MacroActionMacro::Action::RUN);
|
||||||
|
_inputs->setVisible(_entryData->_action ==
|
||||||
|
MacroActionMacro::Action::RUN &&
|
||||||
|
_entryData->_runOptions.setInputs);
|
||||||
|
HighligthMacroSettingsButton(_entryData->_action ==
|
||||||
|
MacroActionMacro::Action::RUN &&
|
||||||
|
_entryData->_runOptions.setInputs &&
|
||||||
|
!_inputs->HasInputsToSet());
|
||||||
|
_actionTypes->setVisible(_entryData->_action ==
|
||||||
|
MacroActionMacro::Action::RUN);
|
||||||
|
_skipWhenPaused->setVisible(_entryData->_action ==
|
||||||
|
MacroActionMacro::Action::RUN);
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacroEdit::SetupMacroInput(Macro *macro) const
|
||||||
|
{
|
||||||
|
if (macro) {
|
||||||
|
_inputs->SetInputVariablesAndValues(
|
||||||
|
macro->GetInputVariables(),
|
||||||
|
_entryData->_runOptions.inputs);
|
||||||
|
} else {
|
||||||
|
_inputs->SetInputVariablesAndValues({}, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacro::RunOptions::Save(obs_data_t *obj) const
|
||||||
|
{
|
||||||
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
|
obs_data_set_int(data, "logic", static_cast<int>(logic));
|
||||||
|
obs_data_set_bool(data, "reevaluateConditionState",
|
||||||
|
reevaluateConditionState);
|
||||||
|
obs_data_set_bool(data, "runElseActions", runElseActions);
|
||||||
|
obs_data_set_bool(data, "skipWhenPaused", skipWhenPaused);
|
||||||
|
obs_data_set_bool(data, "setInputs", setInputs);
|
||||||
|
inputs.Save(data, "inputs");
|
||||||
|
macro.Save(data);
|
||||||
|
obs_data_set_obj(obj, "runOptions", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionMacro::RunOptions::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
if (!obs_data_has_user_value(obj, "runOptions")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OBSDataAutoRelease data = obs_data_get_obj(obj, "runOptions");
|
||||||
|
logic = static_cast<Logic>(obs_data_get_int(data, "logic"));
|
||||||
|
reevaluateConditionState =
|
||||||
|
obs_data_get_bool(data, "reevaluateConditionState");
|
||||||
|
runElseActions = obs_data_get_bool(data, "runElseActions");
|
||||||
|
skipWhenPaused = obs_data_get_bool(data, "skipWhenPaused");
|
||||||
|
setInputs = obs_data_get_bool(data, "setInputs");
|
||||||
|
inputs.Load(data, "inputs");
|
||||||
|
macro.Load(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,25 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "macro-input.hpp"
|
||||||
#include "macro-selection.hpp"
|
#include "macro-selection.hpp"
|
||||||
#include "macro-segment-selection.hpp"
|
#include "macro-segment-selection.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
class MacroActionMacro : public MacroRefAction {
|
class MacroActionMacro final : public MacroRefAction {
|
||||||
public:
|
public:
|
||||||
MacroActionMacro(Macro *m) : MacroAction(m), MacroRefAction(m) {}
|
MacroActionMacro(Macro *m) : MacroAction(m), MacroRefAction(m) {}
|
||||||
bool PerformAction();
|
bool PerformAction();
|
||||||
void LogAction() const;
|
void LogAction() const;
|
||||||
bool Save(obs_data_t *obj) const;
|
bool Save(obs_data_t *obj) const;
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
|
bool PostLoad();
|
||||||
std::string GetShortDesc() const;
|
std::string GetShortDesc() const;
|
||||||
std::string GetId() const { return id; };
|
std::string GetId() const { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create(Macro *m)
|
static std::shared_ptr<MacroAction> Create(Macro *m);
|
||||||
{
|
std::shared_ptr<MacroAction> Copy() const;
|
||||||
return std::make_shared<MacroActionMacro>(m);
|
void ResolveVariablesToFixedValues();
|
||||||
}
|
|
||||||
|
struct RunOptions {
|
||||||
|
void Save(obs_data_t *obj) const;
|
||||||
|
void Load(obs_data_t *obj);
|
||||||
|
enum class Logic {
|
||||||
|
IGNORE_CONDITIONS,
|
||||||
|
CONDITIONS,
|
||||||
|
INVERT_CONDITIONS,
|
||||||
|
};
|
||||||
|
Logic logic;
|
||||||
|
bool reevaluateConditionState = false;
|
||||||
|
bool runElseActions = false;
|
||||||
|
bool skipWhenPaused = true;
|
||||||
|
bool setInputs = false;
|
||||||
|
StringList inputs;
|
||||||
|
MacroRef macro;
|
||||||
|
};
|
||||||
|
|
||||||
enum class Action {
|
enum class Action {
|
||||||
PAUSE,
|
PAUSE,
|
||||||
@@ -31,21 +50,25 @@ public:
|
|||||||
ENABLE_ACTION,
|
ENABLE_ACTION,
|
||||||
TOGGLE_ACTION,
|
TOGGLE_ACTION,
|
||||||
};
|
};
|
||||||
Action _action = Action::PAUSE;
|
Action _action = Action::RUN;
|
||||||
IntVariable _actionIndex = 1;
|
IntVariable _actionIndex = 1;
|
||||||
|
RunOptions _runOptions = {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void RunActions(Macro *actionMacro) const;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const std::string id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionMacroEdit : public QWidget {
|
class MacroActionMacroEdit final : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MacroActionMacroEdit(
|
MacroActionMacroEdit(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
std::shared_ptr<MacroActionMacro> entryData = nullptr);
|
std::shared_ptr<MacroActionMacro> entryData = nullptr);
|
||||||
|
~MacroActionMacroEdit();
|
||||||
void UpdateEntryData();
|
void UpdateEntryData();
|
||||||
static QWidget *Create(QWidget *parent,
|
static QWidget *Create(QWidget *parent,
|
||||||
std::shared_ptr<MacroAction> action)
|
std::shared_ptr<MacroAction> action)
|
||||||
@@ -59,18 +82,37 @@ private slots:
|
|||||||
void MacroChanged(const QString &text);
|
void MacroChanged(const QString &text);
|
||||||
void ActionChanged(int value);
|
void ActionChanged(int value);
|
||||||
void ActionIndexChanged(const IntVariable &value);
|
void ActionIndexChanged(const IntVariable &value);
|
||||||
|
void ConditionMacroChanged(const QString &text);
|
||||||
|
void ConditionBehaviorChanged(int value);
|
||||||
|
void ReevaluateConditionStateChanged(int value);
|
||||||
|
void ActionTypeChanged(int value);
|
||||||
|
void SkipWhenPausedChanged(int value);
|
||||||
|
void SetInputsChanged(int value);
|
||||||
|
void InputsChanged(const StringList &);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
void SetupMacroInput(Macro *) const;
|
||||||
|
|
||||||
MacroSelection *_macros;
|
MacroSelection *_macros;
|
||||||
MacroSegmentSelection *_actionIndex;
|
MacroSegmentSelection *_actionIndex;
|
||||||
QComboBox *_actions;
|
QComboBox *_actions;
|
||||||
|
MacroSelection *_conditionMacros;
|
||||||
|
QComboBox *_conditionBehaviors;
|
||||||
|
QCheckBox *_reevaluateConditionState;
|
||||||
|
QComboBox *_actionTypes;
|
||||||
|
QCheckBox *_skipWhenPaused;
|
||||||
|
QCheckBox *_setInputs;
|
||||||
|
MacroInputEdit *_inputs;
|
||||||
|
QHBoxLayout *_entryLayout;
|
||||||
|
QHBoxLayout *_conditionLayout;
|
||||||
|
QHBoxLayout *_reevaluateConditionStateLayout;
|
||||||
|
QHBoxLayout *_setInputsLayout;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionMacro> _entryData;
|
std::shared_ptr<MacroActionMacro> _entryData;
|
||||||
|
|
||||||
private:
|
|
||||||
void SetWidgetVisibility();
|
|
||||||
|
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ void MacroActionQueue::AddActions(ActionQueue *queue)
|
|||||||
|
|
||||||
auto actions = *GetMacroActions(macro.get());
|
auto actions = *GetMacroActions(macro.get());
|
||||||
for (const auto &action : actions) {
|
for (const auto &action : actions) {
|
||||||
queue->Add(action);
|
if (action->Enabled()) {
|
||||||
|
queue->Add(action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,20 +71,20 @@ void MacroActionQueue::LogAction() const
|
|||||||
}
|
}
|
||||||
switch (_action) {
|
switch (_action) {
|
||||||
case Action::ADD_TO_QUEUE:
|
case Action::ADD_TO_QUEUE:
|
||||||
vblog(LOG_INFO, "queued actions of \"%s\" to \"%s\"",
|
ablog(LOG_INFO, "queued actions of \"%s\" to \"%s\"",
|
||||||
GetMacroName(macro.get()).c_str(),
|
GetMacroName(macro.get()).c_str(),
|
||||||
GetActionQueueName(_queue).c_str());
|
GetActionQueueName(_queue).c_str());
|
||||||
break;
|
break;
|
||||||
case Action::START_QUEUE:
|
case Action::START_QUEUE:
|
||||||
vblog(LOG_INFO, "start queue \"%s\"",
|
ablog(LOG_INFO, "start queue \"%s\"",
|
||||||
GetActionQueueName(_queue).c_str());
|
GetActionQueueName(_queue).c_str());
|
||||||
break;
|
break;
|
||||||
case Action::STOP_QUEUE:
|
case Action::STOP_QUEUE:
|
||||||
vblog(LOG_INFO, "stop queue \"%s\"",
|
ablog(LOG_INFO, "stop queue \"%s\"",
|
||||||
GetActionQueueName(_queue).c_str());
|
GetActionQueueName(_queue).c_str());
|
||||||
break;
|
break;
|
||||||
case Action::CLEAR_QUEUE:
|
case Action::CLEAR_QUEUE:
|
||||||
vblog(LOG_INFO, "cleared queue \"%s\"",
|
ablog(LOG_INFO, "cleared queue \"%s\"",
|
||||||
GetActionQueueName(_queue).c_str());
|
GetActionQueueName(_queue).c_str());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -114,6 +116,16 @@ std::string MacroActionQueue::GetShortDesc() const
|
|||||||
return GetActionQueueName(_queue);
|
return GetActionQueueName(_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MacroAction> MacroActionQueue::Create(Macro *m)
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionQueue>(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MacroAction> MacroActionQueue::Copy() const
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionQueue>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void populateActionSelection(QComboBox *list)
|
static inline void populateActionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (const auto &[_, name] : actionTypes) {
|
for (const auto &[_, name] : actionTypes) {
|
||||||
|
|||||||
@@ -16,10 +16,8 @@ public:
|
|||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
std::string GetShortDesc() const;
|
std::string GetShortDesc() const;
|
||||||
std::string GetId() const { return id; };
|
std::string GetId() const { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create(Macro *m)
|
static std::shared_ptr<MacroAction> Create(Macro *m);
|
||||||
{
|
std::shared_ptr<MacroAction> Copy() const;
|
||||||
return std::make_shared<MacroActionQueue>(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Action {
|
enum class Action {
|
||||||
ADD_TO_QUEUE,
|
ADD_TO_QUEUE,
|
||||||
|
|||||||
92
lib/macro/macro-action-script.cpp
Normal file
92
lib/macro/macro-action-script.cpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include "macro-action-script.hpp"
|
||||||
|
#include "layout-helpers.hpp"
|
||||||
|
#include "macro-helpers.hpp"
|
||||||
|
#include "properties-view.hpp"
|
||||||
|
#include "sync-helpers.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
MacroActionScript::MacroActionScript(Macro *m, const std::string &id,
|
||||||
|
const OBSData &defaultSettings,
|
||||||
|
const std::string &propertiesSignalName,
|
||||||
|
const std::string &triggerSignal,
|
||||||
|
const std::string &completionSignal)
|
||||||
|
: MacroAction(m),
|
||||||
|
MacroSegmentScript(defaultSettings, propertiesSignalName,
|
||||||
|
triggerSignal, completionSignal),
|
||||||
|
_id(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroActionScript::MacroActionScript(const advss::MacroActionScript &other)
|
||||||
|
: MacroAction(other.GetMacro()),
|
||||||
|
MacroSegmentScript(other),
|
||||||
|
_id(other._id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionScript::PerformAction()
|
||||||
|
{
|
||||||
|
if (!ScriptHandler::ActionIdIsValid(_id)) {
|
||||||
|
blog(LOG_WARNING, "skipping unknown script action \"%s\"",
|
||||||
|
_id.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)SendTriggerSignal();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionScript::LogAction() const
|
||||||
|
{
|
||||||
|
ablog(LOG_INFO, "performing script action \"%s\"", GetId().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionScript::Save(obs_data_t *obj) const
|
||||||
|
{
|
||||||
|
MacroAction::Save(obj);
|
||||||
|
MacroSegmentScript::Save(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionScript::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
MacroAction::Load(obj);
|
||||||
|
MacroSegmentScript::Load(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MacroAction> MacroActionScript::Copy() const
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionScript>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionScript::WaitForCompletion() const
|
||||||
|
{
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
auto timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
start - start);
|
||||||
|
const auto timeoutMs = GetTimeoutSeconds() * 1000.0;
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lock(*GetMutex());
|
||||||
|
while (!TriggerIsCompleted()) {
|
||||||
|
if (MacroWaitShouldAbort() || MacroIsStopped(GetMacro())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((double)timePassed.count() > timeoutMs) {
|
||||||
|
blog(LOG_INFO, "script action timeout (%s)",
|
||||||
|
_id.c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetMacroWaitCV().wait_for(lock, 10ms);
|
||||||
|
const auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
timePassed =
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
now - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
29
lib/macro/macro-action-script.hpp
Normal file
29
lib/macro/macro-action-script.hpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "macro-script-handler.hpp"
|
||||||
|
#include "macro-segment-script.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
class MacroActionScript : public MacroAction, public MacroSegmentScript {
|
||||||
|
public:
|
||||||
|
MacroActionScript(Macro *m, const std::string &id,
|
||||||
|
const OBSData &defaultSettings,
|
||||||
|
const std::string &propertiesSignalName,
|
||||||
|
const std::string &triggerSignal,
|
||||||
|
const std::string &signalComplete);
|
||||||
|
MacroActionScript(const advss::MacroActionScript &);
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction() const;
|
||||||
|
bool Save(obs_data_t *obj) const;
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() const { return _id; };
|
||||||
|
std::shared_ptr<MacroAction> Copy() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void WaitForCompletion() const;
|
||||||
|
|
||||||
|
std::string _id = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
@@ -54,6 +54,12 @@ const static std::map<MacroActionVariable::Type, std::string> actionTypes = {
|
|||||||
"AdvSceneSwitcher.action.variable.type.setToTempvar"},
|
"AdvSceneSwitcher.action.variable.type.setToTempvar"},
|
||||||
{MacroActionVariable::Type::SCENE_ITEM_NAME,
|
{MacroActionVariable::Type::SCENE_ITEM_NAME,
|
||||||
"AdvSceneSwitcher.action.variable.type.sceneItemName"},
|
"AdvSceneSwitcher.action.variable.type.sceneItemName"},
|
||||||
|
{MacroActionVariable::Type::PAD,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.padValue"},
|
||||||
|
{MacroActionVariable::Type::TRUNCATE,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.truncateValue"},
|
||||||
|
{MacroActionVariable::Type::SWAP_VALUES,
|
||||||
|
"AdvSceneSwitcher.action.variable.type.swapValues"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void apppend(Variable &var, const std::string &value)
|
static void apppend(Variable &var, const std::string &value)
|
||||||
@@ -198,7 +204,8 @@ void MacroActionVariable::SetToSceneItemName(Variable *var)
|
|||||||
|
|
||||||
struct AskForInputParams {
|
struct AskForInputParams {
|
||||||
AskForInputParams(const QString &prompt_, const QString &placeholder_)
|
AskForInputParams(const QString &prompt_, const QString &placeholder_)
|
||||||
: prompt(prompt_), placeholder(placeholder_){};
|
: prompt(prompt_),
|
||||||
|
placeholder(placeholder_){};
|
||||||
QString prompt;
|
QString prompt;
|
||||||
QString placeholder;
|
QString placeholder;
|
||||||
std::optional<std::string> result;
|
std::optional<std::string> result;
|
||||||
@@ -216,6 +223,38 @@ static void askForInput(void *param)
|
|||||||
parameters->resultReady = true;
|
parameters->resultReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string truncate(const std::string &input,
|
||||||
|
MacroActionVariable::Direction direction,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
if (input.length() <= length) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == MacroActionVariable::Direction::RIGHT) {
|
||||||
|
return input.substr(0, length);
|
||||||
|
} else {
|
||||||
|
return input.substr(input.length() - length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string pad(const std::string &input,
|
||||||
|
MacroActionVariable::Direction direction, size_t length,
|
||||||
|
char paddingChar)
|
||||||
|
{
|
||||||
|
if (input.length() >= length) {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direction == MacroActionVariable::Direction::RIGHT) {
|
||||||
|
return input +
|
||||||
|
std::string(length - input.length(), paddingChar);
|
||||||
|
} else {
|
||||||
|
return std::string(length - input.length(), paddingChar) +
|
||||||
|
input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MacroActionVariable::PerformAction()
|
bool MacroActionVariable::PerformAction()
|
||||||
{
|
{
|
||||||
auto var = _variable.lock();
|
auto var = _variable.lock();
|
||||||
@@ -310,7 +349,10 @@ bool MacroActionVariable::PerformAction()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case Type::ENV_VARIABLE: {
|
case Type::ENV_VARIABLE: {
|
||||||
var->SetValue(std::getenv(_envVariableName.c_str()));
|
auto value = std::getenv(_envVariableName.c_str());
|
||||||
|
if (value) {
|
||||||
|
var->SetValue(value);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case Type::SCENE_ITEM_COUNT: {
|
case Type::SCENE_ITEM_COUNT: {
|
||||||
@@ -344,6 +386,25 @@ bool MacroActionVariable::PerformAction()
|
|||||||
case Type::SCENE_ITEM_NAME:
|
case Type::SCENE_ITEM_NAME:
|
||||||
SetToSceneItemName(var.get());
|
SetToSceneItemName(var.get());
|
||||||
return true;
|
return true;
|
||||||
|
case Type::PAD:
|
||||||
|
var->SetValue(pad(var->Value(), _direction, _stringLength,
|
||||||
|
_paddingChar));
|
||||||
|
return true;
|
||||||
|
case Type::TRUNCATE:
|
||||||
|
var->SetValue(
|
||||||
|
truncate(var->Value(), _direction, _stringLength));
|
||||||
|
return true;
|
||||||
|
case Type::SWAP_VALUES: {
|
||||||
|
auto var2 = _variable2.lock();
|
||||||
|
if (!var2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tempValue = var->Value();
|
||||||
|
var->SetValue(var2->Value());
|
||||||
|
var2->SetValue(tempValue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -377,6 +438,9 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
|
|||||||
_scene.Save(obj);
|
_scene.Save(obj);
|
||||||
_tempVar.Save(obj);
|
_tempVar.Save(obj);
|
||||||
_sceneItemIndex.Save(obj, "sceneItemIndex");
|
_sceneItemIndex.Save(obj, "sceneItemIndex");
|
||||||
|
obs_data_set_int(obj, "direction", static_cast<int>(_direction));
|
||||||
|
_stringLength.Save(obj, "stringLength");
|
||||||
|
obs_data_set_int(obj, "paddingChar", _paddingChar);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,6 +472,13 @@ bool MacroActionVariable::Load(obs_data_t *obj)
|
|||||||
_scene.Load(obj);
|
_scene.Load(obj);
|
||||||
_tempVar.Load(obj, GetMacro());
|
_tempVar.Load(obj, GetMacro());
|
||||||
_sceneItemIndex.Load(obj, "sceneItemIndex");
|
_sceneItemIndex.Load(obj, "sceneItemIndex");
|
||||||
|
_direction = static_cast<Direction>(obs_data_get_int(obj, "direction"));
|
||||||
|
_stringLength.Load(obj, "stringLength");
|
||||||
|
if (obs_data_has_user_value(obj, "paddingChar")) {
|
||||||
|
_paddingChar = obs_data_get_int(obj, "paddingChar");
|
||||||
|
} else {
|
||||||
|
_paddingChar = ' ';
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,6 +493,16 @@ std::string MacroActionVariable::GetShortDesc() const
|
|||||||
return GetWeakVariableName(_variable);
|
return GetWeakVariableName(_variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MacroAction> MacroActionVariable::Create(Macro *m)
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionVariable>(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MacroAction> MacroActionVariable::Copy() const
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionVariable>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionVariable::SetSegmentIndexValue(int value)
|
void MacroActionVariable::SetSegmentIndexValue(int value)
|
||||||
{
|
{
|
||||||
DecrementCurrentSegmentVariableRef();
|
DecrementCurrentSegmentVariableRef();
|
||||||
@@ -485,6 +566,19 @@ int MacroActionVariable::GetSegmentIndexValue() const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionVariable::ResolveVariablesToFixedValues()
|
||||||
|
{
|
||||||
|
_strValue.ResolveVariables();
|
||||||
|
_findStr.ResolveVariables();
|
||||||
|
_replaceStr.ResolveVariables();
|
||||||
|
_mathExpression.ResolveVariables();
|
||||||
|
_inputPrompt.ResolveVariables();
|
||||||
|
_inputPlaceholder.ResolveVariables();
|
||||||
|
_envVariableName.ResolveVariables();
|
||||||
|
_scene.ResolveVariables();
|
||||||
|
_sceneItemIndex.ResolveVariables();
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionVariable::DecrementCurrentSegmentVariableRef()
|
void MacroActionVariable::DecrementCurrentSegmentVariableRef()
|
||||||
{
|
{
|
||||||
auto segment = _macroSegment.lock();
|
auto segment = _macroSegment.lock();
|
||||||
@@ -503,6 +597,16 @@ static inline void populateTypeSelection(QComboBox *list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void populateDirectionSelection(QComboBox *list)
|
||||||
|
{
|
||||||
|
list->addItems(
|
||||||
|
QStringList()
|
||||||
|
<< obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.truncateOrPadDirection.left")
|
||||||
|
<< obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.truncateOrPadDirection.right"));
|
||||||
|
}
|
||||||
|
|
||||||
MacroActionVariableEdit::MacroActionVariableEdit(
|
MacroActionVariableEdit::MacroActionVariableEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroActionVariable> entryData)
|
QWidget *parent, std::shared_ptr<MacroActionVariable> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
@@ -539,7 +643,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
_scenes(new SceneSelectionWidget(this, true, false, true, true,
|
_scenes(new SceneSelectionWidget(this, true, false, true, true,
|
||||||
true)),
|
true)),
|
||||||
_tempVars(new TempVariableSelection(this)),
|
_tempVars(new TempVariableSelection(this)),
|
||||||
|
_tempVarsHelp(new HelpIcon(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.type.setToTempvar.help"))),
|
||||||
_sceneItemIndex(new VariableSpinBox()),
|
_sceneItemIndex(new VariableSpinBox()),
|
||||||
|
_direction(new QComboBox()),
|
||||||
|
_stringLength(new VariableSpinBox()),
|
||||||
|
_paddingCharSelection(new SingleCharSelection()),
|
||||||
_entryLayout(new QHBoxLayout())
|
_entryLayout(new QHBoxLayout())
|
||||||
{
|
{
|
||||||
_numValue->setMinimum(-9999999999);
|
_numValue->setMinimum(-9999999999);
|
||||||
@@ -559,7 +668,9 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
_inputPrompt->setSizePolicy(QSizePolicy::MinimumExpanding,
|
_inputPrompt->setSizePolicy(QSizePolicy::MinimumExpanding,
|
||||||
QSizePolicy::Preferred);
|
QSizePolicy::Preferred);
|
||||||
_sceneItemIndex->setMinimum(1);
|
_sceneItemIndex->setMinimum(1);
|
||||||
|
_stringLength->setMaximum(999);
|
||||||
populateTypeSelection(_actions);
|
populateTypeSelection(_actions);
|
||||||
|
populateDirectionSelection(_direction);
|
||||||
|
|
||||||
QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)),
|
QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)),
|
||||||
this, SLOT(VariableChanged(const QString &)));
|
this, SLOT(VariableChanged(const QString &)));
|
||||||
@@ -615,8 +726,17 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
_sceneItemIndex,
|
_sceneItemIndex,
|
||||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||||
this, SLOT(SceneItemIndexChanged(const NumberVariable<int> &)));
|
this, SLOT(SceneItemIndexChanged(const NumberVariable<int> &)));
|
||||||
|
QWidget::connect(_direction, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(DirectionChanged(int)));
|
||||||
|
QWidget::connect(
|
||||||
|
_stringLength,
|
||||||
|
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||||
|
this, SLOT(StringLengthChanged(const NumberVariable<int> &)));
|
||||||
|
QWidget::connect(_paddingCharSelection,
|
||||||
|
SIGNAL(CharChanged(const QString &)), this,
|
||||||
|
SLOT(CharSelectionChanged(const QString &)));
|
||||||
|
|
||||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
{"{{variables}}", _variables},
|
{"{{variables}}", _variables},
|
||||||
{"{{variables2}}", _variables2},
|
{"{{variables2}}", _variables2},
|
||||||
{"{{actions}}", _actions},
|
{"{{actions}}", _actions},
|
||||||
@@ -637,10 +757,15 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
|||||||
{"{{envVariableName}}", _envVariable},
|
{"{{envVariableName}}", _envVariable},
|
||||||
{"{{scenes}}", _scenes},
|
{"{{scenes}}", _scenes},
|
||||||
{"{{tempVars}}", _tempVars},
|
{"{{tempVars}}", _tempVars},
|
||||||
|
{"{{tempVarsHelp}}", _tempVarsHelp},
|
||||||
{"{{sceneItemIndex}}", _sceneItemIndex},
|
{"{{sceneItemIndex}}", _sceneItemIndex},
|
||||||
|
{"{{direction}}", _direction},
|
||||||
|
{"{{stringLength}}", _stringLength},
|
||||||
|
{"{{paddingCharSelection}}", _paddingCharSelection},
|
||||||
};
|
};
|
||||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"),
|
PlaceWidgets(
|
||||||
_entryLayout, widgetPlaceholders);
|
obs_module_text("AdvSceneSwitcher.action.variable.entry.other"),
|
||||||
|
_entryLayout, widgetPlaceholders);
|
||||||
|
|
||||||
PlaceWidgets(
|
PlaceWidgets(
|
||||||
obs_module_text(
|
obs_module_text(
|
||||||
@@ -733,6 +858,10 @@ void MacroActionVariableEdit::UpdateEntryData()
|
|||||||
_scenes->SetScene(_entryData->_scene);
|
_scenes->SetScene(_entryData->_scene);
|
||||||
_tempVars->SetVariable(_entryData->_tempVar);
|
_tempVars->SetVariable(_entryData->_tempVar);
|
||||||
_sceneItemIndex->SetValue(_entryData->_sceneItemIndex);
|
_sceneItemIndex->SetValue(_entryData->_sceneItemIndex);
|
||||||
|
_direction->setCurrentIndex(static_cast<int>(_entryData->_direction));
|
||||||
|
_stringLength->SetValue(_entryData->_stringLength);
|
||||||
|
_paddingCharSelection->setText(
|
||||||
|
QChar::fromLatin1(_entryData->_paddingChar));
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1089,6 +1218,7 @@ void MacroActionVariableEdit::SelectionChanged(const TempVariableRef &var)
|
|||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
_entryData->_tempVar = var;
|
_entryData->_tempVar = var;
|
||||||
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroActionVariableEdit::SceneItemIndexChanged(
|
void MacroActionVariableEdit::SceneItemIndexChanged(
|
||||||
@@ -1102,12 +1232,85 @@ void MacroActionVariableEdit::SceneItemIndexChanged(
|
|||||||
_entryData->_sceneItemIndex = value;
|
_entryData->_sceneItemIndex = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::DirectionChanged(int value)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_direction =
|
||||||
|
static_cast<MacroActionVariable::Direction>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::StringLengthChanged(
|
||||||
|
const NumberVariable<int> &value)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
_entryData->_stringLength = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroActionVariableEdit::CharSelectionChanged(const QString &character)
|
||||||
|
{
|
||||||
|
if (_loading || !_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lock = LockContext();
|
||||||
|
if (character.isEmpty()) {
|
||||||
|
_entryData->_paddingChar = ' ';
|
||||||
|
} else {
|
||||||
|
_entryData->_paddingChar = character.toStdString().at(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MacroActionVariableEdit::SetWidgetVisibility()
|
void MacroActionVariableEdit::SetWidgetVisibility()
|
||||||
{
|
{
|
||||||
if (!_entryData) {
|
if (!_entryData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
|
{"{{variables}}", _variables},
|
||||||
|
{"{{variables2}}", _variables2},
|
||||||
|
{"{{actions}}", _actions},
|
||||||
|
{"{{strValue}}", _strValue},
|
||||||
|
{"{{numValue}}", _numValue},
|
||||||
|
{"{{segmentIndex}}", _segmentIdx},
|
||||||
|
{"{{mathExpression}}", _mathExpression},
|
||||||
|
{"{{envVariableName}}", _envVariable},
|
||||||
|
{"{{scenes}}", _scenes},
|
||||||
|
{"{{tempVars}}", _tempVars},
|
||||||
|
{"{{tempVarsHelp}}", _tempVarsHelp},
|
||||||
|
{"{{sceneItemIndex}}", _sceneItemIndex},
|
||||||
|
{"{{direction}}", _direction},
|
||||||
|
{"{{stringLength}}", _stringLength},
|
||||||
|
{"{{paddingCharSelection}}", _paddingCharSelection},
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *layoutString = "";
|
||||||
|
if (_entryData->_type == MacroActionVariable::Type::PAD) {
|
||||||
|
layoutString = obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.entry.pad");
|
||||||
|
} else if (_entryData->_type == MacroActionVariable::Type::TRUNCATE) {
|
||||||
|
layoutString = obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.entry.truncate");
|
||||||
|
} else {
|
||||||
|
layoutString = obs_module_text(
|
||||||
|
"AdvSceneSwitcher.action.variable.entry.other");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &[_, widget] : widgetPlaceholders) {
|
||||||
|
_entryLayout->removeWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearLayout(_entryLayout);
|
||||||
|
PlaceWidgets(layoutString, _entryLayout, widgetPlaceholders);
|
||||||
|
|
||||||
if (_entryData->_type == MacroActionVariable::Type::SET_FIXED_VALUE ||
|
if (_entryData->_type == MacroActionVariable::Type::SET_FIXED_VALUE ||
|
||||||
_entryData->_type == MacroActionVariable::Type::APPEND ||
|
_entryData->_type == MacroActionVariable::Type::APPEND ||
|
||||||
_entryData->_type == MacroActionVariable::Type::MATH_EXPRESSION ||
|
_entryData->_type == MacroActionVariable::Type::MATH_EXPRESSION ||
|
||||||
@@ -1119,8 +1322,9 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
AddStretchIfNecessary(_entryLayout);
|
AddStretchIfNecessary(_entryLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
_variables2->setVisible(_entryData->_type ==
|
_variables2->setVisible(
|
||||||
MacroActionVariable::Type::APPEND_VAR);
|
_entryData->_type == MacroActionVariable::Type::APPEND_VAR ||
|
||||||
|
_entryData->_type == MacroActionVariable::Type::SWAP_VALUES);
|
||||||
_strValue->setVisible(
|
_strValue->setVisible(
|
||||||
_entryData->_type ==
|
_entryData->_type ==
|
||||||
MacroActionVariable::Type::SET_FIXED_VALUE ||
|
MacroActionVariable::Type::SET_FIXED_VALUE ||
|
||||||
@@ -1196,8 +1400,20 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
|||||||
MacroActionVariable::Type::SCENE_ITEM_NAME);
|
MacroActionVariable::Type::SCENE_ITEM_NAME);
|
||||||
_tempVars->setVisible(_entryData->_type ==
|
_tempVars->setVisible(_entryData->_type ==
|
||||||
MacroActionVariable::Type::SET_TO_TEMPVAR);
|
MacroActionVariable::Type::SET_TO_TEMPVAR);
|
||||||
|
_tempVarsHelp->setVisible(
|
||||||
|
_entryData->_type ==
|
||||||
|
MacroActionVariable::Type::SET_TO_TEMPVAR &&
|
||||||
|
!_entryData->_tempVar.HasValidID());
|
||||||
_sceneItemIndex->setVisible(_entryData->_type ==
|
_sceneItemIndex->setVisible(_entryData->_type ==
|
||||||
MacroActionVariable::Type::SCENE_ITEM_NAME);
|
MacroActionVariable::Type::SCENE_ITEM_NAME);
|
||||||
|
_direction->setVisible(
|
||||||
|
_entryData->_type == MacroActionVariable::Type::PAD ||
|
||||||
|
_entryData->_type == MacroActionVariable::Type::TRUNCATE);
|
||||||
|
_stringLength->setVisible(
|
||||||
|
_entryData->_type == MacroActionVariable::Type::PAD ||
|
||||||
|
_entryData->_type == MacroActionVariable::Type::TRUNCATE);
|
||||||
|
_paddingCharSelection->setVisible(_entryData->_type ==
|
||||||
|
MacroActionVariable::Type::PAD);
|
||||||
adjustSize();
|
adjustSize();
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "help-icon.hpp"
|
||||||
#include "macro-segment-selection.hpp"
|
#include "macro-segment-selection.hpp"
|
||||||
#include "regex-config.hpp"
|
#include "regex-config.hpp"
|
||||||
#include "resizing-text-edit.hpp"
|
#include "resizing-text-edit.hpp"
|
||||||
#include "scene-selection.hpp"
|
#include "scene-selection.hpp"
|
||||||
|
#include "single-char-selection.hpp"
|
||||||
#include "variable-line-edit.hpp"
|
#include "variable-line-edit.hpp"
|
||||||
#include "variable-text-edit.hpp"
|
#include "variable-text-edit.hpp"
|
||||||
#include "variable-spinbox.hpp"
|
#include "variable-spinbox.hpp"
|
||||||
@@ -17,15 +19,14 @@ public:
|
|||||||
bool PerformAction();
|
bool PerformAction();
|
||||||
bool Save(obs_data_t *obj) const;
|
bool Save(obs_data_t *obj) const;
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
bool PostLoad() override;
|
bool PostLoad();
|
||||||
std::string GetShortDesc() const;
|
std::string GetShortDesc() const;
|
||||||
std::string GetId() const { return id; };
|
std::string GetId() const { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create(Macro *m)
|
static std::shared_ptr<MacroAction> Create(Macro *m);
|
||||||
{
|
std::shared_ptr<MacroAction> Copy() const;
|
||||||
return std::make_shared<MacroActionVariable>(m);
|
|
||||||
}
|
|
||||||
void SetSegmentIndexValue(int);
|
void SetSegmentIndexValue(int);
|
||||||
int GetSegmentIndexValue() const;
|
int GetSegmentIndexValue() const;
|
||||||
|
void ResolveVariablesToFixedValues();
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
SET_FIXED_VALUE,
|
SET_FIXED_VALUE,
|
||||||
@@ -46,6 +47,9 @@ public:
|
|||||||
EXTRACT_JSON,
|
EXTRACT_JSON,
|
||||||
SET_TO_TEMPVAR,
|
SET_TO_TEMPVAR,
|
||||||
SCENE_ITEM_NAME,
|
SCENE_ITEM_NAME,
|
||||||
|
PAD,
|
||||||
|
TRUNCATE,
|
||||||
|
SWAP_VALUES,
|
||||||
};
|
};
|
||||||
|
|
||||||
Type _type = Type::SET_FIXED_VALUE;
|
Type _type = Type::SET_FIXED_VALUE;
|
||||||
@@ -80,6 +84,11 @@ public:
|
|||||||
TempVariableRef _tempVar;
|
TempVariableRef _tempVar;
|
||||||
IntVariable _sceneItemIndex = 1;
|
IntVariable _sceneItemIndex = 1;
|
||||||
|
|
||||||
|
enum class Direction { LEFT, RIGHT };
|
||||||
|
Direction _direction = Direction::LEFT;
|
||||||
|
IntVariable _stringLength = 1;
|
||||||
|
char _paddingChar = '0';
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DecrementCurrentSegmentVariableRef();
|
void DecrementCurrentSegmentVariableRef();
|
||||||
void HandleIndexSubString(Variable *);
|
void HandleIndexSubString(Variable *);
|
||||||
@@ -136,6 +145,9 @@ private slots:
|
|||||||
void SceneChanged(const SceneSelection &);
|
void SceneChanged(const SceneSelection &);
|
||||||
void SelectionChanged(const TempVariableRef &var);
|
void SelectionChanged(const TempVariableRef &var);
|
||||||
void SceneItemIndexChanged(const NumberVariable<int> &);
|
void SceneItemIndexChanged(const NumberVariable<int> &);
|
||||||
|
void DirectionChanged(int);
|
||||||
|
void StringLengthChanged(const NumberVariable<int> &);
|
||||||
|
void CharSelectionChanged(const QString &);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
@@ -175,7 +187,11 @@ private:
|
|||||||
VariableLineEdit *_envVariable;
|
VariableLineEdit *_envVariable;
|
||||||
SceneSelectionWidget *_scenes;
|
SceneSelectionWidget *_scenes;
|
||||||
TempVariableSelection *_tempVars;
|
TempVariableSelection *_tempVars;
|
||||||
|
HelpIcon *_tempVarsHelp;
|
||||||
VariableSpinBox *_sceneItemIndex;
|
VariableSpinBox *_sceneItemIndex;
|
||||||
|
QComboBox *_direction;
|
||||||
|
VariableSpinBox *_stringLength;
|
||||||
|
SingleCharSelection *_paddingCharSelection;
|
||||||
QHBoxLayout *_entryLayout;
|
QHBoxLayout *_entryLayout;
|
||||||
|
|
||||||
std::shared_ptr<MacroActionVariable> _entryData;
|
std::shared_ptr<MacroActionVariable> _entryData;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ bool MacroAction::Load(obs_data_t *obj)
|
|||||||
|
|
||||||
void MacroAction::LogAction() const
|
void MacroAction::LogAction() const
|
||||||
{
|
{
|
||||||
vblog(LOG_INFO, "performed action %s", GetId().c_str());
|
ablog(LOG_INFO, "performed action %s", GetId().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAction::SetEnabled(bool value)
|
void MacroAction::SetEnabled(bool value)
|
||||||
@@ -38,6 +38,8 @@ bool MacroAction::Enabled() const
|
|||||||
return _enabled;
|
return _enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroAction::ResolveVariablesToFixedValues() {}
|
||||||
|
|
||||||
std::string_view MacroAction::GetDefaultID()
|
std::string_view MacroAction::GetDefaultID()
|
||||||
{
|
{
|
||||||
return "scene_switch";
|
return "scene_switch";
|
||||||
|
|||||||
@@ -8,10 +8,17 @@ class EXPORT MacroAction : public MacroSegment {
|
|||||||
public:
|
public:
|
||||||
MacroAction(Macro *m, bool supportsVariableValue = false);
|
MacroAction(Macro *m, bool supportsVariableValue = false);
|
||||||
virtual ~MacroAction() = default;
|
virtual ~MacroAction() = default;
|
||||||
|
virtual std::shared_ptr<MacroAction> Copy() const = 0;
|
||||||
|
|
||||||
virtual bool PerformAction() = 0;
|
virtual bool PerformAction() = 0;
|
||||||
|
virtual void LogAction() const;
|
||||||
|
|
||||||
virtual bool Save(obs_data_t *obj) const = 0;
|
virtual bool Save(obs_data_t *obj) const = 0;
|
||||||
virtual bool Load(obs_data_t *obj) = 0;
|
virtual bool Load(obs_data_t *obj) = 0;
|
||||||
virtual void LogAction() const;
|
|
||||||
|
// Used to resolve variables before actions are added to action queues
|
||||||
|
virtual void ResolveVariablesToFixedValues();
|
||||||
|
|
||||||
void SetEnabled(bool);
|
void SetEnabled(bool);
|
||||||
bool Enabled() const;
|
bool Enabled() const;
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,15 @@
|
|||||||
#include "macro-condition-edit.hpp"
|
#include "macro-condition-edit.hpp"
|
||||||
#include "advanced-scene-switcher.hpp"
|
#include "advanced-scene-switcher.hpp"
|
||||||
#include "macro-properties.hpp"
|
#include "macro-settings.hpp"
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "path-helpers.hpp"
|
#include "path-helpers.hpp"
|
||||||
|
#include "plugin-state-helpers.hpp"
|
||||||
#include "section.hpp"
|
#include "section.hpp"
|
||||||
#include "ui-helpers.hpp"
|
#include "ui-helpers.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
static inline void populateLogicSelection(QComboBox *list, bool root = false)
|
|
||||||
{
|
|
||||||
if (root) {
|
|
||||||
for (const auto &entry : MacroCondition::logicTypes) {
|
|
||||||
if (static_cast<int>(entry.first) < logic_root_offset) {
|
|
||||||
list->addItem(obs_module_text(
|
|
||||||
entry.second._name.c_str()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (const auto &entry : MacroCondition::logicTypes) {
|
|
||||||
if (static_cast<int>(entry.first) >=
|
|
||||||
logic_root_offset) {
|
|
||||||
list->addItem(obs_module_text(
|
|
||||||
entry.second._name.c_str()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void populateConditionSelection(QComboBox *list)
|
static inline void populateConditionSelection(QComboBox *list)
|
||||||
{
|
{
|
||||||
for (const auto &[_, condition] :
|
for (const auto &[_, condition] :
|
||||||
@@ -119,14 +100,13 @@ void DurationModifierEdit::Collapse(bool collapse)
|
|||||||
|
|
||||||
MacroConditionEdit::MacroConditionEdit(
|
MacroConditionEdit::MacroConditionEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroCondition> *entryData,
|
QWidget *parent, std::shared_ptr<MacroCondition> *entryData,
|
||||||
const std::string &id, bool root)
|
const std::string &id, bool isRootCondition)
|
||||||
: MacroSegmentEdit(GetGlobalMacroProperties()._highlightConditions,
|
: MacroSegmentEdit(parent),
|
||||||
parent),
|
|
||||||
_logicSelection(new QComboBox()),
|
_logicSelection(new QComboBox()),
|
||||||
_conditionSelection(new FilterComboBox()),
|
_conditionSelection(new FilterComboBox()),
|
||||||
_dur(new DurationModifierEdit()),
|
_dur(new DurationModifierEdit()),
|
||||||
_entryData(entryData),
|
_entryData(entryData),
|
||||||
_isRoot(root)
|
_isRoot(isRootCondition)
|
||||||
{
|
{
|
||||||
QWidget::connect(_logicSelection, SIGNAL(currentIndexChanged(int)),
|
QWidget::connect(_logicSelection, SIGNAL(currentIndexChanged(int)),
|
||||||
this, SLOT(LogicSelectionChanged(int)));
|
this, SLOT(LogicSelectionChanged(int)));
|
||||||
@@ -138,10 +118,8 @@ MacroConditionEdit::MacroConditionEdit(
|
|||||||
QWidget::connect(_dur, SIGNAL(ModifierChanged(DurationModifier::Type)),
|
QWidget::connect(_dur, SIGNAL(ModifierChanged(DurationModifier::Type)),
|
||||||
this,
|
this,
|
||||||
SLOT(DurationModifierChanged(DurationModifier::Type)));
|
SLOT(DurationModifierChanged(DurationModifier::Type)));
|
||||||
QWidget::connect(window(), SIGNAL(HighlightConditionsChanged(bool)),
|
|
||||||
this, SLOT(EnableHighlight(bool)));
|
|
||||||
|
|
||||||
populateLogicSelection(_logicSelection, root);
|
Logic::PopulateLogicTypeSelection(_logicSelection, isRootCondition);
|
||||||
populateConditionSelection(_conditionSelection);
|
populateConditionSelection(_conditionSelection);
|
||||||
|
|
||||||
_section->AddHeaderWidget(_logicSelection);
|
_section->AddHeaderWidget(_logicSelection);
|
||||||
@@ -170,15 +148,10 @@ void MacroConditionEdit::LogicSelectionChanged(int idx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicType type;
|
|
||||||
if (IsRootNode()) {
|
|
||||||
type = static_cast<LogicType>(idx);
|
|
||||||
} else {
|
|
||||||
type = static_cast<LogicType>(idx + logic_root_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
(*_entryData)->SetLogicType(type);
|
const auto logic = static_cast<Logic::Type>(
|
||||||
|
_logicSelection->itemData(idx).toInt());
|
||||||
|
(*_entryData)->SetLogicType(logic);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionEdit::IsRootNode()
|
bool MacroConditionEdit::IsRootNode()
|
||||||
@@ -188,13 +161,9 @@ bool MacroConditionEdit::IsRootNode()
|
|||||||
|
|
||||||
void MacroConditionEdit::SetLogicSelection()
|
void MacroConditionEdit::SetLogicSelection()
|
||||||
{
|
{
|
||||||
auto logic = (*_entryData)->GetLogicType();
|
const auto logic = (*_entryData)->GetLogicType();
|
||||||
if (IsRootNode()) {
|
_logicSelection->setCurrentIndex(
|
||||||
_logicSelection->setCurrentIndex(static_cast<int>(logic));
|
_logicSelection->findData(static_cast<int>(logic)));
|
||||||
} else {
|
|
||||||
_logicSelection->setCurrentIndex(static_cast<int>(logic) -
|
|
||||||
logic_root_offset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionEdit::SetRootNode(bool root)
|
void MacroConditionEdit::SetRootNode(bool root)
|
||||||
@@ -202,7 +171,7 @@ void MacroConditionEdit::SetRootNode(bool root)
|
|||||||
_isRoot = root;
|
_isRoot = root;
|
||||||
const QSignalBlocker blocker(_logicSelection);
|
const QSignalBlocker blocker(_logicSelection);
|
||||||
_logicSelection->clear();
|
_logicSelection->clear();
|
||||||
populateLogicSelection(_logicSelection, root);
|
Logic::PopulateLogicTypeSelection(_logicSelection, root);
|
||||||
SetLogicSelection();
|
SetLogicSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,6 +223,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
|
|||||||
(*_entryData)->SetIndex(idx);
|
(*_entryData)->SetIndex(idx);
|
||||||
(*_entryData)->SetLogicType(logic);
|
(*_entryData)->SetLogicType(logic);
|
||||||
(*_entryData)->PostLoad();
|
(*_entryData)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
}
|
}
|
||||||
auto widget =
|
auto widget =
|
||||||
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
||||||
@@ -297,34 +267,51 @@ void AdvSceneSwitcher::AddMacroCondition(int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (idx < 0 || idx > (int)macro->Conditions().size()) {
|
if (idx < 0 || idx > (int)macro->Conditions().size()) {
|
||||||
|
assert(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string id;
|
std::string id;
|
||||||
LogicType logic;
|
Logic::Type logic;
|
||||||
if (idx >= 1) {
|
if (idx >= 1) {
|
||||||
id = macro->Conditions().at(idx - 1)->GetId();
|
id = macro->Conditions().at(idx - 1)->GetId();
|
||||||
if (idx == 1) {
|
if (idx == 1) {
|
||||||
logic = LogicType::OR;
|
logic = Logic::Type::OR;
|
||||||
} else {
|
} else {
|
||||||
logic = macro->Conditions().at(idx - 1)->GetLogicType();
|
logic = macro->Conditions().at(idx - 1)->GetLogicType();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
id = MacroCondition::GetDefaultID();
|
id = MacroCondition::GetDefaultID();
|
||||||
logic = LogicType::ROOT_NONE;
|
logic = Logic::Type::ROOT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OBSDataAutoRelease data;
|
||||||
|
if (idx - 1 >= 0) {
|
||||||
|
data = obs_data_create();
|
||||||
|
macro->Conditions().at(idx - 1)->Save(data);
|
||||||
|
}
|
||||||
|
AddMacroCondition(macro.get(), idx, id, data.Get(), logic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::AddMacroCondition(Macro *macro, int idx,
|
||||||
|
const std::string &id,
|
||||||
|
obs_data_t *data, Logic::Type logic)
|
||||||
|
{
|
||||||
|
if (idx < 0 || idx > (int)macro->Conditions().size()) {
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
auto cond = macro->Conditions().emplace(
|
auto cond = macro->Conditions().emplace(
|
||||||
macro->Conditions().begin() + idx,
|
macro->Conditions().begin() + idx,
|
||||||
MacroConditionFactory::Create(id, macro.get()));
|
MacroConditionFactory::Create(id, macro));
|
||||||
if (idx - 1 >= 0) {
|
if (data) {
|
||||||
auto data = obs_data_create();
|
|
||||||
macro->Conditions().at(idx - 1)->Save(data);
|
|
||||||
macro->Conditions().at(idx)->Load(data);
|
macro->Conditions().at(idx)->Load(data);
|
||||||
obs_data_release(data);
|
|
||||||
}
|
}
|
||||||
macro->Conditions().at(idx)->PostLoad();
|
macro->Conditions().at(idx)->PostLoad();
|
||||||
|
RunPostLoadSteps();
|
||||||
(*cond)->SetLogicType(logic);
|
(*cond)->SetLogicType(logic);
|
||||||
macro->UpdateConditionIndices();
|
macro->UpdateConditionIndices();
|
||||||
ui->conditionsList->Insert(
|
ui->conditionsList->Insert(
|
||||||
@@ -334,6 +321,7 @@ void AdvSceneSwitcher::AddMacroCondition(int idx)
|
|||||||
SetConditionData(*macro);
|
SetConditionData(*macro);
|
||||||
}
|
}
|
||||||
HighlightCondition(idx);
|
HighlightCondition(idx);
|
||||||
|
ui->conditionsList->SetHelpMsgVisible(false);
|
||||||
emit(MacroSegmentOrderChanged());
|
emit(MacroSegmentOrderChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +340,6 @@ void AdvSceneSwitcher::on_conditionAdd_clicked()
|
|||||||
if (currentConditionIdx != -1) {
|
if (currentConditionIdx != -1) {
|
||||||
MacroConditionSelectionChanged(currentConditionIdx + 1);
|
MacroConditionSelectionChanged(currentConditionIdx + 1);
|
||||||
}
|
}
|
||||||
ui->conditionsList->SetHelpMsgVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
||||||
@@ -373,7 +360,7 @@ void AdvSceneSwitcher::RemoveMacroCondition(int idx)
|
|||||||
macro->UpdateConditionIndices();
|
macro->UpdateConditionIndices();
|
||||||
if (idx == 0 && macro->Conditions().size() > 0) {
|
if (idx == 0 && macro->Conditions().size() > 0) {
|
||||||
auto newRoot = macro->Conditions().at(0);
|
auto newRoot = macro->Conditions().at(0);
|
||||||
newRoot->SetLogicType(LogicType::ROOT_NONE);
|
newRoot->SetLogicType(Logic::Type::ROOT_NONE);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
ui->conditionsList->WidgetAt(0))
|
ui->conditionsList->WidgetAt(0))
|
||||||
->SetRootNode(true);
|
->SetRootNode(true);
|
||||||
@@ -524,22 +511,23 @@ void AdvSceneSwitcher::MacroConditionReorder(int to, int from)
|
|||||||
auto lock = LockContext();
|
auto lock = LockContext();
|
||||||
auto condition = macro->Conditions().at(from);
|
auto condition = macro->Conditions().at(from);
|
||||||
if (to == 0) {
|
if (to == 0) {
|
||||||
condition->SetLogicType(LogicType::ROOT_NONE);
|
condition->SetLogicType(Logic::Type::ROOT_NONE);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
ui->conditionsList->WidgetAt(from))
|
ui->conditionsList->WidgetAt(from))
|
||||||
->SetRootNode(true);
|
->SetRootNode(true);
|
||||||
macro->Conditions().at(0)->SetLogicType(LogicType::AND);
|
macro->Conditions().at(0)->SetLogicType(
|
||||||
|
Logic::Type::AND);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
ui->conditionsList->WidgetAt(0))
|
ui->conditionsList->WidgetAt(0))
|
||||||
->SetRootNode(false);
|
->SetRootNode(false);
|
||||||
}
|
}
|
||||||
if (from == 0) {
|
if (from == 0) {
|
||||||
condition->SetLogicType(LogicType::AND);
|
condition->SetLogicType(Logic::Type::AND);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
ui->conditionsList->WidgetAt(from))
|
ui->conditionsList->WidgetAt(from))
|
||||||
->SetRootNode(false);
|
->SetRootNode(false);
|
||||||
macro->Conditions().at(1)->SetLogicType(
|
macro->Conditions().at(1)->SetLogicType(
|
||||||
LogicType::ROOT_NONE);
|
Logic::Type::ROOT_NONE);
|
||||||
static_cast<MacroConditionEdit *>(
|
static_cast<MacroConditionEdit *>(
|
||||||
ui->conditionsList->WidgetAt(1))
|
ui->conditionsList->WidgetAt(1))
|
||||||
->SetRootNode(true);
|
->SetRootNode(true);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "macro-condition.hpp"
|
#include "macro-condition.hpp"
|
||||||
#include "macro-condition-factory.hpp"
|
#include "macro-condition-factory.hpp"
|
||||||
#include "filter-combo-box.hpp"
|
#include "filter-combo-box.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,24 @@
|
|||||||
#include "macro-condition-factory.hpp"
|
#include "macro-condition-factory.hpp"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class MacroConditionUnknown : public MacroCondition {
|
||||||
|
public:
|
||||||
|
MacroConditionUnknown(Macro *m) : MacroCondition(m) {}
|
||||||
|
bool CheckCondition() { return false; }
|
||||||
|
bool Save(obs_data_t *obj) const { return MacroCondition::Save(obj); };
|
||||||
|
bool Load(obs_data_t *obj) { return MacroCondition::Load(obj); };
|
||||||
|
std::string GetId() const { return "unknown"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
static std::recursive_mutex mutex;
|
||||||
|
|
||||||
std::map<std::string, MacroConditionInfo> &MacroConditionFactory::GetMap()
|
std::map<std::string, MacroConditionInfo> &MacroConditionFactory::GetMap()
|
||||||
{
|
{
|
||||||
static std::map<std::string, MacroConditionInfo> _methods;
|
static std::map<std::string, MacroConditionInfo> _methods;
|
||||||
@@ -11,6 +28,7 @@ std::map<std::string, MacroConditionInfo> &MacroConditionFactory::GetMap()
|
|||||||
bool MacroConditionFactory::Register(const std::string &id,
|
bool MacroConditionFactory::Register(const std::string &id,
|
||||||
MacroConditionInfo info)
|
MacroConditionInfo info)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (auto it = GetMap().find(id); it == GetMap().end()) {
|
if (auto it = GetMap().find(id); it == GetMap().end()) {
|
||||||
GetMap()[id] = info;
|
GetMap()[id] = info;
|
||||||
return true;
|
return true;
|
||||||
@@ -18,35 +36,60 @@ bool MacroConditionFactory::Register(const std::string &id,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MacroConditionFactory::Deregister(const std::string &id)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
|
if (GetMap().count(id) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GetMap().erase(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<MacroCondition> createUnknownCondition(Macro *m)
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionUnknown>(m);
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<MacroCondition>
|
std::shared_ptr<MacroCondition>
|
||||||
MacroConditionFactory::Create(const std::string &id, Macro *m)
|
MacroConditionFactory::Create(const std::string &id, Macro *m)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._create(m);
|
return it->second._create(m);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return createUnknownCondition(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QWidget *createUnknownConditionWidget()
|
||||||
|
{
|
||||||
|
return new QLabel(
|
||||||
|
obs_module_text("AdvSceneSwitcher.condition.unknown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *
|
QWidget *
|
||||||
MacroConditionFactory::CreateWidget(const std::string &id, QWidget *parent,
|
MacroConditionFactory::CreateWidget(const std::string &id, QWidget *parent,
|
||||||
std::shared_ptr<MacroCondition> cond)
|
std::shared_ptr<MacroCondition> cond)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._createWidget(parent, cond);
|
return it->second._createWidget(parent, cond);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return createUnknownConditionWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MacroConditionFactory::GetConditionName(const std::string &id)
|
std::string MacroConditionFactory::GetConditionName(const std::string &id)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._name;
|
return it->second._name;
|
||||||
}
|
}
|
||||||
return "unknown condition";
|
return obs_module_text("AdvSceneSwitcher.condition.unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MacroConditionFactory::GetIdByName(const QString &name)
|
std::string MacroConditionFactory::GetIdByName(const QString &name)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
for (auto it : GetMap()) {
|
for (auto it : GetMap()) {
|
||||||
if (name == obs_module_text(it.second._name.c_str())) {
|
if (name == obs_module_text(it.second._name.c_str())) {
|
||||||
return it.first;
|
return it.first;
|
||||||
@@ -57,10 +100,21 @@ std::string MacroConditionFactory::GetIdByName(const QString &name)
|
|||||||
|
|
||||||
bool MacroConditionFactory::UsesDurationModifier(const std::string &id)
|
bool MacroConditionFactory::UsesDurationModifier(const std::string &id)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(mutex);
|
||||||
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
if (auto it = GetMap().find(id); it != GetMap().end()) {
|
||||||
return it->second._useDurationModifier;
|
return it->second._useDurationModifier;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanCreateDefaultCondition()
|
||||||
|
{
|
||||||
|
const auto condition = MacroConditionFactory::Create(
|
||||||
|
MacroCondition::GetDefaultID().data(), nullptr);
|
||||||
|
if (!condition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return condition->GetId() == MacroCondition::GetDefaultID().data();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
struct MacroConditionInfo {
|
struct MacroConditionInfo {
|
||||||
using CreateCondition = std::shared_ptr<MacroCondition> (*)(Macro *m);
|
|
||||||
using CreateConditionWidget =
|
using CreateConditionWidget =
|
||||||
QWidget *(*)(QWidget *parent, std::shared_ptr<MacroCondition>);
|
QWidget *(*)(QWidget *parent, std::shared_ptr<MacroCondition>);
|
||||||
CreateCondition _create = nullptr;
|
|
||||||
|
std::function<std::shared_ptr<MacroCondition>(Macro *m)> _create =
|
||||||
|
nullptr;
|
||||||
CreateConditionWidget _createWidget = nullptr;
|
CreateConditionWidget _createWidget = nullptr;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
bool _useDurationModifier = true;
|
bool _useDurationModifier = true;
|
||||||
@@ -19,6 +20,7 @@ class MacroConditionFactory {
|
|||||||
public:
|
public:
|
||||||
MacroConditionFactory() = delete;
|
MacroConditionFactory() = delete;
|
||||||
EXPORT static bool Register(const std::string &, MacroConditionInfo);
|
EXPORT static bool Register(const std::string &, MacroConditionInfo);
|
||||||
|
static bool Deregister(const std::string &);
|
||||||
static std::shared_ptr<MacroCondition> Create(const std::string &,
|
static std::shared_ptr<MacroCondition> Create(const std::string &,
|
||||||
Macro *m);
|
Macro *m);
|
||||||
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
||||||
@@ -32,4 +34,6 @@ private:
|
|||||||
static std::map<std::string, MacroConditionInfo> &GetMap();
|
static std::map<std::string, MacroConditionInfo> &GetMap();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool CanCreateDefaultCondition();
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj) const;
|
bool Save(obs_data_t *obj) const;
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
bool PostLoad() override;
|
bool PostLoad();
|
||||||
std::string GetShortDesc() const;
|
std::string GetShortDesc() const;
|
||||||
std::string GetId() const { return id; };
|
std::string GetId() const { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||||
|
|||||||
79
lib/macro/macro-condition-script.cpp
Normal file
79
lib/macro/macro-condition-script.cpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#include "macro-condition-script.hpp"
|
||||||
|
#include "layout-helpers.hpp"
|
||||||
|
#include "macro-helpers.hpp"
|
||||||
|
#include "sync-helpers.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
MacroConditionScript::MacroConditionScript(
|
||||||
|
Macro *m, const std::string &id, const OBSData &defaultSettings,
|
||||||
|
const std::string &propertiesSignalName,
|
||||||
|
const std::string &triggerSignal, const std::string &completionSignal)
|
||||||
|
: MacroCondition(m),
|
||||||
|
MacroSegmentScript(defaultSettings, propertiesSignalName,
|
||||||
|
triggerSignal, completionSignal),
|
||||||
|
_id(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroConditionScript::MacroConditionScript(
|
||||||
|
const advss::MacroConditionScript &other)
|
||||||
|
: MacroCondition(other.GetMacro()),
|
||||||
|
MacroSegmentScript(other),
|
||||||
|
_id(other._id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionScript::CheckCondition()
|
||||||
|
{
|
||||||
|
if (!ScriptHandler::ConditionIdIsValid(_id)) {
|
||||||
|
blog(LOG_WARNING, "skipping unknown script condition \"%s\"",
|
||||||
|
_id.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SendTriggerSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionScript::Save(obs_data_t *obj) const
|
||||||
|
{
|
||||||
|
MacroCondition::Save(obj);
|
||||||
|
MacroSegmentScript::Save(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroConditionScript::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
MacroCondition::Load(obj);
|
||||||
|
MacroSegmentScript::Load(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroConditionScript::WaitForCompletion() const
|
||||||
|
{
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
auto timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
start - start);
|
||||||
|
const auto timeoutMs = GetTimeoutSeconds() * 1000.0;
|
||||||
|
|
||||||
|
while (!TriggerIsCompleted()) {
|
||||||
|
if (MacroWaitShouldAbort() || MacroIsStopped(GetMacro())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((double)timePassed.count() > timeoutMs) {
|
||||||
|
blog(LOG_INFO, "script condition timeout (%s)",
|
||||||
|
_id.c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(10ms);
|
||||||
|
const auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
timePassed =
|
||||||
|
std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
now - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
27
lib/macro/macro-condition-script.hpp
Normal file
27
lib/macro/macro-condition-script.hpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-condition-edit.hpp"
|
||||||
|
#include "macro-script-handler.hpp"
|
||||||
|
#include "macro-segment-script.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
class MacroConditionScript : public MacroCondition, public MacroSegmentScript {
|
||||||
|
public:
|
||||||
|
MacroConditionScript(Macro *m, const std::string &id,
|
||||||
|
const OBSData &defaultSettings,
|
||||||
|
const std::string &propertiesSignalName,
|
||||||
|
const std::string &triggerSignal,
|
||||||
|
const std::string &signalComplete);
|
||||||
|
MacroConditionScript(const advss::MacroConditionScript &);
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj) const;
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() const { return _id; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
void WaitForCompletion() const;
|
||||||
|
|
||||||
|
std::string _id = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
@@ -2,79 +2,6 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
const std::map<LogicType, LogicTypeInfo> MacroCondition::logicTypes = {
|
|
||||||
{LogicType::NONE, {"AdvSceneSwitcher.logic.none"}},
|
|
||||||
{LogicType::AND, {"AdvSceneSwitcher.logic.and"}},
|
|
||||||
{LogicType::OR, {"AdvSceneSwitcher.logic.or"}},
|
|
||||||
{LogicType::AND_NOT, {"AdvSceneSwitcher.logic.andNot"}},
|
|
||||||
{LogicType::OR_NOT, {"AdvSceneSwitcher.logic.orNot"}},
|
|
||||||
{LogicType::ROOT_NONE, {"AdvSceneSwitcher.logic.rootNone"}},
|
|
||||||
{LogicType::ROOT_NOT, {"AdvSceneSwitcher.logic.not"}},
|
|
||||||
};
|
|
||||||
|
|
||||||
void DurationModifier::Save(obs_data_t *obj, const char *condName,
|
|
||||||
const char *duration) const
|
|
||||||
{
|
|
||||||
obs_data_set_int(obj, condName, static_cast<int>(_type));
|
|
||||||
_dur.Save(obj, duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DurationModifier::Load(obs_data_t *obj, const char *condName,
|
|
||||||
const char *duration)
|
|
||||||
{
|
|
||||||
// For backwards compatibility check if duration value exist without
|
|
||||||
// time constraint condition - if so assume DurationCondition::MORE
|
|
||||||
if (!obs_data_has_user_value(obj, condName) &&
|
|
||||||
obs_data_has_user_value(obj, duration)) {
|
|
||||||
obs_data_set_int(obj, condName, static_cast<int>(Type::MORE));
|
|
||||||
}
|
|
||||||
|
|
||||||
_type = static_cast<Type>(obs_data_get_int(obj, condName));
|
|
||||||
_dur.Load(obj, duration);
|
|
||||||
|
|
||||||
// TODO: remove this fallback
|
|
||||||
if (obs_data_has_user_value(obj, "displayUnit")) {
|
|
||||||
_dur.SetUnit(static_cast<Duration::Unit>(
|
|
||||||
obs_data_get_int(obj, "displayUnit")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DurationModifier::DurationReached()
|
|
||||||
{
|
|
||||||
switch (_type) {
|
|
||||||
case DurationModifier::Type::NONE:
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
case DurationModifier::Type::MORE:
|
|
||||||
return _dur.DurationReached();
|
|
||||||
break;
|
|
||||||
case DurationModifier::Type::EQUAL:
|
|
||||||
if (_dur.DurationReached() && !_timeReached) {
|
|
||||||
_timeReached = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DurationModifier::Type::LESS:
|
|
||||||
return !_dur.DurationReached();
|
|
||||||
break;
|
|
||||||
case DurationModifier::Type::WITHIN:
|
|
||||||
if (_dur.IsReset()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return !_dur.DurationReached();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DurationModifier::Reset()
|
|
||||||
{
|
|
||||||
_timeReached = false;
|
|
||||||
_dur.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroCondition::MacroCondition(Macro *m, bool supportsVariableValue)
|
MacroCondition::MacroCondition(Macro *m, bool supportsVariableValue)
|
||||||
: MacroSegment(m, supportsVariableValue)
|
: MacroSegment(m, supportsVariableValue)
|
||||||
{
|
{
|
||||||
@@ -84,73 +11,64 @@ bool MacroCondition::Save(obs_data_t *obj) const
|
|||||||
{
|
{
|
||||||
MacroSegment::Save(obj);
|
MacroSegment::Save(obj);
|
||||||
obs_data_set_string(obj, "id", GetId().c_str());
|
obs_data_set_string(obj, "id", GetId().c_str());
|
||||||
obs_data_set_int(obj, "logic", static_cast<int>(_logic));
|
_logic.Save(obj, "logic");
|
||||||
|
_durationModifier.Save(obj);
|
||||||
// To avoid conflicts with conditions which also use the Duration class
|
|
||||||
// save the duration modifier in a separate obj
|
|
||||||
auto durObj = obs_data_create();
|
|
||||||
_duration.Save(durObj);
|
|
||||||
obs_data_set_obj(obj, "durationModifier", durObj);
|
|
||||||
obs_data_release(durObj);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroCondition::Load(obs_data_t *obj)
|
bool MacroCondition::Load(obs_data_t *obj)
|
||||||
{
|
{
|
||||||
MacroSegment::Load(obj);
|
MacroSegment::Load(obj);
|
||||||
_logic = static_cast<LogicType>(obs_data_get_int(obj, "logic"));
|
_logic.Load(obj, "logic");
|
||||||
if (obs_data_has_user_value(obj, "durationModifier")) {
|
_durationModifier.Load(obj);
|
||||||
auto durObj = obs_data_get_obj(obj, "durationModifier");
|
|
||||||
_duration.Load(durObj);
|
|
||||||
obs_data_release(durObj);
|
|
||||||
} else {
|
|
||||||
// For backwards compatibility
|
|
||||||
_duration.Load(obj);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroCondition::ValidateLogicSelection(bool isRootCondition,
|
||||||
|
const char *context)
|
||||||
|
{
|
||||||
|
if (_logic.IsValidSelection(isRootCondition)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_logic.IsRootType()) {
|
||||||
|
_logic.SetType(Logic::Type::ROOT_NONE);
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"setting invalid logic selection to 'if' for macro %s",
|
||||||
|
context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logic.SetType(Logic::Type::NONE);
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"setting invalid logic selection to 'ignore' for macro %s",
|
||||||
|
context);
|
||||||
|
}
|
||||||
|
|
||||||
void MacroCondition::ResetDuration()
|
void MacroCondition::ResetDuration()
|
||||||
{
|
{
|
||||||
_duration.Reset();
|
_durationModifier.ResetDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroCondition::CheckDurationModifier(bool &val)
|
bool MacroCondition::CheckDurationModifier(bool conditionValue)
|
||||||
{
|
{
|
||||||
if (_duration.GetType() != DurationModifier::Type::WITHIN && !val) {
|
return _durationModifier.CheckConditionWithDurationModifier(
|
||||||
_duration.Reset();
|
conditionValue);
|
||||||
}
|
}
|
||||||
if (_duration.GetType() == DurationModifier::Type::WITHIN && val) {
|
|
||||||
_duration.Reset();
|
DurationModifier MacroCondition::GetDurationModifier() const
|
||||||
}
|
{
|
||||||
switch (_duration.GetType()) {
|
return _durationModifier;
|
||||||
case DurationModifier::Type::NONE:
|
|
||||||
case DurationModifier::Type::MORE:
|
|
||||||
case DurationModifier::Type::EQUAL:
|
|
||||||
case DurationModifier::Type::LESS:
|
|
||||||
val = val && _duration.DurationReached();
|
|
||||||
return;
|
|
||||||
case DurationModifier::Type::WITHIN:
|
|
||||||
if (val) {
|
|
||||||
_duration.SetTimeRemaining(
|
|
||||||
_duration.GetDuration().Seconds());
|
|
||||||
}
|
|
||||||
val = val || _duration.DurationReached();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroCondition::SetDurationModifier(DurationModifier::Type m)
|
void MacroCondition::SetDurationModifier(DurationModifier::Type m)
|
||||||
{
|
{
|
||||||
_duration.SetModifier(m);
|
_durationModifier.SetModifier(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroCondition::SetDuration(const Duration &duration)
|
void MacroCondition::SetDuration(const Duration &duration)
|
||||||
{
|
{
|
||||||
_duration.SetValue(duration);
|
_durationModifier.SetDuration(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view MacroCondition::GetDefaultID()
|
std::string_view MacroCondition::GetDefaultID()
|
||||||
|
|||||||
@@ -1,63 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro-segment.hpp"
|
#include "macro-segment.hpp"
|
||||||
|
#include "condition-logic.hpp"
|
||||||
|
#include "duration-modifier.hpp"
|
||||||
#include "macro-ref.hpp"
|
#include "macro-ref.hpp"
|
||||||
#include <duration-control.hpp>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
constexpr auto logic_root_offset = 100;
|
|
||||||
|
|
||||||
enum class LogicType {
|
|
||||||
ROOT_NONE = 0,
|
|
||||||
ROOT_NOT,
|
|
||||||
ROOT_LAST,
|
|
||||||
// leave some space for potential expansion
|
|
||||||
NONE = 100,
|
|
||||||
AND,
|
|
||||||
OR,
|
|
||||||
AND_NOT,
|
|
||||||
OR_NOT,
|
|
||||||
LAST,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline bool isRootLogicType(LogicType l)
|
|
||||||
{
|
|
||||||
return static_cast<int>(l) < logic_root_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LogicTypeInfo {
|
|
||||||
std::string _name;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DurationModifier {
|
|
||||||
public:
|
|
||||||
enum class Type {
|
|
||||||
NONE,
|
|
||||||
MORE,
|
|
||||||
EQUAL,
|
|
||||||
LESS,
|
|
||||||
WITHIN, // Condition will remain true for a set a amount of time
|
|
||||||
// regardless of current state
|
|
||||||
};
|
|
||||||
|
|
||||||
void Save(obs_data_t *obj, const char *condName = "time_constraint",
|
|
||||||
const char *duration = "seconds") const;
|
|
||||||
void Load(obs_data_t *obj, const char *condName = "time_constraint",
|
|
||||||
const char *duration = "seconds");
|
|
||||||
void SetModifier(Type cond) { _type = cond; }
|
|
||||||
void SetTimeRemaining(const double &val) { _dur.SetTimeRemaining(val); }
|
|
||||||
void SetValue(const Duration &value) { _dur = value; }
|
|
||||||
Type GetType() { return _type; }
|
|
||||||
Duration GetDuration() { return _dur; }
|
|
||||||
bool DurationReached();
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Type _type = Type::NONE;
|
|
||||||
Duration _dur;
|
|
||||||
bool _timeReached = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EXPORT MacroCondition : public MacroSegment {
|
class EXPORT MacroCondition : public MacroSegment {
|
||||||
public:
|
public:
|
||||||
MacroCondition(Macro *m, bool supportsVariableValue = false);
|
MacroCondition(Macro *m, bool supportsVariableValue = false);
|
||||||
@@ -65,20 +13,24 @@ public:
|
|||||||
virtual bool CheckCondition() = 0;
|
virtual bool CheckCondition() = 0;
|
||||||
virtual bool Save(obs_data_t *obj) const = 0;
|
virtual bool Save(obs_data_t *obj) const = 0;
|
||||||
virtual bool Load(obs_data_t *obj) = 0;
|
virtual bool Load(obs_data_t *obj) = 0;
|
||||||
LogicType GetLogicType() { return _logic; }
|
|
||||||
void SetLogicType(LogicType logic) { _logic = logic; }
|
Logic::Type GetLogicType() const { return _logic.GetType(); }
|
||||||
static const std::map<LogicType, LogicTypeInfo> logicTypes;
|
void SetLogicType(const Logic::Type &logic) { _logic.SetType(logic); }
|
||||||
void ResetDuration();
|
|
||||||
void CheckDurationModifier(bool &val);
|
void ValidateLogicSelection(bool isRootCondition, const char *context);
|
||||||
DurationModifier GetDurationModifier() { return _duration; }
|
|
||||||
|
DurationModifier GetDurationModifier() const;
|
||||||
void SetDurationModifier(DurationModifier::Type m);
|
void SetDurationModifier(DurationModifier::Type m);
|
||||||
void SetDuration(const Duration &duration);
|
void SetDuration(const Duration &duration);
|
||||||
|
|
||||||
|
void ResetDuration();
|
||||||
|
bool CheckDurationModifier(bool conditionValue);
|
||||||
|
|
||||||
static std::string_view GetDefaultID();
|
static std::string_view GetDefaultID();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LogicType _logic = LogicType::ROOT_NONE;
|
Logic _logic = Logic(Logic::Type::ROOT_NONE);
|
||||||
DurationModifier _duration;
|
DurationModifier _durationModifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EXPORT MacroRefCondition : virtual public MacroCondition {
|
class EXPORT MacroRefCondition : virtual public MacroCondition {
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
MacroDock::MacroDock(std::weak_ptr<Macro> m, QWidget *parent,
|
MacroDock::MacroDock(std::weak_ptr<Macro> m,
|
||||||
const StringVariable &runButtonText,
|
const StringVariable &runButtonText,
|
||||||
const StringVariable &pauseButtonText,
|
const StringVariable &pauseButtonText,
|
||||||
const StringVariable &unpauseButtonText,
|
const StringVariable &unpauseButtonText,
|
||||||
const StringVariable &conditionsTrueText,
|
const StringVariable &conditionsTrueText,
|
||||||
const StringVariable &conditionsFalseText,
|
const StringVariable &conditionsFalseText,
|
||||||
bool enableHighlight)
|
bool enableHighlight)
|
||||||
: OBSDock(parent),
|
: QFrame(),
|
||||||
_runButtonText(runButtonText),
|
_runButtonText(runButtonText),
|
||||||
_pauseButtonText(pauseButtonText),
|
_pauseButtonText(pauseButtonText),
|
||||||
_unpauseButtonText(unpauseButtonText),
|
_unpauseButtonText(unpauseButtonText),
|
||||||
@@ -25,19 +25,16 @@ MacroDock::MacroDock(std::weak_ptr<Macro> m, QWidget *parent,
|
|||||||
_statusText(new QLabel(conditionsFalseText.c_str())),
|
_statusText(new QLabel(conditionsFalseText.c_str())),
|
||||||
_macro(m)
|
_macro(m)
|
||||||
{
|
{
|
||||||
|
setFrameShape(QFrame::StyledPanel);
|
||||||
|
setFrameShadow(QFrame::Sunken);
|
||||||
|
|
||||||
auto macro = _macro.lock();
|
auto macro = _macro.lock();
|
||||||
if (macro) {
|
if (macro) {
|
||||||
setWindowTitle(QString::fromStdString(macro->Name()));
|
|
||||||
_run->setVisible(macro->DockHasRunButton());
|
_run->setVisible(macro->DockHasRunButton());
|
||||||
_pauseToggle->setVisible(macro->DockHasPauseButton());
|
_pauseToggle->setVisible(macro->DockHasPauseButton());
|
||||||
_statusText->setVisible(macro->DockHasStatusLabel());
|
_statusText->setVisible(macro->DockHasStatusLabel());
|
||||||
} else {
|
|
||||||
setWindowTitle("<deleted macro>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setFeatures(DockWidgetClosable | DockWidgetMovable |
|
|
||||||
DockWidgetFloatable);
|
|
||||||
|
|
||||||
QWidget::connect(_run, SIGNAL(clicked()), this, SLOT(RunClicked()));
|
QWidget::connect(_run, SIGNAL(clicked()), this, SLOT(RunClicked()));
|
||||||
QWidget::connect(_pauseToggle, SIGNAL(clicked()), this,
|
QWidget::connect(_pauseToggle, SIGNAL(clicked()), this,
|
||||||
SLOT(PauseToggleClicked()));
|
SLOT(PauseToggleClicked()));
|
||||||
@@ -52,21 +49,7 @@ MacroDock::MacroDock(std::weak_ptr<Macro> m, QWidget *parent,
|
|||||||
QWidget::connect(&_timer, SIGNAL(timeout()), this, SLOT(Highlight()));
|
QWidget::connect(&_timer, SIGNAL(timeout()), this, SLOT(Highlight()));
|
||||||
_timer.start(500);
|
_timer.start(500);
|
||||||
|
|
||||||
// QFrame wrapper is necessary to avoid dock being partially
|
setLayout(layout);
|
||||||
// transparent
|
|
||||||
QFrame *wrapper = new QFrame;
|
|
||||||
wrapper->setFrameShape(QFrame::StyledPanel);
|
|
||||||
wrapper->setFrameShadow(QFrame::Sunken);
|
|
||||||
wrapper->setLayout(layout);
|
|
||||||
setWidget(wrapper);
|
|
||||||
|
|
||||||
setFloating(true);
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroDock::SetName(const QString &name)
|
|
||||||
{
|
|
||||||
setWindowTitle(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroDock::ShowRunButton(bool value)
|
void MacroDock::ShowRunButton(bool value)
|
||||||
@@ -167,7 +150,7 @@ void MacroDock::Highlight()
|
|||||||
}
|
}
|
||||||
if (_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
if (_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
||||||
macro->WasExecutedSince(_lastHighlightCheckTime)) {
|
macro->WasExecutedSince(_lastHighlightCheckTime)) {
|
||||||
PulseWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
HighlightWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
||||||
}
|
}
|
||||||
_lastHighlightCheckTime = std::chrono::high_resolution_clock::now();
|
_lastHighlightCheckTime = std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "obs-dock.hpp"
|
|
||||||
#include "variable-string.hpp"
|
#include "variable-string.hpp"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QLabel>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
@@ -12,18 +11,16 @@ namespace advss {
|
|||||||
|
|
||||||
class Macro;
|
class Macro;
|
||||||
|
|
||||||
class MacroDock : public OBSDock {
|
class MacroDock : public QFrame {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MacroDock(std::weak_ptr<Macro>, QWidget *parent,
|
MacroDock(std::weak_ptr<Macro>, const StringVariable &runButtonText,
|
||||||
const StringVariable &runButtonText,
|
|
||||||
const StringVariable &pauseButtonText,
|
const StringVariable &pauseButtonText,
|
||||||
const StringVariable &unpauseButtonText,
|
const StringVariable &unpauseButtonText,
|
||||||
const StringVariable &conditionsTrueText,
|
const StringVariable &conditionsTrueText,
|
||||||
const StringVariable &conditionsFalseText,
|
const StringVariable &conditionsFalseText,
|
||||||
bool enableHighlight);
|
bool enableHighlight);
|
||||||
void SetName(const QString &);
|
|
||||||
void ShowRunButton(bool);
|
void ShowRunButton(bool);
|
||||||
void SetRunButtonText(const StringVariable &);
|
void SetRunButtonText(const StringVariable &);
|
||||||
void ShowPauseButton(bool);
|
void ShowPauseButton(bool);
|
||||||
|
|||||||
@@ -8,8 +8,13 @@
|
|||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
|
static bool usePlainText = false;
|
||||||
|
|
||||||
MacroExportImportDialog::MacroExportImportDialog(Type type)
|
MacroExportImportDialog::MacroExportImportDialog(Type type)
|
||||||
: QDialog(nullptr), _importExportString(new QPlainTextEdit(this))
|
: QDialog(nullptr),
|
||||||
|
_importExportString(new QPlainTextEdit(this)),
|
||||||
|
_usePlainText(new QCheckBox(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.macroTab.export.usePlainText")))
|
||||||
{
|
{
|
||||||
_importExportString->setReadOnly(type == Type::EXPORT_MACRO);
|
_importExportString->setReadOnly(type == Type::EXPORT_MACRO);
|
||||||
auto label = new QLabel(obs_module_text(
|
auto label = new QLabel(obs_module_text(
|
||||||
@@ -29,9 +34,15 @@ MacroExportImportDialog::MacroExportImportDialog(Type type)
|
|||||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
buttons->setCenterButtons(true);
|
buttons->setCenterButtons(true);
|
||||||
|
|
||||||
|
_usePlainText->setChecked(usePlainText);
|
||||||
|
_usePlainText->setVisible(type == Type::EXPORT_MACRO);
|
||||||
|
connect(_usePlainText, &QCheckBox::stateChanged, this,
|
||||||
|
&MacroExportImportDialog::UsePlainTextChanged);
|
||||||
|
|
||||||
auto layout = new QVBoxLayout;
|
auto layout = new QVBoxLayout;
|
||||||
layout->addWidget(label);
|
layout->addWidget(label);
|
||||||
layout->addWidget(_importExportString);
|
layout->addWidget(_importExportString);
|
||||||
|
layout->addWidget(_usePlainText);
|
||||||
layout->addWidget(buttons);
|
layout->addWidget(buttons);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
@@ -64,6 +75,21 @@ void MacroExportImportDialog::ExportMacros(const QString &json)
|
|||||||
dialog.exec();
|
dialog.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroExportImportDialog::UsePlainTextChanged(int value)
|
||||||
|
{
|
||||||
|
if (usePlainText == (!!value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto current = _importExportString->toPlainText();
|
||||||
|
if (usePlainText) {
|
||||||
|
_importExportString->setPlainText(compressMacroString(current));
|
||||||
|
} else {
|
||||||
|
_importExportString->setPlainText(
|
||||||
|
decompressMacroString(current));
|
||||||
|
}
|
||||||
|
usePlainText = value;
|
||||||
|
}
|
||||||
|
|
||||||
static bool isValidData(const QString &json)
|
static bool isValidData(const QString &json)
|
||||||
{
|
{
|
||||||
OBSDataAutoRelease data =
|
OBSDataAutoRelease data =
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
@@ -13,8 +14,12 @@ public:
|
|||||||
static void ExportMacros(const QString &json);
|
static void ExportMacros(const QString &json);
|
||||||
static bool ImportMacros(QString &json);
|
static bool ImportMacros(QString &json);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void UsePlainTextChanged(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPlainTextEdit *_importExportString;
|
QPlainTextEdit *_importExportString;
|
||||||
|
QCheckBox *_usePlainText;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
241
lib/macro/macro-input.cpp
Normal file
241
lib/macro/macro-input.cpp
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
#include "macro-input.hpp"
|
||||||
|
#include "layout-helpers.hpp"
|
||||||
|
#include "log-helper.hpp"
|
||||||
|
#include "obs-module-helper.hpp"
|
||||||
|
#include "variable-line-edit.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <obs.hpp>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
void MacroInputVariables::Save(obs_data_t *obj) const
|
||||||
|
{
|
||||||
|
OBSDataArrayAutoRelease array = obs_data_array_create();
|
||||||
|
for (auto &var : _inputVariables) {
|
||||||
|
OBSDataAutoRelease arrayObj = obs_data_create();
|
||||||
|
auto variable = var.lock();
|
||||||
|
if (variable) {
|
||||||
|
obs_data_set_string(arrayObj, "variableName",
|
||||||
|
variable->Name().c_str());
|
||||||
|
} else {
|
||||||
|
obs_data_set_bool(arrayObj, "invalidVariable", true);
|
||||||
|
}
|
||||||
|
obs_data_array_push_back(array, arrayObj);
|
||||||
|
}
|
||||||
|
obs_data_set_array(obj, "inputVariables", array);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputVariables::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
OBSDataArrayAutoRelease array =
|
||||||
|
obs_data_get_array(obj, "inputVariables");
|
||||||
|
const size_t count = obs_data_array_count(array);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
OBSDataAutoRelease arrayObj = obs_data_array_item(array, i);
|
||||||
|
const bool isInvalid =
|
||||||
|
obs_data_get_bool(arrayObj, "invalidVariable");
|
||||||
|
if (isInvalid) {
|
||||||
|
_inputVariables.emplace_back();
|
||||||
|
} else {
|
||||||
|
const auto name =
|
||||||
|
obs_data_get_string(arrayObj, "variableName");
|
||||||
|
_inputVariables.emplace_back(
|
||||||
|
GetWeakVariableByName(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputVariables::SetValues(const StringList &values)
|
||||||
|
{
|
||||||
|
if (_inputVariables.size() != (size_t)values.size()) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"%s - sizes do not match (variables: %d, values %d)",
|
||||||
|
__func__, (int)_inputVariables.size(), (int)values.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t index = 0;
|
||||||
|
index < _inputVariables.size() && index < (size_t)values.size();
|
||||||
|
index++) {
|
||||||
|
auto variable = _inputVariables.at(index).lock();
|
||||||
|
if (!variable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
variable->SetValue(values.at(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroInputSelection::MacroInputSelection(QWidget *parent) : ListEditor(parent)
|
||||||
|
{
|
||||||
|
_list->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputSelection::SetInputs(const MacroInputVariables &inputs)
|
||||||
|
{
|
||||||
|
_currentSelection = inputs;
|
||||||
|
for (const auto &var : inputs._inputVariables) {
|
||||||
|
auto variable = var.lock();
|
||||||
|
const auto name =
|
||||||
|
variable
|
||||||
|
? QString::fromStdString(variable->Name())
|
||||||
|
: obs_module_text(
|
||||||
|
"AdvSceneSwitcher.macroTab.inputSettings.invalid");
|
||||||
|
|
||||||
|
QVariant v = QVariant::fromValue(name);
|
||||||
|
auto item = new QListWidgetItem(name, _list);
|
||||||
|
item->setData(Qt::UserRole, name);
|
||||||
|
}
|
||||||
|
UpdateListSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputSelection::Add()
|
||||||
|
{
|
||||||
|
std::string varName;
|
||||||
|
bool accepted = VariableSelectionDialog::AskForVariable(varName);
|
||||||
|
|
||||||
|
if (!accepted || varName.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentSelection._inputVariables.emplace_back(
|
||||||
|
GetWeakVariableByName(varName));
|
||||||
|
|
||||||
|
QVariant v = QVariant::fromValue(QString::fromStdString(varName));
|
||||||
|
auto item = new QListWidgetItem(QString::fromStdString(varName), _list);
|
||||||
|
item->setData(Qt::UserRole, QString::fromStdString(varName));
|
||||||
|
UpdateListSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputSelection::Remove()
|
||||||
|
{
|
||||||
|
auto item = _list->currentItem();
|
||||||
|
int idx = _list->currentRow();
|
||||||
|
if (!item || idx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentSelection._inputVariables.erase(
|
||||||
|
std::next(_currentSelection._inputVariables.begin(), idx));
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
UpdateListSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputSelection::Up()
|
||||||
|
{
|
||||||
|
int idx = _list->currentRow();
|
||||||
|
if (idx < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_list->insertItem(idx - 1, _list->takeItem(idx));
|
||||||
|
_list->setCurrentRow(idx - 1);
|
||||||
|
|
||||||
|
std::iter_swap(
|
||||||
|
std::next(_currentSelection._inputVariables.begin(), idx),
|
||||||
|
std::next(_currentSelection._inputVariables.begin(), idx - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputSelection::Down()
|
||||||
|
{
|
||||||
|
int idx = _list->currentRow();
|
||||||
|
if (idx < 0 || idx >= _list->count()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_list->insertItem(idx + 1, _list->takeItem(idx));
|
||||||
|
_list->setCurrentRow(idx + 1);
|
||||||
|
|
||||||
|
std::iter_swap(
|
||||||
|
std::next(_currentSelection._inputVariables.begin(), idx + 1),
|
||||||
|
std::next(_currentSelection._inputVariables.begin(), idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputSelection::Clicked(QListWidgetItem *item)
|
||||||
|
{
|
||||||
|
std::string varName;
|
||||||
|
bool accepted = VariableSelectionDialog::AskForVariable(varName);
|
||||||
|
|
||||||
|
if (!accepted || varName.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->setText(QString::fromStdString(varName));
|
||||||
|
int idx = _list->currentRow();
|
||||||
|
|
||||||
|
_currentSelection._inputVariables.at(idx) =
|
||||||
|
GetWeakVariableByName(varName);
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroInputEdit::MacroInputEdit(QWidget *parent)
|
||||||
|
: QWidget(parent),
|
||||||
|
_layout(new QGridLayout())
|
||||||
|
{
|
||||||
|
setLayout(_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroInputEdit::SetInputVariablesAndValues(
|
||||||
|
const MacroInputVariables &inputs, const StringList &values)
|
||||||
|
{
|
||||||
|
_variables = inputs;
|
||||||
|
_values = values;
|
||||||
|
if ((size_t)_values.size() < _variables._inputVariables.size()) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
for (int i = 0;
|
||||||
|
_variables._inputVariables.size() - (size_t)_values.size();
|
||||||
|
i++) {
|
||||||
|
_values.push_back({});
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
_values.resize(_variables._inputVariables.size());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
SetupWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroInputEdit::HasInputsToSet() const
|
||||||
|
{
|
||||||
|
return !_variables._inputVariables.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HighligthMacroSettingsButton(bool enable);
|
||||||
|
|
||||||
|
void MacroInputEdit::SetupWidgets()
|
||||||
|
{
|
||||||
|
ClearLayout(_layout);
|
||||||
|
|
||||||
|
auto &vars = _variables._inputVariables;
|
||||||
|
if (vars.empty()) {
|
||||||
|
_layout->addWidget(new QLabel(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.macroTab.inputSettings.noInputs")));
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t index = 0; index < vars.size(); index++) {
|
||||||
|
auto variable = vars.at(index).lock();
|
||||||
|
QLabel *label = new QLabel(
|
||||||
|
variable
|
||||||
|
? QString::fromStdString(variable->Name())
|
||||||
|
: obs_module_text(
|
||||||
|
"AdvSceneSwitcher.macroTab.inputSettings.invalid"));
|
||||||
|
_layout->addWidget(label, index, 0);
|
||||||
|
auto valueEdit = new VariableLineEdit(this);
|
||||||
|
valueEdit->setEnabled(!!variable);
|
||||||
|
valueEdit->setText(_values.at(index));
|
||||||
|
connect(valueEdit, &VariableLineEdit::editingFinished,
|
||||||
|
[this, valueEdit, index]() {
|
||||||
|
_values[index] =
|
||||||
|
valueEdit->text().toStdString();
|
||||||
|
emit MacroInputValuesChanged(_values);
|
||||||
|
});
|
||||||
|
_layout->addWidget(valueEdit, index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
63
lib/macro/macro-input.hpp
Normal file
63
lib/macro/macro-input.hpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "list-editor.hpp"
|
||||||
|
#include "string-list.hpp"
|
||||||
|
#include "variable.hpp"
|
||||||
|
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
class MacroInputVariables {
|
||||||
|
public:
|
||||||
|
void Save(obs_data_t *obj) const;
|
||||||
|
void Load(obs_data_t *obj);
|
||||||
|
void SetValues(const StringList &values);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::weak_ptr<Variable>> _inputVariables;
|
||||||
|
friend class MacroInputSelection;
|
||||||
|
friend class MacroInputEdit;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroInputSelection final : public ListEditor {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroInputSelection(QWidget *parent = nullptr);
|
||||||
|
void SetInputs(const MacroInputVariables &inputs);
|
||||||
|
MacroInputVariables GetInputs() const { return _currentSelection; }
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void Add();
|
||||||
|
void Remove();
|
||||||
|
void Up();
|
||||||
|
void Down();
|
||||||
|
void Clicked(QListWidgetItem *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
MacroInputVariables _currentSelection;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroInputEdit final : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroInputEdit(QWidget *parent = nullptr);
|
||||||
|
void SetInputVariablesAndValues(const MacroInputVariables &inputs,
|
||||||
|
const StringList &values);
|
||||||
|
bool HasInputsToSet() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void MacroInputValuesChanged(const StringList &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetupWidgets();
|
||||||
|
|
||||||
|
MacroInputVariables _variables;
|
||||||
|
StringList _values;
|
||||||
|
QGridLayout *_layout;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
@@ -7,68 +7,16 @@
|
|||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
MacroList::MacroList(QWidget *parent, bool allowDuplicates, bool reorder)
|
MacroList::MacroList(QWidget *parent, bool allowDuplicates, bool reorder)
|
||||||
: QWidget(parent),
|
: ListEditor(parent, reorder),
|
||||||
_list(new QListWidget()),
|
_allowDuplicates(allowDuplicates)
|
||||||
_add(new QPushButton()),
|
|
||||||
_remove(new QPushButton()),
|
|
||||||
_up(new QPushButton()),
|
|
||||||
_down(new QPushButton()),
|
|
||||||
_controlsLayout(new QHBoxLayout()),
|
|
||||||
_allowDuplicates(allowDuplicates),
|
|
||||||
_reorder(reorder)
|
|
||||||
{
|
{
|
||||||
_add->setMaximumWidth(22);
|
|
||||||
_add->setProperty("themeID",
|
|
||||||
QVariant(QString::fromUtf8("addIconSmall")));
|
|
||||||
_add->setFlat(true);
|
|
||||||
_remove->setMaximumWidth(22);
|
|
||||||
_remove->setProperty("themeID",
|
|
||||||
QVariant(QString::fromUtf8("removeIconSmall")));
|
|
||||||
_remove->setFlat(true);
|
|
||||||
_up->setMaximumWidth(22);
|
|
||||||
_up->setProperty("themeID",
|
|
||||||
QVariant(QString::fromUtf8("upArrowIconSmall")));
|
|
||||||
_up->setFlat(true);
|
|
||||||
_down->setMaximumWidth(22);
|
|
||||||
_down->setProperty("themeID",
|
|
||||||
QVariant(QString::fromUtf8("downArrowIconSmall")));
|
|
||||||
_down->setFlat(true);
|
|
||||||
|
|
||||||
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(Add()));
|
|
||||||
QWidget::connect(_remove, SIGNAL(clicked()), this, SLOT(Remove()));
|
|
||||||
QWidget::connect(_up, SIGNAL(clicked()), this, SLOT(Up()));
|
|
||||||
QWidget::connect(_down, SIGNAL(clicked()), this, SLOT(Down()));
|
|
||||||
QWidget::connect(_list, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
|
|
||||||
this, SLOT(MacroItemClicked(QListWidgetItem *)));
|
|
||||||
QWidget::connect(window(),
|
QWidget::connect(window(),
|
||||||
SIGNAL(MacroRenamed(const QString &, const QString &)),
|
SIGNAL(MacroRenamed(const QString &, const QString &)),
|
||||||
this,
|
this,
|
||||||
SLOT(MacroRename(const QString &, const QString &)));
|
SLOT(MacroRename(const QString &, const QString &)));
|
||||||
QWidget::connect(window(), SIGNAL(MacroRemoved(const QString &)), this,
|
QWidget::connect(window(), SIGNAL(MacroRemoved(const QString &)), this,
|
||||||
SLOT(MacroRemove(const QString &)));
|
SLOT(MacroRemove(const QString &)));
|
||||||
|
UpdateListSize();
|
||||||
_controlsLayout->addWidget(_add);
|
|
||||||
_controlsLayout->addWidget(_remove);
|
|
||||||
if (reorder) {
|
|
||||||
QFrame *line = new QFrame();
|
|
||||||
line->setFrameShape(QFrame::VLine);
|
|
||||||
line->setFrameShadow(QFrame::Sunken);
|
|
||||||
_controlsLayout->addWidget(line);
|
|
||||||
}
|
|
||||||
_controlsLayout->addWidget(_up);
|
|
||||||
_controlsLayout->addWidget(_down);
|
|
||||||
_controlsLayout->addStretch();
|
|
||||||
|
|
||||||
auto mainLayout = new QVBoxLayout;
|
|
||||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
mainLayout->addWidget(_list);
|
|
||||||
mainLayout->addLayout(_controlsLayout);
|
|
||||||
setLayout(mainLayout);
|
|
||||||
|
|
||||||
_up->setVisible(reorder);
|
|
||||||
_down->setVisible(reorder);
|
|
||||||
|
|
||||||
SetMacroListSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroList::SetContent(const std::vector<MacroRef> ¯os)
|
void MacroList::SetContent(const std::vector<MacroRef> ¯os)
|
||||||
@@ -89,12 +37,15 @@ void MacroList::SetContent(const std::vector<MacroRef> ¯os)
|
|||||||
new QListWidgetItem(listEntryName, _list);
|
new QListWidgetItem(listEntryName, _list);
|
||||||
item->setData(Qt::UserRole, listEntryName);
|
item->setData(Qt::UserRole, listEntryName);
|
||||||
}
|
}
|
||||||
SetMacroListSize();
|
UpdateListSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroList::AddControl(QWidget *widget)
|
QAction *MacroList::AddControl(QWidget *widget, bool addSeperator)
|
||||||
{
|
{
|
||||||
_controlsLayout->insertWidget(_controlsLayout->count() - 1, widget);
|
if (addSeperator) {
|
||||||
|
_controls->addSeparator();
|
||||||
|
}
|
||||||
|
return _controls->addWidget(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MacroList::CurrentRow()
|
int MacroList::CurrentRow()
|
||||||
@@ -122,13 +73,13 @@ void MacroList::MacroRemove(const QString &name)
|
|||||||
delete _list->item(idx);
|
delete _list->item(idx);
|
||||||
idx = FindEntry(name.toStdString());
|
idx = FindEntry(name.toStdString());
|
||||||
}
|
}
|
||||||
SetMacroListSize();
|
UpdateListSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroList::Add()
|
void MacroList::Add()
|
||||||
{
|
{
|
||||||
std::string macroName;
|
std::string macroName;
|
||||||
bool accepted = MacroSelectionDialog::AskForMacro(this, macroName);
|
bool accepted = MacroSelectionDialog::AskForMacro(macroName);
|
||||||
|
|
||||||
if (!accepted || macroName.empty()) {
|
if (!accepted || macroName.empty()) {
|
||||||
return;
|
return;
|
||||||
@@ -142,7 +93,7 @@ void MacroList::Add()
|
|||||||
auto item =
|
auto item =
|
||||||
new QListWidgetItem(QString::fromStdString(macroName), _list);
|
new QListWidgetItem(QString::fromStdString(macroName), _list);
|
||||||
item->setData(Qt::UserRole, QString::fromStdString(macroName));
|
item->setData(Qt::UserRole, QString::fromStdString(macroName));
|
||||||
SetMacroListSize();
|
UpdateListSize();
|
||||||
emit Added(macroName);
|
emit Added(macroName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +105,7 @@ void MacroList::Remove()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
delete item;
|
delete item;
|
||||||
SetMacroListSize();
|
UpdateListSize();
|
||||||
emit Removed(idx);
|
emit Removed(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,10 +129,10 @@ void MacroList::Down()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroList::MacroItemClicked(QListWidgetItem *item)
|
void MacroList::Clicked(QListWidgetItem *item)
|
||||||
{
|
{
|
||||||
std::string macroName;
|
std::string macroName;
|
||||||
bool accepted = MacroSelectionDialog::AskForMacro(this, macroName);
|
bool accepted = MacroSelectionDialog::AskForMacro(macroName);
|
||||||
|
|
||||||
if (!accepted || macroName.empty()) {
|
if (!accepted || macroName.empty()) {
|
||||||
return;
|
return;
|
||||||
@@ -216,10 +167,4 @@ int MacroList::FindEntry(const std::string ¯o)
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroList::SetMacroListSize()
|
|
||||||
{
|
|
||||||
SetHeightToContentHeight(_list);
|
|
||||||
adjustSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "list-editor.hpp"
|
||||||
#include "macro-ref.hpp"
|
#include "macro-ref.hpp"
|
||||||
|
|
||||||
#include <QListWidget>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
|
|
||||||
namespace advss {
|
namespace advss {
|
||||||
|
|
||||||
class ADVSS_EXPORT MacroList : public QWidget {
|
class ADVSS_EXPORT MacroList final : public ListEditor {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MacroList(QWidget *parent, bool allowDuplicates, bool reorder);
|
MacroList(QWidget *parent, bool allowDuplicates, bool reorder);
|
||||||
void SetContent(const std::vector<MacroRef> &);
|
void SetContent(const std::vector<MacroRef> &);
|
||||||
void AddControl(QWidget *);
|
QAction *AddControl(QWidget *, bool addSeperator = true);
|
||||||
int CurrentRow();
|
int CurrentRow();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@@ -22,7 +19,7 @@ private slots:
|
|||||||
void Remove();
|
void Remove();
|
||||||
void Up();
|
void Up();
|
||||||
void Down();
|
void Down();
|
||||||
void MacroItemClicked(QListWidgetItem *);
|
void Clicked(QListWidgetItem *);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void Added(const std::string &);
|
void Added(const std::string &);
|
||||||
@@ -33,16 +30,8 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int FindEntry(const std::string ¯o);
|
int FindEntry(const std::string ¯o);
|
||||||
void SetMacroListSize();
|
|
||||||
|
|
||||||
QListWidget *_list;
|
|
||||||
QPushButton *_add;
|
|
||||||
QPushButton *_remove;
|
|
||||||
QPushButton *_up;
|
|
||||||
QPushButton *_down;
|
|
||||||
QHBoxLayout *_controlsLayout;
|
|
||||||
const bool _allowDuplicates;
|
const bool _allowDuplicates;
|
||||||
const bool _reorder;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|||||||
@@ -96,11 +96,15 @@ void MacroRunButton::Pressed()
|
|||||||
|
|
||||||
bool ret = _elseStateActive ? macro->PerformActions(false, true, true)
|
bool ret = _elseStateActive ? macro->PerformActions(false, true, true)
|
||||||
: macro->PerformActions(true, true, true);
|
: macro->PerformActions(true, true, true);
|
||||||
|
if (ret) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ret) {
|
QString err = obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
||||||
QString err =
|
const bool abortMacro = DisplayMessage(
|
||||||
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
|
err.arg(QString::fromStdString(macro->Name())), true);
|
||||||
DisplayMessage(err.arg(QString::fromStdString(macro->Name())));
|
if (abortMacro) {
|
||||||
|
macro->Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
447
lib/macro/macro-script-handler.cpp
Normal file
447
lib/macro/macro-script-handler.cpp
Normal file
@@ -0,0 +1,447 @@
|
|||||||
|
#include "macro-script-handler.hpp"
|
||||||
|
#include "macro-action-script.hpp"
|
||||||
|
#include "macro-condition-script.hpp"
|
||||||
|
#include "plugin-state-helpers.hpp"
|
||||||
|
#include "log-helper.hpp"
|
||||||
|
#include "variable.hpp"
|
||||||
|
|
||||||
|
#include <obs-properties.h>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
std::mutex ScriptHandler::_mutex = {};
|
||||||
|
std::unordered_map<std::string, ScriptSegmentType> ScriptHandler::_actions = {};
|
||||||
|
std::unordered_map<std::string, ScriptSegmentType> ScriptHandler::_conditions =
|
||||||
|
{};
|
||||||
|
|
||||||
|
/* Procedure handler helpers */
|
||||||
|
|
||||||
|
#define RETURN_STATUS(status) \
|
||||||
|
{ \
|
||||||
|
calldata_set_bool(data, "success", status); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
#define RETURN_SUCCESS() RETURN_STATUS(true);
|
||||||
|
#define RETURN_FAILURE() RETURN_STATUS(false);
|
||||||
|
|
||||||
|
static constexpr std::string_view nameParam = "name";
|
||||||
|
static constexpr std::string_view defaultSettingsParam = "default_settings";
|
||||||
|
static constexpr std::string_view propertiesSignalParam =
|
||||||
|
"properties_signal_name";
|
||||||
|
static constexpr std::string_view triggerSignalParam = "trigger_signal_name";
|
||||||
|
|
||||||
|
static std::string getRegisterScriptSegmentDeclString(const char *funcName)
|
||||||
|
{
|
||||||
|
return std::string("bool ") + funcName + "(in string " +
|
||||||
|
nameParam.data() + ", in ptr " + defaultSettingsParam.data() +
|
||||||
|
", out string " + propertiesSignalParam.data() +
|
||||||
|
", out string " + triggerSignalParam.data() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getDeregisterScriptSegmentDeclString(const char *funcName)
|
||||||
|
{
|
||||||
|
return std::string("bool ") + funcName + "(in string " +
|
||||||
|
nameParam.data() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Script actions */
|
||||||
|
|
||||||
|
static constexpr std::string_view registerActionFuncName =
|
||||||
|
"advss_register_script_action";
|
||||||
|
static constexpr std::string_view deregisterActionFuncName =
|
||||||
|
"advss_deregister_script_action";
|
||||||
|
|
||||||
|
static const std::string registerScriptActionDeclString =
|
||||||
|
getRegisterScriptSegmentDeclString(registerActionFuncName.data());
|
||||||
|
static const std::string deregisterScriptActionDeclString =
|
||||||
|
getDeregisterScriptSegmentDeclString(deregisterActionFuncName.data());
|
||||||
|
|
||||||
|
/* Script conditions */
|
||||||
|
|
||||||
|
static constexpr std::string_view registerConditionFuncName =
|
||||||
|
"advss_register_script_condition";
|
||||||
|
static constexpr std::string_view deregisterConditionFuncName =
|
||||||
|
"advss_deregister_script_condition";
|
||||||
|
|
||||||
|
static const std::string registerScriptConditionDeclString =
|
||||||
|
getRegisterScriptSegmentDeclString(registerConditionFuncName.data());
|
||||||
|
static const std::string deregisterScriptConditionDeclString =
|
||||||
|
getDeregisterScriptSegmentDeclString(
|
||||||
|
deregisterConditionFuncName.data());
|
||||||
|
|
||||||
|
/* Script variables */
|
||||||
|
|
||||||
|
static constexpr std::string_view valueParam = "value";
|
||||||
|
static constexpr std::string_view getVariableValueFuncName =
|
||||||
|
"advss_get_variable_value";
|
||||||
|
static constexpr std::string_view setVariableValueFuncName =
|
||||||
|
"advss_set_variable_value";
|
||||||
|
static const std::string getVariableValueDeclString =
|
||||||
|
std::string("bool ") + getVariableValueFuncName.data() + "(in string " +
|
||||||
|
nameParam.data() + ", out string " + valueParam.data() + ")";
|
||||||
|
static const std::string setVariableValueDeclString =
|
||||||
|
std::string("bool ") + setVariableValueFuncName.data() + "(in string " +
|
||||||
|
nameParam.data() + ", in string " + valueParam.data() + ")";
|
||||||
|
|
||||||
|
static bool setup();
|
||||||
|
static bool setupDone = setup();
|
||||||
|
|
||||||
|
static bool setup()
|
||||||
|
{
|
||||||
|
proc_handler_t *ph = obs_get_proc_handler();
|
||||||
|
assert(ph != NULL);
|
||||||
|
|
||||||
|
proc_handler_add(ph, registerScriptActionDeclString.c_str(),
|
||||||
|
&ScriptHandler::RegisterScriptAction, nullptr);
|
||||||
|
proc_handler_add(ph, deregisterScriptActionDeclString.c_str(),
|
||||||
|
&ScriptHandler::DeregisterScriptAction, nullptr);
|
||||||
|
proc_handler_add(ph, registerScriptConditionDeclString.c_str(),
|
||||||
|
&ScriptHandler::RegisterScriptCondition, nullptr);
|
||||||
|
proc_handler_add(ph, deregisterScriptConditionDeclString.c_str(),
|
||||||
|
&ScriptHandler::DeregisterScriptCondition, nullptr);
|
||||||
|
proc_handler_add(ph, getVariableValueDeclString.c_str(),
|
||||||
|
&ScriptHandler::GetVariableValue, nullptr);
|
||||||
|
proc_handler_add(ph, setVariableValueDeclString.c_str(),
|
||||||
|
&ScriptHandler::SetVariableValue, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void replaceWhitespace(std::string &string)
|
||||||
|
{
|
||||||
|
std::transform(string.begin(), string.end(), string.begin(), [](char c) {
|
||||||
|
return std::isspace(static_cast<unsigned char>(c)) ? '_' : c;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string nameToScriptID(const std::string &name)
|
||||||
|
{
|
||||||
|
return std::string("script_") + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getTriggerSignal(const std::string &name,
|
||||||
|
const bool isAction)
|
||||||
|
{
|
||||||
|
std::string signal = name;
|
||||||
|
replaceWhitespace(signal);
|
||||||
|
signal += "_run";
|
||||||
|
signal += isAction ? "_action" : "_condition";
|
||||||
|
return signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getCompletionSignal(const std::string &name,
|
||||||
|
const bool isAction)
|
||||||
|
{
|
||||||
|
auto signal = getTriggerSignal(name, isAction);
|
||||||
|
signal += "_complete";
|
||||||
|
return signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getPropertiesSignal(const std::string &name,
|
||||||
|
const bool isAction)
|
||||||
|
{
|
||||||
|
std::string signal = name;
|
||||||
|
replaceWhitespace(signal);
|
||||||
|
signal += isAction ? "_action" : "_condition";
|
||||||
|
signal += "_get_properties";
|
||||||
|
return signal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptHandler::RegisterScriptAction(void *, calldata_t *data)
|
||||||
|
{
|
||||||
|
const char *actionName;
|
||||||
|
if (!calldata_get_string(data, nameParam.data(), &actionName) ||
|
||||||
|
strlen(actionName) == 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
registerScriptActionDeclString.data(), nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
obs_data_t *defaultSettingsPtr = nullptr;
|
||||||
|
if (!calldata_get_ptr(data, defaultSettingsParam.data(),
|
||||||
|
&defaultSettingsPtr)) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
registerActionFuncName.data(),
|
||||||
|
defaultSettingsParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
OBSData defaultSettings(defaultSettingsPtr);
|
||||||
|
obs_data_release(defaultSettingsPtr);
|
||||||
|
|
||||||
|
if (_actions.count(actionName) > 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! Action \"%s\" already exists!",
|
||||||
|
registerActionFuncName.data(), actionName);
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string id = nameToScriptID(actionName);
|
||||||
|
auto triggerSignalName = getTriggerSignal(actionName, true);
|
||||||
|
auto completionSignalName = getCompletionSignal(actionName, true);
|
||||||
|
auto propertiesSignalName = getPropertiesSignal(actionName, true);
|
||||||
|
|
||||||
|
const auto createScriptAction =
|
||||||
|
[id, defaultSettings, propertiesSignalName, triggerSignalName,
|
||||||
|
completionSignalName](
|
||||||
|
Macro *m) -> std::shared_ptr<MacroAction> {
|
||||||
|
return std::make_shared<MacroActionScript>(
|
||||||
|
m, id, defaultSettings, propertiesSignalName,
|
||||||
|
triggerSignalName, completionSignalName);
|
||||||
|
};
|
||||||
|
if (!MacroActionFactory::Register(id, {createScriptAction,
|
||||||
|
MacroSegmentScriptEdit::Create,
|
||||||
|
actionName})) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! Action id \"%s\" already exists!",
|
||||||
|
registerActionFuncName.data(), id.c_str());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
blog(LOG_INFO, "[%s] successful for \"%s\"",
|
||||||
|
registerActionFuncName.data(), actionName);
|
||||||
|
|
||||||
|
calldata_set_string(data, triggerSignalParam.data(),
|
||||||
|
triggerSignalName.c_str());
|
||||||
|
calldata_set_string(data, propertiesSignalParam.data(),
|
||||||
|
propertiesSignalName.c_str());
|
||||||
|
_actions.emplace(id, ScriptSegmentType(id, propertiesSignalName,
|
||||||
|
triggerSignalName,
|
||||||
|
completionSignalName));
|
||||||
|
|
||||||
|
RETURN_SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptHandler::DeregisterScriptAction(void *, calldata_t *data)
|
||||||
|
{
|
||||||
|
const char *actionName;
|
||||||
|
if (!calldata_get_string(data, nameParam.data(), &actionName) ||
|
||||||
|
strlen(actionName) == 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
deregisterActionFuncName.data(), nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string id = nameToScriptID(actionName);
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
|
||||||
|
if (_actions.count(id) == 0) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! Action \"%s\" was never registered!",
|
||||||
|
deregisterActionFuncName.data(), id.c_str());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MacroActionFactory::Deregister(id)) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! Action id \"%s\" does not exist!",
|
||||||
|
deregisterActionFuncName.data(), id.c_str());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = _actions.find(id);
|
||||||
|
if (it != _actions.end()) {
|
||||||
|
_actions.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptHandler::RegisterScriptCondition(void *, calldata_t *data)
|
||||||
|
{
|
||||||
|
const char *conditionName;
|
||||||
|
if (!calldata_get_string(data, nameParam.data(), &conditionName) ||
|
||||||
|
strlen(conditionName) == 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
registerScriptConditionDeclString.data(),
|
||||||
|
nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_data_t *defaultSettingsPtr = nullptr;
|
||||||
|
if (!calldata_get_ptr(data, defaultSettingsParam.data(),
|
||||||
|
&defaultSettingsPtr)) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
registerScriptConditionDeclString.data(),
|
||||||
|
defaultSettingsParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
OBSData defaultSettings(defaultSettingsPtr);
|
||||||
|
obs_data_release(defaultSettingsPtr);
|
||||||
|
|
||||||
|
if (_conditions.count(conditionName) > 0) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! Condition \"%s\" already exists!",
|
||||||
|
registerConditionFuncName.data(), conditionName);
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string id = nameToScriptID(conditionName);
|
||||||
|
auto triggerSignalName = getTriggerSignal(conditionName, false);
|
||||||
|
auto completionSignalName = getCompletionSignal(conditionName, false);
|
||||||
|
auto propertiesSignalName = getPropertiesSignal(conditionName, false);
|
||||||
|
|
||||||
|
const auto createScriptCondition =
|
||||||
|
[id, defaultSettings, propertiesSignalName, triggerSignalName,
|
||||||
|
completionSignalName](
|
||||||
|
Macro *m) -> std::shared_ptr<MacroCondition> {
|
||||||
|
return std::make_shared<MacroConditionScript>(
|
||||||
|
m, id, defaultSettings, propertiesSignalName,
|
||||||
|
triggerSignalName, completionSignalName);
|
||||||
|
};
|
||||||
|
if (!MacroConditionFactory::Register(
|
||||||
|
id, {createScriptCondition, MacroSegmentScriptEdit::Create,
|
||||||
|
conditionName})) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! Condition id \"%s\" already exists!",
|
||||||
|
registerConditionFuncName.data(), id.c_str());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
blog(LOG_INFO, "[%s] successful for \"%s\"",
|
||||||
|
registerConditionFuncName.data(), conditionName);
|
||||||
|
|
||||||
|
calldata_set_string(data, triggerSignalParam.data(),
|
||||||
|
triggerSignalName.c_str());
|
||||||
|
calldata_set_string(data, propertiesSignalParam.data(),
|
||||||
|
propertiesSignalName.c_str());
|
||||||
|
_conditions.emplace(id, ScriptSegmentType(id, propertiesSignalName,
|
||||||
|
triggerSignalName,
|
||||||
|
completionSignalName));
|
||||||
|
|
||||||
|
RETURN_SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptHandler::DeregisterScriptCondition(void *, calldata_t *data)
|
||||||
|
{
|
||||||
|
const char *conditionName;
|
||||||
|
if (!calldata_get_string(data, nameParam.data(), &conditionName) ||
|
||||||
|
strlen(conditionName) == 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
deregisterConditionFuncName.data(), nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string id = nameToScriptID(conditionName);
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
|
||||||
|
if (_conditions.count(id) == 0) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! Condition \"%s\" was never registered!",
|
||||||
|
deregisterConditionFuncName.data(), id.c_str());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MacroConditionFactory::Deregister(id)) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! Condition id \"%s\" does not exist!",
|
||||||
|
deregisterConditionFuncName.data(), id.c_str());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = _conditions.find(id);
|
||||||
|
if (it != _conditions.end()) {
|
||||||
|
_conditions.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptHandler::GetVariableValue(void *, calldata_t *data)
|
||||||
|
{
|
||||||
|
const char *variableName;
|
||||||
|
if (!calldata_get_string(data, nameParam.data(), &variableName) ||
|
||||||
|
strlen(variableName) == 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
getVariableValueFuncName.data(), nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto weakVariable = GetWeakVariableByName(variableName);
|
||||||
|
auto variable = weakVariable.lock();
|
||||||
|
if (!variable) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! \"%s\" variable does not exist!",
|
||||||
|
getVariableValueFuncName.data(), nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
calldata_set_string(data, valueParam.data(), variable->Value().c_str());
|
||||||
|
RETURN_SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptHandler::SetVariableValue(void *, calldata_t *data)
|
||||||
|
{
|
||||||
|
const char *variableName;
|
||||||
|
if (!calldata_get_string(data, nameParam.data(), &variableName) ||
|
||||||
|
strlen(variableName) == 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
getVariableValueFuncName.data(), nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
const char *variableValue;
|
||||||
|
if (!calldata_get_string(data, valueParam.data(), &variableValue) ||
|
||||||
|
strlen(variableValue) == 0) {
|
||||||
|
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
|
||||||
|
getVariableValueFuncName.data(), valueParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto weakVariable = GetWeakVariableByName(variableName);
|
||||||
|
auto variable = weakVariable.lock();
|
||||||
|
if (!variable) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[%s] failed! \"%s\" variable does not exist!",
|
||||||
|
getVariableValueFuncName.data(), nameParam.data());
|
||||||
|
RETURN_FAILURE();
|
||||||
|
}
|
||||||
|
|
||||||
|
variable->SetValue(variableValue);
|
||||||
|
RETURN_SUCCESS();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScriptHandler::ActionIdIsValid(const std::string &id)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
return _actions.count(id) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScriptHandler::ConditionIdIsValid(const std::string &id)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
return _conditions.count(id) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string signalNameToTriggerSignalDecl(const std::string &name)
|
||||||
|
{
|
||||||
|
return std::string("void ") + name + "()";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string signalNameToPropertiesSignalDecl(const std::string &name)
|
||||||
|
{
|
||||||
|
return std::string("void ") + name + "(in ptr " +
|
||||||
|
GetPropertiesSignalParamName().data() + ")";
|
||||||
|
}
|
||||||
|
static std::string signalNameToCompletionSignalDecl(const std::string &name)
|
||||||
|
{
|
||||||
|
return std::string("bool ") + name + "(in int " +
|
||||||
|
GeCompletionIdParamName().data() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptSegmentType::ScriptSegmentType(const std::string &id,
|
||||||
|
const std::string &propertiesSignal,
|
||||||
|
const std::string &triggerSignal,
|
||||||
|
const std::string &completionSignal)
|
||||||
|
: _id(id)
|
||||||
|
{
|
||||||
|
signal_handler_add(
|
||||||
|
obs_get_signal_handler(),
|
||||||
|
signalNameToPropertiesSignalDecl(propertiesSignal).c_str());
|
||||||
|
signal_handler_add(
|
||||||
|
obs_get_signal_handler(),
|
||||||
|
signalNameToTriggerSignalDecl(triggerSignal).c_str());
|
||||||
|
signal_handler_add(
|
||||||
|
obs_get_signal_handler(),
|
||||||
|
signalNameToCompletionSignalDecl(completionSignal).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
59
lib/macro/macro-script-handler.hpp
Normal file
59
lib/macro/macro-script-handler.hpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <obs.hpp>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
class ScriptSegmentType {
|
||||||
|
public:
|
||||||
|
ScriptSegmentType() = delete;
|
||||||
|
ScriptSegmentType(const std::string &id,
|
||||||
|
const std::string &propertiesSignal,
|
||||||
|
const std::string &triggerSignal,
|
||||||
|
const std::string &completionSignal);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScriptHandler {
|
||||||
|
public:
|
||||||
|
ScriptHandler() = delete;
|
||||||
|
static void RegisterScriptAction(void *ctx, calldata_t *data);
|
||||||
|
static void DeregisterScriptAction(void *ctx, calldata_t *data);
|
||||||
|
static void RegisterScriptCondition(void *ctx, calldata_t *data);
|
||||||
|
static void DeregisterScriptCondition(void *ctx, calldata_t *data);
|
||||||
|
static void GetVariableValue(void *ctx, calldata_t *data);
|
||||||
|
static void SetVariableValue(void *ctx, calldata_t *data);
|
||||||
|
static bool ActionIdIsValid(const std::string &id);
|
||||||
|
static bool ConditionIdIsValid(const std::string &id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::mutex _mutex;
|
||||||
|
static std::unordered_map<std::string, ScriptSegmentType> _actions;
|
||||||
|
static std::unordered_map<std::string, ScriptSegmentType> _conditions;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr std::string_view GetPropertiesSignalParamName()
|
||||||
|
{
|
||||||
|
return "properties";
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::string_view GetActionCompletionSignalParamName()
|
||||||
|
{
|
||||||
|
return "completion_signal_name";
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::string_view GeCompletionIdParamName()
|
||||||
|
{
|
||||||
|
return "completion_id";
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::string_view GeResultSignalParamName()
|
||||||
|
{
|
||||||
|
return "result";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
124
lib/macro/macro-segment-copy-paste.cpp
Normal file
124
lib/macro/macro-segment-copy-paste.cpp
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
#include "macro-segment-copy-paste.hpp"
|
||||||
|
#include "advanced-scene-switcher.hpp"
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include "ui-helpers.hpp"
|
||||||
|
|
||||||
|
#include <QShortcut>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
struct MacroSegmentCopyInfo {
|
||||||
|
enum class Type { NONE, CONDITION, ACTION, ELSE };
|
||||||
|
Type type = Type::NONE;
|
||||||
|
std::shared_ptr<MacroSegment> segment;
|
||||||
|
};
|
||||||
|
static MacroSegmentCopyInfo copyInfo;
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::CopyMacroSegment()
|
||||||
|
{
|
||||||
|
copyInfo.segment.reset();
|
||||||
|
copyInfo.type = MacroSegmentCopyInfo::Type::NONE;
|
||||||
|
|
||||||
|
if (currentConditionIdx == -1 && currentActionIdx == -1 &&
|
||||||
|
currentElseActionIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentConditionIdx != -1) {
|
||||||
|
copyInfo.type = MacroSegmentCopyInfo::Type::CONDITION;
|
||||||
|
copyInfo.segment = macro->Conditions().at(currentConditionIdx);
|
||||||
|
} else if (currentActionIdx != -1) {
|
||||||
|
copyInfo.type = MacroSegmentCopyInfo::Type::ACTION;
|
||||||
|
copyInfo.segment = macro->Actions().at(currentActionIdx);
|
||||||
|
} else if (currentElseActionIdx != -1) {
|
||||||
|
copyInfo.type = MacroSegmentCopyInfo::Type::ELSE;
|
||||||
|
copyInfo.segment =
|
||||||
|
macro->ElseActions().at(currentElseActionIdx);
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::PasteMacroSegment()
|
||||||
|
{
|
||||||
|
if (copyInfo.type == MacroSegmentCopyInfo::Type::NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto macro = GetSelectedMacro();
|
||||||
|
if (!macro || !copyInfo.segment) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
|
copyInfo.segment->Save(data);
|
||||||
|
|
||||||
|
switch (copyInfo.type) {
|
||||||
|
case MacroSegmentCopyInfo::Type::CONDITION: {
|
||||||
|
const auto condition = std::static_pointer_cast<MacroCondition>(
|
||||||
|
copyInfo.segment);
|
||||||
|
auto logic = condition->GetLogicType();
|
||||||
|
if (logic > Logic::Type::ROOT_LAST &&
|
||||||
|
macro->Conditions().empty()) {
|
||||||
|
logic = Logic::Type::ROOT_NONE;
|
||||||
|
}
|
||||||
|
if (logic < Logic::Type::ROOT_LAST &&
|
||||||
|
!macro->Conditions().empty()) {
|
||||||
|
logic = Logic::Type::OR;
|
||||||
|
}
|
||||||
|
AddMacroCondition(macro.get(), macro->Conditions().size(),
|
||||||
|
copyInfo.segment->GetId(), data.Get(), logic);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MacroSegmentCopyInfo::Type::ACTION:
|
||||||
|
if (IsCursorInWidgetArea(ui->macroElseActions)) {
|
||||||
|
AddMacroElseAction(macro.get(),
|
||||||
|
macro->ElseActions().size(),
|
||||||
|
copyInfo.segment->GetId(),
|
||||||
|
data.Get());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AddMacroAction(macro.get(), macro->Actions().size(),
|
||||||
|
copyInfo.segment->GetId(), data.Get());
|
||||||
|
break;
|
||||||
|
case MacroSegmentCopyInfo::Type::ELSE:
|
||||||
|
if (IsCursorInWidgetArea(ui->macroActions)) {
|
||||||
|
AddMacroAction(macro.get(), macro->Actions().size(),
|
||||||
|
copyInfo.segment->GetId(), data.Get());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AddMacroElseAction(macro.get(), macro->ElseActions().size(),
|
||||||
|
copyInfo.segment->GetId(), data.Get());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroSegmentIsInClipboard()
|
||||||
|
{
|
||||||
|
return copyInfo.type != MacroSegmentCopyInfo::Type::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroActionIsInClipboard()
|
||||||
|
{
|
||||||
|
return copyInfo.type == MacroSegmentCopyInfo::Type::ACTION ||
|
||||||
|
copyInfo.type == MacroSegmentCopyInfo::Type::ELSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupSegmentCopyPasteShortcutHandlers(AdvSceneSwitcher *window)
|
||||||
|
{
|
||||||
|
auto copyShortcut = new QShortcut(QKeySequence("Ctrl+C"), window);
|
||||||
|
QWidget::connect(copyShortcut, &QShortcut::activated, window,
|
||||||
|
&AdvSceneSwitcher::CopyMacroSegment);
|
||||||
|
auto pasteShortcut = new QShortcut(QKeySequence("Ctrl+V"), window);
|
||||||
|
QWidget::connect(pasteShortcut, &QShortcut::activated, window,
|
||||||
|
&AdvSceneSwitcher::PasteMacroSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
9
lib/macro/macro-segment-copy-paste.hpp
Normal file
9
lib/macro/macro-segment-copy-paste.hpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace advss {
|
||||||
|
|
||||||
|
class AdvSceneSwitcher;
|
||||||
|
|
||||||
|
bool MacroSegmentIsInClipboard();
|
||||||
|
bool MacroActionIsInClipboard();
|
||||||
|
void SetupSegmentCopyPasteShortcutHandlers(AdvSceneSwitcher *window);
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
@@ -130,7 +130,7 @@ void MacroSegmentList::Highlight(int idx, QColor color)
|
|||||||
if (!widget) {
|
if (!widget) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PulseWidget(widget, color, QColor(0, 0, 0, 0), true);
|
HighlightWidget(widget, color, QColor(0, 0, 0, 0), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroSegmentList::SetCollapsed(bool collapse)
|
void MacroSegmentList::SetCollapsed(bool collapse)
|
||||||
@@ -176,7 +176,8 @@ bool MacroSegmentList::eventFilter(QObject *object, QEvent *event)
|
|||||||
|
|
||||||
void MacroSegmentList::mousePressEvent(QMouseEvent *event)
|
void MacroSegmentList::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (event->button() == Qt::LeftButton) {
|
if (event->button() == Qt::LeftButton ||
|
||||||
|
event->button() == Qt::RightButton) {
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||||
_dragPosition = GetDragIndex(event->globalPos());
|
_dragPosition = GetDragIndex(event->globalPos());
|
||||||
#else
|
#else
|
||||||
@@ -246,6 +247,11 @@ MacroSegmentEdit *MacroSegmentList::WidgetAt(int idx)
|
|||||||
return static_cast<MacroSegmentEdit *>(item->widget());
|
return static_cast<MacroSegmentEdit *>(item->widget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MacroSegmentEdit *MacroSegmentList::WidgetAt(const QPoint &pos)
|
||||||
|
{
|
||||||
|
return WidgetAt(GetSegmentIndexFromPos(mapToGlobal(pos)));
|
||||||
|
}
|
||||||
|
|
||||||
void MacroSegmentList::HideLastDropLine()
|
void MacroSegmentList::HideLastDropLine()
|
||||||
{
|
{
|
||||||
if (_dropLineIdx >= 0 && _dropLineIdx < _contentLayout->count()) {
|
if (_dropLineIdx >= 0 && _dropLineIdx < _contentLayout->count()) {
|
||||||
@@ -319,7 +325,7 @@ QRect MacroSegmentList::GetContentItemRectWithPadding(int idx)
|
|||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MacroSegmentList::GetWidgetIdx(const QPoint &pos)
|
int MacroSegmentList::GetSegmentIndexFromPos(const QPoint &pos)
|
||||||
{
|
{
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
for (int i = 0; i < _contentLayout->count(); ++i) {
|
for (int i = 0; i < _contentLayout->count(); ++i) {
|
||||||
@@ -359,7 +365,7 @@ void MacroSegmentList::CheckScroll()
|
|||||||
|
|
||||||
void MacroSegmentList::CheckDropLine(const QPoint &pos)
|
void MacroSegmentList::CheckDropLine(const QPoint &pos)
|
||||||
{
|
{
|
||||||
int idx = GetWidgetIdx(pos);
|
int idx = GetSegmentIndexFromPos(pos);
|
||||||
if (idx == _dragPosition) {
|
if (idx == _dragPosition) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -410,7 +416,7 @@ bool MacroSegmentList::IsInListArea(const QPoint &pos)
|
|||||||
|
|
||||||
int MacroSegmentList::GetDropIndex(const QPoint &pos)
|
int MacroSegmentList::GetDropIndex(const QPoint &pos)
|
||||||
{
|
{
|
||||||
int idx = GetWidgetIdx(pos);
|
int idx = GetSegmentIndexFromPos(pos);
|
||||||
if (idx == _dragPosition) {
|
if (idx == _dragPosition) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public:
|
|||||||
void SetHelpMsg(const QString &msg);
|
void SetHelpMsg(const QString &msg);
|
||||||
void SetHelpMsgVisible(bool visible);
|
void SetHelpMsgVisible(bool visible);
|
||||||
MacroSegmentEdit *WidgetAt(int idx);
|
MacroSegmentEdit *WidgetAt(int idx);
|
||||||
|
MacroSegmentEdit *WidgetAt(const QPoint &);
|
||||||
void Insert(int idx, MacroSegmentEdit *widget);
|
void Insert(int idx, MacroSegmentEdit *widget);
|
||||||
void Add(QWidget *widget);
|
void Add(QWidget *widget);
|
||||||
void Remove(int idx);
|
void Remove(int idx);
|
||||||
@@ -44,7 +45,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
int GetDragIndex(const QPoint &);
|
int GetDragIndex(const QPoint &);
|
||||||
int GetDropIndex(const QPoint &);
|
int GetDropIndex(const QPoint &);
|
||||||
int GetWidgetIdx(const QPoint &);
|
int GetSegmentIndexFromPos(const QPoint &);
|
||||||
void CheckScroll();
|
void CheckScroll();
|
||||||
void CheckDropLine(const QPoint &);
|
void CheckDropLine(const QPoint &);
|
||||||
bool IsInListArea(const QPoint &);
|
bool IsInListArea(const QPoint &);
|
||||||
|
|||||||
219
lib/macro/macro-segment-script.cpp
Normal file
219
lib/macro/macro-segment-script.cpp
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#include "macro-segment-script.hpp"
|
||||||
|
#include "layout-helpers.hpp"
|
||||||
|
#include "macro-action.hpp"
|
||||||
|
#include "macro-condition.hpp"
|
||||||
|
#include "macro-helpers.hpp"
|
||||||
|
#include "macro-script-handler.hpp"
|
||||||
|
#include "obs-module-helper.hpp"
|
||||||
|
#include "properties-view.hpp"
|
||||||
|
#include "sync-helpers.hpp"
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
static std::atomic_int completionIdCounter = 0;
|
||||||
|
|
||||||
|
MacroSegmentScript::MacroSegmentScript(obs_data_t *defaultSettings,
|
||||||
|
const std::string &propertiesSignalName,
|
||||||
|
const std::string &triggerSignal,
|
||||||
|
const std::string &completionSignal)
|
||||||
|
: _settings(obs_data_get_defaults(defaultSettings)),
|
||||||
|
_propertiesSignal(propertiesSignalName),
|
||||||
|
_triggerSignal(triggerSignal),
|
||||||
|
_completionSignal(completionSignal)
|
||||||
|
{
|
||||||
|
signal_handler_connect(obs_get_signal_handler(),
|
||||||
|
completionSignal.c_str(),
|
||||||
|
&MacroSegmentScript::CompletionSignalReceived,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroSegmentScript::MacroSegmentScript(const MacroSegmentScript &other)
|
||||||
|
: _settings(obs_data_create()),
|
||||||
|
_propertiesSignal(other._propertiesSignal),
|
||||||
|
_triggerSignal(other._triggerSignal),
|
||||||
|
_completionSignal(other._completionSignal)
|
||||||
|
{
|
||||||
|
signal_handler_connect(obs_get_signal_handler(),
|
||||||
|
_completionSignal.c_str(),
|
||||||
|
&MacroSegmentScript::CompletionSignalReceived,
|
||||||
|
this);
|
||||||
|
obs_data_apply(_settings.Get(), other._settings.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroSegmentScript::Save(obs_data_t *obj) const
|
||||||
|
{
|
||||||
|
obs_data_set_obj(obj, "settings", _settings.Get());
|
||||||
|
_timeout.Save(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroSegmentScript::Load(obs_data_t *obj)
|
||||||
|
{
|
||||||
|
OBSDataAutoRelease settings = obs_data_get_obj(obj, "settings");
|
||||||
|
obs_data_apply(_settings.Get(), settings);
|
||||||
|
_timeout.Load(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_properties_t *MacroSegmentScript::GetProperties() const
|
||||||
|
{
|
||||||
|
auto data = calldata_create();
|
||||||
|
signal_handler_signal(obs_get_signal_handler(),
|
||||||
|
_propertiesSignal.c_str(), data);
|
||||||
|
obs_properties_t *properties = nullptr;
|
||||||
|
if (!calldata_get_ptr(data, GetPropertiesSignalParamName().data(),
|
||||||
|
&properties)) {
|
||||||
|
calldata_destroy(data);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
calldata_destroy(data);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegmentScript::UpdateSettings(obs_data_t *newSettings) const
|
||||||
|
{
|
||||||
|
obs_data_clear(_settings.Get());
|
||||||
|
obs_data_apply(_settings.Get(), newSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MacroSegmentScript::SendTriggerSignal()
|
||||||
|
{
|
||||||
|
_completionId = ++completionIdCounter;
|
||||||
|
_triggerIsComplete = false;
|
||||||
|
_triggerResult = false;
|
||||||
|
|
||||||
|
auto data = calldata_create();
|
||||||
|
calldata_set_string(data, GetActionCompletionSignalParamName().data(),
|
||||||
|
_completionSignal.c_str());
|
||||||
|
calldata_set_int(data, GeCompletionIdParamName().data(), _completionId);
|
||||||
|
calldata_set_string(data, "settings", obs_data_get_json(GetSettings()));
|
||||||
|
signal_handler_signal(obs_get_signal_handler(), _triggerSignal.c_str(),
|
||||||
|
data);
|
||||||
|
calldata_destroy(data);
|
||||||
|
|
||||||
|
SetMacroAbortWait(false);
|
||||||
|
WaitForCompletion();
|
||||||
|
|
||||||
|
return _triggerResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegmentScript::CompletionSignalReceived(void *param, calldata_t *data)
|
||||||
|
{
|
||||||
|
auto segment = static_cast<MacroSegmentScript *>(param);
|
||||||
|
long long int id;
|
||||||
|
if (!calldata_get_int(data, GeCompletionIdParamName().data(), &id)) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"received completion signal without \"%s\" parameter",
|
||||||
|
GeCompletionIdParamName().data());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool result;
|
||||||
|
if (!calldata_get_bool(data, GeResultSignalParamName().data(),
|
||||||
|
&result)) {
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"received completion signal without \"%s\" parameter",
|
||||||
|
GeResultSignalParamName().data());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (id != segment->_completionId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
segment->_triggerIsComplete = true;
|
||||||
|
segment->_triggerResult = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_properties_t *MacroSegmentScriptEdit::GetProperties(void *obj)
|
||||||
|
{
|
||||||
|
auto segmentEdit = reinterpret_cast<MacroSegmentScriptEdit *>(obj);
|
||||||
|
if (!segmentEdit) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return segmentEdit->_entryData->GetProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegmentScriptEdit::UpdateSettings(void *obj, obs_data_t *settings)
|
||||||
|
{
|
||||||
|
auto segmentEdit = reinterpret_cast<MacroSegmentScriptEdit *>(obj);
|
||||||
|
if (!segmentEdit || segmentEdit->_loading || !segmentEdit->_entryData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto lock = LockContext();
|
||||||
|
segmentEdit->_entryData->UpdateSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroSegmentScriptEdit::MacroSegmentScriptEdit(
|
||||||
|
QWidget *parent, std::shared_ptr<MacroSegmentScript> entryData)
|
||||||
|
: QWidget(parent),
|
||||||
|
_timeout(new DurationSelection(this))
|
||||||
|
{
|
||||||
|
QWidget::connect(_timeout, &DurationSelection::DurationChanged, this,
|
||||||
|
&MacroSegmentScriptEdit::TimeoutChanged);
|
||||||
|
|
||||||
|
auto timeoutLayout = new QHBoxLayout();
|
||||||
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.script.timeout"),
|
||||||
|
timeoutLayout, {{"{{timeout}}", _timeout}});
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout();
|
||||||
|
|
||||||
|
auto properties = entryData->GetProperties();
|
||||||
|
if (!!properties) {
|
||||||
|
obs_properties_destroy(properties);
|
||||||
|
|
||||||
|
// We need a separate OBSData object here as we can't risk
|
||||||
|
// entryData->_settings being modified while it is currently used
|
||||||
|
OBSDataAutoRelease data = obs_data_create();
|
||||||
|
obs_data_apply(data, entryData->GetSettings());
|
||||||
|
|
||||||
|
#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(30, 0, 0)
|
||||||
|
auto propertiesView =
|
||||||
|
new OBSPropertiesView(data.Get(), this, GetProperties,
|
||||||
|
nullptr, UpdateSettings);
|
||||||
|
layout->addWidget(propertiesView);
|
||||||
|
connect(propertiesView, &OBSPropertiesView::PropertiesResized,
|
||||||
|
this, [this]() {
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
layout->addWidget(new QLabel(
|
||||||
|
"Displaying script properties not supported when compiled for OBS 29!"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->addLayout(timeoutLayout);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
_entryData = entryData;
|
||||||
|
UpdateEntryData();
|
||||||
|
_loading = false;
|
||||||
|
|
||||||
|
adjustSize();
|
||||||
|
updateGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegmentScriptEdit::UpdateEntryData()
|
||||||
|
{
|
||||||
|
_timeout->SetDuration(_entryData->_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *MacroSegmentScriptEdit::Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> segment)
|
||||||
|
{
|
||||||
|
return new MacroSegmentScriptEdit(
|
||||||
|
parent, std::dynamic_pointer_cast<MacroSegmentScript>(segment));
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *MacroSegmentScriptEdit::Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> segment)
|
||||||
|
{
|
||||||
|
return new MacroSegmentScriptEdit(
|
||||||
|
parent, std::dynamic_pointer_cast<MacroSegmentScript>(segment));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroSegmentScriptEdit::TimeoutChanged(const Duration &timeout)
|
||||||
|
{
|
||||||
|
GUARD_LOADING_AND_LOCK();
|
||||||
|
_entryData->_timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
78
lib/macro/macro-segment-script.hpp
Normal file
78
lib/macro/macro-segment-script.hpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
#include "macro-script-handler.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <obs-data.h>
|
||||||
|
|
||||||
|
namespace advss {
|
||||||
|
|
||||||
|
class Macro;
|
||||||
|
class MacroAction;
|
||||||
|
class MacroCondition;
|
||||||
|
|
||||||
|
class MacroSegmentScript {
|
||||||
|
public:
|
||||||
|
MacroSegmentScript(obs_data_t *defaultSettings,
|
||||||
|
const std::string &propertiesSignalName,
|
||||||
|
const std::string &triggerSignal,
|
||||||
|
const std::string &completionSignal);
|
||||||
|
MacroSegmentScript(const advss::MacroSegmentScript &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool Save(obs_data_t *obj) const;
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
|
||||||
|
obs_properties_t *GetProperties() const;
|
||||||
|
OBSData GetSettings() const { return _settings.Get(); }
|
||||||
|
void UpdateSettings(obs_data_t *newSettings) const;
|
||||||
|
|
||||||
|
bool SendTriggerSignal();
|
||||||
|
double GetTimeoutSeconds() const { return _timeout.Seconds(); };
|
||||||
|
bool TriggerIsCompleted() const { return _triggerIsComplete; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void WaitForCompletion() const = 0;
|
||||||
|
static void CompletionSignalReceived(void *param, calldata_t *data);
|
||||||
|
|
||||||
|
OBSDataAutoRelease _settings;
|
||||||
|
std::string _propertiesSignal = "";
|
||||||
|
|
||||||
|
std::string _triggerSignal = "";
|
||||||
|
std::string _completionSignal = "";
|
||||||
|
std::atomic_bool _triggerIsComplete = {false};
|
||||||
|
bool _triggerResult = false;
|
||||||
|
int64_t _completionId = 0;
|
||||||
|
|
||||||
|
Duration _timeout = Duration(10.0);
|
||||||
|
|
||||||
|
friend class MacroSegmentScriptEdit;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroSegmentScriptEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroSegmentScriptEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroSegmentScript> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> segment);
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> segment);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void TimeoutChanged(const Duration &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static obs_properties_t *GetProperties(void *obj);
|
||||||
|
static void UpdateSettings(void *obj, obs_data_t *settings);
|
||||||
|
|
||||||
|
DurationSelection *_timeout;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroSegmentScript> _entryData;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace advss
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user