mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-07 09:05:57 -05:00
Compare commits
223 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bc59c1082 | ||
|
|
8b9f03a349 | ||
|
|
093b0f9ec0 | ||
|
|
254eabfa8d | ||
|
|
b2da8faf37 | ||
|
|
3eba20e2d8 | ||
|
|
08841aa88e | ||
|
|
2e96c226b5 | ||
|
|
c34308f743 | ||
|
|
4af07d9d55 | ||
|
|
d743260ca8 | ||
|
|
8ff50056f0 | ||
|
|
b786831f3b | ||
|
|
32e2a5f44c | ||
|
|
e3f277c32a | ||
|
|
5a7d76061c | ||
|
|
39a8c34fa6 | ||
|
|
ead51e2f13 | ||
|
|
3b465e1fdc | ||
|
|
26fd26051b | ||
|
|
08933a3683 | ||
|
|
9be00ba3ca | ||
|
|
cce15529fe | ||
|
|
588f90f0b1 | ||
|
|
d3220c40dc | ||
|
|
79c659b4fa | ||
|
|
292adb990d | ||
|
|
b7a0f6c5d0 | ||
|
|
b3f1aff03c | ||
|
|
aea9d1b319 | ||
|
|
1fd724e4f4 | ||
|
|
3d1c613f1c | ||
|
|
9ca2f4470b | ||
|
|
34527b08a9 | ||
|
|
3ae1050488 | ||
|
|
d7ec7c6e40 | ||
|
|
e98ee64974 | ||
|
|
7c6428b27e | ||
|
|
aca9b84fc6 | ||
|
|
d397f5e406 | ||
|
|
97cbcd7e61 | ||
|
|
64fd8dd50d | ||
|
|
a0dd1cf3ef | ||
|
|
25cf51abea | ||
|
|
3c8f5088d3 | ||
|
|
66f3c74cf3 | ||
|
|
6c23110fb9 | ||
|
|
c9001df97c | ||
|
|
76fa1f8942 | ||
|
|
55ca146a82 | ||
|
|
a3625242de | ||
|
|
db4214c918 | ||
|
|
f024199e2d | ||
|
|
299e7bc868 | ||
|
|
0262e066bf | ||
|
|
bee75336d0 | ||
|
|
96b472776a | ||
|
|
fb457f723a | ||
|
|
eee3e05c10 | ||
|
|
ccc147a1b3 | ||
|
|
45a149f6df | ||
|
|
076be21d40 | ||
|
|
ab5bdb32f5 | ||
|
|
8cfed048cc | ||
|
|
c842595214 | ||
|
|
8fa3e8b038 | ||
|
|
174c17edea | ||
|
|
9d8fadda80 | ||
|
|
58028d3c3d | ||
|
|
3dcabe543f | ||
|
|
1a7ebc5569 | ||
|
|
522ab2963e | ||
|
|
d9bd98ce9c | ||
|
|
2af0735a2f | ||
|
|
556943c293 | ||
|
|
e3004184c4 | ||
|
|
7b2c2e91db | ||
|
|
06ea7bf1d9 | ||
|
|
1474509cb9 | ||
|
|
87aa8d3b40 | ||
|
|
d3e8b76fa6 | ||
|
|
99c9b1a4a2 | ||
|
|
8c0aad4c96 | ||
|
|
c964ed04d3 | ||
|
|
810235e0b7 | ||
|
|
e2b3563810 | ||
|
|
76c5ec480b | ||
|
|
84e4b740a8 | ||
|
|
95409dfa26 | ||
|
|
058af0d3bb | ||
|
|
fd789b476b | ||
|
|
3fc82df278 | ||
|
|
d541356fd3 | ||
|
|
5c2adacca1 | ||
|
|
7200668158 | ||
|
|
7cf7fd6112 | ||
|
|
41821cbeb2 | ||
|
|
9537579235 | ||
|
|
40a701a934 | ||
|
|
6c8556c66c | ||
|
|
a467dffd05 | ||
|
|
497dbd89d4 | ||
|
|
0fdbce25a1 | ||
|
|
7e3e621ae5 | ||
|
|
9dfbd266fc | ||
|
|
8d02f63c36 | ||
|
|
f31c54fd72 | ||
|
|
7719087065 | ||
|
|
0b175a41d1 | ||
|
|
0824abc4f5 | ||
|
|
efef29603b | ||
|
|
034a1b0c93 | ||
|
|
86fefe1e9e | ||
|
|
0bc15b4c2d | ||
|
|
7cfa956b80 | ||
|
|
9670a01e1a | ||
|
|
371f6daf5a | ||
|
|
1c141abd06 | ||
|
|
13788c2dfa | ||
|
|
daf36365a8 | ||
|
|
cea4df90b1 | ||
|
|
80b824e0a7 | ||
|
|
0bfdc3890b | ||
|
|
cc067de021 | ||
|
|
57c0734ba6 | ||
|
|
913682e128 | ||
|
|
92711c5798 | ||
|
|
80334088d0 | ||
|
|
bdd9d12257 | ||
|
|
decee4647b | ||
|
|
4991e74a72 | ||
|
|
baa158bb33 | ||
|
|
0975ffabfa | ||
|
|
beec7d5939 | ||
|
|
1bf2a154e2 | ||
|
|
aa691cf51c | ||
|
|
8fc12bee99 | ||
|
|
5e8a0f92ee | ||
|
|
86029e8e0e | ||
|
|
a86d6f1f76 | ||
|
|
8ef798c70c | ||
|
|
efc8726054 | ||
|
|
7b72abb100 | ||
|
|
311ee5d0a0 | ||
|
|
5e4258968a | ||
|
|
ae4e861f7f | ||
|
|
d692444687 | ||
|
|
6976c98fd8 | ||
|
|
75f8d0cb07 | ||
|
|
a7e03245bd | ||
|
|
056e7ef737 | ||
|
|
675c23d7cc | ||
|
|
c4b66ef7f6 | ||
|
|
5cae1bca41 | ||
|
|
407d338b8b | ||
|
|
edd9f18de0 | ||
|
|
c9769a799d | ||
|
|
047ca93486 | ||
|
|
bd00a3f97e | ||
|
|
72f67705ed | ||
|
|
38161f63a3 | ||
|
|
b9f6e47a49 | ||
|
|
c82c56dbb7 | ||
|
|
326cc0c46f | ||
|
|
d9997d374d | ||
|
|
c18d799f4a | ||
|
|
fdb72629db | ||
|
|
7fda5e3820 | ||
|
|
78966e456a | ||
|
|
49a042039e | ||
|
|
adb266927f | ||
|
|
703f24b8fc | ||
|
|
de6120c401 | ||
|
|
b1f7a255d5 | ||
|
|
d112e92d33 | ||
|
|
5c4dd6dae1 | ||
|
|
546a83ee07 | ||
|
|
09ab29b4ba | ||
|
|
86d4e59dc2 | ||
|
|
bf03edd391 | ||
|
|
aa7714210a | ||
|
|
2454ea8fa5 | ||
|
|
a5edbc8b88 | ||
|
|
ec6cffcd6a | ||
|
|
89849a0792 | ||
|
|
48e6bcbb7a | ||
|
|
6893d9539e | ||
|
|
4a84bede37 | ||
|
|
77642c54d8 | ||
|
|
069b0f89d0 | ||
|
|
e517fa7b39 | ||
|
|
9301713c49 | ||
|
|
66285a0d3d | ||
|
|
e83a9e8d94 | ||
|
|
881e197cb2 | ||
|
|
e7f031641f | ||
|
|
198a5dc1ec | ||
|
|
5496c256c0 | ||
|
|
a93cec2bb9 | ||
|
|
32101627a6 | ||
|
|
c2d2a27d44 | ||
|
|
5eb8378612 | ||
|
|
961ea655fd | ||
|
|
c1704f2164 | ||
|
|
e4b060976b | ||
|
|
186198bfd4 | ||
|
|
283025f1a8 | ||
|
|
5b4ddfa669 | ||
|
|
572b974b82 | ||
|
|
ae71b24c60 | ||
|
|
e803ba75f9 | ||
|
|
72bd905e7c | ||
|
|
51680adc20 | ||
|
|
4b84850f00 | ||
|
|
6a998934d0 | ||
|
|
b80c16a446 | ||
|
|
f4d11dd6e6 | ||
|
|
4248b86705 | ||
|
|
305ce96ad0 | ||
|
|
74dfd9af30 | ||
|
|
c911862d8c | ||
|
|
2a73583793 | ||
|
|
8f16d05a28 |
49
.github/workflows/build-debian.yml
vendored
Normal file
49
.github/workflows/build-debian.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: debian-build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: 'recursive'
|
||||||
|
- name: check_libobs_revision
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install libobs-dev
|
||||||
|
mkdir source
|
||||||
|
cd source
|
||||||
|
dpkg -l libobs-dev | tr -s " "| grep libobs | cut -d" " -f3 > libobs.rev
|
||||||
|
- name: install_frontend_header
|
||||||
|
run: |
|
||||||
|
[ -e /usr/include/obs/obs-frontend-api.h ] && { echo "ERROR: obs-frontend-api.h already in system. Maybe the package libobs-dev is installing it."; exit 1; }
|
||||||
|
cd source
|
||||||
|
LIBOBSREV=$(cat libobs.rev)
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install devscripts
|
||||||
|
dget -u http://archive.ubuntu.com/ubuntu/pool/universe/o/obs-studio/obs-studio_$LIBOBSREV.dsc
|
||||||
|
cd ..
|
||||||
|
sudo find -name obs-frontend-api.h -exec cp {} /usr/include/obs/ \;
|
||||||
|
egrep '#include <obs.h>' /usr/include/obs/obs-frontend-api.h || { echo "ERROR: check if the sed commands are needed from now."; exit 1; }
|
||||||
|
sudo sed -i 's/#include <obs.h>/#include <obs\/obs.h>/' /usr/include/obs/obs-frontend-api.h
|
||||||
|
sudo sed -i 's/#include <util\/darray.h>/#include <obs\/util\/darray.h>/' /usr/include/obs/obs-frontend-api.h
|
||||||
|
- name: create_tarball
|
||||||
|
run: |
|
||||||
|
cd ..
|
||||||
|
tar --exclude=.git -cvzf obs-scene-switcher_0.1+testonly.orig.tar.gz SceneSwitcher
|
||||||
|
- name: create_debian_dir
|
||||||
|
run: |
|
||||||
|
cp -a CI/linux/debian .
|
||||||
|
- name: install_dependencies
|
||||||
|
run: |
|
||||||
|
# devscripts and libobs-dev are needed but they were already installed
|
||||||
|
# from check_libobs_revision and install_frontend_header sections.
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install cmake debhelper libcurl4-openssl-dev libxss-dev libxtst-dev qtbase5-dev libopencv-dev
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
debuild --no-lintian --no-sign
|
||||||
116
.github/workflows/build.yml
vendored
116
.github/workflows/build.yml
vendored
@@ -9,6 +9,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
PLUGIN_NAME: SceneSwitcher
|
PLUGIN_NAME: SceneSwitcher
|
||||||
LIB_NAME: advanced-scene-switcher
|
LIB_NAME: advanced-scene-switcher
|
||||||
|
OBS_TAG: 27.1.1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
macos64:
|
macos64:
|
||||||
@@ -23,6 +24,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repository: obsproject/obs-studio
|
repository: obsproject/obs-studio
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
ref: 'refs/tags/${{ env.OBS_TAG }}'
|
||||||
- name: "Checkout plugin"
|
- name: "Checkout plugin"
|
||||||
uses: actions/checkout@v2.3.4
|
uses: actions/checkout@v2.3.4
|
||||||
with:
|
with:
|
||||||
@@ -57,6 +59,15 @@ jobs:
|
|||||||
curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/macos-qt-${{ env.QT_VERSION }}-${{ env.MACOS_DEPS_VERSION }}.tar.gz
|
curl -L -O https://github.com/obsproject/obs-deps/releases/download/${{ env.MACOS_DEPS_VERSION }}/macos-qt-${{ env.QT_VERSION }}-${{ env.MACOS_DEPS_VERSION }}.tar.gz
|
||||||
tar -xf ./macos-qt-${{ env.QT_VERSION }}-${{ env.MACOS_DEPS_VERSION }}.tar.gz -C "/tmp"
|
tar -xf ./macos-qt-${{ env.QT_VERSION }}-${{ env.MACOS_DEPS_VERSION }}.tar.gz -C "/tmp"
|
||||||
xattr -r -d com.apple.quarantine /tmp/obsdeps
|
xattr -r -d com.apple.quarantine /tmp/obsdeps
|
||||||
|
- name: 'Build prerequisite: OpenCV'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}/deps/opencv
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DBUILD_LIST="core,imgproc,objdetect" ..
|
||||||
|
make -j4
|
||||||
|
make install
|
||||||
- name: Configure
|
- name: Configure
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -104,13 +115,14 @@ jobs:
|
|||||||
path: ./nightly/*.pkg
|
path: ./nightly/*.pkg
|
||||||
ubuntu64:
|
ubuntu64:
|
||||||
name: 'Linux/Ubuntu 64-bit'
|
name: 'Linux/Ubuntu 64-bit'
|
||||||
runs-on: [ubuntu-18.04]
|
runs-on: [ubuntu-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2.3.4
|
uses: actions/checkout@v2.3.4
|
||||||
with:
|
with:
|
||||||
repository: obsproject/obs-studio
|
repository: obsproject/obs-studio
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
ref: 'refs/tags/${{ env.OBS_TAG }}'
|
||||||
- name: "Checkout plugin"
|
- name: "Checkout plugin"
|
||||||
uses: actions/checkout@v2.3.4
|
uses: actions/checkout@v2.3.4
|
||||||
with:
|
with:
|
||||||
@@ -160,6 +172,7 @@ jobs:
|
|||||||
libxcb-xinerama0-dev \
|
libxcb-xinerama0-dev \
|
||||||
libxcomposite-dev \
|
libxcomposite-dev \
|
||||||
libxinerama-dev \
|
libxinerama-dev \
|
||||||
|
libxtst-dev \
|
||||||
libmbedtls-dev \
|
libmbedtls-dev \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
python3-dev \
|
python3-dev \
|
||||||
@@ -167,7 +180,10 @@ jobs:
|
|||||||
qtbase5-private-dev \
|
qtbase5-private-dev \
|
||||||
libqt5svg5-dev \
|
libqt5svg5-dev \
|
||||||
swig \
|
swig \
|
||||||
libxss-dev
|
libxss-dev \
|
||||||
|
libx11-xcb-dev \
|
||||||
|
libxcb-xfixes0-dev \
|
||||||
|
libopencv-dev
|
||||||
- name: 'Configure'
|
- name: 'Configure'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -185,6 +201,7 @@ jobs:
|
|||||||
FILE_NAME=${{ env.PLUGIN_NAME }}-$FILE_DATE-${{ github.sha }}-linux64.tar.gz
|
FILE_NAME=${{ env.PLUGIN_NAME }}-$FILE_DATE-${{ github.sha }}-linux64.tar.gz
|
||||||
echo "FILE_NAME=${FILE_NAME}" >> $GITHUB_ENV
|
echo "FILE_NAME=${FILE_NAME}" >> $GITHUB_ENV
|
||||||
mkdir -p ./${{ env.LIB_NAME }}/bin/64bit/
|
mkdir -p ./${{ env.LIB_NAME }}/bin/64bit/
|
||||||
|
strip -d ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.LIB_NAME }}.so
|
||||||
mv ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.LIB_NAME }}.so ./${{ env.LIB_NAME }}/bin/64bit/${{ env.LIB_NAME }}.so
|
mv ./build/UI/frontend-plugins/${{ env.PLUGIN_NAME }}/${{ env.LIB_NAME }}.so ./${{ env.LIB_NAME }}/bin/64bit/${{ env.LIB_NAME }}.so
|
||||||
mv ./UI/frontend-plugins/${{ env.PLUGIN_NAME }}/data ./${{ env.LIB_NAME }}/data
|
mv ./UI/frontend-plugins/${{ env.PLUGIN_NAME }}/data ./${{ env.LIB_NAME }}/data
|
||||||
tar -cvzf "${FILE_NAME}" ${{ env.LIB_NAME }}
|
tar -cvzf "${FILE_NAME}" ${{ env.LIB_NAME }}
|
||||||
@@ -196,11 +213,14 @@ jobs:
|
|||||||
windows:
|
windows:
|
||||||
name: Windows
|
name: Windows
|
||||||
runs-on: [windows-latest]
|
runs-on: [windows-latest]
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: [32, 64]
|
||||||
env:
|
env:
|
||||||
QT_VERSION: 5.10.1
|
QT_VERSION: 5.10.1
|
||||||
CMAKE_GENERATOR: "Visual Studio 16 2019"
|
CMAKE_GENERATOR: "Visual Studio 16 2019"
|
||||||
CMAKE_SYSTEM_VERSION: "10.0.18363.657"
|
CMAKE_SYSTEM_VERSION: "10.0.18363.657"
|
||||||
WINDOWS_DEPS_VERSION: '2017'
|
WINDOWS_DEPS_VERSION: '2019'
|
||||||
steps:
|
steps:
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v1.0.2
|
||||||
@@ -209,6 +229,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
repository: obsproject/obs-studio
|
repository: obsproject/obs-studio
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
ref: 'refs/tags/${{ env.OBS_TAG }}'
|
||||||
- name: Checkout plugin
|
- name: Checkout plugin
|
||||||
uses: actions/checkout@v2.3.4
|
uses: actions/checkout@v2.3.4
|
||||||
with:
|
with:
|
||||||
@@ -227,53 +248,97 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -f --retry 5 -C -
|
curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -f --retry 5 -C -
|
||||||
7z x dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -o"${{ github.workspace }}/cmbuild/deps"
|
7z x dependencies${{ env.WINDOWS_DEPS_VERSION }}.zip -o"${{ github.workspace }}/cmbuild/deps"
|
||||||
|
- name: 'Build prerequisite: OpenCV'
|
||||||
|
run: |
|
||||||
|
cd UI/frontend-plugins/${{ env.PLUGIN_NAME }}/deps/opencv
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
if ( ${{ matrix.arch }} -eq 32 )
|
||||||
|
{
|
||||||
|
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"Win32" -DBUILD_LIST="core,imgproc,objdetect" ..
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"x64" -DBUILD_LIST="core,imgproc,objdetect" ..
|
||||||
|
}
|
||||||
|
msbuild /m /p:Configuration=Release OpenCV.sln
|
||||||
|
msbuild INSTALL.vcxproj
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: |
|
run: |
|
||||||
mkdir ./package
|
mkdir ./package
|
||||||
mkdir ./build32
|
mkdir ./build${{ matrix.arch }}
|
||||||
cd ./build32
|
cd ./build${{ matrix.arch }}
|
||||||
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"Win32" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win32" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2017" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
|
Get-Location
|
||||||
cd ..
|
if ( ${{ matrix.arch }} -eq 32 )
|
||||||
mkdir ./build64
|
{
|
||||||
cd ./build64
|
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"Win32" -DOpenCV_DIR="${{ github.workspace }}/UI/frontend-plugins/SceneSwitcher/deps/opencv/build/" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win32" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2017" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
|
||||||
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"x64" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win64" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2017_64" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmake -G"${{ env.CMAKE_GENERATOR }}" -A"x64" -DOpenCV_DIR="${{ github.workspace }}/UI/frontend-plugins/SceneSwitcher/deps/opencv/build/" -DCMAKE_SYSTEM_VERSION="${{ env.CMAKE_SYSTEM_VERSION }}" -DBUILD_BROWSER=false -DBUILD_CAPTIONS=false -DCOMPILE_D3D12_HOOK=false -DDepsPath="${{ github.workspace }}/cmbuild/deps/win64" -DQTDIR="${{ github.workspace }}/cmbuild/QT/${{ env.QT_VERSION }}/msvc2017_64" -DCOPIED_DEPENDENCIES=FALSE -DCOPY_DEPENDENCIES=TRUE ..
|
||||||
|
}
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
msbuild /m /p:Configuration=RelWithDebInfo .\build32\obs-studio.sln
|
msbuild /m /p:Configuration=RelWithDebInfo .\build${{ matrix.arch }}\obs-studio.sln
|
||||||
msbuild /m /p:Configuration=RelWithDebInfo .\build64\obs-studio.sln
|
|
||||||
- name: Package
|
- name: Package
|
||||||
if: success()
|
if: success()
|
||||||
run: |
|
run: |
|
||||||
$env:FILE_DATE=(Get-Date -UFormat "%F")
|
$env:FILE_DATE=(Get-Date -UFormat "%F")
|
||||||
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-windows"
|
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-windows"
|
||||||
echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV}
|
echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV}
|
||||||
robocopy .\build32\rundir\RelWithDebInfo\obs-plugins\32bit\ .\package\obs-plugins\32bit ${{ env.LIB_NAME }}.* /E /XF .gitignore
|
robocopy .\build${{ matrix.arch }}\rundir\RelWithDebInfo\obs-plugins\${{ matrix.arch }}bit\ .\package\obs-plugins\${{ matrix.arch }}bit ${{ env.LIB_NAME }}.* /E /XF .gitignore
|
||||||
robocopy .\build64\rundir\RelWithDebInfo\obs-plugins\64bit\ .\package\obs-plugins\64bit ${{ env.LIB_NAME }}.* /E /XF .gitignore
|
robocopy .\build${{ matrix.arch }}\rundir\RelWithDebInfo\data\obs-plugins\${{ env.LIB_NAME }}\ .\package\data\obs-plugins\${{ env.LIB_NAME }}\ /E /XF .gitignore
|
||||||
robocopy .\build64\rundir\RelWithDebInfo\data\obs-plugins\${{ env.LIB_NAME }}\ .\package\data\obs-plugins\${{ env.LIB_NAME }}\ /E /XF .gitignore
|
cp UI/frontend-plugins/${{ env.PLUGIN_NAME }}/deps/opencv/build/bin/Release/*dll package/obs-plugins/${{ matrix.arch }}bit
|
||||||
exit 0
|
exit 0
|
||||||
- name: Publish zip
|
- name: Publish zip
|
||||||
if: success()
|
if: success()
|
||||||
uses: actions/upload-artifact@v2.2.1
|
uses: actions/upload-artifact@v2.2.1
|
||||||
with:
|
with:
|
||||||
name: '${{ env.FILE_NAME }}'
|
name: '${{ env.FILE_NAME }}-${{ matrix.arch }}bit'
|
||||||
path: package/*
|
path: package/*
|
||||||
- name: "Package Installer (Prereqs)"
|
windows-installer:
|
||||||
|
needs: [windows]
|
||||||
|
name: 'Create Windows Installer'
|
||||||
|
runs-on: [windows-latest]
|
||||||
|
steps:
|
||||||
|
- name: "Checkout plugin"
|
||||||
|
uses: actions/checkout@v2.3.4
|
||||||
|
- name: Add msbuild to PATH
|
||||||
|
uses: microsoft/setup-msbuild@v1.0.2
|
||||||
|
- name: "Prepare innosetup"
|
||||||
|
run: |
|
||||||
|
curl "-kL" "https://files.jrsoftware.org/is/6/innosetup-6.0.3.exe" "-f" "--retry" "5" "-o" "inno.exe"
|
||||||
|
.\inno.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
continue-on-error: true
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
path: artifacts
|
||||||
|
- name: "Prepare package dir"
|
||||||
run: |
|
run: |
|
||||||
curl "-kL" "https://github.com/Xaymar/msvc-redist-helper/releases/download/0.1/msvc-redist-helper-64.exe" "-f" "--retry" "5" "-o" "msvc-redist-helper-64.exe"
|
curl "-kL" "https://github.com/Xaymar/msvc-redist-helper/releases/download/0.1/msvc-redist-helper-64.exe" "-f" "--retry" "5" "-o" "msvc-redist-helper-64.exe"
|
||||||
curl "-kL" "https://github.com/Xaymar/msvc-redist-helper/releases/download/0.1/msvc-redist-helper-32.exe" "-f" "--retry" "5" "-o" "msvc-redist-helper-32.exe"
|
curl "-kL" "https://github.com/Xaymar/msvc-redist-helper/releases/download/0.1/msvc-redist-helper-32.exe" "-f" "--retry" "5" "-o" "msvc-redist-helper-32.exe"
|
||||||
curl "-kL" "https://files.jrsoftware.org/is/6/innosetup-6.0.3.exe" "-f" "--retry" "5" "-o" "inno.exe"
|
$env:FILE_DATE=(Get-Date -UFormat "%F")
|
||||||
.\inno.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART
|
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-windows"
|
||||||
- name: "Package Installer (Compile)"
|
echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV}
|
||||||
|
mkdir package
|
||||||
|
cd package
|
||||||
|
cp -r ../artifacts/${env:FILE_NAME}-32bit/* .
|
||||||
|
cp -r ../artifacts/${env:FILE_NAME}-64bit/obs-plugins/* obs-plugins
|
||||||
|
- name: "Compile"
|
||||||
run: |
|
run: |
|
||||||
& 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe' /Qp ".\build64\UI\frontend-plugins\${{ env.PLUGIN_NAME }}\CI\windows\setup.iss"
|
& 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe' /Qp ".\build\CI\windows\setup.iss"
|
||||||
- name: Publish installer
|
- name: "Publish"
|
||||||
if: success()
|
if: success()
|
||||||
uses: actions/upload-artifact@v2.2.0
|
uses: actions/upload-artifact@v2.2.0
|
||||||
with:
|
with:
|
||||||
name: '${{ env.FILE_NAME }}-installer'
|
name: '${{ env.FILE_NAME }}-installer'
|
||||||
path: build64/UI/frontend-plugins/SceneSwitcher/CI/windows/Output/*.exe
|
path: build/CI/windows/Output/*.exe
|
||||||
release:
|
release:
|
||||||
needs: [macos64, ubuntu64, windows]
|
needs: [macos64, ubuntu64, windows, windows-installer]
|
||||||
name: 'Create Release'
|
name: 'Create Release'
|
||||||
runs-on: [ubuntu-18.04]
|
runs-on: [ubuntu-18.04]
|
||||||
steps:
|
steps:
|
||||||
@@ -291,7 +356,8 @@ jobs:
|
|||||||
mkdir -p ${{ env.PLUGIN_NAME }}/Linux ${{ env.PLUGIN_NAME }}/MacOs ${{ env.PLUGIN_NAME }}/Windows
|
mkdir -p ${{ env.PLUGIN_NAME }}/Linux ${{ env.PLUGIN_NAME }}/MacOs ${{ env.PLUGIN_NAME }}/Windows
|
||||||
tar xf artifacts/${{ env.PLUGIN_NAME }}*-linux64.tar.gz/${{ env.PLUGIN_NAME }}*-linux64.tar.gz -C ${{ env.PLUGIN_NAME }}/Linux/
|
tar xf artifacts/${{ env.PLUGIN_NAME }}*-linux64.tar.gz/${{ env.PLUGIN_NAME }}*-linux64.tar.gz -C ${{ env.PLUGIN_NAME }}/Linux/
|
||||||
mv artifacts/${{ env.PLUGIN_NAME }}*-macos.pkg/${{ env.PLUGIN_NAME }}*-macos.pkg ${{ env.PLUGIN_NAME }}/MacOs/${{ env.PLUGIN_NAME }}.pkg
|
mv artifacts/${{ env.PLUGIN_NAME }}*-macos.pkg/${{ env.PLUGIN_NAME }}*-macos.pkg ${{ env.PLUGIN_NAME }}/MacOs/${{ env.PLUGIN_NAME }}.pkg
|
||||||
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows/* ${{ env.PLUGIN_NAME }}/Windows/
|
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows-32bit/* ${{ env.PLUGIN_NAME }}/Windows/
|
||||||
|
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows-64bit/obs-plugins/* ${{ env.PLUGIN_NAME }}/Windows/obs-plugins
|
||||||
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows-installer/*.exe ${{ env.PLUGIN_NAME }}/Windows/
|
mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows-installer/*.exe ${{ env.PLUGIN_NAME }}/Windows/
|
||||||
rm ${{ env.PLUGIN_NAME }}/Windows/obs-plugins/32bit/advanced-scene-switcher.pdb
|
rm ${{ env.PLUGIN_NAME }}/Windows/obs-plugins/32bit/advanced-scene-switcher.pdb
|
||||||
rm ${{ env.PLUGIN_NAME }}/Windows/obs-plugins/64bit/advanced-scene-switcher.pdb
|
rm ${{ env.PLUGIN_NAME }}/Windows/obs-plugins/64bit/advanced-scene-switcher.pdb
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
|||||||
[submodule "deps/websocketpp"]
|
[submodule "deps/websocketpp"]
|
||||||
path = deps/websocketpp
|
path = deps/websocketpp
|
||||||
url = https://github.com/zaphoyd/websocketpp.git
|
url = https://github.com/zaphoyd/websocketpp.git
|
||||||
|
[submodule "deps/opencv"]
|
||||||
|
path = deps/opencv
|
||||||
|
url = https://github.com/opencv/opencv.git
|
||||||
|
|||||||
152
BUILDING.md
Normal file
152
BUILDING.md
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
# Compiling the plugin
|
||||||
|
|
||||||
|
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**)
|
||||||
|
- 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/install-instructions), [Qt](https://download.qt.io/official_releases/qt/5.15/5.15.2/) 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.
|
||||||
|
|
||||||
|
Note that your Qt install must include the QtConcurrent module.
|
||||||
|
|
||||||
|
## Compiling in tree (recommended)
|
||||||
|
Add the "SceneSwitcher" source directory to your obs-studio source directory under obs-studio/UI/frontend-plugins/:
|
||||||
|
```
|
||||||
|
cd obs-studio/UI/frontend-plugins/
|
||||||
|
git clone --recursive https://github.com/WarmUpTill/SceneSwitcher.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Then modify the obs-studio/UI/frontend-plugins/CMakeLists.txt file and add an entry for the scene switcher:
|
||||||
|
```
|
||||||
|
add_subdirectory(SceneSwitcher)
|
||||||
|
```
|
||||||
|
|
||||||
|
Now follow the [build instructions for obs-studio](https://obsproject.com/wiki/install-instructions) for your particular platform.
|
||||||
|
|
||||||
|
Note that on Linux systems it might be necessary to additionally install the following packages to fulfill the dependencies to `XTest`, `XScreensaver` and `OpenCV` - exact command may differ:
|
||||||
|
```
|
||||||
|
sudo apt-get install \
|
||||||
|
libxtst-dev \
|
||||||
|
libxss-dev \
|
||||||
|
libopencv-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Compiling out of tree
|
||||||
|
### Prerequisites
|
||||||
|
You'll need [Qt](https://download.qt.io/official_releases/qt/5.15/5.15.2/), [CMake](https://cmake.org/download/) and a working [OBS Studio development environment](https://obsproject.com/wiki/install-instructions) installed on your computer.
|
||||||
|
Once you've set this up, do the following:
|
||||||
|
```
|
||||||
|
git clone --recursive https://github.com/WarmUpTill/SceneSwitcher.git
|
||||||
|
cd SceneSwitcher
|
||||||
|
mkdir build && cd build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
In cmake-gui, you'll have to set these CMake variables :
|
||||||
|
- **BUILD_OUT_OF_TREE** (bool) : true
|
||||||
|
|
||||||
|
- **LIBOBS_LIB** (filepath) : location of the obs.lib file
|
||||||
|
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
|
||||||
|
code of OBS Studio, located at [source_directory]/libobs/.
|
||||||
|
|
||||||
|
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the obs-frontend-api.lib file
|
||||||
|
(usually in the same place as LIBOBS_LIB)
|
||||||
|
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api
|
||||||
|
subfolder in the source code of OBS Studio, located at [source_directory]/UI/obs-frontend-api.
|
||||||
|
|
||||||
|
- **CURL_LIBRARY** (filepath) : location of the libcurl.lib file
|
||||||
|
(part of the dependencies2019/win64/bin folder used to build OBS)
|
||||||
|
- **CURL_INCLUDE_DIR** (path) : location of the curl
|
||||||
|
subfolder in OBS dependencies folder: ".../dependencies2019/win64/include/"
|
||||||
|
|
||||||
|
|
||||||
|
Assuming that you set up Qt via QT installer:
|
||||||
|
- **Qt5Core_DIR** (path) : C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Core
|
||||||
|
- **Qt5Gui_DIR** (path): C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Gui
|
||||||
|
- **Qt5Widgets_DIR** (path) : C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5Widgets
|
||||||
|
|
||||||
|
Just keep hitting configure until all the vars are filled out. Then hit generate.
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
Install dependencies `XTest`, `XScreensaver` and `OpenCV` - exact command may differ:
|
||||||
|
```
|
||||||
|
sudo apt-get install \
|
||||||
|
libxtst-dev \
|
||||||
|
libxss-dev \
|
||||||
|
libopencv-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Most versions of Linux you can use cmake-gui or the command line.
|
||||||
|
|
||||||
|
**For the command line:**
|
||||||
|
```
|
||||||
|
# [...] are placeholders
|
||||||
|
cmake -DBUILD_OUT_OF_TREE=1 \
|
||||||
|
-DLIBOBS_INCLUDE_DIR=[...]/obs-studio/libobs/ \
|
||||||
|
-DLIBOBS_LIB=[...]/libobs.so \
|
||||||
|
-DLIBOBS_FRONTEND_INCLUDE_DIR=[...]/obs-studio/UI/obs-frontend-api/ \
|
||||||
|
-DLIBOBS_FRONTEND_API_LIB=[...]/libobs-frontend-api.so \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/usr ..
|
||||||
|
make -j4
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
For cmake-gui you'll have to set the following variables:
|
||||||
|
- **BUILD_OUT_OF_TREE** (bool) : true
|
||||||
|
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
|
||||||
|
code of OBS Studio, located at [source_directory]/libobs/.
|
||||||
|
- **LIBOBS_LIB** (filepath) : location of the libobs.so file (usually CMake finds
|
||||||
|
this, but if not it'll usually be in /usr/lib/libobs.so)
|
||||||
|
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the libobs-frontend-api.so
|
||||||
|
file (usually in the same place as LIBOBS_LIB)
|
||||||
|
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api
|
||||||
|
subfolder in the source code of OBS Studio, located at
|
||||||
|
[source_directory]/UI/obs-frontend-api.
|
||||||
|
|
||||||
|
Assuming that you installed Qt via your system package manager, it should be
|
||||||
|
found automatically. If not, then usually you'll find it in something like:
|
||||||
|
- **Qt5Core_DIR** (path) : /usr/lib64/cmake/Qt5Core
|
||||||
|
- **Qt5Gui_DIR** (path): /usr/lib64/cmake/Qt5Gui
|
||||||
|
- **Qt5Widgets_DIR** (path) : /usr/lib64/cmake/Qt5Widgets
|
||||||
|
|
||||||
|
Just keep hitting configure until all the vars are filled out. Then hit generate.
|
||||||
|
|
||||||
|
Then open a terminal in the build folder and type:
|
||||||
|
```
|
||||||
|
make -j4
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
NOTE: The Linux version of this plugin is dependent on libXScrnSaver, libcurl and libXtst.
|
||||||
|
|
||||||
|
### OS X
|
||||||
|
In cmake-gui, you'll have to set these CMake variables :
|
||||||
|
- **BUILD_OUT_OF_TREE** (bool) : true
|
||||||
|
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
|
||||||
|
code of OBS Studio, located at [source_directory]/libobs/.
|
||||||
|
- **LIBOBS_LIB** (filepath) : location of the libobs.0.dylib file (usually
|
||||||
|
in /Applications/OBS.app/Contents/Resources/bin/libobs.0.dylib)
|
||||||
|
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the libobs-frontend-api.0.dylib
|
||||||
|
file (usually in usually in /Applications/OBS.app/Contents/Resources/bin/libobs-frontend-api.0.dylib)
|
||||||
|
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api subfolder
|
||||||
|
in the source code of OBS Studio, located at [source_directory]/UI/obs-frontend-api.
|
||||||
|
|
||||||
|
Assuming that you installed Qt via the regular Qt App way:
|
||||||
|
- **Qt5Core_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5Core
|
||||||
|
- **Qt5Widgets_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5Widgets
|
||||||
|
- **Qt5MacExtras_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5MacExtras
|
||||||
|
|
||||||
|
|
||||||
|
Just keep hitting configure until all the vars are filled out. Then hit generate.
|
||||||
|
|
||||||
|
Open xcode (or a terminal, depending on the build type you chose), build and copy
|
||||||
|
the advanced-scene-switcher.so file to 'Library/Application Support/obs-studio/plugins/advanced-scene-switcher/bin/'
|
||||||
|
And the 'data' folder to 'Library/Application Support/obs-studio/plugins/advanced-scene-switcher/'.
|
||||||
|
|
||||||
|
Note that you might have to adjust the library search paths using the install_name_tool if you want the plugin to run on machines other than your build machine:
|
||||||
|
```
|
||||||
|
install_name_tool -change @rpath/libobs-frontend-api.dylib @executable_path/../Frameworks/libobs-frontend-api.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
||||||
|
install_name_tool -change @rpath/libobs.0.dylib @executable_path/../Frameworks/libobs.0.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
||||||
|
install_name_tool -change /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
||||||
|
install_name_tool -change /usr/local/opt/qt5/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
||||||
|
install_name_tool -change /usr/local/opt/qt5/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
||||||
|
```
|
||||||
5
CI/linux/debian/changelog
Normal file
5
CI/linux/debian/changelog
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
obs-scene-switcher (0.1+testonly) focal; urgency=medium
|
||||||
|
|
||||||
|
* Initial release (Closes: #123456)
|
||||||
|
|
||||||
|
-- Joao Eriberto Mota Filho <eriberto@debian.org> Fri, 03 Sep 2021 11:39:52 -0300
|
||||||
22
CI/linux/debian/control
Normal file
22
CI/linux/debian/control
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Source: obs-scene-switcher
|
||||||
|
Section: video
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Joao Eriberto Mota Filho <eriberto@debian.org>
|
||||||
|
Build-Depends: cmake,
|
||||||
|
debhelper-compat (= 12),
|
||||||
|
libcurl4-openssl-dev,
|
||||||
|
libobs-dev,
|
||||||
|
libxtst-dev,
|
||||||
|
qtbase5-dev,
|
||||||
|
libxss-dev,
|
||||||
|
libopencv-dev
|
||||||
|
Standards-Version: 4.6.0
|
||||||
|
Homepage: https://obsproject.com/forum/resources/advanced-scene-switcher.395/
|
||||||
|
Rules-Requires-Root: no
|
||||||
|
|
||||||
|
Package: obs-scene-switcher
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Description: automated scene switcher for OBS Studio (plugin)
|
||||||
|
Advanced Scene Switcher is based on the built in scene switcher. It extends
|
||||||
|
its functionality by adding several features.
|
||||||
60
CI/linux/debian/copyright
Normal file
60
CI/linux/debian/copyright
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: SceneSwitcher
|
||||||
|
Upstream-Contact: https://github.com/WarmUpTill/SceneSwitcher/issues
|
||||||
|
Source: https://github.com/WarmUpTill/SceneSwitcher
|
||||||
|
|
||||||
|
Files: *
|
||||||
|
Copyright: 2016-2021 WarmUpTill <WarmUpTill@web.de>
|
||||||
|
License: GPL-2
|
||||||
|
|
||||||
|
Files: cmake/GetGitRevisionDescription.cmake
|
||||||
|
cmake/GetGitRevisionDescription.cmake.in
|
||||||
|
Copyright: 2009-2013 Iowa State University
|
||||||
|
2013-2020 Contributors
|
||||||
|
2013-2020 Ryan Pavlik
|
||||||
|
License: BSL-1.0
|
||||||
|
|
||||||
|
Files: debian/*
|
||||||
|
Copyright: 2021 Joao Eriberto Mota Filho <eriberto@debian.org>
|
||||||
|
License: BSL-1.0
|
||||||
|
|
||||||
|
License: GPL-2
|
||||||
|
This package is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2.
|
||||||
|
.
|
||||||
|
This package is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
|
.
|
||||||
|
On Debian systems, the complete text of the GNU General
|
||||||
|
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||||
|
|
||||||
|
License: BSL-1.0
|
||||||
|
Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
.
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
.
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
16
CI/linux/debian/rules
Normal file
16
CI/linux/debian/rules
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
#export DH_VERBOSE = 1
|
||||||
|
|
||||||
|
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||||
|
|
||||||
|
export QT_SELECT = qt5
|
||||||
|
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
||||||
|
|
||||||
|
dh_auto_configure -- -DBUILD_OUT_OF_TREE=1 \
|
||||||
|
-DLIBOBS_INCLUDE_DIR=/usr/include/obs \
|
||||||
|
-DLIBOBS_LIB=/usr/lib/${DEB_TARGET_MULTIARCH}/libobs.so \
|
||||||
|
-DLIBOBS_FRONTEND_INCLUDE_DIR=/usr/include/obs \
|
||||||
|
-DLIBOBS_FRONTEND_API_LIB=/usr/lib/${DEB_TARGET_MULTIARCH}/libobs-frontend-api.so
|
||||||
1
CI/linux/debian/source/format
Normal file
1
CI/linux/debian/source/format
Normal file
@@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
||||||
@@ -46,6 +46,294 @@
|
|||||||
<key>UID</key>
|
<key>UID</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_objdetect.4.5.3.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_features2d.4.5.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_core.4.5.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_calib3d.4.5.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_calib3d.4.5.3.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_imgproc.4.5.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_features2d.4.5.3.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_core.4.5.3.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_flann.4.5.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_calib3d.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_objdetect.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_imgproc.4.5.3.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_flann.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_imgproc.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_flann.4.5.3.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_features2d.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_core.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CHILDREN</key>
|
||||||
|
<array/>
|
||||||
|
<key>GID</key>
|
||||||
|
<integer>80</integer>
|
||||||
|
<key>PATH</key>
|
||||||
|
<string>../../deps/opencv/build/lib/libopencv_objdetect.4.5.dylib</string>
|
||||||
|
<key>PATH_TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>PERMISSIONS</key>
|
||||||
|
<integer>493</integer>
|
||||||
|
<key>TYPE</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
<key>UID</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>GID</key>
|
<key>GID</key>
|
||||||
<integer>80</integer>
|
<integer>80</integer>
|
||||||
|
|||||||
619
CMakeLists.txt
619
CMakeLists.txt
@@ -1,270 +1,411 @@
|
|||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
|
||||||
project(advanced-scene-switcher)
|
project(advanced-scene-switcher)
|
||||||
add_definitions(-DASIO_STANDALONE)
|
|
||||||
|
|
||||||
# generate version info
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE RELWITHDEBINFO)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compiler settings
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC
|
||||||
|
OR CMAKE_COMPILER_IS_GNUCXX
|
||||||
|
OR CMAKE_COMPILER_IS_CLANG)
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"-Wall -Wextra -Wvla -Wno-unused-function -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS} -fno-strict-aliasing"
|
||||||
|
)
|
||||||
|
set(CMAKE_C_FLAGS
|
||||||
|
"-Wall -Wextra -Wvla -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-braces -Wno-missing-field-initializers ${CMAKE_C_FLAGS} -std=gnu99 -fno-strict-aliasing"
|
||||||
|
)
|
||||||
|
|
||||||
|
option(USE_LIBC++ "Use libc++ instead of libstdc++" ${APPLE})
|
||||||
|
if(USE_LIBC++)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
|
endif()
|
||||||
|
elseif(MSVC)
|
||||||
|
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||||
|
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Disable pointless constant condition warnings
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} /wd4127 /wd4201 /wd4456 /wd4457 /wd4458 /wd4459 /wd4595"
|
||||||
|
)
|
||||||
|
add_definitions(-DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS
|
||||||
|
-D_CRT_NONSTDC_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Generate version info
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp" @ONLY)
|
git_describe(GIT_TAG)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cpp.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp" @ONLY)
|
||||||
|
|
||||||
|
# Windows installer
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
get_filename_component(ISS_PLUGIN_FILES_DIR "${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE)
|
get_filename_component(ISS_PLUGIN_FILES_DIR
|
||||||
file(TO_NATIVE_PATH "${ISS_PLUGIN_FILES_DIR}" ISS_PLUGIN_FILES_DIR)
|
"${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE)
|
||||||
get_filename_component(ISS_MSVC_REDIST_HELPER_DIR "${CMAKE_PACKAGE_PREFIX}\\.." ABSOLUTE)
|
file(TO_NATIVE_PATH "${ISS_PLUGIN_FILES_DIR}" ISS_PLUGIN_FILES_DIR)
|
||||||
file(TO_NATIVE_PATH "${ISS_MSVC_REDIST_HELPER_DIR}" ISS_MSVC_REDIST_HELPER_DIR)
|
get_filename_component(ISS_MSVC_REDIST_HELPER_DIR "${CMAKE_BINARY_DIR}\\.."
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CI/windows/setup.iss.in" "${CMAKE_CURRENT_BINARY_DIR}/CI/windows/setup.iss" @ONLY)
|
ABSOLUTE)
|
||||||
endif()
|
file(TO_NATIVE_PATH "${ISS_MSVC_REDIST_HELPER_DIR}"
|
||||||
|
ISS_MSVC_REDIST_HELPER_DIR)
|
||||||
if(WIN32)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CI/windows/setup.iss.in"
|
||||||
get_filename_component(ISS_PLUGIN_FILES_DIR "${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE)
|
"${CMAKE_CURRENT_BINARY_DIR}/CI/windows/setup.iss" @ONLY)
|
||||||
file(TO_NATIVE_PATH "${ISS_PLUGIN_FILES_DIR}" ISS_PLUGIN_FILES_DIR)
|
|
||||||
get_filename_component(ISS_MSVC_REDIST_HELPER_DIR "${CMAKE_PACKAGE_PREFIX}\\.." ABSOLUTE)
|
|
||||||
file(TO_NATIVE_PATH "${ISS_MSVC_REDIST_HELPER_DIR}" ISS_MSVC_REDIST_HELPER_DIR)
|
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CI/windows/setup.iss.in" "${CMAKE_CURRENT_BINARY_DIR}/CI/windows/setup.iss" @ONLY)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Out of tree specific settings
|
||||||
if(BUILD_OUT_OF_TREE)
|
if(BUILD_OUT_OF_TREE)
|
||||||
set(CMAKE_PREFIX_PATH "${QTDIR}")
|
set(CMAKE_PREFIX_PATH "${QTDIR}")
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external")
|
find_package(Qt5Core REQUIRED)
|
||||||
|
find_package(Qt5Widgets REQUIRED)
|
||||||
|
find_package(LibObs)
|
||||||
|
find_package(LibObs-frontend-api)
|
||||||
|
if(LibObs_FOUND)
|
||||||
|
set(LIBOBS_LIB ${LIBOBS_LIBRARIES})
|
||||||
|
set(LIBOBS_INCLUDE_DIR ${LIBOBS_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
if(LibObs-frontend-api_FOUND)
|
||||||
|
set(LIBOBS_FRONTEND_API_LIB ${LIBOBS-FRONTEND-API_LIBRARIES})
|
||||||
|
set(LIBOBS_FRONTEND_INCLUDE_DIR ${LIBOBS-FRONTEND-API_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
include(external/FindLibObs.cmake)
|
if(NOT LIBOBS_LIB)
|
||||||
find_package(LibObs REQUIRED)
|
message(FATAL_ERROR "obs library not found - please set LIBOBS_LIB")
|
||||||
find_package(Qt5Core REQUIRED)
|
endif()
|
||||||
find_package(Qt5Widgets REQUIRED)
|
if(NOT LIBOBS_FRONTEND_API_LIB)
|
||||||
find_package(Libcurl REQUIRED)
|
message(
|
||||||
find_path(LIBOBS_FRONTEND_INCLUDE_DIR HINTS ${LIBOBS_INCLUDE_DIRS})
|
FATAL_ERROR
|
||||||
find_file(LIBOBS_FRONTEND_API_LIB NAMES libobs-frontend-api.* HINTS ${LIBOBS_LIB} )
|
"libobs frontend-api library not found - please set LIBOBS_FRONTEND_API_LIB"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(NOT LIBOBS_INCLUDE_DIR)
|
||||||
|
message(
|
||||||
|
FATAL_ERROR "obs.hpp header not found - please set LIBOBS_INCLUDE_DIR")
|
||||||
|
endif()
|
||||||
|
if(NOT LIBOBS_FRONTEND_INCLUDE_DIR)
|
||||||
|
message(
|
||||||
|
FATAL_ERROR
|
||||||
|
" obs-frontend-api.h not found - please set LIBOBS_FRONTEND_INCLUDE_DIR"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories("${LIBOBS_INCLUDE_DIR}" "${LIBOBS_FRONTEND_INCLUDE_DIR}"
|
||||||
|
${Qt5Core_INCLUDES} ${Qt5Widgets_INCLUDES})
|
||||||
|
|
||||||
|
find_package(CURL REQUIRED)
|
||||||
|
include_directories("${CURL_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
# Backwards compatability with older OBS versions
|
||||||
|
if(LibObs_VERSION_MAJOR GREATER_EQUAL 27)
|
||||||
|
add_definitions(-DVCAM_SUPPORTED)
|
||||||
|
else()
|
||||||
|
message(
|
||||||
|
WARNING
|
||||||
|
"OBS version ${LibObs_VERSION_MAJOR} found - disabling virtual camera functionality"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(LibObs_VERSION_MAJOR GREATER_EQUAL 26)
|
||||||
|
add_definitions(-DREPLAYBUFFER_SUPPORTED)
|
||||||
|
else()
|
||||||
|
message(
|
||||||
|
WARNING
|
||||||
|
"OBS version ${LibObs_VERSION_MAJOR} found - disabling replay buffer functionality"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
find_package(Libcurl REQUIRED)
|
||||||
|
include_directories("${LIBCURL_INCLUDE_DIRS}")
|
||||||
|
add_definitions(-DVCAM_SUPPORTED)
|
||||||
|
add_definitions(-DREPLAYBUFFER_SUPPORTED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Platform specific settings
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
find_library(COCOA Cocoa)
|
find_library(COCOA Cocoa)
|
||||||
if(BUILD_OUT_OF_TREE)
|
if(BUILD_OUT_OF_TREE)
|
||||||
find_package(Qt5MacExtras REQUIRED)
|
find_package(Qt5MacExtras REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
include_directories(${COCOA})
|
include_directories(${COCOA})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
find_package(X11 REQUIRED)
|
find_package(X11 REQUIRED COMPONENTS Xtst Xss)
|
||||||
link_libraries(${X11_LIBRARIES})
|
link_libraries(${X11_LIBRARIES})
|
||||||
include_directories(${X11_INCLUDE_DIR})
|
include_directories("${X11_INCLUDE_DIR}" "${X11_Xtst_INCLUDE_PATH}"
|
||||||
|
"${X11_Xss_INCLUDE_PATH}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(advanced-scene-switcher_HEADERS
|
|
||||||
${advanced-scene-switcher_HEADERS}
|
|
||||||
src/headers/advanced-scene-switcher.hpp
|
|
||||||
src/headers/switcher-data-structs.hpp
|
|
||||||
src/headers/utility.hpp
|
|
||||||
src/headers/scene-group.hpp
|
|
||||||
src/headers/scene-trigger.hpp
|
|
||||||
src/headers/switch-audio.hpp
|
|
||||||
src/headers/switch-executable.hpp
|
|
||||||
src/headers/switch-file.hpp
|
|
||||||
src/headers/switch-idle.hpp
|
|
||||||
src/headers/switch-media.hpp
|
|
||||||
src/headers/switch-network.hpp
|
|
||||||
src/headers/switch-pause.hpp
|
|
||||||
src/headers/switch-random.hpp
|
|
||||||
src/headers/switch-screen-region.hpp
|
|
||||||
src/headers/switch-time.hpp
|
|
||||||
src/headers/switch-transitions.hpp
|
|
||||||
src/headers/switch-window.hpp
|
|
||||||
src/headers/switch-sequence.hpp
|
|
||||||
src/headers/switch-video.hpp
|
|
||||||
src/headers/switch-generic.hpp
|
|
||||||
src/headers/macro-action-edit.hpp
|
|
||||||
src/headers/macro-action-audio.hpp
|
|
||||||
src/headers/macro-action-recording.hpp
|
|
||||||
src/headers/macro-action-replay-buffer.hpp
|
|
||||||
src/headers/macro-action-run.hpp
|
|
||||||
src/headers/macro-action-streaming.hpp
|
|
||||||
src/headers/macro-action-switch-scene.hpp
|
|
||||||
src/headers/macro-action-wait.hpp
|
|
||||||
src/headers/macro-condition-edit.hpp
|
|
||||||
src/headers/macro-condition-audio.hpp
|
|
||||||
src/headers/macro-condition-file.hpp
|
|
||||||
src/headers/macro-condition-idle.hpp
|
|
||||||
src/headers/macro-condition-media.hpp
|
|
||||||
src/headers/macro-condition-plugin-state.hpp
|
|
||||||
src/headers/macro-condition-process.hpp
|
|
||||||
src/headers/macro-condition-recording.hpp
|
|
||||||
src/headers/macro-condition-region.hpp
|
|
||||||
src/headers/macro-condition-scene.hpp
|
|
||||||
src/headers/macro-condition-streaming.hpp
|
|
||||||
src/headers/macro-condition-video.hpp
|
|
||||||
src/headers/macro-condition-window.hpp
|
|
||||||
src/headers/macro.hpp
|
|
||||||
src/headers/curl-helper.hpp
|
|
||||||
src/headers/screenshot-helper.hpp
|
|
||||||
src/headers/name-dialog.hpp
|
|
||||||
src/headers/duration-control.hpp
|
|
||||||
src/headers/section.hpp
|
|
||||||
src/headers/volume-control.hpp
|
|
||||||
src/headers/version.h
|
|
||||||
)
|
|
||||||
|
|
||||||
set(advanced-scene-switcher_SOURCES
|
|
||||||
${advanced-scene-switcher_SOURCES}
|
|
||||||
src/advanced-scene-switcher.cpp
|
|
||||||
src/advanced-scene-switcher-module.c
|
|
||||||
src/switcher-data-structs.cpp
|
|
||||||
src/scene-group.cpp
|
|
||||||
src/scene-trigger.cpp
|
|
||||||
src/switch-transitions.cpp
|
|
||||||
src/switch-screen-region.cpp
|
|
||||||
src/switch-priority.cpp
|
|
||||||
src/switch-executable.cpp
|
|
||||||
src/switch-idle.cpp
|
|
||||||
src/switch-sequence.cpp
|
|
||||||
src/switch-file.cpp
|
|
||||||
src/switch-window.cpp
|
|
||||||
src/switch-media.cpp
|
|
||||||
src/switch-network.cpp
|
|
||||||
src/hotkey.cpp
|
|
||||||
src/general.cpp
|
|
||||||
src/switch-pause.cpp
|
|
||||||
src/switch-random.cpp
|
|
||||||
src/switch-time.cpp
|
|
||||||
src/switch-audio.cpp
|
|
||||||
src/switch-video.cpp
|
|
||||||
src/switch-generic.cpp
|
|
||||||
src/macro-action-edit.cpp
|
|
||||||
src/macro-action-audio.cpp
|
|
||||||
src/macro-action-recording.cpp
|
|
||||||
src/macro-action-replay-buffer.cpp
|
|
||||||
src/macro-action-run.cpp
|
|
||||||
src/macro-action-streaming.cpp
|
|
||||||
src/macro-action-switch-scene.cpp
|
|
||||||
src/macro-action-wait.cpp
|
|
||||||
src/macro-condition-edit.cpp
|
|
||||||
src/macro-condition-audio.cpp
|
|
||||||
src/macro-condition-file.cpp
|
|
||||||
src/macro-condition-idle.cpp
|
|
||||||
src/macro-condition-media.cpp
|
|
||||||
src/macro-condition-plugin-state.cpp
|
|
||||||
src/macro-condition-process.cpp
|
|
||||||
src/macro-condition-recording.cpp
|
|
||||||
src/macro-condition-region.cpp
|
|
||||||
src/macro-condition-scene.cpp
|
|
||||||
src/macro-condition-streaming.cpp
|
|
||||||
src/macro-condition-video.cpp
|
|
||||||
src/macro-condition-window.cpp
|
|
||||||
src/macro.cpp
|
|
||||||
src/macro-tab.cpp
|
|
||||||
src/curl-helper.cpp
|
|
||||||
src/screenshot-helper.cpp
|
|
||||||
src/name-dialog.cpp
|
|
||||||
src/duration-control.cpp
|
|
||||||
src/section.cpp
|
|
||||||
src/volume-control.cpp
|
|
||||||
src/version.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(advanced-scene-switcher_UI
|
|
||||||
${advanced-scene-switcher_UI}
|
|
||||||
forms/advanced-scene-switcher.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
set(advanced-scene-switcher_PLATFORM_SOURCES
|
||||||
|
src/win/advanced-scene-switcher-win.cpp)
|
||||||
set(advanced-scene-switcher_PLATFORM_SOURCES
|
|
||||||
src/win/advanced-scene-switcher-win.cpp)
|
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
set(advanced-scene-switcher_PLATFORM_SOURCES
|
set(advanced-scene-switcher_PLATFORM_SOURCES
|
||||||
src/osx/advanced-scene-switcher-osx.mm)
|
src/osx/advanced-scene-switcher-osx.mm)
|
||||||
set_source_files_properties(advanced-scene-switcher-osx.mm
|
set_source_files_properties(advanced-scene-switcher-osx.mm
|
||||||
PROPERTIES COMPILE_FLAGS "-fobjc-arc")
|
PROPERTIES COMPILE_FLAGS "-fobjc-arc")
|
||||||
set(advanced-scene-switcher_PLATFORM_LIBS
|
set(advanced-scene-switcher_PLATFORM_LIBS ${COCOA})
|
||||||
${COCOA})
|
|
||||||
else()
|
else()
|
||||||
set(advanced-scene-switcher_PLATFORM_SOURCES
|
set(advanced-scene-switcher_PLATFORM_SOURCES
|
||||||
src/linux/advanced-scene-switcher-nix.cpp)
|
src/linux/advanced-scene-switcher-nix.cpp)
|
||||||
set(advanced-scene-switcher_PLATFORM_LIBS
|
set(advanced-scene-switcher_PLATFORM_LIBS Xss)
|
||||||
Xss)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
qt5_wrap_ui(advanced-scene-switcher_UI_HEADERS
|
# asio and websocketpp
|
||||||
${advanced-scene-switcher_UI}
|
add_definitions(-DASIO_STANDALONE)
|
||||||
${advanced-scene-switcher_PLATFORM_UI})
|
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp")
|
||||||
|
if(WIN32)
|
||||||
|
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(advanced-scene-switcher MODULE
|
# opencv
|
||||||
${advanced-scene-switcher_HEADERS}
|
find_package(OpenCV REQUIRED)
|
||||||
${advanced-scene-switcher_SOURCES}
|
include_directories("${OpenCV_INCLUDE_DIRS}")
|
||||||
${advanced-scene-switcher_UI_HEADERS}
|
|
||||||
${advanced-scene-switcher_PLATFORM_SOURCES}
|
|
||||||
${advanced-scene-switcher_PLATFORM_HEADERS}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
# Setup QT tools
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/forms")
|
||||||
|
set(advanced-scene-switcher_UI ${advanced-scene-switcher_UI}
|
||||||
|
forms/advanced-scene-switcher.ui)
|
||||||
|
qt5_wrap_ui(advanced-scene-switcher_UI_HEADERS ${advanced-scene-switcher_UI}
|
||||||
|
${advanced-scene-switcher_PLATFORM_UI})
|
||||||
|
|
||||||
|
# The plugin sources
|
||||||
|
set(advanced-scene-switcher_HEADERS
|
||||||
|
${advanced-scene-switcher_HEADERS}
|
||||||
|
src/headers/advanced-scene-switcher.hpp
|
||||||
|
src/headers/switcher-data-structs.hpp
|
||||||
|
src/headers/scene-group.hpp
|
||||||
|
src/headers/scene-trigger.hpp
|
||||||
|
src/headers/switch-audio.hpp
|
||||||
|
src/headers/switch-executable.hpp
|
||||||
|
src/headers/switch-file.hpp
|
||||||
|
src/headers/switch-idle.hpp
|
||||||
|
src/headers/switch-media.hpp
|
||||||
|
src/headers/switch-network.hpp
|
||||||
|
src/headers/switch-pause.hpp
|
||||||
|
src/headers/switch-random.hpp
|
||||||
|
src/headers/switch-screen-region.hpp
|
||||||
|
src/headers/switch-time.hpp
|
||||||
|
src/headers/switch-transitions.hpp
|
||||||
|
src/headers/switch-window.hpp
|
||||||
|
src/headers/switch-sequence.hpp
|
||||||
|
src/headers/switch-video.hpp
|
||||||
|
src/headers/switch-generic.hpp
|
||||||
|
src/headers/macro-action-edit.hpp
|
||||||
|
src/headers/macro-action-audio.hpp
|
||||||
|
src/headers/macro-action-file.hpp
|
||||||
|
src/headers/macro-action-filter.hpp
|
||||||
|
src/headers/macro-action-hotkey.hpp
|
||||||
|
src/headers/macro-action-macro.hpp
|
||||||
|
src/headers/macro-action-media.hpp
|
||||||
|
src/headers/macro-action-plugin-state.hpp
|
||||||
|
src/headers/macro-action-preview-scene.hpp
|
||||||
|
src/headers/macro-action-recording.hpp
|
||||||
|
src/headers/macro-action-replay-buffer.hpp
|
||||||
|
src/headers/macro-action-run.hpp
|
||||||
|
src/headers/macro-action-scene-order.hpp
|
||||||
|
src/headers/macro-action-scene-swap.hpp
|
||||||
|
src/headers/macro-action-scene-switch.hpp
|
||||||
|
src/headers/macro-action-scene-transform.hpp
|
||||||
|
src/headers/macro-action-scene-visibility.hpp
|
||||||
|
src/headers/macro-action-source.hpp
|
||||||
|
src/headers/macro-action-streaming.hpp
|
||||||
|
src/headers/macro-action-timer.hpp
|
||||||
|
src/headers/macro-action-transition.hpp
|
||||||
|
src/headers/macro-action-virtual-cam.hpp
|
||||||
|
src/headers/macro-action-wait.hpp
|
||||||
|
src/headers/macro-condition-edit.hpp
|
||||||
|
src/headers/macro-condition-audio.hpp
|
||||||
|
src/headers/macro-condition-cursor.hpp
|
||||||
|
src/headers/macro-condition-date.hpp
|
||||||
|
src/headers/macro-condition-file.hpp
|
||||||
|
src/headers/macro-condition-filter.hpp
|
||||||
|
src/headers/macro-condition-hotkey.hpp
|
||||||
|
src/headers/macro-condition-idle.hpp
|
||||||
|
src/headers/macro-condition-macro.hpp
|
||||||
|
src/headers/macro-condition-media.hpp
|
||||||
|
src/headers/macro-condition-plugin-state.hpp
|
||||||
|
src/headers/macro-condition-process.hpp
|
||||||
|
src/headers/macro-condition-recording.hpp
|
||||||
|
src/headers/macro-condition-replay-buffer.hpp
|
||||||
|
src/headers/macro-condition-scene-order.hpp
|
||||||
|
src/headers/macro-condition-scene-transform.hpp
|
||||||
|
src/headers/macro-condition-scene.hpp
|
||||||
|
src/headers/macro-condition-source.hpp
|
||||||
|
src/headers/macro-condition-streaming.hpp
|
||||||
|
src/headers/macro-condition-timer.hpp
|
||||||
|
src/headers/macro-condition-transition.hpp
|
||||||
|
src/headers/macro-condition-video.hpp
|
||||||
|
src/headers/macro-condition-virtual-cam.hpp
|
||||||
|
src/headers/macro-condition-window.hpp
|
||||||
|
src/headers/macro.hpp
|
||||||
|
src/headers/macro-controls.hpp
|
||||||
|
src/headers/macro-segment.hpp
|
||||||
|
src/headers/macro-selection.hpp
|
||||||
|
src/headers/curl-helper.hpp
|
||||||
|
src/headers/hotkey.hpp
|
||||||
|
src/headers/scene-selection.hpp
|
||||||
|
src/headers/screenshot-helper.hpp
|
||||||
|
src/headers/transition-selection.hpp
|
||||||
|
src/headers/name-dialog.hpp
|
||||||
|
src/headers/duration-control.hpp
|
||||||
|
src/headers/file-selection.hpp
|
||||||
|
src/headers/section.hpp
|
||||||
|
src/headers/platform-funcs.hpp
|
||||||
|
src/headers/utility.hpp
|
||||||
|
src/headers/volume-control.hpp
|
||||||
|
src/headers/version.h)
|
||||||
|
|
||||||
|
set(advanced-scene-switcher_SOURCES
|
||||||
|
${advanced-scene-switcher_SOURCES}
|
||||||
|
src/advanced-scene-switcher.cpp
|
||||||
|
src/advanced-scene-switcher-module.c
|
||||||
|
src/switcher-data-structs.cpp
|
||||||
|
src/scene-group.cpp
|
||||||
|
src/scene-trigger.cpp
|
||||||
|
src/switch-transitions.cpp
|
||||||
|
src/switch-screen-region.cpp
|
||||||
|
src/switch-priority.cpp
|
||||||
|
src/switch-executable.cpp
|
||||||
|
src/switch-idle.cpp
|
||||||
|
src/switch-sequence.cpp
|
||||||
|
src/switch-file.cpp
|
||||||
|
src/switch-window.cpp
|
||||||
|
src/switch-media.cpp
|
||||||
|
src/switch-network.cpp
|
||||||
|
src/file-selection.cpp
|
||||||
|
src/hotkey.cpp
|
||||||
|
src/general.cpp
|
||||||
|
src/switch-pause.cpp
|
||||||
|
src/switch-random.cpp
|
||||||
|
src/switch-time.cpp
|
||||||
|
src/switch-audio.cpp
|
||||||
|
src/switch-video.cpp
|
||||||
|
src/switch-generic.cpp
|
||||||
|
src/macro-action-edit.cpp
|
||||||
|
src/macro-action-audio.cpp
|
||||||
|
src/macro-action-file.cpp
|
||||||
|
src/macro-action-filter.cpp
|
||||||
|
src/macro-action-hotkey.cpp
|
||||||
|
src/macro-action-macro.cpp
|
||||||
|
src/macro-action-media.cpp
|
||||||
|
src/macro-action-plugin-state.cpp
|
||||||
|
src/macro-action-preview-scene.cpp
|
||||||
|
src/macro-action-recording.cpp
|
||||||
|
src/macro-action-replay-buffer.cpp
|
||||||
|
src/macro-action-run.cpp
|
||||||
|
src/macro-action-scene-order.cpp
|
||||||
|
src/macro-action-scene-swap.cpp
|
||||||
|
src/macro-action-scene-switch.cpp
|
||||||
|
src/macro-action-scene-transform.cpp
|
||||||
|
src/macro-action-scene-visibility.cpp
|
||||||
|
src/macro-action-source.cpp
|
||||||
|
src/macro-action-streaming.cpp
|
||||||
|
src/macro-action-timer.cpp
|
||||||
|
src/macro-action-transition.cpp
|
||||||
|
src/macro-action-virtual-cam.cpp
|
||||||
|
src/macro-action-wait.cpp
|
||||||
|
src/macro-condition-edit.cpp
|
||||||
|
src/macro-condition-audio.cpp
|
||||||
|
src/macro-condition-cursor.cpp
|
||||||
|
src/macro-condition-date.cpp
|
||||||
|
src/macro-condition-file.cpp
|
||||||
|
src/macro-condition-filter.cpp
|
||||||
|
src/macro-condition-hotkey.cpp
|
||||||
|
src/macro-condition-idle.cpp
|
||||||
|
src/macro-condition-macro.cpp
|
||||||
|
src/macro-condition-media.cpp
|
||||||
|
src/macro-condition-plugin-state.cpp
|
||||||
|
src/macro-condition-process.cpp
|
||||||
|
src/macro-condition-recording.cpp
|
||||||
|
src/macro-condition-replay-buffer.cpp
|
||||||
|
src/macro-condition-scene-order.cpp
|
||||||
|
src/macro-condition-scene-transform.cpp
|
||||||
|
src/macro-condition-scene.cpp
|
||||||
|
src/macro-condition-source.cpp
|
||||||
|
src/macro-condition-streaming.cpp
|
||||||
|
src/macro-condition-timer.cpp
|
||||||
|
src/macro-condition-transition.cpp
|
||||||
|
src/macro-condition-video.cpp
|
||||||
|
src/macro-condition-virtual-cam.cpp
|
||||||
|
src/macro-condition-window.cpp
|
||||||
|
src/macro.cpp
|
||||||
|
src/macro-controls.cpp
|
||||||
|
src/macro-segment.cpp
|
||||||
|
src/macro-selection.cpp
|
||||||
|
src/macro-tab.cpp
|
||||||
|
src/curl-helper.cpp
|
||||||
|
src/scene-selection.cpp
|
||||||
|
src/screenshot-helper.cpp
|
||||||
|
src/transition-selection.cpp
|
||||||
|
src/name-dialog.cpp
|
||||||
|
src/duration-control.cpp
|
||||||
|
src/section.cpp
|
||||||
|
src/utility.cpp
|
||||||
|
src/volume-control.cpp
|
||||||
|
src/version.cpp)
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
advanced-scene-switcher MODULE
|
||||||
|
${advanced-scene-switcher_HEADERS}
|
||||||
|
${advanced-scene-switcher_SOURCES}
|
||||||
|
${advanced-scene-switcher_UI_HEADERS}
|
||||||
|
${advanced-scene-switcher_PLATFORM_SOURCES}
|
||||||
|
${advanced-scene-switcher_PLATFORM_HEADERS})
|
||||||
|
|
||||||
|
# Out of tree build
|
||||||
if(BUILD_OUT_OF_TREE)
|
if(BUILD_OUT_OF_TREE)
|
||||||
include_directories(
|
target_link_libraries(
|
||||||
"${LIBOBS_INCLUDE_DIRS}"
|
advanced-scene-switcher
|
||||||
"${LIBOBS_FRONTEND_INCLUDE_DIR}"
|
${advanced-scene-switcher_PLATFORM_LIBS}
|
||||||
${Qt5Core_INCLUDES}
|
${OpenCV_LIBRARIES}
|
||||||
${Qt5Widgets_INCLUDES}
|
${LIBOBS_LIB}
|
||||||
${LIBCURL_INCLUDE_DIRS})
|
${LIBOBS_FRONTEND_API_LIB}
|
||||||
|
Qt5::Core
|
||||||
|
Qt5::Widgets)
|
||||||
|
|
||||||
target_link_libraries(advanced-scene-switcher
|
# Additional commands to install the module in the correct place. Find all the
|
||||||
${advanced-scene-switcher_PLATFORM_LIBS}
|
# translation files so we can copy them to the correct place later on.
|
||||||
${LIBOBS_LIB}
|
file(GLOB ASS_TRANSLATION_FILES "data/locale/*.ini")
|
||||||
${LIBOBS_FRONTEND_API_LIB}
|
|
||||||
Qt5::Core
|
|
||||||
Qt5::Widgets)
|
|
||||||
|
|
||||||
# Additional commands to install the module in the correct place.
|
# OSX
|
||||||
# Find all the translation files so we can copy them to the correct
|
if(APPLE)
|
||||||
# place later on.
|
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "")
|
||||||
file(GLOB ASS_TRANSLATION_FILES
|
endif()
|
||||||
"data/locale/*.ini"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Windows
|
# Linux
|
||||||
if(WIN32)
|
if(UNIX AND NOT APPLE)
|
||||||
string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
if(NOT LIB_OUT_DIR)
|
||||||
message("${CMAKE_CXX_FLAGS_RELEASE}")
|
set(LIB_OUT_DIR "/lib/obs-plugins")
|
||||||
|
endif()
|
||||||
find_package(w32-pthreads REQUIRED)
|
if(NOT DATA_OUT_DIR)
|
||||||
|
set(DATA_OUT_DIR "/share/obs/obs-plugins/advanced-scene-switcher")
|
||||||
target_link_libraries(advanced-scene-switcher
|
endif()
|
||||||
w32-pthreads)
|
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "")
|
||||||
endif()
|
install(TARGETS advanced-scene-switcher
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR})
|
||||||
# OSX
|
install(DIRECTORY data/locale
|
||||||
if(APPLE)
|
DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR})
|
||||||
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "")
|
install(DIRECTORY data/res
|
||||||
endif()
|
DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR})
|
||||||
|
endif()
|
||||||
# Linux
|
|
||||||
if(UNIX AND NOT APPLE)
|
|
||||||
set(CMAKE_C_FLAGS "-Wall -Wextra -Wvla -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-braces -Wno-missing-field-initializers ${CMAKE_C_FLAGS} -std=c99 -fno-strict-aliasing")
|
|
||||||
|
|
||||||
if(ARCH EQUAL 64)
|
|
||||||
set(ARCH_NAME "x86_64")
|
|
||||||
else()
|
|
||||||
set(ARCH_NAME "i686")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "")
|
|
||||||
|
|
||||||
install(TARGETS advanced-scene-switcher
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/obs-plugins)
|
|
||||||
install(FILES ${ASS_TRANSLATION_FILES}
|
|
||||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/obs/obs-plugins/advanced-scene-switcher/locale")
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
target_link_libraries(advanced-scene-switcher
|
# In tree build
|
||||||
${advanced-scene-switcher_PLATFORM_LIBS}
|
target_link_libraries(
|
||||||
obs-frontend-api
|
advanced-scene-switcher
|
||||||
Qt5::Widgets
|
${advanced-scene-switcher_PLATFORM_LIBS}
|
||||||
libobs)
|
${OpenCV_LIBRARIES}
|
||||||
|
obs-frontend-api
|
||||||
install_obs_plugin_with_data(advanced-scene-switcher data)
|
Qt5::Widgets
|
||||||
|
libobs)
|
||||||
|
install_obs_plugin_with_data(advanced-scene-switcher data)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
128
README.md
128
README.md
@@ -1,119 +1,27 @@
|
|||||||
# SceneSwitcher
|
# SceneSwitcher
|
||||||
An automated scene switcher for OBS Studio
|
An automated scene switcher for OBS Studio.
|
||||||
|
|
||||||
More information can be found on https://obsproject.com/forum/resources/automatic-scene-switching.395/ and see https://github.com/WarmUpTill/SceneSwitcher/blob/master/CI/release/README.txt for installing releases.
|
More information can be found on https://obsproject.com/forum/resources/automatic-scene-switching.395/.
|
||||||
|
|
||||||
## Compiling in tree (recommended)
|
## Downloads
|
||||||
Add the "SceneSwitcher" source directory to your obs-studio source directory under obs-studio/UI/frontend-plugins/:
|
|
||||||
|
Binaries for Windows, MacOS, and Linux are available in the [Releases](https://github.com/WarmUpTill/SceneSwitcher/releases) section.
|
||||||
|
|
||||||
|
## Installing the plugin
|
||||||
|
|
||||||
|
For the Windows and MacOS platforms, it is recommended to run the provided installers.
|
||||||
|
|
||||||
|
For Linux the Snap package manager offers an OBS Studio installation which is bundled with the plugin:
|
||||||
```
|
```
|
||||||
cd obs-studio/UI/frontend-plugins/
|
sudo snap install obs-studio
|
||||||
git clone https://github.com/WarmUpTill/SceneSwitcher.git
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then modify the obs-studio/UI/frontend-plugins/CMakeLists.txt file and add an entry for the scene switcher:
|
If that is not an option you will have to ...
|
||||||
add_subdirectory(SceneSwitcher)
|
1. Copy the library to the plugins folder of you obs installation.
|
||||||
|
2. Copy the contents of the data directory to its respective folders of your obs installation.
|
||||||
|
|
||||||
## Compiling out of tree
|
Unfortunately the exact location of these folders may vary from system to system.
|
||||||
### Prerequisites
|
|
||||||
You'll need CMake and a working development environment for OBS Studio installed
|
|
||||||
on your computer. Once you've done that, do the following:
|
|
||||||
```
|
|
||||||
git clone https://github.com/WarmUpTill/SceneSwitcher.git
|
|
||||||
cd SceneSwitcher
|
|
||||||
mkdir build && cd build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Windows
|
## Compiling the plugin
|
||||||
In cmake-gui, you'll have to set these CMake variables :
|
|
||||||
- **BUILD_OUT_OF_TREE** (bool) : true
|
|
||||||
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
|
|
||||||
code of OBS Studio, located at [source_directory]/libobs/.
|
|
||||||
- **LIBOBS_LIB** (filepath) : location of the obs.dll file (usually set to
|
|
||||||
C:\Program Files\obs-studio\bin\64bit\obs.dll)
|
|
||||||
|
|
||||||
Assuming that you installed Qt via the regular Qt App way:
|
See the [build instructions](BUILDING.md).
|
||||||
- **Qt5Core_DIR** (path) : C:/Qt/5.10.1/msvc2017_64/lib/cmake/Qt5Core
|
|
||||||
- **Qt5Gui_DIR** (path): C:/Qt/5.10.1/msvc2017_64/lib/cmake/Qt5Gui
|
|
||||||
- **Qt5Widgets_DIR** (path) : C:/Qt/5.10.1/msvc2017_64/lib/cmake/Qt5Widgets
|
|
||||||
|
|
||||||
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the libobs-frontend-api.dll
|
|
||||||
file, usually C:/Program Files/obs-studio/bin/64bit/obs-frontend-api.dll
|
|
||||||
(usually in the same place as LIBOBS_LIB)
|
|
||||||
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api
|
|
||||||
subfolder in the source code of OBS Studio, located at [source_directory]/UI/obs-frontend-api.
|
|
||||||
|
|
||||||
Just keep hitting configure until all the vars are filled out. Then hit generate.
|
|
||||||
|
|
||||||
### Linux
|
|
||||||
Most versions of Linux you can use cmake-gui or the command line.
|
|
||||||
|
|
||||||
**For the command line:**
|
|
||||||
```
|
|
||||||
cmake -DBUILD_OUT_OF_TREE=1 -DLIBOBS_INCLUDE_DIR="<path to the libobs/ sub-folder in obs-studio's source code>" \
|
|
||||||
-DLIBOBS_FRONTEND_INCLUDE_DIR="<path to the UI/obs-frontend-api/ sub-folder in obs-studio's source code>" \
|
|
||||||
-DLIBOBS_LIB="<path to the libobs.so file>" \
|
|
||||||
-DLIBOBS_FRONTEND_API_LIB="<path to the libobs-frontend-api.so file (usually in the same place as LIBOBS_LIB)>" \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr ..
|
|
||||||
make -j4
|
|
||||||
sudo make install
|
|
||||||
```
|
|
||||||
|
|
||||||
For cmake-gui you'll have to set the following variables:
|
|
||||||
- **BUILD_OUT_OF_TREE** (bool) : true
|
|
||||||
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
|
|
||||||
code of OBS Studio, located at [source_directory]/libobs/.
|
|
||||||
- **LIBOBS_LIB** (filepath) : location of the libobs.so file (usually CMake finds
|
|
||||||
this, but if not it'll usually be in /usr/lib/libobs.so)
|
|
||||||
|
|
||||||
Assuming that you installed Qt via your system package manager, it should be
|
|
||||||
found automatically. If not, then usually you'll find it in something like:
|
|
||||||
- **Qt5Core_DIR** (path) : /usr/lib64/cmake/Qt5Core
|
|
||||||
- **Qt5Gui_DIR** (path): /usr/lib64/cmake/Qt5Gui
|
|
||||||
- **Qt5Widgets_DIR** (path) : /usr/lib64/cmake/Qt5Widgets
|
|
||||||
|
|
||||||
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the libobs-frontend-api.so
|
|
||||||
file (usually in the same place as LIBOBS_LIB)
|
|
||||||
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api
|
|
||||||
subfolder in the source code of OBS Studio, located at
|
|
||||||
[source_directory]/UI/obs-frontend-api.
|
|
||||||
|
|
||||||
Just keep hitting configure until all the vars are filled out. Then hit generate.
|
|
||||||
|
|
||||||
Then open a terminal in the build folder and type:
|
|
||||||
```
|
|
||||||
make -j4
|
|
||||||
sudo make install
|
|
||||||
```
|
|
||||||
NOTE: The Linux version of this plugin is dependent on libXScrnSaver.
|
|
||||||
|
|
||||||
### OS X
|
|
||||||
In cmake-gui, you'll have to set these CMake variables :
|
|
||||||
- **BUILD_OUT_OF_TREE** (bool) : true
|
|
||||||
- **LIBOBS_INCLUDE_DIR** (path) : location of the libobs subfolder in the source
|
|
||||||
code of OBS Studio, located at [source_directory]/libobs/.
|
|
||||||
- **LIBOBS_LIB** (filepath) : location of the libobs.0.dylib file (usually
|
|
||||||
in /Applications/OBS.app/Contents/Resources/bin/libobs.0.dylib)
|
|
||||||
|
|
||||||
Assuming that you installed Qt via the regular Qt App way:
|
|
||||||
- **Qt5Core_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5Core
|
|
||||||
- **Qt5Widgets_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5Widgets
|
|
||||||
- **Qt5MacExtras_DIR** (path) : Usually /Applications/Qt/5.10.1/clang_64/lib/cmake/Qt5MacExtras
|
|
||||||
|
|
||||||
- **LIBOBS_FRONTEND_API_LIB** (filepath) : location of the libobs-frontend-api.0.dylib
|
|
||||||
file (usually in usually in /Applications/OBS.app/Contents/Resources/bin/libobs-frontend-api.0.dylib)
|
|
||||||
- **LIBOBS_FRONTEND_INCLUDE_DIR** (path) : location of the obs-frontend-api subfolder
|
|
||||||
in the source code of OBS Studio, located at [source_directory]/UI/obs-frontend-api.
|
|
||||||
|
|
||||||
Just keep hitting configure until all the vars are filled out. Then hit generate.
|
|
||||||
|
|
||||||
Open xcode (or a terminal, depending on the build type you chose), build and copy
|
|
||||||
the advanced-scene-switcher.so file to /Applications/OBS.app/Contents/PlugIns
|
|
||||||
|
|
||||||
Note that you might have to adjust the library search paths using the install_name_tool if you want the plugin to run on machines other than your build machine:
|
|
||||||
```
|
|
||||||
install_name_tool -change @rpath/libobs-frontend-api.dylib @executable_path/../Frameworks/libobs-frontend-api.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
|
||||||
install_name_tool -change @rpath/libobs.0.dylib @executable_path/../Frameworks/libobs.0.dylib UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
|
||||||
install_name_tool -change /usr/local/opt/qt5/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
|
||||||
install_name_tool -change /usr/local/opt/qt5/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
|
||||||
install_name_tool -change /usr/local/opt/qt5/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore UI/frontend-plugins/SceneSwitcher/advanced-scene-switcher.so
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
#include "src/headers/version.h"
|
#include "src/headers/version.h"
|
||||||
#define GIT_SHA1 "@GIT_SHA1@"
|
#define GIT_SHA1 "@GIT_SHA1@"
|
||||||
const char g_GIT_SHA1[] = GIT_SHA1;
|
#define GIT_TAG "@GIT_TAG@"
|
||||||
|
const char g_GIT_SHA1[] = GIT_SHA1;
|
||||||
|
const char g_GIT_TAG[] = GIT_TAG;
|
||||||
@@ -227,7 +227,9 @@ AdvSceneSwitcher.networkTab.Disabledwarning="Diese Funktionalität musste unter
|
|||||||
AdvSceneSwitcher.networkTab.server="Server starten (Sendet Szenenwechselnachrichten zu allen verbundenen Clients)"
|
AdvSceneSwitcher.networkTab.server="Server starten (Sendet Szenenwechselnachrichten zu allen verbundenen Clients)"
|
||||||
AdvSceneSwitcher.networkTab.server.port="Port"
|
AdvSceneSwitcher.networkTab.server.port="Port"
|
||||||
AdvSceneSwitcher.networkTab.server.lockToIPv4="Nur IPv4 verwenden (deaktiviert IPv6)"
|
AdvSceneSwitcher.networkTab.server.lockToIPv4="Nur IPv4 verwenden (deaktiviert IPv6)"
|
||||||
AdvSceneSwitcher.networkTab.server.restrictSendToAutomatedSwitches="Sende nur Szenenwechselnachrichten für automatisierte Szenenwechsel"
|
AdvSceneSwitcher.networkTab.server.sendSceneChange="Sende Nachrichten für Szenenwechsel"
|
||||||
|
AdvSceneSwitcher.networkTab.server.restrictSendToAutomatedSwitches="Sende nur Szenenwechselnachrichten für automatisierte Szenenwechsel"
|
||||||
|
AdvSceneSwitcher.networkTab.server.sendPreview="Sende Nachrichten für Vorschau Szenenwechsel im Studio-Modus"
|
||||||
AdvSceneSwitcher.networkTab.startFailed.message="Der WebSocket-Server konnte nicht gestartet werden, mögliche Gründe:\n - Der TCP-Port %1 wird möglicherweise gerade von einem anderen Programm verwendet. Versuchen Sie einen anderen Port in den Websocket-Servereinstellungen zu setzen oder alle Programme zu beenden, die den Port möglicherweise verwenden.\n - Fehler: %2"
|
AdvSceneSwitcher.networkTab.startFailed.message="Der WebSocket-Server konnte nicht gestartet werden, mögliche Gründe:\n - Der TCP-Port %1 wird möglicherweise gerade von einem anderen Programm verwendet. Versuchen Sie einen anderen Port in den Websocket-Servereinstellungen zu setzen oder alle Programme zu beenden, die den Port möglicherweise verwenden.\n - Fehler: %2"
|
||||||
AdvSceneSwitcher.networkTab.server.status.currentStatus="Aktueller Status"
|
AdvSceneSwitcher.networkTab.server.status.currentStatus="Aktueller Status"
|
||||||
AdvSceneSwitcher.networkTab.server.status.notRunning="Nicht gestartet"
|
AdvSceneSwitcher.networkTab.server.status.notRunning="Nicht gestartet"
|
||||||
@@ -282,6 +284,8 @@ AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.muteSource="Audio Quelle stu
|
|||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.unmuteSource="Audio Quelle aktiv schalten"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.unmuteSource="Audio Quelle aktiv schalten"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startSwitcher="Szenenwechsler starten"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startSwitcher="Szenenwechsler starten"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopSwitcher="Szenenwechsler stoppen"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopSwitcher="Szenenwechsler stoppen"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startVirtualCamera="Virtuelle Kamera starten"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopVirtualCamera="Virtuelle Kamera stoppen"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.entry="Wenn {{scenes}} {{triggers}} {{actions}} {{audioSources}} nach {{duration}} "
|
AdvSceneSwitcher.sceneTriggerTab.entry="Wenn {{scenes}} {{triggers}} {{actions}} {{audioSources}} nach {{duration}} "
|
||||||
AdvSceneSwitcher.sceneTriggerTab.help="Dieser Tab ermöglicht es automatisiert Handlungen, wie etwa das Stoppen von einer Aufnahme oder des Streamens, bei einem Szenenwechsel auszuführen."
|
AdvSceneSwitcher.sceneTriggerTab.help="Dieser Tab ermöglicht es automatisiert Handlungen, wie etwa das Stoppen von einer Aufnahme oder des Streamens, bei einem Szenenwechsel auszuführen."
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ AdvSceneSwitcher.generalTab.priority.macro="Macro"
|
|||||||
AdvSceneSwitcher.macroTab.title="Macro"
|
AdvSceneSwitcher.macroTab.title="Macro"
|
||||||
AdvSceneSwitcher.macroTab.macros="Macros"
|
AdvSceneSwitcher.macroTab.macros="Macros"
|
||||||
AdvSceneSwitcher.macroTab.help="Macros allow you to execute a string of actions depending on multiple conditions.\n\nClick on the highlighted plus symbol to add a new Macro."
|
AdvSceneSwitcher.macroTab.help="Macros allow you to execute a string of actions depending on multiple conditions.\n\nClick on the highlighted plus symbol to add a new Macro."
|
||||||
AdvSceneSwitcher.macroTab.editConditionHelp="This section allows you to define Macro conditions.\n\nSelect an existing or add a new Macro on the left."
|
AdvSceneSwitcher.macroTab.editConditionHelp="This section allows you to define Macro conditions.\n\nSelect an existing or add a new Macro on the left.\nThen click the plus button below to add a new condition."
|
||||||
AdvSceneSwitcher.macroTab.editActionHelp="This section allows you to define Macro actions.\n\nSelect an existing or add a new Macro on the left."
|
AdvSceneSwitcher.macroTab.editActionHelp="This section allows you to define Macro actions.\n\nSelect an existing or add a new Macro on the left.\nThen click the plus button below to add a new action."
|
||||||
AdvSceneSwitcher.macroTab.edit="Edit macro"
|
AdvSceneSwitcher.macroTab.edit="Edit macro"
|
||||||
AdvSceneSwitcher.macroTab.edit.logic="Logic type:"
|
AdvSceneSwitcher.macroTab.edit.logic="Logic type:"
|
||||||
AdvSceneSwitcher.macroTab.edit.condition="Condition type:"
|
AdvSceneSwitcher.macroTab.edit.condition="Condition type:"
|
||||||
@@ -68,6 +68,9 @@ AdvSceneSwitcher.macroTab.name="Name:"
|
|||||||
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
AdvSceneSwitcher.macroTab.defaultname="Macro %1"
|
||||||
AdvSceneSwitcher.macroTab.exists="Macro name exists already"
|
AdvSceneSwitcher.macroTab.exists="Macro name exists already"
|
||||||
AdvSceneSwitcher.macroTab.copy="Create copy"
|
AdvSceneSwitcher.macroTab.copy="Create copy"
|
||||||
|
AdvSceneSwitcher.macroTab.expandAll="Expand all"
|
||||||
|
AdvSceneSwitcher.macroTab.collapseAll="Collapse all"
|
||||||
|
|
||||||
; Macro Logic
|
; Macro Logic
|
||||||
AdvSceneSwitcher.logic.none="Ignore entry"
|
AdvSceneSwitcher.logic.none="Ignore entry"
|
||||||
AdvSceneSwitcher.logic.and="And"
|
AdvSceneSwitcher.logic.and="And"
|
||||||
@@ -76,22 +79,31 @@ AdvSceneSwitcher.logic.andNot="And not"
|
|||||||
AdvSceneSwitcher.logic.orNot="Or not"
|
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.audio="Audio"
|
AdvSceneSwitcher.condition.audio="Audio"
|
||||||
AdvSceneSwitcher.ondition.audio.state.below="Below"
|
AdvSceneSwitcher.condition.audio.state.below="Below"
|
||||||
AdvSceneSwitcher.ondition.audio.state.above="Above"
|
AdvSceneSwitcher.condition.audio.state.above="Above"
|
||||||
AdvSceneSwitcher.condition.audio.entry="Volume of {{audioSources}} is {{condition}} {{volume}} for {{duration}} seconds"
|
AdvSceneSwitcher.condition.audio.entry="Volume of {{audioSources}} is {{condition}} {{volume}}"
|
||||||
AdvSceneSwitcher.condition.region="Screen region"
|
AdvSceneSwitcher.condition.cursor="Cursor"
|
||||||
AdvSceneSwitcher.condition.region.entry="Cursor is in {{minX}} {{minY}} x {{maxX}} {{maxY}}"
|
AdvSceneSwitcher.condition.cursor.type.region="is in region"
|
||||||
|
AdvSceneSwitcher.condition.cursor.type.moving="is moving"
|
||||||
|
AdvSceneSwitcher.condition.cursor.showFrame="Show frame"
|
||||||
|
AdvSceneSwitcher.condition.cursor.hideFrame="Hide frame"
|
||||||
|
AdvSceneSwitcher.condition.cursor.entry.line1="Cursor is {{conditions}} {{minX}} {{minY}} {{maxX}} {{maxY}} - {{toggleFrameButton}}"
|
||||||
|
AdvSceneSwitcher.condition.cursor.entry.line2="Cursor is currently at {{xPos}} x {{yPos}}"
|
||||||
AdvSceneSwitcher.condition.scene="Scene"
|
AdvSceneSwitcher.condition.scene="Scene"
|
||||||
AdvSceneSwitcher.condition.scene.type.current="Current"
|
AdvSceneSwitcher.condition.scene.type.current="Current scene is"
|
||||||
AdvSceneSwitcher.condition.scene.type.previous="Previous"
|
AdvSceneSwitcher.condition.scene.type.previous="Previous scene is"
|
||||||
AdvSceneSwitcher.condition.scene.entry="{{sceneType}} scene is {{scenes}} for {{duration}}"
|
AdvSceneSwitcher.condition.scene.type.changed="Scene chagned"
|
||||||
|
AdvSceneSwitcher.condition.scene.type.notChanged="Scene has not changed"
|
||||||
|
AdvSceneSwitcher.condition.scene.waitForTransition="Wait for transition to complete"
|
||||||
|
AdvSceneSwitcher.condition.scene.entry="{{sceneType}} {{scenes}} {{waitForTransition}}"
|
||||||
AdvSceneSwitcher.condition.window="Window"
|
AdvSceneSwitcher.condition.window="Window"
|
||||||
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} exist and ..."
|
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} exist and ..."
|
||||||
AdvSceneSwitcher.condition.window.entry.line2="... is {{fullscreen}} fullscreen {{maximized}} maximized {{focused}} focused"
|
AdvSceneSwitcher.condition.window.entry.line2="... is {{fullscreen}} fullscreen {{maximized}} maximized {{focused}} focused {{windowFocusChanged}} foreground window changed"
|
||||||
AdvSceneSwitcher.condition.file="File"
|
AdvSceneSwitcher.condition.file="File"
|
||||||
AdvSceneSwitcher.condition.file.entry.line1="Content of {{fileType}} {{filePath}} {{browseButton}} matches:"
|
AdvSceneSwitcher.condition.file.entry.line1="Content of {{fileType}} {{filePath}} matches:"
|
||||||
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||||
AdvSceneSwitcher.condition.media="Media"
|
AdvSceneSwitcher.condition.media="Media"
|
||||||
@@ -102,19 +114,37 @@ AdvSceneSwitcher.condition.video.condition.differ="does not match"
|
|||||||
AdvSceneSwitcher.condition.video.condition.hasChanged="has changed"
|
AdvSceneSwitcher.condition.video.condition.hasChanged="has changed"
|
||||||
AdvSceneSwitcher.condition.video.condition.hasNotChanged="has not changed"
|
AdvSceneSwitcher.condition.video.condition.hasNotChanged="has not changed"
|
||||||
AdvSceneSwitcher.condition.video.condition.noImage="has no output"
|
AdvSceneSwitcher.condition.video.condition.noImage="has no output"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.pattern="matches pattern"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.object="contains object"
|
||||||
AdvSceneSwitcher.condition.video.askFileAction="Do you want to use an existing file or create a screenshot of the currently selected source?"
|
AdvSceneSwitcher.condition.video.askFileAction="Do you want to use an existing file or create a screenshot of the currently selected source?"
|
||||||
AdvSceneSwitcher.condition.video.askFileAction.file="Use existing file"
|
AdvSceneSwitcher.condition.video.askFileAction.file="Use existing file"
|
||||||
AdvSceneSwitcher.condition.video.askFileAction.screenshot="Create screenshot"
|
AdvSceneSwitcher.condition.video.askFileAction.screenshot="Create screenshot"
|
||||||
AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{filePath}} {{browseButton}} for {{duration}}"
|
AdvSceneSwitcher.condition.video.patternThreshold="Threshold: "
|
||||||
|
AdvSceneSwitcher.condition.video.patternThresholdDescription="A higher threshold value means that the pattern needs to match the video source more closely."
|
||||||
|
AdvSceneSwitcher.condition.video.patternThresholdUseAlphaAsMask="Use alpha channel as mask for pattern."
|
||||||
|
AdvSceneSwitcher.condition.video.objectScaleThreshold="Scale factor: "
|
||||||
|
AdvSceneSwitcher.condition.video.objectScaleThresholdDescription="A lower scale factor will lead to more matches but higher CPU load."
|
||||||
|
AdvSceneSwitcher.condition.video.minNeighborDescription="A higher minimum neighbors value will result in fewer but higher quality matches."
|
||||||
|
AdvSceneSwitcher.condition.video.showMatch="Show match"
|
||||||
|
AdvSceneSwitcher.condition.video.screenshotFail="Failed to get screenshot of source!"
|
||||||
|
AdvSceneSwitcher.condition.video.patternMatchFail="Pattern was not found!"
|
||||||
|
AdvSceneSwitcher.condition.video.objectMatchFail="Object was not found!"
|
||||||
|
AdvSceneSwitcher.condition.video.modelLoadFail="Model data could not be loaded!"
|
||||||
|
AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{imagePath}}"
|
||||||
|
AdvSceneSwitcher.condition.video.entry.modelPath="Model data (haar cascade classifier): {{modelDataPath}}"
|
||||||
|
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum neighbors: {{minNeighbors}}"
|
||||||
|
AdvSceneSwitcher.condition.video.entry.minSize="Minimum size: {{minSizeX}} x {{minSizeY}}"
|
||||||
|
AdvSceneSwitcher.condition.video.entry.maxSize="Maximum size: {{maxSizeX}} x {{maxSizeY}}"
|
||||||
|
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduce CPU load by performing check only every {{throttleCount}} milliseconds"
|
||||||
AdvSceneSwitcher.condition.stream="Streaming"
|
AdvSceneSwitcher.condition.stream="Streaming"
|
||||||
AdvSceneSwitcher.condition.stream.state.start="Stream running"
|
AdvSceneSwitcher.condition.stream.state.start="Stream running"
|
||||||
AdvSceneSwitcher.condition.stream.state.stop="Stream stopped"
|
AdvSceneSwitcher.condition.stream.state.stop="Stream stopped"
|
||||||
AdvSceneSwitcher.condition.stream.entry="{{streamState}} for {{duration}}"
|
AdvSceneSwitcher.condition.stream.entry="{{streamState}}"
|
||||||
AdvSceneSwitcher.condition.record="Recording"
|
AdvSceneSwitcher.condition.record="Recording"
|
||||||
AdvSceneSwitcher.condition.record.state.start="Recording running"
|
AdvSceneSwitcher.condition.record.state.start="Recording running"
|
||||||
AdvSceneSwitcher.condition.record.state.pause="Recording paused"
|
AdvSceneSwitcher.condition.record.state.pause="Recording paused"
|
||||||
AdvSceneSwitcher.condition.record.state.stop="Recording stopped"
|
AdvSceneSwitcher.condition.record.state.stop="Recording stopped"
|
||||||
AdvSceneSwitcher.condition.record.entry="{{recordState}} for {{duration}}"
|
AdvSceneSwitcher.condition.record.entry="{{recordState}}"
|
||||||
AdvSceneSwitcher.condition.process="Process"
|
AdvSceneSwitcher.condition.process="Process"
|
||||||
AdvSceneSwitcher.condition.process.entry="{{processes}} is running {{focused}} and is focused"
|
AdvSceneSwitcher.condition.process.entry="{{processes}} is running {{focused}} and is focused"
|
||||||
AdvSceneSwitcher.condition.idle="Idle"
|
AdvSceneSwitcher.condition.idle="Idle"
|
||||||
@@ -122,6 +152,81 @@ AdvSceneSwitcher.condition.idle.entry="No keyboard or mouse inputs for {{duratio
|
|||||||
AdvSceneSwitcher.condition.pluginState="Plugin state"
|
AdvSceneSwitcher.condition.pluginState="Plugin state"
|
||||||
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Automated scene change was triggered in this interval"
|
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Automated scene change was triggered in this interval"
|
||||||
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
||||||
|
AdvSceneSwitcher.condition.timer="Timer"
|
||||||
|
AdvSceneSwitcher.condition.timer.pause="Pause"
|
||||||
|
AdvSceneSwitcher.condition.timer.continue="Continue"
|
||||||
|
AdvSceneSwitcher.condition.timer.entry.line1="{{duration}} have passed"
|
||||||
|
AdvSceneSwitcher.condition.timer.entry.line2="Time remaining: {{remaining}} seconds"
|
||||||
|
AdvSceneSwitcher.condition.timer.entry.line3="{{pauseContinue}} {{reset}} {{saveRemaining}} Save time remaining {{autoReset}} Automatically reset timer after duration was reached"
|
||||||
|
AdvSceneSwitcher.condition.timer.reset="Reset"
|
||||||
|
AdvSceneSwitcher.condition.macro="Macro"
|
||||||
|
AdvSceneSwitcher.condition.macro.type.count="Count"
|
||||||
|
AdvSceneSwitcher.condition.macro.type.state="State"
|
||||||
|
AdvSceneSwitcher.condition.macro.type.selection="Condition type: {{types}}"
|
||||||
|
AdvSceneSwitcher.condition.macro.count.type.below="Less than"
|
||||||
|
AdvSceneSwitcher.condition.macro.count.type.above="More than"
|
||||||
|
AdvSceneSwitcher.condition.macro.count.type.equal="Exactly"
|
||||||
|
AdvSceneSwitcher.condition.macro.count.reset="Reset"
|
||||||
|
AdvSceneSwitcher.condition.macro.state.entry="Conditions of {{macros}} are true"
|
||||||
|
AdvSceneSwitcher.condition.macro.count.entry.line1="{{macros}} was executed {{conditions}} {{count}} times"
|
||||||
|
AdvSceneSwitcher.condition.macro.count.entry.line2="Current count: {{currentCount}} {{resetCount}}"
|
||||||
|
AdvSceneSwitcher.condition.source="Source"
|
||||||
|
AdvSceneSwitcher.condition.source.type.active="Is active"
|
||||||
|
AdvSceneSwitcher.condition.source.type.showing="Is showing"
|
||||||
|
AdvSceneSwitcher.condition.source.type.settings="Settings match"
|
||||||
|
AdvSceneSwitcher.condition.source.regex="Use regular expressions"
|
||||||
|
AdvSceneSwitcher.condition.source.getSettings="Get current settings"
|
||||||
|
AdvSceneSwitcher.condition.source.entry.line1="{{sources}} {{conditions}}"
|
||||||
|
AdvSceneSwitcher.condition.source.entry.line2="{{settings}}"
|
||||||
|
AdvSceneSwitcher.condition.source.entry.line3="{{regex}} {{getSettings}}"
|
||||||
|
AdvSceneSwitcher.condition.virtualCamera="Virtual camera"
|
||||||
|
AdvSceneSwitcher.condition.virtualCamera.state.start="Virtual camera started"
|
||||||
|
AdvSceneSwitcher.condition.virtualCamera.state.stop="Virtual camera stopped"
|
||||||
|
AdvSceneSwitcher.condition.virtualCamera.entry="{{states}}"
|
||||||
|
AdvSceneSwitcher.condition.filter="Filter"
|
||||||
|
AdvSceneSwitcher.condition.filter.type.active="Is enabled"
|
||||||
|
AdvSceneSwitcher.condition.filter.type.showing="Is disabled"
|
||||||
|
AdvSceneSwitcher.condition.filter.type.settings="Settings match"
|
||||||
|
AdvSceneSwitcher.condition.filter.regex="Use regular expressions"
|
||||||
|
AdvSceneSwitcher.condition.filter.getSettings="Get current settings"
|
||||||
|
AdvSceneSwitcher.condition.filter.entry.line1="On {{sources}} {{filters}} {{conditions}}"
|
||||||
|
AdvSceneSwitcher.condition.filter.entry.line2="{{settings}}"
|
||||||
|
AdvSceneSwitcher.condition.filter.entry.line3="{{regex}} {{getSettings}}"
|
||||||
|
AdvSceneSwitcher.condition.sceneOrder="Scene item order"
|
||||||
|
AdvSceneSwitcher.condition.sceneOrder.type.above="Is above"
|
||||||
|
AdvSceneSwitcher.condition.sceneOrder.type.below="Is below"
|
||||||
|
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.entry="On {{scenes}} {{sources}} {{conditions}} {{sources2}} {{position}}"
|
||||||
|
AdvSceneSwitcher.condition.hotkey="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.entry="Name: {{name}}"
|
||||||
|
AdvSceneSwitcher.condition.replay="Replay buffer"
|
||||||
|
AdvSceneSwitcher.condition.replay.state.stopped="Replay buffer stopped"
|
||||||
|
AdvSceneSwitcher.condition.replay.state.started="Replay buffer started"
|
||||||
|
AdvSceneSwitcher.condition.replay.state.saved="Replay buffer saved"
|
||||||
|
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||||
|
AdvSceneSwitcher.condition.date="Date"
|
||||||
|
AdvSceneSwitcher.condition.date.state.at="At"
|
||||||
|
AdvSceneSwitcher.condition.date.state.after="After"
|
||||||
|
AdvSceneSwitcher.condition.date.state.before="Before"
|
||||||
|
AdvSceneSwitcher.condition.date.state.between="Between"
|
||||||
|
AdvSceneSwitcher.condition.date.entry.line1="{{condition}} {{dateTime}} {{dateTime2}} {{ignoreDate}} Ignore date component {{ignoreTime}} Ignore time component"
|
||||||
|
AdvSceneSwitcher.condition.date.entry.line2="{{repeat}} Repeat every {{duration}} on date match"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform="Scene item transform"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.regex="Use regular expressions"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.entry.line1="On {{scenes}} {{sources}} matches transform"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
|
||||||
|
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
|
||||||
|
AdvSceneSwitcher.condition.transition="Transition"
|
||||||
|
AdvSceneSwitcher.condition.transition.type.current="Current transition type is"
|
||||||
|
AdvSceneSwitcher.condition.transition.type.duration="Current transition duration is"
|
||||||
|
AdvSceneSwitcher.condition.transition.type.started="Transition active"
|
||||||
|
AdvSceneSwitcher.condition.transition.type.ended="Transition ended"
|
||||||
|
AdvSceneSwitcher.condition.transition.durationSuffix="seconds"
|
||||||
|
AdvSceneSwitcher.condition.transition.entry="{{conditions}}{{transitions}}{{duration}}{{durationSuffix}}"
|
||||||
|
|
||||||
; Macro Actions
|
; Macro Actions
|
||||||
AdvSceneSwitcher.action.switchScene="Switch scene"
|
AdvSceneSwitcher.action.switchScene="Switch scene"
|
||||||
@@ -154,8 +259,87 @@ AdvSceneSwitcher.action.streaming.type.stop="Stop streaming"
|
|||||||
AdvSceneSwitcher.action.streaming.type.start="Start streaming"
|
AdvSceneSwitcher.action.streaming.type.start="Start streaming"
|
||||||
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||||
AdvSceneSwitcher.action.run="Run"
|
AdvSceneSwitcher.action.run="Run"
|
||||||
AdvSceneSwitcher.action.run.entry="Run {{filePath}} {{browseButton}}"
|
AdvSceneSwitcher.action.run.arguments="Arguments:"
|
||||||
|
AdvSceneSwitcher.action.run.addArgument="Add argument"
|
||||||
|
AdvSceneSwitcher.action.run.addArgumentDescription="Add new argument:"
|
||||||
|
AdvSceneSwitcher.action.run.entry="Run {{filePath}}"
|
||||||
|
AdvSceneSwitcher.action.sceneVisibility="Scene item visibility"
|
||||||
|
AdvSceneSwitcher.action.sceneVisibility.type.show="Show"
|
||||||
|
AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
|
||||||
|
AdvSceneSwitcher.action.sceneVisibility.entry="On {{scenes}} {{actions}} {{sources}}"
|
||||||
|
AdvSceneSwitcher.action.filter="Filter"
|
||||||
|
AdvSceneSwitcher.action.filter.type.enable="Enable"
|
||||||
|
AdvSceneSwitcher.action.filter.type.disable="Disable"
|
||||||
|
AdvSceneSwitcher.action.filter.type.settings="Set settings"
|
||||||
|
AdvSceneSwitcher.action.filter.entry="On {{sources}} {{actions}} {{filters}}"
|
||||||
|
AdvSceneSwitcher.action.filter.getSettings="Get current settings"
|
||||||
|
AdvSceneSwitcher.action.source="Source"
|
||||||
|
AdvSceneSwitcher.action.source.type.enable="Enable"
|
||||||
|
AdvSceneSwitcher.action.source.type.disable="Disable"
|
||||||
|
AdvSceneSwitcher.action.source.type.settings="Set settings"
|
||||||
|
AdvSceneSwitcher.action.source.entry="{{actions}} {{sources}}"
|
||||||
|
AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI"
|
||||||
|
AdvSceneSwitcher.action.source.getSettings="Get current settings"
|
||||||
|
AdvSceneSwitcher.action.media="Media"
|
||||||
|
AdvSceneSwitcher.action.media.type.play="Play"
|
||||||
|
AdvSceneSwitcher.action.media.type.pause="Pause"
|
||||||
|
AdvSceneSwitcher.action.media.type.stop="Stop"
|
||||||
|
AdvSceneSwitcher.action.media.type.restart="Restart"
|
||||||
|
AdvSceneSwitcher.action.media.type.next="Next"
|
||||||
|
AdvSceneSwitcher.action.media.type.previous="Previous"
|
||||||
|
AdvSceneSwitcher.action.media.entry="{{actions}} {{mediaSources}}"
|
||||||
|
AdvSceneSwitcher.action.macro="Macro"
|
||||||
|
AdvSceneSwitcher.action.macro.type.pause="Pause"
|
||||||
|
AdvSceneSwitcher.action.macro.type.unpause="Unpause"
|
||||||
|
AdvSceneSwitcher.action.macro.type.resetCounter="Reset counter"
|
||||||
|
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
|
||||||
|
AdvSceneSwitcher.action.pluginState="Plugin state"
|
||||||
|
AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin"
|
||||||
|
AdvSceneSwitcher.action.pluginState.type.noMatch="Change the no-match behaviour:"
|
||||||
|
AdvSceneSwitcher.action.pluginState.entry="{{actions}} {{values}} {{scenes}}"
|
||||||
|
AdvSceneSwitcher.action.virtualCamera="Virtual camera"
|
||||||
|
AdvSceneSwitcher.action.virtualCamera.type.stop="Stop virtual camera"
|
||||||
|
AdvSceneSwitcher.action.virtualCamera.type.start="Start virtual camera"
|
||||||
|
AdvSceneSwitcher.action.virtualCamera.entry="{{actions}}"
|
||||||
|
AdvSceneSwitcher.action.hotkey="Hotkey"
|
||||||
|
AdvSceneSwitcher.action.hotkey.leftShift="Left Shift"
|
||||||
|
AdvSceneSwitcher.action.hotkey.rightShift="Right Shift"
|
||||||
|
AdvSceneSwitcher.action.hotkey.leftCtrl="Left Ctrl"
|
||||||
|
AdvSceneSwitcher.action.hotkey.rightCtrl="Right Ctrl"
|
||||||
|
AdvSceneSwitcher.action.hotkey.leftAlt="Left Alt"
|
||||||
|
AdvSceneSwitcher.action.hotkey.rightAlt="Right Alt"
|
||||||
|
AdvSceneSwitcher.action.hotkey.leftMeta="Left Meta"
|
||||||
|
AdvSceneSwitcher.action.hotkey.rightMeta="Right Meta"
|
||||||
|
AdvSceneSwitcher.action.hotkey.onlyOBS="Send keypress only to OBS"
|
||||||
|
AdvSceneSwitcher.action.hotkey.disabled="Cannot simulate key presses - functionality disabled!"
|
||||||
|
AdvSceneSwitcher.action.hotkey.entry="Press {{keys}} for {{duration}} milliseconds"
|
||||||
|
AdvSceneSwitcher.action.sceneOrder="Scene item order"
|
||||||
|
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Move up"
|
||||||
|
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down"
|
||||||
|
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Move to top"
|
||||||
|
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom"
|
||||||
|
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position"
|
||||||
|
AdvSceneSwitcher.action.sceneOrder.entry="On {{scenes}} {{actions}} {{sources}} {{position}}"
|
||||||
|
AdvSceneSwitcher.action.sceneTransform="Scene item transform"
|
||||||
|
AdvSceneSwitcher.action.sceneTransform.getTransform="Get transform"
|
||||||
|
AdvSceneSwitcher.action.sceneTransform.entry="On {{scenes}} transform {{sources}}"
|
||||||
|
AdvSceneSwitcher.action.file="File"
|
||||||
|
AdvSceneSwitcher.action.file.type.write="Write"
|
||||||
|
AdvSceneSwitcher.action.file.type.append="Append"
|
||||||
|
AdvSceneSwitcher.action.file.entry="{{actions}} to {{filePath}}:"
|
||||||
|
AdvSceneSwitcher.action.previewScene="Switch preview scene"
|
||||||
|
AdvSceneSwitcher.action.previewScene.entry="Switch preview scene to {{scenes}}"
|
||||||
|
AdvSceneSwitcher.action.SceneSwap="Swap scene (Studio mode)"
|
||||||
|
AdvSceneSwitcher.action.SceneSwap.entry="Swap preview and program scene in studio mode"
|
||||||
|
AdvSceneSwitcher.action.transition="Transition"
|
||||||
|
AdvSceneSwitcher.action.transition.entry.line1="{{setType}}Set transition type to {{transitions}}"
|
||||||
|
AdvSceneSwitcher.action.transition.entry.line2="{{setDuration}}Set transition duration to {{duration}}seconds"
|
||||||
|
AdvSceneSwitcher.action.timer="Timer"
|
||||||
|
AdvSceneSwitcher.action.timer.type.pause="Pause"
|
||||||
|
AdvSceneSwitcher.action.timer.type.continue="Continue"
|
||||||
|
AdvSceneSwitcher.action.timer.type.reset="Reset"
|
||||||
|
AdvSceneSwitcher.action.timer.type.setTimeRemaining="Set time remaining of"
|
||||||
|
AdvSceneSwitcher.action.timer.entry="{{timerAction}} timers on {{macros}} {{duration}}"
|
||||||
|
|
||||||
; Transition Tab
|
; Transition Tab
|
||||||
AdvSceneSwitcher.transitionTab.title="Transition"
|
AdvSceneSwitcher.transitionTab.title="Transition"
|
||||||
@@ -327,12 +511,15 @@ AdvSceneSwitcher.videoTab.help="<html><head/><body><p>This tab will allow you to
|
|||||||
|
|
||||||
; 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.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."
|
||||||
AdvSceneSwitcher.networkTab.DisabledWarning="This functionality unfortunately had to be disabled on macOS due to library incompatibilities when running the obs-websocket plugin in parallel."
|
AdvSceneSwitcher.networkTab.DisabledWarning="This functionality unfortunately had to be disabled on macOS due to library incompatibilities when running the obs-websocket plugin in parallel."
|
||||||
AdvSceneSwitcher.networkTab.server="Start server (Sends scene switch messages to all connected clients)"
|
AdvSceneSwitcher.networkTab.server="Start server (Sends scene switch messages to all connected clients)"
|
||||||
AdvSceneSwitcher.networkTab.server.port="Port"
|
AdvSceneSwitcher.networkTab.server.port="Port"
|
||||||
AdvSceneSwitcher.networkTab.server.lockToIPv4="Lock server to only using IPv4"
|
AdvSceneSwitcher.networkTab.server.lockToIPv4="Lock server to only using IPv4"
|
||||||
|
AdvSceneSwitcher.networkTab.server.sendSceneChange="Send messages for scene changes"
|
||||||
AdvSceneSwitcher.networkTab.server.restrictSendToAutomatedSwitches="Only send messages for automated scene switches"
|
AdvSceneSwitcher.networkTab.server.restrictSendToAutomatedSwitches="Only send messages for automated scene switches"
|
||||||
|
AdvSceneSwitcher.networkTab.server.sendPreview="Send messages for preview scene change when running in Studio mode"
|
||||||
AdvSceneSwitcher.networkTab.startFailed.message="The WebSockets server failed to start, maybe because:\n - TCP port %1 may currently be in use elsewhere on this system, possibly by another application. Try setting a different TCP port in the WebSocket server settings, or stop any application that could be using this port.\n - Error message: %2"
|
AdvSceneSwitcher.networkTab.startFailed.message="The WebSockets server failed to start, maybe because:\n - TCP port %1 may currently be in use elsewhere on this system, possibly by another application. Try setting a different TCP port in the WebSocket server settings, or stop any application that could be using this port.\n - Error message: %2"
|
||||||
AdvSceneSwitcher.networkTab.server.status.currentStatus="Current status"
|
AdvSceneSwitcher.networkTab.server.status.currentStatus="Current status"
|
||||||
AdvSceneSwitcher.networkTab.server.status.notRunning="Not running"
|
AdvSceneSwitcher.networkTab.server.status.notRunning="Not running"
|
||||||
@@ -387,6 +574,8 @@ AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.muteSource="mute source"
|
|||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.unmuteSource="unmute source"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.unmuteSource="unmute source"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startSwitcher="start the scene switcher"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startSwitcher="start the scene switcher"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopSwitcher="stop the scene switcher"
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopSwitcher="stop the scene switcher"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startVirtualCamera="start virtual camera"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopVirtualCamera="stop virtual camera"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.entry="When {{scenes}} {{triggers}} {{actions}} {{audioSources}} after {{duration}}"
|
AdvSceneSwitcher.sceneTriggerTab.entry="When {{scenes}} {{triggers}} {{actions}} {{audioSources}} after {{duration}}"
|
||||||
AdvSceneSwitcher.sceneTriggerTab.help="This tab allows you to trigger actions on scene changes, like stopping recording or streaming."
|
AdvSceneSwitcher.sceneTriggerTab.help="This tab allows you to trigger actions on scene changes, like stopping recording or streaming."
|
||||||
|
|
||||||
@@ -394,6 +583,8 @@ AdvSceneSwitcher.sceneTriggerTab.help="This tab allows you to trigger actions on
|
|||||||
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"
|
||||||
|
AdvSceneSwitcher.hotkey.macro.pause="Pause macro %1"
|
||||||
|
AdvSceneSwitcher.hotkey.macro.unpause="Unpause macro %1"
|
||||||
|
|
||||||
AdvSceneSwitcher.askBackup="Detected a new version of the Advanced Scene Switcher.\nShould a backup of the old settings be created?"
|
AdvSceneSwitcher.askBackup="Detected a new version of the Advanced Scene Switcher.\nShould a backup of the old settings be created?"
|
||||||
|
|
||||||
@@ -402,13 +593,20 @@ AdvSceneSwitcher.browse="Browse"
|
|||||||
|
|
||||||
AdvSceneSwitcher.selectScene="--select scene--"
|
AdvSceneSwitcher.selectScene="--select scene--"
|
||||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||||
|
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||||
|
AdvSceneSwitcher.selectAnyScene="Any Scene"
|
||||||
AdvSceneSwitcher.currentTransition="Current Transition"
|
AdvSceneSwitcher.currentTransition="Current Transition"
|
||||||
|
AdvSceneSwitcher.anyTransition="Any Transition"
|
||||||
AdvSceneSwitcher.selectTransition="--select transition--"
|
AdvSceneSwitcher.selectTransition="--select transition--"
|
||||||
AdvSceneSwitcher.selectWindow="--select window--"
|
AdvSceneSwitcher.selectWindow="--select window--"
|
||||||
|
AdvSceneSwitcher.selectSource="--select source--"
|
||||||
AdvSceneSwitcher.selectAudioSource="--select audio source--"
|
AdvSceneSwitcher.selectAudioSource="--select audio source--"
|
||||||
AdvSceneSwitcher.selectVideoSource="--select video source--"
|
AdvSceneSwitcher.selectVideoSource="--select video source--"
|
||||||
AdvSceneSwitcher.selectMediaSource="--select media source--"
|
AdvSceneSwitcher.selectMediaSource="--select media source--"
|
||||||
AdvSceneSwitcher.selectProcess="--select process--"
|
AdvSceneSwitcher.selectProcess="--select process--"
|
||||||
|
AdvSceneSwitcher.selectFilter="--select filter--"
|
||||||
|
AdvSceneSwitcher.selectMacro="--select macro--"
|
||||||
|
AdvSceneSwitcher.selectItem="--select item--"
|
||||||
AdvSceneSwitcher.enterPath="--enter path--"
|
AdvSceneSwitcher.enterPath="--enter path--"
|
||||||
AdvSceneSwitcher.enterText="--enter text--"
|
AdvSceneSwitcher.enterText="--enter text--"
|
||||||
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="invalid entries will not be saved"
|
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="invalid entries will not be saved"
|
||||||
@@ -421,3 +619,7 @@ AdvSceneSwitcher.unit.milliseconds="milliseconds"
|
|||||||
AdvSceneSwitcher.unit.secends="seconds"
|
AdvSceneSwitcher.unit.secends="seconds"
|
||||||
AdvSceneSwitcher.unit.minutes="minutes"
|
AdvSceneSwitcher.unit.minutes="minutes"
|
||||||
AdvSceneSwitcher.unit.hours="hours"
|
AdvSceneSwitcher.unit.hours="hours"
|
||||||
|
AdvSceneSwitcher.duration.condition.none="No time constraint"
|
||||||
|
AdvSceneSwitcher.duration.condition.more="For at least"
|
||||||
|
AdvSceneSwitcher.duration.condition.equal="For exactly"
|
||||||
|
AdvSceneSwitcher.duration.condition.less="For at most"
|
||||||
|
|||||||
422
data/locale/ru-RU.ini
Normal file
422
data/locale/ru-RU.ini
Normal file
@@ -0,0 +1,422 @@
|
|||||||
|
AdvSceneSwitcher.pluginName="Advanced Scene Switcher"
|
||||||
|
AdvSceneSwitcher.windowTitle="Advanced Scene Switcher"
|
||||||
|
|
||||||
|
; General Tab
|
||||||
|
AdvSceneSwitcher.generalTab.title="Общие"
|
||||||
|
AdvSceneSwitcher.generalTab.status="Статус"
|
||||||
|
AdvSceneSwitcher.generalTab.status.hotkeytips="Горячие клавиши можно определить в настройках OBS"
|
||||||
|
AdvSceneSwitcher.generalTab.status.currentStatus="Advanced Scene Switcher сейчас:"
|
||||||
|
AdvSceneSwitcher.generalTab.status.onStartup="При запуске OBS:"
|
||||||
|
AdvSceneSwitcher.generalTab.status.onStartup.asLastRun="Запустить переключатель сцен, если он был запущен"
|
||||||
|
AdvSceneSwitcher.generalTab.status.onStartup.alwaysStart="Всегда запускать переключатель сцен"
|
||||||
|
AdvSceneSwitcher.generalTab.status.onStartup.doNotStart="Не запускать переключатель сцен"
|
||||||
|
AdvSceneSwitcher.generalTab.status.start="Старт"
|
||||||
|
AdvSceneSwitcher.generalTab.status.stop="Стоп"
|
||||||
|
AdvSceneSwitcher.generalTab.status.autoStart="Автоматически запускать переключатель сцен, когда:"
|
||||||
|
AdvSceneSwitcher.generalTab.status.autoStart.never="Никогда"
|
||||||
|
AdvSceneSwitcher.generalTab.status.autoStart.recording="Запись"
|
||||||
|
AdvSceneSwitcher.generalTab.status.autoStart.streaming="Вещание"
|
||||||
|
AdvSceneSwitcher.generalTab.status.autoStart.recordingAndStreaming="Запись или потоковое вещание"
|
||||||
|
AdvSceneSwitcher.generalTab.status.checkInterval="Проверять условия переключения каждый раз"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior="Общее поведение"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet="Если не выполняется условие переключения для"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip="Будет только настолько точным, насколько настроен интервал проверки."
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.dontSwitch="Не переключаться"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchToRandom="Переключиться на любую сцену на вкладке Random"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.onNoMet.switchTo="Переключиться на:"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.cooldown="После совпадения не переключаться между сценами в течение"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="В течение этого времени потенциальные совпадения будут игнорироваться!"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Включить ведение подробного журнала"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Сохранять положение и размер окна"
|
||||||
|
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Отключить подсказки пользовательского интерфейса"
|
||||||
|
AdvSceneSwitcher.generalTab.priority="Приоритет"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.description="Приоритет методов переключения (самый высокий приоритет - вверху)"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.threadPriority="Использовать приоритет потока"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.threadPriorityNotice="(Поднимать приоритет выше \"Нормальный\" не рекомендуется)"
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings="Сохранить / загрузить настройки"
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Экспорт"
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="Импорт"
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Экспортировать настройки расширенного переключателя сцен в файл ..."
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Импортировать настройки Advanced Scene Switcher из файла ..."
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Текстовые файлы (*.txt)"
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="Advanced Scene Switcher не удалось импортировать настройки"
|
||||||
|
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Настройки Advanced Scene Switcher импортированы успешно"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.fileContent="Содержание файла"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.sceneSequence="Последовательность сцены"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.idleDetection="Обнаружение простоя"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.executable="Исполняемый файл"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.screenRegion="Область экрана"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.windowTitle="Заголовок окна"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.media="Медиа"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.time="Время"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.audio="Аудио"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.video="Видео"
|
||||||
|
AdvSceneSwitcher.generalTab.priority.macro="Макрос"
|
||||||
|
|
||||||
|
; Macro Tab
|
||||||
|
AdvSceneSwitcher.macroTab.title="Макрос"
|
||||||
|
AdvSceneSwitcher.macroTab.macros="Макросы"
|
||||||
|
AdvSceneSwitcher.macroTab.help="Макросы позволяют выполнять ряд действий в зависимости от нескольких условий.\n\nНажмите на выделенный символ плюса, чтобы добавить новый макрос."
|
||||||
|
AdvSceneSwitcher.macroTab.editConditionHelp="Этот раздел позволяет определить условия макроса.\n\nВыберите существующий или добавьте новый макрос слева."
|
||||||
|
AdvSceneSwitcher.macroTab.editActionHelp="Этот раздел позволяет определить действия макроса.\n\n\nВыберите существующий или добавьте новый макрос слева."
|
||||||
|
AdvSceneSwitcher.macroTab.edit="Редактировать макрос"
|
||||||
|
AdvSceneSwitcher.macroTab.edit.logic="Тип логики:"
|
||||||
|
AdvSceneSwitcher.macroTab.edit.condition="Тип условия:"
|
||||||
|
AdvSceneSwitcher.macroTab.edit.action="Тип действия:"
|
||||||
|
AdvSceneSwitcher.macroTab.add="Добавить новый макрос"
|
||||||
|
AdvSceneSwitcher.macroTab.name="Имя:"
|
||||||
|
AdvSceneSwitcher.macroTab.defaultname="Макрос %1"
|
||||||
|
AdvSceneSwitcher.macroTab.exists="Имя макроса уже существует"
|
||||||
|
AdvSceneSwitcher.macroTab.copy="Создать копию"
|
||||||
|
; Macro Logic
|
||||||
|
AdvSceneSwitcher.logic.none="Игнорировать вход"
|
||||||
|
AdvSceneSwitcher.logic.and="И"
|
||||||
|
AdvSceneSwitcher.logic.or="Или"
|
||||||
|
AdvSceneSwitcher.logic.andNot="И не"
|
||||||
|
AdvSceneSwitcher.logic.orNot="Или нет"
|
||||||
|
AdvSceneSwitcher.logic.rootNone="Если"
|
||||||
|
AdvSceneSwitcher.logic.not="Если нет"
|
||||||
|
; Macro Conditions
|
||||||
|
AdvSceneSwitcher.condition.audio="Аудио"
|
||||||
|
AdvSceneSwitcher.ondition.audio.state.below="Ниже"
|
||||||
|
AdvSceneSwitcher.ondition.audio.state.above="Выше"
|
||||||
|
AdvSceneSwitcher.condition.audio.entry="Громкость {{audioSources}} равна {{condition}} {{volume}} в течении {{duration}} секунд"
|
||||||
|
AdvSceneSwitcher.condition.cursor="Область экрана"
|
||||||
|
AdvSceneSwitcher.condition.scene="Сцена"
|
||||||
|
AdvSceneSwitcher.condition.scene.type.current="Текущий"
|
||||||
|
AdvSceneSwitcher.condition.scene.type.previous="Предыдущий"
|
||||||
|
AdvSceneSwitcher.condition.scene.entry="{{sceneType}} сцена является {{scenes}} на {{duration}}"
|
||||||
|
AdvSceneSwitcher.condition.window="Окно"
|
||||||
|
AdvSceneSwitcher.condition.window.entry.line1="{{windows}} существует и ..."
|
||||||
|
AdvSceneSwitcher.condition.window.entry.line2="... это {{fullscreen}} полноэкранный {{maximized}} максимизированный {{focused}} сфокусированный"
|
||||||
|
AdvSceneSwitcher.condition.file="Файл"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line1="Содержимое {{fileType}} {{filePath}} {{browseButton}} соответствует:"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line2="{{matchText}}"
|
||||||
|
AdvSceneSwitcher.condition.file.entry.line3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||||
|
AdvSceneSwitcher.condition.media="Медиа"
|
||||||
|
AdvSceneSwitcher.condition.media.entry="{{mediaSources}} состояние {{states}} и {{timeRestrictions}} {{time}}"
|
||||||
|
AdvSceneSwitcher.condition.video="Видео"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.match="точно соответствует"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.differ="не совпадает"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.hasChanged="изменилось"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.hasNotChanged="не изменилось"
|
||||||
|
AdvSceneSwitcher.condition.video.condition.noImage="не имеет вывода"
|
||||||
|
AdvSceneSwitcher.condition.video.askFileAction="Вы хотите использовать существующий файл или создать скриншот текущего выбранного источника?"
|
||||||
|
AdvSceneSwitcher.condition.video.askFileAction.file="Использовать существующий файл"
|
||||||
|
AdvSceneSwitcher.condition.video.askFileAction.screenshot="Создать скриншот"
|
||||||
|
AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{filePath}} {{browseButton}} для {{duration}}"
|
||||||
|
AdvSceneSwitcher.condition.stream="Потоковое вещание"
|
||||||
|
AdvSceneSwitcher.condition.stream.state.start="Поток запущен"
|
||||||
|
AdvSceneSwitcher.condition.stream.state.stop="Поток остановлен"
|
||||||
|
AdvSceneSwitcher.condition.stream.entry="{{streamState}} для {{duration}}"
|
||||||
|
AdvSceneSwitcher.condition.record="Запись"
|
||||||
|
AdvSceneSwitcher.condition.record.state.start="Запись запущена"
|
||||||
|
AdvSceneSwitcher.condition.record.state.pause="Запись приостановлена"
|
||||||
|
AdvSceneSwitcher.condition.record.state.stop="Запись остановлена"
|
||||||
|
AdvSceneSwitcher.condition.record.entry="{{recordState}} для {{duration}}"
|
||||||
|
AdvSceneSwitcher.condition.process="Процесс"
|
||||||
|
AdvSceneSwitcher.condition.process.entry="{{processes}} запущен {{focused}} и сфокусирован"
|
||||||
|
AdvSceneSwitcher.condition.idle="Простой"
|
||||||
|
AdvSceneSwitcher.condition.idle.entry="Не было ни клавиатуры, ни мыши в течении{{duration}}"
|
||||||
|
AdvSceneSwitcher.condition.pluginState="Состояние плагина"
|
||||||
|
AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Автоматическая смена сцены была запущена в этом интервале"
|
||||||
|
AdvSceneSwitcher.condition.pluginState.entry="{{condition}}"
|
||||||
|
|
||||||
|
; Macro Actions
|
||||||
|
AdvSceneSwitcher.action.switchScene="Переключить сцену"
|
||||||
|
AdvSceneSwitcher.action.scene.entry="Перейти к сцене {{scenes}} используя {{transitions}} с продолжительностью {{duration}} секунд"
|
||||||
|
AdvSceneSwitcher.action.wait="Подождать"
|
||||||
|
AdvSceneSwitcher.action.wait.type.fixed="фиксированный"
|
||||||
|
AdvSceneSwitcher.action.wait.type.random="случайный"
|
||||||
|
AdvSceneSwitcher.action.wait.entry.fixed="Ожидать {{waitType}} в течении {{duration}}"
|
||||||
|
AdvSceneSwitcher.action.wait.entry.random="Ожидание {{waitType}} длительностью от {{duration}} до {{duration2}}"
|
||||||
|
AdvSceneSwitcher.action.audio="Аудио"
|
||||||
|
AdvSceneSwitcher.action.audio.type.mute="Замьютить"
|
||||||
|
AdvSceneSwitcher.action.audio.type.unmute="Размьютить"
|
||||||
|
AdvSceneSwitcher.action.audio.type.sourceVolume="Установить громкость источника"
|
||||||
|
AdvSceneSwitcher.action.audio.type.masterVolume="Установить главную громкость"
|
||||||
|
AdvSceneSwitcher.action.audio.entry="{{actions}} {{audioSources}} {{volume}}"
|
||||||
|
AdvSceneSwitcher.action.recording="Запись"
|
||||||
|
AdvSceneSwitcher.action.recording.type.stop="Остановить запись"
|
||||||
|
AdvSceneSwitcher.action.recording.type.start="Начать запись"
|
||||||
|
AdvSceneSwitcher.action.recording.type.pause="Пауза записи"
|
||||||
|
AdvSceneSwitcher.action.recording.type.unpause="Снять запись с паузы"
|
||||||
|
AdvSceneSwitcher.action.recording.pause.hint="Обратите внимание, что в зависимости от настроек записи вы можете не иметь возможности приостановить запись"
|
||||||
|
AdvSceneSwitcher.action.recording.entry="{{actions}}{{pauseHint}}"
|
||||||
|
AdvSceneSwitcher.action.replay="Буфер воспроизведения"
|
||||||
|
AdvSceneSwitcher.action.replay.type.stop="Остановить буфер воспроизведения"
|
||||||
|
AdvSceneSwitcher.action.replay.type.start="Начать воспроизведение буфера"
|
||||||
|
AdvSceneSwitcher.action.replay.type.save="Сохранить буфер воспроизведения"
|
||||||
|
AdvSceneSwitcher.action.replay.entry="{{actions}}"
|
||||||
|
AdvSceneSwitcher.action.streaming="Потоковое вещание"
|
||||||
|
AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание"
|
||||||
|
AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание"
|
||||||
|
AdvSceneSwitcher.action.streaming.entry="{{actions}}"
|
||||||
|
AdvSceneSwitcher.action.run="Запустить"
|
||||||
|
AdvSceneSwitcher.action.run.entry="Запустить {{filePath}} {{browseButton}}"
|
||||||
|
|
||||||
|
|
||||||
|
; Transition Tab
|
||||||
|
AdvSceneSwitcher.transitionTab.title="Переход"
|
||||||
|
AdvSceneSwitcher.transitionTab.setTransitionBy="При изменении переходов:"
|
||||||
|
AdvSceneSwitcher.transitionTab.transitionOverride="Установить переопределение переходов"
|
||||||
|
AdvSceneSwitcher.transitionTab.adjustActiveTransitionType="Изменить тип активного перехода"
|
||||||
|
AdvSceneSwitcher.transitionTab.transitionBehaviorSelectionError="Должна быть включена хотя бы одна опция:\n\n - Использовать переопределения переходов\n\n - Изменить тип активного перехода"
|
||||||
|
AdvSceneSwitcher.transitionTab.transitionForAToB="Использовать переход для автоматического переключения сцены со сцены A на сцену B"
|
||||||
|
AdvSceneSwitcher.transitionTab.transitionsHelp="<html><head/><body><p>Эти настройки <span style=\"font-style:italic;\">только</span> влияют на переходы, вызванные переключателем сцен - Проверьте <a href=\"https://obsproject.com/forum/resources/transition-table.1174/\"><span style=\" text-decoration: underline; color:#268bd2;\">Transition Table</span></a> если вы хотите настроить его для ручного изменения сцены.<br/>Настройки, определенные здесь, имеют приоритет над настройками перехода, сконфигурированными в других местах переключателя сцен.<br/><br/>Нажмите на символ плюса ниже, чтобы добавить новую запись.</p></body></html>"
|
||||||
|
AdvSceneSwitcher.transitionTab.defaultTransition="Изменить переход, если сцена активна"
|
||||||
|
AdvSceneSwitcher.transitionTab.entry="Переход от {{scenes}} к {{scenes2}} с помощью {{transitions}} с длительностью {{duration}}"
|
||||||
|
AdvSceneSwitcher.transitionTab.defaultTransitionEntry="Когда сцена {{scenes}} активна, изменить переход сцены по умолчанию на {{transitions}}"
|
||||||
|
AdvSceneSwitcher.transitionTab.defaultTransitionsHelp="Нажмите на символ плюса, чтобы добавить запись."
|
||||||
|
AdvSceneSwitcher.transitionTab.defaultTransition.delay="Переключить переход {{defTransitionDelay}} после смены сцены."
|
||||||
|
AdvSceneSwitcher.transitionTab.defaultTransition.delay.help="Задержка используется для того, чтобы избежать отмены переключения сцены, что может произойти, если тип перехода будет изменен, когда переход еще продолжается."
|
||||||
|
|
||||||
|
; Pause Scenes Tab
|
||||||
|
AdvSceneSwitcher.pauseTab.title="Пауза"
|
||||||
|
AdvSceneSwitcher.pauseTab.pauseOnScene="Приостановить Scene Switcher на сцене"
|
||||||
|
AdvSceneSwitcher.pauseTab.pauseInFocus1="Приостановить Scene Switcher когда "
|
||||||
|
AdvSceneSwitcher.pauseTab.pauseInFocus2="находится в фокусе"
|
||||||
|
AdvSceneSwitcher.pauseTab.pauseTypeScene="сцена активна"
|
||||||
|
AdvSceneSwitcher.pauseTab.pauseTypeWindow="окно в фокусе"
|
||||||
|
AdvSceneSwitcher.pauseTab.pauseTargetAll="все"
|
||||||
|
AdvSceneSwitcher.pauseTab.pauseEntry="Пауза {{pauseTargets}} проверяет, когда {{pauseTypes}} {{scenes}} {{windows}}"
|
||||||
|
AdvSceneSwitcher.pauseTab.help="На этой вкладке вы можете настроить приостановку отдельных методов переключения, если сцена активна или окно находится в фокусе.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Window Title Tab
|
||||||
|
AdvSceneSwitcher.windowTitleTab.title="Название"
|
||||||
|
AdvSceneSwitcher.windowTitleTab.regexrDescription="<html><head/><body><p>Введите либо прямые заголовки окон, либо правильное регулярное выражение. Вы можете проверить синтаксис и соответствие регулярных выражений, используя <a href=\"https://regexr.com\"><span style=\" text-decoration: underline; color:#268bd2;\">RegExr</span></a></p></body></html>"
|
||||||
|
AdvSceneSwitcher.windowTitleTab.stayInFocus1="Игнорировать имя этого окна"
|
||||||
|
AdvSceneSwitcher.windowTitleTab.stayInFocus2=" "
|
||||||
|
AdvSceneSwitcher.windowTitleTab.fullscreen="if fullscreen"
|
||||||
|
AdvSceneSwitcher.windowTitleTab.maximized="if maximized"
|
||||||
|
AdvSceneSwitcher.windowTitleTab.focused="if focused"
|
||||||
|
AdvSceneSwitcher.windowTitleTab.entry="{{windows}} {{scenes}} {{transitions}} {{fullscreen}} {{maximized}} {{focused}}"
|
||||||
|
AdvSceneSwitcher.windowTitleTab.windowsHelp="Переключение сцен на основе заголовков окон запущенных приложений.\nВы можете выбрать следующие дополнительные условия:\nОкно полноэкранное\nОкно максимизированное\nОкно сфокусированное\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
AdvSceneSwitcher.windowTitleTab.ignoreWindowsHelp="Если заголовок окна игнорируется, переключатель сцен будет действовать так, как будто ранее выбранное окно все еще в фокусе.\nЭто позволит вам избежать переключения сцен, если вы часто переключаетесь на другое окно, которое не должно вызывать смену сцены.\n\nВыберите окно или введите заголовок окна выше и нажмите на символ плюса ниже, чтобы добавить его в список."
|
||||||
|
|
||||||
|
; Executable Tab
|
||||||
|
AdvSceneSwitcher.executableTab.title="Исполняемый"
|
||||||
|
AdvSceneSwitcher.executableTab.implemented="Implemented by dasOven"
|
||||||
|
AdvSceneSwitcher.executableTab.requiresFocus="только если сфокусирован"
|
||||||
|
AdvSceneSwitcher.executableTab.entry="Когда {{processes}} запущены, переключить на {{scenes}} используя {{transitions}} {{requiresFocus}}"
|
||||||
|
AdvSceneSwitcher.executableTab.help="Эта вкладка позволит вам автоматически переключаться между сценами, если запущен процесс.\nЭто может быть полезно в ситуациях, когда имя окна может измениться или неизвестно.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Screen Region Tab
|
||||||
|
AdvSceneSwitcher.screenRegionTab.title="Регион"
|
||||||
|
AdvSceneSwitcher.screenRegionTab.currentPosition="Курсор в данный момент находится в:"
|
||||||
|
AdvSceneSwitcher.screenRegionTab.showGuideFrames="Показать направляющие кадры"
|
||||||
|
AdvSceneSwitcher.screenRegionTab.hideGuideFrames="Скрыть направляющие рамки"
|
||||||
|
AdvSceneSwitcher.screenRegionTab.excludeScenes.None="Нет выбора"
|
||||||
|
AdvSceneSwitcher.screenRegionTab.entry="Если курсор находится в {{minX}} {{minY}} x {{maxX}} {{maxY}} переключить на {{scenes}} используя {{transitions}} если не указано {{excludeScenes}}"
|
||||||
|
AdvSceneSwitcher.screenRegionTab.help="Эта вкладка позволит вам автоматически переключать сцены, основываясь на текущем положении курсора мыши.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Media Tab
|
||||||
|
AdvSceneSwitcher.mediaTab.title="Медиа"
|
||||||
|
AdvSceneSwitcher.mediaTab.implemented="Implemented by Exeldro"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.none="Нет"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.playing="Играет"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.opening="Открытие"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.buffering="Буферизация"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.Paused="Приостановлено"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.stopped="Остановлено"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.ended="Закончилось"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.error="Ошибка"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.playedToEnd="Воспроизведено до конца"
|
||||||
|
AdvSceneSwitcher.mediaTab.states.any="Любой"
|
||||||
|
AdvSceneSwitcher.mediaTab.timeRestriction.none="Нет"
|
||||||
|
AdvSceneSwitcher.mediaTab.timeRestriction.shorter="Время короче"
|
||||||
|
AdvSceneSwitcher.mediaTab.timeRestriction.longer="Время больше"
|
||||||
|
AdvSceneSwitcher.mediaTab.timeRestriction.remainShorter="Оставшееся время короче"
|
||||||
|
AdvSceneSwitcher.mediaTab.timeRestriction.remainLonger="Время, оставшееся дольше"
|
||||||
|
AdvSceneSwitcher.mediaTab.entry="Когда состояние {{mediaSources}} равно {{states}} и {{timeRestrictions}} {{time}} переключиться на {{scenes}} используя {{transitions}}"
|
||||||
|
AdvSceneSwitcher.mediaTab.help="Эта вкладка позволит вам переключать сцены на основе состояний медиаисточников.\nНапример, вы можете автоматически переключиться на предыдущую сцену, когда выбранный медиаисточник закончил свое воспроизведение.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; File Tab
|
||||||
|
AdvSceneSwitcher.fileTab.title="Файл"
|
||||||
|
AdvSceneSwitcher.fileTab.readWriteSceneFile="Считать / записать сцену из / в файл"
|
||||||
|
AdvSceneSwitcher.fileTab.currentSceneOutputFile="Записать имя текущей сцены в этот файл:"
|
||||||
|
AdvSceneSwitcher.fileTab.switchSceneBaseOnFile="Включить переключение сцен на основе ввода файла"
|
||||||
|
AdvSceneSwitcher.fileTab.switchSceneNameInputFile="Считать имя сцены, на которую нужно переключиться, из этого файла:"
|
||||||
|
AdvSceneSwitcher.fileTab.switchSceneBaseOnFileContent="Переключать сцену на основе содержимого файла"
|
||||||
|
AdvSceneSwitcher.fileTab.remoteFileWarning="Обратите внимание, что при выборе опции remote переключатель сцен будет пытаться получить доступ к удаленному местоположению каждые x мс, как указано на вкладке Общие"
|
||||||
|
AdvSceneSwitcher.fileTab.remoteFileWarning1="Обратите внимание, что переключатель сцены будет пытаться получить доступ к удаленному местоположению каждые "
|
||||||
|
AdvSceneSwitcher.fileTab.remoteFileWarning2="ms"
|
||||||
|
AdvSceneSwitcher.fileTab.libcurlWarning="Не удалось загрузить libcurl! Доступ к удаленным файлам невозможен!"
|
||||||
|
AdvSceneSwitcher.fileTab.selectWrite="Выберите файл для записи в ..."
|
||||||
|
AdvSceneSwitcher.fileTab.selectRead="Выберите файл для чтения из ..."
|
||||||
|
AdvSceneSwitcher.fileTab.textFileType="Текстовые файлы (*.txt)"
|
||||||
|
AdvSceneSwitcher.fileTab.anyFileType="Любые файлы (*.*)"
|
||||||
|
AdvSceneSwitcher.fileTab.remote="удаленный файл"
|
||||||
|
AdvSceneSwitcher.fileTab.local="локальный файл"
|
||||||
|
AdvSceneSwitcher.fileTab.useRegExp="использовать регулярные выражения (сопоставление шаблонов)"
|
||||||
|
AdvSceneSwitcher.fileTab.checkfileContentTime="если дата модификации изменена"
|
||||||
|
AdvSceneSwitcher.fileTab.checkfileContent="если содержимое изменено"
|
||||||
|
AdvSceneSwitcher.fileTab.entry="Переключиться на {{scenes}} используя {{transitions}} если содержимое {{fileType}} {{filePath}} {{browseButton}} совпадает:"
|
||||||
|
AdvSceneSwitcher.fileTab.entry2="{{matchText}}"
|
||||||
|
AdvSceneSwitcher.fileTab.entry3="{{useRegex}} {{checkModificationDate}} {{checkFileContent}}"
|
||||||
|
AdvSceneSwitcher.fileTab.help="Эта вкладка позволит вам автоматически переключать сцены на основе содержимого удаленных или локальных файлов.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Random Tab
|
||||||
|
AdvSceneSwitcher.randomTab.title="Рандом"
|
||||||
|
AdvSceneSwitcher.randomTab.randomDisabledWarning="Функциональность отключена - для активации выберите \"Если условие переключения не выполнено, переключиться на любую сцену на вкладке Random\" на вкладке Общие"
|
||||||
|
AdvSceneSwitcher.randomTab.entry="Если условие переключения не выполнено, переключиться на {{scenes}} используя {{transitions}} для {{delay}}"
|
||||||
|
AdvSceneSwitcher.randomTab.help="Переключатель сцен будет случайным образом выбирать запись на этой вкладке для переключения на заданное время.\nЗаметьте, что одна и та же запись не будет выбрана дважды подряд.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Time Tab
|
||||||
|
AdvSceneSwitcher.timeTab.title="Время"
|
||||||
|
AdvSceneSwitcher.timeTab.anyDay="В любой день"
|
||||||
|
AdvSceneSwitcher.timeTab.mondays="По понедельникам"
|
||||||
|
AdvSceneSwitcher.timeTab.tuesdays="По вторникам"
|
||||||
|
AdvSceneSwitcher.timeTab.wednesdays="По средам"
|
||||||
|
AdvSceneSwitcher.timeTab.thursdays="По четвергам"
|
||||||
|
AdvSceneSwitcher.timeTab.fridays="По пятницам"
|
||||||
|
AdvSceneSwitcher.timeTab.saturdays="По субботам"
|
||||||
|
AdvSceneSwitcher.timeTab.sundays="По воскресеньям"
|
||||||
|
AdvSceneSwitcher.timeTab.afterstart="После начала потокового вещания/записи"
|
||||||
|
AdvSceneSwitcher.timeTab.afterstart.tip="Будет использоваться время относительно начала потокового вещания/записи"
|
||||||
|
AdvSceneSwitcher.timeTab.entry="{{triggers}} в {{time}} переключаются на {{scenes}} используя {{transitions}}"
|
||||||
|
AdvSceneSwitcher.timeTab.help="Эта вкладка позволит вам автоматически переключаться на другую сцену на основе текущего местного времени.\n\nЗаметьте, что переключатель сцен будет переключаться только в точное время, которое вы указали.\nУбедитесь, что вы настроили параметры приоритета на вкладке Общие по своему вкусу, чтобы выбранная временная точка не была пропущена из-за других методов переключения, имеющих более высокий приоритет.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Idle Tab
|
||||||
|
AdvSceneSwitcher.idleTab.title="Бездействие"
|
||||||
|
AdvSceneSwitcher.idleTab.enable="Включить обнаружение простоя"
|
||||||
|
AdvSceneSwitcher.idleTab.idleswitch="После {{duration}} отсутствия ввода с клавиатуры или мыши переключиться на сцену {{scenes}} используя {{transitions}}"
|
||||||
|
AdvSceneSwitcher.idleTab.dontSwitchIfFocus1="Не переключаться, если"
|
||||||
|
AdvSceneSwitcher.idleTab.dontSwitchIfFocus2="находится в фокусе"
|
||||||
|
|
||||||
|
; Scene Sequence Tab
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.title="Последовательность"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.description="Последовательность автоматического переключения сцен может быть отменена либо паузой/остановкой переключателя сцен, либо ручным переключением на другую сцену"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.save="Сохранить последовательность сцен в файл"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.load="Загрузить последовательности сцен из файла"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.saveTitle="Сохранить последовательность сцен в файл ..."
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.loadTitle="Выберите файл для чтения последовательности сцен из файла ..."
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.loadFail="Advanced Scene Switcher не удалось импортировать настройки!"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.loadSuccess="Настройки Advanced Scene Switcher импортированы успешно!"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.fileType="Текстовые файлы (*.txt)"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.interruptible="прервать"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.interruptibleHint="Другие методы переключения разрешены для прерывания этой последовательности сцен"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.entry="Когда {{startScenes}} активен, переключить на {{scenes}} после {{delay}} используя {{transitions}} {{interruptible}}"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.extendEdit="Расширить последовательность"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.extendEntry="После {{delay}} переключиться на {{scenes}} используя {{transitions}}"
|
||||||
|
AdvSceneSwitcher.sceneSequenceTab.help="Эта вкладка позволит вам автоматически переключаться на другую сцену, если сцена была активна в течение заданного периода времени.\nНапример, вы можете автоматически переключаться между двумя сценами.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Audio Tab
|
||||||
|
AdvSceneSwitcher.audioTab.title="Аудио"
|
||||||
|
AdvSceneSwitcher.audioTab.condition.above="выше"
|
||||||
|
AdvSceneSwitcher.audioTab.condition.below="ниже"
|
||||||
|
AdvSceneSwitcher.audioTab.ignoreInactiveSource="если источник неактивен"
|
||||||
|
AdvSceneSwitcher.audioTab.entry="Когда громкость {{audioSources}} равна {{condition}} {{volumeWidget}} в течение {{duration}} секунд переключить на {{scenes}} используя {{transitions}} {{ignoreInactiveSource}}"
|
||||||
|
AdvSceneSwitcher.audioTab.multiMatchfallbackCondition="Если несколько записей совпадают ..."
|
||||||
|
AdvSceneSwitcher.audioTab.multiMatchfallback="... в течение {{duration}} секунд переключить на {{scenes}} используя {{transitions}}"
|
||||||
|
AdvSceneSwitcher.audioTab.help="Эта вкладка позволит вам переключать сцены в зависимости от громкости источников.\nНапример, вы можете автоматически переключиться на другую сцену, если громкость вашего микрофона достигнет определенного порога.\n\nНажмите на выделенный символ плюса, чтобы продолжить."
|
||||||
|
|
||||||
|
; Video Tab
|
||||||
|
AdvSceneSwitcher.videoTab.title="Видео"
|
||||||
|
AdvSceneSwitcher.videoTab.getScreenshot="Получить снимок экрана для выбранной записи"
|
||||||
|
AdvSceneSwitcher.videoTab.getScreenshotHelp="Получить скриншот источника видео текущей выбранной записи и автоматически установить его в качестве целевого изображени"
|
||||||
|
AdvSceneSwitcher.videoTab.condition.match="точно соответствует"
|
||||||
|
AdvSceneSwitcher.videoTab.condition.match.tooltip="Точное совпадение требует, чтобы целевое и исходное изображение имели одинаковое разрешение.\nДаже каждый пиксель должен совпадать, поэтому не рекомендуется использовать форматы изображений, которые используют сжатие (например, .JPG)!"
|
||||||
|
AdvSceneSwitcher.videoTab.condition.differ="не совпадает"
|
||||||
|
AdvSceneSwitcher.videoTab.condition.hasNotChanged="не изменилось"
|
||||||
|
AdvSceneSwitcher.videoTab.condition.hasChanged="изменилось"
|
||||||
|
AdvSceneSwitcher.videoTab.ignoreInactiveSource="если источник неактивен"
|
||||||
|
AdvSceneSwitcher.videoTab.entry="Когда {{videoSources}} {{condition}} {{filePath}} {{browseButton}} для {{duration}} переключиться на {{scenes}} используя {{transitions}} {{ignoreInactiveSource}}"
|
||||||
|
AdvSceneSwitcher.videoTab.help="<html><head/><body><p>Эта вкладка позволит вам переключать сцены на основе текущего видеовыхода выбранных источников.<br/>Обязательно проверьте <a href=\"https://obsproject.com/forum/resources/pixel-match-switcher.1202/\"><span style=\" text-decoration: underline; color:#268bd2;\">Pixel Match Switcher</span></a> для еще лучшей реализации этой функциональности.<br/><br/> Нажмите на выделенный символ плюса, чтобы продолжить.</p></body></html>"
|
||||||
|
|
||||||
|
; Network Tab
|
||||||
|
AdvSceneSwitcher.networkTab.title="Сеть"
|
||||||
|
AdvSceneSwitcher.networkTab.warning="Запуск сервера вне локальной сети позволит третьим лицам читать активную сцену."
|
||||||
|
AdvSceneSwitcher.networkTab.DisabledWarning="ту функциональность, к сожалению, пришлось отключить на macOS из-за несовместимости библиотек при параллельном запуске плагина obs-websocket."
|
||||||
|
AdvSceneSwitcher.networkTab.server="Запустить сервер (отправляет сообщения о переключении сцены всем подключенным клиентам)"
|
||||||
|
AdvSceneSwitcher.networkTab.server.port="Порт"
|
||||||
|
AdvSceneSwitcher.networkTab.server.lockToIPv4="Заблокировать сервер на использование только IPv4"
|
||||||
|
AdvSceneSwitcher.networkTab.server.restrictSendToAutomatedSwitches="Отправлять сообщения только для автоматических переключателей сцен"
|
||||||
|
AdvSceneSwitcher.networkTab.startFailed.message="Сервер WebSockets не удалось запустить, возможно потому, что:\n - TCP порт %1 может в настоящее время использоваться в другом месте в этой системе, возможно, другим приложением. Попробуйте установить другой TCP порт в настройках сервера WebSocket, или остановите любое приложение, которое может использовать этот порт.\n - Сообщение об ошибке: %2"
|
||||||
|
AdvSceneSwitcher.networkTab.server.status.currentStatus="Текущий статус"
|
||||||
|
AdvSceneSwitcher.networkTab.server.status.notRunning="Не запущен"
|
||||||
|
AdvSceneSwitcher.networkTab.server.status.starting="Запуск"
|
||||||
|
AdvSceneSwitcher.networkTab.server.status.running="Работает"
|
||||||
|
AdvSceneSwitcher.networkTab.server.restart="Перезапустить сервер"
|
||||||
|
AdvSceneSwitcher.networkTab.client="Запустить клиент (Получает сообщения о переключении сцен)"
|
||||||
|
AdvSceneSwitcher.networkTab.client.address="Имя хоста или IP-адрес"
|
||||||
|
AdvSceneSwitcher.networkTab.client.port="Порт"
|
||||||
|
AdvSceneSwitcher.networkTab.client.status.currentStatus="Текущий статус"
|
||||||
|
AdvSceneSwitcher.networkTab.client.status.disconnected="Отключено"
|
||||||
|
AdvSceneSwitcher.networkTab.client.status.connecting="Подключение"
|
||||||
|
AdvSceneSwitcher.networkTab.client.status.connected="Подключено"
|
||||||
|
AdvSceneSwitcher.networkTab.client.reconnect="Принудительное переподключение"
|
||||||
|
|
||||||
|
; Scene Group Tab
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.title="Группа сцен"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.list="Группы сцен"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit="Редактировать группы сцен"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit.name="Имя:"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit.type="Тип: {{type}}"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.type.count="Количество"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.type.time="Время"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.type.random="Случайно"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit.count="Переход к следующей сцене в списке после {{count}} совпадений"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit.time="Переход к следующей сцене в списке по истечении {{time}}"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit.random="Выбирать следующую сцену в списке случайным образом"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit.repeat="Начинать с начала, если достигнут конец списка сцен"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.edit.addScene="Добавить сцену"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.add="Добавить группу сцен"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.defaultname="Группа сцен %1"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.exists="Группа сцен или название сцены уже существует"
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.help="Группы сцен могут быть выбраны в качестве цели так же, как и обычные сцены.\n\nКак следует из названия, группа сцен представляет собой набор из нескольких сцен.\nГруппа сцен будет продвигаться по списку назначенных ей сцен в зависимости от настроенных параметров, которые можно найти справа.\n\nВы можете настроить группу сцен на переход к следующей сцене в списке:\nПосле определенного количества раз, когда группа сцен выбрана в качестве цели.\nПо истечении определенного времени.\nИли случайным образом.\n\nНапример, группа сцен, содержащая сцены ...\nScene 1\nScene 2\nScene 3 \n... активирует \"Scene 1\" в первый раз, когда он выбран в качестве цели.\nВо второй раз он активируется \"Scene 2\".\nОставшееся время \"Scene 3\" будет активирован.\n\nНажмите на выделенный символ плюса ниже, чтобы добавить новую группу сцен."
|
||||||
|
AdvSceneSwitcher.sceneGroupTab.scenes.help="Выберите группу сцен, которую вы хотите изменить слева.\n\nВыберите сцену для добавления в эту группу сцен, выбрав сцену выше и нажав на символ плюса ниже.\n\nСцена может быть добавлена несколько раз в одну и ту же группу сцен."
|
||||||
|
|
||||||
|
; Scene Trigger Tab
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.title="Триггеры сцены"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none="--выбрать триггер--"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneActive="активен"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneInactive="не активен"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.sceneLeave="переключился с"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.none="--выбрать действие--"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startRecording="начать запись"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.pauseRecording="приостановить запись"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.unpauseRecording="отменить паузу записи"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopRecording="остановить запись"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopStreaming="остановить потоковое вещание"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startStreaming="начать потоковое вещание"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startReplayBuffer="запустить буфер воспроизведения"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopReplayBuffer="остановить буфер воспроизведения"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.muteSource="отключить источник"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.unmuteSource="включить источник"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.startSwitcher="запустить переключатель сцены"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.stopSwitcher="остановить переключатель сцены"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.entry="Когда {{scenes}} {{triggers}} {{actions}} {{audioSources}} после {{duration}}"
|
||||||
|
AdvSceneSwitcher.sceneTriggerTab.help="Эта вкладка позволяет запускать действия при изменении сцены, например, остановку записи или потоковой передачи."
|
||||||
|
|
||||||
|
; Hotkey
|
||||||
|
AdvSceneSwitcher.hotkey.startSwitcherHotkey="Запустить Advanced Scene Switcher"
|
||||||
|
AdvSceneSwitcher.hotkey.stopSwitcherHotkey="становить Advanced Scene Switcher"
|
||||||
|
AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Переключить старт/стоп для Advanced Scene Switcher"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.askBackup="Обнаружена новая версия Advanced Scene Switcher.\nНужно ли создать резервную копию старых настроек?"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.close="Закрыть"
|
||||||
|
AdvSceneSwitcher.browse="Обзор"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.selectScene="--выбрать сцену--"
|
||||||
|
AdvSceneSwitcher.selectPreviousScene="Предыдущая сцена"
|
||||||
|
AdvSceneSwitcher.currentTransition="Текущий переход"
|
||||||
|
AdvSceneSwitcher.selectTransition="--выбрать переход--"
|
||||||
|
AdvSceneSwitcher.selectWindow="--выбрать окно--"
|
||||||
|
AdvSceneSwitcher.selectAudioSource="--выбрать источник звука--"
|
||||||
|
AdvSceneSwitcher.selectVideoSource="--sвыбрать источник видео--"
|
||||||
|
AdvSceneSwitcher.selectMediaSource="--выбрать источник мультимедиа--"
|
||||||
|
AdvSceneSwitcher.selectProcess="--выбрать процесс--"
|
||||||
|
AdvSceneSwitcher.enterPath="--ввести путь--"
|
||||||
|
AdvSceneSwitcher.enterText="--ввести текст--"
|
||||||
|
AdvSceneSwitcher.invaildEntriesWillNotBeSaved="недействительные записи не будут сохранены"
|
||||||
|
AdvSceneSwitcher.selectWindowTip="Используйте \"OBS\" для указания окна OBS\nИспользуйте \"Переключение задач\"для указания ALT + TAB"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.status.active="Активный"
|
||||||
|
AdvSceneSwitcher.status.inactive="Неактивен"
|
||||||
|
|
||||||
|
AdvSceneSwitcher.unit.milliseconds="миллисекунды"
|
||||||
|
AdvSceneSwitcher.unit.secends="секунды"
|
||||||
|
AdvSceneSwitcher.unit.minutes="минуты"
|
||||||
|
AdvSceneSwitcher.unit.hours="часы"
|
||||||
15452
data/res/cascadeClassifiers/haarcascade_eye.xml
Normal file
15452
data/res/cascadeClassifiers/haarcascade_eye.xml
Normal file
File diff suppressed because it is too large
Load Diff
33158
data/res/cascadeClassifiers/haarcascade_eye_tree_eyeglasses.xml
Normal file
33158
data/res/cascadeClassifiers/haarcascade_eye_tree_eyeglasses.xml
Normal file
File diff suppressed because it is too large
Load Diff
26161
data/res/cascadeClassifiers/haarcascade_frontalface_alt.xml
Normal file
26161
data/res/cascadeClassifiers/haarcascade_frontalface_alt.xml
Normal file
File diff suppressed because it is too large
Load Diff
23550
data/res/cascadeClassifiers/haarcascade_frontalface_alt2.xml
Normal file
23550
data/res/cascadeClassifiers/haarcascade_frontalface_alt2.xml
Normal file
File diff suppressed because it is too large
Load Diff
103493
data/res/cascadeClassifiers/haarcascade_frontalface_alt_tree.xml
Normal file
103493
data/res/cascadeClassifiers/haarcascade_frontalface_alt_tree.xml
Normal file
File diff suppressed because it is too large
Load Diff
35712
data/res/cascadeClassifiers/haarcascade_frontalface_default.xml
Normal file
35712
data/res/cascadeClassifiers/haarcascade_frontalface_default.xml
Normal file
File diff suppressed because it is too large
Load Diff
18118
data/res/cascadeClassifiers/haarcascade_fullbody.xml
Normal file
18118
data/res/cascadeClassifiers/haarcascade_fullbody.xml
Normal file
File diff suppressed because it is too large
Load Diff
9803
data/res/cascadeClassifiers/haarcascade_lefteye_2splits.xml
Normal file
9803
data/res/cascadeClassifiers/haarcascade_lefteye_2splits.xml
Normal file
File diff suppressed because it is too large
Load Diff
15085
data/res/cascadeClassifiers/haarcascade_lowerbody.xml
Normal file
15085
data/res/cascadeClassifiers/haarcascade_lowerbody.xml
Normal file
File diff suppressed because it is too large
Load Diff
31930
data/res/cascadeClassifiers/haarcascade_profileface.xml
Normal file
31930
data/res/cascadeClassifiers/haarcascade_profileface.xml
Normal file
File diff suppressed because it is too large
Load Diff
9833
data/res/cascadeClassifiers/haarcascade_righteye_2splits.xml
Normal file
9833
data/res/cascadeClassifiers/haarcascade_righteye_2splits.xml
Normal file
File diff suppressed because it is too large
Load Diff
29767
data/res/cascadeClassifiers/haarcascade_upperbody.xml
Normal file
29767
data/res/cascadeClassifiers/haarcascade_upperbody.xml
Normal file
File diff suppressed because it is too large
Load Diff
3
data/res/time.svg
Normal file
3
data/res/time.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#d2d2d2" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
1
deps/opencv
vendored
Submodule
1
deps/opencv
vendored
Submodule
Submodule deps/opencv added at ad6e82942b
107
external/FindLibObs.cmake
vendored
107
external/FindLibObs.cmake
vendored
@@ -1,107 +0,0 @@
|
|||||||
# This module can be copied and used by external plugins for OBS
|
|
||||||
#
|
|
||||||
# Once done these will be defined:
|
|
||||||
#
|
|
||||||
# LIBOBS_FOUND
|
|
||||||
# LIBOBS_INCLUDE_DIRS
|
|
||||||
# LIBOBS_LIBRARIES
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
if (PKG_CONFIG_FOUND)
|
|
||||||
pkg_check_modules(_OBS QUIET obs libobs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(_lib_suffix 64)
|
|
||||||
else()
|
|
||||||
set(_lib_suffix 32)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(DEFINED CMAKE_BUILD_TYPE)
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
set(_build_type_base "debug")
|
|
||||||
else()
|
|
||||||
set(_build_type_base "release")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_path(LIBOBS_INCLUDE_DIR
|
|
||||||
NAMES obs.h
|
|
||||||
HINTS
|
|
||||||
ENV obsPath${_lib_suffix}
|
|
||||||
ENV obsPath
|
|
||||||
${obsPath}
|
|
||||||
PATHS
|
|
||||||
/usr/include /usr/local/include /opt/local/include /sw/include
|
|
||||||
PATH_SUFFIXES
|
|
||||||
libobs
|
|
||||||
)
|
|
||||||
|
|
||||||
function(find_obs_lib base_name repo_build_path lib_name)
|
|
||||||
string(TOUPPER "${base_name}" base_name_u)
|
|
||||||
|
|
||||||
if(DEFINED _build_type_base)
|
|
||||||
set(_build_type_${repo_build_path} "${_build_type_base}/${repo_build_path}")
|
|
||||||
set(_build_type_${repo_build_path}${_lib_suffix} "${_build_type_base}${_lib_suffix}/${repo_build_path}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_library(${base_name_u}_LIB
|
|
||||||
NAMES ${_${base_name_u}_LIBRARIES} ${lib_name} lib${lib_name}
|
|
||||||
HINTS
|
|
||||||
ENV obsPath${_lib_suffix}
|
|
||||||
ENV obsPath
|
|
||||||
${obsPath}
|
|
||||||
${_${base_name_u}_LIBRARY_DIRS}
|
|
||||||
PATHS
|
|
||||||
/usr/lib /usr/local/lib /opt/local/lib /sw/lib
|
|
||||||
PATH_SUFFIXES
|
|
||||||
lib${_lib_suffix} lib
|
|
||||||
libs${_lib_suffix} libs
|
|
||||||
bin${_lib_suffix} bin
|
|
||||||
../lib${_lib_suffix} ../lib
|
|
||||||
../libs${_lib_suffix} ../libs
|
|
||||||
../bin${_lib_suffix} ../bin
|
|
||||||
# base repo non-msvc-specific search paths
|
|
||||||
${_build_type_${repo_build_path}}
|
|
||||||
${_build_type_${repo_build_path}${_lib_suffix}}
|
|
||||||
build/${repo_build_path}
|
|
||||||
build${_lib_suffix}/${repo_build_path}
|
|
||||||
# base repo msvc-specific search paths on windows
|
|
||||||
build${_lib_suffix}/${repo_build_path}/Debug
|
|
||||||
build${_lib_suffix}/${repo_build_path}/RelWithDebInfo
|
|
||||||
build/${repo_build_path}/Debug
|
|
||||||
build/${repo_build_path}/RelWithDebInfo
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
find_obs_lib(LIBOBS libobs obs)
|
|
||||||
|
|
||||||
if(MSVC)
|
|
||||||
find_obs_lib(W32_PTHREADS deps/w32-pthreads w32-pthreads)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(Libobs DEFAULT_MSG LIBOBS_LIB LIBOBS_INCLUDE_DIR)
|
|
||||||
mark_as_advanced(LIBOBS_INCLUDE_DIR LIBOBS_LIB)
|
|
||||||
|
|
||||||
if(LIBOBS_FOUND)
|
|
||||||
if(MSVC)
|
|
||||||
if (NOT DEFINED W32_PTHREADS_LIB)
|
|
||||||
message(FATAL_ERROR "Could not find the w32-pthreads library" )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(W32_PTHREADS_INCLUDE_DIR ${LIBOBS_INCLUDE_DIR}/../deps/w32-pthreads)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(LIBOBS_INCLUDE_DIRS ${LIBOBS_INCLUDE_DIR} ${W32_PTHREADS_INCLUDE_DIR})
|
|
||||||
set(LIBOBS_LIBRARIES ${LIBOBS_LIB} ${W32_PTHREADS_LIB})
|
|
||||||
include(${LIBOBS_INCLUDE_DIR}/../cmake/external/ObsPluginHelpers.cmake)
|
|
||||||
|
|
||||||
# allows external plugins to easily use/share common dependencies that are often included with libobs (such as FFmpeg)
|
|
||||||
if(NOT DEFINED INCLUDED_LIBOBS_CMAKE_MODULES)
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LIBOBS_INCLUDE_DIR}/../cmake/Modules/")
|
|
||||||
set(INCLUDED_LIBOBS_CMAKE_MODULES true)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Could not find the libobs library" )
|
|
||||||
endif()
|
|
||||||
163
external/ObsPluginHelpers.cmake
vendored
163
external/ObsPluginHelpers.cmake
vendored
@@ -1,163 +0,0 @@
|
|||||||
# Functions for generating external plugins
|
|
||||||
|
|
||||||
set(EXTERNAL_PLUGIN_OUTPUT_DIR "${CMAKE_BINARY_DIR}/rundir")
|
|
||||||
|
|
||||||
# Fix XCode includes to ignore warnings on system includes
|
|
||||||
function(target_include_directories_system _target)
|
|
||||||
if(XCODE)
|
|
||||||
foreach(_arg ${ARGN})
|
|
||||||
if("${_arg}" STREQUAL "PRIVATE" OR "${_arg}" STREQUAL "PUBLIC" OR "${_arg}" STREQUAL "INTERFACE")
|
|
||||||
set(_scope ${_arg})
|
|
||||||
else()
|
|
||||||
target_compile_options(${_target} ${_scope} -isystem${_arg})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
else()
|
|
||||||
target_include_directories(${_target} SYSTEM ${_scope} ${ARGN})
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(install_external_plugin_data_internal target source_dir target_dir)
|
|
||||||
install(DIRECTORY ${source_dir}/
|
|
||||||
DESTINATION "${target}/${target_dir}"
|
|
||||||
USE_SOURCE_PERMISSIONS)
|
|
||||||
add_custom_command(TARGET ${target} POST_BUILD
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/${source_dir}" "${EXTERNAL_PLUGIN_OUTPUT_DIR}/$<CONFIGURATION>/${target}/${target_dir}"
|
|
||||||
VERBATIM)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs data
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
# 'data_loc' specifies the directory of the data
|
|
||||||
function(install_external_plugin_data target data_loc)
|
|
||||||
install_external_plugin_data_internal(${target} ${data_loc} "data")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs data in an architecture-specific data directory on windows/linux (data/32bit or data/64bit). Does not apply for mac.
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
# 'data_loc' specifies the directory of the data being installed
|
|
||||||
function(install_external_plugin_arch_data target data_loc)
|
|
||||||
if(APPLE)
|
|
||||||
set(_bit_suffix "")
|
|
||||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(_bit_suffix "/64bit")
|
|
||||||
else()
|
|
||||||
set(_bit_suffix "/32bit")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install_external_plugin_data_internal(${target} ${data_loc} "data${_bit_suffix}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs data in the target's bin directory
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
# 'data_loc' specifies the directory of the data being installed
|
|
||||||
function(install_external_plugin_data_to_bin target data_loc)
|
|
||||||
if(APPLE)
|
|
||||||
set(_bit_suffix "")
|
|
||||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(_bit_suffix "/64bit")
|
|
||||||
else()
|
|
||||||
set(_bit_suffix "/32bit")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install_external_plugin_data_internal(${target} ${data_loc} "bin${_bit_suffix}")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs an additional binary to a target
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
# 'additional_target' specifies the additional binary
|
|
||||||
function(install_external_plugin_additional target additional_target)
|
|
||||||
if(APPLE)
|
|
||||||
set(_bit_suffix "")
|
|
||||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(_bit_suffix "64bit/")
|
|
||||||
else()
|
|
||||||
set(_bit_suffix "32bit/")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(${additional_target} PROPERTIES
|
|
||||||
PREFIX "")
|
|
||||||
|
|
||||||
install(TARGETS ${additional_target}
|
|
||||||
LIBRARY DESTINATION "bin"
|
|
||||||
RUNTIME DESTINATION "bin")
|
|
||||||
add_custom_command(TARGET ${additional_target} POST_BUILD
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
|
||||||
"$<TARGET_FILE:${additional_target}>"
|
|
||||||
"${EXTERNAL_PLUGIN_OUTPUT_DIR}/$<CONFIGURATION>/${target}/bin/${_bit_suffix}$<TARGET_FILE_NAME:${additional_target}>"
|
|
||||||
VERBATIM)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs the binary of the target
|
|
||||||
# 'target' is the target project being installed
|
|
||||||
function(install_external_plugin target)
|
|
||||||
install_external_plugin_additional(${target} ${target})
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs the binary and data of the target
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
function(install_external_plugin_with_data target data_loc)
|
|
||||||
install_external_plugin(${target})
|
|
||||||
install_external_plugin_data(${target} ${data_loc})
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs an additional binary to the data of a target
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
# 'additional_target' specifies the additional binary
|
|
||||||
function(install_external_plugin_bin_to_data target additional_target)
|
|
||||||
install(TARGETS ${additional_target}
|
|
||||||
LIBRARY DESTINATION "data"
|
|
||||||
RUNTIME DESTINATION "data")
|
|
||||||
add_custom_command(TARGET ${additional_target} POST_BUILD
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
|
||||||
"$<TARGET_FILE:${additional_target}>"
|
|
||||||
"${EXTERNAL_PLUGIN_OUTPUT_DIR}/$<CONFIGURATION>/${target}/data/$<TARGET_FILE_NAME:${additional_target}>"
|
|
||||||
VERBATIM)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs an additional binary in an architecture-specific data directory on windows/linux (data/32bit or data/64bit). Does not apply for mac.
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
# 'additional_target' specifies the additional binary
|
|
||||||
function(install_external_plugin_bin_to_arch_data target additional_target)
|
|
||||||
if(APPLE)
|
|
||||||
set(_bit_suffix "")
|
|
||||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(_bit_suffix "/64bit")
|
|
||||||
else()
|
|
||||||
set(_bit_suffix "/32bit")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(TARGETS ${additional_target}
|
|
||||||
LIBRARY DESTINATION "data${_bit_suffix}"
|
|
||||||
RUNTIME DESTINATION "data${_bit_suffix}")
|
|
||||||
add_custom_command(TARGET ${additional_target} POST_BUILD
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
|
||||||
"$<TARGET_FILE:${additional_target}>"
|
|
||||||
"${EXTERNAL_PLUGIN_OUTPUT_DIR}/$<CONFIGURATION>/${target}/data${_bit_suffix}/$<TARGET_FILE_NAME:${additional_target}>"
|
|
||||||
VERBATIM)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Installs an additional file in an architecture-specific data directory on windows/linux (data/32bit or data/64bit). Does not apply for mac.
|
|
||||||
# 'target' is the destination target project being installed to
|
|
||||||
# 'additional_target' specifies the additional binary
|
|
||||||
function(install_external_plugin_data_file_to_arch_data target additional_target file_target)
|
|
||||||
if(APPLE)
|
|
||||||
set(_bit_suffix "")
|
|
||||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
set(_bit_suffix "/64bit")
|
|
||||||
else()
|
|
||||||
set(_bit_suffix "/32bit")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
get_filename_component(file_target_name ${file_target} NAME)
|
|
||||||
|
|
||||||
install(TARGETS ${additional_target}
|
|
||||||
LIBRARY DESTINATION "data${_bit_suffix}"
|
|
||||||
RUNTIME DESTINATION "data${_bit_suffix}")
|
|
||||||
add_custom_command(TARGET ${additional_target} POST_BUILD
|
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
|
||||||
"${file_target}"
|
|
||||||
"${EXTERNAL_PLUGIN_OUTPUT_DIR}/$<CONFIGURATION>/${target}/data${_bit_suffix}/${file_target_name}"
|
|
||||||
VERBATIM)
|
|
||||||
endfunction()
|
|
||||||
@@ -258,13 +258,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line_6">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_52">
|
<layout class="QHBoxLayout" name="horizontalLayout_52">
|
||||||
<item>
|
<item>
|
||||||
@@ -362,20 +355,8 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_41">
|
<layout class="QHBoxLayout" name="horizontalLayout_41">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListWidget" name="priorityList"/>
|
<widget class="QListWidget" name="priorityList">
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_30">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
@@ -693,13 +674,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line_4">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_65">
|
<spacer name="horizontalSpacer_65">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -723,7 +697,7 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>AdvSceneSwitcher.macroTab.edit</string>
|
<string>AdvSceneSwitcher.macroTab.edit</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_34" stretch="1,20,10">
|
<layout class="QVBoxLayout" name="verticalLayout_34">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0">
|
<layout class="QHBoxLayout" name="horizontalLayout_18" stretch="0,0,0">
|
||||||
<item>
|
<item>
|
||||||
@@ -752,184 +726,204 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QScrollArea" name="macroConditions">
|
<widget class="QSplitter" name="splitter">
|
||||||
<property name="widgetResizable">
|
<property name="orientation">
|
||||||
<bool>true</bool>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="scrollAreaWidgetContents_2">
|
<widget class="QScrollArea" name="macroConditions">
|
||||||
<property name="geometry">
|
<property name="widgetResizable">
|
||||||
<rect>
|
<bool>true</bool>
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>767</width>
|
|
||||||
<height>293</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_35" stretch="10,1">
|
<widget class="QWidget" name="scrollAreaWidgetContents_2">
|
||||||
<item>
|
<property name="geometry">
|
||||||
<layout class="QGridLayout" name="gridLayout_27">
|
<rect>
|
||||||
<item row="0" column="0">
|
<x>0</x>
|
||||||
<widget class="QLabel" name="macroEditConditionHelp">
|
<y>0</y>
|
||||||
<property name="enabled">
|
<width>767</width>
|
||||||
<bool>false</bool>
|
<height>220</height>
|
||||||
</property>
|
</rect>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>AdvSceneSwitcher.macroTab.editConditionHelp</string>
|
<layout class="QVBoxLayout" name="verticalLayout_35" stretch="10,1">
|
||||||
</property>
|
<property name="sizeConstraint">
|
||||||
<property name="alignment">
|
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||||
<set>Qt::AlignCenter</set>
|
</property>
|
||||||
</property>
|
<item>
|
||||||
<property name="wordWrap">
|
<layout class="QGridLayout" name="gridLayout_27">
|
||||||
<bool>true</bool>
|
<property name="sizeConstraint">
|
||||||
</property>
|
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<item row="0" column="0">
|
||||||
<item row="0" column="0">
|
<widget class="QLabel" name="macroEditConditionHelp">
|
||||||
<layout class="QVBoxLayout" name="macroEditConditionLayout"/>
|
<property name="enabled">
|
||||||
</item>
|
<bool>false</bool>
|
||||||
</layout>
|
</property>
|
||||||
</item>
|
<property name="text">
|
||||||
<item>
|
<string>AdvSceneSwitcher.macroTab.editConditionHelp</string>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
</property>
|
||||||
<item>
|
<property name="alignment">
|
||||||
<widget class="QPushButton" name="conditionAdd">
|
<set>Qt::AlignCenter</set>
|
||||||
<property name="maximumSize">
|
</property>
|
||||||
<size>
|
<property name="wordWrap">
|
||||||
<width>22</width>
|
<bool>true</bool>
|
||||||
<height>22</height>
|
</property>
|
||||||
</size>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="flat">
|
<item row="0" column="0">
|
||||||
<bool>true</bool>
|
<layout class="QVBoxLayout" name="macroEditConditionLayout">
|
||||||
</property>
|
<property name="sizeConstraint">
|
||||||
<property name="themeID" stdset="0">
|
<enum>QLayout::SetFixedSize</enum>
|
||||||
<string notr="true">addIconSmall</string>
|
</property>
|
||||||
</property>
|
</layout>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
</layout>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QPushButton" name="conditionRemove">
|
<item>
|
||||||
<property name="maximumSize">
|
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||||
<size>
|
<item>
|
||||||
<width>22</width>
|
<widget class="QPushButton" name="conditionAdd">
|
||||||
<height>22</height>
|
<property name="maximumSize">
|
||||||
</size>
|
<size>
|
||||||
</property>
|
<width>22</width>
|
||||||
<property name="flat">
|
<height>22</height>
|
||||||
<bool>true</bool>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="themeID" stdset="0">
|
<property name="flat">
|
||||||
<string notr="true">removeIconSmall</string>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="themeID" stdset="0">
|
||||||
</item>
|
<string notr="true">addIconSmall</string>
|
||||||
<item>
|
</property>
|
||||||
<spacer name="horizontalSpacer_15">
|
</widget>
|
||||||
<property name="orientation">
|
</item>
|
||||||
<enum>Qt::Horizontal</enum>
|
<item>
|
||||||
</property>
|
<widget class="QPushButton" name="conditionRemove">
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>22</width>
|
||||||
<height>20</height>
|
<height>22</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
<property name="flat">
|
||||||
</item>
|
<bool>true</bool>
|
||||||
</layout>
|
</property>
|
||||||
</item>
|
<property name="themeID" stdset="0">
|
||||||
</layout>
|
<string notr="true">removeIconSmall</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</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>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
<widget class="QScrollArea" name="macroActions">
|
||||||
</item>
|
<property name="widgetResizable">
|
||||||
<item>
|
<bool>true</bool>
|
||||||
<widget class="QScrollArea" name="macroActions">
|
|
||||||
<property name="widgetResizable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="scrollAreaWidgetContents_3">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>767</width>
|
|
||||||
<height>145</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_33" stretch="10,1">
|
<widget class="QWidget" name="scrollAreaWidgetContents_3">
|
||||||
<item>
|
<property name="geometry">
|
||||||
<layout class="QGridLayout" name="gridLayout_25">
|
<rect>
|
||||||
<item row="0" column="0">
|
<x>0</x>
|
||||||
<widget class="QLabel" name="macroEditActionHelp">
|
<y>0</y>
|
||||||
<property name="enabled">
|
<width>767</width>
|
||||||
<bool>false</bool>
|
<height>219</height>
|
||||||
</property>
|
</rect>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>AdvSceneSwitcher.macroTab.editActionHelp</string>
|
<layout class="QVBoxLayout" name="verticalLayout_33" stretch="10,1">
|
||||||
</property>
|
<property name="sizeConstraint">
|
||||||
<property name="alignment">
|
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||||
<set>Qt::AlignCenter</set>
|
</property>
|
||||||
</property>
|
<item>
|
||||||
<property name="wordWrap">
|
<layout class="QGridLayout" name="gridLayout_25">
|
||||||
<bool>true</bool>
|
<item row="0" column="0">
|
||||||
</property>
|
<widget class="QLabel" name="macroEditActionHelp">
|
||||||
</widget>
|
<property name="enabled">
|
||||||
</item>
|
<bool>false</bool>
|
||||||
<item row="0" column="0">
|
</property>
|
||||||
<layout class="QVBoxLayout" name="macroEditActionLayout"/>
|
<property name="text">
|
||||||
</item>
|
<string>AdvSceneSwitcher.macroTab.editActionHelp</string>
|
||||||
</layout>
|
</property>
|
||||||
</item>
|
<property name="alignment">
|
||||||
<item>
|
<set>Qt::AlignCenter</set>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
</property>
|
||||||
<item>
|
<property name="wordWrap">
|
||||||
<widget class="QPushButton" name="actionAdd">
|
<bool>true</bool>
|
||||||
<property name="maximumSize">
|
</property>
|
||||||
<size>
|
</widget>
|
||||||
<width>22</width>
|
</item>
|
||||||
<height>22</height>
|
<item row="0" column="0">
|
||||||
</size>
|
<layout class="QVBoxLayout" name="macroEditActionLayout">
|
||||||
</property>
|
<property name="sizeConstraint">
|
||||||
<property name="flat">
|
<enum>QLayout::SetMinAndMaxSize</enum>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
</layout>
|
||||||
<property name="themeID" stdset="0">
|
</item>
|
||||||
<string notr="true">addIconSmall</string>
|
</layout>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="actionRemove">
|
<widget class="QPushButton" name="actionAdd">
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>22</width>
|
<width>22</width>
|
||||||
<height>22</height>
|
<height>22</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="themeID" stdset="0">
|
<property name="themeID" stdset="0">
|
||||||
<string notr="true">removeIconSmall</string>
|
<string notr="true">addIconSmall</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_14">
|
<widget class="QPushButton" name="actionRemove">
|
||||||
<property name="orientation">
|
<property name="maximumSize">
|
||||||
<enum>Qt::Horizontal</enum>
|
<size>
|
||||||
</property>
|
<width>22</width>
|
||||||
<property name="sizeHint" stdset="0">
|
<height>22</height>
|
||||||
<size>
|
</size>
|
||||||
<width>40</width>
|
</property>
|
||||||
<height>20</height>
|
<property name="flat">
|
||||||
</size>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
<property name="themeID" stdset="0">
|
||||||
</item>
|
<string notr="true">removeIconSmall</string>
|
||||||
</layout>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
</layout>
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_14">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -3703,6 +3697,13 @@
|
|||||||
<string>AdvSceneSwitcher.networkTab.title</string>
|
<string>AdvSceneSwitcher.networkTab.title</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_30">
|
<layout class="QVBoxLayout" name="verticalLayout_30">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="networkTabDescription">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.networkTab.description</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="networkTabWarningLabel">
|
<widget class="QLabel" name="networkTabWarningLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -3724,6 +3725,27 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_31">
|
<layout class="QVBoxLayout" name="verticalLayout_31">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_24">
|
<layout class="QGridLayout" name="gridLayout_24">
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="restrictSend">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.networkTab.server.restrictSendToAutomatedSwitches</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.networkTab.server.status.currentStatus</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="serverStatus">
|
||||||
|
<property name="text">
|
||||||
|
<string>AdvSceneSwitcher.networkTab.server.status.notRunning</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QSpinBox" name="serverPort">
|
<widget class="QSpinBox" name="serverPort">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
@@ -3751,24 +3773,17 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="1">
|
||||||
<widget class="QLabel" name="label_19">
|
<widget class="QCheckBox" name="sendPreview">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>AdvSceneSwitcher.networkTab.server.status.currentStatus</string>
|
<string>AdvSceneSwitcher.networkTab.server.sendPreview</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLabel" name="serverStatus">
|
|
||||||
<property name="text">
|
|
||||||
<string>AdvSceneSwitcher.networkTab.server.status.notRunning</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QCheckBox" name="restrictSend">
|
<widget class="QCheckBox" name="sendSceneChange">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>AdvSceneSwitcher.networkTab.server.restrictSendToAutomatedSwitches</string>
|
<string>AdvSceneSwitcher.networkTab.server.sendSceneChange</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QtGui/qstandarditemmodel.h>
|
#include <QFileDialog>
|
||||||
#include <QPropertyAnimation>
|
#include <regex>
|
||||||
#include <QGraphicsColorizeEffect>
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
#include <util/util.hpp>
|
|
||||||
|
|
||||||
#include "headers/advanced-scene-switcher.hpp"
|
#include "headers/advanced-scene-switcher.hpp"
|
||||||
#include "headers/curl-helper.hpp"
|
#include "headers/curl-helper.hpp"
|
||||||
@@ -73,331 +70,36 @@ void AdvSceneSwitcher::loadUI()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* UI helpers
|
* Saving and loading
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void AdvSceneSwitcher::addSelectionEntry(QComboBox *sel,
|
void AskBackup(obs_data_t *obj)
|
||||||
const char *description,
|
|
||||||
bool selectable, const char *tooltip)
|
|
||||||
{
|
{
|
||||||
sel->addItem(description);
|
bool backupSettings = DisplayMessage(
|
||||||
|
obs_module_text("AdvSceneSwitcher.askBackup"), true);
|
||||||
|
|
||||||
if (strcmp(tooltip, "") != 0) {
|
if (!backupSettings) {
|
||||||
sel->setItemData(0, tooltip, Qt::ToolTipRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStandardItemModel *model =
|
|
||||||
qobject_cast<QStandardItemModel *>(sel->model());
|
|
||||||
QModelIndex firstIndex =
|
|
||||||
model->index(0, sel->modelColumn(), sel->rootModelIndex());
|
|
||||||
QStandardItem *firstItem = model->itemFromIndex(firstIndex);
|
|
||||||
if (!selectable) {
|
|
||||||
firstItem->setSelectable(false);
|
|
||||||
firstItem->setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::populateSceneSelection(QComboBox *sel, bool addPrevious,
|
|
||||||
bool addSceneGroup,
|
|
||||||
bool addSelect,
|
|
||||||
std::string selectText,
|
|
||||||
bool selectable)
|
|
||||||
{
|
|
||||||
if (addSelect) {
|
|
||||||
if (selectText.empty()) {
|
|
||||||
addSelectionEntry(
|
|
||||||
sel,
|
|
||||||
obs_module_text("AdvSceneSwitcher.selectScene"),
|
|
||||||
selectable,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
|
|
||||||
} else {
|
|
||||||
addSelectionEntry(sel, selectText.c_str(), selectable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BPtr<char *> scenes = obs_frontend_get_scene_names();
|
|
||||||
char **temp = scenes;
|
|
||||||
while (*temp) {
|
|
||||||
const char *name = *temp;
|
|
||||||
sel->addItem(name);
|
|
||||||
temp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addPrevious) {
|
|
||||||
sel->addItem(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.selectPreviousScene"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addSceneGroup) {
|
|
||||||
for (auto &sg : switcher->sceneGroups) {
|
|
||||||
sel->addItem(QString::fromStdString(sg.name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::populateTransitionSelection(QComboBox *sel,
|
|
||||||
bool addCurrent,
|
|
||||||
bool addSelect,
|
|
||||||
bool selectable)
|
|
||||||
{
|
|
||||||
if (addSelect) {
|
|
||||||
addSelectionEntry(
|
|
||||||
sel,
|
|
||||||
obs_module_text("AdvSceneSwitcher.selectTransition"),
|
|
||||||
selectable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addCurrent) {
|
|
||||||
sel->addItem(
|
|
||||||
obs_module_text("AdvSceneSwitcher.currentTransition"));
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_frontend_source_list *transitions = new obs_frontend_source_list();
|
|
||||||
obs_frontend_get_transitions(transitions);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < transitions->sources.num; i++) {
|
|
||||||
const char *name =
|
|
||||||
obs_source_get_name(transitions->sources.array[i]);
|
|
||||||
sel->addItem(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_frontend_source_list_free(transitions);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::populateWindowSelection(QComboBox *sel, bool addSelect)
|
|
||||||
{
|
|
||||||
if (addSelect) {
|
|
||||||
addSelectionEntry(
|
|
||||||
sel, obs_module_text("AdvSceneSwitcher.selectWindow"));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> windows;
|
|
||||||
GetWindowList(windows);
|
|
||||||
sort(windows.begin(), windows.end());
|
|
||||||
|
|
||||||
for (std::string &window : windows) {
|
|
||||||
sel->addItem(window.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
sel->setItemData(0, obs_module_text("AdvSceneSwitcher.selectWindowTip"),
|
|
||||||
Qt::ToolTipRole);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::populateAudioSelection(QComboBox *sel, bool addSelect)
|
|
||||||
{
|
|
||||||
if (addSelect) {
|
|
||||||
addSelectionEntry(
|
|
||||||
sel,
|
|
||||||
obs_module_text("AdvSceneSwitcher.selectAudioSource"),
|
|
||||||
false,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
|
|
||||||
{
|
|
||||||
std::vector<std::string> *list =
|
|
||||||
reinterpret_cast<std::vector<std::string> *>(data);
|
|
||||||
uint32_t flags = obs_source_get_output_flags(source);
|
|
||||||
|
|
||||||
if ((flags & OBS_SOURCE_AUDIO) != 0) {
|
|
||||||
list->push_back(obs_source_get_name(source));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::string> audioSources;
|
|
||||||
obs_enum_sources(sourceEnum, &audioSources);
|
|
||||||
sort(audioSources.begin(), audioSources.end());
|
|
||||||
for (std::string &source : audioSources) {
|
|
||||||
sel->addItem(source.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::populateVideoSelection(QComboBox *sel, bool addScenes,
|
|
||||||
bool addSelect)
|
|
||||||
{
|
|
||||||
if (addSelect) {
|
|
||||||
addSelectionEntry(
|
|
||||||
sel,
|
|
||||||
obs_module_text("AdvSceneSwitcher.selectVideoSource"),
|
|
||||||
false,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
|
|
||||||
{
|
|
||||||
std::vector<std::string> *list =
|
|
||||||
reinterpret_cast<std::vector<std::string> *>(data);
|
|
||||||
uint32_t flags = obs_source_get_output_flags(source);
|
|
||||||
std::string test = obs_source_get_name(source);
|
|
||||||
if ((flags & (OBS_SOURCE_VIDEO | OBS_SOURCE_ASYNC)) != 0) {
|
|
||||||
list->push_back(obs_source_get_name(source));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::string> videoSources;
|
|
||||||
obs_enum_sources(sourceEnum, &videoSources);
|
|
||||||
sort(videoSources.begin(), videoSources.end());
|
|
||||||
for (std::string &source : videoSources) {
|
|
||||||
sel->addItem(source.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addScenes) {
|
|
||||||
populateSceneSelection(sel, false, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::populateMediaSelection(QComboBox *sel, bool addSelect)
|
|
||||||
{
|
|
||||||
if (addSelect) {
|
|
||||||
addSelectionEntry(
|
|
||||||
sel,
|
|
||||||
obs_module_text("AdvSceneSwitcher.selectMediaSource"),
|
|
||||||
false,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
|
|
||||||
{
|
|
||||||
std::vector<std::string> *list =
|
|
||||||
reinterpret_cast<std::vector<std::string> *>(data);
|
|
||||||
std::string sourceId = obs_source_get_id(source);
|
|
||||||
if (sourceId.compare("ffmpeg_source") == 0 ||
|
|
||||||
sourceId.compare("vlc_source") == 0) {
|
|
||||||
list->push_back(obs_source_get_name(source));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::string> mediaSources;
|
|
||||||
obs_enum_sources(sourceEnum, &mediaSources);
|
|
||||||
sort(mediaSources.begin(), mediaSources.end());
|
|
||||||
for (std::string &source : mediaSources) {
|
|
||||||
sel->addItem(source.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::populateProcessSelection(QComboBox *sel, bool addSelect)
|
|
||||||
{
|
|
||||||
if (addSelect) {
|
|
||||||
addSelectionEntry(
|
|
||||||
sel, obs_module_text("AdvSceneSwitcher.selectProcess"));
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList processes;
|
|
||||||
GetProcessList(processes);
|
|
||||||
processes.sort();
|
|
||||||
for (QString &process : processes)
|
|
||||||
sel->addItem(process);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::listAddClicked(QListWidget *list,
|
|
||||||
SwitchWidget *newWidget,
|
|
||||||
QPushButton *addButton,
|
|
||||||
QMetaObject::Connection *addHighlight)
|
|
||||||
{
|
|
||||||
if (!list || !newWidget) {
|
|
||||||
blog(LOG_WARNING,
|
|
||||||
"listAddClicked called without valid list or widget");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addButton && addHighlight) {
|
QString directory = QFileDialog::getSaveFileName(
|
||||||
addButton->disconnect(*addHighlight);
|
nullptr,
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle"),
|
||||||
|
QDir::currentPath(),
|
||||||
|
obs_module_text(
|
||||||
|
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType"));
|
||||||
|
if (directory.isEmpty()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QListWidgetItem *item;
|
QFile file(directory);
|
||||||
item = new QListWidgetItem(list);
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
list->addItem(item);
|
return;
|
||||||
item->setSizeHint(newWidget->minimumSizeHint());
|
|
||||||
list->setItemWidget(item, newWidget);
|
|
||||||
|
|
||||||
list->scrollToItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AdvSceneSwitcher::listMoveUp(QListWidget *list)
|
|
||||||
{
|
|
||||||
int index = list->currentRow();
|
|
||||||
if (index == -1 || index == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *row = list->itemWidget(list->currentItem());
|
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||||
QListWidgetItem *itemN = list->currentItem()->clone();
|
|
||||||
|
|
||||||
list->insertItem(index - 1, itemN);
|
|
||||||
list->setItemWidget(itemN, row);
|
|
||||||
|
|
||||||
list->takeItem(index + 1);
|
|
||||||
list->setCurrentRow(index - 1);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdvSceneSwitcher::listMoveDown(QListWidget *list)
|
|
||||||
{
|
|
||||||
int index = list->currentRow();
|
|
||||||
if (index == -1 || index == list->count() - 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *row = list->itemWidget(list->currentItem());
|
|
||||||
QListWidgetItem *itemN = list->currentItem()->clone();
|
|
||||||
|
|
||||||
list->insertItem(index + 2, itemN);
|
|
||||||
list->setItemWidget(itemN, row);
|
|
||||||
|
|
||||||
list->takeItem(index);
|
|
||||||
list->setCurrentRow(index + 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMetaObject::Connection AdvSceneSwitcher::PulseWidget(QWidget *widget,
|
|
||||||
QColor endColor,
|
|
||||||
QColor startColor,
|
|
||||||
QString specifier)
|
|
||||||
{
|
|
||||||
if (switcher->disableHints) {
|
|
||||||
return QMetaObject::Connection();
|
|
||||||
}
|
|
||||||
|
|
||||||
widget->setStyleSheet(specifier + "{ \
|
|
||||||
border-style: outset; \
|
|
||||||
border-width: 2px; \
|
|
||||||
border-radius: 10px; \
|
|
||||||
border-color: rgb(0,0,0,0) \
|
|
||||||
}");
|
|
||||||
|
|
||||||
QGraphicsColorizeEffect *eEffect = new QGraphicsColorizeEffect(widget);
|
|
||||||
widget->setGraphicsEffect(eEffect);
|
|
||||||
QPropertyAnimation *paAnimation =
|
|
||||||
new QPropertyAnimation(eEffect, "color");
|
|
||||||
paAnimation->setStartValue(startColor);
|
|
||||||
paAnimation->setEndValue(endColor);
|
|
||||||
paAnimation->setDuration(1000);
|
|
||||||
// Play backwards to return to original state on timer end
|
|
||||||
paAnimation->setDirection(QAbstractAnimation::Backward);
|
|
||||||
|
|
||||||
auto con = QWidget::connect(
|
|
||||||
paAnimation, &QPropertyAnimation::finished, [paAnimation]() {
|
|
||||||
QTimer::singleShot(1000, [paAnimation] {
|
|
||||||
paAnimation->start();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
paAnimation->start();
|
|
||||||
|
|
||||||
return con;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Saving and loading
|
|
||||||
******************************************************************************/
|
|
||||||
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||||
{
|
{
|
||||||
if (saving) {
|
if (saving) {
|
||||||
@@ -422,7 +124,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||||||
obj = obs_data_create();
|
obj = obs_data_create();
|
||||||
}
|
}
|
||||||
if (switcher->versionChanged(obj, g_GIT_SHA1)) {
|
if (switcher->versionChanged(obj, g_GIT_SHA1)) {
|
||||||
AdvSceneSwitcher::AskBackup(obj);
|
AskBackup(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
switcher->loadSettings(obj);
|
switcher->loadSettings(obj);
|
||||||
@@ -484,6 +186,7 @@ void SwitcherData::Thread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
vblog(LOG_INFO, "try to sleep for %ld", duration.count());
|
vblog(LOG_INFO, "try to sleep for %ld", duration.count());
|
||||||
|
setWaitScene();
|
||||||
cv.wait_for(lock, duration);
|
cv.wait_for(lock, duration);
|
||||||
|
|
||||||
startTime = std::chrono::high_resolution_clock::now();
|
startTime = std::chrono::high_resolution_clock::now();
|
||||||
@@ -497,6 +200,7 @@ void SwitcherData::Thread()
|
|||||||
if (checkPause()) {
|
if (checkPause()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
setPreconditions();
|
||||||
match = checkForMatch(scene, transition, linger,
|
match = checkForMatch(scene, transition, linger,
|
||||||
setPrevSceneAfterLinger, macroMatch);
|
setPrevSceneAfterLinger, macroMatch);
|
||||||
if (stop) {
|
if (stop) {
|
||||||
@@ -510,6 +214,7 @@ void SwitcherData::Thread()
|
|||||||
vblog(LOG_INFO, "sleep for %ld before switching scene",
|
vblog(LOG_INFO, "sleep for %ld before switching scene",
|
||||||
duration.count());
|
duration.count());
|
||||||
|
|
||||||
|
setWaitScene();
|
||||||
cv.wait_for(lock, duration);
|
cv.wait_for(lock, duration);
|
||||||
|
|
||||||
if (stop) {
|
if (stop) {
|
||||||
@@ -527,12 +232,17 @@ void SwitcherData::Thread()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// After this point we will call frontend functions
|
// After this point we will call frontend functions like
|
||||||
// obs_frontend_set_current_scene() and
|
// obs_frontend_set_current_scene() and
|
||||||
// obs_frontend_set_current_transition()
|
// obs_frontend_set_current_transition()
|
||||||
//
|
//
|
||||||
// During this time SaveSceneSwitcher() could be called
|
// During this time SaveSceneSwitcher() could be called
|
||||||
// leading to a deadlock, so we have to unlock()
|
// leading to a deadlock with the frontend function being stuck
|
||||||
|
// in QMetaObject::invokeMethod() holding the mutex and
|
||||||
|
// OBS being stuck in SaveSceneSwitcher().
|
||||||
|
//
|
||||||
|
// So we have to unlock() risking race conditions as these are
|
||||||
|
// less frequent than the above described deadlock
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
@@ -549,6 +259,37 @@ void SwitcherData::Thread()
|
|||||||
blog(LOG_INFO, "stopped");
|
blog(LOG_INFO, "stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SwitcherData::setPreconditions()
|
||||||
|
{
|
||||||
|
// Window title
|
||||||
|
lastTitle = currentTitle;
|
||||||
|
std::string title;
|
||||||
|
GetCurrentWindowTitle(title);
|
||||||
|
for (auto &window : ignoreWindowsSwitches) {
|
||||||
|
bool equals = (title == window);
|
||||||
|
bool matches = false;
|
||||||
|
if (!equals) {
|
||||||
|
try {
|
||||||
|
std::regex expr(window);
|
||||||
|
matches = std::regex_match(title, expr);
|
||||||
|
|
||||||
|
} catch (const std::regex_error &) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (equals || matches) {
|
||||||
|
title = lastTitle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentTitle = title;
|
||||||
|
|
||||||
|
// Cursor
|
||||||
|
std::pair<int, int> cursorPos = getCursorPos();
|
||||||
|
cursorPosChanged = cursorPos.first != switcher->lastCursorPos.first ||
|
||||||
|
cursorPos.second != switcher->lastCursorPos.second;
|
||||||
|
lastCursorPos = getCursorPos();
|
||||||
|
}
|
||||||
|
|
||||||
bool SwitcherData::checkForMatch(OBSWeakSource &scene,
|
bool SwitcherData::checkForMatch(OBSWeakSource &scene,
|
||||||
OBSWeakSource &transition, int &linger,
|
OBSWeakSource &transition, int &linger,
|
||||||
bool &setPrevSceneAfterLinger,
|
bool &setPrevSceneAfterLinger,
|
||||||
@@ -616,7 +357,7 @@ bool SwitcherData::checkForMatch(OBSWeakSource &scene,
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchScene(sceneSwitchInfo sceneSwitch)
|
void switchScene(const sceneSwitchInfo &sceneSwitch)
|
||||||
{
|
{
|
||||||
if (!sceneSwitch.scene && switcher->verbose) {
|
if (!sceneSwitch.scene && switcher->verbose) {
|
||||||
blog(LOG_INFO, "nothing to switch to");
|
blog(LOG_INFO, "nothing to switch to");
|
||||||
@@ -640,7 +381,7 @@ void switchScene(sceneSwitchInfo sceneSwitch)
|
|||||||
blog(LOG_INFO, "switched scene");
|
blog(LOG_INFO, "switched scene");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switcher->networkConfig.ServerEnabled) {
|
if (switcher->networkConfig.ShouldSendSceneChange()) {
|
||||||
switcher->server.sendMessage(sceneSwitch);
|
switcher->server.sendMessage(sceneSwitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -648,6 +389,13 @@ void switchScene(sceneSwitchInfo sceneSwitch)
|
|||||||
obs_source_release(source);
|
obs_source_release(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void switchPreviewScene(const OBSWeakSource &ws)
|
||||||
|
{
|
||||||
|
auto source = obs_weak_source_get_source(ws);
|
||||||
|
obs_frontend_set_current_preview_scene(source);
|
||||||
|
obs_source_release(source);
|
||||||
|
}
|
||||||
|
|
||||||
void SwitcherData::Start()
|
void SwitcherData::Start()
|
||||||
{
|
{
|
||||||
if (!(th && th->isRunning())) {
|
if (!(th && th->isRunning())) {
|
||||||
@@ -669,23 +417,38 @@ void SwitcherData::Start()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetMacroCounters()
|
||||||
|
{
|
||||||
|
for (auto &m : switcher->macros) {
|
||||||
|
m.ResetCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SwitcherData::Stop()
|
void SwitcherData::Stop()
|
||||||
{
|
{
|
||||||
if (th && th->isRunning()) {
|
if (th && th->isRunning()) {
|
||||||
stop = true;
|
stop = true;
|
||||||
transitionCv.notify_one();
|
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
|
abortMacroWait = true;
|
||||||
|
macroWaitCv.notify_one();
|
||||||
th->wait();
|
th->wait();
|
||||||
delete th;
|
delete th;
|
||||||
th = nullptr;
|
th = nullptr;
|
||||||
|
|
||||||
writeToStatusFile("Advanced Scene Switcher stopped");
|
writeToStatusFile("Advanced Scene Switcher stopped");
|
||||||
|
ResetMacroCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
server.stop();
|
server.stop();
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SwitcherData::setWaitScene()
|
||||||
|
{
|
||||||
|
waitScene = obs_frontend_get_current_scene();
|
||||||
|
obs_source_release(waitScene);
|
||||||
|
}
|
||||||
|
|
||||||
bool SwitcherData::sceneChangedDuringWait()
|
bool SwitcherData::sceneChangedDuringWait()
|
||||||
{
|
{
|
||||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
||||||
@@ -709,58 +472,90 @@ extern "C" void FreeSceneSwitcher()
|
|||||||
loaded_curl_lib = nullptr;
|
loaded_curl_lib = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlatformCleanup();
|
||||||
|
|
||||||
delete switcher;
|
delete switcher;
|
||||||
switcher = nullptr;
|
switcher = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleSceneChange(SwitcherData *s)
|
void handleSceneChange()
|
||||||
{
|
{
|
||||||
|
switcher->lastSceneChangeTime =
|
||||||
|
std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
// Stop waiting if scene was changed
|
// Stop waiting if scene was changed
|
||||||
if (s->sceneChangedDuringWait()) {
|
if (switcher->sceneChangedDuringWait()) {
|
||||||
s->cv.notify_one();
|
switcher->cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set previous scene
|
// Set current and previous scene
|
||||||
obs_source_t *source = obs_frontend_get_current_scene();
|
obs_source_t *source = obs_frontend_get_current_scene();
|
||||||
obs_weak_source_t *ws = obs_source_get_weak_source(source);
|
obs_weak_source_t *ws = obs_source_get_weak_source(source);
|
||||||
obs_source_release(source);
|
|
||||||
obs_weak_source_release(ws);
|
if (ws && ws != switcher->currentScene) {
|
||||||
if (source && s->previousSceneHelper != ws) {
|
switcher->previousScene = switcher->currentScene;
|
||||||
s->previousScene = s->previousSceneHelper;
|
switcher->currentScene = ws;
|
||||||
s->previousSceneHelper = ws;
|
vblog(LOG_INFO, "current scene: %s",
|
||||||
|
GetWeakSourceName(switcher->currentScene).c_str());
|
||||||
|
vblog(LOG_INFO, "previous scene: %s",
|
||||||
|
GetWeakSourceName(switcher->previousScene).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
s->checkTriggers();
|
obs_source_release(source);
|
||||||
s->checkDefaultSceneTransitions();
|
obs_weak_source_release(ws);
|
||||||
|
|
||||||
if (switcher->networkConfig.ServerEnabled &&
|
switcher->checkTriggers();
|
||||||
switcher->networkConfig.SendAll) {
|
switcher->checkDefaultSceneTransitions();
|
||||||
|
|
||||||
|
if (switcher->networkConfig.ShouldSendFrontendSceneChange()) {
|
||||||
switcher->server.sendMessage({ws, nullptr, 0});
|
switcher->server.sendMessage({ws, nullptr, 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLiveTime(SwitcherData *s)
|
void setLiveTime()
|
||||||
{
|
{
|
||||||
s->liveTime = QDateTime::currentDateTime();
|
switcher->liveTime = QDateTime::currentDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetLiveTime(SwitcherData *s)
|
void resetLiveTime()
|
||||||
{
|
{
|
||||||
s->liveTime = QDateTime();
|
switcher->liveTime = QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAutoStartRecording(SwitcherData *s)
|
void checkAutoStartRecording()
|
||||||
{
|
{
|
||||||
if (s->autoStartEvent == AutoStartEvent::RECORDING ||
|
if (switcher->autoStartEvent == AutoStartEvent::RECORDING ||
|
||||||
s->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
||||||
s->Start();
|
switcher->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAutoStartStreaming(SwitcherData *s)
|
void checkAutoStartStreaming()
|
||||||
{
|
{
|
||||||
if (s->autoStartEvent == AutoStartEvent::STREAMING ||
|
if (switcher->autoStartEvent == AutoStartEvent::STREAMING ||
|
||||||
s->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
switcher->autoStartEvent == AutoStartEvent::RECORINDG_OR_STREAMING)
|
||||||
s->Start();
|
switcher->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handlePeviewSceneChange()
|
||||||
|
{
|
||||||
|
if (switcher->networkConfig.ShouldSendPrviewSceneChange()) {
|
||||||
|
auto source = obs_frontend_get_current_preview_scene();
|
||||||
|
auto weak = obs_source_get_weak_source(source);
|
||||||
|
switcher->server.sendMessage({weak, nullptr, 0}, true);
|
||||||
|
obs_weak_source_release(weak);
|
||||||
|
obs_source_release(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setReplayBufferSaved()
|
||||||
|
{
|
||||||
|
switcher->replayBufferSaved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTranstionEnd()
|
||||||
|
{
|
||||||
|
switcher->lastTransitionEndTime =
|
||||||
|
std::chrono::high_resolution_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note to future self:
|
// Note to future self:
|
||||||
@@ -768,24 +563,39 @@ void checkAutoStartStreaming(SwitcherData *s)
|
|||||||
// frontend functions such as obs_frontend_set_current_scene()
|
// frontend functions such as obs_frontend_set_current_scene()
|
||||||
static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
||||||
{
|
{
|
||||||
|
if (!switcher) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case OBS_FRONTEND_EVENT_EXIT:
|
case OBS_FRONTEND_EVENT_EXIT:
|
||||||
FreeSceneSwitcher();
|
FreeSceneSwitcher();
|
||||||
break;
|
break;
|
||||||
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
|
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
|
||||||
handleSceneChange((SwitcherData *)switcher);
|
handleSceneChange();
|
||||||
|
break;
|
||||||
|
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED:
|
||||||
|
handlePeviewSceneChange();
|
||||||
break;
|
break;
|
||||||
case OBS_FRONTEND_EVENT_RECORDING_STARTED:
|
case OBS_FRONTEND_EVENT_RECORDING_STARTED:
|
||||||
setLiveTime((SwitcherData *)switcher);
|
setLiveTime();
|
||||||
checkAutoStartRecording((SwitcherData *)switcher);
|
checkAutoStartRecording();
|
||||||
break;
|
break;
|
||||||
case OBS_FRONTEND_EVENT_STREAMING_STARTED:
|
case OBS_FRONTEND_EVENT_STREAMING_STARTED:
|
||||||
setLiveTime((SwitcherData *)switcher);
|
setLiveTime();
|
||||||
checkAutoStartStreaming((SwitcherData *)switcher);
|
checkAutoStartStreaming();
|
||||||
break;
|
break;
|
||||||
case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
|
case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
|
||||||
case OBS_FRONTEND_EVENT_STREAMING_STOPPED:
|
case OBS_FRONTEND_EVENT_STREAMING_STOPPED:
|
||||||
resetLiveTime((SwitcherData *)switcher);
|
resetLiveTime();
|
||||||
|
break;
|
||||||
|
#ifdef REPLAYBUFFER_SUPPORTED
|
||||||
|
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVED:
|
||||||
|
setReplayBufferSaved();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case OBS_FRONTEND_EVENT_TRANSITION_STOPPED:
|
||||||
|
setTranstionEnd();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -794,6 +604,7 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher)
|
|||||||
|
|
||||||
extern "C" void InitSceneSwitcher()
|
extern "C" void InitSceneSwitcher()
|
||||||
{
|
{
|
||||||
|
blog(LOG_INFO, "version: %s", g_GIT_TAG);
|
||||||
blog(LOG_INFO, "version: %s", g_GIT_SHA1);
|
blog(LOG_INFO, "version: %s", g_GIT_SHA1);
|
||||||
|
|
||||||
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
|
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
|
||||||
@@ -805,6 +616,8 @@ extern "C" void InitSceneSwitcher()
|
|||||||
switcher->curl = f_curl_init();
|
switcher->curl = f_curl_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlatformInit();
|
||||||
|
|
||||||
auto cb = []() {
|
auto cb = []() {
|
||||||
QMainWindow *window =
|
QMainWindow *window =
|
||||||
(QMainWindow *)obs_frontend_get_main_window();
|
(QMainWindow *)obs_frontend_get_main_window();
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ bool resolveCurl()
|
|||||||
|
|
||||||
bool loadCurl()
|
bool loadCurl()
|
||||||
{
|
{
|
||||||
|
loaded_curl_lib = new QLibrary(curl_library_name, nullptr);
|
||||||
|
if (resolveCurl()) {
|
||||||
|
blog(LOG_INFO, "[adv-ss] found curl library");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
delete loaded_curl_lib;
|
||||||
|
loaded_curl_lib = nullptr;
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"[adv-ss] couldn't find the curl library in PATH");
|
||||||
|
}
|
||||||
|
|
||||||
QStringList locations;
|
QStringList locations;
|
||||||
locations << QDir::currentPath();
|
locations << QDir::currentPath();
|
||||||
#if defined(__linux__) || defined(__APPLE__)
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "headers/duration-control.hpp"
|
#include "headers/duration-control.hpp"
|
||||||
|
#include "headers/utility.hpp"
|
||||||
#include "obs-module.h"
|
#include "obs-module.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -31,6 +32,27 @@ bool Duration::DurationReached()
|
|||||||
return runTime.count() >= seconds * 1000;
|
return runTime.count() >= seconds * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Duration::TimeRemaining()
|
||||||
|
{
|
||||||
|
if (_startTime.time_since_epoch().count() == 0) {
|
||||||
|
return seconds;
|
||||||
|
}
|
||||||
|
auto runTime = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
std::chrono::high_resolution_clock::now() - _startTime);
|
||||||
|
|
||||||
|
if (runTime.count() >= seconds * 1000) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (seconds * 1000 - runTime.count()) / 1000.;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Duration::SetTimeRemaining(double remaining)
|
||||||
|
{
|
||||||
|
long long msPassed = (seconds - remaining) * 1000;
|
||||||
|
_startTime = std::chrono::high_resolution_clock::now() -
|
||||||
|
std::chrono::milliseconds(msPassed);
|
||||||
|
}
|
||||||
|
|
||||||
void Duration::Reset()
|
void Duration::Reset()
|
||||||
{
|
{
|
||||||
_startTime = {};
|
_startTime = {};
|
||||||
@@ -99,6 +121,8 @@ DurationSelection::DurationSelection(QWidget *parent, bool showUnitSelection)
|
|||||||
SLOT(_UnitChanged(int)));
|
SLOT(_UnitChanged(int)));
|
||||||
|
|
||||||
QHBoxLayout *layout = new QHBoxLayout;
|
QHBoxLayout *layout = new QHBoxLayout;
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setSpacing(11);
|
||||||
layout->addWidget(_duration);
|
layout->addWidget(_duration);
|
||||||
if (showUnitSelection) {
|
if (showUnitSelection) {
|
||||||
layout->addWidget(_unitSelection);
|
layout->addWidget(_unitSelection);
|
||||||
@@ -137,3 +161,131 @@ void DurationSelection::_UnitChanged(int idx)
|
|||||||
|
|
||||||
emit UnitChanged(unit);
|
emit UnitChanged(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DurationConstraint::Save(obs_data_t *obj, const char *condName,
|
||||||
|
const char *secondsName, const char *unitName)
|
||||||
|
{
|
||||||
|
obs_data_set_int(obj, condName, static_cast<int>(_type));
|
||||||
|
_dur.Save(obj, secondsName, unitName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraint::Load(obs_data_t *obj, const char *condName,
|
||||||
|
const char *secondsName, const char *unitName)
|
||||||
|
{
|
||||||
|
// For backwards compatability 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, secondsName)) {
|
||||||
|
obs_data_set_int(obj, condName,
|
||||||
|
static_cast<int>(DurationCondition::MORE));
|
||||||
|
}
|
||||||
|
|
||||||
|
_type = static_cast<DurationCondition>(obs_data_get_int(obj, condName));
|
||||||
|
_dur.Load(obj, secondsName, unitName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DurationConstraint::DurationReached()
|
||||||
|
{
|
||||||
|
switch (_type) {
|
||||||
|
case DurationCondition::NONE:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case DurationCondition::MORE:
|
||||||
|
return _dur.DurationReached();
|
||||||
|
break;
|
||||||
|
case DurationCondition::EQUAL:
|
||||||
|
if (_dur.DurationReached() && !_timeReached) {
|
||||||
|
_timeReached = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DurationCondition::LESS:
|
||||||
|
return !_dur.DurationReached();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraint::Reset()
|
||||||
|
{
|
||||||
|
_timeReached = false;
|
||||||
|
_dur.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void populateConditions(QComboBox *list)
|
||||||
|
{
|
||||||
|
list->addItem(
|
||||||
|
obs_module_text("AdvSceneSwitcher.duration.condition.none"));
|
||||||
|
list->addItem(
|
||||||
|
obs_module_text("AdvSceneSwitcher.duration.condition.more"));
|
||||||
|
list->addItem(
|
||||||
|
obs_module_text("AdvSceneSwitcher.duration.condition.equal"));
|
||||||
|
list->addItem(
|
||||||
|
obs_module_text("AdvSceneSwitcher.duration.condition.less"));
|
||||||
|
}
|
||||||
|
|
||||||
|
DurationConstraintEdit::DurationConstraintEdit(QWidget *parent)
|
||||||
|
{
|
||||||
|
_condition = new QComboBox(parent);
|
||||||
|
_duration = new DurationSelection(parent);
|
||||||
|
_toggle = new QPushButton(parent);
|
||||||
|
_toggle->setMaximumSize(22, 22);
|
||||||
|
_toggle->setIcon(
|
||||||
|
QIcon(QString::fromStdString(getDataFilePath("res/time.svg"))));
|
||||||
|
populateConditions(_condition);
|
||||||
|
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(_ConditionChanged(int)));
|
||||||
|
QObject::connect(_duration, &DurationSelection::DurationChanged, this,
|
||||||
|
&DurationConstraintEdit::DurationChanged);
|
||||||
|
QObject::connect(_duration, &DurationSelection::UnitChanged, this,
|
||||||
|
&DurationConstraintEdit::UnitChanged);
|
||||||
|
QWidget::connect(_toggle, SIGNAL(clicked()), this,
|
||||||
|
SLOT(ToggleClicked()));
|
||||||
|
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout;
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setSpacing(11);
|
||||||
|
layout->addWidget(_toggle);
|
||||||
|
layout->addWidget(_condition);
|
||||||
|
layout->addWidget(_duration);
|
||||||
|
setLayout(layout);
|
||||||
|
Collapse(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraintEdit::SetValue(DurationConstraint &value)
|
||||||
|
{
|
||||||
|
_duration->SetDuration(value.GetDuration());
|
||||||
|
_condition->setCurrentIndex(static_cast<int>(value.GetCondition()));
|
||||||
|
_duration->setVisible(value.GetCondition() != DurationCondition::NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraintEdit::SetUnit(DurationUnit u)
|
||||||
|
{
|
||||||
|
_duration->SetUnit(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraintEdit::SetDuration(const Duration &d)
|
||||||
|
{
|
||||||
|
_duration->SetDuration(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraintEdit::_ConditionChanged(int value)
|
||||||
|
{
|
||||||
|
auto cond = static_cast<DurationCondition>(value);
|
||||||
|
Collapse(cond == DurationCondition::NONE);
|
||||||
|
emit ConditionChanged(cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraintEdit::ToggleClicked()
|
||||||
|
{
|
||||||
|
Collapse(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DurationConstraintEdit::Collapse(bool collapse)
|
||||||
|
{
|
||||||
|
_toggle->setVisible(collapse);
|
||||||
|
_duration->setVisible(!collapse);
|
||||||
|
_condition->setVisible(!collapse);
|
||||||
|
}
|
||||||
|
|||||||
49
src/file-selection.cpp
Normal file
49
src/file-selection.cpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#include "headers/file-selection.hpp"
|
||||||
|
|
||||||
|
#include <obs-module.h>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
|
FileSelection::FileSelection(FileSelection::Type type, QWidget *parent)
|
||||||
|
: _type(type), QWidget(parent)
|
||||||
|
{
|
||||||
|
_filePath = new QLineEdit();
|
||||||
|
_browseButton =
|
||||||
|
new QPushButton(obs_module_text("AdvSceneSwitcher.browse"));
|
||||||
|
|
||||||
|
QWidget::connect(_filePath, SIGNAL(editingFinished()), this,
|
||||||
|
SLOT(PathChange()));
|
||||||
|
QWidget::connect(_browseButton, SIGNAL(clicked()), this,
|
||||||
|
SLOT(BrowseButtonClicked()));
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout;
|
||||||
|
layout->addWidget(_filePath);
|
||||||
|
layout->addWidget(_browseButton);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSelection::SetPath(const QString &path)
|
||||||
|
{
|
||||||
|
_filePath->setText(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSelection::BrowseButtonClicked()
|
||||||
|
{
|
||||||
|
QString path;
|
||||||
|
if (_type == FileSelection::Type::WRITE) {
|
||||||
|
path = QFileDialog::getSaveFileName(this);
|
||||||
|
} else {
|
||||||
|
path = QFileDialog::getOpenFileName(this);
|
||||||
|
}
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_filePath->setText(path);
|
||||||
|
emit PathChanged(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSelection::PathChange()
|
||||||
|
{
|
||||||
|
emit PathChanged(_filePath->text());
|
||||||
|
}
|
||||||
@@ -1,14 +1,23 @@
|
|||||||
#include <QFileDialog>
|
|
||||||
|
|
||||||
#include "headers/advanced-scene-switcher.hpp"
|
#include "headers/advanced-scene-switcher.hpp"
|
||||||
#include "headers/utility.hpp"
|
#include "headers/utility.hpp"
|
||||||
#include "headers/version.h"
|
#include "headers/version.h"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#if __linux__
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#endif
|
||||||
|
|
||||||
QMetaObject::Connection inactivePluse;
|
QMetaObject::Connection inactivePluse;
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_close_clicked()
|
void AdvSceneSwitcher::on_close_clicked()
|
||||||
{
|
{
|
||||||
done(0);
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvSceneSwitcher::reject()
|
||||||
|
{
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::UpdateNonMatchingScene(const QString &name)
|
void AdvSceneSwitcher::UpdateNonMatchingScene(const QString &name)
|
||||||
@@ -156,8 +165,11 @@ void AdvSceneSwitcher::SetStopped()
|
|||||||
obs_module_text("AdvSceneSwitcher.generalTab.status.start"));
|
obs_module_text("AdvSceneSwitcher.generalTab.status.start"));
|
||||||
ui->pluginRunningText->setText(
|
ui->pluginRunningText->setText(
|
||||||
obs_module_text("AdvSceneSwitcher.status.inactive"));
|
obs_module_text("AdvSceneSwitcher.status.inactive"));
|
||||||
inactivePluse = PulseWidget(ui->pluginRunningText, QColor(Qt::red),
|
if (!switcher->disableHints) {
|
||||||
QColor(0, 0, 0, 0), "QLabel ");
|
inactivePluse = PulseWidget(ui->pluginRunningText,
|
||||||
|
QColor(Qt::red), QColor(0, 0, 0, 0),
|
||||||
|
"QLabel ");
|
||||||
|
}
|
||||||
currentStatusActive = false;
|
currentStatusActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,34 +219,6 @@ void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
|
|||||||
switcher->disableHints = state;
|
switcher->disableHints = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::AskBackup(obs_data_t *obj)
|
|
||||||
{
|
|
||||||
bool backupSettings = DisplayMessage(
|
|
||||||
obs_module_text("AdvSceneSwitcher.askBackup"), true);
|
|
||||||
|
|
||||||
if (!backupSettings) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString directory = QFileDialog::getSaveFileName(
|
|
||||||
nullptr,
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle"),
|
|
||||||
QDir::currentPath(),
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType"));
|
|
||||||
if (directory.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile file(directory);
|
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AdvSceneSwitcher::on_exportSettings_clicked()
|
void AdvSceneSwitcher::on_exportSettings_clicked()
|
||||||
{
|
{
|
||||||
QString directory = QFileDialog::getSaveFileName(
|
QString directory = QFileDialog::getSaveFileName(
|
||||||
@@ -402,9 +386,23 @@ void AdvSceneSwitcher::setTabOrder()
|
|||||||
connect(bar, &QTabBar::tabMoved, this, &AdvSceneSwitcher::on_tabMoved);
|
connect(bar, &QTabBar::tabMoved, this, &AdvSceneSwitcher::on_tabMoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool windowPosValid(QPoint pos)
|
||||||
|
{
|
||||||
|
#if __linux__
|
||||||
|
// QDesktopWidget::availableGeometry() is deprecated.
|
||||||
|
// Switch to QGuiApplication::screenAt() when it is available on most Linux platforms.
|
||||||
|
QDesktopWidget *desktop = QApplication::desktop();
|
||||||
|
auto screen = desktop->availableGeometry(pos);
|
||||||
|
return (pos.x() > screen.x()) && (pos.y() > screen.y()) &&
|
||||||
|
(pos.x() < screen.width() && (pos.y() < screen.height()));
|
||||||
|
#else
|
||||||
|
return !!QGuiApplication::screenAt(pos);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void AdvSceneSwitcher::restoreWindowGeo()
|
void AdvSceneSwitcher::restoreWindowGeo()
|
||||||
{
|
{
|
||||||
if (switcher->saveWindowGeo) {
|
if (switcher->saveWindowGeo && windowPosValid(switcher->windowPos)) {
|
||||||
this->resize(switcher->windowSize);
|
this->resize(switcher->windowSize);
|
||||||
this->move(switcher->windowPos);
|
this->move(switcher->windowPos);
|
||||||
}
|
}
|
||||||
@@ -889,4 +887,6 @@ void AdvSceneSwitcher::setupGeneralTab()
|
|||||||
QTimer *statusTimer = new QTimer(this);
|
QTimer *statusTimer = new QTimer(this);
|
||||||
connect(statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
|
connect(statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
|
||||||
statusTimer->start(1000);
|
statusTimer->start(1000);
|
||||||
|
|
||||||
|
setWindowTitle(windowTitle() + " - " + g_GIT_TAG);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "ui_advanced-scene-switcher.h"
|
#include "ui_advanced-scene-switcher.h"
|
||||||
#endif
|
#endif
|
||||||
#include "switcher-data-structs.hpp"
|
#include "switcher-data-structs.hpp"
|
||||||
|
#include "platform-funcs.hpp"
|
||||||
|
|
||||||
#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__)
|
#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__)
|
||||||
#define vblog(level, msg, ...) \
|
#define vblog(level, msg, ...) \
|
||||||
@@ -13,6 +14,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
class QCloseEvent;
|
class QCloseEvent;
|
||||||
|
class MacroActionEdit;
|
||||||
|
class MacroConditionEdit;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Advanced Scene Switcher window
|
* Advanced Scene Switcher window
|
||||||
@@ -27,6 +30,7 @@ public:
|
|||||||
|
|
||||||
AdvSceneSwitcher(QWidget *parent);
|
AdvSceneSwitcher(QWidget *parent);
|
||||||
|
|
||||||
|
void reject() override;
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
void SetStarted();
|
void SetStarted();
|
||||||
@@ -46,6 +50,14 @@ public:
|
|||||||
bool addNewMacro(std::string &name);
|
bool addNewMacro(std::string &name);
|
||||||
Macro *getSelectedMacro();
|
Macro *getSelectedMacro();
|
||||||
void SetEditMacro(Macro &m);
|
void SetEditMacro(Macro &m);
|
||||||
|
void HighlightAction(int idx);
|
||||||
|
void HighlightCondition(int idx);
|
||||||
|
void PopulateMacroActions(Macro &m, int afterIdx = 0);
|
||||||
|
void PopulateMacroConditions(Macro &m, int afterIdx = 0);
|
||||||
|
void ConnectControlSignals(MacroActionEdit *);
|
||||||
|
void ConnectControlSignals(MacroConditionEdit *);
|
||||||
|
void SwapActions(Macro *m, int pos1, int pos2);
|
||||||
|
void SwapConditions(Macro *m, int pos1, int pos2);
|
||||||
|
|
||||||
void loadUI();
|
void loadUI();
|
||||||
void setupGeneralTab();
|
void setupGeneralTab();
|
||||||
@@ -69,44 +81,10 @@ public:
|
|||||||
void setTabOrder();
|
void setTabOrder();
|
||||||
void restoreWindowGeo();
|
void restoreWindowGeo();
|
||||||
|
|
||||||
static void AskBackup(obs_data_t *obj);
|
|
||||||
|
|
||||||
static void addSelectionEntry(QComboBox *sel, const char *description,
|
|
||||||
bool selectable = false,
|
|
||||||
const char *tooltip = "");
|
|
||||||
static void populateSceneSelection(QComboBox *sel,
|
|
||||||
bool addPrevious = false,
|
|
||||||
bool addSceneGroup = false,
|
|
||||||
bool addSelect = true,
|
|
||||||
std::string selectText = "",
|
|
||||||
bool selectable = false);
|
|
||||||
|
|
||||||
static void populateTransitionSelection(QComboBox *sel,
|
|
||||||
bool addCurrent = true,
|
|
||||||
bool addSelect = true,
|
|
||||||
bool selectable = false);
|
|
||||||
static void populateWindowSelection(QComboBox *sel,
|
|
||||||
bool addSelect = true);
|
|
||||||
static void populateAudioSelection(QComboBox *sel,
|
|
||||||
bool addSelect = true);
|
|
||||||
static void populateVideoSelection(QComboBox *sel,
|
|
||||||
bool addScenes = true,
|
|
||||||
bool addSelect = true);
|
|
||||||
static void populateMediaSelection(QComboBox *sel,
|
|
||||||
bool addSelect = true);
|
|
||||||
static void populateProcessSelection(QComboBox *sel,
|
|
||||||
bool addSelect = true);
|
|
||||||
QMetaObject::Connection PulseWidget(QWidget *widget, QColor endColor,
|
|
||||||
QColor = QColor(0, 0, 0, 0),
|
|
||||||
QString specifier = "QLabel ");
|
|
||||||
|
|
||||||
void listAddClicked(QListWidget *list, SwitchWidget *newWidget,
|
|
||||||
QPushButton *addButton = nullptr,
|
|
||||||
QMetaObject::Connection *addHighlight = nullptr);
|
|
||||||
bool listMoveUp(QListWidget *list);
|
|
||||||
bool listMoveDown(QListWidget *list);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void MacroAdded(const QString &name);
|
||||||
|
void MacroRemoved(const QString &name);
|
||||||
|
void MacroRenamed(const QString &oldName, const QString newName);
|
||||||
void SceneGroupAdded(const QString &name);
|
void SceneGroupAdded(const QString &name);
|
||||||
void SceneGroupRemoved(const QString &name);
|
void SceneGroupRemoved(const QString &name);
|
||||||
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||||
@@ -137,12 +115,27 @@ public slots:
|
|||||||
void on_macroDown_clicked();
|
void on_macroDown_clicked();
|
||||||
void on_macroName_editingFinished();
|
void on_macroName_editingFinished();
|
||||||
void on_macros_currentRowChanged(int idx);
|
void on_macros_currentRowChanged(int idx);
|
||||||
|
void on_macros_itemChanged(QListWidgetItem *);
|
||||||
void on_conditionAdd_clicked();
|
void on_conditionAdd_clicked();
|
||||||
void on_conditionRemove_clicked();
|
void on_conditionRemove_clicked();
|
||||||
void on_actionAdd_clicked();
|
void on_actionAdd_clicked();
|
||||||
void on_actionRemove_clicked();
|
void on_actionRemove_clicked();
|
||||||
void showMacroContextMenu(const QPoint &);
|
void ShowMacroContextMenu(const QPoint &);
|
||||||
void copyMacro();
|
void ShowMacroActionsContextMenu(const QPoint &);
|
||||||
|
void ShowMacroConditionsContextMenu(const QPoint &);
|
||||||
|
void CopyMacro();
|
||||||
|
void ExpandAllActions();
|
||||||
|
void ExpandAllConditions();
|
||||||
|
void CollapseAllActions();
|
||||||
|
void CollapseAllConditions();
|
||||||
|
void AddMacroAction(int idx);
|
||||||
|
void RemoveMacroAction(int idx);
|
||||||
|
void MoveMacroActionUp(int idx);
|
||||||
|
void MoveMacroActionDown(int idx);
|
||||||
|
void AddMacroCondition(int idx);
|
||||||
|
void RemoveMacroCondition(int idx);
|
||||||
|
void MoveMacroConditionUp(int idx);
|
||||||
|
void MoveMacroConditionDown(int idx);
|
||||||
|
|
||||||
void on_screenRegionSwitches_currentRowChanged(int idx);
|
void on_screenRegionSwitches_currentRowChanged(int idx);
|
||||||
void on_showFrame_clicked();
|
void on_showFrame_clicked();
|
||||||
@@ -243,7 +236,9 @@ public slots:
|
|||||||
void on_clientSettings_toggled(bool on);
|
void on_clientSettings_toggled(bool on);
|
||||||
void on_clientHostname_textChanged(const QString &text);
|
void on_clientHostname_textChanged(const QString &text);
|
||||||
void on_clientPort_valueChanged(int value);
|
void on_clientPort_valueChanged(int value);
|
||||||
|
void on_sendSceneChange_stateChanged(int state);
|
||||||
void on_restrictSend_stateChanged(int state);
|
void on_restrictSend_stateChanged(int state);
|
||||||
|
void on_sendPreview_stateChanged(int state);
|
||||||
void on_clientReconnect_clicked();
|
void on_clientReconnect_clicked();
|
||||||
void updateClientStatus();
|
void updateClientStatus();
|
||||||
|
|
||||||
@@ -276,40 +271,17 @@ public slots:
|
|||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Windowtitle helper
|
|
||||||
******************************************************************************/
|
|
||||||
void GetWindowList(std::vector<std::string> &windows);
|
|
||||||
void GetWindowList(QStringList &windows);
|
|
||||||
void GetCurrentWindowTitle(std::string &title);
|
|
||||||
bool isFullscreen(std::string &title);
|
|
||||||
bool isMaximized(std::string &title);
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Screenregion helper
|
|
||||||
******************************************************************************/
|
|
||||||
std::pair<int, int> getCursorPos();
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Idle detection helper
|
|
||||||
******************************************************************************/
|
|
||||||
int secondsSinceLastInput();
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Executable helper
|
|
||||||
******************************************************************************/
|
|
||||||
void GetProcessList(QStringList &processes);
|
|
||||||
bool isInFocus(const QString &executable);
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Sceneswitch helper
|
* Sceneswitch helper
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void setNextTransition(sceneSwitchInfo &ssi, obs_source_t *currentSource,
|
void setNextTransition(const sceneSwitchInfo &ssi, obs_source_t *currentSource,
|
||||||
transitionData &td);
|
transitionData &td);
|
||||||
void overwriteTransitionOverride(sceneSwitchInfo ssi, transitionData &td);
|
void overwriteTransitionOverride(const sceneSwitchInfo &ssi,
|
||||||
void restoreTransitionOverride(obs_source_t *scene, transitionData td);
|
transitionData &td);
|
||||||
void switchScene(sceneSwitchInfo ssi);
|
void restoreTransitionOverride(obs_source_t *scene, const transitionData &td);
|
||||||
|
void switchScene(const sceneSwitchInfo &ssi);
|
||||||
|
void switchPreviewScene(const OBSWeakSource &ws);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Main SwitcherData
|
* Main SwitcherData
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
constexpr auto curl_library_name = "libcurl.dll";
|
constexpr auto curl_library_name = "libcurl.dll";
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
#define curl_library_name "libcurl.4.dylib"
|
constexpr auto curl_library_name = "libcurl.4.dylib";
|
||||||
#else
|
#else
|
||||||
#define curl_library_name "libcurl.so.4"
|
constexpr auto curl_library_name = "libcurl.so.4";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef CURL *(*initFunction)(void);
|
typedef CURL *(*initFunction)(void);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QPushButton>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include "obs-data.h"
|
#include "obs-data.h"
|
||||||
@@ -20,6 +21,8 @@ public:
|
|||||||
const char *unitName = "displayUnit");
|
const char *unitName = "displayUnit");
|
||||||
|
|
||||||
bool DurationReached();
|
bool DurationReached();
|
||||||
|
double TimeRemaining();
|
||||||
|
void SetTimeRemaining(double);
|
||||||
void Reset();
|
void Reset();
|
||||||
std::string ToString();
|
std::string ToString();
|
||||||
|
|
||||||
@@ -53,3 +56,57 @@ private:
|
|||||||
|
|
||||||
double _unitMultiplier;
|
double _unitMultiplier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class DurationCondition {
|
||||||
|
NONE,
|
||||||
|
MORE,
|
||||||
|
EQUAL,
|
||||||
|
LESS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DurationConstraint {
|
||||||
|
public:
|
||||||
|
void Save(obs_data_t *obj, const char *condName = "time_constraint",
|
||||||
|
const char *secondsName = "seconds",
|
||||||
|
const char *unitName = "displayUnit");
|
||||||
|
void Load(obs_data_t *obj, const char *condName = "time_constraint",
|
||||||
|
const char *secondsName = "seconds",
|
||||||
|
const char *unitName = "displayUnit");
|
||||||
|
void SetCondition(DurationCondition cond) { _type = cond; }
|
||||||
|
void SetDuration(const Duration &dur) { _dur = dur; }
|
||||||
|
void SetValue(double value) { _dur.seconds = value; }
|
||||||
|
void SetUnit(DurationUnit u) { _dur.displayUnit = u; }
|
||||||
|
DurationCondition GetCondition() { return _type; }
|
||||||
|
Duration GetDuration() { return _dur; }
|
||||||
|
bool DurationReached();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DurationCondition _type = DurationCondition::NONE;
|
||||||
|
Duration _dur;
|
||||||
|
bool _timeReached = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DurationConstraintEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
DurationConstraintEdit(QWidget *parent = nullptr);
|
||||||
|
void SetValue(DurationConstraint &value);
|
||||||
|
void SetUnit(DurationUnit u);
|
||||||
|
void SetDuration(const Duration &d);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void _ConditionChanged(int value);
|
||||||
|
void ToggleClicked();
|
||||||
|
signals:
|
||||||
|
void DurationChanged(double value);
|
||||||
|
void UnitChanged(DurationUnit u);
|
||||||
|
void ConditionChanged(DurationCondition value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Collapse(bool collapse);
|
||||||
|
|
||||||
|
DurationSelection *_duration;
|
||||||
|
QComboBox *_condition;
|
||||||
|
QPushButton *_toggle;
|
||||||
|
};
|
||||||
|
|||||||
30
src/headers/file-selection.hpp
Normal file
30
src/headers/file-selection.hpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class FileSelection : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class Type {
|
||||||
|
READ,
|
||||||
|
WRITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
FileSelection(FileSelection::Type type = FileSelection::Type::READ,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
void SetPath(const QString &);
|
||||||
|
QPushButton *Button() { return _browseButton; }
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void BrowseButtonClicked();
|
||||||
|
void PathChange();
|
||||||
|
signals:
|
||||||
|
void PathChanged(const QString &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type _type;
|
||||||
|
QLineEdit *_filePath;
|
||||||
|
QPushButton *_browseButton;
|
||||||
|
};
|
||||||
125
src/headers/hotkey.hpp
Normal file
125
src/headers/hotkey.hpp
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern bool canSimulateKeyPresses;
|
||||||
|
|
||||||
|
enum class HotkeyType {
|
||||||
|
Key_NoKey = 0,
|
||||||
|
|
||||||
|
Key_A,
|
||||||
|
Key_B,
|
||||||
|
Key_C,
|
||||||
|
Key_D,
|
||||||
|
Key_E,
|
||||||
|
Key_F,
|
||||||
|
Key_G,
|
||||||
|
Key_H,
|
||||||
|
Key_I,
|
||||||
|
Key_J,
|
||||||
|
Key_K,
|
||||||
|
Key_L,
|
||||||
|
Key_M,
|
||||||
|
Key_N,
|
||||||
|
Key_O,
|
||||||
|
Key_P,
|
||||||
|
Key_Q,
|
||||||
|
Key_R,
|
||||||
|
Key_S,
|
||||||
|
Key_T,
|
||||||
|
Key_U,
|
||||||
|
Key_V,
|
||||||
|
Key_W,
|
||||||
|
Key_X,
|
||||||
|
Key_Y,
|
||||||
|
Key_Z,
|
||||||
|
|
||||||
|
Key_0,
|
||||||
|
Key_1,
|
||||||
|
Key_2,
|
||||||
|
Key_3,
|
||||||
|
Key_4,
|
||||||
|
Key_5,
|
||||||
|
Key_6,
|
||||||
|
Key_7,
|
||||||
|
Key_8,
|
||||||
|
Key_9,
|
||||||
|
|
||||||
|
Key_F1,
|
||||||
|
Key_F2,
|
||||||
|
Key_F3,
|
||||||
|
Key_F4,
|
||||||
|
Key_F5,
|
||||||
|
Key_F6,
|
||||||
|
Key_F7,
|
||||||
|
Key_F8,
|
||||||
|
Key_F9,
|
||||||
|
Key_F10,
|
||||||
|
Key_F11,
|
||||||
|
Key_F12,
|
||||||
|
Key_F13,
|
||||||
|
Key_F14,
|
||||||
|
Key_F15,
|
||||||
|
Key_F16,
|
||||||
|
Key_F17,
|
||||||
|
Key_F18,
|
||||||
|
Key_F19,
|
||||||
|
Key_F20,
|
||||||
|
Key_F21,
|
||||||
|
Key_F22,
|
||||||
|
Key_F23,
|
||||||
|
Key_F24,
|
||||||
|
|
||||||
|
Key_Escape,
|
||||||
|
Key_Space,
|
||||||
|
Key_Return,
|
||||||
|
Key_Backspace,
|
||||||
|
Key_Tab,
|
||||||
|
|
||||||
|
Key_Shift_L,
|
||||||
|
Key_Shift_R,
|
||||||
|
Key_Control_L,
|
||||||
|
Key_Control_R,
|
||||||
|
Key_Alt_L,
|
||||||
|
Key_Alt_R,
|
||||||
|
Key_Win_L,
|
||||||
|
Key_Win_R,
|
||||||
|
Key_Apps,
|
||||||
|
|
||||||
|
Key_CapsLock,
|
||||||
|
Key_NumLock,
|
||||||
|
Key_ScrollLock,
|
||||||
|
|
||||||
|
Key_PrintScreen,
|
||||||
|
Key_Pause,
|
||||||
|
|
||||||
|
Key_Insert,
|
||||||
|
Key_Delete,
|
||||||
|
Key_PageUP,
|
||||||
|
Key_PageDown,
|
||||||
|
Key_Home,
|
||||||
|
Key_End,
|
||||||
|
|
||||||
|
Key_Left,
|
||||||
|
Key_Right,
|
||||||
|
Key_Up,
|
||||||
|
Key_Down,
|
||||||
|
|
||||||
|
Key_Numpad0,
|
||||||
|
Key_Numpad1,
|
||||||
|
Key_Numpad2,
|
||||||
|
Key_Numpad3,
|
||||||
|
Key_Numpad4,
|
||||||
|
Key_Numpad5,
|
||||||
|
Key_Numpad6,
|
||||||
|
Key_Numpad7,
|
||||||
|
Key_Numpad8,
|
||||||
|
Key_Numpad9,
|
||||||
|
|
||||||
|
Key_NumpadAdd,
|
||||||
|
Key_NumpadSubtract,
|
||||||
|
Key_NumpadMultiply,
|
||||||
|
Key_NumpadDivide,
|
||||||
|
Key_NumpadDecimal,
|
||||||
|
Key_NumpadEnter
|
||||||
|
};
|
||||||
|
|
||||||
|
void registerHotkeys();
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
enum class AudioAction {
|
enum class AudioAction {
|
||||||
@@ -15,7 +16,8 @@ public:
|
|||||||
void LogAction();
|
void LogAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create()
|
static std::shared_ptr<MacroAction> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionAudio>();
|
return std::make_shared<MacroActionAudio>();
|
||||||
@@ -27,7 +29,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionAudioEdit : public QWidget {
|
class MacroActionAudioEdit : public QWidget {
|
||||||
@@ -37,6 +39,7 @@ public:
|
|||||||
MacroActionAudioEdit(
|
MacroActionAudioEdit(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
std::shared_ptr<MacroActionAudio> entryData = nullptr);
|
std::shared_ptr<MacroActionAudio> entryData = nullptr);
|
||||||
|
void SetWidgetVisibility();
|
||||||
void UpdateEntryData();
|
void UpdateEntryData();
|
||||||
static QWidget *Create(QWidget *parent,
|
static QWidget *Create(QWidget *parent,
|
||||||
std::shared_ptr<MacroAction> action)
|
std::shared_ptr<MacroAction> action)
|
||||||
@@ -50,6 +53,8 @@ private slots:
|
|||||||
void SourceChanged(const QString &text);
|
void SourceChanged(const QString &text);
|
||||||
void ActionChanged(int value);
|
void ActionChanged(int value);
|
||||||
void VolumeChanged(int value);
|
void VolumeChanged(int value);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_audioSources;
|
QComboBox *_audioSources;
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QGroupBox>
|
|
||||||
#include <deque>
|
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "section.hpp"
|
|
||||||
|
|
||||||
struct MacroActionInfo {
|
struct MacroActionInfo {
|
||||||
using TCreateMethod = std::shared_ptr<MacroAction> (*)();
|
using TCreateMethod = std::shared_ptr<MacroAction> (*)();
|
||||||
@@ -20,35 +13,35 @@ struct MacroActionInfo {
|
|||||||
class MacroActionFactory {
|
class MacroActionFactory {
|
||||||
public:
|
public:
|
||||||
MacroActionFactory() = delete;
|
MacroActionFactory() = delete;
|
||||||
static bool Register(int id, MacroActionInfo);
|
static bool Register(const std::string &id, MacroActionInfo);
|
||||||
static std::shared_ptr<MacroAction> Create(const int id);
|
static std::shared_ptr<MacroAction> Create(const std::string &id);
|
||||||
static QWidget *CreateWidget(const int id, QWidget *parent,
|
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
||||||
std::shared_ptr<MacroAction> action);
|
std::shared_ptr<MacroAction> action);
|
||||||
static auto GetActionTypes() { return _methods; }
|
static auto GetActionTypes() { return _methods; }
|
||||||
|
static std::string GetActionName(const std::string &id);
|
||||||
|
static std::string GetIdByName(const QString &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::map<int, MacroActionInfo> _methods;
|
static std::map<std::string, MacroActionInfo> _methods;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionEdit : public QWidget {
|
class MacroActionEdit : public MacroSegmentEdit {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MacroActionEdit(QWidget *parent = nullptr,
|
MacroActionEdit(QWidget *parent = nullptr,
|
||||||
std::shared_ptr<MacroAction> * = nullptr, int type = 0,
|
std::shared_ptr<MacroAction> * = nullptr,
|
||||||
bool startCollapsed = false);
|
const std::string &id = "scene_switch");
|
||||||
void UpdateEntryData(int type);
|
void UpdateEntryData(const std::string &id);
|
||||||
void Collapse(bool collapsed);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void ActionSelectionChanged(int idx);
|
void ActionSelectionChanged(const QString &text);
|
||||||
|
|
||||||
protected:
|
|
||||||
QComboBox *_actionSelection;
|
|
||||||
Section *_section;
|
|
||||||
|
|
||||||
std::shared_ptr<MacroAction> *_entryData;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MacroSegment *Data();
|
||||||
|
|
||||||
|
QComboBox *_actionSelection;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroAction> *_entryData;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|||||||
65
src/headers/macro-action-file.hpp
Normal file
65
src/headers/macro-action-file.hpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "file-selection.hpp"
|
||||||
|
|
||||||
|
enum class FileAction {
|
||||||
|
WRITE,
|
||||||
|
APPEND,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionFile : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionFile>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||||
|
std::string _text = obs_module_text("AdvSceneSwitcher.enterText");
|
||||||
|
FileAction _action = FileAction::WRITE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionFileEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionFileEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionFile> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionFileEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionFile>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void PathChanged(const QString &text);
|
||||||
|
void TextChanged();
|
||||||
|
void ActionChanged(int value);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FileSelection *_filePath;
|
||||||
|
QPlainTextEdit *_text;
|
||||||
|
QComboBox *_actions;
|
||||||
|
std::shared_ptr<MacroActionFile> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
71
src/headers/macro-action-filter.hpp
Normal file
71
src/headers/macro-action-filter.hpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
|
enum class FilterAction {
|
||||||
|
ENABLE,
|
||||||
|
DISABLE,
|
||||||
|
SETTINGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionFilter : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionFilter>();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSWeakSource _source;
|
||||||
|
OBSWeakSource _filter;
|
||||||
|
FilterAction _action = FilterAction::ENABLE;
|
||||||
|
std::string _settings = "";
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionFilterEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionFilterEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionFilter> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionFilterEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionFilter>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void FilterChanged(const QString &text);
|
||||||
|
void ActionChanged(int value);
|
||||||
|
void GetSettingsClicked();
|
||||||
|
void SettingsChanged();
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_sources;
|
||||||
|
QComboBox *_filters;
|
||||||
|
QComboBox *_actions;
|
||||||
|
QPushButton *_getSettings;
|
||||||
|
QPlainTextEdit *_settings;
|
||||||
|
std::shared_ptr<MacroActionFilter> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetWidgetVisibility(bool);
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
92
src/headers/macro-action-hotkey.hpp
Normal file
92
src/headers/macro-action-hotkey.hpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "hotkey.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
class MacroActionHotkey : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionHotkey>();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSWeakSource _HotkeySource;
|
||||||
|
HotkeyType _key = HotkeyType::Key_NoKey;
|
||||||
|
bool _leftShift = false;
|
||||||
|
bool _rightShift = false;
|
||||||
|
bool _leftCtrl = false;
|
||||||
|
bool _rightCtrl = false;
|
||||||
|
bool _leftAlt = false;
|
||||||
|
bool _rightAlt = false;
|
||||||
|
bool _leftMeta = false;
|
||||||
|
bool _rightMeta = false;
|
||||||
|
int _duration = 300; // in ms
|
||||||
|
#ifdef __APPLE__
|
||||||
|
bool _onlySendToObs = true;
|
||||||
|
#else
|
||||||
|
bool _onlySendToObs = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionHotkeyEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionHotkeyEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionHotkey> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionHotkeyEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionHotkey>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void KeyChanged(int key);
|
||||||
|
void LShiftChanged(int state);
|
||||||
|
void RShiftChanged(int state);
|
||||||
|
void LCtrlChanged(int state);
|
||||||
|
void RCtrlChanged(int state);
|
||||||
|
void LAltChanged(int state);
|
||||||
|
void RAltChanged(int state);
|
||||||
|
void LMetaChanged(int state);
|
||||||
|
void RMetaChanged(int state);
|
||||||
|
void DurationChanged(int ms);
|
||||||
|
void OnlySendToOBSChanged(int state);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_keys;
|
||||||
|
QCheckBox *_leftShift;
|
||||||
|
QCheckBox *_rightShift;
|
||||||
|
QCheckBox *_leftCtrl;
|
||||||
|
QCheckBox *_rightCtrl;
|
||||||
|
QCheckBox *_leftAlt;
|
||||||
|
QCheckBox *_rightAlt;
|
||||||
|
QCheckBox *_leftMeta;
|
||||||
|
QCheckBox *_rightMeta;
|
||||||
|
QSpinBox *_duration;
|
||||||
|
QCheckBox *_onlySendToOBS;
|
||||||
|
QLabel *_noKeyPressSimulationWarning;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroActionHotkey> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetWarningVisibility();
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
64
src/headers/macro-action-macro.hpp
Normal file
64
src/headers/macro-action-macro.hpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "macro-selection.hpp"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
enum class PerformMacroAction {
|
||||||
|
PAUSE,
|
||||||
|
UNPAUSE,
|
||||||
|
RESET_COUNTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionMacro : public MacroRefAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionMacro>();
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformMacroAction _action = PerformMacroAction::PAUSE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionMacroEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionMacroEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionMacro> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionMacroEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionMacro>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void MacroChanged(const QString &text);
|
||||||
|
void MacroRemove(const QString &name);
|
||||||
|
void ActionChanged(int value);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MacroSelection *_macros;
|
||||||
|
QComboBox *_actions;
|
||||||
|
std::shared_ptr<MacroActionMacro> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
67
src/headers/macro-action-media.hpp
Normal file
67
src/headers/macro-action-media.hpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
enum class MediaAction {
|
||||||
|
PLAY,
|
||||||
|
PAUSE,
|
||||||
|
STOP,
|
||||||
|
RESTART,
|
||||||
|
NEXT,
|
||||||
|
PREVIOUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionMedia : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionMedia>();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSWeakSource _mediaSource;
|
||||||
|
MediaAction _action = MediaAction::PLAY;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionMediaEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionMediaEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionMedia> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionMediaEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionMedia>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void ActionChanged(int value);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_mediaSources;
|
||||||
|
QComboBox *_actions;
|
||||||
|
std::shared_ptr<MacroActionMedia> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
65
src/headers/macro-action-plugin-state.hpp
Normal file
65
src/headers/macro-action-plugin-state.hpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
enum class PluginStateAction {
|
||||||
|
STOP,
|
||||||
|
NO_MATCH_BEHAVIOUR,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionPluginState : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionPluginState>();
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginStateAction _action = PluginStateAction::STOP;
|
||||||
|
int _value = 0;
|
||||||
|
OBSWeakSource _scene;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionPluginStateEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionPluginStateEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionPluginState> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionPluginStateEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionPluginState>(
|
||||||
|
action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ActionChanged(int value);
|
||||||
|
void ValueChanged(int value);
|
||||||
|
void SceneChanged(const QString &text);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_actions;
|
||||||
|
QComboBox *_values;
|
||||||
|
QComboBox *_scenes;
|
||||||
|
std::shared_ptr<MacroActionPluginState> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetWidgetVisibility(PluginStateAction, int);
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
54
src/headers/macro-action-preview-scene.hpp
Normal file
54
src/headers/macro-action-preview-scene.hpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
|
|
||||||
|
class MacroActionPreviewScene : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionPreviewScene>();
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneSelection _scene;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionPreviewSceneEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionPreviewSceneEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionPreviewScene> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionPreviewSceneEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionPreviewScene>(
|
||||||
|
action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SceneSelectionWidget *_scenes;
|
||||||
|
std::shared_ptr<MacroActionPreviewScene> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <QDoubleSpinBox>
|
|
||||||
#include <QLabel>
|
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
enum class RecordAction {
|
enum class RecordAction {
|
||||||
STOP,
|
STOP,
|
||||||
START,
|
START,
|
||||||
@@ -16,7 +17,7 @@ public:
|
|||||||
void LogAction();
|
void LogAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create()
|
static std::shared_ptr<MacroAction> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionRecord>();
|
return std::make_shared<MacroActionRecord>();
|
||||||
@@ -26,7 +27,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionRecordEdit : public QWidget {
|
class MacroActionRecordEdit : public QWidget {
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
#ifdef REPLAYBUFFER_SUPPORTED
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <QDoubleSpinBox>
|
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
enum class ReplayBufferAction {
|
enum class ReplayBufferAction {
|
||||||
STOP,
|
STOP,
|
||||||
START,
|
START,
|
||||||
@@ -15,7 +18,7 @@ public:
|
|||||||
void LogAction();
|
void LogAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create()
|
static std::shared_ptr<MacroAction> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionReplayBuffer>();
|
return std::make_shared<MacroActionReplayBuffer>();
|
||||||
@@ -33,7 +36,7 @@ private:
|
|||||||
Duration _duration;
|
Duration _duration;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionReplayBufferEdit : public QWidget {
|
class MacroActionReplayBufferEdit : public QWidget {
|
||||||
@@ -64,3 +67,5 @@ private:
|
|||||||
QHBoxLayout *_mainLayout;
|
QHBoxLayout *_mainLayout;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "file-selection.hpp"
|
||||||
|
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
class MacroActionRun : public MacroAction {
|
class MacroActionRun : public MacroAction {
|
||||||
public:
|
public:
|
||||||
@@ -10,17 +13,19 @@ public:
|
|||||||
void LogAction();
|
void LogAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create()
|
static std::shared_ptr<MacroAction> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionRun>();
|
return std::make_shared<MacroActionRun>();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string _path = obs_module_text("AdvSceneSwitcher.enterPath");
|
std::string _path = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||||
|
QStringList _args;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionRunEdit : public QWidget {
|
class MacroActionRunEdit : public QWidget {
|
||||||
@@ -39,14 +44,23 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void FilePathChanged();
|
void PathChanged(const QString &text);
|
||||||
void BrowseButtonClicked();
|
void AddArg();
|
||||||
|
void RemoveArg();
|
||||||
|
void ArgUp();
|
||||||
|
void ArgDown();
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<MacroActionRun> _entryData;
|
std::shared_ptr<MacroActionRun> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLineEdit *_filePath;
|
FileSelection *_filePath;
|
||||||
QPushButton *_browseButton;
|
QListWidget *_argList;
|
||||||
|
QPushButton *_addArg;
|
||||||
|
QPushButton *_removeArg;
|
||||||
|
QPushButton *_argUp;
|
||||||
|
QPushButton *_argDown;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|||||||
72
src/headers/macro-action-scene-order.hpp
Normal file
72
src/headers/macro-action-scene-order.hpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
|
|
||||||
|
enum class SceneOrderAction {
|
||||||
|
MOVE_UP,
|
||||||
|
MOVE_DOWN,
|
||||||
|
MOVE_TOP,
|
||||||
|
MOVE_BOTTOM,
|
||||||
|
POSITION,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSceneOrder : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionSceneOrder>();
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneSelection _scene;
|
||||||
|
OBSWeakSource _source;
|
||||||
|
SceneOrderAction _action = SceneOrderAction::MOVE_UP;
|
||||||
|
int _position = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSceneOrderEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionSceneOrderEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionSceneOrder> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionSceneOrderEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionSceneOrder>(
|
||||||
|
action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void ActionChanged(int value);
|
||||||
|
void PositionChanged(int value);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SceneSelectionWidget *_scenes;
|
||||||
|
QComboBox *_sources;
|
||||||
|
QComboBox *_actions;
|
||||||
|
QSpinBox *_position;
|
||||||
|
std::shared_ptr<MacroActionSceneOrder> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
38
src/headers/macro-action-scene-swap.hpp
Normal file
38
src/headers/macro-action-scene-swap.hpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
|
class MacroActionSceneSwap : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionSceneSwap>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSceneSwapEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionSceneSwapEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionSceneSwap> entryData = nullptr);
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionSceneSwapEdit(
|
||||||
|
parent, std::dynamic_pointer_cast<MacroActionSceneSwap>(
|
||||||
|
action));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<MacroActionSceneSwap> _entryData;
|
||||||
|
};
|
||||||
@@ -3,13 +3,16 @@
|
|||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
// TODO: Switch to using SceneSelection class and widget instead
|
||||||
|
|
||||||
class MacroActionSwitchScene : public MacroAction, public SceneSwitcherEntry {
|
class MacroActionSwitchScene : public MacroAction, public SceneSwitcherEntry {
|
||||||
public:
|
public:
|
||||||
bool PerformAction();
|
bool PerformAction();
|
||||||
void LogAction();
|
void LogAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
|
||||||
static std::shared_ptr<MacroAction> Create()
|
static std::shared_ptr<MacroAction> Create()
|
||||||
{
|
{
|
||||||
@@ -21,7 +24,7 @@ private:
|
|||||||
const char *getType() { return "MacroActionSwitchScene"; }
|
const char *getType() { return "MacroActionSwitchScene"; }
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionSwitchSceneEdit : public SwitchWidget {
|
class MacroActionSwitchSceneEdit : public SwitchWidget {
|
||||||
@@ -42,6 +45,9 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void DurationChanged(double seconds);
|
void DurationChanged(double seconds);
|
||||||
|
void ChangeHeaderInfo(const QString &);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DurationSelection *_duration;
|
DurationSelection *_duration;
|
||||||
66
src/headers/macro-action-scene-transform.hpp
Normal file
66
src/headers/macro-action-scene-transform.hpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
|
|
||||||
|
class MacroActionSceneTransform : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionSceneTransform>();
|
||||||
|
}
|
||||||
|
std::string GetSettings();
|
||||||
|
void SetSettings(std::string &);
|
||||||
|
|
||||||
|
SceneSelection _scene;
|
||||||
|
OBSWeakSource _source;
|
||||||
|
struct obs_transform_info _info;
|
||||||
|
struct obs_sceneitem_crop _crop;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSceneTransformEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionSceneTransformEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionSceneTransform> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionSceneTransformEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionSceneTransform>(
|
||||||
|
action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void GetSettingsClicked();
|
||||||
|
void SettingsChanged();
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SceneSelectionWidget *_scenes;
|
||||||
|
QComboBox *_sources;
|
||||||
|
QPushButton *_getSettings;
|
||||||
|
QPlainTextEdit *_settings;
|
||||||
|
std::shared_ptr<MacroActionSceneTransform> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
66
src/headers/macro-action-scene-visibility.hpp
Normal file
66
src/headers/macro-action-scene-visibility.hpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
|
|
||||||
|
enum class SceneVisibilityAction {
|
||||||
|
SHOW,
|
||||||
|
HIDE,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSceneVisibility : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionSceneVisibility>();
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneSelection _scene;
|
||||||
|
OBSWeakSource _source;
|
||||||
|
SceneVisibilityAction _action = SceneVisibilityAction::SHOW;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSceneVisibilityEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionSceneVisibilityEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionSceneVisibility> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionSceneVisibilityEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionSceneVisibility>(
|
||||||
|
action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void ActionChanged(int value);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SceneSelectionWidget *_scenes;
|
||||||
|
QComboBox *_sources;
|
||||||
|
QComboBox *_actions;
|
||||||
|
std::shared_ptr<MacroActionSceneVisibility> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
72
src/headers/macro-action-source.hpp
Normal file
72
src/headers/macro-action-source.hpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
|
enum class SourceAction {
|
||||||
|
ENABLE,
|
||||||
|
DISABLE,
|
||||||
|
SETTINGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSource : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionSource>();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSWeakSource _source;
|
||||||
|
std::string _settings = "";
|
||||||
|
SourceAction _action = SourceAction::ENABLE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionSourceEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionSourceEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionSource> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionSourceEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionSource>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void ActionChanged(int value);
|
||||||
|
void GetSettingsClicked();
|
||||||
|
void SettingsChanged();
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_sources;
|
||||||
|
QComboBox *_actions;
|
||||||
|
QPushButton *_getSettings;
|
||||||
|
QPlainTextEdit *_settings;
|
||||||
|
QLabel *_warning;
|
||||||
|
std::shared_ptr<MacroActionSource> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetWidgetVisibility(bool);
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <QDoubleSpinBox>
|
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
enum class StreamAction {
|
enum class StreamAction {
|
||||||
STOP,
|
STOP,
|
||||||
START,
|
START,
|
||||||
@@ -14,7 +17,7 @@ public:
|
|||||||
void LogAction();
|
void LogAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create()
|
static std::shared_ptr<MacroAction> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionStream>();
|
return std::make_shared<MacroActionStream>();
|
||||||
@@ -28,7 +31,7 @@ private:
|
|||||||
Duration _retryCooldown;
|
Duration _retryCooldown;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionStreamEdit : public QWidget {
|
class MacroActionStreamEdit : public QWidget {
|
||||||
|
|||||||
72
src/headers/macro-action-timer.hpp
Normal file
72
src/headers/macro-action-timer.hpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
#include "macro-selection.hpp"
|
||||||
|
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
enum class TimerAction {
|
||||||
|
PAUSE,
|
||||||
|
CONTINUE,
|
||||||
|
RESET,
|
||||||
|
SET_TIME_REMAINING,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionTimer : public MacroRefAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionTimer>();
|
||||||
|
}
|
||||||
|
Duration _duration;
|
||||||
|
TimerAction _actionType = TimerAction::PAUSE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionTimerEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionTimerEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionTimer> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionTimerEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionTimer>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void MacroChanged(const QString &text);
|
||||||
|
void MacroRemove(const QString &name);
|
||||||
|
void DurationChanged(double value);
|
||||||
|
void DurationUnitChanged(DurationUnit unit);
|
||||||
|
void ActionTypeChanged(int value);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
|
||||||
|
MacroSelection *_macros;
|
||||||
|
DurationSelection *_duration;
|
||||||
|
QComboBox *_timerAction;
|
||||||
|
std::shared_ptr<MacroActionTimer> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
68
src/headers/macro-action-transition.hpp
Normal file
68
src/headers/macro-action-transition.hpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
#include "transition-selection.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
class MacroActionTransition : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionTransition>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _setDuration = true;
|
||||||
|
bool _setType = true;
|
||||||
|
TransitionSelection _transition;
|
||||||
|
Duration _duration;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionTransitionEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionTransitionEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionTransition> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionTransitionEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionTransition>(
|
||||||
|
action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SetTypeChanged(int state);
|
||||||
|
void SetDurationChanged(int state);
|
||||||
|
void TransitionChanged(const TransitionSelection &);
|
||||||
|
void DurationChanged(double seconds);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QCheckBox *_setType;
|
||||||
|
QCheckBox *_setDuration;
|
||||||
|
TransitionSelectionWidget *_transitions;
|
||||||
|
DurationSelection *_duration;
|
||||||
|
QHBoxLayout *_typeLayout;
|
||||||
|
QHBoxLayout *_durationLayout;
|
||||||
|
std::shared_ptr<MacroActionTransition> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
61
src/headers/macro-action-virtual-cam.hpp
Normal file
61
src/headers/macro-action-virtual-cam.hpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#ifdef VCAM_SUPPORTED
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "macro-action-edit.hpp"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
enum class VCamAction {
|
||||||
|
STOP,
|
||||||
|
START,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionVCam : public MacroAction {
|
||||||
|
public:
|
||||||
|
bool PerformAction();
|
||||||
|
void LogAction();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroAction> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroActionVCam>();
|
||||||
|
}
|
||||||
|
|
||||||
|
VCamAction _action = VCamAction::STOP;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroActionVCamEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroActionVCamEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroActionVCam> entryData = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroAction> action)
|
||||||
|
{
|
||||||
|
return new MacroActionVCamEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroActionVCam>(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ActionChanged(int value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_actions;
|
||||||
|
std::shared_ptr<MacroActionVCam> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHBoxLayout *_mainLayout;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <QDoubleSpinBox>
|
|
||||||
#include "macro-action-edit.hpp"
|
#include "macro-action-edit.hpp"
|
||||||
#include "duration-control.hpp"
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
enum class WaitType {
|
enum class WaitType {
|
||||||
FIXED,
|
FIXED,
|
||||||
RANDOM,
|
RANDOM,
|
||||||
@@ -13,7 +15,7 @@ public:
|
|||||||
bool PerformAction();
|
bool PerformAction();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroAction> Create()
|
static std::shared_ptr<MacroAction> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroActionWait>();
|
return std::make_shared<MacroActionWait>();
|
||||||
@@ -24,7 +26,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroActionWaitEdit : public QWidget {
|
class MacroActionWaitEdit : public QWidget {
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include "duration-control.hpp"
|
|
||||||
|
|
||||||
enum class AudioCondition {
|
enum class AudioCondition {
|
||||||
ABOVE,
|
ABOVE,
|
||||||
BELOW,
|
BELOW,
|
||||||
@@ -19,7 +17,8 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionAudio>();
|
return std::make_shared<MacroConditionAudio>();
|
||||||
@@ -33,13 +32,12 @@ public:
|
|||||||
OBSWeakSource _audioSource;
|
OBSWeakSource _audioSource;
|
||||||
int _volume = 0;
|
int _volume = 0;
|
||||||
AudioCondition _condition = AudioCondition::ABOVE;
|
AudioCondition _condition = AudioCondition::ABOVE;
|
||||||
Duration _duration;
|
|
||||||
obs_volmeter_t *_volmeter = nullptr;
|
obs_volmeter_t *_volmeter = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _peak = -std::numeric_limits<float>::infinity();
|
float _peak = -std::numeric_limits<float>::infinity();
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionAudioEdit : public QWidget {
|
class MacroConditionAudioEdit : public QWidget {
|
||||||
@@ -63,13 +61,13 @@ private slots:
|
|||||||
void SourceChanged(const QString &text);
|
void SourceChanged(const QString &text);
|
||||||
void VolumeThresholdChanged(int vol);
|
void VolumeThresholdChanged(int vol);
|
||||||
void ConditionChanged(int cond);
|
void ConditionChanged(int cond);
|
||||||
void DurationChanged(double seconds);
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_audioSources;
|
QComboBox *_audioSources;
|
||||||
QComboBox *_condition;
|
QComboBox *_condition;
|
||||||
QSpinBox *_volume;
|
QSpinBox *_volume;
|
||||||
DurationSelection *_duration;
|
|
||||||
VolControl *_volMeter = nullptr;
|
VolControl *_volMeter = nullptr;
|
||||||
std::shared_ptr<MacroConditionAudio> _entryData;
|
std::shared_ptr<MacroConditionAudio> _entryData;
|
||||||
|
|
||||||
|
|||||||
76
src/headers/macro-condition-cursor.hpp
Normal file
76
src/headers/macro-condition-cursor.hpp
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
enum class CursorCondition {
|
||||||
|
REGION,
|
||||||
|
MOVING,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionCursor : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionCursor>();
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorCondition _condition = CursorCondition::REGION;
|
||||||
|
int _minX = 0, _minY = 0, _maxX = 0, _maxY = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionCursorEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionCursorEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionCursor> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionCursorEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionCursor>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ConditionChanged(int cond);
|
||||||
|
void MinXChanged(int pos);
|
||||||
|
void MinYChanged(int pos);
|
||||||
|
void MaxXChanged(int pos);
|
||||||
|
void MaxYChanged(int pos);
|
||||||
|
void UpdateCursorPos();
|
||||||
|
void ToggleFrame();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QSpinBox *_minX;
|
||||||
|
QSpinBox *_minY;
|
||||||
|
QSpinBox *_maxX;
|
||||||
|
QSpinBox *_maxY;
|
||||||
|
QComboBox *_conditions;
|
||||||
|
QPushButton *_frameToggle;
|
||||||
|
QLabel *_xPos;
|
||||||
|
QLabel *_yPos;
|
||||||
|
std::shared_ptr<MacroConditionCursor> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetRegionSelectionVisible(bool);
|
||||||
|
void SetupFrame();
|
||||||
|
QTimer _timer;
|
||||||
|
QFrame _frame;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
82
src/headers/macro-condition-date.hpp
Normal file
82
src/headers/macro-condition-date.hpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QDateTimeEdit>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
enum class DateCondition {
|
||||||
|
AT,
|
||||||
|
AFTER,
|
||||||
|
BEFORE,
|
||||||
|
BETWEEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionDate : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionDate>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime _dateTime;
|
||||||
|
QDateTime _dateTime2;
|
||||||
|
bool _ignoreDate = false;
|
||||||
|
bool _ignoreTime = false;
|
||||||
|
bool _repeat = false;
|
||||||
|
Duration _duration;
|
||||||
|
DateCondition _condition = DateCondition::AT;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionDateEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionDateEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionDate> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionDateEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionDate>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ConditionChanged(int cond);
|
||||||
|
void DateTimeChanged(const QDateTime &datetime);
|
||||||
|
void DateTime2Changed(const QDateTime &datetime);
|
||||||
|
void IgnoreDateChanged(int state);
|
||||||
|
void IgnoreTimeChanged(int state);
|
||||||
|
void RepeatChanged(int state);
|
||||||
|
void DurationChanged(double seconds);
|
||||||
|
void DurationUnitChanged(DurationUnit unit);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_condition;
|
||||||
|
QDateTimeEdit *_dateTime;
|
||||||
|
QDateTimeEdit *_dateTime2;
|
||||||
|
QCheckBox *_ignoreDate;
|
||||||
|
QCheckBox *_ignoreTime;
|
||||||
|
QCheckBox *_repeat;
|
||||||
|
DurationSelection *_duration;
|
||||||
|
std::shared_ptr<MacroConditionDate> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ShowSecondDateSelection(bool visible);
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -1,12 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "advanced-scene-switcher.hpp"
|
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include "macro-condition-scene.hpp"
|
|
||||||
#include "section.hpp"
|
|
||||||
#include "utility.hpp"
|
|
||||||
|
|
||||||
#include <QGroupBox>
|
|
||||||
|
|
||||||
struct MacroConditionInfo {
|
struct MacroConditionInfo {
|
||||||
using TCreateMethod = std::shared_ptr<MacroCondition> (*)();
|
using TCreateMethod = std::shared_ptr<MacroCondition> (*)();
|
||||||
@@ -15,45 +8,51 @@ struct MacroConditionInfo {
|
|||||||
TCreateMethod _createFunc;
|
TCreateMethod _createFunc;
|
||||||
TCreateWidgetMethod _createWidgetFunc;
|
TCreateWidgetMethod _createWidgetFunc;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
|
bool _useDurationConstraint = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionFactory {
|
class MacroConditionFactory {
|
||||||
public:
|
public:
|
||||||
MacroConditionFactory() = delete;
|
MacroConditionFactory() = delete;
|
||||||
static bool Register(int id, MacroConditionInfo);
|
static bool Register(const std::string &, MacroConditionInfo);
|
||||||
static std::shared_ptr<MacroCondition> Create(const int id);
|
static std::shared_ptr<MacroCondition> Create(const std::string &);
|
||||||
static QWidget *CreateWidget(const int id, QWidget *parent,
|
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
||||||
std::shared_ptr<MacroCondition>);
|
std::shared_ptr<MacroCondition>);
|
||||||
static auto GetConditionTypes() { return _methods; }
|
static auto GetConditionTypes() { return _methods; }
|
||||||
|
static std::string GetConditionName(const std::string &);
|
||||||
|
static std::string GetIdByName(const QString &name);
|
||||||
|
static bool UsesDurationConstraint(const std::string &id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::map<int, MacroConditionInfo> _methods;
|
static std::map<std::string, MacroConditionInfo> _methods;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionEdit : public QWidget {
|
class MacroConditionEdit : public MacroSegmentEdit {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MacroConditionEdit(QWidget *parent = nullptr,
|
MacroConditionEdit(QWidget *parent = nullptr,
|
||||||
std::shared_ptr<MacroCondition> * = nullptr,
|
std::shared_ptr<MacroCondition> * = nullptr,
|
||||||
int type = 0, bool root = true,
|
const std::string &id = "scene", bool root = true);
|
||||||
bool startCollapsed = false);
|
|
||||||
bool IsRootNode();
|
bool IsRootNode();
|
||||||
void UpdateEntryData(int type);
|
void SetRootNode(bool);
|
||||||
void Collapse(bool collapsed);
|
void UpdateEntryData(const std::string &id);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void LogicSelectionChanged(int idx);
|
void LogicSelectionChanged(int idx);
|
||||||
void ConditionSelectionChanged(int idx);
|
void ConditionSelectionChanged(const QString &text);
|
||||||
|
void DurationChanged(double seconds);
|
||||||
protected:
|
void DurationConditionChanged(DurationCondition cond);
|
||||||
QComboBox *_logicSelection;
|
void DurationUnitChanged(DurationUnit unit);
|
||||||
QComboBox *_conditionSelection;
|
|
||||||
Section *_section;
|
|
||||||
|
|
||||||
std::shared_ptr<MacroCondition> *_entryData;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MacroSegment *Data();
|
||||||
|
|
||||||
|
QComboBox *_logicSelection;
|
||||||
|
QComboBox *_conditionSelection;
|
||||||
|
DurationConstraintEdit *_dur;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroCondition> *_entryData;
|
||||||
bool _isRoot = true;
|
bool _isRoot = true;
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
#include "file-selection.hpp"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
@@ -18,7 +20,8 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionFile>();
|
return std::make_shared<MacroConditionFile>();
|
||||||
@@ -39,7 +42,7 @@ private:
|
|||||||
QDateTime _lastMod;
|
QDateTime _lastMod;
|
||||||
size_t _lastHash = 0;
|
size_t _lastHash = 0;
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionFileEdit : public QWidget {
|
class MacroConditionFileEdit : public QWidget {
|
||||||
@@ -60,17 +63,17 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void FileTypeChanged(int index);
|
void FileTypeChanged(int index);
|
||||||
void FilePathChanged();
|
void PathChanged(const QString &text);
|
||||||
void BrowseButtonClicked();
|
|
||||||
void MatchTextChanged();
|
void MatchTextChanged();
|
||||||
void UseRegexChanged(int state);
|
void UseRegexChanged(int state);
|
||||||
void CheckModificationDateChanged(int state);
|
void CheckModificationDateChanged(int state);
|
||||||
void OnlyMatchIfChangedChanged(int state);
|
void OnlyMatchIfChangedChanged(int state);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_fileType;
|
QComboBox *_fileType;
|
||||||
QLineEdit *_filePath;
|
FileSelection *_filePath;
|
||||||
QPushButton *_browseButton;
|
|
||||||
QPlainTextEdit *_matchText;
|
QPlainTextEdit *_matchText;
|
||||||
QCheckBox *_useRegex;
|
QCheckBox *_useRegex;
|
||||||
QCheckBox *_checkModificationDate;
|
QCheckBox *_checkModificationDate;
|
||||||
|
|||||||
77
src/headers/macro-condition-filter.hpp
Normal file
77
src/headers/macro-condition-filter.hpp
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
|
enum class FilterCondition {
|
||||||
|
ENABLED,
|
||||||
|
DISABLED,
|
||||||
|
SETTINGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionFilter : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionFilter>();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSWeakSource _source;
|
||||||
|
OBSWeakSource _filter;
|
||||||
|
FilterCondition _condition = FilterCondition::ENABLED;
|
||||||
|
std::string _settings = "";
|
||||||
|
bool _regex = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionFilterEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionFilterEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionFilter> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionFilterEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionFilter>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void FilterChanged(const QString &text);
|
||||||
|
void ConditionChanged(int cond);
|
||||||
|
void GetSettingsClicked();
|
||||||
|
void SettingsChanged();
|
||||||
|
void RegexChanged(int);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_sources;
|
||||||
|
QComboBox *_filters;
|
||||||
|
QComboBox *_conditions;
|
||||||
|
QPushButton *_getSettings;
|
||||||
|
QPlainTextEdit *_settings;
|
||||||
|
QCheckBox *_regex;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroConditionFilter> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetSettingsSelectionVisible(bool visible);
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
54
src/headers/macro-condition-hotkey.hpp
Normal file
54
src/headers/macro-condition-hotkey.hpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
class MacroConditionHotkey : public MacroCondition {
|
||||||
|
public:
|
||||||
|
MacroConditionHotkey();
|
||||||
|
~MacroConditionHotkey();
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionHotkey>();
|
||||||
|
}
|
||||||
|
void SetPressed() { _pressed = true; }
|
||||||
|
|
||||||
|
std::string _name;
|
||||||
|
obs_hotkey_id _hotkeyID = OBS_INVALID_HOTKEY_ID;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _pressed = false;
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionHotkeyEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionHotkeyEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionHotkey> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionHotkeyEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionHotkey>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void NameChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QLineEdit *_name;
|
||||||
|
std::shared_ptr<MacroConditionHotkey> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include "duration-control.hpp"
|
|
||||||
|
|
||||||
class MacroConditionIdle : public MacroCondition {
|
class MacroConditionIdle : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionIdle>();
|
return std::make_shared<MacroConditionIdle>();
|
||||||
@@ -19,7 +20,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionIdleEdit : public QWidget {
|
class MacroConditionIdleEdit : public QWidget {
|
||||||
|
|||||||
91
src/headers/macro-condition-macro.hpp
Normal file
91
src/headers/macro-condition-macro.hpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include "macro-selection.hpp"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
enum class MacroConditionMacroType {
|
||||||
|
COUNT,
|
||||||
|
STATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CounterCondition {
|
||||||
|
BELOW,
|
||||||
|
ABOVE,
|
||||||
|
EQUAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionMacro : public MacroRefCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionMacro>();
|
||||||
|
}
|
||||||
|
|
||||||
|
MacroConditionMacroType _type = MacroConditionMacroType::STATE;
|
||||||
|
CounterCondition _counterCondition = CounterCondition::BELOW;
|
||||||
|
int _count = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool CheckCountCondition();
|
||||||
|
bool CheckStateCondition();
|
||||||
|
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionMacroEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionMacroEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionMacro> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionMacroEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionMacro>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void MacroChanged(const QString &text);
|
||||||
|
void MacroRemove(const QString &name);
|
||||||
|
void TypeChanged(int type);
|
||||||
|
void CountChanged(int value);
|
||||||
|
void ConditionChanged(int cond);
|
||||||
|
void ResetClicked();
|
||||||
|
void UpdateCount();
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
MacroSelection *_macros;
|
||||||
|
QComboBox *_types;
|
||||||
|
QComboBox *_counterConditions;
|
||||||
|
QSpinBox *_count;
|
||||||
|
QLabel *_currentCount;
|
||||||
|
QPushButton *_resetCount;
|
||||||
|
QHBoxLayout *_settingsLine1;
|
||||||
|
QHBoxLayout *_settingsLine2;
|
||||||
|
std::unique_ptr<QTimer> _timer;
|
||||||
|
std::shared_ptr<MacroConditionMacro> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ClearLayouts();
|
||||||
|
void SetupStateWidgets();
|
||||||
|
void SetupCountWidgets();
|
||||||
|
void ResetTimer();
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -39,7 +39,8 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionMedia>();
|
return std::make_shared<MacroConditionMedia>();
|
||||||
@@ -65,7 +66,7 @@ private:
|
|||||||
bool _playedToEnd = false;
|
bool _playedToEnd = false;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionMediaEdit : public QWidget {
|
class MacroConditionMediaEdit : public QWidget {
|
||||||
@@ -90,6 +91,8 @@ private slots:
|
|||||||
void TimeRestrictionChanged(int index);
|
void TimeRestrictionChanged(int index);
|
||||||
void TimeChanged(double seconds);
|
void TimeChanged(double seconds);
|
||||||
void TimeUnitChanged(DurationUnit unit);
|
void TimeUnitChanged(DurationUnit unit);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_mediaSources;
|
QComboBox *_mediaSources;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionPluginState>();
|
return std::make_shared<MacroConditionPluginState>();
|
||||||
@@ -22,7 +22,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionPluginStateEdit : public QWidget {
|
class MacroConditionPluginStateEdit : public QWidget {
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include <QWidget>
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
class MacroConditionProcess : public MacroCondition {
|
class MacroConditionProcess : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionProcess>();
|
return std::make_shared<MacroConditionProcess>();
|
||||||
@@ -19,7 +21,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionProcessEdit : public QWidget {
|
class MacroConditionProcessEdit : public QWidget {
|
||||||
@@ -41,6 +43,8 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void ProcessChanged(const QString &text);
|
void ProcessChanged(const QString &text);
|
||||||
void FocusChanged(int state);
|
void FocusChanged(int state);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_processSelection;
|
QComboBox *_processSelection;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include "duration-control.hpp"
|
|
||||||
|
|
||||||
enum class RecordState {
|
enum class RecordState {
|
||||||
STOP,
|
STOP,
|
||||||
@@ -15,18 +14,17 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionRecord>();
|
return std::make_shared<MacroConditionRecord>();
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordState _recordState;
|
RecordState _recordState;
|
||||||
Duration _duration;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionRecordEdit : public QWidget {
|
class MacroConditionRecordEdit : public QWidget {
|
||||||
@@ -47,12 +45,9 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void StateChanged(int value);
|
void StateChanged(int value);
|
||||||
void DurationChanged(double seconds);
|
|
||||||
void DurationUnitChanged(DurationUnit unit);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_recordState;
|
QComboBox *_recordState;
|
||||||
DurationSelection *_duration;
|
|
||||||
std::shared_ptr<MacroConditionRecord> _entryData;
|
std::shared_ptr<MacroConditionRecord> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "macro.hpp"
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QComboBox>
|
|
||||||
|
|
||||||
class MacroConditionRegion : public MacroCondition {
|
|
||||||
public:
|
|
||||||
bool CheckCondition();
|
|
||||||
bool Save(obs_data_t *obj);
|
|
||||||
bool Load(obs_data_t *obj);
|
|
||||||
int GetId() { return id; };
|
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
|
||||||
{
|
|
||||||
return std::make_shared<MacroConditionRegion>();
|
|
||||||
}
|
|
||||||
|
|
||||||
int _minX = 0, _minY = 0, _maxX = 0, _maxY = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool _registered;
|
|
||||||
static const int id;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MacroConditionRegionEdit : public QWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MacroConditionRegionEdit(
|
|
||||||
QWidget *parent,
|
|
||||||
std::shared_ptr<MacroConditionRegion> cond = nullptr);
|
|
||||||
void UpdateEntryData();
|
|
||||||
static QWidget *Create(QWidget *parent,
|
|
||||||
std::shared_ptr<MacroCondition> cond)
|
|
||||||
{
|
|
||||||
return new MacroConditionRegionEdit(
|
|
||||||
parent,
|
|
||||||
std::dynamic_pointer_cast<MacroConditionRegion>(cond));
|
|
||||||
}
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void MinXChanged(int pos);
|
|
||||||
void MinYChanged(int pos);
|
|
||||||
void MaxXChanged(int pos);
|
|
||||||
void MaxYChanged(int pos);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QSpinBox *_minX;
|
|
||||||
QSpinBox *_minY;
|
|
||||||
QSpinBox *_maxX;
|
|
||||||
QSpinBox *_maxY;
|
|
||||||
std::shared_ptr<MacroConditionRegion> _entryData;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _loading = true;
|
|
||||||
};
|
|
||||||
60
src/headers/macro-condition-replay-buffer.hpp
Normal file
60
src/headers/macro-condition-replay-buffer.hpp
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#ifdef REPLAYBUFFER_SUPPORTED
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
enum class ReplayBufferState {
|
||||||
|
STOP,
|
||||||
|
START,
|
||||||
|
SAVE,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionReplayBuffer : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionReplayBuffer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReplayBufferState _state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionReplayBufferEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionReplayBufferEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionReplayBuffer> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionReplayBufferEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionReplayBuffer>(
|
||||||
|
cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void StateChanged(int value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_state;
|
||||||
|
std::shared_ptr<MacroConditionReplayBuffer> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
76
src/headers/macro-condition-scene-order.hpp
Normal file
76
src/headers/macro-condition-scene-order.hpp
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
enum class SceneOrderCondition {
|
||||||
|
ABOVE,
|
||||||
|
BELOW,
|
||||||
|
POSITION,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionSceneOrder : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionSceneOrder>();
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneSelection _scene;
|
||||||
|
OBSWeakSource _source;
|
||||||
|
OBSWeakSource _source2;
|
||||||
|
int _position = 0;
|
||||||
|
SceneOrderCondition _condition = SceneOrderCondition::ABOVE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionSceneOrderEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionSceneOrderEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionSceneOrder> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionSceneOrderEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionSceneOrder>(
|
||||||
|
cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void Source2Changed(const QString &text);
|
||||||
|
void ConditionChanged(int cond);
|
||||||
|
void PositionChanged(int cond);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SceneSelectionWidget *_scenes;
|
||||||
|
QComboBox *_conditions;
|
||||||
|
QComboBox *_sources;
|
||||||
|
QComboBox *_sources2;
|
||||||
|
QSpinBox *_position;
|
||||||
|
QLabel *_posInfo;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroConditionSceneOrder> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetWidgetVisibility(bool showPos);
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
69
src/headers/macro-condition-scene-transform.hpp
Normal file
69
src/headers/macro-condition-scene-transform.hpp
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
|
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
|
class MacroConditionSceneTransform : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionSceneTransform>();
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneSelection _scene;
|
||||||
|
OBSWeakSource _source;
|
||||||
|
bool _regex = false;
|
||||||
|
std::string _settings = "";
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionSceneTransformEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionSceneTransformEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionSceneTransform> entryData =
|
||||||
|
nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionSceneTransformEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionSceneTransform>(
|
||||||
|
cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void GetSettingsClicked();
|
||||||
|
void SettingsChanged();
|
||||||
|
void RegexChanged(int);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SceneSelectionWidget *_scenes;
|
||||||
|
QComboBox *_sources;
|
||||||
|
QPushButton *_getSettings;
|
||||||
|
QPlainTextEdit *_settings;
|
||||||
|
QCheckBox *_regex;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroConditionSceneTransform> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
#include "scene-selection.hpp"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include "duration-control.hpp"
|
#include <QCheckBox>
|
||||||
|
|
||||||
enum class SceneType {
|
enum class SceneType {
|
||||||
CURRENT,
|
CURRENT,
|
||||||
PREVIOUS,
|
PREVIOUS,
|
||||||
|
CHANGED,
|
||||||
|
NOTCHANGED,
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionScene : public MacroCondition {
|
class MacroConditionScene : public MacroCondition {
|
||||||
@@ -14,19 +18,21 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionScene>();
|
return std::make_shared<MacroConditionScene>();
|
||||||
}
|
}
|
||||||
|
|
||||||
OBSWeakSource _scene;
|
bool _waitForTransition = false;
|
||||||
|
SceneSelection _scene;
|
||||||
SceneType _type;
|
SceneType _type;
|
||||||
Duration _duration;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::chrono::high_resolution_clock::time_point _lastSceneChangeTime{};
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionSceneEdit : public QWidget {
|
class MacroConditionSceneEdit : public QWidget {
|
||||||
@@ -46,17 +52,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void SceneChanged(const QString &text);
|
void SceneChanged(const SceneSelection &);
|
||||||
void TypeChanged(int value);
|
void TypeChanged(int value);
|
||||||
void DurationChanged(double seconds);
|
void WaitForTransitionChanged(int state);
|
||||||
void DurationUnitChanged(DurationUnit unit);
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_sceneSelection;
|
SceneSelectionWidget *_scenes;
|
||||||
QComboBox *_sceneType;
|
QComboBox *_sceneType;
|
||||||
DurationSelection *_duration;
|
QCheckBox *_waitForTransition;
|
||||||
std::shared_ptr<MacroConditionScene> _entryData;
|
std::shared_ptr<MacroConditionScene> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|||||||
74
src/headers/macro-condition-source.hpp
Normal file
74
src/headers/macro-condition-source.hpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
|
enum class SourceCondition {
|
||||||
|
ACTIVE,
|
||||||
|
SHOWING,
|
||||||
|
SETTINGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionSource : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionSource>();
|
||||||
|
}
|
||||||
|
|
||||||
|
OBSWeakSource _source = nullptr;
|
||||||
|
SourceCondition _condition = SourceCondition::ACTIVE;
|
||||||
|
std::string _settings = "";
|
||||||
|
bool _regex = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionSourceEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionSourceEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionSource> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionSourceEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionSource>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SourceChanged(const QString &text);
|
||||||
|
void ConditionChanged(int cond);
|
||||||
|
void GetSettingsClicked();
|
||||||
|
void SettingsChanged();
|
||||||
|
void RegexChanged(int);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_sources;
|
||||||
|
QComboBox *_conditions;
|
||||||
|
QPushButton *_getSettings;
|
||||||
|
QPlainTextEdit *_settings;
|
||||||
|
QCheckBox *_regex;
|
||||||
|
|
||||||
|
std::shared_ptr<MacroConditionSource> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetSettingsSelectionVisible(bool visible);
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include "duration-control.hpp"
|
|
||||||
|
|
||||||
enum class StreamState {
|
enum class StreamState {
|
||||||
STOP,
|
STOP,
|
||||||
@@ -14,18 +13,17 @@ public:
|
|||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionStream>();
|
return std::make_shared<MacroConditionStream>();
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamState _streamState;
|
StreamState _streamState;
|
||||||
Duration _duration;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionStreamEdit : public QWidget {
|
class MacroConditionStreamEdit : public QWidget {
|
||||||
@@ -46,12 +44,9 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void StateChanged(int value);
|
void StateChanged(int value);
|
||||||
void DurationChanged(double seconds);
|
|
||||||
void DurationUnitChanged(DurationUnit unit);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_streamState;
|
QComboBox *_streamState;
|
||||||
DurationSelection *_duration;
|
|
||||||
std::shared_ptr<MacroConditionStream> _entryData;
|
std::shared_ptr<MacroConditionStream> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
73
src/headers/macro-condition-timer.hpp
Normal file
73
src/headers/macro-condition-timer.hpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
class MacroConditionTimer : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionTimer>();
|
||||||
|
}
|
||||||
|
void Pause();
|
||||||
|
void Continue();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
Duration _duration;
|
||||||
|
bool _paused = false;
|
||||||
|
bool _saveRemaining = false;
|
||||||
|
double _remaining = 0.;
|
||||||
|
bool _oneshot = false;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionTimerEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionTimerEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionTimer> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionTimerEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionTimer>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void DurationChanged(double seconds);
|
||||||
|
void DurationUnitChanged(DurationUnit unit);
|
||||||
|
void SaveRemainingChanged(int state);
|
||||||
|
void AutoResetChanged(int state);
|
||||||
|
void PauseContinueClicked();
|
||||||
|
void ResetClicked();
|
||||||
|
void UpdateTimeRemaining();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetPauseContinueButtonLabel();
|
||||||
|
|
||||||
|
DurationSelection *_duration;
|
||||||
|
QCheckBox *_autoReset;
|
||||||
|
QCheckBox *_saveRemaining;
|
||||||
|
QPushButton *_reset;
|
||||||
|
QPushButton *_pauseConinue;
|
||||||
|
QLabel *_remaining;
|
||||||
|
std::shared_ptr<MacroConditionTimer> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTimer timer;
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
79
src/headers/macro-condition-transition.hpp
Normal file
79
src/headers/macro-condition-transition.hpp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
#include "transition-selection.hpp"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
enum class TransitionCondition {
|
||||||
|
CURRENT,
|
||||||
|
DURATION,
|
||||||
|
STARTED,
|
||||||
|
ENDED,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionTransition : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionTransition>();
|
||||||
|
}
|
||||||
|
void ConnectToTransitionSignals();
|
||||||
|
void DisconnectTransitionSignals();
|
||||||
|
|
||||||
|
TransitionCondition _condition = TransitionCondition::CURRENT;
|
||||||
|
TransitionSelection _transition;
|
||||||
|
Duration _duration;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void TransitionStarted(void *data, calldata_t *);
|
||||||
|
static void TransitionEnded(void *data, calldata_t *);
|
||||||
|
|
||||||
|
bool _started = false;
|
||||||
|
bool _ended = false;
|
||||||
|
std::chrono::high_resolution_clock::time_point _lastTransitionEndTime{};
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionTransitionEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionTransitionEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionTransition> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionTransitionEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionTransition>(
|
||||||
|
cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ConditionChanged(int cond);
|
||||||
|
void TransitionChanged(const TransitionSelection &);
|
||||||
|
void DurationChanged(double seconds);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_conditions;
|
||||||
|
TransitionSelectionWidget *_transitions;
|
||||||
|
DurationSelection *_duration;
|
||||||
|
QLabel *_durationSuffix;
|
||||||
|
std::shared_ptr<MacroConditionTransition> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
|
#include "screenshot-helper.hpp"
|
||||||
|
#include "file-selection.hpp"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include "duration-control.hpp"
|
#include <opencv2/opencv.hpp>
|
||||||
#include "screenshot-helper.hpp"
|
|
||||||
|
|
||||||
enum class VideoCondition {
|
enum class VideoCondition {
|
||||||
MATCH,
|
MATCH,
|
||||||
@@ -12,14 +16,26 @@ enum class VideoCondition {
|
|||||||
HAS_NOT_CHANGED,
|
HAS_NOT_CHANGED,
|
||||||
HAS_CHANGED,
|
HAS_CHANGED,
|
||||||
NO_IMAGE,
|
NO_IMAGE,
|
||||||
|
PATTERN,
|
||||||
|
OBJECT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PatternMatchData {
|
||||||
|
cv::Mat4b rgbaPattern;
|
||||||
|
cv::Mat3b rgbPattern;
|
||||||
|
cv::Mat1b mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int minMinNeighbors = 3;
|
||||||
|
constexpr int maxMinNeighbors = 6;
|
||||||
|
|
||||||
class MacroConditionVideo : public MacroCondition {
|
class MacroConditionVideo : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
QImage GetMatchImage() { return _matchImage; };
|
QImage GetMatchImage() { return _matchImage; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
@@ -27,19 +43,65 @@ public:
|
|||||||
}
|
}
|
||||||
void GetScreenshot();
|
void GetScreenshot();
|
||||||
bool LoadImageFromFile();
|
bool LoadImageFromFile();
|
||||||
|
bool LoadModelData(std::string &path);
|
||||||
|
std::string GetModelDataPath() { return _modelDataPath; }
|
||||||
|
void ResetLastMatch() { _lastMatchResult = false; }
|
||||||
|
|
||||||
OBSWeakSource _videoSource;
|
OBSWeakSource _videoSource;
|
||||||
VideoCondition _condition = VideoCondition::MATCH;
|
VideoCondition _condition = VideoCondition::MATCH;
|
||||||
Duration _duration;
|
|
||||||
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||||
|
bool _useAlphaAsMask = false;
|
||||||
|
PatternMatchData _patternData;
|
||||||
|
double _patternThreshold = 0.8;
|
||||||
|
cv::CascadeClassifier _objectCascade;
|
||||||
|
double _scaleFactor = 1.1;
|
||||||
|
int _minNeighbors = minMinNeighbors;
|
||||||
|
int _minSizeX = 0;
|
||||||
|
int _minSizeY = 0;
|
||||||
|
int _maxSizeX = 0;
|
||||||
|
int _maxSizeY = 0;
|
||||||
|
|
||||||
|
bool _throttleEnabled = false;
|
||||||
|
int _throttleCount = 3;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool ScreenshotContainsPattern();
|
||||||
|
bool ScreenshotContainsObject();
|
||||||
bool Compare();
|
bool Compare();
|
||||||
|
bool CheckShouldBeSkipped();
|
||||||
|
|
||||||
std::unique_ptr<AdvSSScreenshotObj> _screenshotData = nullptr;
|
std::unique_ptr<AdvSSScreenshotObj> _screenshotData = nullptr;
|
||||||
QImage _matchImage;
|
QImage _matchImage;
|
||||||
|
std::string _modelDataPath =
|
||||||
|
obs_get_module_data_path(obs_current_module()) +
|
||||||
|
std::string(
|
||||||
|
"/res/cascadeClassifiers/haarcascade_frontalface_alt.xml");
|
||||||
|
bool _lastMatchResult = false;
|
||||||
|
int _runCount = 0;
|
||||||
|
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThresholdSlider : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThresholdSlider(double min = 0., double max = 1.,
|
||||||
|
const QString &label = "threshold",
|
||||||
|
const QString &description = "", QWidget *parent = 0);
|
||||||
|
void SetDoubleValue(double);
|
||||||
|
public slots:
|
||||||
|
void NotifyValueChanged(int value);
|
||||||
|
signals:
|
||||||
|
void DoubleValueChanged(double value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetDoubleValueText(double);
|
||||||
|
QLabel *_value;
|
||||||
|
QSlider *_slider;
|
||||||
|
double _scale = 100.0;
|
||||||
|
int _precision = 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionVideoEdit : public QWidget {
|
class MacroConditionVideoEdit : public QWidget {
|
||||||
@@ -59,24 +121,58 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UpdatePreviewTooltip();
|
void UpdatePreviewTooltip();
|
||||||
void SetFilePath(const QString &text);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void SourceChanged(const QString &text);
|
void SourceChanged(const QString &text);
|
||||||
void ConditionChanged(int cond);
|
void ConditionChanged(int cond);
|
||||||
void FilePathChanged();
|
void ImagePathChanged(const QString &text);
|
||||||
void BrowseButtonClicked();
|
void ImageBrowseButtonClicked();
|
||||||
void DurationChanged(double seconds);
|
void PatternThresholdChanged(double);
|
||||||
void DurationUnitChanged(DurationUnit unit);
|
void UseAlphaAsMaskChanged(int value);
|
||||||
|
|
||||||
|
void ModelPathChanged(const QString &text);
|
||||||
|
void ObjectScaleThresholdChanged(double);
|
||||||
|
void MinNeighborsChanged(int value);
|
||||||
|
void MinSizeXChanged(int value);
|
||||||
|
void MinSizeYChanged(int value);
|
||||||
|
void MaxSizeXChanged(int value);
|
||||||
|
void MaxSizeYChanged(int value);
|
||||||
|
|
||||||
|
void ThrottleEnableChanged(int value);
|
||||||
|
void ThrottleCountChanged(int value);
|
||||||
|
void ShowMatchClicked();
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_videoSelection;
|
QComboBox *_videoSelection;
|
||||||
DurationSelection *_duration;
|
|
||||||
QComboBox *_condition;
|
QComboBox *_condition;
|
||||||
QLineEdit *_filePath;
|
|
||||||
QPushButton *_browseButton;
|
FileSelection *_imagePath;
|
||||||
|
ThresholdSlider *_patternThreshold;
|
||||||
|
QCheckBox *_useAlphaAsMask;
|
||||||
|
|
||||||
|
FileSelection *_modelDataPath;
|
||||||
|
QHBoxLayout *_modelPathLayout;
|
||||||
|
ThresholdSlider *_objectScaleThreshold;
|
||||||
|
QHBoxLayout *_neighborsControlLayout;
|
||||||
|
QSpinBox *_minNeighbors;
|
||||||
|
QLabel *_minNeighborsDescription;
|
||||||
|
QHBoxLayout *_minSizeControlLayout;
|
||||||
|
QSpinBox *_minSizeX;
|
||||||
|
QSpinBox *_minSizeY;
|
||||||
|
QHBoxLayout *_maxSizeControlLayout;
|
||||||
|
QSpinBox *_maxSizeX;
|
||||||
|
QSpinBox *_maxSizeY;
|
||||||
|
|
||||||
|
QHBoxLayout *_throttleControlLayout;
|
||||||
|
QCheckBox *_throttleEnable;
|
||||||
|
QSpinBox *_throttleCount;
|
||||||
|
QPushButton *_showMatch;
|
||||||
|
|
||||||
std::shared_ptr<MacroConditionVideo> _entryData;
|
std::shared_ptr<MacroConditionVideo> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SetWidgetVisibility();
|
||||||
bool _loading = true;
|
bool _loading = true;
|
||||||
};
|
};
|
||||||
|
|||||||
58
src/headers/macro-condition-virtual-cam.hpp
Normal file
58
src/headers/macro-condition-virtual-cam.hpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#ifdef VCAM_SUPPORTED
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "macro.hpp"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
enum class VCamState {
|
||||||
|
STOP,
|
||||||
|
START,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionVCam : public MacroCondition {
|
||||||
|
public:
|
||||||
|
bool CheckCondition();
|
||||||
|
bool Save(obs_data_t *obj);
|
||||||
|
bool Load(obs_data_t *obj);
|
||||||
|
std::string GetId() { return id; };
|
||||||
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
|
{
|
||||||
|
return std::make_shared<MacroConditionVCam>();
|
||||||
|
}
|
||||||
|
|
||||||
|
VCamState _state;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool _registered;
|
||||||
|
static const std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroConditionVCamEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroConditionVCamEdit(
|
||||||
|
QWidget *parent,
|
||||||
|
std::shared_ptr<MacroConditionVCam> cond = nullptr);
|
||||||
|
void UpdateEntryData();
|
||||||
|
static QWidget *Create(QWidget *parent,
|
||||||
|
std::shared_ptr<MacroCondition> cond)
|
||||||
|
{
|
||||||
|
return new MacroConditionVCamEdit(
|
||||||
|
parent,
|
||||||
|
std::dynamic_pointer_cast<MacroConditionVCam>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void StateChanged(int value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QComboBox *_states;
|
||||||
|
std::shared_ptr<MacroConditionVCam> _entryData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _loading = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "macro.hpp"
|
#include "macro.hpp"
|
||||||
#include <QWidget>
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
|
||||||
class MacroConditionWindow : public MacroCondition {
|
class MacroConditionWindow : public MacroCondition {
|
||||||
public:
|
public:
|
||||||
bool CheckCondition();
|
bool CheckCondition();
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
int GetId() { return id; };
|
std::string GetShortDesc();
|
||||||
|
std::string GetId() { return id; };
|
||||||
static std::shared_ptr<MacroCondition> Create()
|
static std::shared_ptr<MacroCondition> Create()
|
||||||
{
|
{
|
||||||
return std::make_shared<MacroConditionWindow>();
|
return std::make_shared<MacroConditionWindow>();
|
||||||
@@ -24,10 +26,11 @@ public:
|
|||||||
bool _fullscreen = false;
|
bool _fullscreen = false;
|
||||||
bool _maximized = false;
|
bool _maximized = false;
|
||||||
bool _focus = true;
|
bool _focus = true;
|
||||||
|
bool _windowFocusChanged = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _registered;
|
static bool _registered;
|
||||||
static const int id;
|
static const std::string id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroConditionWindowEdit : public QWidget {
|
class MacroConditionWindowEdit : public QWidget {
|
||||||
@@ -50,13 +53,17 @@ private slots:
|
|||||||
void WindowChanged(const QString &text);
|
void WindowChanged(const QString &text);
|
||||||
void FullscreenChanged(int state);
|
void FullscreenChanged(int state);
|
||||||
void MaximizedChanged(int state);
|
void MaximizedChanged(int state);
|
||||||
void FocusChanged(int state);
|
void FocusedChanged(int state);
|
||||||
|
void WindowFocusChanged(int state);
|
||||||
|
signals:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QComboBox *_windowSelection;
|
QComboBox *_windowSelection;
|
||||||
QCheckBox *_fullscreen;
|
QCheckBox *_fullscreen;
|
||||||
QCheckBox *_maximized;
|
QCheckBox *_maximized;
|
||||||
QCheckBox *_focused;
|
QCheckBox *_focused;
|
||||||
|
QCheckBox *_windowFocusChanged;
|
||||||
std::shared_ptr<MacroConditionWindow> _entryData;
|
std::shared_ptr<MacroConditionWindow> _entryData;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
31
src/headers/macro-controls.hpp
Normal file
31
src/headers/macro-controls.hpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class MacroEntryControls : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MacroEntryControls(const int animationDuration = 300,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
|
void Show(bool visible = true);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void Add();
|
||||||
|
void Remove();
|
||||||
|
void Up();
|
||||||
|
void Down();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPushButton *_add;
|
||||||
|
QPushButton *_remove;
|
||||||
|
QPushButton *_up;
|
||||||
|
QPushButton *_down;
|
||||||
|
QPropertyAnimation *_animation = nullptr;
|
||||||
|
};
|
||||||
72
src/headers/macro-segment.hpp
Normal file
72
src/headers/macro-segment.hpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QWidget>
|
||||||
|
#include <obs.hpp>
|
||||||
|
|
||||||
|
class MacroSegment {
|
||||||
|
public:
|
||||||
|
void SetIndex(int idx) { _idx = idx; }
|
||||||
|
int GetIndex() { return _idx; }
|
||||||
|
void SetCollapsed(bool collapsed) { _collapsed = collapsed; }
|
||||||
|
bool GetCollapsed() { return _collapsed; }
|
||||||
|
virtual bool Save(obs_data_t *obj) = 0;
|
||||||
|
virtual bool Load(obs_data_t *obj) = 0;
|
||||||
|
virtual std::string GetShortDesc();
|
||||||
|
virtual std::string GetId() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _idx;
|
||||||
|
bool _collapsed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Section;
|
||||||
|
class QLabel;
|
||||||
|
class MacroEntryControls;
|
||||||
|
|
||||||
|
class MacroSegmentEdit : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroSegmentEdit(QWidget *parent = nullptr);
|
||||||
|
// Use this function to avoid accidental edits when scrolling through
|
||||||
|
// list of actions and conditions
|
||||||
|
void SetFocusPolicyOfWidgets();
|
||||||
|
void SetCollapsed(bool collapsed);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void HeaderInfoChanged(const QString &);
|
||||||
|
void Add();
|
||||||
|
void Remove();
|
||||||
|
void Up();
|
||||||
|
void Down();
|
||||||
|
void Collapsed(bool);
|
||||||
|
signals:
|
||||||
|
void MacroAdded(const QString &name);
|
||||||
|
void MacroRemoved(const QString &name);
|
||||||
|
void MacroRenamed(const QString &oldName, const QString newName);
|
||||||
|
void SceneGroupAdded(const QString &name);
|
||||||
|
void SceneGroupRemoved(const QString &name);
|
||||||
|
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||||
|
void AddAt(int idx);
|
||||||
|
void RemoveAt(int idx);
|
||||||
|
void UpAt(int idx);
|
||||||
|
void DownAt(int idx);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void enterEvent(QEvent *e);
|
||||||
|
void leaveEvent(QEvent *e);
|
||||||
|
|
||||||
|
Section *_section;
|
||||||
|
QLabel *_headerInfo;
|
||||||
|
MacroEntryControls *_controls;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual MacroSegment *Data() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MouseWheelWidgetAdjustmentGuard : public QObject {
|
||||||
|
public:
|
||||||
|
explicit MouseWheelWidgetAdjustmentGuard(QObject *parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *o, QEvent *e) override;
|
||||||
|
};
|
||||||
17
src/headers/macro-selection.hpp
Normal file
17
src/headers/macro-selection.hpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
class Macro;
|
||||||
|
|
||||||
|
class MacroSelection : public QComboBox {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MacroSelection(QWidget *parent);
|
||||||
|
void SetCurrentMacro(Macro *);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void MacroAdd(const QString &name);
|
||||||
|
void MacroRemove(const QString &name);
|
||||||
|
void MacroRename(const QString &oldName, const QString &newName);
|
||||||
|
};
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "macro-segment.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <obs.hpp>
|
#include <obs.hpp>
|
||||||
#include <obs-module.h>
|
#include <obs-module.h>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
constexpr auto macro_func = 10;
|
constexpr auto macro_func = 10;
|
||||||
constexpr auto default_priority_10 = macro_func;
|
constexpr auto default_priority_10 = macro_func;
|
||||||
@@ -33,56 +37,110 @@ struct LogicTypeInfo {
|
|||||||
std::string _name;
|
std::string _name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroCondition {
|
class MacroCondition : public MacroSegment {
|
||||||
public:
|
public:
|
||||||
virtual bool CheckCondition() = 0;
|
virtual bool CheckCondition() = 0;
|
||||||
virtual bool Save(obs_data_t *obj) = 0;
|
virtual bool Save(obs_data_t *obj) = 0;
|
||||||
virtual bool Load(obs_data_t *obj) = 0;
|
virtual bool Load(obs_data_t *obj) = 0;
|
||||||
virtual int GetId() = 0;
|
|
||||||
LogicType GetLogicType() { return _logic; }
|
LogicType GetLogicType() { return _logic; }
|
||||||
void SetLogicType(LogicType logic) { _logic = logic; }
|
void SetLogicType(LogicType logic) { _logic = logic; }
|
||||||
|
|
||||||
static const std::map<LogicType, LogicTypeInfo> logicTypes;
|
static const std::map<LogicType, LogicTypeInfo> logicTypes;
|
||||||
|
|
||||||
|
bool DurationReached() { return _duration.DurationReached(); }
|
||||||
|
void ResetDuration() { _duration.Reset(); }
|
||||||
|
DurationConstraint GetDurationConstraint() { return _duration; }
|
||||||
|
void SetDurationConstraint(const DurationConstraint &dur);
|
||||||
|
void SetDurationCondition(DurationCondition cond);
|
||||||
|
void SetDurationUnit(DurationUnit u);
|
||||||
|
void SetDuration(double seconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LogicType _logic;
|
LogicType _logic;
|
||||||
|
DurationConstraint _duration;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MacroAction {
|
class MacroAction : public MacroSegment {
|
||||||
public:
|
public:
|
||||||
virtual bool PerformAction() = 0;
|
virtual bool PerformAction() = 0;
|
||||||
virtual bool Save(obs_data_t *obj) = 0;
|
virtual bool Save(obs_data_t *obj) = 0;
|
||||||
virtual bool Load(obs_data_t *obj) = 0;
|
virtual bool Load(obs_data_t *obj) = 0;
|
||||||
virtual int GetId() = 0;
|
|
||||||
virtual void LogAction();
|
virtual void LogAction();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Macro {
|
class Macro {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Macro(std::string name = "");
|
Macro(const std::string &name = "");
|
||||||
virtual ~Macro();
|
virtual ~Macro();
|
||||||
|
|
||||||
bool CeckMatch();
|
bool CeckMatch();
|
||||||
bool PerformAction();
|
bool PerformAction();
|
||||||
bool Matched() { return _matched; }
|
bool Matched() { return _matched; }
|
||||||
std::string Name() { return _name; }
|
std::string Name() { return _name; }
|
||||||
void SetName(std::string name) { _name = name; }
|
void SetName(const std::string &name);
|
||||||
|
void SetPaused(bool pause = true) { _paused = pause; }
|
||||||
|
bool Paused() { return _paused; }
|
||||||
|
int GetCount() { return _count; };
|
||||||
|
void ResetCount() { _count = 0; };
|
||||||
std::deque<std::shared_ptr<MacroCondition>> &Conditions()
|
std::deque<std::shared_ptr<MacroCondition>> &Conditions()
|
||||||
{
|
{
|
||||||
return _conditions;
|
return _conditions;
|
||||||
}
|
}
|
||||||
|
void UpdateActionIndices();
|
||||||
|
void UpdateConditionIndices();
|
||||||
std::deque<std::shared_ptr<MacroAction>> &Actions() { return _actions; }
|
std::deque<std::shared_ptr<MacroAction>> &Actions() { return _actions; }
|
||||||
|
|
||||||
bool Save(obs_data_t *obj);
|
bool Save(obs_data_t *obj);
|
||||||
bool Load(obs_data_t *obj);
|
bool Load(obs_data_t *obj);
|
||||||
|
// Some macros can refer to other macros, which are not yet loaded.
|
||||||
|
// Use this function to set these references after loading is complete.
|
||||||
|
void ResolveMacroRef();
|
||||||
|
|
||||||
// Helper function for plugin state condition regarding scene change
|
// Helper function for plugin state condition regarding scene change
|
||||||
bool SwitchesScene();
|
bool SwitchesScene();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SetupHotkeys();
|
||||||
|
void ClearHotkeys();
|
||||||
|
void SetHotkeysDesc();
|
||||||
|
|
||||||
std::string _name = "";
|
std::string _name = "";
|
||||||
std::deque<std::shared_ptr<MacroCondition>> _conditions;
|
std::deque<std::shared_ptr<MacroCondition>> _conditions;
|
||||||
std::deque<std::shared_ptr<MacroAction>> _actions;
|
std::deque<std::shared_ptr<MacroAction>> _actions;
|
||||||
bool _matched = false;
|
bool _matched = false;
|
||||||
|
bool _paused = false;
|
||||||
|
int _count = 0;
|
||||||
|
obs_hotkey_id _pauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||||
|
obs_hotkey_id _unpauseHotkey = OBS_INVALID_HOTKEY_ID;
|
||||||
|
};
|
||||||
|
|
||||||
|
Macro *GetMacroByName(const char *name);
|
||||||
|
Macro *GetMacroByQString(const QString &name);
|
||||||
|
|
||||||
|
class MacroRef {
|
||||||
|
public:
|
||||||
|
MacroRef(){};
|
||||||
|
MacroRef(std::string name);
|
||||||
|
void UpdateRef();
|
||||||
|
void UpdateRef(std::string name);
|
||||||
|
void UpdateRef(QString name);
|
||||||
|
void Save(obs_data_t *obj);
|
||||||
|
void Load(obs_data_t *obj);
|
||||||
|
Macro *get();
|
||||||
|
Macro *operator->();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string _name = "";
|
||||||
|
Macro *_ref = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroRefCondition : public MacroCondition {
|
||||||
|
public:
|
||||||
|
void ResolveMacroRef();
|
||||||
|
MacroRef _macro;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MacroRefAction : public MacroAction {
|
||||||
|
public:
|
||||||
|
void ResolveMacroRef();
|
||||||
|
MacroRef _macro;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public:
|
|||||||
static bool AskForName(QWidget *parent, const QString &title,
|
static bool AskForName(QWidget *parent, const QString &title,
|
||||||
const QString &text, std::string &userTextInput,
|
const QString &text, std::string &userTextInput,
|
||||||
const QString &placeHolder = QString(""),
|
const QString &placeHolder = QString(""),
|
||||||
int maxSize = 170);
|
int maxSize = 170, bool clean = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel *label;
|
QLabel *label;
|
||||||
|
|||||||
15
src/headers/platform-funcs.hpp
Normal file
15
src/headers/platform-funcs.hpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "hotkey.hpp"
|
||||||
|
|
||||||
|
void GetWindowList(std::vector<std::string> &windows);
|
||||||
|
void GetWindowList(QStringList &windows);
|
||||||
|
void GetCurrentWindowTitle(std::string &title);
|
||||||
|
bool isFullscreen(const std::string &title);
|
||||||
|
bool isMaximized(const std::string &title);
|
||||||
|
std::pair<int, int> getCursorPos();
|
||||||
|
int secondsSinceLastInput();
|
||||||
|
void GetProcessList(QStringList &processes);
|
||||||
|
bool isInFocus(const QString &executable);
|
||||||
|
void PressKeys(const std::vector<HotkeyType> keys, int duration);
|
||||||
|
void PlatformInit();
|
||||||
|
void PlatformCleanup();
|
||||||
@@ -40,9 +40,9 @@ struct SceneGroup {
|
|||||||
int lastRandomScene = -1;
|
int lastRandomScene = -1;
|
||||||
|
|
||||||
inline SceneGroup(){};
|
inline SceneGroup(){};
|
||||||
inline SceneGroup(std::string name_) : name(name_){};
|
inline SceneGroup(const std::string &name_) : name(name_){};
|
||||||
inline SceneGroup(std::string name_, AdvanceCondition type_,
|
inline SceneGroup(const std::string &name_, AdvanceCondition type_,
|
||||||
std::vector<OBSWeakSource> scenes_, int count_,
|
const std::vector<OBSWeakSource> &scenes_, int count_,
|
||||||
double time_, bool repeat_)
|
double time_, bool repeat_)
|
||||||
: name(name_),
|
: name(name_),
|
||||||
type(type_),
|
type(type_),
|
||||||
@@ -82,3 +82,6 @@ private:
|
|||||||
|
|
||||||
SceneGroup *sceneGroup = nullptr;
|
SceneGroup *sceneGroup = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SceneGroup *GetSceneGroupByName(const char *name);
|
||||||
|
SceneGroup *GetSceneGroupByQString(const QString &name);
|
||||||
|
|||||||
51
src/headers/scene-selection.hpp
Normal file
51
src/headers/scene-selection.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "scene-group.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
enum class SceneSelectionType {
|
||||||
|
SCENE,
|
||||||
|
GROUP,
|
||||||
|
PREVIOUS,
|
||||||
|
CURRENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
class SceneSelection {
|
||||||
|
public:
|
||||||
|
void Save(obs_data_t *obj, const char *name = "scene",
|
||||||
|
const char *typeName = "sceneType");
|
||||||
|
void Load(obs_data_t *obj, const char *name = "scene",
|
||||||
|
const char *typeName = "sceneType");
|
||||||
|
|
||||||
|
SceneSelectionType GetType() { return _type; }
|
||||||
|
OBSWeakSource GetScene(bool advance = true);
|
||||||
|
std::string ToString();
|
||||||
|
|
||||||
|
private:
|
||||||
|
OBSWeakSource _scene;
|
||||||
|
SceneGroup *_group = nullptr;
|
||||||
|
SceneSelectionType _type = SceneSelectionType::SCENE;
|
||||||
|
friend class SceneSelectionWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SceneSelectionWidget : public QComboBox {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SceneSelectionWidget(QWidget *parent, bool sceneGroups = false,
|
||||||
|
bool previous = false, bool current = false);
|
||||||
|
void SetScene(SceneSelection &);
|
||||||
|
signals:
|
||||||
|
void SceneChanged(const SceneSelection &);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void SelectionChanged(const QString &name);
|
||||||
|
void SceneGroupAdd(const QString &name);
|
||||||
|
void SceneGroupRemove(const QString &name);
|
||||||
|
void SceneGroupRename(const QString &oldName, const QString &newName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool IsCurrentSceneSelected(const QString &name);
|
||||||
|
bool IsPreviousSceneSelected(const QString &name);
|
||||||
|
};
|
||||||
@@ -1,6 +1,14 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
Note: Long-term goal is to remove this tab / file.
|
||||||
|
Most functionality shall be moved to the Macro tab instead.
|
||||||
|
|
||||||
|
So if you plan to make changes here, please consider applying them to the
|
||||||
|
corresponding macro tab functionality instead.
|
||||||
|
******************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "switch-generic.hpp"
|
#include "switch-generic.hpp"
|
||||||
|
#include "duration-control.hpp"
|
||||||
|
|
||||||
enum class sceneTriggerType {
|
enum class sceneTriggerType {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
@@ -27,13 +35,16 @@ enum class sceneTriggerAction {
|
|||||||
|
|
||||||
START_SWITCHER,
|
START_SWITCHER,
|
||||||
STOP_SWITCHER,
|
STOP_SWITCHER,
|
||||||
|
|
||||||
|
START_VCAM,
|
||||||
|
STOP_VCAM,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SceneTrigger : SceneSwitcherEntry {
|
struct SceneTrigger : SceneSwitcherEntry {
|
||||||
static bool pause;
|
static bool pause;
|
||||||
sceneTriggerType triggerType = sceneTriggerType::NONE;
|
sceneTriggerType triggerType = sceneTriggerType::NONE;
|
||||||
sceneTriggerAction triggerAction = sceneTriggerAction::NONE;
|
sceneTriggerAction triggerAction = sceneTriggerAction::NONE;
|
||||||
double duration = 0;
|
Duration duration;
|
||||||
OBSWeakSource audioSource = nullptr;
|
OBSWeakSource audioSource = nullptr;
|
||||||
|
|
||||||
const char *getType() { return "trigger"; }
|
const char *getType() { return "trigger"; }
|
||||||
@@ -60,13 +71,14 @@ public:
|
|||||||
private slots:
|
private slots:
|
||||||
void TriggerTypeChanged(int index);
|
void TriggerTypeChanged(int index);
|
||||||
void TriggerActionChanged(int index);
|
void TriggerActionChanged(int index);
|
||||||
void DurationChanged(double dur);
|
void DurationChanged(double seconds);
|
||||||
|
void DurationUnitChanged(DurationUnit unit);
|
||||||
void AudioSourceChanged(const QString &text);
|
void AudioSourceChanged(const QString &text);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QComboBox *triggers;
|
QComboBox *triggers;
|
||||||
QComboBox *actions;
|
QComboBox *actions;
|
||||||
QDoubleSpinBox *duration;
|
DurationSelection *duration;
|
||||||
QComboBox *audioSources;
|
QComboBox *audioSources;
|
||||||
|
|
||||||
SceneTrigger *switchData;
|
SceneTrigger *switchData;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user