mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-26 20:05:25 -05:00
cleanup
This commit is contained in:
parent
3381e6d62f
commit
d41868c660
|
|
@ -1,17 +1,17 @@
|
|||
#include <obs-module.h>
|
||||
|
||||
OBS_DECLARE_MODULE()
|
||||
|
||||
void InitSceneSwitcher();
|
||||
void FreeSceneSwitcher();
|
||||
|
||||
bool obs_module_load(void)
|
||||
{
|
||||
InitSceneSwitcher();
|
||||
return true;
|
||||
}
|
||||
|
||||
void obs_module_unload(void)
|
||||
{
|
||||
FreeSceneSwitcher();
|
||||
}
|
||||
#include <obs-module.h>
|
||||
|
||||
OBS_DECLARE_MODULE()
|
||||
|
||||
void InitSceneSwitcher();
|
||||
void FreeSceneSwitcher();
|
||||
|
||||
bool obs_module_load(void)
|
||||
{
|
||||
InitSceneSwitcher();
|
||||
return true;
|
||||
}
|
||||
|
||||
void obs_module_unload(void)
|
||||
{
|
||||
FreeSceneSwitcher();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,172 +1,168 @@
|
|||
#include <windows.h>
|
||||
#include <util/platform.h>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include <TlHelp32.h>
|
||||
#include <Psapi.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static bool GetWindowTitle(HWND window, string& title)
|
||||
{
|
||||
size_t len = (size_t)GetWindowTextLengthW(window);
|
||||
wstring wtitle;
|
||||
|
||||
wtitle.resize(len);
|
||||
if (!GetWindowTextW(window, &wtitle[0], (int)len + 1))
|
||||
return false;
|
||||
|
||||
len = os_wcs_to_utf8(wtitle.c_str(), 0, nullptr, 0);
|
||||
title.resize(len);
|
||||
os_wcs_to_utf8(wtitle.c_str(), 0, &title[0], len + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WindowValid(HWND window)
|
||||
{
|
||||
LONG_PTR styles, ex_styles;
|
||||
RECT rect;
|
||||
DWORD id;
|
||||
|
||||
if (!IsWindowVisible(window))
|
||||
return false;
|
||||
GetWindowThreadProcessId(window, &id);
|
||||
if (id == GetCurrentProcessId())
|
||||
return false;
|
||||
|
||||
GetClientRect(window, &rect);
|
||||
styles = GetWindowLongPtr(window, GWL_STYLE);
|
||||
ex_styles = GetWindowLongPtr(window, GWL_EXSTYLE);
|
||||
|
||||
if (ex_styles & WS_EX_TOOLWINDOW)
|
||||
return false;
|
||||
if (styles & WS_CHILD)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetWindowList(vector<string>& windows)
|
||||
{
|
||||
HWND window = GetWindow(GetDesktopWindow(), GW_CHILD);
|
||||
|
||||
while (window)
|
||||
{
|
||||
string title;
|
||||
if (WindowValid(window) && GetWindowTitle(window, title))
|
||||
windows.emplace_back(title);
|
||||
window = GetNextWindow(window, GW_HWNDNEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void GetCurrentWindowTitle(string& title)
|
||||
{
|
||||
HWND window = GetForegroundWindow();
|
||||
DWORD pid;
|
||||
DWORD thid;
|
||||
thid = GetWindowThreadProcessId(window, &pid);
|
||||
/*GetWindowText will freeze if the control it is reading was created in another thread.
|
||||
It does not directly read the control.Instead,
|
||||
it waits for the thread that created the control to process a WM_GETTEXT message.
|
||||
So if that thread is frozen in a WaitFor... call you have a deadlock.*/
|
||||
DWORD this_thid = GetCurrentThreadId();
|
||||
//wstring message = L"\nUI id " + to_wstring(thid) + L", this_th_id " + to_wstring(this_thid) + L"\n";
|
||||
//OutputDebugString(message.c_str());
|
||||
//if (this_thid == thid) {
|
||||
if (GetCurrentProcessId() == pid) {
|
||||
title = "OBS";
|
||||
return;
|
||||
}
|
||||
GetWindowTitle(window, title);
|
||||
}
|
||||
|
||||
pair<int, int> getCursorPos()
|
||||
{
|
||||
pair<int, int> pos(0, 0);
|
||||
POINT cursorPos;
|
||||
if (GetPhysicalCursorPos(&cursorPos))
|
||||
{
|
||||
pos.first = cursorPos.x;
|
||||
pos.second = cursorPos.y;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool isFullscreen()
|
||||
{
|
||||
RECT appBounds;
|
||||
RECT rc;
|
||||
GetWindowRect(GetDesktopWindow(), &rc);
|
||||
HWND hwnd = GetForegroundWindow();
|
||||
if (hwnd != GetDesktopWindow() && hwnd != GetShellWindow())
|
||||
{
|
||||
GetWindowRect(hwnd, &appBounds);
|
||||
if (rc.bottom == appBounds.bottom && rc.top == appBounds.top && rc.left == appBounds.left
|
||||
&& rc.right == appBounds.right)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetProcessList(QStringList &processes) {
|
||||
|
||||
HANDLE procSnapshot;
|
||||
PROCESSENTRY32 procEntry;
|
||||
|
||||
procSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (procSnapshot == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
procEntry.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
if (!Process32First(procSnapshot, &procEntry)) {
|
||||
CloseHandle(procSnapshot);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
QString tempexe = QString::fromWCharArray(procEntry.szExeFile);
|
||||
if (tempexe == "System") continue;
|
||||
if (tempexe == "[System Process]") continue;
|
||||
if (processes.contains(tempexe)) continue;
|
||||
processes.append(tempexe);
|
||||
} while (Process32Next(procSnapshot, &procEntry));
|
||||
|
||||
CloseHandle(procSnapshot);
|
||||
}
|
||||
|
||||
bool isInFocus(const QString &exeToCheck) {
|
||||
// only checks if the current foreground window is from the same executable,
|
||||
// may return true for incorrent not meant windows from a program
|
||||
HWND foregroundWindow = GetForegroundWindow();
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(foregroundWindow, &processId);
|
||||
|
||||
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
|
||||
if (process == NULL) return false;
|
||||
|
||||
WCHAR executablePath[600];
|
||||
GetModuleFileNameEx(process, 0, executablePath, 600);
|
||||
CloseHandle(process);
|
||||
|
||||
return exeToCheck == QString::fromWCharArray(executablePath).split(QRegExp("(/|\\\\)")).back();
|
||||
}
|
||||
|
||||
int getLastInputTime()
|
||||
{
|
||||
LASTINPUTINFO lastInputInfo;
|
||||
lastInputInfo.cbSize = sizeof(LASTINPUTINFO);
|
||||
if (GetLastInputInfo(&lastInputInfo))
|
||||
return lastInputInfo.dwTime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getTime()
|
||||
{
|
||||
return GetTickCount();
|
||||
}
|
||||
|
||||
int secondsSinceLastInput()
|
||||
{
|
||||
return (getTime() - getLastInputTime()) / 1000;
|
||||
}
|
||||
#include <windows.h>
|
||||
#include <util/platform.h>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include <TlHelp32.h>
|
||||
#include <Psapi.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static bool GetWindowTitle(HWND window, string& title)
|
||||
{
|
||||
size_t len = (size_t)GetWindowTextLengthW(window);
|
||||
wstring wtitle;
|
||||
|
||||
wtitle.resize(len);
|
||||
if (!GetWindowTextW(window, &wtitle[0], (int)len + 1))
|
||||
return false;
|
||||
|
||||
len = os_wcs_to_utf8(wtitle.c_str(), 0, nullptr, 0);
|
||||
title.resize(len);
|
||||
os_wcs_to_utf8(wtitle.c_str(), 0, &title[0], len + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WindowValid(HWND window)
|
||||
{
|
||||
LONG_PTR styles, ex_styles;
|
||||
RECT rect;
|
||||
DWORD id;
|
||||
|
||||
if (!IsWindowVisible(window))
|
||||
return false;
|
||||
GetWindowThreadProcessId(window, &id);
|
||||
if (id == GetCurrentProcessId())
|
||||
return false;
|
||||
|
||||
GetClientRect(window, &rect);
|
||||
styles = GetWindowLongPtr(window, GWL_STYLE);
|
||||
ex_styles = GetWindowLongPtr(window, GWL_EXSTYLE);
|
||||
|
||||
if (ex_styles & WS_EX_TOOLWINDOW)
|
||||
return false;
|
||||
if (styles & WS_CHILD)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetWindowList(vector<string>& windows)
|
||||
{
|
||||
HWND window = GetWindow(GetDesktopWindow(), GW_CHILD);
|
||||
|
||||
while (window)
|
||||
{
|
||||
string title;
|
||||
if (WindowValid(window) && GetWindowTitle(window, title))
|
||||
windows.emplace_back(title);
|
||||
window = GetNextWindow(window, GW_HWNDNEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void GetCurrentWindowTitle(string& title)
|
||||
{
|
||||
HWND window = GetForegroundWindow();
|
||||
DWORD pid;
|
||||
DWORD thid;
|
||||
thid = GetWindowThreadProcessId(window, &pid);
|
||||
/*GetWindowText will freeze if the control it is reading was created in another thread.
|
||||
It does not directly read the control.Instead,
|
||||
it waits for the thread that created the control to process a WM_GETTEXT message.
|
||||
So if that thread is frozen in a WaitFor... call you have a deadlock.*/
|
||||
if (GetCurrentProcessId() == pid) {
|
||||
title = "OBS";
|
||||
return;
|
||||
}
|
||||
GetWindowTitle(window, title);
|
||||
}
|
||||
|
||||
pair<int, int> getCursorPos()
|
||||
{
|
||||
pair<int, int> pos(0, 0);
|
||||
POINT cursorPos;
|
||||
if (GetPhysicalCursorPos(&cursorPos))
|
||||
{
|
||||
pos.first = cursorPos.x;
|
||||
pos.second = cursorPos.y;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool isFullscreen()
|
||||
{
|
||||
RECT appBounds;
|
||||
RECT rc;
|
||||
GetWindowRect(GetDesktopWindow(), &rc);
|
||||
HWND hwnd = GetForegroundWindow();
|
||||
if (hwnd != GetDesktopWindow() && hwnd != GetShellWindow())
|
||||
{
|
||||
GetWindowRect(hwnd, &appBounds);
|
||||
if (rc.bottom == appBounds.bottom && rc.top == appBounds.top && rc.left == appBounds.left
|
||||
&& rc.right == appBounds.right)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GetProcessList(QStringList &processes) {
|
||||
|
||||
HANDLE procSnapshot;
|
||||
PROCESSENTRY32 procEntry;
|
||||
|
||||
procSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (procSnapshot == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
procEntry.dwSize = sizeof(PROCESSENTRY32);
|
||||
|
||||
if (!Process32First(procSnapshot, &procEntry)) {
|
||||
CloseHandle(procSnapshot);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
QString tempexe = QString::fromWCharArray(procEntry.szExeFile);
|
||||
if (tempexe == "System") continue;
|
||||
if (tempexe == "[System Process]") continue;
|
||||
if (processes.contains(tempexe)) continue;
|
||||
processes.append(tempexe);
|
||||
} while (Process32Next(procSnapshot, &procEntry));
|
||||
|
||||
CloseHandle(procSnapshot);
|
||||
}
|
||||
|
||||
bool isInFocus(const QString &exeToCheck) {
|
||||
// only checks if the current foreground window is from the same executable,
|
||||
// may return true for incorrent not meant windows from a program
|
||||
HWND foregroundWindow = GetForegroundWindow();
|
||||
DWORD processId = 0;
|
||||
GetWindowThreadProcessId(foregroundWindow, &processId);
|
||||
|
||||
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
|
||||
if (process == NULL) return false;
|
||||
|
||||
WCHAR executablePath[600];
|
||||
GetModuleFileNameEx(process, 0, executablePath, 600);
|
||||
CloseHandle(process);
|
||||
|
||||
return exeToCheck == QString::fromWCharArray(executablePath).split(QRegExp("(/|\\\\)")).back();
|
||||
}
|
||||
|
||||
int getLastInputTime()
|
||||
{
|
||||
LASTINPUTINFO lastInputInfo;
|
||||
lastInputInfo.cbSize = sizeof(LASTINPUTINFO);
|
||||
if (GetLastInputInfo(&lastInputInfo))
|
||||
return lastInputInfo.dwTime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getTime()
|
||||
{
|
||||
return GetTickCount();
|
||||
}
|
||||
|
||||
int secondsSinceLastInput()
|
||||
{
|
||||
return (getTime() - getLastInputTime()) / 1000;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,134 +1,175 @@
|
|||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "ui_advanced-scene-switcher.h"
|
||||
#include "switcher-data-structs.hpp"
|
||||
|
||||
struct obs_weak_source;
|
||||
typedef struct obs_weak_source obs_weak_source_t;
|
||||
|
||||
class QCloseEvent;
|
||||
|
||||
class SceneSwitcher : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
std::unique_ptr<Ui_SceneSwitcher> ui;
|
||||
bool loading = true;
|
||||
|
||||
SceneSwitcher(QWidget *parent);
|
||||
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
void SetStarted();
|
||||
void SetStopped();
|
||||
|
||||
int FindByData(const QString &window);
|
||||
int ScreenRegionFindByData(const QString ®ion);
|
||||
int PauseScenesFindByData(const QString &scene);
|
||||
int PauseWindowsFindByData(const QString &window);
|
||||
int IgnoreWindowsFindByData(const QString &window);
|
||||
int SceneRoundTripFindByData(const QString &scene1);
|
||||
int SceneTransitionsFindByData(const QString &scene1, const QString &scene2);
|
||||
int DefaultTransitionsFindByData(const QString &scene);
|
||||
int executableFindByData(const QString &exe);
|
||||
int IgnoreIdleWindowsFindByData(const QString& window);
|
||||
int randomFindByData(const QString& scene);
|
||||
|
||||
void UpdateNonMatchingScene(const QString &name);
|
||||
void UpdateAutoStopScene(const QString &name);
|
||||
void UpdateIdleDataTransition(const QString& name);
|
||||
void UpdateIdleDataScene(const QString& name);
|
||||
|
||||
public slots:
|
||||
void on_switches_currentRowChanged(int idx);
|
||||
void on_add_clicked();
|
||||
void on_remove_clicked();
|
||||
void on_noMatchDontSwitch_clicked();
|
||||
void on_noMatchSwitch_clicked();
|
||||
void on_noMatchRandomSwitch_clicked();
|
||||
void on_startAtLaunch_toggled(bool value);
|
||||
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
|
||||
void on_checkInterval_valueChanged(int value);
|
||||
void on_toggleStartButton_clicked();
|
||||
|
||||
void on_screenRegions_currentRowChanged(int idx);
|
||||
void on_screenRegionAdd_clicked();
|
||||
void on_screenRegionRemove_clicked();
|
||||
|
||||
void on_pauseScenes_currentRowChanged(int idx);
|
||||
void on_pauseScenesAdd_clicked();
|
||||
void on_pauseScenesRemove_clicked();
|
||||
|
||||
void on_pauseWindows_currentRowChanged(int idx);
|
||||
void on_pauseWindowsAdd_clicked();
|
||||
void on_pauseWindowsRemove_clicked();
|
||||
|
||||
void on_ignoreWindows_currentRowChanged(int idx);
|
||||
void on_ignoreWindowsAdd_clicked();
|
||||
void on_ignoreWindowsRemove_clicked();
|
||||
|
||||
void on_sceneRoundTrips_currentRowChanged(int idx);
|
||||
void on_sceneRoundTripAdd_clicked();
|
||||
void on_sceneRoundTripRemove_clicked();
|
||||
void on_sceneRoundTripSave_clicked();
|
||||
void on_sceneRoundTripLoad_clicked();
|
||||
|
||||
void on_autoStopSceneCheckBox_stateChanged(int state);
|
||||
void on_autoStopScenes_currentTextChanged(const QString &text);
|
||||
|
||||
void on_sceneTransitions_currentRowChanged(int idx);
|
||||
void on_transitionsAdd_clicked();
|
||||
void on_transitionsRemove_clicked();
|
||||
void on_defaultTransitions_currentRowChanged(int idx);
|
||||
void on_defaultTransitionsAdd_clicked();
|
||||
void on_defaultTransitionsRemove_clicked();
|
||||
|
||||
void on_browseButton_clicked();
|
||||
void on_readFileCheckBox_stateChanged(int state);
|
||||
void on_readPathLineEdit_textChanged(const QString & text);
|
||||
void on_writePathLineEdit_textChanged(const QString & text);
|
||||
void on_browseButton_2_clicked();
|
||||
|
||||
void on_executableAdd_clicked();
|
||||
void on_executableRemove_clicked();
|
||||
void on_executables_currentRowChanged(int idx);
|
||||
|
||||
void on_idleCheckBox_stateChanged(int state);
|
||||
void on_idleTransitions_currentTextChanged(const QString& text);
|
||||
void on_idleScenes_currentTextChanged(const QString& text);
|
||||
void on_idleSpinBox_valueChanged(int i);
|
||||
void on_ignoreIdleWindows_currentRowChanged(int idx);
|
||||
void on_ignoreIdleAdd_clicked();
|
||||
void on_ignoreIdleRemove_clicked();
|
||||
|
||||
void on_randomAdd_clicked();
|
||||
void on_randomRemove_clicked();
|
||||
void on_randomScenesList_currentRowChanged(int idx);
|
||||
|
||||
void on_fileAdd_clicked();
|
||||
void on_fileRemove_clicked();
|
||||
void on_fileScenesList_currentRowChanged(int idx);
|
||||
void on_browseButton_3_clicked();
|
||||
|
||||
void on_priorityUp_clicked();
|
||||
void on_priorityDown_clicked();
|
||||
|
||||
void updateScreenRegionCursorPos();
|
||||
|
||||
void on_close_clicked();
|
||||
};
|
||||
|
||||
void GetWindowList(std::vector<std::string> &windows);
|
||||
void GetCurrentWindowTitle(std::string &title);
|
||||
pair<int, int> getCursorPos();
|
||||
bool isFullscreen();
|
||||
int secondsSinceLastInput();
|
||||
bool isInFocus(const QString &exeToCheck);
|
||||
void GetProcessList(QStringList &processes);
|
||||
|
||||
struct SwitcherData;
|
||||
extern SwitcherData* switcher;
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "ui_advanced-scene-switcher.h"
|
||||
#include "switcher-data-structs.hpp"
|
||||
|
||||
class QCloseEvent;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Advanced Scene Switcher window
|
||||
*******************************************************************************/
|
||||
class SceneSwitcher : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
std::unique_ptr<Ui_SceneSwitcher> ui;
|
||||
bool loading = true;
|
||||
|
||||
SceneSwitcher(QWidget *parent);
|
||||
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
void SetStarted();
|
||||
void SetStopped();
|
||||
|
||||
int FindByData(const QString &window);
|
||||
int ScreenRegionFindByData(const QString ®ion);
|
||||
int PauseScenesFindByData(const QString &scene);
|
||||
int PauseWindowsFindByData(const QString &window);
|
||||
int IgnoreWindowsFindByData(const QString &window);
|
||||
int SceneRoundTripFindByData(const QString &scene1);
|
||||
int SceneTransitionsFindByData(const QString &scene1, const QString &scene2);
|
||||
int DefaultTransitionsFindByData(const QString &scene);
|
||||
int executableFindByData(const QString &exe);
|
||||
int IgnoreIdleWindowsFindByData(const QString& window);
|
||||
int randomFindByData(const QString& scene);
|
||||
|
||||
void UpdateNonMatchingScene(const QString &name);
|
||||
void UpdateAutoStopScene(const QString &name);
|
||||
void UpdateIdleDataTransition(const QString& name);
|
||||
void UpdateIdleDataScene(const QString& name);
|
||||
|
||||
public slots:
|
||||
void on_switches_currentRowChanged(int idx);
|
||||
void on_add_clicked();
|
||||
void on_remove_clicked();
|
||||
void on_noMatchDontSwitch_clicked();
|
||||
void on_noMatchSwitch_clicked();
|
||||
void on_noMatchRandomSwitch_clicked();
|
||||
void on_startAtLaunch_toggled(bool value);
|
||||
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
|
||||
void on_checkInterval_valueChanged(int value);
|
||||
void on_toggleStartButton_clicked();
|
||||
|
||||
void on_screenRegions_currentRowChanged(int idx);
|
||||
void on_screenRegionAdd_clicked();
|
||||
void on_screenRegionRemove_clicked();
|
||||
|
||||
void on_pauseScenes_currentRowChanged(int idx);
|
||||
void on_pauseScenesAdd_clicked();
|
||||
void on_pauseScenesRemove_clicked();
|
||||
|
||||
void on_pauseWindows_currentRowChanged(int idx);
|
||||
void on_pauseWindowsAdd_clicked();
|
||||
void on_pauseWindowsRemove_clicked();
|
||||
|
||||
void on_ignoreWindows_currentRowChanged(int idx);
|
||||
void on_ignoreWindowsAdd_clicked();
|
||||
void on_ignoreWindowsRemove_clicked();
|
||||
|
||||
void on_sceneRoundTrips_currentRowChanged(int idx);
|
||||
void on_sceneRoundTripAdd_clicked();
|
||||
void on_sceneRoundTripRemove_clicked();
|
||||
void on_sceneRoundTripSave_clicked();
|
||||
void on_sceneRoundTripLoad_clicked();
|
||||
|
||||
void on_autoStopSceneCheckBox_stateChanged(int state);
|
||||
void on_autoStopScenes_currentTextChanged(const QString &text);
|
||||
|
||||
void on_sceneTransitions_currentRowChanged(int idx);
|
||||
void on_transitionsAdd_clicked();
|
||||
void on_transitionsRemove_clicked();
|
||||
void on_defaultTransitions_currentRowChanged(int idx);
|
||||
void on_defaultTransitionsAdd_clicked();
|
||||
void on_defaultTransitionsRemove_clicked();
|
||||
|
||||
void on_browseButton_clicked();
|
||||
void on_readFileCheckBox_stateChanged(int state);
|
||||
void on_readPathLineEdit_textChanged(const QString & text);
|
||||
void on_writePathLineEdit_textChanged(const QString & text);
|
||||
void on_browseButton_2_clicked();
|
||||
|
||||
void on_executableAdd_clicked();
|
||||
void on_executableRemove_clicked();
|
||||
void on_executables_currentRowChanged(int idx);
|
||||
|
||||
void on_idleCheckBox_stateChanged(int state);
|
||||
void on_idleTransitions_currentTextChanged(const QString& text);
|
||||
void on_idleScenes_currentTextChanged(const QString& text);
|
||||
void on_idleSpinBox_valueChanged(int i);
|
||||
void on_ignoreIdleWindows_currentRowChanged(int idx);
|
||||
void on_ignoreIdleAdd_clicked();
|
||||
void on_ignoreIdleRemove_clicked();
|
||||
|
||||
void on_randomAdd_clicked();
|
||||
void on_randomRemove_clicked();
|
||||
void on_randomScenesList_currentRowChanged(int idx);
|
||||
|
||||
void on_fileAdd_clicked();
|
||||
void on_fileRemove_clicked();
|
||||
void on_fileScenesList_currentRowChanged(int idx);
|
||||
void on_browseButton_3_clicked();
|
||||
|
||||
void on_priorityUp_clicked();
|
||||
void on_priorityDown_clicked();
|
||||
|
||||
void updateScreenRegionCursorPos();
|
||||
|
||||
void on_close_clicked();
|
||||
};
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Windowtitle helper
|
||||
********************************************************************************/
|
||||
void GetWindowList(std::vector<std::string> &windows);
|
||||
void GetCurrentWindowTitle(std::string &title);
|
||||
bool isFullscreen();
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Screenregion helper
|
||||
********************************************************************************/
|
||||
pair<int, int> getCursorPos();
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Idle detection helper
|
||||
********************************************************************************/
|
||||
int secondsSinceLastInput();
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Executable helper
|
||||
********************************************************************************/
|
||||
void GetProcessList(QStringList &processes);
|
||||
bool isInFocus(const QString &exeToCheck);
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Sceneswitch helper
|
||||
********************************************************************************/
|
||||
struct obs_weak_source;
|
||||
typedef struct obs_weak_source obs_weak_source_t;
|
||||
|
||||
obs_weak_source_t* getNextTransition(obs_weak_source_t* scene1, obs_weak_source_t* scene2);
|
||||
void switchScene(OBSWeakSource scene, OBSWeakSource transition);
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Hotkey helper
|
||||
********************************************************************************/
|
||||
void startStopHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pressed);
|
||||
void loadKeybinding(obs_hotkey_id hotkeyId);
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Main SwitcherData
|
||||
********************************************************************************/
|
||||
struct SwitcherData;
|
||||
extern SwitcherData* switcher;
|
||||
|
|
|
|||
|
|
@ -1,140 +1,140 @@
|
|||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
int SceneSwitcher::executableFindByData(const QString& exe)
|
||||
{
|
||||
int count = ui->executables->count();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->executables->item(i);
|
||||
QString itemExe = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemExe == exe)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_executables_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->executables->item(idx);
|
||||
|
||||
QString exec = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->executableSwitches)
|
||||
{
|
||||
if (exec.compare(s.mExe) == 0)
|
||||
{
|
||||
QString sceneName = GetWeakSourceName(s.mScene).c_str();
|
||||
QString transitionName = GetWeakSourceName(s.mTransition).c_str();
|
||||
ui->executableScenes->setCurrentText(sceneName);
|
||||
ui->executable->setCurrentText(exec);
|
||||
ui->executableTransitions->setCurrentText(transitionName);
|
||||
ui->requiresFocusCheckBox->setChecked(s.mInFocus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_executableAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->executableScenes->currentText();
|
||||
QString exeName = ui->executable->currentText();
|
||||
QString transitionName = ui->executableTransitions->currentText();
|
||||
bool inFocus = ui->requiresFocusCheckBox->isChecked();
|
||||
|
||||
if (exeName.isEmpty() || sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
QVariant v = QVariant::fromValue(exeName);
|
||||
|
||||
QString text = MakeSwitchNameExecutable(sceneName, exeName, transitionName, inFocus);
|
||||
|
||||
int idx = executableFindByData(exeName);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->executableSwitches.emplace_back(
|
||||
source, transition, exeName.toUtf8().constData(), inFocus);
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->executables);
|
||||
item->setData(Qt::UserRole, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->executables->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->executableSwitches)
|
||||
{
|
||||
if (s.mExe == exeName)
|
||||
{
|
||||
s.mScene = source;
|
||||
s.mTransition = transition;
|
||||
s.mInFocus = inFocus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->executables->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_executableRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->executables->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString exe = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->executableSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.mExe == exe)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SwitcherData::checkExeSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
QStringList runningProcesses;
|
||||
GetProcessList(runningProcesses);
|
||||
for (ExecutableSceneSwitch& s : executableSwitches)
|
||||
{
|
||||
if (runningProcesses.contains(s.mExe))
|
||||
{
|
||||
scene = s.mScene;
|
||||
transition = s.mTransition;
|
||||
match = !s.mInFocus || (s.mInFocus && isInFocus(s.mExe));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
int SceneSwitcher::executableFindByData(const QString& exe)
|
||||
{
|
||||
int count = ui->executables->count();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->executables->item(i);
|
||||
QString itemExe = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemExe == exe)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_executables_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->executables->item(idx);
|
||||
|
||||
QString exec = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->executableSwitches)
|
||||
{
|
||||
if (exec.compare(s.mExe) == 0)
|
||||
{
|
||||
QString sceneName = GetWeakSourceName(s.mScene).c_str();
|
||||
QString transitionName = GetWeakSourceName(s.mTransition).c_str();
|
||||
ui->executableScenes->setCurrentText(sceneName);
|
||||
ui->executable->setCurrentText(exec);
|
||||
ui->executableTransitions->setCurrentText(transitionName);
|
||||
ui->requiresFocusCheckBox->setChecked(s.mInFocus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_executableAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->executableScenes->currentText();
|
||||
QString exeName = ui->executable->currentText();
|
||||
QString transitionName = ui->executableTransitions->currentText();
|
||||
bool inFocus = ui->requiresFocusCheckBox->isChecked();
|
||||
|
||||
if (exeName.isEmpty() || sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
QVariant v = QVariant::fromValue(exeName);
|
||||
|
||||
QString text = MakeSwitchNameExecutable(sceneName, exeName, transitionName, inFocus);
|
||||
|
||||
int idx = executableFindByData(exeName);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->executableSwitches.emplace_back(
|
||||
source, transition, exeName.toUtf8().constData(), inFocus);
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->executables);
|
||||
item->setData(Qt::UserRole, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->executables->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->executableSwitches)
|
||||
{
|
||||
if (s.mExe == exeName)
|
||||
{
|
||||
s.mScene = source;
|
||||
s.mTransition = transition;
|
||||
s.mInFocus = inFocus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->executables->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_executableRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->executables->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString exe = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->executableSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.mExe == exe)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SwitcherData::checkExeSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
QStringList runningProcesses;
|
||||
GetProcessList(runningProcesses);
|
||||
for (ExecutableSceneSwitch& s : executableSwitches)
|
||||
{
|
||||
if (runningProcesses.contains(s.mExe))
|
||||
{
|
||||
scene = s.mScene;
|
||||
transition = s.mTransition;
|
||||
match = !s.mInFocus || (s.mInFocus && isInFocus(s.mExe));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
515
file-switch.cpp
515
file-switch.cpp
|
|
@ -1,261 +1,254 @@
|
|||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <QDateTime>
|
||||
#include <obs.hpp>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
|
||||
|
||||
void SceneSwitcher::on_browseButton_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to write to ..."), QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (!path.isEmpty())
|
||||
ui->writePathLineEdit->setText(path);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_readFileCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (!state)
|
||||
{
|
||||
ui->browseButton_2->setDisabled(true);
|
||||
ui->readPathLineEdit->setDisabled(true);
|
||||
switcher->fileIO.readEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->browseButton_2->setDisabled(false);
|
||||
ui->readPathLineEdit->setDisabled(false);
|
||||
switcher->fileIO.readEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_readPathLineEdit_textChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (text.isEmpty())
|
||||
{
|
||||
switcher->fileIO.readEnabled = false;
|
||||
return;
|
||||
}
|
||||
switcher->fileIO.readEnabled = true;
|
||||
switcher->fileIO.readPath = text.toUtf8().constData();
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_writePathLineEdit_textChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (text.isEmpty())
|
||||
{
|
||||
switcher->fileIO.writeEnabled = false;
|
||||
return;
|
||||
}
|
||||
switcher->fileIO.writeEnabled = true;
|
||||
switcher->fileIO.writePath = text.toUtf8().constData();
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_browseButton_2_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to read from ..."), QDir::currentPath(), tr("Any files (*.*)"));
|
||||
if (!path.isEmpty())
|
||||
ui->readPathLineEdit->setText(path);
|
||||
}
|
||||
|
||||
void SwitcherData::writeSceneInfoToFile()
|
||||
{
|
||||
if (!fileIO.writeEnabled || fileIO.writePath.empty())
|
||||
return;
|
||||
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
|
||||
QFile file(QString::fromStdString(fileIO.writePath));
|
||||
if (file.open(QIODevice::WriteOnly))
|
||||
{
|
||||
const char* msg = obs_source_get_name(currentSource);
|
||||
file.write(msg, qstrlen(msg));
|
||||
file.close();
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
}
|
||||
|
||||
obs_weak_source_t* getNextTransition(obs_weak_source_t* scene1, obs_weak_source_t* scene2);
|
||||
|
||||
void SwitcherData::checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
if (!fileIO.readEnabled || fileIO.readPath.empty())
|
||||
return;
|
||||
|
||||
QFile file(QString::fromStdString(fileIO.readPath));
|
||||
if (file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QTextStream in(&file);
|
||||
QString sceneStr = in.readLine();
|
||||
obs_source_t* sceneRead = obs_get_source_by_name(sceneStr.toUtf8().constData());
|
||||
if (sceneRead){
|
||||
obs_weak_source_t* sceneReadWs = obs_source_get_weak_source(sceneRead);
|
||||
|
||||
match = true;
|
||||
scene = sceneReadWs;
|
||||
transition = nullptr;
|
||||
|
||||
obs_weak_source_release(sceneReadWs);
|
||||
obs_source_release(sceneRead);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::checkFileContent(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
for (FileSwitch& s : fileSwitches)
|
||||
{
|
||||
bool equal = false;
|
||||
QString t = QString::fromStdString(s.text);
|
||||
QFile file(QString::fromStdString(s.file));
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
continue;
|
||||
|
||||
//check file mod date
|
||||
if (s.useTime)
|
||||
{
|
||||
QDateTime newLastMod = QFileInfo(file).lastModified();
|
||||
if (s.lastMod == newLastMod)
|
||||
continue;
|
||||
s.lastMod = newLastMod;
|
||||
}
|
||||
|
||||
|
||||
if (s.useRegex)
|
||||
{
|
||||
QTextStream in(&file);
|
||||
QRegExp rx(t);
|
||||
equal = rx.exactMatch(in.readAll());
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Im using QTextStream here so the conversion between different lineendings is done by QT.
|
||||
*QT itself uses only the linefeed internally so the input by the user is always using that,
|
||||
*but the files selected by the user might use different line endings.
|
||||
*If you are reading this and know of a cleaner way to do this, please let me know :)
|
||||
*/
|
||||
QTextStream in(&file);
|
||||
QTextStream text(&t);
|
||||
while (!in.atEnd() && !text.atEnd())
|
||||
{
|
||||
QString fileLine = in.readLine();
|
||||
QString textLine = text.readLine();
|
||||
if (QString::compare(fileLine, textLine, Qt::CaseSensitive) != 0)
|
||||
{
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
equal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
if (equal)
|
||||
{
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
match = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_browseButton_3_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to read from ..."), QDir::currentPath(), tr("Any files (*.*)"));
|
||||
if (!path.isEmpty())
|
||||
ui->filePathLineEdit->setText(path);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_fileAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->fileScenes->currentText();
|
||||
QString transitionName = ui->fileTransitions->currentText();
|
||||
QString fileName = ui->filePathLineEdit->text();
|
||||
QString text = ui->fileTextEdit->toPlainText();
|
||||
bool useRegex = ui->fileContentRegExCheckBox->isChecked();
|
||||
bool useTime = ui->fileContentTimeCheckBox->isChecked();
|
||||
|
||||
if (sceneName.isEmpty() || transitionName.isEmpty() || fileName.isEmpty() || text.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString switchText = MakeFileSwitchName(sceneName, transitionName, fileName, text, useRegex, useTime);
|
||||
QVariant v = QVariant::fromValue(switchText);
|
||||
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(switchText, ui->fileScenesList);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->fileSwitches.emplace_back(
|
||||
source, transition, fileName.toUtf8().constData(), text.toUtf8().constData(), useRegex, useTime);
|
||||
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_fileRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->fileScenesList->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
int idx = ui->fileScenesList->currentRow();
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
auto& switches = switcher->fileSwitches;
|
||||
switches.erase(switches.begin() + idx);
|
||||
}
|
||||
qDeleteAll(ui->fileScenesList->selectedItems());
|
||||
//delete item;
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_fileScenesList_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
if (switcher->fileSwitches.size() <= idx)
|
||||
return;
|
||||
FileSwitch s = switcher->fileSwitches[idx];
|
||||
|
||||
string sceneName = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
|
||||
ui->fileScenes->setCurrentText(sceneName.c_str());
|
||||
ui->fileTransitions->setCurrentText(transitionName.c_str());
|
||||
ui->fileTextEdit->setPlainText(s.text.c_str());
|
||||
ui->filePathLineEdit->setText(s.file.c_str());
|
||||
ui->fileContentRegExCheckBox->setChecked(s.useRegex);
|
||||
ui->fileContentTimeCheckBox->setChecked(s.useTime);
|
||||
}
|
||||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <QDateTime>
|
||||
#include <obs.hpp>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
|
||||
|
||||
void SceneSwitcher::on_browseButton_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to write to ..."), QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (!path.isEmpty())
|
||||
ui->writePathLineEdit->setText(path);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_readFileCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (!state)
|
||||
{
|
||||
ui->browseButton_2->setDisabled(true);
|
||||
ui->readPathLineEdit->setDisabled(true);
|
||||
switcher->fileIO.readEnabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->browseButton_2->setDisabled(false);
|
||||
ui->readPathLineEdit->setDisabled(false);
|
||||
switcher->fileIO.readEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_readPathLineEdit_textChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (text.isEmpty())
|
||||
{
|
||||
switcher->fileIO.readEnabled = false;
|
||||
return;
|
||||
}
|
||||
switcher->fileIO.readEnabled = true;
|
||||
switcher->fileIO.readPath = text.toUtf8().constData();
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_writePathLineEdit_textChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (text.isEmpty())
|
||||
{
|
||||
switcher->fileIO.writeEnabled = false;
|
||||
return;
|
||||
}
|
||||
switcher->fileIO.writeEnabled = true;
|
||||
switcher->fileIO.writePath = text.toUtf8().constData();
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_browseButton_2_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to read from ..."), QDir::currentPath(), tr("Any files (*.*)"));
|
||||
if (!path.isEmpty())
|
||||
ui->readPathLineEdit->setText(path);
|
||||
}
|
||||
|
||||
void SwitcherData::writeSceneInfoToFile()
|
||||
{
|
||||
if (!fileIO.writeEnabled || fileIO.writePath.empty())
|
||||
return;
|
||||
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
|
||||
QFile file(QString::fromStdString(fileIO.writePath));
|
||||
if (file.open(QIODevice::WriteOnly))
|
||||
{
|
||||
const char* msg = obs_source_get_name(currentSource);
|
||||
file.write(msg, qstrlen(msg));
|
||||
file.close();
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
}
|
||||
|
||||
void SwitcherData::checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
if (!fileIO.readEnabled || fileIO.readPath.empty())
|
||||
return;
|
||||
|
||||
QFile file(QString::fromStdString(fileIO.readPath));
|
||||
if (file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QTextStream in(&file);
|
||||
QString sceneStr = in.readLine();
|
||||
obs_source_t* sceneRead = obs_get_source_by_name(sceneStr.toUtf8().constData());
|
||||
if (sceneRead){
|
||||
obs_weak_source_t* sceneReadWs = obs_source_get_weak_source(sceneRead);
|
||||
|
||||
match = true;
|
||||
scene = sceneReadWs;
|
||||
transition = nullptr;
|
||||
|
||||
obs_weak_source_release(sceneReadWs);
|
||||
obs_source_release(sceneRead);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::checkFileContent(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
for (FileSwitch& s : fileSwitches)
|
||||
{
|
||||
bool equal = false;
|
||||
QString t = QString::fromStdString(s.text);
|
||||
QFile file(QString::fromStdString(s.file));
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
continue;
|
||||
|
||||
if (s.useTime)
|
||||
{
|
||||
QDateTime newLastMod = QFileInfo(file).lastModified();
|
||||
if (s.lastMod == newLastMod)
|
||||
continue;
|
||||
s.lastMod = newLastMod;
|
||||
}
|
||||
|
||||
if (s.useRegex)
|
||||
{
|
||||
QTextStream in(&file);
|
||||
QRegExp rx(t);
|
||||
equal = rx.exactMatch(in.readAll());
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Im using QTextStream here so the conversion between different lineendings is done by QT.
|
||||
*QT itself uses only the linefeed internally so the input by the user is always using that,
|
||||
*but the files selected by the user might use different line endings.
|
||||
*If you are reading this and know of a cleaner way to do this, please let me know :)
|
||||
*/
|
||||
QTextStream in(&file);
|
||||
QTextStream text(&t);
|
||||
while (!in.atEnd() && !text.atEnd())
|
||||
{
|
||||
QString fileLine = in.readLine();
|
||||
QString textLine = text.readLine();
|
||||
if (QString::compare(fileLine, textLine, Qt::CaseSensitive) != 0)
|
||||
{
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
equal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
if (equal)
|
||||
{
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
match = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_browseButton_3_clicked()
|
||||
{
|
||||
QString path = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to read from ..."), QDir::currentPath(), tr("Any files (*.*)"));
|
||||
if (!path.isEmpty())
|
||||
ui->filePathLineEdit->setText(path);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_fileAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->fileScenes->currentText();
|
||||
QString transitionName = ui->fileTransitions->currentText();
|
||||
QString fileName = ui->filePathLineEdit->text();
|
||||
QString text = ui->fileTextEdit->toPlainText();
|
||||
bool useRegex = ui->fileContentRegExCheckBox->isChecked();
|
||||
bool useTime = ui->fileContentTimeCheckBox->isChecked();
|
||||
|
||||
if (sceneName.isEmpty() || transitionName.isEmpty() || fileName.isEmpty() || text.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString switchText = MakeFileSwitchName(sceneName, transitionName, fileName, text, useRegex, useTime);
|
||||
QVariant v = QVariant::fromValue(switchText);
|
||||
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(switchText, ui->fileScenesList);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->fileSwitches.emplace_back(
|
||||
source, transition, fileName.toUtf8().constData(), text.toUtf8().constData(), useRegex, useTime);
|
||||
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_fileRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->fileScenesList->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
int idx = ui->fileScenesList->currentRow();
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
auto& switches = switcher->fileSwitches;
|
||||
switches.erase(switches.begin() + idx);
|
||||
}
|
||||
qDeleteAll(ui->fileScenesList->selectedItems());
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_fileScenesList_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
if (switcher->fileSwitches.size() <= idx)
|
||||
return;
|
||||
FileSwitch s = switcher->fileSwitches[idx];
|
||||
|
||||
string sceneName = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
|
||||
ui->fileScenes->setCurrentText(sceneName.c_str());
|
||||
ui->fileTransitions->setCurrentText(transitionName.c_str());
|
||||
ui->fileTextEdit->setPlainText(s.text.c_str());
|
||||
ui->filePathLineEdit->setText(s.file.c_str());
|
||||
ui->fileContentRegExCheckBox->setChecked(s.useRegex);
|
||||
ui->fileContentTimeCheckBox->setChecked(s.useTime);
|
||||
}
|
||||
|
|
|
|||
214
general.cpp
214
general.cpp
|
|
@ -1,107 +1,107 @@
|
|||
#include "advanced-scene-switcher.hpp"
|
||||
#include <obs-module.h>
|
||||
|
||||
void SceneSwitcher::on_close_clicked()
|
||||
{
|
||||
done(0);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_startAtLaunch_toggled(bool value)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->startAtLaunch = value;
|
||||
}
|
||||
|
||||
void SceneSwitcher::UpdateNonMatchingScene(const QString& name)
|
||||
{
|
||||
obs_source_t* scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->nonMatchingScene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchDontSwitch_clicked()
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = NO_SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchSwitch_clicked()
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(true);
|
||||
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchRandomSwitch_clicked()
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = RANDOM_SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateNonMatchingScene(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_checkInterval_valueChanged(int value)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->interval = value;
|
||||
}
|
||||
|
||||
void SceneSwitcher::SetStarted()
|
||||
{
|
||||
ui->toggleStartButton->setText("Stop");
|
||||
ui->pluginRunningText->setText("Active");
|
||||
}
|
||||
|
||||
void SceneSwitcher::SetStopped()
|
||||
{
|
||||
ui->toggleStartButton->setText("Start");
|
||||
ui->pluginRunningText->setText("Inactive");
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_toggleStartButton_clicked()
|
||||
{
|
||||
if (switcher->th.joinable())
|
||||
{
|
||||
switcher->Stop();
|
||||
SetStopped();
|
||||
}
|
||||
else
|
||||
{
|
||||
switcher->Start();
|
||||
SetStarted();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::closeEvent(QCloseEvent*)
|
||||
{
|
||||
obs_frontend_save();
|
||||
}
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
#include <obs-module.h>
|
||||
|
||||
void SceneSwitcher::on_close_clicked()
|
||||
{
|
||||
done(0);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_startAtLaunch_toggled(bool value)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->startAtLaunch = value;
|
||||
}
|
||||
|
||||
void SceneSwitcher::UpdateNonMatchingScene(const QString& name)
|
||||
{
|
||||
obs_source_t* scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->nonMatchingScene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchDontSwitch_clicked()
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = NO_SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchSwitch_clicked()
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(true);
|
||||
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchRandomSwitch_clicked()
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switchIfNotMatching = RANDOM_SWITCH;
|
||||
ui->noMatchSwitchScene->setEnabled(false);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateNonMatchingScene(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_checkInterval_valueChanged(int value)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->interval = value;
|
||||
}
|
||||
|
||||
void SceneSwitcher::SetStarted()
|
||||
{
|
||||
ui->toggleStartButton->setText("Stop");
|
||||
ui->pluginRunningText->setText("Active");
|
||||
}
|
||||
|
||||
void SceneSwitcher::SetStopped()
|
||||
{
|
||||
ui->toggleStartButton->setText("Start");
|
||||
ui->pluginRunningText->setText("Inactive");
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_toggleStartButton_clicked()
|
||||
{
|
||||
if (switcher->th.joinable())
|
||||
{
|
||||
switcher->Stop();
|
||||
SetStopped();
|
||||
}
|
||||
else
|
||||
{
|
||||
switcher->Start();
|
||||
SetStarted();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::closeEvent(QCloseEvent*)
|
||||
{
|
||||
obs_frontend_save();
|
||||
}
|
||||
|
|
|
|||
144
hotkey.cpp
144
hotkey.cpp
|
|
@ -1,72 +1,72 @@
|
|||
#include <obs-module.h>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void startStopHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pressed)
|
||||
{
|
||||
UNUSED_PARAMETER(data);
|
||||
UNUSED_PARAMETER(hotkey);
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
if (switcher->th.joinable())
|
||||
switcher->Stop();
|
||||
else
|
||||
switcher->Start();
|
||||
}
|
||||
|
||||
obs_data_array* hotkeyData = obs_hotkey_save(id);
|
||||
|
||||
if (hotkeyData != NULL)
|
||||
{
|
||||
char* path = obs_module_config_path("");
|
||||
ofstream file;
|
||||
file.open(string(path).append("hotkey.txt"), ofstream::trunc);
|
||||
if (file.is_open())
|
||||
{
|
||||
size_t num = obs_data_array_count(hotkeyData);
|
||||
for (size_t i = 0; i < num; i++)
|
||||
{
|
||||
obs_data_t* data = obs_data_array_item(hotkeyData, i);
|
||||
string temp = obs_data_get_json(data);
|
||||
obs_data_release(data);
|
||||
file << temp;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
bfree(path);
|
||||
}
|
||||
obs_data_array_release(hotkeyData);
|
||||
}
|
||||
|
||||
string loadConfigFile(string filename)
|
||||
{
|
||||
ifstream settingsFile;
|
||||
char* path = obs_module_config_path("");
|
||||
string value;
|
||||
|
||||
settingsFile.open(string(path).append(filename));
|
||||
if (settingsFile.is_open())
|
||||
{
|
||||
settingsFile.seekg(0, ios::end);
|
||||
value.reserve(settingsFile.tellg());
|
||||
settingsFile.seekg(0, ios::beg);
|
||||
value.assign((istreambuf_iterator<char>(settingsFile)), istreambuf_iterator<char>());
|
||||
settingsFile.close();
|
||||
}
|
||||
bfree(path);
|
||||
return value;
|
||||
}
|
||||
|
||||
void loadKeybinding(obs_hotkey_id hotkeyId)
|
||||
{
|
||||
string bindings = loadConfigFile("hotkey.txt");
|
||||
if (!bindings.empty())
|
||||
{
|
||||
obs_data_array_t* hotkeyData = obs_data_array_create();
|
||||
obs_data_t* data = obs_data_create_from_json(bindings.c_str());
|
||||
obs_data_array_insert(hotkeyData, 0, data);
|
||||
obs_data_release(data);
|
||||
obs_hotkey_load(hotkeyId, hotkeyData);
|
||||
obs_data_array_release(hotkeyData);
|
||||
}
|
||||
}
|
||||
#include <obs-module.h>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void startStopHotkeyFunc(void* data, obs_hotkey_id id, obs_hotkey_t* hotkey, bool pressed)
|
||||
{
|
||||
UNUSED_PARAMETER(data);
|
||||
UNUSED_PARAMETER(hotkey);
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
if (switcher->th.joinable())
|
||||
switcher->Stop();
|
||||
else
|
||||
switcher->Start();
|
||||
}
|
||||
|
||||
obs_data_array* hotkeyData = obs_hotkey_save(id);
|
||||
|
||||
if (hotkeyData != NULL)
|
||||
{
|
||||
char* path = obs_module_config_path("");
|
||||
ofstream file;
|
||||
file.open(string(path).append("hotkey.txt"), ofstream::trunc);
|
||||
if (file.is_open())
|
||||
{
|
||||
size_t num = obs_data_array_count(hotkeyData);
|
||||
for (size_t i = 0; i < num; i++)
|
||||
{
|
||||
obs_data_t* data = obs_data_array_item(hotkeyData, i);
|
||||
string temp = obs_data_get_json(data);
|
||||
obs_data_release(data);
|
||||
file << temp;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
bfree(path);
|
||||
}
|
||||
obs_data_array_release(hotkeyData);
|
||||
}
|
||||
|
||||
string loadConfigFile(string filename)
|
||||
{
|
||||
ifstream settingsFile;
|
||||
char* path = obs_module_config_path("");
|
||||
string value;
|
||||
|
||||
settingsFile.open(string(path).append(filename));
|
||||
if (settingsFile.is_open())
|
||||
{
|
||||
settingsFile.seekg(0, ios::end);
|
||||
value.reserve(settingsFile.tellg());
|
||||
settingsFile.seekg(0, ios::beg);
|
||||
value.assign((istreambuf_iterator<char>(settingsFile)), istreambuf_iterator<char>());
|
||||
settingsFile.close();
|
||||
}
|
||||
bfree(path);
|
||||
return value;
|
||||
}
|
||||
|
||||
void loadKeybinding(obs_hotkey_id hotkeyId)
|
||||
{
|
||||
string bindings = loadConfigFile("hotkey.txt");
|
||||
if (!bindings.empty())
|
||||
{
|
||||
obs_data_array_t* hotkeyData = obs_data_array_create();
|
||||
obs_data_t* data = obs_data_create_from_json(bindings.c_str());
|
||||
obs_data_array_insert(hotkeyData, 0, data);
|
||||
obs_data_release(data);
|
||||
obs_hotkey_load(hotkeyId, hotkeyData);
|
||||
obs_data_array_release(hotkeyData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
420
idle-switch.cpp
420
idle-switch.cpp
|
|
@ -1,210 +1,210 @@
|
|||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SwitcherData::checkIdleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
if (!idleData.idleEnable)
|
||||
return;
|
||||
|
||||
string title;
|
||||
bool ignoreIdle = false;
|
||||
//lock.unlock();
|
||||
GetCurrentWindowTitle(title);
|
||||
//lock.lock();
|
||||
|
||||
for (string& window : ignoreIdleWindows)
|
||||
{
|
||||
if (window == title)
|
||||
{
|
||||
ignoreIdle = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreIdle)
|
||||
{
|
||||
for (string& window : ignoreIdleWindows)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(window));
|
||||
if (matches)
|
||||
{
|
||||
ignoreIdle = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreIdle && secondsSinceLastInput() > idleData.time)
|
||||
{
|
||||
scene = idleData.scene;
|
||||
transition = idleData.transition;
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (!state)
|
||||
{
|
||||
ui->idleScenes->setDisabled(true);
|
||||
ui->idleSpinBox->setDisabled(true);
|
||||
ui->idleTransitions->setDisabled(true);
|
||||
|
||||
switcher->idleData.idleEnable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->idleScenes->setDisabled(false);
|
||||
ui->idleSpinBox->setDisabled(false);
|
||||
ui->idleTransitions->setDisabled(false);
|
||||
|
||||
switcher->idleData.idleEnable = true;
|
||||
|
||||
UpdateIdleDataTransition(ui->idleTransitions->currentText());
|
||||
UpdateIdleDataScene(ui->idleScenes->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::UpdateIdleDataTransition(const QString& name)
|
||||
{
|
||||
obs_weak_source_t* transition = GetWeakTransitionByQString(name);
|
||||
switcher->idleData.transition = transition;
|
||||
}
|
||||
|
||||
void SceneSwitcher::UpdateIdleDataScene(const QString& name)
|
||||
{
|
||||
obs_source_t* scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->idleData.scene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleTransitions_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateIdleDataTransition(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleScenes_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateIdleDataScene(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleSpinBox_valueChanged(int i)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->idleData.time = i;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreIdleWindows_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->ignoreIdleWindows->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& w : switcher->ignoreIdleWindows)
|
||||
{
|
||||
if (window.compare(w.c_str()) == 0)
|
||||
{
|
||||
ui->ignoreIdleWindowsWindows->setCurrentText(w.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreIdleAdd_clicked()
|
||||
{
|
||||
QString windowName = ui->ignoreIdleWindowsWindows->currentText();
|
||||
|
||||
if (windowName.isEmpty())
|
||||
return;
|
||||
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->ignoreIdleWindows->findItems(windowName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(windowName, ui->ignoreIdleWindows);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->ignoreIdleWindows.emplace_back(windowName.toUtf8().constData());
|
||||
ui->ignoreIdleWindows->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreIdleRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreIdleWindows->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString windowName = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& windows = switcher->ignoreIdleWindows;
|
||||
|
||||
for (auto it = windows.begin(); it != windows.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == windowName.toUtf8().constData())
|
||||
{
|
||||
windows.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
int SceneSwitcher::IgnoreIdleWindowsFindByData(const QString& window)
|
||||
{
|
||||
int count = ui->ignoreIdleWindows->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreIdleWindows->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SwitcherData::checkIdleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
if (!idleData.idleEnable)
|
||||
return;
|
||||
|
||||
string title;
|
||||
bool ignoreIdle = false;
|
||||
//lock.unlock();
|
||||
GetCurrentWindowTitle(title);
|
||||
//lock.lock();
|
||||
|
||||
for (string& window : ignoreIdleWindows)
|
||||
{
|
||||
if (window == title)
|
||||
{
|
||||
ignoreIdle = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreIdle)
|
||||
{
|
||||
for (string& window : ignoreIdleWindows)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(window));
|
||||
if (matches)
|
||||
{
|
||||
ignoreIdle = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreIdle && secondsSinceLastInput() > idleData.time)
|
||||
{
|
||||
scene = idleData.scene;
|
||||
transition = idleData.transition;
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (!state)
|
||||
{
|
||||
ui->idleScenes->setDisabled(true);
|
||||
ui->idleSpinBox->setDisabled(true);
|
||||
ui->idleTransitions->setDisabled(true);
|
||||
|
||||
switcher->idleData.idleEnable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->idleScenes->setDisabled(false);
|
||||
ui->idleSpinBox->setDisabled(false);
|
||||
ui->idleTransitions->setDisabled(false);
|
||||
|
||||
switcher->idleData.idleEnable = true;
|
||||
|
||||
UpdateIdleDataTransition(ui->idleTransitions->currentText());
|
||||
UpdateIdleDataScene(ui->idleScenes->currentText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::UpdateIdleDataTransition(const QString& name)
|
||||
{
|
||||
obs_weak_source_t* transition = GetWeakTransitionByQString(name);
|
||||
switcher->idleData.transition = transition;
|
||||
}
|
||||
|
||||
void SceneSwitcher::UpdateIdleDataScene(const QString& name)
|
||||
{
|
||||
obs_source_t* scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->idleData.scene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleTransitions_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateIdleDataTransition(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleScenes_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateIdleDataScene(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_idleSpinBox_valueChanged(int i)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->idleData.time = i;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreIdleWindows_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->ignoreIdleWindows->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& w : switcher->ignoreIdleWindows)
|
||||
{
|
||||
if (window.compare(w.c_str()) == 0)
|
||||
{
|
||||
ui->ignoreIdleWindowsWindows->setCurrentText(w.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreIdleAdd_clicked()
|
||||
{
|
||||
QString windowName = ui->ignoreIdleWindowsWindows->currentText();
|
||||
|
||||
if (windowName.isEmpty())
|
||||
return;
|
||||
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->ignoreIdleWindows->findItems(windowName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(windowName, ui->ignoreIdleWindows);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->ignoreIdleWindows.emplace_back(windowName.toUtf8().constData());
|
||||
ui->ignoreIdleWindows->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreIdleRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreIdleWindows->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString windowName = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& windows = switcher->ignoreIdleWindows;
|
||||
|
||||
for (auto it = windows.begin(); it != windows.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == windowName.toUtf8().constData())
|
||||
{
|
||||
windows.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
int SceneSwitcher::IgnoreIdleWindowsFindByData(const QString& window)
|
||||
{
|
||||
int count = ui->ignoreIdleWindows->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreIdleWindows->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
|
|
|||
484
pause-switch.cpp
484
pause-switch.cpp
|
|
@ -1,242 +1,242 @@
|
|||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_pauseScenesAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->pauseScenesScenes->currentText();
|
||||
|
||||
if (sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
QVariant v = QVariant::fromValue(sceneName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->pauseScenes->findItems(sceneName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(sceneName, ui->pauseScenes);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->pauseScenesSwitches.emplace_back(source);
|
||||
ui->pauseScenes->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseScenesRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseScenes->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString pauseScene = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->pauseScenesSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == GetWeakSourceByQString(pauseScene))
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseWindowsAdd_clicked()
|
||||
{
|
||||
QString windowName = ui->pauseWindowsWindows->currentText();
|
||||
|
||||
if (windowName.isEmpty())
|
||||
return;
|
||||
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->pauseWindows->findItems(windowName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(windowName, ui->pauseWindows);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->pauseWindowsSwitches.emplace_back(windowName.toUtf8().constData());
|
||||
ui->pauseWindows->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseWindowsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseWindows->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString windowName = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->pauseWindowsSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == windowName.toUtf8().constData())
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseScenes_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->pauseScenes->item(idx);
|
||||
|
||||
QString scene = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->pauseScenesSwitches)
|
||||
{
|
||||
string name = GetWeakSourceName(s);
|
||||
if (scene.compare(name.c_str()) == 0)
|
||||
{
|
||||
ui->pauseScenesScenes->setCurrentText(name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseWindows_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->pauseWindows->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->pauseWindowsSwitches)
|
||||
{
|
||||
if (window.compare(s.c_str()) == 0)
|
||||
{
|
||||
ui->pauseWindowsWindows->setCurrentText(s.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SceneSwitcher::PauseScenesFindByData(const QString& scene)
|
||||
{
|
||||
int count = ui->pauseScenes->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseScenes->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == scene)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int SceneSwitcher::PauseWindowsFindByData(const QString& window)
|
||||
{
|
||||
int count = ui->pauseWindows->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseWindows->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool SwitcherData::checkPause()
|
||||
{
|
||||
bool pause = false;
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
for (OBSWeakSource& s : pauseScenesSwitches)
|
||||
{
|
||||
if (s == ws)
|
||||
{
|
||||
pause = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
|
||||
string title;
|
||||
if (!pause)
|
||||
{
|
||||
//lock.unlock();
|
||||
GetCurrentWindowTitle(title);
|
||||
//lock.lock();
|
||||
for (string& window : pauseWindowsSwitches)
|
||||
{
|
||||
if (window == title)
|
||||
{
|
||||
pause = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
//lock.unlock();
|
||||
GetCurrentWindowTitle(title);
|
||||
//lock.lock();
|
||||
for (string& window : pauseWindowsSwitches)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(window));
|
||||
if (matches)
|
||||
{
|
||||
pause = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
return pause;
|
||||
}
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_pauseScenesAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->pauseScenesScenes->currentText();
|
||||
|
||||
if (sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
QVariant v = QVariant::fromValue(sceneName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->pauseScenes->findItems(sceneName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(sceneName, ui->pauseScenes);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->pauseScenesSwitches.emplace_back(source);
|
||||
ui->pauseScenes->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseScenesRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseScenes->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString pauseScene = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->pauseScenesSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == GetWeakSourceByQString(pauseScene))
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseWindowsAdd_clicked()
|
||||
{
|
||||
QString windowName = ui->pauseWindowsWindows->currentText();
|
||||
|
||||
if (windowName.isEmpty())
|
||||
return;
|
||||
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->pauseWindows->findItems(windowName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(windowName, ui->pauseWindows);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->pauseWindowsSwitches.emplace_back(windowName.toUtf8().constData());
|
||||
ui->pauseWindows->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseWindowsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseWindows->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString windowName = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->pauseWindowsSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == windowName.toUtf8().constData())
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseScenes_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->pauseScenes->item(idx);
|
||||
|
||||
QString scene = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->pauseScenesSwitches)
|
||||
{
|
||||
string name = GetWeakSourceName(s);
|
||||
if (scene.compare(name.c_str()) == 0)
|
||||
{
|
||||
ui->pauseScenesScenes->setCurrentText(name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_pauseWindows_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->pauseWindows->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->pauseWindowsSwitches)
|
||||
{
|
||||
if (window.compare(s.c_str()) == 0)
|
||||
{
|
||||
ui->pauseWindowsWindows->setCurrentText(s.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SceneSwitcher::PauseScenesFindByData(const QString& scene)
|
||||
{
|
||||
int count = ui->pauseScenes->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseScenes->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == scene)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int SceneSwitcher::PauseWindowsFindByData(const QString& window)
|
||||
{
|
||||
int count = ui->pauseWindows->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->pauseWindows->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool SwitcherData::checkPause()
|
||||
{
|
||||
bool pause = false;
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
for (OBSWeakSource& s : pauseScenesSwitches)
|
||||
{
|
||||
if (s == ws)
|
||||
{
|
||||
pause = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
|
||||
string title;
|
||||
if (!pause)
|
||||
{
|
||||
//lock.unlock();
|
||||
GetCurrentWindowTitle(title);
|
||||
//lock.lock();
|
||||
for (string& window : pauseWindowsSwitches)
|
||||
{
|
||||
if (window == title)
|
||||
{
|
||||
pause = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
//lock.unlock();
|
||||
GetCurrentWindowTitle(title);
|
||||
//lock.lock();
|
||||
for (string& window : pauseWindowsSwitches)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(window));
|
||||
if (matches)
|
||||
{
|
||||
pause = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
return pause;
|
||||
}
|
||||
|
|
|
|||
89
priority.cpp
89
priority.cpp
|
|
@ -1,45 +1,44 @@
|
|||
#include <algorithm>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_priorityUp_clicked()
|
||||
{
|
||||
int currentIndex = ui->priorityList->currentRow();
|
||||
if (currentIndex != -1 && currentIndex != 0)
|
||||
{
|
||||
ui->priorityList->insertItem(currentIndex - 1 ,ui->priorityList->takeItem(currentIndex));
|
||||
ui->priorityList->setCurrentRow(currentIndex -1);
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->functionNamesByPriority.begin() + currentIndex, switcher->functionNamesByPriority.begin() + currentIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_priorityDown_clicked()
|
||||
{
|
||||
int currentIndex = ui->priorityList->currentRow();
|
||||
if (currentIndex != -1 && currentIndex != ui->priorityList->count() - 1)
|
||||
{
|
||||
ui->priorityList->insertItem(currentIndex + 1, ui->priorityList->takeItem(currentIndex));
|
||||
ui->priorityList->setCurrentRow(currentIndex + 1);
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->functionNamesByPriority.begin() + currentIndex, switcher->functionNamesByPriority.begin() + currentIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SwitcherData::prioFuncsValid()
|
||||
{
|
||||
auto it = std::unique(functionNamesByPriority.begin(), functionNamesByPriority.end());
|
||||
bool wasUnique = (it == functionNamesByPriority.end());
|
||||
if (!wasUnique)
|
||||
return false;
|
||||
|
||||
for (int p : functionNamesByPriority)
|
||||
{
|
||||
if (p < 0 || p > 5)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_priorityUp_clicked()
|
||||
{
|
||||
int currentIndex = ui->priorityList->currentRow();
|
||||
if (currentIndex != -1 && currentIndex != 0)
|
||||
{
|
||||
ui->priorityList->insertItem(currentIndex - 1 ,ui->priorityList->takeItem(currentIndex));
|
||||
ui->priorityList->setCurrentRow(currentIndex -1);
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->functionNamesByPriority.begin() + currentIndex, switcher->functionNamesByPriority.begin() + currentIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_priorityDown_clicked()
|
||||
{
|
||||
int currentIndex = ui->priorityList->currentRow();
|
||||
if (currentIndex != -1 && currentIndex != ui->priorityList->count() - 1)
|
||||
{
|
||||
ui->priorityList->insertItem(currentIndex + 1, ui->priorityList->takeItem(currentIndex));
|
||||
ui->priorityList->setCurrentRow(currentIndex + 1);
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->functionNamesByPriority.begin() + currentIndex, switcher->functionNamesByPriority.begin() + currentIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool SwitcherData::prioFuncsValid()
|
||||
{
|
||||
auto it = std::unique(functionNamesByPriority.begin(), functionNamesByPriority.end());
|
||||
bool wasUnique = (it == functionNamesByPriority.end());
|
||||
if (!wasUnique)
|
||||
return false;
|
||||
|
||||
for (int p : functionNamesByPriority)
|
||||
{
|
||||
if (p < 0 || p > 5)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
284
random.cpp
284
random.cpp
|
|
@ -1,143 +1,141 @@
|
|||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_randomScenesList_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->randomScenesList->item(idx);
|
||||
|
||||
QString randomSceneStr = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->randomSwitches)
|
||||
{
|
||||
if (randomSceneStr.compare(s.randomSwitchStr.c_str()) == 0)
|
||||
{
|
||||
QString sceneName = GetWeakSourceName(s.scene).c_str();
|
||||
QString transitionName = GetWeakSourceName(s.transition).c_str();
|
||||
ui->randomScenes->setCurrentText(sceneName);
|
||||
ui->randomSpinBox->setValue(s.delay);
|
||||
ui->randomTransitions->setCurrentText(transitionName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SceneSwitcher::randomFindByData(const QString& randomStr)
|
||||
{
|
||||
int count = ui->randomScenesList->count();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->randomScenesList->item(i);
|
||||
QString str = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (str == randomStr)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_randomAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->randomScenes->currentText();
|
||||
QString transitionName = ui->randomTransitions->currentText();
|
||||
double delay = ui->randomSpinBox->value();
|
||||
|
||||
|
||||
if (sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
|
||||
QString text = MakeRandomSwitchName(sceneName, transitionName, delay);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = randomFindByData(text);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->randomSwitches.emplace_back(
|
||||
source, transition, delay, text.toUtf8().constData());
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->randomScenesList);
|
||||
item->setData(Qt::UserRole, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->randomScenesList->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->randomSwitches)
|
||||
{
|
||||
if (s.scene == source)
|
||||
{
|
||||
s.delay = delay;
|
||||
s.transition = transition;
|
||||
s.randomSwitchStr = text.toUtf8().constData();;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->randomScenesList->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_randomRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->randomScenesList->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->randomSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.randomSwitchStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
void SwitcherData::checkRandom(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, int& delay)
|
||||
{
|
||||
if (randomSwitches.size() == 0)
|
||||
return;
|
||||
|
||||
vector<RandomSwitch> rs (randomSwitches);
|
||||
std::random_shuffle(rs.begin(), rs.end());
|
||||
for (RandomSwitch& r : rs)
|
||||
{
|
||||
if (r.scene == lastRandomScene)
|
||||
continue;
|
||||
scene = r.scene;
|
||||
transition = r.transition;
|
||||
delay = (int)r.delay * 1000;
|
||||
match = true;
|
||||
lastRandomScene = r.scene;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_randomScenesList_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->randomScenesList->item(idx);
|
||||
|
||||
QString randomSceneStr = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->randomSwitches)
|
||||
{
|
||||
if (randomSceneStr.compare(s.randomSwitchStr.c_str()) == 0)
|
||||
{
|
||||
QString sceneName = GetWeakSourceName(s.scene).c_str();
|
||||
QString transitionName = GetWeakSourceName(s.transition).c_str();
|
||||
ui->randomScenes->setCurrentText(sceneName);
|
||||
ui->randomSpinBox->setValue(s.delay);
|
||||
ui->randomTransitions->setCurrentText(transitionName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SceneSwitcher::randomFindByData(const QString& randomStr)
|
||||
{
|
||||
int count = ui->randomScenesList->count();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->randomScenesList->item(i);
|
||||
QString str = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (str == randomStr)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_randomAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->randomScenes->currentText();
|
||||
QString transitionName = ui->randomTransitions->currentText();
|
||||
double delay = ui->randomSpinBox->value();
|
||||
|
||||
|
||||
if (sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
|
||||
QString text = MakeRandomSwitchName(sceneName, transitionName, delay);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = randomFindByData(text);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->randomSwitches.emplace_back(
|
||||
source, transition, delay, text.toUtf8().constData());
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->randomScenesList);
|
||||
item->setData(Qt::UserRole, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->randomScenesList->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->randomSwitches)
|
||||
{
|
||||
if (s.scene == source)
|
||||
{
|
||||
s.delay = delay;
|
||||
s.transition = transition;
|
||||
s.randomSwitchStr = text.toUtf8().constData();;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->randomScenesList->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_randomRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->randomScenesList->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->randomSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.randomSwitchStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SwitcherData::checkRandom(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, int& delay)
|
||||
{
|
||||
if (randomSwitches.size() == 0)
|
||||
return;
|
||||
|
||||
vector<RandomSwitch> rs (randomSwitches);
|
||||
std::random_shuffle(rs.begin(), rs.end());
|
||||
for (RandomSwitch& r : rs)
|
||||
{
|
||||
if (r.scene == lastRandomScene)
|
||||
continue;
|
||||
scene = r.scene;
|
||||
transition = r.transition;
|
||||
delay = (int)r.delay * 1000;
|
||||
match = true;
|
||||
lastRandomScene = r.scene;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,309 +1,305 @@
|
|||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <obs.hpp>
|
||||
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
obs_weak_source_t* getNextTransition(obs_weak_source_t* scene1, obs_weak_source_t* scene2);
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripAdd_clicked()
|
||||
{
|
||||
QString scene1Name = ui->sceneRoundTripScenes1->currentText();
|
||||
QString scene2Name = ui->sceneRoundTripScenes2->currentText();
|
||||
QString transitionName = ui->sceneRoundTripTransitions->currentText();
|
||||
|
||||
if (scene1Name.isEmpty() || scene2Name.isEmpty())
|
||||
return;
|
||||
|
||||
double delay = ui->sceneRoundTripSpinBox->value();
|
||||
|
||||
if (scene1Name == scene2Name)
|
||||
return;
|
||||
|
||||
OBSWeakSource source1 = GetWeakSourceByQString(scene1Name);
|
||||
OBSWeakSource source2 = GetWeakSourceByQString(scene2Name);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString text = MakeSceneRoundTripSwitchName(scene1Name, scene2Name, transitionName, delay);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = SceneRoundTripFindByData(scene1Name);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->sceneRoundTrips);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->sceneRoundTripSwitches.emplace_back(
|
||||
source1, source2, transition, int(delay * 1000), text.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
if (s.scene1 == source1)
|
||||
{
|
||||
s.scene2 = source2;
|
||||
s.delay = int(delay * 1000);
|
||||
s.transition = transition;
|
||||
s.sceneRoundTripStr = text.toUtf8().constData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->sceneRoundTrips->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->sceneRoundTripSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.sceneRoundTripStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_autoStopSceneCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (!state)
|
||||
{
|
||||
ui->autoStopScenes->setDisabled(true);
|
||||
switcher->autoStopEnable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->autoStopScenes->setDisabled(false);
|
||||
switcher->autoStopEnable = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::UpdateAutoStopScene(const QString& name)
|
||||
{
|
||||
obs_source_t* scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->autoStopScene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_autoStopScenes_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateAutoStopScene(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripSave_clicked()
|
||||
{
|
||||
QString directory = QFileDialog::getSaveFileName(
|
||||
this, tr("Save Scene Round Trip to file ..."), QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
QFile file(directory);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
return;
|
||||
QTextStream out(&file);
|
||||
for (SceneRoundTripSwitch s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
out << QString::fromStdString(GetWeakSourceName(s.scene1)) << "\n";
|
||||
out << QString::fromStdString(GetWeakSourceName(s.scene2)) << "\n";
|
||||
out << s.delay << "\n";
|
||||
out << QString::fromStdString(s.sceneRoundTripStr) << "\n";
|
||||
out << QString::fromStdString(GetWeakSourceName(s.transition)) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripLoad_clicked()
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
QString directory = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to read Scene Round Trip from ..."), QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
QFile file(directory);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
|
||||
QTextStream in(&file);
|
||||
vector<QString> lines;
|
||||
|
||||
vector<SceneRoundTripSwitch> newSceneRoundTripSwitch;
|
||||
|
||||
while (!in.atEnd())
|
||||
{
|
||||
QString line = in.readLine();
|
||||
lines.push_back(line);
|
||||
if (lines.size() == 5)
|
||||
{
|
||||
OBSWeakSource scene1 = GetWeakSourceByQString(lines[0]);
|
||||
OBSWeakSource scene2 = GetWeakSourceByQString(lines[1]);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(lines[4]);
|
||||
|
||||
if (WeakSourceValid(scene1) && WeakSourceValid(scene2)
|
||||
&& WeakSourceValid(transition))
|
||||
{
|
||||
newSceneRoundTripSwitch.emplace_back(SceneRoundTripSwitch(
|
||||
GetWeakSourceByQString(lines[0]),
|
||||
GetWeakSourceByQString(lines[1]),
|
||||
GetWeakTransitionByQString(lines[4]),
|
||||
lines[2].toInt(),
|
||||
lines[3].toStdString()));
|
||||
}
|
||||
lines.clear();
|
||||
}
|
||||
}
|
||||
//unvalid amount of lines in file or nothing valid read
|
||||
if (lines.size() != 0 || newSceneRoundTripSwitch.size() == 0)
|
||||
return;
|
||||
|
||||
switcher->sceneRoundTripSwitches.clear();
|
||||
ui->sceneRoundTrips->clear();
|
||||
switcher->sceneRoundTripSwitches = newSceneRoundTripSwitch;
|
||||
for (SceneRoundTripSwitch s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(s.sceneRoundTripStr), ui->sceneRoundTrips);
|
||||
item->setData(Qt::UserRole, QString::fromStdString(s.sceneRoundTripStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SwitcherData::checkSceneRoundTrip(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock)
|
||||
{
|
||||
bool sceneRoundTripActive = false;
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
for (SceneRoundTripSwitch& s : sceneRoundTripSwitches)
|
||||
{
|
||||
if (s.scene1 == ws)
|
||||
{
|
||||
sceneRoundTripActive = true;
|
||||
int dur = s.delay - interval;
|
||||
if (dur > 0)
|
||||
{
|
||||
string s = obs_source_get_name(currentSource);
|
||||
waitSceneName = s;
|
||||
cv.wait_for(lock, chrono::milliseconds(dur));
|
||||
}
|
||||
obs_source_t* currentSource2 = obs_frontend_get_current_scene();
|
||||
|
||||
// only switch if user hasn't changed scene manually
|
||||
if (currentSource == currentSource2)
|
||||
{
|
||||
match = true;
|
||||
scene = s.scene2;
|
||||
transition = s.transition;
|
||||
}
|
||||
obs_source_release(currentSource2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTrips_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->item(idx);
|
||||
|
||||
QString sceneRoundTrip = item->text();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
if (sceneRoundTrip.compare(s.sceneRoundTripStr.c_str()) == 0)
|
||||
{
|
||||
string scene1 = GetWeakSourceName(s.scene1);
|
||||
string scene2 = GetWeakSourceName(s.scene2);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
int delay = s.delay;
|
||||
ui->sceneRoundTripScenes1->setCurrentText(scene1.c_str());
|
||||
ui->sceneRoundTripScenes2->setCurrentText(scene2.c_str());
|
||||
ui->sceneRoundTripTransitions->setCurrentText(transitionName.c_str());
|
||||
ui->sceneRoundTripSpinBox->setValue((double)delay/1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SceneSwitcher::SceneRoundTripFindByData(const QString& scene1)
|
||||
{
|
||||
QRegExp rx(scene1 + " ->.*");
|
||||
int count = ui->sceneRoundTrips->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->item(i);
|
||||
QString itemString = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (rx.exactMatch(itemString))
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
void SwitcherData::autoStopStreamAndRecording()
|
||||
{
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
if (ws && autoStopScene == ws)
|
||||
{
|
||||
if (obs_frontend_streaming_active())
|
||||
obs_frontend_streaming_stop();
|
||||
if (obs_frontend_recording_active())
|
||||
obs_frontend_recording_stop();
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <obs.hpp>
|
||||
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripAdd_clicked()
|
||||
{
|
||||
QString scene1Name = ui->sceneRoundTripScenes1->currentText();
|
||||
QString scene2Name = ui->sceneRoundTripScenes2->currentText();
|
||||
QString transitionName = ui->sceneRoundTripTransitions->currentText();
|
||||
|
||||
if (scene1Name.isEmpty() || scene2Name.isEmpty())
|
||||
return;
|
||||
|
||||
double delay = ui->sceneRoundTripSpinBox->value();
|
||||
|
||||
if (scene1Name == scene2Name)
|
||||
return;
|
||||
|
||||
OBSWeakSource source1 = GetWeakSourceByQString(scene1Name);
|
||||
OBSWeakSource source2 = GetWeakSourceByQString(scene2Name);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString text = MakeSceneRoundTripSwitchName(scene1Name, scene2Name, transitionName, delay);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = SceneRoundTripFindByData(scene1Name);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->sceneRoundTrips);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->sceneRoundTripSwitches.emplace_back(
|
||||
source1, source2, transition, int(delay * 1000), text.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
if (s.scene1 == source1)
|
||||
{
|
||||
s.scene2 = source2;
|
||||
s.delay = int(delay * 1000);
|
||||
s.transition = transition;
|
||||
s.sceneRoundTripStr = text.toUtf8().constData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->sceneRoundTrips->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->sceneRoundTripSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.sceneRoundTripStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_autoStopSceneCheckBox_stateChanged(int state)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
if (!state)
|
||||
{
|
||||
ui->autoStopScenes->setDisabled(true);
|
||||
switcher->autoStopEnable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->autoStopScenes->setDisabled(false);
|
||||
switcher->autoStopEnable = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::UpdateAutoStopScene(const QString& name)
|
||||
{
|
||||
obs_source_t* scene = obs_get_source_by_name(name.toUtf8().constData());
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(scene);
|
||||
|
||||
switcher->autoStopScene = ws;
|
||||
|
||||
obs_weak_source_release(ws);
|
||||
obs_source_release(scene);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_autoStopScenes_currentTextChanged(const QString& text)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
UpdateAutoStopScene(text);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripSave_clicked()
|
||||
{
|
||||
QString directory = QFileDialog::getSaveFileName(
|
||||
this, tr("Save Scene Round Trip to file ..."), QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
QFile file(directory);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
return;
|
||||
QTextStream out(&file);
|
||||
for (SceneRoundTripSwitch s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
out << QString::fromStdString(GetWeakSourceName(s.scene1)) << "\n";
|
||||
out << QString::fromStdString(GetWeakSourceName(s.scene2)) << "\n";
|
||||
out << s.delay << "\n";
|
||||
out << QString::fromStdString(s.sceneRoundTripStr) << "\n";
|
||||
out << QString::fromStdString(GetWeakSourceName(s.transition)) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripLoad_clicked()
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
|
||||
QString directory = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to read Scene Round Trip from ..."), QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (!directory.isEmpty())
|
||||
{
|
||||
QFile file(directory);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
|
||||
QTextStream in(&file);
|
||||
vector<QString> lines;
|
||||
|
||||
vector<SceneRoundTripSwitch> newSceneRoundTripSwitch;
|
||||
|
||||
while (!in.atEnd())
|
||||
{
|
||||
QString line = in.readLine();
|
||||
lines.push_back(line);
|
||||
if (lines.size() == 5)
|
||||
{
|
||||
OBSWeakSource scene1 = GetWeakSourceByQString(lines[0]);
|
||||
OBSWeakSource scene2 = GetWeakSourceByQString(lines[1]);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(lines[4]);
|
||||
|
||||
if (WeakSourceValid(scene1) && WeakSourceValid(scene2)
|
||||
&& WeakSourceValid(transition))
|
||||
{
|
||||
newSceneRoundTripSwitch.emplace_back(SceneRoundTripSwitch(
|
||||
GetWeakSourceByQString(lines[0]),
|
||||
GetWeakSourceByQString(lines[1]),
|
||||
GetWeakTransitionByQString(lines[4]),
|
||||
lines[2].toInt(),
|
||||
lines[3].toStdString()));
|
||||
}
|
||||
lines.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (lines.size() != 0 || newSceneRoundTripSwitch.size() == 0)
|
||||
return;
|
||||
|
||||
switcher->sceneRoundTripSwitches.clear();
|
||||
ui->sceneRoundTrips->clear();
|
||||
switcher->sceneRoundTripSwitches = newSceneRoundTripSwitch;
|
||||
for (SceneRoundTripSwitch s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(s.sceneRoundTripStr), ui->sceneRoundTrips);
|
||||
item->setData(Qt::UserRole, QString::fromStdString(s.sceneRoundTripStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SwitcherData::checkSceneRoundTrip(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock)
|
||||
{
|
||||
bool sceneRoundTripActive = false;
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
for (SceneRoundTripSwitch& s : sceneRoundTripSwitches)
|
||||
{
|
||||
if (s.scene1 == ws)
|
||||
{
|
||||
sceneRoundTripActive = true;
|
||||
int dur = s.delay - interval;
|
||||
if (dur > 0)
|
||||
{
|
||||
waitScene = currentSource;
|
||||
cv.wait_for(lock, chrono::milliseconds(dur));
|
||||
}
|
||||
obs_source_t* currentSource2 = obs_frontend_get_current_scene();
|
||||
|
||||
// only switch if user hasn't changed scene manually
|
||||
if (currentSource == currentSource2)
|
||||
{
|
||||
match = true;
|
||||
scene = s.scene2;
|
||||
transition = s.transition;
|
||||
}
|
||||
obs_source_release(currentSource2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTrips_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->item(idx);
|
||||
|
||||
QString sceneRoundTrip = item->text();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneRoundTripSwitches)
|
||||
{
|
||||
if (sceneRoundTrip.compare(s.sceneRoundTripStr.c_str()) == 0)
|
||||
{
|
||||
string scene1 = GetWeakSourceName(s.scene1);
|
||||
string scene2 = GetWeakSourceName(s.scene2);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
int delay = s.delay;
|
||||
ui->sceneRoundTripScenes1->setCurrentText(scene1.c_str());
|
||||
ui->sceneRoundTripScenes2->setCurrentText(scene2.c_str());
|
||||
ui->sceneRoundTripTransitions->setCurrentText(transitionName.c_str());
|
||||
ui->sceneRoundTripSpinBox->setValue((double)delay/1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SceneSwitcher::SceneRoundTripFindByData(const QString& scene1)
|
||||
{
|
||||
QRegExp rx(scene1 + " ->.*");
|
||||
int count = ui->sceneRoundTrips->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneRoundTrips->item(i);
|
||||
QString itemString = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (rx.exactMatch(itemString))
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
void SwitcherData::autoStopStreamAndRecording()
|
||||
{
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
if (ws && autoStopScene == ws)
|
||||
{
|
||||
if (obs_frontend_streaming_active())
|
||||
obs_frontend_streaming_stop();
|
||||
if (obs_frontend_recording_active())
|
||||
obs_frontend_recording_stop();
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,283 +1,284 @@
|
|||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_transitionsAdd_clicked()
|
||||
{
|
||||
QString scene1Name = ui->transitionsScene1->currentText();
|
||||
QString scene2Name = ui->transitionsScene2->currentText();
|
||||
QString transitionName = ui->transitionsTransitions->currentText();
|
||||
|
||||
if (scene1Name.isEmpty() || scene2Name.isEmpty())
|
||||
return;
|
||||
|
||||
if (scene1Name == scene2Name)
|
||||
return;
|
||||
|
||||
OBSWeakSource source1 = GetWeakSourceByQString(scene1Name);
|
||||
OBSWeakSource source2 = GetWeakSourceByQString(scene2Name);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString text = MakeSceneTransitionName(scene1Name, scene2Name, transitionName);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = SceneTransitionsFindByData(scene1Name, scene2Name);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->sceneTransitions);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->sceneTransitions.emplace_back(
|
||||
source1, source2, transition, text.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneTransitions->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneTransitions)
|
||||
{
|
||||
if (s.scene1 == source1 && s.scene2 == source2)
|
||||
{
|
||||
s.transition = transition;
|
||||
s.sceneTransitionStr = text.toUtf8().constData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->sceneTransitions->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_transitionsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneTransitions->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->sceneTransitions;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.sceneTransitionStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_defaultTransitionsAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->defaultTransitionsScene->currentText();
|
||||
QString transitionName = ui->defaultTransitionsTransitions->currentText();
|
||||
|
||||
if (sceneName.isEmpty() || transitionName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString text = MakeDefaultSceneTransitionName(sceneName, transitionName);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = DefaultTransitionsFindByData(sceneName);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->defaultTransitions);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->defaultSceneTransitions.emplace_back(
|
||||
source, transition, text.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->defaultTransitions->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->defaultSceneTransitions)
|
||||
{
|
||||
if (s.scene == source)
|
||||
{
|
||||
s.transition = transition;
|
||||
s.sceneTransitionStr = text.toUtf8().constData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->defaultTransitions->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_defaultTransitionsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->defaultTransitions->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->defaultSceneTransitions;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.sceneTransitionStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SwitcherData::setDefaultSceneTransitions(unique_lock<mutex>& lock)
|
||||
{
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
for (DefaultSceneTransition& s : defaultSceneTransitions)
|
||||
{
|
||||
if (s.scene == ws)
|
||||
{
|
||||
obs_source_t* transition = obs_weak_source_get_source(s.transition);
|
||||
//sleep planned but no fitting OBS event to measure transition time
|
||||
obs_frontend_set_current_transition(transition);
|
||||
obs_source_release(transition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
||||
int SceneSwitcher::SceneTransitionsFindByData(const QString& scene1, const QString& scene2)
|
||||
{
|
||||
QRegExp rx(scene1 + " --- .* --> " + scene2);
|
||||
int count = ui->sceneTransitions->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneTransitions->item(i);
|
||||
QString itemString = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (rx.exactMatch(itemString))
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int SceneSwitcher::DefaultTransitionsFindByData(const QString& scene)
|
||||
{
|
||||
QRegExp rx(scene + " --> .*");
|
||||
int count = ui->defaultTransitions->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->defaultTransitions->item(i);
|
||||
QString itemString = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (rx.exactMatch(itemString))
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneTransitions_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->sceneTransitions->item(idx);
|
||||
|
||||
QString sceneTransition = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneTransitions)
|
||||
{
|
||||
if (sceneTransition.compare(s.sceneTransitionStr.c_str()) == 0)
|
||||
{
|
||||
string scene1 = GetWeakSourceName(s.scene1);
|
||||
string scene2 = GetWeakSourceName(s.scene2);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->transitionsScene1->setCurrentText(scene1.c_str());
|
||||
ui->transitionsScene2->setCurrentText(scene2.c_str());
|
||||
ui->transitionsTransitions->setCurrentText(transitionName.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_defaultTransitions_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->defaultTransitions->item(idx);
|
||||
|
||||
QString sceneTransition = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->defaultSceneTransitions)
|
||||
{
|
||||
if (sceneTransition.compare(s.sceneTransitionStr.c_str()) == 0)
|
||||
{
|
||||
string scene = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->defaultTransitionsScene->setCurrentText(scene.c_str());
|
||||
ui->defaultTransitionsTransitions->setCurrentText(transitionName.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obs_weak_source_t* getNextTransition(obs_weak_source_t* scene1, obs_weak_source_t* scene2)
|
||||
{
|
||||
obs_weak_source_t* ws = nullptr;
|
||||
if (scene1 && scene2)
|
||||
{
|
||||
for (SceneTransition& t : switcher->sceneTransitions)
|
||||
{
|
||||
if (t.scene1 == scene1 && t.scene2 == scene2)
|
||||
ws = t.transition;
|
||||
}
|
||||
obs_weak_source_addref(ws);
|
||||
}
|
||||
return ws;
|
||||
}
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_transitionsAdd_clicked()
|
||||
{
|
||||
QString scene1Name = ui->transitionsScene1->currentText();
|
||||
QString scene2Name = ui->transitionsScene2->currentText();
|
||||
QString transitionName = ui->transitionsTransitions->currentText();
|
||||
|
||||
if (scene1Name.isEmpty() || scene2Name.isEmpty())
|
||||
return;
|
||||
|
||||
if (scene1Name == scene2Name)
|
||||
return;
|
||||
|
||||
OBSWeakSource source1 = GetWeakSourceByQString(scene1Name);
|
||||
OBSWeakSource source2 = GetWeakSourceByQString(scene2Name);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString text = MakeSceneTransitionName(scene1Name, scene2Name, transitionName);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = SceneTransitionsFindByData(scene1Name, scene2Name);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->sceneTransitions);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->sceneTransitions.emplace_back(
|
||||
source1, source2, transition, text.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneTransitions->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneTransitions)
|
||||
{
|
||||
if (s.scene1 == source1 && s.scene2 == source2)
|
||||
{
|
||||
s.transition = transition;
|
||||
s.sceneTransitionStr = text.toUtf8().constData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->sceneTransitions->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_transitionsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneTransitions->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->sceneTransitions;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.sceneTransitionStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_defaultTransitionsAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->defaultTransitionsScene->currentText();
|
||||
QString transitionName = ui->defaultTransitionsTransitions->currentText();
|
||||
|
||||
if (sceneName.isEmpty() || transitionName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString text = MakeDefaultSceneTransitionName(sceneName, transitionName);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = DefaultTransitionsFindByData(sceneName);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->defaultTransitions);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->defaultSceneTransitions.emplace_back(
|
||||
source, transition, text.toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->defaultTransitions->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->defaultSceneTransitions)
|
||||
{
|
||||
if (s.scene == source)
|
||||
{
|
||||
s.transition = transition;
|
||||
s.sceneTransitionStr = text.toUtf8().constData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->defaultTransitions->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_defaultTransitionsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->defaultTransitions->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string text = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->defaultSceneTransitions;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.sceneTransitionStr == text)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SwitcherData::setDefaultSceneTransitions(unique_lock<mutex>& lock)
|
||||
{
|
||||
obs_source_t* currentSource = obs_frontend_get_current_scene();
|
||||
obs_weak_source_t* ws = obs_source_get_weak_source(currentSource);
|
||||
|
||||
for (DefaultSceneTransition& s : defaultSceneTransitions)
|
||||
{
|
||||
if (s.scene == ws)
|
||||
{
|
||||
obs_source_t* transition = obs_weak_source_get_source(s.transition);
|
||||
//This might cancel the current transition
|
||||
//There is no way to be sure when the previous transition finished
|
||||
obs_frontend_set_current_transition(transition);
|
||||
obs_source_release(transition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
obs_source_release(currentSource);
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
||||
int SceneSwitcher::SceneTransitionsFindByData(const QString& scene1, const QString& scene2)
|
||||
{
|
||||
QRegExp rx(scene1 + " --- .* --> " + scene2);
|
||||
int count = ui->sceneTransitions->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->sceneTransitions->item(i);
|
||||
QString itemString = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (rx.exactMatch(itemString))
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
int SceneSwitcher::DefaultTransitionsFindByData(const QString& scene)
|
||||
{
|
||||
QRegExp rx(scene + " --> .*");
|
||||
int count = ui->defaultTransitions->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->defaultTransitions->item(i);
|
||||
QString itemString = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (rx.exactMatch(itemString))
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneTransitions_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->sceneTransitions->item(idx);
|
||||
|
||||
QString sceneTransition = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->sceneTransitions)
|
||||
{
|
||||
if (sceneTransition.compare(s.sceneTransitionStr.c_str()) == 0)
|
||||
{
|
||||
string scene1 = GetWeakSourceName(s.scene1);
|
||||
string scene2 = GetWeakSourceName(s.scene2);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->transitionsScene1->setCurrentText(scene1.c_str());
|
||||
ui->transitionsScene2->setCurrentText(scene2.c_str());
|
||||
ui->transitionsTransitions->setCurrentText(transitionName.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_defaultTransitions_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->defaultTransitions->item(idx);
|
||||
|
||||
QString sceneTransition = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->defaultSceneTransitions)
|
||||
{
|
||||
if (sceneTransition.compare(s.sceneTransitionStr.c_str()) == 0)
|
||||
{
|
||||
string scene = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->defaultTransitionsScene->setCurrentText(scene.c_str());
|
||||
ui->defaultTransitionsTransitions->setCurrentText(transitionName.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obs_weak_source_t* getNextTransition(obs_weak_source_t* scene1, obs_weak_source_t* scene2)
|
||||
{
|
||||
obs_weak_source_t* ws = nullptr;
|
||||
if (scene1 && scene2)
|
||||
{
|
||||
for (SceneTransition& t : switcher->sceneTransitions)
|
||||
{
|
||||
if (t.scene1 == scene1 && t.scene2 == scene2)
|
||||
ws = t.transition;
|
||||
}
|
||||
obs_weak_source_addref(ws);
|
||||
}
|
||||
return ws;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,165 +1,165 @@
|
|||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SwitcherData::checkScreenRegionSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
pair<int, int> cursorPos = getCursorPos();
|
||||
int minRegionSize = 99999;
|
||||
|
||||
for (auto& s : screenRegionSwitches)
|
||||
{
|
||||
if (cursorPos.first >= s.minX && cursorPos.second >= s.minY
|
||||
&& cursorPos.first <= s.maxX && cursorPos.second <= s.maxY)
|
||||
{
|
||||
int regionSize = (s.maxX - s.minX) + (s.maxY - s.minY);
|
||||
if (regionSize < minRegionSize)
|
||||
{
|
||||
match = true;
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
minRegionSize = regionSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::updateScreenRegionCursorPos()
|
||||
{
|
||||
pair<int, int> position = getCursorPos();
|
||||
ui->cursorXPosition->setText(QString::number(position.first));
|
||||
;
|
||||
ui->cursorYPosition->setText(QString::number(position.second));
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_screenRegionAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->screenRegionScenes->currentText();
|
||||
QString transitionName = ui->screenRegionsTransitions->currentText();
|
||||
|
||||
if (sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
int minX = ui->screenRegionMinX->value();
|
||||
int minY = ui->screenRegionMinY->value();
|
||||
int maxX = ui->screenRegionMaxX->value();
|
||||
int maxY = ui->screenRegionMaxY->value();
|
||||
|
||||
string regionStr = to_string(minX) + ", " + to_string(minY) + " x " + to_string(maxX) + ", "
|
||||
+ to_string(maxY);
|
||||
QString region = QString::fromStdString(regionStr);
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
QVariant v = QVariant::fromValue(region);
|
||||
|
||||
QString text = MakeScreenRegionSwitchName(sceneName, transitionName, minX, minY, maxX, maxY);
|
||||
|
||||
int idx = ScreenRegionFindByData(region);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->screenRegions);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->screenRegionSwitches.emplace_back(
|
||||
source, transition, minX, minY, maxX, maxY, regionStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->screenRegions->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
string curRegion = region.toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->screenRegionSwitches)
|
||||
{
|
||||
if (s.regionStr == curRegion)
|
||||
{
|
||||
s.scene = source;
|
||||
s.transition = transition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->screenRegions->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_screenRegionRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->screenRegions->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string region = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->screenRegionSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.regionStr == region)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_screenRegions_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->screenRegions->item(idx);
|
||||
|
||||
QString region = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->screenRegionSwitches)
|
||||
{
|
||||
if (region.compare(s.regionStr.c_str()) == 0)
|
||||
{
|
||||
string name = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->screenRegionScenes->setCurrentText(name.c_str());
|
||||
ui->screenRegionsTransitions->setCurrentText(transitionName.c_str());
|
||||
ui->screenRegionMinX->setValue(s.minX);
|
||||
ui->screenRegionMinY->setValue(s.minY);
|
||||
ui->screenRegionMaxX->setValue(s.maxX);
|
||||
ui->screenRegionMaxY->setValue(s.maxY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SceneSwitcher::ScreenRegionFindByData(const QString& region)
|
||||
{
|
||||
int count = ui->screenRegions->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->screenRegions->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == region)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SwitcherData::checkScreenRegionSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
pair<int, int> cursorPos = getCursorPos();
|
||||
int minRegionSize = 99999;
|
||||
|
||||
for (auto& s : screenRegionSwitches)
|
||||
{
|
||||
if (cursorPos.first >= s.minX && cursorPos.second >= s.minY
|
||||
&& cursorPos.first <= s.maxX && cursorPos.second <= s.maxY)
|
||||
{
|
||||
int regionSize = (s.maxX - s.minX) + (s.maxY - s.minY);
|
||||
if (regionSize < minRegionSize)
|
||||
{
|
||||
match = true;
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
minRegionSize = regionSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::updateScreenRegionCursorPos()
|
||||
{
|
||||
pair<int, int> position = getCursorPos();
|
||||
ui->cursorXPosition->setText(QString::number(position.first));
|
||||
;
|
||||
ui->cursorYPosition->setText(QString::number(position.second));
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_screenRegionAdd_clicked()
|
||||
{
|
||||
QString sceneName = ui->screenRegionScenes->currentText();
|
||||
QString transitionName = ui->screenRegionsTransitions->currentText();
|
||||
|
||||
if (sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
int minX = ui->screenRegionMinX->value();
|
||||
int minY = ui->screenRegionMinY->value();
|
||||
int maxX = ui->screenRegionMaxX->value();
|
||||
int maxY = ui->screenRegionMaxY->value();
|
||||
|
||||
string regionStr = to_string(minX) + ", " + to_string(minY) + " x " + to_string(maxX) + ", "
|
||||
+ to_string(maxY);
|
||||
QString region = QString::fromStdString(regionStr);
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
QVariant v = QVariant::fromValue(region);
|
||||
|
||||
QString text = MakeScreenRegionSwitchName(sceneName, transitionName, minX, minY, maxX, maxY);
|
||||
|
||||
int idx = ScreenRegionFindByData(region);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->screenRegions);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->screenRegionSwitches.emplace_back(
|
||||
source, transition, minX, minY, maxX, maxY, regionStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->screenRegions->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
string curRegion = region.toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->screenRegionSwitches)
|
||||
{
|
||||
if (s.regionStr == curRegion)
|
||||
{
|
||||
s.scene = source;
|
||||
s.transition = transition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->screenRegions->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_screenRegionRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->screenRegions->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string region = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->screenRegionSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.regionStr == region)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_screenRegions_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->screenRegions->item(idx);
|
||||
|
||||
QString region = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->screenRegionSwitches)
|
||||
{
|
||||
if (region.compare(s.regionStr.c_str()) == 0)
|
||||
{
|
||||
string name = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->screenRegionScenes->setCurrentText(name.c_str());
|
||||
ui->screenRegionsTransitions->setCurrentText(transitionName.c_str());
|
||||
ui->screenRegionMinX->setValue(s.minX);
|
||||
ui->screenRegionMinY->setValue(s.minY);
|
||||
ui->screenRegionMaxX->setValue(s.maxX);
|
||||
ui->screenRegionMaxY->setValue(s.maxY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SceneSwitcher::ScreenRegionFindByData(const QString& region)
|
||||
{
|
||||
int count = ui->screenRegions->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->screenRegions->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == region)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,354 +1,372 @@
|
|||
#pragma once
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <regex>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <QDateTime>
|
||||
#include "utility.hpp"
|
||||
|
||||
#define DEFAULT_INTERVAL 300
|
||||
|
||||
#define DEFAULT_IDLE_TIME 60
|
||||
|
||||
#define READ_FILE_FUNC 0
|
||||
#define ROUND_TRIP_FUNC 1
|
||||
#define IDLE_FUNC 2
|
||||
#define EXE_FUNC 3
|
||||
#define SCREEN_REGION_FUNC 4
|
||||
#define WINDOW_TITLE_FUNC 5
|
||||
|
||||
#define DEFAULT_PRIORITY_0 READ_FILE_FUNC
|
||||
#define DEFAULT_PRIORITY_1 ROUND_TRIP_FUNC
|
||||
#define DEFAULT_PRIORITY_2 IDLE_FUNC
|
||||
#define DEFAULT_PRIORITY_3 EXE_FUNC
|
||||
#define DEFAULT_PRIORITY_4 SCREEN_REGION_FUNC
|
||||
#define DEFAULT_PRIORITY_5 WINDOW_TITLE_FUNC
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct SceneSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
string window;
|
||||
OBSWeakSource transition;
|
||||
bool fullscreen;
|
||||
|
||||
inline SceneSwitch(
|
||||
OBSWeakSource scene_, const char* window_, OBSWeakSource transition_, bool fullscreen_)
|
||||
: scene(scene_)
|
||||
, window(window_)
|
||||
, transition(transition_)
|
||||
, fullscreen(fullscreen_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ExecutableSceneSwitch
|
||||
{
|
||||
OBSWeakSource mScene;
|
||||
OBSWeakSource mTransition;
|
||||
QString mExe;
|
||||
bool mInFocus;
|
||||
|
||||
inline ExecutableSceneSwitch(
|
||||
OBSWeakSource scene, OBSWeakSource transition, const QString& exe, bool inFocus)
|
||||
: mScene(scene)
|
||||
, mTransition(transition)
|
||||
, mExe(exe)
|
||||
, mInFocus(inFocus)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ScreenRegionSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
int minX, minY, maxX, maxY;
|
||||
string regionStr;
|
||||
|
||||
inline ScreenRegionSwitch(OBSWeakSource scene_, OBSWeakSource transition_, int minX_, int minY_,
|
||||
int maxX_, int maxY_, string regionStr_)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, minX(minX_)
|
||||
, minY(minY_)
|
||||
, maxX(maxX_)
|
||||
, maxY(maxY_)
|
||||
, regionStr(regionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneRoundTripSwitch
|
||||
{
|
||||
OBSWeakSource scene1;
|
||||
OBSWeakSource scene2;
|
||||
OBSWeakSource transition;
|
||||
int delay;
|
||||
string sceneRoundTripStr;
|
||||
|
||||
inline SceneRoundTripSwitch(OBSWeakSource scene1_, OBSWeakSource scene2_,
|
||||
OBSWeakSource transition_, int delay_, string str)
|
||||
: scene1(scene1_)
|
||||
, scene2(scene2_)
|
||||
, transition(transition_)
|
||||
, delay(delay_)
|
||||
, sceneRoundTripStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct RandomSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
double delay;
|
||||
string randomSwitchStr;
|
||||
|
||||
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_
|
||||
, double delay_, string str)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, delay(delay_)
|
||||
, randomSwitchStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneTransition
|
||||
{
|
||||
OBSWeakSource scene1;
|
||||
OBSWeakSource scene2;
|
||||
OBSWeakSource transition;
|
||||
string sceneTransitionStr;
|
||||
|
||||
inline SceneTransition(OBSWeakSource scene1_, OBSWeakSource scene2_, OBSWeakSource transition_,
|
||||
string sceneTransitionStr_)
|
||||
: scene1(scene1_)
|
||||
, scene2(scene2_)
|
||||
, transition(transition_)
|
||||
, sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct DefaultSceneTransition
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
string sceneTransitionStr;
|
||||
|
||||
inline DefaultSceneTransition(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
string sceneTransitionStr_)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct FileSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
string file;
|
||||
string text;
|
||||
bool useRegex = false;
|
||||
bool useTime = false;
|
||||
QDateTime lastMod;
|
||||
|
||||
inline FileSwitch(
|
||||
OBSWeakSource scene_, OBSWeakSource transition_, const char* file_, const char* text_, bool useRegex_, bool useTime_)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, file(file_)
|
||||
, text(text_)
|
||||
, useRegex(useRegex_)
|
||||
, useTime(useTime_)
|
||||
, lastMod()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct FileIOData
|
||||
{
|
||||
bool readEnabled = false;
|
||||
string readPath;
|
||||
bool writeEnabled = false;
|
||||
string writePath;
|
||||
};
|
||||
|
||||
struct IdleData
|
||||
{
|
||||
bool idleEnable = false;
|
||||
int time = DEFAULT_IDLE_TIME;
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NO_SWITCH = 0,
|
||||
SWITCH = 1,
|
||||
RANDOM_SWITCH = 2
|
||||
} NoMatch;
|
||||
|
||||
|
||||
|
||||
struct SwitcherData
|
||||
{
|
||||
thread th;
|
||||
condition_variable cv;
|
||||
mutex m;
|
||||
bool transitionActive = false;
|
||||
bool waitForTransition = false;
|
||||
condition_variable transitionCv;
|
||||
bool stop = false;
|
||||
|
||||
vector<SceneSwitch> switches;
|
||||
string lastTitle;
|
||||
OBSWeakSource nonMatchingScene;
|
||||
OBSWeakSource lastRandomScene;
|
||||
int interval = DEFAULT_INTERVAL;
|
||||
NoMatch switchIfNotMatching = NO_SWITCH;
|
||||
bool startAtLaunch = false;
|
||||
vector<ScreenRegionSwitch> screenRegionSwitches;
|
||||
vector<OBSWeakSource> pauseScenesSwitches;
|
||||
vector<string> pauseWindowsSwitches;
|
||||
vector<string> ignoreWindowsSwitches;
|
||||
vector<SceneRoundTripSwitch> sceneRoundTripSwitches;
|
||||
vector<RandomSwitch> randomSwitches;
|
||||
vector<FileSwitch> fileSwitches;
|
||||
bool autoStopEnable = false;
|
||||
OBSWeakSource autoStopScene;
|
||||
string waitSceneName; //indicates which scene was active when we startet waiting on something
|
||||
vector<SceneTransition> sceneTransitions;
|
||||
vector<DefaultSceneTransition> defaultSceneTransitions;
|
||||
vector<ExecutableSceneSwitch> executableSwitches;
|
||||
FileIOData fileIO;
|
||||
IdleData idleData;
|
||||
vector<string> ignoreIdleWindows;
|
||||
vector<int> functionNamesByPriority = vector<int>{
|
||||
DEFAULT_PRIORITY_0,
|
||||
DEFAULT_PRIORITY_1,
|
||||
DEFAULT_PRIORITY_2,
|
||||
DEFAULT_PRIORITY_3,
|
||||
DEFAULT_PRIORITY_4,
|
||||
DEFAULT_PRIORITY_5,
|
||||
};
|
||||
|
||||
void Thread();
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
bool sceneChangedDuringWait();
|
||||
bool prioFuncsValid();
|
||||
void writeSceneInfoToFile();
|
||||
void setDefaultSceneTransitions(unique_lock<mutex>& lock);
|
||||
void autoStopStreamAndRecording();
|
||||
bool checkPause();
|
||||
void checkSceneRoundTrip(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock);
|
||||
void checkIdleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkWindowTitleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkExeSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkScreenRegionSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkFileContent(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkRandom(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, int& delay);
|
||||
|
||||
|
||||
|
||||
void Prune()
|
||||
{
|
||||
for (size_t i = 0; i < switches.size(); i++)
|
||||
{
|
||||
SceneSwitch& s = switches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
switches.erase(switches.begin() + i--);
|
||||
}
|
||||
|
||||
if (nonMatchingScene && !WeakSourceValid(nonMatchingScene))
|
||||
{
|
||||
switchIfNotMatching = NO_SWITCH;
|
||||
nonMatchingScene = nullptr;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < randomSwitches.size(); i++)
|
||||
{
|
||||
RandomSwitch& s = randomSwitches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
randomSwitches.erase(randomSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < screenRegionSwitches.size(); i++)
|
||||
{
|
||||
ScreenRegionSwitch& s = screenRegionSwitches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
screenRegionSwitches.erase(screenRegionSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < pauseScenesSwitches.size(); i++)
|
||||
{
|
||||
OBSWeakSource& scene = pauseScenesSwitches[i];
|
||||
if (!WeakSourceValid(scene))
|
||||
pauseScenesSwitches.erase(pauseScenesSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sceneRoundTripSwitches.size(); i++)
|
||||
{
|
||||
SceneRoundTripSwitch& s = sceneRoundTripSwitches[i];
|
||||
if (!WeakSourceValid(s.scene1) || !WeakSourceValid(s.scene2)
|
||||
|| !WeakSourceValid(s.transition))
|
||||
sceneRoundTripSwitches.erase(sceneRoundTripSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!WeakSourceValid(autoStopScene))
|
||||
{
|
||||
autoStopScene = nullptr;
|
||||
autoStopEnable = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sceneTransitions.size(); i++)
|
||||
{
|
||||
SceneTransition& s = sceneTransitions[i];
|
||||
if (!WeakSourceValid(s.scene1) || !WeakSourceValid(s.scene2)
|
||||
|| !WeakSourceValid(s.transition))
|
||||
sceneTransitions.erase(sceneTransitions.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < defaultSceneTransitions.size(); i++)
|
||||
{
|
||||
DefaultSceneTransition& s = defaultSceneTransitions[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
defaultSceneTransitions.erase(defaultSceneTransitions.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < executableSwitches.size(); i++)
|
||||
{
|
||||
ExecutableSceneSwitch& s = executableSwitches[i];
|
||||
if (!WeakSourceValid(s.mScene) || !WeakSourceValid(s.mTransition))
|
||||
executableSwitches.erase(executableSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fileSwitches.size(); i++)
|
||||
{
|
||||
FileSwitch& s = fileSwitches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
fileSwitches.erase(fileSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!WeakSourceValid(idleData.scene) || !WeakSourceValid(idleData.transition))
|
||||
{
|
||||
idleData.idleEnable = false;
|
||||
}
|
||||
}
|
||||
inline ~SwitcherData()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
};
|
||||
|
||||
#pragma once
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <regex>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <QDateTime>
|
||||
#include "utility.hpp"
|
||||
|
||||
#define DEFAULT_INTERVAL 300
|
||||
|
||||
#define DEFAULT_IDLE_TIME 60
|
||||
|
||||
#define READ_FILE_FUNC 0
|
||||
#define ROUND_TRIP_FUNC 1
|
||||
#define IDLE_FUNC 2
|
||||
#define EXE_FUNC 3
|
||||
#define SCREEN_REGION_FUNC 4
|
||||
#define WINDOW_TITLE_FUNC 5
|
||||
|
||||
#define DEFAULT_PRIORITY_0 READ_FILE_FUNC
|
||||
#define DEFAULT_PRIORITY_1 ROUND_TRIP_FUNC
|
||||
#define DEFAULT_PRIORITY_2 IDLE_FUNC
|
||||
#define DEFAULT_PRIORITY_3 EXE_FUNC
|
||||
#define DEFAULT_PRIORITY_4 SCREEN_REGION_FUNC
|
||||
#define DEFAULT_PRIORITY_5 WINDOW_TITLE_FUNC
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* Data structs for each scene switching method
|
||||
********************************************************************************/
|
||||
struct WindowSceneSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
string window;
|
||||
OBSWeakSource transition;
|
||||
bool fullscreen;
|
||||
|
||||
inline WindowSceneSwitch(
|
||||
OBSWeakSource scene_, const char* window_, OBSWeakSource transition_, bool fullscreen_)
|
||||
: scene(scene_)
|
||||
, window(window_)
|
||||
, transition(transition_)
|
||||
, fullscreen(fullscreen_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ExecutableSceneSwitch
|
||||
{
|
||||
OBSWeakSource mScene;
|
||||
OBSWeakSource mTransition;
|
||||
QString mExe;
|
||||
bool mInFocus;
|
||||
|
||||
inline ExecutableSceneSwitch(
|
||||
OBSWeakSource scene, OBSWeakSource transition, const QString& exe, bool inFocus)
|
||||
: mScene(scene)
|
||||
, mTransition(transition)
|
||||
, mExe(exe)
|
||||
, mInFocus(inFocus)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ScreenRegionSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
int minX, minY, maxX, maxY;
|
||||
string regionStr;
|
||||
|
||||
inline ScreenRegionSwitch(OBSWeakSource scene_, OBSWeakSource transition_, int minX_, int minY_,
|
||||
int maxX_, int maxY_, string regionStr_)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, minX(minX_)
|
||||
, minY(minY_)
|
||||
, maxX(maxX_)
|
||||
, maxY(maxY_)
|
||||
, regionStr(regionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneRoundTripSwitch
|
||||
{
|
||||
OBSWeakSource scene1;
|
||||
OBSWeakSource scene2;
|
||||
OBSWeakSource transition;
|
||||
int delay;
|
||||
string sceneRoundTripStr;
|
||||
|
||||
inline SceneRoundTripSwitch(OBSWeakSource scene1_, OBSWeakSource scene2_,
|
||||
OBSWeakSource transition_, int delay_, string str)
|
||||
: scene1(scene1_)
|
||||
, scene2(scene2_)
|
||||
, transition(transition_)
|
||||
, delay(delay_)
|
||||
, sceneRoundTripStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct RandomSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
double delay;
|
||||
string randomSwitchStr;
|
||||
|
||||
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_
|
||||
, double delay_, string str)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, delay(delay_)
|
||||
, randomSwitchStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneTransition
|
||||
{
|
||||
OBSWeakSource scene1;
|
||||
OBSWeakSource scene2;
|
||||
OBSWeakSource transition;
|
||||
string sceneTransitionStr;
|
||||
|
||||
inline SceneTransition(OBSWeakSource scene1_, OBSWeakSource scene2_, OBSWeakSource transition_,
|
||||
string sceneTransitionStr_)
|
||||
: scene1(scene1_)
|
||||
, scene2(scene2_)
|
||||
, transition(transition_)
|
||||
, sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct DefaultSceneTransition
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
string sceneTransitionStr;
|
||||
|
||||
inline DefaultSceneTransition(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
string sceneTransitionStr_)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct FileSwitch
|
||||
{
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
string file;
|
||||
string text;
|
||||
bool useRegex = false;
|
||||
bool useTime = false;
|
||||
QDateTime lastMod;
|
||||
|
||||
inline FileSwitch(
|
||||
OBSWeakSource scene_, OBSWeakSource transition_, const char* file_, const char* text_, bool useRegex_, bool useTime_)
|
||||
: scene(scene_)
|
||||
, transition(transition_)
|
||||
, file(file_)
|
||||
, text(text_)
|
||||
, useRegex(useRegex_)
|
||||
, useTime(useTime_)
|
||||
, lastMod()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct FileIOData
|
||||
{
|
||||
bool readEnabled = false;
|
||||
string readPath;
|
||||
bool writeEnabled = false;
|
||||
string writePath;
|
||||
};
|
||||
|
||||
struct IdleData
|
||||
{
|
||||
bool idleEnable = false;
|
||||
int time = DEFAULT_IDLE_TIME;
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NO_SWITCH = 0,
|
||||
SWITCH = 1,
|
||||
RANDOM_SWITCH = 2
|
||||
} NoMatch;
|
||||
|
||||
|
||||
/********************************************************************************
|
||||
* SwitcherData
|
||||
********************************************************************************/
|
||||
struct SwitcherData
|
||||
{
|
||||
thread th;
|
||||
condition_variable cv;
|
||||
mutex m;
|
||||
bool transitionActive = false;
|
||||
bool waitForTransition = false;
|
||||
condition_variable transitionCv;
|
||||
bool startAtLaunch = false;
|
||||
bool stop = false;
|
||||
obs_source_t* waitScene = NULL; //scene during which wait started
|
||||
|
||||
int interval = DEFAULT_INTERVAL;
|
||||
|
||||
OBSWeakSource nonMatchingScene;
|
||||
|
||||
OBSWeakSource lastRandomScene;
|
||||
|
||||
NoMatch switchIfNotMatching = NO_SWITCH;
|
||||
|
||||
vector<WindowSceneSwitch> windowSwitches;
|
||||
vector<string> ignoreIdleWindows;
|
||||
string lastTitle;
|
||||
|
||||
vector<ScreenRegionSwitch> screenRegionSwitches;
|
||||
|
||||
vector<OBSWeakSource> pauseScenesSwitches;
|
||||
|
||||
vector<string> pauseWindowsSwitches;
|
||||
|
||||
vector<string> ignoreWindowsSwitches;
|
||||
|
||||
vector<SceneRoundTripSwitch> sceneRoundTripSwitches;
|
||||
|
||||
vector<RandomSwitch> randomSwitches;
|
||||
|
||||
FileIOData fileIO;
|
||||
IdleData idleData;
|
||||
vector<FileSwitch> fileSwitches;
|
||||
|
||||
vector<ExecutableSceneSwitch> executableSwitches;
|
||||
|
||||
bool autoStopEnable = false;
|
||||
OBSWeakSource autoStopScene;
|
||||
|
||||
vector<SceneTransition> sceneTransitions;
|
||||
vector<DefaultSceneTransition> defaultSceneTransitions;
|
||||
|
||||
vector<int> functionNamesByPriority = vector<int>{
|
||||
DEFAULT_PRIORITY_0,
|
||||
DEFAULT_PRIORITY_1,
|
||||
DEFAULT_PRIORITY_2,
|
||||
DEFAULT_PRIORITY_3,
|
||||
DEFAULT_PRIORITY_4,
|
||||
DEFAULT_PRIORITY_5,
|
||||
};
|
||||
|
||||
void Thread();
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
bool sceneChangedDuringWait();
|
||||
bool prioFuncsValid();
|
||||
void writeSceneInfoToFile();
|
||||
void setDefaultSceneTransitions(unique_lock<mutex>& lock);
|
||||
void autoStopStreamAndRecording();
|
||||
bool checkPause();
|
||||
void checkSceneRoundTrip(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock);
|
||||
void checkIdleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkWindowTitleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkExeSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkScreenRegionSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkFileContent(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
|
||||
void checkRandom(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, int& delay);
|
||||
|
||||
void Prune()
|
||||
{
|
||||
for (size_t i = 0; i < windowSwitches.size(); i++)
|
||||
{
|
||||
WindowSceneSwitch& s = windowSwitches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
windowSwitches.erase(windowSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (nonMatchingScene && !WeakSourceValid(nonMatchingScene))
|
||||
{
|
||||
switchIfNotMatching = NO_SWITCH;
|
||||
nonMatchingScene = nullptr;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < randomSwitches.size(); i++)
|
||||
{
|
||||
RandomSwitch& s = randomSwitches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
randomSwitches.erase(randomSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < screenRegionSwitches.size(); i++)
|
||||
{
|
||||
ScreenRegionSwitch& s = screenRegionSwitches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
screenRegionSwitches.erase(screenRegionSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < pauseScenesSwitches.size(); i++)
|
||||
{
|
||||
OBSWeakSource& scene = pauseScenesSwitches[i];
|
||||
if (!WeakSourceValid(scene))
|
||||
pauseScenesSwitches.erase(pauseScenesSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sceneRoundTripSwitches.size(); i++)
|
||||
{
|
||||
SceneRoundTripSwitch& s = sceneRoundTripSwitches[i];
|
||||
if (!WeakSourceValid(s.scene1) || !WeakSourceValid(s.scene2)
|
||||
|| !WeakSourceValid(s.transition))
|
||||
sceneRoundTripSwitches.erase(sceneRoundTripSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!WeakSourceValid(autoStopScene))
|
||||
{
|
||||
autoStopScene = nullptr;
|
||||
autoStopEnable = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sceneTransitions.size(); i++)
|
||||
{
|
||||
SceneTransition& s = sceneTransitions[i];
|
||||
if (!WeakSourceValid(s.scene1) || !WeakSourceValid(s.scene2)
|
||||
|| !WeakSourceValid(s.transition))
|
||||
sceneTransitions.erase(sceneTransitions.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < defaultSceneTransitions.size(); i++)
|
||||
{
|
||||
DefaultSceneTransition& s = defaultSceneTransitions[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
defaultSceneTransitions.erase(defaultSceneTransitions.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < executableSwitches.size(); i++)
|
||||
{
|
||||
ExecutableSceneSwitch& s = executableSwitches[i];
|
||||
if (!WeakSourceValid(s.mScene) || !WeakSourceValid(s.mTransition))
|
||||
executableSwitches.erase(executableSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fileSwitches.size(); i++)
|
||||
{
|
||||
FileSwitch& s = fileSwitches[i];
|
||||
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
|
||||
fileSwitches.erase(fileSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!WeakSourceValid(idleData.scene) || !WeakSourceValid(idleData.transition))
|
||||
{
|
||||
idleData.idleEnable = false;
|
||||
}
|
||||
}
|
||||
inline ~SwitcherData()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
333
utility.hpp
333
utility.hpp
|
|
@ -1,167 +1,166 @@
|
|||
#pragma once
|
||||
#include <obs.hpp>
|
||||
#include <QString>
|
||||
#include <obs-frontend-api.h>
|
||||
#include "switcher-data-structs.hpp"
|
||||
using namespace std;
|
||||
|
||||
static inline bool WeakSourceValid(obs_weak_source_t* ws)
|
||||
{
|
||||
obs_source_t* source = obs_weak_source_get_source(ws);
|
||||
if (source)
|
||||
obs_source_release(source);
|
||||
return !!source;
|
||||
}
|
||||
|
||||
static inline QString MakeSwitchName(
|
||||
const QString& scene, const QString& value, const QString& transition, bool fullscreen)
|
||||
{
|
||||
if (!fullscreen)
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition
|
||||
+ QStringLiteral("]: ") + value;
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ value + QStringLiteral(" (only if window is fullscreen)");
|
||||
}
|
||||
|
||||
static inline QString MakeSwitchNameExecutable(
|
||||
const QString& scene, const QString& value, const QString& transition, bool inFocus)
|
||||
{
|
||||
if (!inFocus)
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition
|
||||
+ QStringLiteral("]: ") + value;
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ value + QStringLiteral(" (only if window is focused)");
|
||||
}
|
||||
|
||||
static inline QString MakeScreenRegionSwitchName(
|
||||
const QString& scene, const QString& transition, int minX, int minY, int maxX, int maxY)
|
||||
{
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ QString::number(minX) + QStringLiteral(", ") + QString::number(minY)
|
||||
+ QStringLiteral(" x ") + QString::number(maxX) + QStringLiteral(", ")
|
||||
+ QString::number(maxY);
|
||||
}
|
||||
|
||||
static inline QString MakeSceneRoundTripSwitchName(
|
||||
const QString& scene1, const QString& scene2, const QString& transition, double delay)
|
||||
{
|
||||
return scene1 + QStringLiteral(" -> wait for ") + QString::number(delay)
|
||||
+ QStringLiteral(" seconds -> ") + scene2 + QStringLiteral(" (using ") + transition
|
||||
+ QStringLiteral(" transition)");
|
||||
}
|
||||
|
||||
static inline QString MakeSceneTransitionName(
|
||||
const QString& scene1, const QString& scene2, const QString& transition)
|
||||
{
|
||||
return scene1 + QStringLiteral(" --- ") + transition + QStringLiteral(" --> ") + scene2;
|
||||
}
|
||||
|
||||
static inline QString MakeDefaultSceneTransitionName(
|
||||
const QString& scene, const QString& transition)
|
||||
{
|
||||
return scene + QStringLiteral(" --> ") + transition;
|
||||
}
|
||||
|
||||
static inline QString MakeRandomSwitchName(
|
||||
const QString& scene, const QString& transition, double& delay)
|
||||
{
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ QString::number(delay) + QStringLiteral(" seconds");
|
||||
}
|
||||
|
||||
static inline QString MakeFileSwitchName(
|
||||
const QString& scene, const QString& transition, const QString& fileName, const QString& text, bool useRegex, bool useTime)
|
||||
{
|
||||
QString switchName = QStringLiteral("Switch to ") + scene + QStringLiteral(" using ") + transition + QStringLiteral(" if ")
|
||||
+ fileName;
|
||||
if (useTime)
|
||||
switchName += QStringLiteral(" was modified and");
|
||||
switchName += QStringLiteral(" contains");
|
||||
if (useRegex)
|
||||
switchName += QStringLiteral(" (RegEx): \n\"");
|
||||
else
|
||||
switchName += QStringLiteral(": \n\"");
|
||||
if (text.length() > 30)
|
||||
switchName += text.left(27) + QStringLiteral("...\"");
|
||||
else
|
||||
switchName += text + QStringLiteral("\"");
|
||||
|
||||
return switchName;
|
||||
}
|
||||
|
||||
static inline string GetWeakSourceName(obs_weak_source_t* weak_source)
|
||||
{
|
||||
string name;
|
||||
|
||||
obs_source_t* source = obs_weak_source_get_source(weak_source);
|
||||
if (source)
|
||||
{
|
||||
name = obs_source_get_name(source);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakSourceByName(const char* name)
|
||||
{
|
||||
OBSWeakSource weak;
|
||||
obs_source_t* source = obs_get_source_by_name(name);
|
||||
if (source)
|
||||
{
|
||||
weak = obs_source_get_weak_source(source);
|
||||
obs_weak_source_release(weak);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
return weak;
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakSourceByQString(const QString& name)
|
||||
{
|
||||
return GetWeakSourceByName(name.toUtf8().constData());
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakTransitionByName(const char* transitionName)
|
||||
{
|
||||
OBSWeakSource weak;
|
||||
obs_source_t* source = nullptr;
|
||||
|
||||
if (strcmp(transitionName, "Default") == 0)
|
||||
{
|
||||
source = obs_frontend_get_current_transition();
|
||||
weak = obs_source_get_weak_source(source);
|
||||
obs_source_release(source);
|
||||
obs_weak_source_release(weak);
|
||||
return weak;
|
||||
}
|
||||
|
||||
obs_frontend_source_list* transitions = new obs_frontend_source_list();
|
||||
obs_frontend_get_transitions(transitions);
|
||||
bool match = false;
|
||||
|
||||
for (size_t i = 0; i < transitions->sources.num; i++)
|
||||
{
|
||||
const char* name = obs_source_get_name(transitions->sources.array[i]);
|
||||
if (strcmp(transitionName, name) == 0)
|
||||
{
|
||||
match = true;
|
||||
source = transitions->sources.array[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match){
|
||||
weak = obs_source_get_weak_source(source);
|
||||
obs_weak_source_release(weak);
|
||||
}
|
||||
obs_frontend_source_list_free(transitions);
|
||||
|
||||
return weak;
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakTransitionByQString(const QString& name)
|
||||
{
|
||||
return GetWeakTransitionByName(name.toUtf8().constData());
|
||||
}
|
||||
|
||||
#pragma once
|
||||
#include <obs.hpp>
|
||||
#include <QString>
|
||||
#include <obs-frontend-api.h>
|
||||
#include "switcher-data-structs.hpp"
|
||||
using namespace std;
|
||||
|
||||
static inline bool WeakSourceValid(obs_weak_source_t* ws)
|
||||
{
|
||||
obs_source_t* source = obs_weak_source_get_source(ws);
|
||||
if (source)
|
||||
obs_source_release(source);
|
||||
return !!source;
|
||||
}
|
||||
|
||||
static inline QString MakeSwitchName(
|
||||
const QString& scene, const QString& value, const QString& transition, bool fullscreen)
|
||||
{
|
||||
if (!fullscreen)
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition
|
||||
+ QStringLiteral("]: ") + value;
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ value + QStringLiteral(" (only if window is fullscreen)");
|
||||
}
|
||||
|
||||
static inline QString MakeSwitchNameExecutable(
|
||||
const QString& scene, const QString& value, const QString& transition, bool inFocus)
|
||||
{
|
||||
if (!inFocus)
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition
|
||||
+ QStringLiteral("]: ") + value;
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ value + QStringLiteral(" (only if window is focused)");
|
||||
}
|
||||
|
||||
static inline QString MakeScreenRegionSwitchName(
|
||||
const QString& scene, const QString& transition, int minX, int minY, int maxX, int maxY)
|
||||
{
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ QString::number(minX) + QStringLiteral(", ") + QString::number(minY)
|
||||
+ QStringLiteral(" x ") + QString::number(maxX) + QStringLiteral(", ")
|
||||
+ QString::number(maxY);
|
||||
}
|
||||
|
||||
static inline QString MakeSceneRoundTripSwitchName(
|
||||
const QString& scene1, const QString& scene2, const QString& transition, double delay)
|
||||
{
|
||||
return scene1 + QStringLiteral(" -> wait for ") + QString::number(delay)
|
||||
+ QStringLiteral(" seconds -> ") + scene2 + QStringLiteral(" (using ") + transition
|
||||
+ QStringLiteral(" transition)");
|
||||
}
|
||||
|
||||
static inline QString MakeSceneTransitionName(
|
||||
const QString& scene1, const QString& scene2, const QString& transition)
|
||||
{
|
||||
return scene1 + QStringLiteral(" --- ") + transition + QStringLiteral(" --> ") + scene2;
|
||||
}
|
||||
|
||||
static inline QString MakeDefaultSceneTransitionName(
|
||||
const QString& scene, const QString& transition)
|
||||
{
|
||||
return scene + QStringLiteral(" --> ") + transition;
|
||||
}
|
||||
|
||||
static inline QString MakeRandomSwitchName(
|
||||
const QString& scene, const QString& transition, double& delay)
|
||||
{
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + QStringLiteral("]: ")
|
||||
+ QString::number(delay) + QStringLiteral(" seconds");
|
||||
}
|
||||
|
||||
static inline QString MakeFileSwitchName(
|
||||
const QString& scene, const QString& transition, const QString& fileName, const QString& text, bool useRegex, bool useTime)
|
||||
{
|
||||
QString switchName = QStringLiteral("Switch to ") + scene + QStringLiteral(" using ") + transition + QStringLiteral(" if ")
|
||||
+ fileName;
|
||||
if (useTime)
|
||||
switchName += QStringLiteral(" was modified and");
|
||||
switchName += QStringLiteral(" contains");
|
||||
if (useRegex)
|
||||
switchName += QStringLiteral(" (RegEx): \n\"");
|
||||
else
|
||||
switchName += QStringLiteral(": \n\"");
|
||||
if (text.length() > 30)
|
||||
switchName += text.left(27) + QStringLiteral("...\"");
|
||||
else
|
||||
switchName += text + QStringLiteral("\"");
|
||||
|
||||
return switchName;
|
||||
}
|
||||
|
||||
static inline string GetWeakSourceName(obs_weak_source_t* weak_source)
|
||||
{
|
||||
string name;
|
||||
|
||||
obs_source_t* source = obs_weak_source_get_source(weak_source);
|
||||
if (source)
|
||||
{
|
||||
name = obs_source_get_name(source);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakSourceByName(const char* name)
|
||||
{
|
||||
OBSWeakSource weak;
|
||||
obs_source_t* source = obs_get_source_by_name(name);
|
||||
if (source)
|
||||
{
|
||||
weak = obs_source_get_weak_source(source);
|
||||
obs_weak_source_release(weak);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
return weak;
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakSourceByQString(const QString& name)
|
||||
{
|
||||
return GetWeakSourceByName(name.toUtf8().constData());
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakTransitionByName(const char* transitionName)
|
||||
{
|
||||
OBSWeakSource weak;
|
||||
obs_source_t* source = nullptr;
|
||||
|
||||
if (strcmp(transitionName, "Default") == 0)
|
||||
{
|
||||
source = obs_frontend_get_current_transition();
|
||||
weak = obs_source_get_weak_source(source);
|
||||
obs_source_release(source);
|
||||
obs_weak_source_release(weak);
|
||||
return weak;
|
||||
}
|
||||
|
||||
obs_frontend_source_list* transitions = new obs_frontend_source_list();
|
||||
obs_frontend_get_transitions(transitions);
|
||||
bool match = false;
|
||||
|
||||
for (size_t i = 0; i < transitions->sources.num; i++)
|
||||
{
|
||||
const char* name = obs_source_get_name(transitions->sources.array[i]);
|
||||
if (strcmp(transitionName, name) == 0)
|
||||
{
|
||||
match = true;
|
||||
source = transitions->sources.array[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match){
|
||||
weak = obs_source_get_weak_source(source);
|
||||
obs_weak_source_release(weak);
|
||||
}
|
||||
obs_frontend_source_list_free(transitions);
|
||||
|
||||
return weak;
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakTransitionByQString(const QString& name)
|
||||
{
|
||||
return GetWeakTransitionByName(name.toUtf8().constData());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,283 +1,280 @@
|
|||
#include <obs-module.h>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_add_clicked()
|
||||
{
|
||||
QString sceneName = ui->scenes->currentText();
|
||||
QString windowName = ui->windows->currentText();
|
||||
QString transitionName = ui->transitions->currentText();
|
||||
bool fullscreen = ui->fullscreenCheckBox->isChecked();
|
||||
|
||||
if (windowName.isEmpty() || sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QString text = MakeSwitchName(sceneName, windowName, transitionName, fullscreen);
|
||||
|
||||
int idx = FindByData(windowName);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->switches.emplace_back(
|
||||
source, windowName.toUtf8().constData(), transition, fullscreen);
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->switches);
|
||||
item->setData(Qt::UserRole, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->switches->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
string window = windowName.toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->switches)
|
||||
{
|
||||
if (s.window == window)
|
||||
{
|
||||
s.scene = source;
|
||||
s.transition = transition;
|
||||
s.fullscreen = fullscreen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->switches->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_remove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->switches->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string window = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->switches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.window == window)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SceneSwitcher::on_ignoreWindowsAdd_clicked()
|
||||
{
|
||||
QString windowName = ui->ignoreWindowsWindows->currentText();
|
||||
|
||||
if (windowName.isEmpty())
|
||||
return;
|
||||
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->ignoreWindows->findItems(windowName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(windowName, ui->ignoreWindows);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->ignoreWindowsSwitches.emplace_back(windowName.toUtf8().constData());
|
||||
ui->ignoreWindows->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreWindowsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreWindows->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString windowName = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->ignoreWindowsSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == windowName.toUtf8().constData())
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
int SceneSwitcher::FindByData(const QString& window)
|
||||
{
|
||||
int count = ui->switches->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->switches->item(i);
|
||||
QString itemWindow = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemWindow == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int SceneSwitcher::IgnoreWindowsFindByData(const QString& window)
|
||||
{
|
||||
int count = ui->ignoreWindows->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreWindows->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_switches_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->switches->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->switches)
|
||||
{
|
||||
if (window.compare(s.window.c_str()) == 0)
|
||||
{
|
||||
string name = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->scenes->setCurrentText(name.c_str());
|
||||
ui->windows->setCurrentText(window);
|
||||
ui->transitions->setCurrentText(transitionName.c_str());
|
||||
ui->fullscreenCheckBox->setChecked(s.fullscreen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SceneSwitcher::on_ignoreWindows_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->ignoreWindows->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->ignoreWindowsSwitches)
|
||||
{
|
||||
if (window.compare(s.c_str()) == 0)
|
||||
{
|
||||
ui->ignoreWindowsWindows->setCurrentText(s.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::checkWindowTitleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
//check if title should be ignored
|
||||
string title;
|
||||
GetCurrentWindowTitle(title);
|
||||
for (auto& window : ignoreWindowsSwitches)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(window));
|
||||
if (matches)
|
||||
{
|
||||
title = lastTitle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
lastTitle = title;
|
||||
|
||||
//direct match
|
||||
for (SceneSwitch& s : switches)
|
||||
{
|
||||
if (s.window == title)
|
||||
{
|
||||
match = !s.fullscreen || (s.fullscreen && isFullscreen());
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//regex match
|
||||
for (SceneSwitch& s : switches)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(s.window));
|
||||
if (matches)
|
||||
{
|
||||
match = !s.fullscreen || (s.fullscreen && isFullscreen());
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <obs-module.h>
|
||||
#include "advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_add_clicked()
|
||||
{
|
||||
QString sceneName = ui->scenes->currentText();
|
||||
QString windowName = ui->windows->currentText();
|
||||
QString transitionName = ui->transitions->currentText();
|
||||
bool fullscreen = ui->fullscreenCheckBox->isChecked();
|
||||
|
||||
if (windowName.isEmpty() || sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QString text = MakeSwitchName(sceneName, windowName, transitionName, fullscreen);
|
||||
|
||||
int idx = FindByData(windowName);
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->windowSwitches.emplace_back(
|
||||
source, windowName.toUtf8().constData(), transition, fullscreen);
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(text, ui->switches);
|
||||
item->setData(Qt::UserRole, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
QListWidgetItem* item = ui->switches->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
string window = windowName.toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->windowSwitches)
|
||||
{
|
||||
if (s.window == window)
|
||||
{
|
||||
s.scene = source;
|
||||
s.transition = transition;
|
||||
s.fullscreen = fullscreen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->switches->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_remove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->switches->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
string window = item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->windowSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s.window == window)
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SceneSwitcher::on_ignoreWindowsAdd_clicked()
|
||||
{
|
||||
QString windowName = ui->ignoreWindowsWindows->currentText();
|
||||
|
||||
if (windowName.isEmpty())
|
||||
return;
|
||||
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QList<QListWidgetItem*> items = ui->ignoreWindows->findItems(windowName, Qt::MatchExactly);
|
||||
|
||||
if (items.size() == 0)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem(windowName, ui->ignoreWindows);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
switcher->ignoreWindowsSwitches.emplace_back(windowName.toUtf8().constData());
|
||||
ui->ignoreWindows->sortItems();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_ignoreWindowsRemove_clicked()
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreWindows->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString windowName = item->data(Qt::UserRole).toString();
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
auto& switches = switcher->ignoreWindowsSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it)
|
||||
{
|
||||
auto& s = *it;
|
||||
|
||||
if (s == windowName.toUtf8().constData())
|
||||
{
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
int SceneSwitcher::FindByData(const QString& window)
|
||||
{
|
||||
int count = ui->switches->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->switches->item(i);
|
||||
QString itemWindow = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemWindow == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int SceneSwitcher::IgnoreWindowsFindByData(const QString& window)
|
||||
{
|
||||
int count = ui->ignoreWindows->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = ui->ignoreWindows->item(i);
|
||||
QString itemRegion = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (itemRegion == window)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_switches_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->switches->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->windowSwitches)
|
||||
{
|
||||
if (window.compare(s.window.c_str()) == 0)
|
||||
{
|
||||
string name = GetWeakSourceName(s.scene);
|
||||
string transitionName = GetWeakSourceName(s.transition);
|
||||
ui->scenes->setCurrentText(name.c_str());
|
||||
ui->windows->setCurrentText(window);
|
||||
ui->transitions->setCurrentText(transitionName.c_str());
|
||||
ui->fullscreenCheckBox->setChecked(s.fullscreen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SceneSwitcher::on_ignoreWindows_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem* item = ui->ignoreWindows->item(idx);
|
||||
|
||||
QString window = item->data(Qt::UserRole).toString();
|
||||
|
||||
lock_guard<mutex> lock(switcher->m);
|
||||
for (auto& s : switcher->ignoreWindowsSwitches)
|
||||
{
|
||||
if (window.compare(s.c_str()) == 0)
|
||||
{
|
||||
ui->ignoreWindowsWindows->setCurrentText(s.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::checkWindowTitleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition)
|
||||
{
|
||||
//check if title should be ignored
|
||||
string title;
|
||||
GetCurrentWindowTitle(title);
|
||||
for (auto& window : ignoreWindowsSwitches)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(window));
|
||||
if (matches)
|
||||
{
|
||||
title = lastTitle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
lastTitle = title;
|
||||
|
||||
//direct match
|
||||
for (WindowSceneSwitch& s : windowSwitches)
|
||||
{
|
||||
if (s.window == title)
|
||||
{
|
||||
match = !s.fullscreen || (s.fullscreen && isFullscreen());
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//regex match
|
||||
for (WindowSceneSwitch& s : windowSwitches)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool matches = regex_match(title, regex(s.window));
|
||||
if (matches)
|
||||
{
|
||||
match = !s.fullscreen || (s.fullscreen && isFullscreen());
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
}
|
||||
}
|
||||
catch (const regex_error&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user