Compare commits

..

11 Commits

Author SHA1 Message Date
WarmUpTill
7d381b9ba1 Adjust to merge 2021-06-06 19:24:10 +02:00
WarmUpTill
d66a2dc408 Merge branch 'master' into virtual-desktop 2021-06-06 19:14:14 +02:00
WarmUpTill
2ac1a226e2 Implement virtual desktop funcs for windows 2021-05-16 14:58:43 +02:00
WarmUpTill
f56b0b56a7 Merge branch 'master' into virtual-desktop 2021-05-16 13:42:13 +02:00
WarmUpTill
6c1eb3ffab Fix random order of various macro entries 2021-05-15 00:40:43 +02:00
WarmUpTill
e9d6067db2 Show currently active virtual desktop 2021-05-15 00:19:00 +02:00
WarmUpTill
d691492a31 Populate virt desktop selection 2021-05-15 00:04:49 +02:00
WarmUpTill
950dfe8688 Request correct information to get virt desktop count 2021-05-15 00:04:35 +02:00
WarmUpTill
fb38f60609 Drop static used for testing ... 2021-05-14 23:55:23 +02:00
WarmUpTill
3c283a0818 Format 2021-05-14 23:35:57 +02:00
WarmUpTill
271bbcbe95 Add macro condition "virtual desktop" (draft) 2021-05-14 23:34:39 +02:00
193 changed files with 2666 additions and 364811 deletions

View File

@@ -1,49 +0,0 @@
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 libprocps-dev
- name: build
run: |
debuild --no-lintian --no-sign

View File

@@ -1,11 +1,14 @@
name: build obs plugin name: build obs plugin
on: [push, pull_request, workflow_dispatch] on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env: env:
PLUGIN_NAME: SceneSwitcher PLUGIN_NAME: SceneSwitcher
LIB_NAME: advanced-scene-switcher LIB_NAME: advanced-scene-switcher
OBS_TAG: 27.1.3
jobs: jobs:
macos64: macos64:
@@ -20,7 +23,6 @@ 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:
@@ -55,15 +57,6 @@ 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: |
@@ -111,14 +104,13 @@ jobs:
path: ./nightly/*.pkg path: ./nightly/*.pkg
ubuntu64: ubuntu64:
name: 'Linux/Ubuntu 64-bit' name: 'Linux/Ubuntu 64-bit'
runs-on: [ubuntu-latest] runs-on: [ubuntu-18.04]
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:
@@ -168,7 +160,6 @@ 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 \
@@ -176,11 +167,7 @@ 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 \
libprocps-dev
- name: 'Configure' - name: 'Configure'
shell: bash shell: bash
run: | run: |
@@ -198,7 +185,6 @@ 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 }}
@@ -210,9 +196,6 @@ 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"
@@ -226,7 +209,6 @@ 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:
@@ -245,97 +227,53 @@ 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 ./build${{ matrix.arch }} mkdir ./build32
cd ./build${{ matrix.arch }} cd ./build32
Get-Location 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 ..
if ( ${{ matrix.arch }} -eq 32 ) cd ..
{ mkdir ./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 .. cd ./build64
} 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 .\build${{ matrix.arch }}\obs-studio.sln msbuild /m /p:Configuration=RelWithDebInfo .\build32\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 .\build${{ matrix.arch }}\rundir\RelWithDebInfo\obs-plugins\${{ matrix.arch }}bit\ .\package\obs-plugins\${{ matrix.arch }}bit ${{ env.LIB_NAME }}.* /E /XF .gitignore robocopy .\build32\rundir\RelWithDebInfo\obs-plugins\32bit\ .\package\obs-plugins\32bit ${{ 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\obs-plugins\64bit\ .\package\obs-plugins\64bit ${{ 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 robocopy .\build64\rundir\RelWithDebInfo\data\obs-plugins\${{ env.LIB_NAME }}\ .\package\data\obs-plugins\${{ env.LIB_NAME }}\ /E /XF .gitignore
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 }}-${{ matrix.arch }}bit' name: '${{ env.FILE_NAME }}'
path: package/* path: package/*
windows-installer: - name: "Package Installer (Prereqs)"
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"
$env:FILE_DATE=(Get-Date -UFormat "%F") curl "-kL" "https://files.jrsoftware.org/is/6/innosetup-6.0.3.exe" "-f" "--retry" "5" "-o" "inno.exe"
$env:FILE_NAME="${{ env.PLUGIN_NAME }}-${env:FILE_DATE}-${{ github.sha }}-windows" .\inno.exe /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART
echo "FILE_NAME=${env:FILE_NAME}" >> ${env:GITHUB_ENV} - name: "Package Installer (Compile)"
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 ".\build\CI\windows\setup.iss" & 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe' /Qp ".\build64\UI\frontend-plugins\${{ env.PLUGIN_NAME }}\CI\windows\setup.iss"
- name: "Publish" - name: Publish installer
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: build/CI/windows/Output/*.exe path: build64/UI/frontend-plugins/SceneSwitcher/CI/windows/Output/*.exe
release: release:
needs: [macos64, ubuntu64, windows, windows-installer] needs: [macos64, ubuntu64, windows]
name: 'Create Release' name: 'Create Release'
runs-on: [ubuntu-18.04] runs-on: [ubuntu-18.04]
steps: steps:
@@ -353,8 +291,7 @@ 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-32bit/* ${{ env.PLUGIN_NAME }}/Windows/ mv ./artifacts/${{ env.PLUGIN_NAME }}*-windows/* ${{ 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
View File

@@ -4,6 +4,3 @@
[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

View File

@@ -1,152 +0,0 @@
# 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
```

View File

@@ -1,5 +0,0 @@
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

View File

@@ -1,22 +0,0 @@
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.

View File

@@ -1,60 +0,0 @@
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.

View File

@@ -1,16 +0,0 @@
#!/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

View File

@@ -1 +0,0 @@
3.0 (native)

View File

@@ -46,294 +46,6 @@
<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>

View File

@@ -1,4 +1,4 @@
Note that you will have to use OBS version 27 or newer! Note that you will have to use OBS version 26.1 or newer!
--- Windows --- --- Windows ---
Recommended: Run the provided installer. (You might have to click 'More info' and select 'Run anyway' if it is blocked by Windows) Recommended: Run the provided installer. (You might have to click 'More info' and select 'Run anyway' if it is blocked by Windows)
@@ -8,17 +8,17 @@ It is usually located at 'C:\Program Files (x86)\obs-studio\'.
Remember to install the Visual C++ Redistributable for Visual Studio 2019, if you have not done so already. (See plugin overview page) Remember to install the Visual C++ Redistributable for Visual Studio 2019, if you have not done so already. (See plugin overview page)
--- macOS --- --- macOS ---
Run the provided installer. (You might have to right-click or control-click and select 'open' if it is blocked) Recommended: Run the provided installer. (You might have to right-click or control-click and select 'open' if it is blocked)
Alternatively extract the *so file and data folder and either ...
... right-click the OBS app inside your Applications folder and choose 'Show Package Contents'.
Copy the advanced-scene-switcher.so file to 'Contents/Plugins' and the 'data' folder to 'Contents/Resources'.
... or 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/'.
--- Linux --- --- Linux ---
Note that the plugin has dependencies to:
* libXss
* libopencv-imgproc
* libopencv-objdetect
Optional:
* libXtst
* libcurl
Copy the advanced-scene-switcher.so file and into the OBS Studio plugin folder. Copy the advanced-scene-switcher.so file and into the OBS Studio plugin folder.
The location of this folder can vary, so you might have to look around a bit. The location of this folder can vary, so you might have to look around a bit.

View File

@@ -1,433 +1,294 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.5)
project(advanced-scene-switcher) project(advanced-scene-switcher)
add_definitions(-DASIO_STANDALONE)
if(NOT CMAKE_BUILD_TYPE) # generate version info
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)
git_describe(GIT_TAG) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp" @ONLY)
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 get_filename_component(ISS_PLUGIN_FILES_DIR "${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE)
"${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE) file(TO_NATIVE_PATH "${ISS_PLUGIN_FILES_DIR}" ISS_PLUGIN_FILES_DIR)
file(TO_NATIVE_PATH "${ISS_PLUGIN_FILES_DIR}" ISS_PLUGIN_FILES_DIR) get_filename_component(ISS_MSVC_REDIST_HELPER_DIR "${CMAKE_PACKAGE_PREFIX}\\.." ABSOLUTE)
get_filename_component(ISS_MSVC_REDIST_HELPER_DIR "${CMAKE_BINARY_DIR}\\.." file(TO_NATIVE_PATH "${ISS_MSVC_REDIST_HELPER_DIR}" ISS_MSVC_REDIST_HELPER_DIR)
ABSOLUTE) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CI/windows/setup.iss.in" "${CMAKE_CURRENT_BINARY_DIR}/CI/windows/setup.iss" @ONLY)
file(TO_NATIVE_PATH "${ISS_MSVC_REDIST_HELPER_DIR}" endif()
ISS_MSVC_REDIST_HELPER_DIR)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CI/windows/setup.iss.in" if(WIN32)
"${CMAKE_CURRENT_BINARY_DIR}/CI/windows/setup.iss" @ONLY) get_filename_component(ISS_PLUGIN_FILES_DIR "${CMAKE_BINARY_DIR}\\..\\package" ABSOLUTE)
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)
find_package(Qt5Core REQUIRED) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external")
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()
if(NOT LIBOBS_LIB) include(external/FindLibObs.cmake)
message(FATAL_ERROR "obs library not found - please set LIBOBS_LIB") find_package(LibObs REQUIRED)
endif() find_package(Qt5Core REQUIRED)
if(NOT LIBOBS_FRONTEND_API_LIB) find_package(Qt5Widgets REQUIRED)
message( find_package(Libcurl REQUIRED)
FATAL_ERROR find_path(LIBOBS_FRONTEND_INCLUDE_DIR HINTS ${LIBOBS_INCLUDE_DIRS})
"libobs frontend-api library not found - please set LIBOBS_FRONTEND_API_LIB" find_file(LIBOBS_FRONTEND_API_LIB NAMES libobs-frontend-api.* HINTS ${LIBOBS_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 COMPONENTS Xtst Xss) find_package(X11 REQUIRED)
find_path(PROCPS_INCLUDE_DIR NAMES proc/procps.h) link_libraries(${X11_LIBRARIES})
if(NOT PROCPS_INCLUDE_DIR) include_directories(${X11_INCLUDE_DIR})
message(
FATAL_ERROR "procps include dir not found - please set PROCPS_INCLUDE_DIR"
)
endif()
find_library(PROCPS_LIBRARY NAMES procps)
if(NOT PROCPS_LIBRARY)
message(FATAL_ERROR "procps lib not found - please set PROCPS_LIBRARY")
endif()
link_libraries(${X11_LIBRARIES} ${procps_LIBRARIES})
include_directories("${X11_INCLUDE_DIR}" "${X11_Xtst_INCLUDE_PATH}"
"${X11_Xss_INCLUDE_PATH}" "${PROCPS_INCLUDE_DIR}")
endif() endif()
if(WIN32) include_directories(
set(advanced-scene-switcher_PLATFORM_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
src/win/advanced-scene-switcher-win.cpp) "${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp"
elseif(APPLE) )
set(advanced-scene-switcher_PLATFORM_SOURCES
src/osx/advanced-scene-switcher-osx.mm)
set_source_files_properties(advanced-scene-switcher-osx.mm
PROPERTIES COMPILE_FLAGS "-fobjc-arc")
set(advanced-scene-switcher_PLATFORM_LIBS ${COCOA})
else()
set(advanced-scene-switcher_PLATFORM_SOURCES
src/linux/advanced-scene-switcher-nix.cpp)
set(advanced-scene-switcher_PLATFORM_LIBS Xss ${PROCPS_LIBRARY})
endif()
# asio and websocketpp
add_definitions(-DASIO_STANDALONE)
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()
# 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 set(advanced-scene-switcher_HEADERS
${advanced-scene-switcher_HEADERS} ${advanced-scene-switcher_HEADERS}
src/headers/advanced-scene-switcher.hpp src/headers/advanced-scene-switcher.hpp
src/headers/switcher-data-structs.hpp src/headers/switcher-data-structs.hpp
src/headers/scene-group.hpp src/headers/scene-group.hpp
src/headers/scene-trigger.hpp src/headers/scene-trigger.hpp
src/headers/switch-audio.hpp src/headers/switch-audio.hpp
src/headers/switch-executable.hpp src/headers/switch-executable.hpp
src/headers/switch-file.hpp src/headers/switch-file.hpp
src/headers/switch-idle.hpp src/headers/switch-idle.hpp
src/headers/switch-media.hpp src/headers/switch-media.hpp
src/headers/switch-network.hpp src/headers/switch-network.hpp
src/headers/switch-pause.hpp src/headers/switch-pause.hpp
src/headers/switch-random.hpp src/headers/switch-random.hpp
src/headers/switch-screen-region.hpp src/headers/switch-screen-region.hpp
src/headers/switch-time.hpp src/headers/switch-time.hpp
src/headers/switch-transitions.hpp src/headers/switch-transitions.hpp
src/headers/switch-window.hpp src/headers/switch-window.hpp
src/headers/switch-sequence.hpp src/headers/switch-sequence.hpp
src/headers/switch-video.hpp src/headers/switch-video.hpp
src/headers/switch-generic.hpp src/headers/switch-generic.hpp
src/headers/macro-action-edit.hpp src/headers/macro-action-edit.hpp
src/headers/macro-action-audio.hpp src/headers/macro-action-audio.hpp
src/headers/macro-action-file.hpp src/headers/macro-action-filter.hpp
src/headers/macro-action-filter.hpp src/headers/macro-action-macro.hpp
src/headers/macro-action-hotkey.hpp src/headers/macro-action-media.hpp
src/headers/macro-action-macro.hpp src/headers/macro-action-plugin-state.hpp
src/headers/macro-action-media.hpp src/headers/macro-action-recording.hpp
src/headers/macro-action-plugin-state.hpp src/headers/macro-action-replay-buffer.hpp
src/headers/macro-action-preview-scene.hpp src/headers/macro-action-run.hpp
src/headers/macro-action-random.hpp src/headers/macro-action-scene-switch.hpp
src/headers/macro-action-recording.hpp src/headers/macro-action-scene-visibility.hpp
src/headers/macro-action-replay-buffer.hpp src/headers/macro-action-source.hpp
src/headers/macro-action-run.hpp src/headers/macro-action-streaming.hpp
src/headers/macro-action-scene-order.hpp src/headers/macro-action-wait.hpp
src/headers/macro-action-scene-swap.hpp src/headers/macro-condition-edit.hpp
src/headers/macro-action-scene-switch.hpp src/headers/macro-condition-audio.hpp
src/headers/macro-action-scene-transform.hpp src/headers/macro-condition-counter.hpp
src/headers/macro-action-scene-visibility.hpp src/headers/macro-condition-file.hpp
src/headers/macro-action-source.hpp src/headers/macro-condition-idle.hpp
src/headers/macro-action-streaming.hpp src/headers/macro-condition-interval.hpp
src/headers/macro-action-timer.hpp src/headers/macro-condition-media.hpp
src/headers/macro-action-transition.hpp src/headers/macro-condition-plugin-state.hpp
src/headers/macro-action-virtual-cam.hpp src/headers/macro-condition-process.hpp
src/headers/macro-action-wait.hpp src/headers/macro-condition-recording.hpp
src/headers/macro-condition-edit.hpp src/headers/macro-condition-region.hpp
src/headers/macro-condition-audio.hpp src/headers/macro-condition-scene.hpp
src/headers/macro-condition-cursor.hpp src/headers/macro-condition-source.hpp
src/headers/macro-condition-date.hpp src/headers/macro-condition-streaming.hpp
src/headers/macro-condition-file.hpp src/headers/macro-condition-video.hpp
src/headers/macro-condition-filter.hpp src/headers/macro-condition-virt-desktop.hpp
src/headers/macro-condition-hotkey.hpp src/headers/macro-condition-window.hpp
src/headers/macro-condition-idle.hpp src/headers/macro.hpp
src/headers/macro-condition-macro.hpp src/headers/macro-selection.hpp
src/headers/macro-condition-media.hpp src/headers/curl-helper.hpp
src/headers/macro-condition-plugin-state.hpp src/headers/screenshot-helper.hpp
src/headers/macro-condition-process.hpp src/headers/name-dialog.hpp
src/headers/macro-condition-recording.hpp src/headers/duration-control.hpp
src/headers/macro-condition-replay-buffer.hpp src/headers/section.hpp
src/headers/macro-condition-scene-order.hpp src/headers/platform-funcs.hpp
src/headers/macro-condition-scene-transform.hpp src/headers/utility.hpp
src/headers/macro-condition-scene-visibility.hpp src/headers/volume-control.hpp
src/headers/macro-condition-scene.hpp src/headers/version.h
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 set(advanced-scene-switcher_SOURCES
${advanced-scene-switcher_SOURCES} ${advanced-scene-switcher_SOURCES}
src/advanced-scene-switcher.cpp src/advanced-scene-switcher.cpp
src/advanced-scene-switcher-module.c src/advanced-scene-switcher-module.c
src/switcher-data-structs.cpp src/switcher-data-structs.cpp
src/scene-group.cpp src/scene-group.cpp
src/scene-trigger.cpp src/scene-trigger.cpp
src/switch-transitions.cpp src/switch-transitions.cpp
src/switch-screen-region.cpp src/switch-screen-region.cpp
src/switch-priority.cpp src/switch-priority.cpp
src/switch-executable.cpp src/switch-executable.cpp
src/switch-idle.cpp src/switch-idle.cpp
src/switch-sequence.cpp src/switch-sequence.cpp
src/switch-file.cpp src/switch-file.cpp
src/switch-window.cpp src/switch-window.cpp
src/switch-media.cpp src/switch-media.cpp
src/switch-network.cpp src/switch-network.cpp
src/file-selection.cpp src/hotkey.cpp
src/hotkey.cpp src/general.cpp
src/general.cpp src/switch-pause.cpp
src/switch-pause.cpp src/switch-random.cpp
src/switch-random.cpp src/switch-time.cpp
src/switch-time.cpp src/switch-audio.cpp
src/switch-audio.cpp src/switch-video.cpp
src/switch-video.cpp src/switch-generic.cpp
src/switch-generic.cpp src/macro-action-edit.cpp
src/macro-action-edit.cpp src/macro-action-audio.cpp
src/macro-action-audio.cpp src/macro-action-filter.cpp
src/macro-action-file.cpp src/macro-action-macro.cpp
src/macro-action-filter.cpp src/macro-action-media.cpp
src/macro-action-hotkey.cpp src/macro-action-plugin-state.cpp
src/macro-action-macro.cpp src/macro-action-recording.cpp
src/macro-action-media.cpp src/macro-action-replay-buffer.cpp
src/macro-action-plugin-state.cpp src/macro-action-run.cpp
src/macro-action-preview-scene.cpp src/macro-action-scene-switch.cpp
src/macro-action-random.cpp src/macro-action-scene-visibility.cpp
src/macro-action-recording.cpp src/macro-action-source.cpp
src/macro-action-replay-buffer.cpp src/macro-action-streaming.cpp
src/macro-action-run.cpp src/macro-action-wait.cpp
src/macro-action-scene-order.cpp src/macro-condition-edit.cpp
src/macro-action-scene-swap.cpp src/macro-condition-audio.cpp
src/macro-action-scene-switch.cpp src/macro-condition-counter.cpp
src/macro-action-scene-transform.cpp src/macro-condition-file.cpp
src/macro-action-scene-visibility.cpp src/macro-condition-idle.cpp
src/macro-action-source.cpp src/macro-condition-interval.cpp
src/macro-action-streaming.cpp src/macro-condition-media.cpp
src/macro-action-timer.cpp src/macro-condition-plugin-state.cpp
src/macro-action-transition.cpp src/macro-condition-process.cpp
src/macro-action-virtual-cam.cpp src/macro-condition-recording.cpp
src/macro-action-wait.cpp src/macro-condition-region.cpp
src/macro-condition-edit.cpp src/macro-condition-scene.cpp
src/macro-condition-audio.cpp src/macro-condition-source.cpp
src/macro-condition-cursor.cpp src/macro-condition-streaming.cpp
src/macro-condition-date.cpp src/macro-condition-video.cpp
src/macro-condition-file.cpp src/macro-condition-virt-desktop.cpp
src/macro-condition-filter.cpp src/macro-condition-window.cpp
src/macro-condition-hotkey.cpp src/macro.cpp
src/macro-condition-idle.cpp src/macro-selection.cpp
src/macro-condition-macro.cpp src/macro-tab.cpp
src/macro-condition-media.cpp src/curl-helper.cpp
src/macro-condition-plugin-state.cpp src/screenshot-helper.cpp
src/macro-condition-process.cpp src/name-dialog.cpp
src/macro-condition-recording.cpp src/duration-control.cpp
src/macro-condition-replay-buffer.cpp src/section.cpp
src/macro-condition-scene-order.cpp src/utility.cpp
src/macro-condition-scene-transform.cpp src/volume-control.cpp
src/macro-condition-scene-visibility.cpp src/version.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)
# opencv set(advanced-scene-switcher_UI
find_package(OpenCV) ${advanced-scene-switcher_UI}
if(OpenCV_FOUND) forms/advanced-scene-switcher.ui
include_directories("${OpenCV_INCLUDE_DIRS}") )
if(WIN32)
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
set(advanced-scene-switcher_PLATFORM_SOURCES
src/win/advanced-scene-switcher-win.cpp)
elseif(APPLE)
set(advanced-scene-switcher_PLATFORM_SOURCES
src/osx/advanced-scene-switcher-osx.mm)
set_source_files_properties(advanced-scene-switcher-osx.mm
PROPERTIES COMPILE_FLAGS "-fobjc-arc")
set(advanced-scene-switcher_PLATFORM_LIBS
${COCOA})
else() else()
set(OpenCV_LIBRARIES "") set(advanced-scene-switcher_PLATFORM_SOURCES
message( src/linux/advanced-scene-switcher-nix.cpp)
WARNING set(advanced-scene-switcher_PLATFORM_LIBS
"OpenCV not found! Functionality relying on OpenCV will be disabled!\nOpenCV sources are available under: ${CMAKE_CURRENT_SOURCE_DIR}/deps/opencv" Xss)
)
list(REMOVE_ITEM advanced-scene-switcher_SOURCES
src/macro-condition-video.cpp)
list(REMOVE_ITEM advanced-scene-switcher_HEADERS
src/headers/macro-condition-video.hpp)
endif() endif()
add_library( qt5_wrap_ui(advanced-scene-switcher_UI_HEADERS
advanced-scene-switcher MODULE ${advanced-scene-switcher_UI}
${advanced-scene-switcher_HEADERS} ${advanced-scene-switcher_PLATFORM_UI})
${advanced-scene-switcher_SOURCES}
${advanced-scene-switcher_UI_HEADERS} add_library(advanced-scene-switcher MODULE
${advanced-scene-switcher_PLATFORM_SOURCES} ${advanced-scene-switcher_HEADERS}
${advanced-scene-switcher_PLATFORM_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)
target_link_libraries( include_directories(
advanced-scene-switcher "${LIBOBS_INCLUDE_DIRS}"
${advanced-scene-switcher_PLATFORM_LIBS} "${LIBOBS_FRONTEND_INCLUDE_DIR}"
${OpenCV_LIBRARIES} ${Qt5Core_INCLUDES}
${LIBOBS_LIB} ${Qt5Widgets_INCLUDES}
${LIBOBS_FRONTEND_API_LIB} ${LIBCURL_INCLUDE_DIRS})
Qt5::Core
Qt5::Widgets)
# Additional commands to install the module in the correct place. Find all the target_link_libraries(advanced-scene-switcher
# translation files so we can copy them to the correct place later on. ${advanced-scene-switcher_PLATFORM_LIBS}
file(GLOB ASS_TRANSLATION_FILES "data/locale/*.ini") ${LIBOBS_LIB}
${LIBOBS_FRONTEND_API_LIB}
Qt5::Core
Qt5::Widgets)
# OSX # Additional commands to install the module in the correct place.
if(APPLE) # Find all the translation files so we can copy them to the correct
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "") # place later on.
endif() file(GLOB ASS_TRANSLATION_FILES
"data/locale/*.ini"
)
# Linux # Windows
if(UNIX AND NOT APPLE) if(WIN32)
if(NOT LIB_OUT_DIR) string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
set(LIB_OUT_DIR "/lib/obs-plugins") message("${CMAKE_CXX_FLAGS_RELEASE}")
endif()
if(NOT DATA_OUT_DIR) find_package(w32-pthreads REQUIRED)
set(DATA_OUT_DIR "/share/obs/obs-plugins/advanced-scene-switcher")
endif() target_link_libraries(advanced-scene-switcher
set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "") w32-pthreads)
install(TARGETS advanced-scene-switcher endif()
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_OUT_DIR})
install(DIRECTORY data/locale # OSX
DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR}) if(APPLE)
install(DIRECTORY data/res set_target_properties(advanced-scene-switcher PROPERTIES PREFIX "")
DESTINATION ${CMAKE_INSTALL_PREFIX}/${DATA_OUT_DIR}) endif()
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()
# In tree build target_link_libraries(advanced-scene-switcher
target_link_libraries( ${advanced-scene-switcher_PLATFORM_LIBS}
advanced-scene-switcher ${advanced-scene-switcher_PLATFORM_LIBS} obs-frontend-api
${OpenCV_LIBRARIES} obs-frontend-api Qt5::Widgets libobs) Qt5::Widgets
install_obs_plugin_with_data(advanced-scene-switcher data) libobs)
install_obs_plugin_with_data(advanced-scene-switcher data)
endif() endif()

128
README.md
View File

@@ -1,27 +1,119 @@
# 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/. 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.
## Downloads ## Compiling in tree (recommended)
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:
``` ```
sudo snap install obs-studio cd obs-studio/UI/frontend-plugins/
git clone https://github.com/WarmUpTill/SceneSwitcher.git
``` ```
If that is not an option you will have to ... Then modify the obs-studio/UI/frontend-plugins/CMakeLists.txt file and add an entry for the scene switcher:
1. Copy the library to the plugins folder of you obs installation. add_subdirectory(SceneSwitcher)
2. Copy the contents of the data directory to its respective folders of your obs installation.
Unfortunately the exact location of these folders may vary from system to system. ## Compiling out of tree
### 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
```
## Compiling the plugin ### Windows
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)
See the [build instructions](BUILDING.md). Assuming that you installed Qt via the regular Qt App way:
- **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
```

View File

@@ -1,5 +1,3 @@
#include "src/headers/version.h" #include "src/headers/version.h"
#define GIT_SHA1 "@GIT_SHA1@" #define GIT_SHA1 "@GIT_SHA1@"
#define GIT_TAG "@GIT_TAG@" const char g_GIT_SHA1[] = GIT_SHA1;
const char g_GIT_SHA1[] = GIT_SHA1;
const char g_GIT_TAG[] = GIT_TAG;

View File

@@ -45,7 +45,7 @@ AdvSceneSwitcher.generalTab.priority.fileContent="Datei Inhalt"
AdvSceneSwitcher.generalTab.priority.sceneSequence="Szenenfolge" AdvSceneSwitcher.generalTab.priority.sceneSequence="Szenenfolge"
AdvSceneSwitcher.generalTab.priority.idleDetection="Inaktivitätserkennung" AdvSceneSwitcher.generalTab.priority.idleDetection="Inaktivitätserkennung"
AdvSceneSwitcher.generalTab.priority.executable="Prozess" AdvSceneSwitcher.generalTab.priority.executable="Prozess"
AdvSceneSwitcher.generalTab.priority.screenRegion="Bildschirmbereich" AdvSceneSwitcher.generalTab.priority.screenRegion="Bildschrimbereich"
AdvSceneSwitcher.generalTab.priority.windowTitle="Fenstername" AdvSceneSwitcher.generalTab.priority.windowTitle="Fenstername"
AdvSceneSwitcher.generalTab.priority.media="Medien" AdvSceneSwitcher.generalTab.priority.media="Medien"
AdvSceneSwitcher.generalTab.priority.time="Zeit" AdvSceneSwitcher.generalTab.priority.time="Zeit"
@@ -98,7 +98,7 @@ AdvSceneSwitcher.executableTab.entry="Wenn {{processes}} läuft wechsle zu {{sce
AdvSceneSwitcher.executableTab.help="Dieser Tab erlaubt es Szenen zu wechseln, wenn bestimmte Prozesse laufen.\nDas kann nützlich sein, wenn sich der Name eines Fensters ändern kann oder dieser nicht bekannt ist.\n\nKlicke auf das markierte Plus Symbol, um einen neuen Eintrag hinzuzufügen." AdvSceneSwitcher.executableTab.help="Dieser Tab erlaubt es Szenen zu wechseln, wenn bestimmte Prozesse laufen.\nDas kann nützlich sein, wenn sich der Name eines Fensters ändern kann oder dieser nicht bekannt ist.\n\nKlicke auf das markierte Plus Symbol, um einen neuen Eintrag hinzuzufügen."
; Screen Region Tab ; Screen Region Tab
AdvSceneSwitcher.screenRegionTab.title="Bildschirmbereich" AdvSceneSwitcher.screenRegionTab.title="Bildschrimbereich"
AdvSceneSwitcher.screenRegionTab.currentPosition="Mauszeiger ist bei:" AdvSceneSwitcher.screenRegionTab.currentPosition="Mauszeiger ist bei:"
AdvSceneSwitcher.screenRegionTab.showGuideFrames="Hilfsrahmen einblenden" AdvSceneSwitcher.screenRegionTab.showGuideFrames="Hilfsrahmen einblenden"
AdvSceneSwitcher.screenRegionTab.hideGuideFrames="Hilfsrahmen ausblenden" AdvSceneSwitcher.screenRegionTab.hideGuideFrames="Hilfsrahmen ausblenden"
@@ -284,8 +284,6 @@ 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."

View File

@@ -28,7 +28,6 @@ AdvSceneSwitcher.generalTab.generalBehavior.cooldown="After a match do not switc
AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="During this time potential matches will be ignored!" AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint="During this time potential matches will be ignored!"
AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Enable verbose logging" AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Enable verbose logging"
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Save window position and size" AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Save window position and size"
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="Show system tray notifications"
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints" AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints"
AdvSceneSwitcher.generalTab.priority="Priority" AdvSceneSwitcher.generalTab.priority="Priority"
AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)" AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)"
@@ -69,8 +68,6 @@ 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"
@@ -86,25 +83,17 @@ AdvSceneSwitcher.condition.audio="Audio"
AdvSceneSwitcher.condition.audio.state.below="Below" AdvSceneSwitcher.condition.audio.state.below="Below"
AdvSceneSwitcher.condition.audio.state.above="Above" AdvSceneSwitcher.condition.audio.state.above="Above"
AdvSceneSwitcher.condition.audio.entry="Volume of {{audioSources}} is {{condition}} {{volume}}" AdvSceneSwitcher.condition.audio.entry="Volume of {{audioSources}} is {{condition}} {{volume}}"
AdvSceneSwitcher.condition.cursor="Cursor" AdvSceneSwitcher.condition.region="Screen region"
AdvSceneSwitcher.condition.cursor.type.region="is in region" AdvSceneSwitcher.condition.region.entry="Cursor is in {{minX}} {{minY}} x {{maxX}} {{maxY}}"
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 scene is" AdvSceneSwitcher.condition.scene.type.current="Current"
AdvSceneSwitcher.condition.scene.type.previous="Previous scene is" AdvSceneSwitcher.condition.scene.type.previous="Previous"
AdvSceneSwitcher.condition.scene.type.changed="Scene changed" AdvSceneSwitcher.condition.scene.entry="{{sceneType}} scene is {{scenes}}"
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 {{windowFocusChanged}} foreground window changed" AdvSceneSwitcher.condition.window.entry.line2="... is {{fullscreen}} fullscreen {{maximized}} maximized {{focused}} focused"
AdvSceneSwitcher.condition.file="File" AdvSceneSwitcher.condition.file="File"
AdvSceneSwitcher.condition.file.entry.line1="Content of {{fileType}} {{filePath}} matches:" AdvSceneSwitcher.condition.file.entry.line1="Content of {{fileType}} {{filePath}} {{browseButton}} 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"
@@ -115,35 +104,13 @@ 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.usePatternForChangedCheck="Use pattern matching" AdvSceneSwitcher.condition.video.entry="{{videoSources}} {{condition}} {{filePath}} {{browseButton}}"
AdvSceneSwitcher.condition.video.usePatternForChangedCheck.tooltip="This will allow you to control how much the image has to change for the condition to be true."
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.state.starting="Stream starting"
AdvSceneSwitcher.condition.stream.state.stopping="Stream stopping"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}" 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"
@@ -157,25 +124,19 @@ 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.virtDesktop="Virtual desktop"
AdvSceneSwitcher.condition.timer.pause="Pause" AdvSceneSwitcher.condition.virtDesktop.notAvailable="Not availbale"
AdvSceneSwitcher.condition.timer.continue="Continue" AdvSceneSwitcher.condition.virtDesktop.entry.line1="Active virtual desktop is {{virtDesktops}}"
AdvSceneSwitcher.condition.timer.entry.line1="{{duration}} have passed" AdvSceneSwitcher.condition.virtDesktop.entry.line2="Current: {{currentDesktop}}"
AdvSceneSwitcher.condition.timer.entry.line2="Time remaining: {{remaining}} seconds" AdvSceneSwitcher.condition.interval="Interval"
AdvSceneSwitcher.condition.timer.entry.line3="{{pauseContinue}} {{reset}} {{saveRemaining}} Save time remaining {{autoReset}} Automatically reset timer after duration was reached" AdvSceneSwitcher.condition.interval.entry="{{duration}} have passed"
AdvSceneSwitcher.condition.timer.reset="Reset" AdvSceneSwitcher.condition.counter="Count"
AdvSceneSwitcher.condition.macro="Macro" AdvSceneSwitcher.condition.counter.type.below="Less than"
AdvSceneSwitcher.condition.macro.type.count="Count" AdvSceneSwitcher.condition.counter.type.above="More than"
AdvSceneSwitcher.condition.macro.type.state="State" AdvSceneSwitcher.condition.counter.type.equal="Exactly"
AdvSceneSwitcher.condition.macro.type.selection="Condition type: {{types}}" AdvSceneSwitcher.condition.counter.reset="Reset"
AdvSceneSwitcher.condition.macro.count.type.below="Less than" AdvSceneSwitcher.condition.counter.entry.line1="{{macros}} was executed {{conditions}} {{count}} times"
AdvSceneSwitcher.condition.macro.count.type.above="More than" AdvSceneSwitcher.condition.counter.entry.line2="Current count: {{currentCount}} {{resetCount}}"
AdvSceneSwitcher.condition.macro.count.type.equal="Exactly"
AdvSceneSwitcher.condition.macro.count.reset="Reset"
AdvSceneSwitcher.condition.macro.pausedWarning="Selected macro is currently paused!"
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="Source"
AdvSceneSwitcher.condition.source.type.active="Is active" AdvSceneSwitcher.condition.source.type.active="Is active"
AdvSceneSwitcher.condition.source.type.showing="Is showing" AdvSceneSwitcher.condition.source.type.showing="Is showing"
@@ -185,58 +146,6 @@ AdvSceneSwitcher.condition.source.getSettings="Get current settings"
AdvSceneSwitcher.condition.source.entry.line1="{{sources}} {{conditions}}" AdvSceneSwitcher.condition.source.entry.line1="{{sources}} {{conditions}}"
AdvSceneSwitcher.condition.source.entry.line2="{{settings}}" AdvSceneSwitcher.condition.source.entry.line2="{{settings}}"
AdvSceneSwitcher.condition.source.entry.line3="{{regex}} {{getSettings}}" AdvSceneSwitcher.condition.source.entry.line3="{{regex}} {{getSettings}}"
AdvSceneSwitcher.condition.virtualCamera="Virtual camera"
AdvSceneSwitcher.condition.virtualCamera.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}}"
AdvSceneSwitcher.condition.sceneVisibility="Scene item visibility"
AdvSceneSwitcher.condition.sceneVisibility.type.shown="Shown"
AdvSceneSwitcher.condition.sceneVisibility.type.hidden="Hidden"
AdvSceneSwitcher.condition.sceneVisibility.entry="On {{scenes}} {{sources}} is {{conditions}} "
; Macro Actions ; Macro Actions
AdvSceneSwitcher.action.switchScene="Switch scene" AdvSceneSwitcher.action.switchScene="Switch scene"
@@ -251,7 +160,6 @@ AdvSceneSwitcher.action.audio.type.mute="Mute"
AdvSceneSwitcher.action.audio.type.unmute="Unmute" AdvSceneSwitcher.action.audio.type.unmute="Unmute"
AdvSceneSwitcher.action.audio.type.sourceVolume="Set source volume" AdvSceneSwitcher.action.audio.type.sourceVolume="Set source volume"
AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume" AdvSceneSwitcher.action.audio.type.masterVolume="Set master volume"
AdvSceneSwitcher.action.audio.fade="{{fade}}Fade over {{duration}} seconds"
AdvSceneSwitcher.action.audio.entry="{{actions}} {{audioSources}} {{volume}}" AdvSceneSwitcher.action.audio.entry="{{actions}} {{audioSources}} {{volume}}"
AdvSceneSwitcher.action.recording="Recording" AdvSceneSwitcher.action.recording="Recording"
AdvSceneSwitcher.action.recording.type.stop="Stop recording" AdvSceneSwitcher.action.recording.type.stop="Stop recording"
@@ -270,22 +178,15 @@ 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.arguments="Arguments:" AdvSceneSwitcher.action.run.entry="Run {{filePath}} {{browseButton}}"
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="Scene item visibility"
AdvSceneSwitcher.action.sceneVisibility.type.show="Show" AdvSceneSwitcher.action.sceneVisibility.type.show="Show"
AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide" AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
AdvSceneSwitcher.action.sceneVisibility.type.source="Source" AdvSceneSwitcher.action.sceneVisibility.entry="On {{scenes}} {{actions}} {{sources}}"
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Any"
AdvSceneSwitcher.action.sceneVisibility.entry="On {{scenes}} {{actions}} {{sourceTypes}} {{sources}}"
AdvSceneSwitcher.action.filter="Filter" AdvSceneSwitcher.action.filter="Filter"
AdvSceneSwitcher.action.filter.type.enable="Enable" AdvSceneSwitcher.action.filter.type.enable="Enable"
AdvSceneSwitcher.action.filter.type.disable="Disable" AdvSceneSwitcher.action.filter.type.disable="Disable"
AdvSceneSwitcher.action.filter.type.settings="Set settings"
AdvSceneSwitcher.action.filter.entry="On {{sources}} {{actions}} {{filters}}" AdvSceneSwitcher.action.filter.entry="On {{sources}} {{actions}} {{filters}}"
AdvSceneSwitcher.action.filter.getSettings="Get current settings"
AdvSceneSwitcher.action.source="Source" AdvSceneSwitcher.action.source="Source"
AdvSceneSwitcher.action.source.type.enable="Enable" AdvSceneSwitcher.action.source.type.enable="Enable"
AdvSceneSwitcher.action.source.type.disable="Disable" AdvSceneSwitcher.action.source.type.disable="Disable"
@@ -308,55 +209,7 @@ AdvSceneSwitcher.action.macro.type.resetCounter="Reset counter"
AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}" AdvSceneSwitcher.action.macro.entry="{{actions}} {{macros}}"
AdvSceneSwitcher.action.pluginState="Plugin state" AdvSceneSwitcher.action.pluginState="Plugin state"
AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin" AdvSceneSwitcher.action.pluginState.type.stop="Stop the Advanced Scene Switcher plugin"
AdvSceneSwitcher.action.pluginState.type.noMatch="Change the no-match behaviour:" AdvSceneSwitcher.action.pluginState.entry="{{actions}}"
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}}"
AdvSceneSwitcher.action.random="Random"
AdvSceneSwitcher.action.random.arguments="Macros:"
AdvSceneSwitcher.action.random.addArgument="Add Macro"
AdvSceneSwitcher.action.random.entry="Run {{macroSelection}}"
; Transition Tab ; Transition Tab
AdvSceneSwitcher.transitionTab.title="Transition" AdvSceneSwitcher.transitionTab.title="Transition"
@@ -528,7 +381,6 @@ 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)"
@@ -591,8 +443,6 @@ 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."
@@ -610,10 +460,7 @@ 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.selectSource="--select source--"
@@ -631,8 +478,6 @@ AdvSceneSwitcher.selectWindowTip="Use \"OBS\" to specify OBS window\nUse \"Task
AdvSceneSwitcher.status.active="Active" AdvSceneSwitcher.status.active="Active"
AdvSceneSwitcher.status.inactive="Inactive" AdvSceneSwitcher.status.inactive="Inactive"
AdvSceneSwitcher.running="Plugin running"
AdvSceneSwitcher.stopped="Plugin stopped"
AdvSceneSwitcher.unit.milliseconds="milliseconds" AdvSceneSwitcher.unit.milliseconds="milliseconds"
AdvSceneSwitcher.unit.secends="seconds" AdvSceneSwitcher.unit.secends="seconds"

View File

@@ -81,7 +81,8 @@ AdvSceneSwitcher.condition.audio="Аудио"
AdvSceneSwitcher.ondition.audio.state.below="Ниже" AdvSceneSwitcher.ondition.audio.state.below="Ниже"
AdvSceneSwitcher.ondition.audio.state.above="Выше" AdvSceneSwitcher.ondition.audio.state.above="Выше"
AdvSceneSwitcher.condition.audio.entry="Громкость {{audioSources}} равна {{condition}} {{volume}} в течении {{duration}} секунд" AdvSceneSwitcher.condition.audio.entry="Громкость {{audioSources}} равна {{condition}} {{volume}} в течении {{duration}} секунд"
AdvSceneSwitcher.condition.cursor="Область экрана" AdvSceneSwitcher.condition.region="Область экрана"
AdvSceneSwitcher.condition.region.entry="Курсор находится в {{minX}} {{minY}} x {{maxX}} {{maxY}}"
AdvSceneSwitcher.condition.scene="Сцена" AdvSceneSwitcher.condition.scene="Сцена"
AdvSceneSwitcher.condition.scene.type.current="Текущий" AdvSceneSwitcher.condition.scene.type.current="Текущий"
AdvSceneSwitcher.condition.scene.type.previous="Предыдущий" AdvSceneSwitcher.condition.scene.type.previous="Предыдущий"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
deps/opencv vendored

Submodule deps/opencv deleted from ad6e82942b

107
external/FindLibObs.cmake vendored Normal file
View File

@@ -0,0 +1,107 @@
# 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 Normal file
View File

@@ -0,0 +1,163 @@
# 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()

View File

@@ -258,6 +258,13 @@
</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>
@@ -306,30 +313,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="showTrayNotifications">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_48"> <layout class="QHBoxLayout" name="horizontalLayout_48">
<item> <item>
@@ -381,6 +364,19 @@
<item> <item>
<widget class="QListWidget" name="priorityList"/> <widget class="QListWidget" name="priorityList"/>
</item> </item>
<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>
</layout> </layout>
</item> </item>
</layout> </layout>
@@ -697,6 +693,13 @@
</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">
@@ -3720,13 +3723,6 @@
<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">

View File

@@ -1,8 +1,6 @@
#include <QMainWindow> #include <QMainWindow>
#include <QAction> #include <QAction>
#include <QFileDialog> #include <QFileDialog>
#include <regex>
#include <filesystem>
#include <obs-module.h> #include <obs-module.h>
#include <obs-frontend-api.h> #include <obs-frontend-api.h>
@@ -20,7 +18,6 @@ SwitcherData *switcher = nullptr;
AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent) AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent)
: QDialog(parent), ui(new Ui_AdvSceneSwitcher) : QDialog(parent), ui(new Ui_AdvSceneSwitcher)
{ {
switcher->settingsWindowOpened = true;
ui->setupUi(this); ui->setupUi(this);
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
@@ -29,13 +26,6 @@ AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent)
loadUI(); loadUI();
} }
AdvSceneSwitcher::~AdvSceneSwitcher()
{
if (switcher) {
switcher->settingsWindowOpened = false;
}
}
bool translationAvailable() bool translationAvailable()
{ {
return !!strcmp(obs_module_text("AdvSceneSwitcher.pluginName"), return !!strcmp(obs_module_text("AdvSceneSwitcher.pluginName"),
@@ -45,16 +35,9 @@ bool translationAvailable()
void AdvSceneSwitcher::loadUI() void AdvSceneSwitcher::loadUI()
{ {
if (!translationAvailable()) { if (!translationAvailable()) {
QString msg = "Failed to find plug-in's 'data' directory.\n" (void)DisplayMessage(
"Please check installation instructions!\n\n" "Failed to find plug-in's 'data' directory.\n"
"Data most likely expected at:\n\n"; "Please check installation instructions!");
#ifdef _WIN32
msg += QString::fromStdString(
(std::filesystem::current_path().string()));
msg += "/";
#endif
msg += obs_get_module_data_path(obs_current_module());
(void)DisplayMessage(msg);
} }
#if __APPLE__ #if __APPLE__
@@ -120,23 +103,33 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
{ {
if (saving) { if (saving) {
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
switcher->Prune(); switcher->Prune();
obs_data_t *obj = obs_data_create(); obs_data_t *obj = obs_data_create();
switcher->saveSettings(obj); switcher->saveSettings(obj);
obs_data_set_obj(save_data, "advanced-scene-switcher", obj); obs_data_set_obj(save_data, "advanced-scene-switcher", obj);
obs_data_release(obj); obs_data_release(obj);
} else { } else {
switcher->m.lock(); switcher->m.lock();
obs_data_t *obj = obs_data_t *obj =
obs_data_get_obj(save_data, "advanced-scene-switcher"); obs_data_get_obj(save_data, "advanced-scene-switcher");
if (!obj) { if (!obj) {
obj = obs_data_create(); obj = obs_data_create();
} }
if (switcher->versionChanged(obj, g_GIT_SHA1)) { if (switcher->versionChanged(obj, g_GIT_SHA1)) {
AskBackup(obj); AskBackup(obj);
} }
switcher->loadSettings(obj); switcher->loadSettings(obj);
obs_data_release(obj); obs_data_release(obj);
switcher->m.unlock(); switcher->m.unlock();
// Stop the scene switcher at least once to // Stop the scene switcher at least once to
@@ -172,7 +165,9 @@ void SwitcherData::Thread()
bool setPrevSceneAfterLinger = false; bool setPrevSceneAfterLinger = false;
bool macroMatch = false; bool macroMatch = false;
macroSceneSwitched = false; macroSceneSwitched = false;
endTime = std::chrono::high_resolution_clock::now(); endTime = std::chrono::high_resolution_clock::now();
auto runTime = auto runTime =
std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::duration_cast<std::chrono::milliseconds>(
endTime - startTime); endTime - startTime);
@@ -204,7 +199,6 @@ 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) {
@@ -236,17 +230,12 @@ void SwitcherData::Thread()
} }
} }
// After this point we will call frontend functions like // After this point we will call frontend functions
// 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 with the frontend function being stuck // leading to a deadlock, so we have to unlock()
// 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) {
@@ -263,37 +252,6 @@ 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,
@@ -419,18 +377,12 @@ void SwitcherData::Start()
if (networkConfig.ClientEnabled) { if (networkConfig.ClientEnabled) {
client.connect(networkConfig.GetClientUri()); client.connect(networkConfig.GetClientUri());
} }
if (showSystemTrayNotifications) {
DisplayTrayMessage(
obs_module_text("AdvSceneSwitcher.pluginName"),
obs_module_text("AdvSceneSwitcher.running"));
}
} }
void ResetMacroCounters() void ResetMacroCounters()
{ {
for (auto &m : switcher->macros) { for (auto &m : switcher->macros) {
m->ResetCount(); m.ResetCount();
} }
} }
@@ -438,9 +390,8 @@ 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;
@@ -451,19 +402,6 @@ void SwitcherData::Stop()
server.stop(); server.stop();
client.disconnect(); client.disconnect();
for (auto &t : audioHelperThreads) {
if (t.joinable()) {
t.join();
}
}
audioHelperThreads.clear();
if (showSystemTrayNotifications) {
DisplayTrayMessage(
obs_module_text("AdvSceneSwitcher.pluginName"),
obs_module_text("AdvSceneSwitcher.stopped"));
}
} }
void SwitcherData::setWaitScene() void SwitcherData::setWaitScene()
@@ -495,37 +433,26 @@ extern "C" void FreeSceneSwitcher()
loaded_curl_lib = nullptr; loaded_curl_lib = nullptr;
} }
PlatformCleanup();
delete switcher; delete switcher;
switcher = nullptr; switcher = nullptr;
} }
void handleSceneChange() void handleSceneChange()
{ {
switcher->lastSceneChangeTime =
std::chrono::high_resolution_clock::now();
// Stop waiting if scene was changed // Stop waiting if scene was changed
if (switcher->sceneChangedDuringWait()) { if (switcher->sceneChangedDuringWait()) {
switcher->cv.notify_one(); switcher->cv.notify_one();
} }
// Set current and previous scene // Set 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);
if (ws && ws != switcher->currentScene) {
switcher->previousScene = switcher->currentScene;
switcher->currentScene = ws;
vblog(LOG_INFO, "current scene: %s",
GetWeakSourceName(switcher->currentScene).c_str());
vblog(LOG_INFO, "previous scene: %s",
GetWeakSourceName(switcher->previousScene).c_str());
}
obs_source_release(source); obs_source_release(source);
obs_weak_source_release(ws); obs_weak_source_release(ws);
if (source && switcher->previousSceneHelper != ws) {
switcher->previousScene = switcher->previousSceneHelper;
switcher->previousSceneHelper = ws;
}
switcher->checkTriggers(); switcher->checkTriggers();
switcher->checkDefaultSceneTransitions(); switcher->checkDefaultSceneTransitions();
@@ -570,29 +497,6 @@ void handlePeviewSceneChange()
} }
} }
void setReplayBufferSaved()
{
switcher->replayBufferSaved = true;
}
void setTranstionEnd()
{
switcher->lastTransitionEndTime =
std::chrono::high_resolution_clock::now();
}
void setStreamStarting()
{
switcher->lastStreamStartingTime =
std::chrono::high_resolution_clock::now();
}
void setStreamStopping()
{
switcher->lastStreamStoppingTime =
std::chrono::high_resolution_clock::now();
}
// Note to future self: // Note to future self:
// be careful using switcher->m here as there is potential for deadlocks when using // be careful using switcher->m here as there is potential for deadlocks when using
// frontend functions such as obs_frontend_set_current_scene() // frontend functions such as obs_frontend_set_current_scene()
@@ -624,30 +528,13 @@ static void OBSEvent(enum obs_frontend_event event, void *switcher)
case OBS_FRONTEND_EVENT_STREAMING_STOPPED: case OBS_FRONTEND_EVENT_STREAMING_STOPPED:
resetLiveTime(); resetLiveTime();
break; break;
#ifdef REPLAYBUFFER_SUPPORTED
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVED:
setReplayBufferSaved();
break;
#endif
case OBS_FRONTEND_EVENT_TRANSITION_STOPPED:
setTranstionEnd();
break;
case OBS_FRONTEND_EVENT_STREAMING_STARTING:
setStreamStarting();
break;
case OBS_FRONTEND_EVENT_STREAMING_STOPPING:
setStreamStopping();
break;
default: default:
break; break;
} }
} }
AdvSceneSwitcher *ssWindow;
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(
@@ -659,19 +546,12 @@ extern "C" void InitSceneSwitcher()
switcher->curl = f_curl_init(); switcher->curl = f_curl_init();
} }
PlatformInit();
auto cb = []() { auto cb = []() {
if (switcher->settingsWindowOpened) { QMainWindow *window =
ssWindow->show(); (QMainWindow *)obs_frontend_get_main_window();
ssWindow->raise();
ssWindow->activateWindow(); AdvSceneSwitcher ss(window);
} else { ss.exec();
ssWindow = new AdvSceneSwitcher(
(QMainWindow *)obs_frontend_get_main_window());
ssWindow->setAttribute(Qt::WA_DeleteOnClose);
ssWindow->show();
}
}; };
obs_frontend_add_save_callback(SaveSceneSwitcher, nullptr); obs_frontend_add_save_callback(SaveSceneSwitcher, nullptr);

View File

@@ -33,17 +33,6 @@ 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__)

View File

@@ -32,27 +32,6 @@ 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 = {};

View File

@@ -1,49 +0,0 @@
#include "headers/file-selection.hpp"
#include <obs-module.h>
#include <QLayout>
#include <QFileDialog>
FileSelection::FileSelection(FileSelection::Type type, QWidget *parent)
: QWidget(parent), _type(type)
{
_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());
}

View File

@@ -3,21 +3,12 @@
#include "headers/version.h" #include "headers/version.h"
#include <QFileDialog> #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()
{ {
close(); done(0);
}
void AdvSceneSwitcher::reject()
{
close();
} }
void AdvSceneSwitcher::UpdateNonMatchingScene(const QString &name) void AdvSceneSwitcher::UpdateNonMatchingScene(const QString &name)
@@ -186,9 +177,6 @@ void AdvSceneSwitcher::on_toggleStartButton_clicked()
void AdvSceneSwitcher::closeEvent(QCloseEvent *) void AdvSceneSwitcher::closeEvent(QCloseEvent *)
{ {
if (!switcher) {
return;
}
switcher->windowPos = this->pos(); switcher->windowPos = this->pos();
switcher->windowSize = this->size(); switcher->windowSize = this->size();
@@ -213,15 +201,6 @@ void AdvSceneSwitcher::on_saveWindowGeo_stateChanged(int state)
switcher->saveWindowGeo = state; switcher->saveWindowGeo = state;
} }
void AdvSceneSwitcher::on_showTrayNotifications_stateChanged(int state)
{
if (loading) {
return;
}
switcher->showSystemTrayNotifications = state;
}
void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state) void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
{ {
if (loading) { if (loading) {
@@ -398,23 +377,9 @@ 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 && windowPosValid(switcher->windowPos)) { if (switcher->saveWindowGeo) {
this->resize(switcher->windowSize); this->resize(switcher->windowSize);
this->move(switcher->windowPos); this->move(switcher->windowPos);
} }
@@ -515,8 +480,6 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
static_cast<int>(autoStartEvent)); static_cast<int>(autoStartEvent));
obs_data_set_bool(obj, "verbose", verbose); obs_data_set_bool(obj, "verbose", verbose);
obs_data_set_bool(obj, "showSystemTrayNotifications",
showSystemTrayNotifications);
obs_data_set_bool(obj, "disableHints", disableHints); obs_data_set_bool(obj, "disableHints", disableHints);
obs_data_set_int(obj, "priority0", functionNamesByPriority[0]); obs_data_set_int(obj, "priority0", functionNamesByPriority[0]);
@@ -588,8 +551,6 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
obs_data_get_int(obj, "autoStartEvent")); obs_data_get_int(obj, "autoStartEvent"));
verbose = obs_data_get_bool(obj, "verbose"); verbose = obs_data_get_bool(obj, "verbose");
showSystemTrayNotifications =
obs_data_get_bool(obj, "showSystemTrayNotifications");
disableHints = obs_data_get_bool(obj, "disableHints"); disableHints = obs_data_get_bool(obj, "disableHints");
obs_data_set_default_int(obj, "priority0", default_priority_0); obs_data_set_default_int(obj, "priority0", default_priority_0);
@@ -816,8 +777,6 @@ void AdvSceneSwitcher::setupGeneralTab()
ui->verboseLogging->setChecked(switcher->verbose); ui->verboseLogging->setChecked(switcher->verbose);
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo); ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
ui->showTrayNotifications->setChecked(
switcher->showSystemTrayNotifications);
ui->uiHintsDisable->setChecked(switcher->disableHints); ui->uiHintsDisable->setChecked(switcher->disableHints);
for (int p : switcher->functionNamesByPriority) { for (int p : switcher->functionNamesByPriority) {
@@ -905,6 +864,4 @@ 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);
} }

View File

@@ -14,8 +14,6 @@
} }
class QCloseEvent; class QCloseEvent;
class MacroActionEdit;
class MacroConditionEdit;
/******************************************************************************* /*******************************************************************************
* Advanced Scene Switcher window * Advanced Scene Switcher window
@@ -29,9 +27,7 @@ public:
bool currentStatusActive = false; bool currentStatusActive = false;
AdvSceneSwitcher(QWidget *parent); AdvSceneSwitcher(QWidget *parent);
~AdvSceneSwitcher();
void reject() override;
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
void SetStarted(); void SetStarted();
@@ -51,14 +47,6 @@ 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, uint32_t afterIdx = 0);
void PopulateMacroConditions(Macro &m, uint32_t 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();
@@ -121,22 +109,8 @@ public slots:
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 ShowMacroActionsContextMenu(const QPoint &); void copyMacro();
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();
@@ -165,7 +139,6 @@ public slots:
void on_verboseLogging_stateChanged(int state); void on_verboseLogging_stateChanged(int state);
void on_saveWindowGeo_stateChanged(int state); void on_saveWindowGeo_stateChanged(int state);
void on_showTrayNotifications_stateChanged(int state);
void on_uiHintsDisable_stateChanged(int state); void on_uiHintsDisable_stateChanged(int state);
void on_exportSettings_clicked(); void on_exportSettings_clicked();

View File

@@ -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__
constexpr auto curl_library_name = "libcurl.4.dylib"; #define curl_library_name "libcurl.4.dylib"
#else #else
constexpr auto curl_library_name = "libcurl.so.4"; #define curl_library_name "libcurl.so.4"
#endif #endif
typedef CURL *(*initFunction)(void); typedef CURL *(*initFunction)(void);

View File

@@ -21,8 +21,6 @@ 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();

View File

@@ -1,30 +0,0 @@
#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;
};

View File

@@ -1,125 +0,0 @@
#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();

View File

@@ -1,10 +1,6 @@
#pragma once #pragma once
#include "macro-action-edit.hpp"
#include "duration-control.hpp"
#include <QSpinBox> #include <QSpinBox>
#include <QCheckBox> #include "macro-action-edit.hpp"
#include <QHBoxLayout>
enum class AudioAction { enum class AudioAction {
MUTE, MUTE,
@@ -19,7 +15,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
{ {
@@ -29,8 +24,6 @@ public:
OBSWeakSource _audioSource; OBSWeakSource _audioSource;
AudioAction _action = AudioAction::MUTE; AudioAction _action = AudioAction::MUTE;
int _volume = 0; int _volume = 0;
bool _fade = false;
Duration _duration;
private: private:
static bool _registered; static bool _registered;
@@ -58,20 +51,14 @@ 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);
void FadeChanged(int value);
void DurationChanged(double seconds);
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
QComboBox *_audioSources; QComboBox *_audioSources;
QComboBox *_actions; QComboBox *_actions;
QSpinBox *_volumePercent; QSpinBox *_volumePercent;
QCheckBox *_fade;
DurationSelection *_duration;
QHBoxLayout *_fadeLayout;
std::shared_ptr<MacroActionAudio> _entryData; std::shared_ptr<MacroActionAudio> _entryData;
private: private:
QHBoxLayout *_mainLayout;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,5 +1,12 @@
#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> (*)();
@@ -25,23 +32,25 @@ private:
static std::map<std::string, MacroActionInfo> _methods; static std::map<std::string, MacroActionInfo> _methods;
}; };
class MacroActionEdit : public MacroSegmentEdit { class MacroActionEdit : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
MacroActionEdit(QWidget *parent = nullptr, MacroActionEdit(QWidget *parent = nullptr,
std::shared_ptr<MacroAction> * = nullptr, std::shared_ptr<MacroAction> * = nullptr,
const std::string &id = "scene_switch"); const std::string &id = "scene_switch",
void UpdateEntryData(const std::string &id); bool startCollapsed = false);
void UpdateEntryData(const std::string &id, bool collapse);
private slots: private slots:
void ActionSelectionChanged(const QString &text); void ActionSelectionChanged(const QString &text);
private: protected:
MacroSegment *Data();
QComboBox *_actionSelection; QComboBox *_actionSelection;
Section *_section;
std::shared_ptr<MacroAction> *_entryData; std::shared_ptr<MacroAction> *_entryData;
private:
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,65 +0,0 @@
#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;
};

View File

@@ -1,12 +1,10 @@
#pragma once #pragma once
#include <QSpinBox> #include <QSpinBox>
#include <QPlainTextEdit>
#include "macro-action-edit.hpp" #include "macro-action-edit.hpp"
enum class FilterAction { enum class FilterAction {
ENABLE, ENABLE,
DISABLE, DISABLE,
SETTINGS,
}; };
class MacroActionFilter : public MacroAction { class MacroActionFilter : public MacroAction {
@@ -15,7 +13,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
{ {
@@ -25,7 +22,6 @@ public:
OBSWeakSource _source; OBSWeakSource _source;
OBSWeakSource _filter; OBSWeakSource _filter;
FilterAction _action = FilterAction::ENABLE; FilterAction _action = FilterAction::ENABLE;
std::string _settings = "";
private: private:
static bool _registered; static bool _registered;
@@ -52,20 +48,14 @@ private slots:
void SourceChanged(const QString &text); void SourceChanged(const QString &text);
void FilterChanged(const QString &text); void FilterChanged(const QString &text);
void ActionChanged(int value); void ActionChanged(int value);
void GetSettingsClicked();
void SettingsChanged();
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
QComboBox *_sources; QComboBox *_sources;
QComboBox *_filters; QComboBox *_filters;
QComboBox *_actions; QComboBox *_actions;
QPushButton *_getSettings;
QPlainTextEdit *_settings;
std::shared_ptr<MacroActionFilter> _entryData; std::shared_ptr<MacroActionFilter> _entryData;
private: private:
void SetWidgetVisibility(bool); QHBoxLayout *_mainLayout;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,92 +0,0 @@
#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;
};

View File

@@ -1,9 +1,8 @@
#pragma once #pragma once
#include <QDoubleSpinBox>
#include "macro-action-edit.hpp" #include "macro-action-edit.hpp"
#include "macro-selection.hpp" #include "macro-selection.hpp"
#include <QHBoxLayout>
enum class PerformMacroAction { enum class PerformMacroAction {
PAUSE, PAUSE,
UNPAUSE, UNPAUSE,
@@ -16,7 +15,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
{ {
@@ -50,8 +48,6 @@ private slots:
void MacroChanged(const QString &text); void MacroChanged(const QString &text);
void MacroRemove(const QString &name); void MacroRemove(const QString &name);
void ActionChanged(int value); void ActionChanged(int value);
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
MacroSelection *_macros; MacroSelection *_macros;

View File

@@ -1,8 +1,6 @@
#pragma once #pragma once
#include "macro-action-edit.hpp"
#include <QSpinBox> #include <QSpinBox>
#include <QHBoxLayout> #include "macro-action-edit.hpp"
enum class MediaAction { enum class MediaAction {
PLAY, PLAY,
@@ -19,7 +17,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
{ {
@@ -53,8 +50,6 @@ public:
private slots: private slots:
void SourceChanged(const QString &text); void SourceChanged(const QString &text);
void ActionChanged(int value); void ActionChanged(int value);
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
QComboBox *_mediaSources; QComboBox *_mediaSources;

View File

@@ -1,12 +1,9 @@
#pragma once #pragma once
#include "macro-action-edit.hpp"
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QHBoxLayout> #include "macro-action-edit.hpp"
enum class PluginStateAction { enum class PluginStateAction {
STOP, STOP,
NO_MATCH_BEHAVIOUR,
}; };
class MacroActionPluginState : public MacroAction { class MacroActionPluginState : public MacroAction {
@@ -22,8 +19,6 @@ public:
} }
PluginStateAction _action = PluginStateAction::STOP; PluginStateAction _action = PluginStateAction::STOP;
int _value = 0;
OBSWeakSource _scene;
private: private:
static bool _registered; static bool _registered;
@@ -49,17 +44,12 @@ public:
private slots: private slots:
void ActionChanged(int value); void ActionChanged(int value);
void ValueChanged(int value);
void SceneChanged(const QString &text);
protected: protected:
QComboBox *_actions; QComboBox *_actions;
QComboBox *_values;
QComboBox *_scenes;
std::shared_ptr<MacroActionPluginState> _entryData; std::shared_ptr<MacroActionPluginState> _entryData;
private: private:
void SetWidgetVisibility(PluginStateAction, int);
QHBoxLayout *_mainLayout; QHBoxLayout *_mainLayout;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,54 +0,0 @@
#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;
};

View File

@@ -1,63 +0,0 @@
#pragma once
#include "macro-action-edit.hpp"
#include "macro-selection.hpp"
#include <QPushButton>
#include <QListWidget>
#include <unordered_map>
class MacroActionRandom : public MultiMacroRefAction {
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<MacroActionRandom>();
}
// TODO: add weights to each macro ...
// std::unordered_map<MacroRef, int> _weights;
private:
MacroRef lastRandomMacro;
static bool _registered;
static const std::string id;
};
class MacroActionRandomEdit : public QWidget {
Q_OBJECT
public:
MacroActionRandomEdit(
QWidget *parent,
std::shared_ptr<MacroActionRandom> entryData = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroAction> action)
{
return new MacroActionRandomEdit(
parent,
std::dynamic_pointer_cast<MacroActionRandom>(action));
}
private slots:
void MacroRemove(const QString &name);
void MacroRename(const QString &oldName, const QString &newName);
void AddMacro();
void RemoveMacro();
int FindEntry(const std::string &macro);
void MacroSelectionChanged(int idx);
protected:
std::shared_ptr<MacroActionRandom> _entryData;
private:
MacroSelection *_macroSelection;
QListWidget *_macroList;
QPushButton *_add;
QPushButton *_remove;
bool _loading = true;
};

View File

@@ -1,9 +1,8 @@
#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,

View File

@@ -1,11 +1,8 @@
#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,
@@ -67,5 +64,3 @@ private:
QHBoxLayout *_mainLayout; QHBoxLayout *_mainLayout;
bool _loading = true; bool _loading = true;
}; };
#endif

View File

@@ -1,11 +1,8 @@
#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:
@@ -13,7 +10,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
{ {
@@ -21,7 +17,6 @@ public:
} }
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;
@@ -44,23 +39,14 @@ public:
} }
private slots: private slots:
void PathChanged(const QString &text); void FilePathChanged();
void AddArg(); void BrowseButtonClicked();
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:
FileSelection *_filePath; QLineEdit *_filePath;
QListWidget *_argList; QPushButton *_browseButton;
QPushButton *_addArg;
QPushButton *_removeArg;
QPushButton *_argUp;
QPushButton *_argDown;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,72 +0,0 @@
#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;
};

View File

@@ -1,38 +0,0 @@
#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;
};

View File

@@ -3,15 +3,12 @@
#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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
@@ -45,9 +42,6 @@ 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;

View File

@@ -1,66 +0,0 @@
#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;
};

View File

@@ -1,35 +1,26 @@
#pragma once #pragma once
#include <QSpinBox> #include <QSpinBox>
#include "macro-action-edit.hpp" #include "macro-action-edit.hpp"
#include "scene-selection.hpp"
enum class SceneVisibilityAction { enum class SceneVisibilityAction {
SHOW, SHOW,
HIDE, HIDE,
}; };
enum class SceneItemSourceType {
SOURCE,
SOURCE_GROUP,
};
class MacroActionSceneVisibility : public MacroAction { class MacroActionSceneVisibility : public MacroAction {
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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
{ {
return std::make_shared<MacroActionSceneVisibility>(); return std::make_shared<MacroActionSceneVisibility>();
} }
SceneSelection _scene; OBSWeakSource _scene;
SceneItemSourceType _sourceType = SceneItemSourceType::SOURCE;
OBSWeakSource _source; OBSWeakSource _source;
std::string _sourceGroup = "";
SceneVisibilityAction _action = SceneVisibilityAction::SHOW; SceneVisibilityAction _action = SceneVisibilityAction::SHOW;
private: private:
@@ -55,16 +46,12 @@ public:
} }
private slots: private slots:
void SceneChanged(const SceneSelection &); void SceneChanged(const QString &text);
void SourceTypeChanged(int value);
void SourceChanged(const QString &text); void SourceChanged(const QString &text);
void ActionChanged(int value); void ActionChanged(int value);
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
SceneSelectionWidget *_scenes; QComboBox *_scenes;
QComboBox *_sourceTypes;
QComboBox *_sources; QComboBox *_sources;
QComboBox *_actions; QComboBox *_actions;
std::shared_ptr<MacroActionSceneVisibility> _entryData; std::shared_ptr<MacroActionSceneVisibility> _entryData;

View File

@@ -18,7 +18,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroAction> Create() static std::shared_ptr<MacroAction> Create()
{ {
@@ -55,8 +54,6 @@ private slots:
void ActionChanged(int value); void ActionChanged(int value);
void GetSettingsClicked(); void GetSettingsClicked();
void SettingsChanged(); void SettingsChanged();
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
QComboBox *_sources; QComboBox *_sources;
@@ -68,5 +65,6 @@ protected:
private: private:
void SetWidgetVisibility(bool); void SetWidgetVisibility(bool);
QHBoxLayout *_mainLayout;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,11 +1,8 @@
#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,

View File

@@ -1,72 +0,0 @@
#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;
};

View File

@@ -1,68 +0,0 @@
#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;
};

View File

@@ -1,61 +0,0 @@
#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

View File

@@ -1,10 +1,8 @@
#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,

View File

@@ -17,7 +17,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroCondition> Create() static std::shared_ptr<MacroCondition> Create()
{ {
@@ -61,8 +60,6 @@ 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);
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
QComboBox *_audioSources; QComboBox *_audioSources;

View File

@@ -0,0 +1,70 @@
#pragma once
#include "macro.hpp"
#include "macro-selection.hpp"
#include <QWidget>
#include <QSpinBox>
#include <QLabel>
#include <QTimer>
enum class CounterCondition {
BELOW,
ABOVE,
EQUAL,
};
class MacroConditionCounter : public MacroRefCondition {
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<MacroConditionCounter>();
}
CounterCondition _condition = CounterCondition::BELOW;
int _count = 0;
private:
static bool _registered;
static const std::string id;
};
class MacroConditionCounterEdit : public QWidget {
Q_OBJECT
public:
MacroConditionCounterEdit(
QWidget *parent,
std::shared_ptr<MacroConditionCounter> cond = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroCondition> cond)
{
return new MacroConditionCounterEdit(
parent,
std::dynamic_pointer_cast<MacroConditionCounter>(cond));
}
private slots:
void MacroChanged(const QString &text);
void MacroRemove(const QString &name);
void CountChanged(int value);
void ConditionChanged(int cond);
void ResetClicked();
void UpdateCount();
protected:
MacroSelection *_macros;
QComboBox *_conditions;
QSpinBox *_count;
QLabel *_currentCount;
QPushButton *_resetCount;
std::unique_ptr<QTimer> _timer;
std::shared_ptr<MacroConditionCounter> _entryData;
private:
void ResetTimer();
bool _loading = true;
};

View File

@@ -1,76 +0,0 @@
#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;
};

View File

@@ -1,82 +0,0 @@
#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;
};

View File

@@ -1,5 +1,12 @@
#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> (*)();
@@ -27,16 +34,16 @@ private:
static std::map<std::string, MacroConditionInfo> _methods; static std::map<std::string, MacroConditionInfo> _methods;
}; };
class MacroConditionEdit : public MacroSegmentEdit { class MacroConditionEdit : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
MacroConditionEdit(QWidget *parent = nullptr, MacroConditionEdit(QWidget *parent = nullptr,
std::shared_ptr<MacroCondition> * = nullptr, std::shared_ptr<MacroCondition> * = nullptr,
const std::string &id = "scene", bool root = true); const std::string &id = "scene", bool root = true,
bool startCollapsed = false);
bool IsRootNode(); bool IsRootNode();
void SetRootNode(bool); void UpdateEntryData(const std::string &id, bool collapse);
void UpdateEntryData(const std::string &id);
private slots: private slots:
void LogicSelectionChanged(int idx); void LogicSelectionChanged(int idx);
@@ -45,14 +52,15 @@ private slots:
void DurationConditionChanged(DurationCondition cond); void DurationConditionChanged(DurationCondition cond);
void DurationUnitChanged(DurationUnit unit); void DurationUnitChanged(DurationUnit unit);
private: protected:
MacroSegment *Data();
QComboBox *_logicSelection; QComboBox *_logicSelection;
QComboBox *_conditionSelection; QComboBox *_conditionSelection;
Section *_section;
DurationConstraintEdit *_dur; DurationConstraintEdit *_dur;
std::shared_ptr<MacroCondition> *_entryData; std::shared_ptr<MacroCondition> *_entryData;
private:
bool _isRoot = true; bool _isRoot = true;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,7 +1,5 @@
#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>
@@ -20,7 +18,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroCondition> Create() static std::shared_ptr<MacroCondition> Create()
{ {
@@ -63,17 +60,17 @@ public:
private slots: private slots:
void FileTypeChanged(int index); void FileTypeChanged(int index);
void PathChanged(const QString &text); void FilePathChanged();
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;
FileSelection *_filePath; QLineEdit *_filePath;
QPushButton *_browseButton;
QPlainTextEdit *_matchText; QPlainTextEdit *_matchText;
QCheckBox *_useRegex; QCheckBox *_useRegex;
QCheckBox *_checkModificationDate; QCheckBox *_checkModificationDate;

View File

@@ -1,77 +0,0 @@
#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;
};

View File

@@ -1,54 +0,0 @@
#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;
};

View File

@@ -0,0 +1,52 @@
#pragma once
#include "macro.hpp"
#include <QWidget>
#include <QComboBox>
#include "duration-control.hpp"
class MacroConditionInterval : 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<MacroConditionInterval>();
}
Duration _duration;
private:
static bool _registered;
static const std::string id;
};
class MacroConditionIntervalEdit : public QWidget {
Q_OBJECT
public:
MacroConditionIntervalEdit(
QWidget *parent,
std::shared_ptr<MacroConditionInterval> cond = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroCondition> cond)
{
return new MacroConditionIntervalEdit(
parent,
std::dynamic_pointer_cast<MacroConditionInterval>(
cond));
}
private slots:
void DurationChanged(double seconds);
void DurationUnitChanged(DurationUnit unit);
protected:
DurationSelection *_duration;
std::shared_ptr<MacroConditionInterval> _entryData;
private:
bool _loading = true;
};

View File

@@ -1,93 +0,0 @@
#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();
void UpdatePaused();
signals:
void HeaderInfoChanged(const QString &);
protected:
MacroSelection *_macros;
QComboBox *_types;
QComboBox *_counterConditions;
QSpinBox *_count;
QLabel *_currentCount;
QLabel *_pausedWarning;
QPushButton *_resetCount;
QHBoxLayout *_settingsLine1;
QHBoxLayout *_settingsLine2;
QTimer _countTimer;
QTimer _pausedTimer;
std::shared_ptr<MacroConditionMacro> _entryData;
private:
void ClearLayouts();
void SetupStateWidgets();
void SetupCountWidgets();
bool _loading = true;
};

View File

@@ -39,7 +39,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroCondition> Create() static std::shared_ptr<MacroCondition> Create()
{ {
@@ -91,8 +90,6 @@ 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;

View File

@@ -1,15 +1,13 @@
#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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroCondition> Create() static std::shared_ptr<MacroCondition> Create()
{ {
@@ -43,8 +41,6 @@ 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;

View File

@@ -0,0 +1,55 @@
#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);
std::string 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 std::string 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;
};

View File

@@ -1,60 +0,0 @@
#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

View File

@@ -1,76 +0,0 @@
#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;
};

View File

@@ -1,69 +0,0 @@
#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;
};

View File

@@ -1,66 +0,0 @@
#pragma once
#include "macro.hpp"
#include "scene-selection.hpp"
#include <QComboBox>
enum class SceneVisibilityCondition {
SHOWN,
HIDDEN,
};
class MacroConditionSceneVisibility : 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<MacroConditionSceneVisibility>();
}
SceneSelection _scene;
OBSWeakSource _source;
SceneVisibilityCondition _condition = SceneVisibilityCondition::SHOWN;
private:
static bool _registered;
static const std::string id;
};
class MacroConditionSceneVisibilityEdit : public QWidget {
Q_OBJECT
public:
MacroConditionSceneVisibilityEdit(
QWidget *parent,
std::shared_ptr<MacroConditionSceneVisibility> cond = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroCondition> cond)
{
return new MacroConditionSceneVisibilityEdit(
parent,
std::dynamic_pointer_cast<MacroConditionSceneVisibility>(
cond));
}
private slots:
void SceneChanged(const SceneSelection &);
void SourceChanged(const QString &text);
void ConditionChanged(int cond);
signals:
void HeaderInfoChanged(const QString &);
protected:
SceneSelectionWidget *_scenes;
QComboBox *_sources;
QComboBox *_conditions;
std::shared_ptr<MacroConditionSceneVisibility> _entryData;
private:
bool _loading = true;
};

View File

@@ -1,16 +1,11 @@
#pragma once #pragma once
#include "macro.hpp" #include "macro.hpp"
#include "scene-selection.hpp"
#include <QWidget> #include <QWidget>
#include <QComboBox> #include <QComboBox>
#include <QCheckBox>
enum class SceneType { enum class SceneType {
CURRENT, CURRENT,
PREVIOUS, PREVIOUS,
CHANGED,
NOTCHANGED,
}; };
class MacroConditionScene : public MacroCondition { class MacroConditionScene : public MacroCondition {
@@ -18,19 +13,16 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; 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>();
} }
bool _waitForTransition = false; OBSWeakSource _scene;
SceneSelection _scene;
SceneType _type; SceneType _type;
private: private:
std::chrono::high_resolution_clock::time_point _lastSceneChangeTime{};
static bool _registered; static bool _registered;
static const std::string id; static const std::string id;
}; };
@@ -52,19 +44,14 @@ public:
} }
private slots: private slots:
void SceneChanged(const SceneSelection &); void SceneChanged(const QString &text);
void TypeChanged(int value); void TypeChanged(int value);
void WaitForTransitionChanged(int state);
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
SceneSelectionWidget *_scenes; QComboBox *_sceneSelection;
QComboBox *_sceneType; QComboBox *_sceneType;
QCheckBox *_waitForTransition;
std::shared_ptr<MacroConditionScene> _entryData; std::shared_ptr<MacroConditionScene> _entryData;
private: private:
void SetWidgetVisibility();
bool _loading = true; bool _loading = true;
}; };

View File

@@ -1,10 +1,7 @@
#pragma once #pragma once
#include "macro.hpp" #include "macro.hpp"
#include <QWidget>
#include <QComboBox> #include <QComboBox>
#include <QPushButton>
#include <QPlainTextEdit>
#include <QCheckBox>
enum class SourceCondition { enum class SourceCondition {
ACTIVE, ACTIVE,
@@ -17,7 +14,6 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroCondition> Create() static std::shared_ptr<MacroCondition> Create()
{ {
@@ -56,8 +52,6 @@ private slots:
void GetSettingsClicked(); void GetSettingsClicked();
void SettingsChanged(); void SettingsChanged();
void RegexChanged(int); void RegexChanged(int);
signals:
void HeaderInfoChanged(const QString &);
protected: protected:
QComboBox *_sources; QComboBox *_sources;

View File

@@ -6,8 +6,6 @@
enum class StreamState { enum class StreamState {
STOP, STOP,
START, START,
STARTING,
STOPPING,
}; };
class MacroConditionStream : public MacroCondition { class MacroConditionStream : public MacroCondition {
@@ -24,9 +22,6 @@ public:
StreamState _streamState; StreamState _streamState;
private: private:
std::chrono::high_resolution_clock::time_point _lastStreamStartingTime{};
std::chrono::high_resolution_clock::time_point _lastStreamStoppingTime{};
static bool _registered; static bool _registered;
static const std::string id; static const std::string id;
}; };

View File

@@ -1,73 +0,0 @@
#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;
};

View File

@@ -1,79 +0,0 @@
#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;
};

View File

@@ -1,14 +1,10 @@
#pragma once #pragma once
#include "macro.hpp" #include "macro.hpp"
#include "screenshot-helper.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 <opencv2/opencv.hpp>
enum class VideoCondition { enum class VideoCondition {
MATCH, MATCH,
@@ -16,25 +12,13 @@ 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);
std::string GetShortDesc();
std::string GetId() { return id; }; 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()
@@ -43,69 +27,20 @@ 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;
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath"); std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
bool _useAlphaAsMask = false;
bool _usePatternForChangedCheck = 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 OutputChanged();
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 std::string 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 {
Q_OBJECT Q_OBJECT
@@ -123,60 +58,21 @@ 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 ImagePathChanged(const QString &text); void FilePathChanged();
void ImageBrowseButtonClicked(); void BrowseButtonClicked();
void UsePatternForChangedCheckChanged(int value);
void PatternThresholdChanged(double);
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;
QComboBox *_condition; QComboBox *_condition;
QLineEdit *_filePath;
QCheckBox *_usePatternForChangedCheck; 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;
}; };

View File

@@ -0,0 +1,51 @@
#pragma once
#include "macro.hpp"
#include <QWidget>
#include <QComboBox>
class MacroConditionVirtDesktop : 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<MacroConditionVirtDesktop>();
}
long _desktop = 0;
private:
static bool _registered;
static const std::string id;
};
class MacroConditionVirtDesktopEdit : public QWidget {
Q_OBJECT
public:
MacroConditionVirtDesktopEdit(
QWidget *parent,
std::shared_ptr<MacroConditionVirtDesktop> cond = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroCondition> cond)
{
return new MacroConditionVirtDesktopEdit(
parent,
std::dynamic_pointer_cast<MacroConditionVirtDesktop>(
cond));
}
private slots:
void DesktopChanged(int value);
void UpdateCurrentDesktop();
protected:
QComboBox *_virtDesktops;
QLabel *_currentDesktop;
std::shared_ptr<MacroConditionVirtDesktop> _entryData;
private:
bool _loading = true;
};

View File

@@ -1,58 +0,0 @@
#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

View File

@@ -1,15 +1,13 @@
#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);
std::string GetShortDesc();
std::string GetId() { return id; }; std::string GetId() { return id; };
static std::shared_ptr<MacroCondition> Create() static std::shared_ptr<MacroCondition> Create()
{ {
@@ -26,7 +24,6 @@ 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;
@@ -53,17 +50,13 @@ 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 FocusedChanged(int state); void FocusChanged(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:

View File

@@ -1,31 +0,0 @@
#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;
};

View File

@@ -1,72 +0,0 @@
#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;
};

View File

@@ -1,5 +1,4 @@
#pragma once #pragma once
#include "macro-segment.hpp"
#include "duration-control.hpp" #include "duration-control.hpp"
#include <string> #include <string>
@@ -37,11 +36,13 @@ struct LogicTypeInfo {
std::string _name; std::string _name;
}; };
class MacroCondition : public MacroSegment { class MacroCondition {
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 std::string 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;
@@ -59,11 +60,12 @@ private:
DurationConstraint _duration; DurationConstraint _duration;
}; };
class MacroAction : public MacroSegment { class MacroAction {
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 std::string GetId() = 0;
virtual void LogAction(); virtual void LogAction();
}; };
@@ -77,7 +79,7 @@ public:
bool Matched() { return _matched; } bool Matched() { return _matched; }
std::string Name() { return _name; } std::string Name() { return _name; }
void SetName(const std::string &name); void SetName(const std::string &name);
void SetPaused(bool pause = true); void SetPaused(bool pause = true) { _paused = pause; }
bool Paused() { return _paused; } bool Paused() { return _paused; }
int GetCount() { return _count; }; int GetCount() { return _count; };
void ResetCount() { _count = 0; }; void ResetCount() { _count = 0; };
@@ -85,8 +87,6 @@ public:
{ {
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);
@@ -102,7 +102,6 @@ private:
void SetupHotkeys(); void SetupHotkeys();
void ClearHotkeys(); void ClearHotkeys();
void SetHotkeysDesc(); void SetHotkeysDesc();
void ResetTimers();
std::string _name = ""; std::string _name = "";
std::deque<std::shared_ptr<MacroCondition>> _conditions; std::deque<std::shared_ptr<MacroCondition>> _conditions;
@@ -145,9 +144,3 @@ public:
void ResolveMacroRef(); void ResolveMacroRef();
MacroRef _macro; MacroRef _macro;
}; };
class MultiMacroRefAction : public MacroAction {
public:
void ResolveMacroRef();
std::vector<MacroRef> _macros;
};

View File

@@ -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, bool clean = true); int maxSize = 170);
private: private:
QLabel *label; QLabel *label;

View File

@@ -1,5 +1,4 @@
#pragma once #pragma once
#include "hotkey.hpp"
void GetWindowList(std::vector<std::string> &windows); void GetWindowList(std::vector<std::string> &windows);
void GetWindowList(QStringList &windows); void GetWindowList(QStringList &windows);
@@ -10,6 +9,5 @@ std::pair<int, int> getCursorPos();
int secondsSinceLastInput(); int secondsSinceLastInput();
void GetProcessList(QStringList &processes); void GetProcessList(QStringList &processes);
bool isInFocus(const QString &executable); bool isInFocus(const QString &executable);
void PressKeys(const std::vector<HotkeyType> keys, int duration); bool GetCurrentVirtualDesktop(long &desktop);
void PlatformInit(); bool GetVirtualDesktopCount(long &ndesktops);
void PlatformCleanup();

View File

@@ -82,6 +82,3 @@ private:
SceneGroup *sceneGroup = nullptr; SceneGroup *sceneGroup = nullptr;
}; };
SceneGroup *GetSceneGroupByName(const char *name);
SceneGroup *GetSceneGroupByQString(const QString &name);

View File

@@ -1,51 +0,0 @@
#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);
};

Some files were not shown because too many files have changed in this diff Show More