mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-13 04:37:14 -05:00
Refactor, fixes and maximized option for title tab (#40)
* move definitions of switcher structs to separate files * remove useless comment * cleanup and silence warnings * add generic switch * removed delay on main thread startup as it served no purpose * clean up ultility.hpp * do not save switchStr to file as it could cause issues when scenes are renamed * rename sceneRoundTrip to sceneSequence * add option to switch if window is maximized to title tab
This commit is contained in:
@@ -36,26 +36,40 @@ if(BUILD_OUT_OF_TREE)
|
||||
src/headers/switcher-data-structs.hpp
|
||||
src/headers/utility.hpp
|
||||
src/headers/curl-helper.hpp
|
||||
src/headers/switch-audio.hpp
|
||||
src/headers/switch-executable.hpp
|
||||
src/headers/switch-file.hpp
|
||||
src/headers/switch-idle.hpp
|
||||
src/headers/switch-media.hpp
|
||||
src/headers/switch-random.hpp
|
||||
src/headers/switch-screen-region.hpp
|
||||
src/headers/switch-time.hpp
|
||||
src/headers/switch-transitions.hpp
|
||||
src/headers/switch-window.hpp
|
||||
src/headers/swtich-sequence.hpp
|
||||
src/headers/switch-generic.hpp
|
||||
)
|
||||
|
||||
set(advanced-scene-switcher_SOURCES
|
||||
${advanced-scene-switcher_SOURCES}
|
||||
src/advanced-scene-switcher.cpp
|
||||
src/advanced-scene-switcher-module.c
|
||||
src/scene-transitions.cpp
|
||||
src/screen-region-switch.cpp
|
||||
src/priority.cpp
|
||||
src/executable-switch.cpp
|
||||
src/idle-switch.cpp
|
||||
src/scene-round-trip.cpp
|
||||
src/file-switch.cpp
|
||||
src/window-title-switch.cpp
|
||||
src/media-switch.cpp
|
||||
src/switcher-data-structs.cpp
|
||||
src/switch-transitions.cpp
|
||||
src/switch-screen-region.cpp
|
||||
src/switch-priority.cpp
|
||||
src/switch-executable.cpp
|
||||
src/switch-idle.cpp
|
||||
src/switch-sequence.cpp
|
||||
src/switch-file.cpp
|
||||
src/switch-window.cpp
|
||||
src/switch-media.cpp
|
||||
src/hotkey.cpp
|
||||
src/general.cpp
|
||||
src/pause-switch.cpp
|
||||
src/random.cpp
|
||||
src/time-switch.cpp
|
||||
src/switch-pause.cpp
|
||||
src/switch-random.cpp
|
||||
src/switch-time.cpp
|
||||
src/switch-audio.cpp
|
||||
src/curl-helper.cpp
|
||||
)
|
||||
|
||||
@@ -170,27 +184,40 @@ else ()
|
||||
src/headers/utility.hpp
|
||||
src/headers/curl-helper.hpp
|
||||
src/headers/volume-control.hpp
|
||||
src/headers/switch-audio.hpp
|
||||
src/headers/switch-executable.hpp
|
||||
src/headers/switch-file.hpp
|
||||
src/headers/switch-idle.hpp
|
||||
src/headers/switch-media.hpp
|
||||
src/headers/switch-random.hpp
|
||||
src/headers/switch-screen-region.hpp
|
||||
src/headers/switch-time.hpp
|
||||
src/headers/switch-transitions.hpp
|
||||
src/headers/switch-window.hpp
|
||||
src/headers/swtich-sequence.hpp
|
||||
src/headers/switch-generic.hpp
|
||||
)
|
||||
|
||||
set(advanced-scene-switcher_SOURCES
|
||||
${advanced-scene-switcher_SOURCES}
|
||||
src/advanced-scene-switcher.cpp
|
||||
src/advanced-scene-switcher-module.c
|
||||
src/scene-transitions.cpp
|
||||
src/screen-region-switch.cpp
|
||||
src/priority.cpp
|
||||
src/executable-switch.cpp
|
||||
src/idle-switch.cpp
|
||||
src/scene-round-trip.cpp
|
||||
src/file-switch.cpp
|
||||
src/window-title-switch.cpp
|
||||
src/media-switch.cpp
|
||||
src/switcher-data-structs.cpp
|
||||
src/switch-transitions.cpp
|
||||
src/switch-screen-region.cpp
|
||||
src/switch-priority.cpp
|
||||
src/switch-executable.cpp
|
||||
src/switch-idle.cpp
|
||||
src/switch-sequence.cpp
|
||||
src/switch-file.cpp
|
||||
src/switch-window.cpp
|
||||
src/switch-media.cpp
|
||||
src/hotkey.cpp
|
||||
src/general.cpp
|
||||
src/pause-switch.cpp
|
||||
src/random.cpp
|
||||
src/time-switch.cpp
|
||||
src/audio-switch.cpp
|
||||
src/switch-pause.cpp
|
||||
src/switch-random.cpp
|
||||
src/switch-time.cpp
|
||||
src/switch-audio.cpp
|
||||
src/curl-helper.cpp
|
||||
src/volume-control.cpp
|
||||
)
|
||||
|
||||
@@ -1246,14 +1246,21 @@
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fullscreenCheckBox">
|
||||
<property name="text">
|
||||
<string>only if fullscreen</string>
|
||||
<string>if fullscreen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="maximizedCheckBox">
|
||||
<property name="text">
|
||||
<string>if maximized</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="focusCheckBox">
|
||||
<property name="text">
|
||||
<string>only if focused</string>
|
||||
<string>if focused</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -3359,7 +3366,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="sceneRoundTripTab">
|
||||
<widget class="QWidget" name="sceneSequenceTab">
|
||||
<attribute name="title">
|
||||
<string notr="true">Sequence</string>
|
||||
</attribute>
|
||||
@@ -3374,7 +3381,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="sceneRoundTripScenes1">
|
||||
<widget class="QComboBox" name="sceneSequenceScenes1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -3397,7 +3404,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="sceneRoundTripScenes2">
|
||||
<widget class="QComboBox" name="sceneSequenceScenes2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -3420,7 +3427,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="sceneRoundTripSpinBox">
|
||||
<widget class="QDoubleSpinBox" name="sceneSequenceSpinBox">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -3430,7 +3437,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="sceneRoundTripDelayUnits"/>
|
||||
<widget class="QComboBox" name="sceneSequenceDelayUnits"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_17">
|
||||
@@ -3440,7 +3447,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="sceneRoundTripTransitions"/>
|
||||
<widget class="QComboBox" name="sceneSequenceTransitions"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_9">
|
||||
@@ -3465,7 +3472,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="sceneRoundTrips">
|
||||
<widget class="QListWidget" name="sceneSequences">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -3480,7 +3487,7 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneRoundTripAdd">
|
||||
<widget class="QPushButton" name="sceneSequenceAdd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
@@ -3496,7 +3503,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneRoundTripRemove">
|
||||
<widget class="QPushButton" name="sceneSequenceRemove">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
@@ -3551,7 +3558,7 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneRoundTripUp">
|
||||
<widget class="QPushButton" name="sceneSequenceUp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
@@ -3574,7 +3581,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneRoundTripDown">
|
||||
<widget class="QPushButton" name="sceneSequenceDown">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
@@ -3627,14 +3634,14 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_28">
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneRoundTripSave">
|
||||
<widget class="QPushButton" name="sceneSequenceSave">
|
||||
<property name="text">
|
||||
<string>Save Round Trips to file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneRoundTripLoad">
|
||||
<widget class="QPushButton" name="sceneSequenceLoad">
|
||||
<property name="text">
|
||||
<string>Load Round Trips from file</string>
|
||||
</property>
|
||||
|
||||
@@ -112,7 +112,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
switcher->saveWindowTitleSwitches(obj);
|
||||
switcher->saveScreenRegionSwitches(obj);
|
||||
switcher->savePauseSwitches(obj);
|
||||
switcher->saveSceneRoundTripSwitches(obj);
|
||||
switcher->saveSceneSequenceSwitches(obj);
|
||||
switcher->saveSceneTransitions(obj);
|
||||
switcher->saveIdleSwitches(obj);
|
||||
switcher->saveExecutableSwitches(obj);
|
||||
@@ -138,7 +138,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
switcher->loadWindowTitleSwitches(obj);
|
||||
switcher->loadScreenRegionSwitches(obj);
|
||||
switcher->loadPauseSwitches(obj);
|
||||
switcher->loadSceneRoundTripSwitches(obj);
|
||||
switcher->loadSceneSequenceSwitches(obj);
|
||||
switcher->loadSceneTransitions(obj);
|
||||
switcher->loadIdleSwitches(obj);
|
||||
switcher->loadExecutableSwitches(obj);
|
||||
@@ -153,9 +153,11 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
|
||||
switcher->m.unlock();
|
||||
|
||||
if (switcher->stop)
|
||||
switcher->Stop();
|
||||
else
|
||||
// stop the scene switcher at least once
|
||||
// to avoid issues with scene collection changes
|
||||
bool start = !switcher->stop;
|
||||
switcher->Stop();
|
||||
if (start)
|
||||
switcher->Start();
|
||||
}
|
||||
}
|
||||
@@ -166,9 +168,6 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
void SwitcherData::Thread()
|
||||
{
|
||||
blog(LOG_INFO, "Advanced Scene Switcher started");
|
||||
//to avoid scene duplication when rapidly switching scene collection
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
|
||||
int sleep = 0;
|
||||
|
||||
while (true) {
|
||||
@@ -237,7 +236,7 @@ void SwitcherData::Thread()
|
||||
transition);
|
||||
break;
|
||||
case round_trip_func:
|
||||
checkSceneRoundTrip(match, scene, transition,
|
||||
checkSceneSequence(match, scene, transition,
|
||||
lock);
|
||||
if (sceneChangedDuringWait()) //scene might have changed during the sleep
|
||||
{
|
||||
|
||||
@@ -15,7 +15,8 @@ QLibrary *loaded_curl_lib = nullptr;
|
||||
bool resolveCurl()
|
||||
{
|
||||
f_curl_init = (initFunction)loaded_curl_lib->resolve("curl_easy_init");
|
||||
f_curl_setopt = (setOptFunction)loaded_curl_lib->resolve("curl_easy_setopt");
|
||||
f_curl_setopt =
|
||||
(setOptFunction)loaded_curl_lib->resolve("curl_easy_setopt");
|
||||
f_curl_perform =
|
||||
(performFunction)loaded_curl_lib->resolve("curl_easy_perform");
|
||||
f_curl_cleanup =
|
||||
@@ -43,7 +44,8 @@ bool loadCurl()
|
||||
|
||||
for (QString path : locations) {
|
||||
blog(LOG_INFO, "trying '%s'", path.toUtf8().constData());
|
||||
QFileInfo libPath(QDir(path).absoluteFilePath(CURL_LIBRARY_NAME));
|
||||
QFileInfo libPath(
|
||||
QDir(path).absoluteFilePath(curl_library_name));
|
||||
|
||||
if (libPath.exists() && libPath.isFile()) {
|
||||
QString libFilePath = libPath.absoluteFilePath();
|
||||
|
||||
@@ -257,7 +257,7 @@ void SceneSwitcher::on_exportSettings_clicked()
|
||||
switcher->saveWindowTitleSwitches(obj);
|
||||
switcher->saveScreenRegionSwitches(obj);
|
||||
switcher->savePauseSwitches(obj);
|
||||
switcher->saveSceneRoundTripSwitches(obj);
|
||||
switcher->saveSceneSequenceSwitches(obj);
|
||||
switcher->saveSceneTransitions(obj);
|
||||
switcher->saveIdleSwitches(obj);
|
||||
switcher->saveExecutableSwitches(obj);
|
||||
@@ -302,7 +302,7 @@ void SceneSwitcher::on_importSettings_clicked()
|
||||
switcher->loadWindowTitleSwitches(obj);
|
||||
switcher->loadScreenRegionSwitches(obj);
|
||||
switcher->loadPauseSwitches(obj);
|
||||
switcher->loadSceneRoundTripSwitches(obj);
|
||||
switcher->loadSceneSequenceSwitches(obj);
|
||||
switcher->loadSceneTransitions(obj);
|
||||
switcher->loadIdleSwitches(obj);
|
||||
switcher->loadExecutableSwitches(obj);
|
||||
@@ -674,7 +674,7 @@ void SceneSwitcher::setupGeneralTab()
|
||||
item->setData(Qt::UserRole, text);
|
||||
}
|
||||
|
||||
for (int i = 0; i < switcher->threadPriorities.size(); ++i) {
|
||||
for (int i = 0; i < (int)switcher->threadPriorities.size(); ++i) {
|
||||
ui->threadPriority->addItem(
|
||||
switcher->threadPriorities[i].name.c_str());
|
||||
ui->threadPriority->setItemData(
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
int PauseScenesFindByData(const QString &scene);
|
||||
int PauseWindowsFindByData(const QString &window);
|
||||
int IgnoreWindowsFindByData(const QString &window);
|
||||
int SceneRoundTripFindByData(const QString &scene1);
|
||||
int SceneSequenceFindByData(const QString &scene1);
|
||||
int SceneTransitionsFindByData(const QString &scene1,
|
||||
const QString &scene2);
|
||||
int DefaultTransitionsFindByData(const QString &scene);
|
||||
@@ -106,14 +106,14 @@ public slots:
|
||||
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_sceneRoundTripUp_clicked();
|
||||
void on_sceneRoundTripDown_clicked();
|
||||
void on_sceneRoundTripDelayUnits_currentIndexChanged(int index);
|
||||
void on_sceneSequences_currentRowChanged(int idx);
|
||||
void on_sceneSequenceAdd_clicked();
|
||||
void on_sceneSequenceRemove_clicked();
|
||||
void on_sceneSequenceSave_clicked();
|
||||
void on_sceneSequenceLoad_clicked();
|
||||
void on_sceneSequenceUp_clicked();
|
||||
void on_sceneSequenceDown_clicked();
|
||||
void on_sceneSequenceDelayUnits_currentIndexChanged(int index);
|
||||
|
||||
void on_autoStopSceneCheckBox_stateChanged(int state);
|
||||
void on_autoStopScenes_currentTextChanged(const QString &text);
|
||||
@@ -205,6 +205,7 @@ void GetWindowList(std::vector<std::string> &windows);
|
||||
void GetWindowList(QStringList &windows); // Overloaded
|
||||
void GetCurrentWindowTitle(std::string &title);
|
||||
bool isFullscreen(std::string &title);
|
||||
bool isMaximized(std::string &title);
|
||||
|
||||
/********************************************************************************
|
||||
* Screenregion helper
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#include <QLibrary>
|
||||
|
||||
#if defined(WIN32)
|
||||
#define CURL_LIBRARY_NAME "libcurl.dll"
|
||||
constexpr auto curl_library_name = "libcurl.dll";
|
||||
#elif __APPLE__
|
||||
#define CURL_LIBRARY_NAME "libcurl.4.dylib"
|
||||
#define curl_library_name "libcurl.4.dylib"
|
||||
#else
|
||||
#define CURL_LIBRARY_NAME "libcurl.so.4"
|
||||
#define curl_library_name "libcurl.so.4"
|
||||
#endif
|
||||
|
||||
typedef CURL *(*initFunction)(void);
|
||||
|
||||
115
src/headers/switch-audio.hpp
Normal file
115
src/headers/switch-audio.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto audio_func = 8;
|
||||
constexpr auto default_priority_8 = audio_func;
|
||||
|
||||
struct AudioSwitch : virtual SceneSwitcherEntry {
|
||||
OBSWeakSource audioSource;
|
||||
int volumeThreshold;
|
||||
float peak;
|
||||
std::string audioSwitchStr;
|
||||
obs_volmeter_t *volmeter;
|
||||
|
||||
const char *getType() { return "audio"; }
|
||||
|
||||
static void setVolumeLevel(void *data,
|
||||
const float magnitude[MAX_AUDIO_CHANNELS],
|
||||
const float peak[MAX_AUDIO_CHANNELS],
|
||||
const float inputPeak[MAX_AUDIO_CHANNELS])
|
||||
{
|
||||
UNUSED_PARAMETER(magnitude);
|
||||
UNUSED_PARAMETER(inputPeak);
|
||||
AudioSwitch *s = static_cast<AudioSwitch *>(data);
|
||||
|
||||
s->peak = peak[0];
|
||||
for (int i = 1; i < MAX_AUDIO_CHANNELS; i++)
|
||||
if (peak[i] > s->peak)
|
||||
s->peak = peak[i];
|
||||
}
|
||||
|
||||
bool valid()
|
||||
{
|
||||
return (usePreviousScene || WeakSourceValid(scene)) &&
|
||||
WeakSourceValid(audioSource) &&
|
||||
WeakSourceValid(transition);
|
||||
}
|
||||
|
||||
inline AudioSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
OBSWeakSource audioSource_, int volumeThreshold_,
|
||||
bool usePreviousScene_, std::string audioSwitchStr_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
audioSource(audioSource_),
|
||||
volumeThreshold(volumeThreshold_),
|
||||
audioSwitchStr(audioSwitchStr_)
|
||||
{
|
||||
volmeter = obs_volmeter_create(OBS_FADER_LOG);
|
||||
obs_volmeter_add_callback(volmeter, setVolumeLevel, this);
|
||||
obs_source_t *as = obs_weak_source_get_source(audioSource);
|
||||
if (!obs_volmeter_attach_source(volmeter, as)) {
|
||||
const char *name = obs_source_get_name(as);
|
||||
blog(LOG_WARNING,
|
||||
"failed to attach volmeter to source %s", name);
|
||||
}
|
||||
obs_source_release(as);
|
||||
}
|
||||
|
||||
AudioSwitch(const AudioSwitch &other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
audioSource(other.audioSource),
|
||||
volumeThreshold(other.volumeThreshold),
|
||||
audioSwitchStr(other.audioSwitchStr)
|
||||
{
|
||||
volmeter = obs_volmeter_create(OBS_FADER_LOG);
|
||||
obs_volmeter_add_callback(volmeter, setVolumeLevel, this);
|
||||
obs_source_t *as =
|
||||
obs_weak_source_get_source(other.audioSource);
|
||||
if (!obs_volmeter_attach_source(volmeter, as)) {
|
||||
const char *name = obs_source_get_name(as);
|
||||
blog(LOG_WARNING,
|
||||
"failed to attach volmeter to source %s", name);
|
||||
}
|
||||
obs_source_release(as);
|
||||
}
|
||||
|
||||
AudioSwitch(AudioSwitch &&other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
audioSource(other.audioSource),
|
||||
volumeThreshold(other.volumeThreshold),
|
||||
audioSwitchStr(other.audioSwitchStr),
|
||||
volmeter(other.volmeter)
|
||||
{
|
||||
other.volmeter = nullptr;
|
||||
}
|
||||
|
||||
inline ~AudioSwitch()
|
||||
{
|
||||
obs_volmeter_remove_callback(volmeter, setVolumeLevel, this);
|
||||
obs_volmeter_destroy(volmeter);
|
||||
}
|
||||
|
||||
AudioSwitch &operator=(const AudioSwitch &other)
|
||||
{
|
||||
return *this = AudioSwitch(other);
|
||||
}
|
||||
|
||||
AudioSwitch &operator=(AudioSwitch &&other) noexcept
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
obs_volmeter_destroy(volmeter);
|
||||
volmeter = other.volmeter;
|
||||
other.volmeter = nullptr;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeAudioSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
const QString &audioSrouce,
|
||||
const int &volume);
|
||||
28
src/headers/switch-executable.hpp
Normal file
28
src/headers/switch-executable.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto exe_func = 3;
|
||||
constexpr auto default_priority_3 = exe_func;
|
||||
|
||||
struct ExecutableSceneSwitch : SceneSwitcherEntry {
|
||||
QString exe;
|
||||
bool inFocus;
|
||||
|
||||
const char *getType() { return "exec"; }
|
||||
|
||||
inline ExecutableSceneSwitch(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_,
|
||||
const QString &exe_, bool inFocus_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
exe(exe_),
|
||||
inFocus(inFocus_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeSwitchNameExecutable(const QString &scene,
|
||||
const QString &value,
|
||||
const QString &transition,
|
||||
bool inFocus);
|
||||
44
src/headers/switch-file.hpp
Normal file
44
src/headers/switch-file.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto read_file_func = 0;
|
||||
constexpr auto default_priority_0 = read_file_func;
|
||||
|
||||
struct FileSwitch : SceneSwitcherEntry {
|
||||
std::string file;
|
||||
std::string text;
|
||||
bool remote = false;
|
||||
bool useRegex = false;
|
||||
bool useTime = false;
|
||||
QDateTime lastMod;
|
||||
|
||||
const char *getType() { return "file"; }
|
||||
|
||||
inline FileSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
const char *file_, const char *text_, bool remote_,
|
||||
bool useRegex_, bool useTime_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
file(file_),
|
||||
text(text_),
|
||||
remote(remote_),
|
||||
useRegex(useRegex_),
|
||||
useTime(useTime_),
|
||||
lastMod()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct FileIOData {
|
||||
bool readEnabled = false;
|
||||
std::string readPath;
|
||||
bool writeEnabled = false;
|
||||
std::string writePath;
|
||||
};
|
||||
|
||||
static inline QString MakeFileSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
const QString &fileName,
|
||||
const QString &text, bool useRegex,
|
||||
bool useTime);
|
||||
48
src/headers/switch-generic.hpp
Normal file
48
src/headers/switch-generic.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <obs.hpp>
|
||||
|
||||
struct SceneSwitcherEntry {
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
bool usePreviousScene;
|
||||
|
||||
virtual bool valid()
|
||||
{
|
||||
return (usePreviousScene || WeakSourceValid(scene)) &&
|
||||
WeakSourceValid(transition);
|
||||
}
|
||||
|
||||
virtual const char *getType() = 0;
|
||||
|
||||
// TODO
|
||||
//virtual bool checkMatch() = 0;
|
||||
|
||||
virtual void logMatch()
|
||||
{
|
||||
obs_source_t *s = obs_weak_source_get_source(scene);
|
||||
const char *sceneName = obs_source_get_name(s);
|
||||
obs_source_release(s);
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher match for '%s' - switch to scene '%s'",
|
||||
getType(), sceneName);
|
||||
}
|
||||
|
||||
inline SceneSwitcherEntry() : usePreviousScene(false) {}
|
||||
|
||||
inline SceneSwitcherEntry(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_,
|
||||
bool usePreviousScene_)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
usePreviousScene(usePreviousScene_)
|
||||
{
|
||||
}
|
||||
inline SceneSwitcherEntry(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
usePreviousScene(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
16
src/headers/switch-idle.hpp
Normal file
16
src/headers/switch-idle.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto default_idle_time = 60;
|
||||
constexpr auto idle_func = 2;
|
||||
constexpr auto default_priority_2 = idle_func;
|
||||
|
||||
struct IdleData : SceneSwitcherEntry {
|
||||
bool idleEnable = false;
|
||||
int time = default_idle_time;
|
||||
bool alreadySwitched = false;
|
||||
|
||||
const char *getType() { return "idle"; }
|
||||
};
|
||||
50
src/headers/switch-media.hpp
Normal file
50
src/headers/switch-media.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto media_func = 6;
|
||||
constexpr auto default_priority_6 = media_func;
|
||||
|
||||
typedef enum {
|
||||
TIME_RESTRICTION_NONE,
|
||||
TIME_RESTRICTION_SHORTER,
|
||||
TIME_RESTRICTION_LONGER,
|
||||
TIME_RESTRICTION_REMAINING_SHORTER,
|
||||
TIME_RESTRICTION_REMAINING_LONGER,
|
||||
} time_restriction;
|
||||
|
||||
struct MediaSwitch : SceneSwitcherEntry {
|
||||
OBSWeakSource source;
|
||||
obs_media_state state;
|
||||
time_restriction restriction;
|
||||
int64_t time;
|
||||
bool matched;
|
||||
std::string mediaSwitchStr;
|
||||
|
||||
const char *getType() { return "meida"; }
|
||||
|
||||
bool valid()
|
||||
{
|
||||
return (usePreviousScene || WeakSourceValid(scene)) &&
|
||||
WeakSourceValid(source) && WeakSourceValid(transition);
|
||||
}
|
||||
|
||||
inline MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
|
||||
OBSWeakSource transition_, obs_media_state state_,
|
||||
time_restriction restriction_, uint64_t time_,
|
||||
bool usePreviousScene_, std::string mediaSwitchStr_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
source(source_),
|
||||
state(state_),
|
||||
restriction(restriction_),
|
||||
time(time_),
|
||||
mediaSwitchStr(mediaSwitchStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString
|
||||
MakeMediaSwitchName(const QString &source, const QString &scene,
|
||||
const QString &transition, obs_media_state state,
|
||||
time_restriction restriction, uint64_t time);
|
||||
23
src/headers/switch-random.hpp
Normal file
23
src/headers/switch-random.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
struct RandomSwitch : SceneSwitcherEntry {
|
||||
double delay;
|
||||
std::string randomSwitchStr;
|
||||
|
||||
const char *getType() { return "random"; }
|
||||
|
||||
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
double delay_, std::string str)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
delay(delay_),
|
||||
randomSwitchStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeRandomSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
double &delay);
|
||||
32
src/headers/switch-screen-region.hpp
Normal file
32
src/headers/switch-screen-region.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto screen_region_func = 4;
|
||||
constexpr auto default_priority_4 = screen_region_func;
|
||||
|
||||
struct ScreenRegionSwitch : SceneSwitcherEntry {
|
||||
int minX, minY, maxX, maxY;
|
||||
std::string regionStr;
|
||||
|
||||
const char *getType() { return "region"; }
|
||||
|
||||
inline ScreenRegionSwitch(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_, int minX_,
|
||||
int minY_, int maxX_, int maxY_,
|
||||
std::string regionStr_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
minX(minX_),
|
||||
minY(minY_),
|
||||
maxX(maxX_),
|
||||
maxY(maxY_),
|
||||
regionStr(regionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeScreenRegionSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
int minX, int minY, int maxX,
|
||||
int maxY);
|
||||
43
src/headers/switch-time.hpp
Normal file
43
src/headers/switch-time.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <QDateTime>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto time_func = 7;
|
||||
constexpr auto default_priority_7 = time_func;
|
||||
|
||||
typedef enum {
|
||||
ANY_DAY = 0,
|
||||
MONDAY = 1,
|
||||
TUSEDAY = 2,
|
||||
WEDNESDAY = 3,
|
||||
THURSDAY = 4,
|
||||
FRIDAY = 5,
|
||||
SATURDAY = 6,
|
||||
SUNDAY = 7,
|
||||
LIVE = 8
|
||||
} timeTrigger;
|
||||
|
||||
struct TimeSwitch : SceneSwitcherEntry {
|
||||
timeTrigger trigger;
|
||||
QTime time;
|
||||
std::string timeSwitchStr;
|
||||
|
||||
const char *getType() { return "time"; }
|
||||
|
||||
inline TimeSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
timeTrigger trigger_, QTime time_,
|
||||
bool usePreviousScene_, std::string timeSwitchStr_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
trigger(trigger_),
|
||||
time(time_),
|
||||
timeSwitchStr(timeSwitchStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeTimeSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
const timeTrigger &trigger,
|
||||
const QTime &time);
|
||||
47
src/headers/switch-transitions.hpp
Normal file
47
src/headers/switch-transitions.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
struct SceneTransition : SceneSwitcherEntry {
|
||||
OBSWeakSource scene2;
|
||||
std::string sceneTransitionStr;
|
||||
|
||||
const char *getType() { return "transition"; }
|
||||
|
||||
bool valid()
|
||||
{
|
||||
return (WeakSourceValid(scene) && WeakSourceValid(scene2)) &&
|
||||
WeakSourceValid(transition);
|
||||
}
|
||||
|
||||
inline SceneTransition(OBSWeakSource scene_, OBSWeakSource scene2_,
|
||||
OBSWeakSource transition_,
|
||||
std::string sceneTransitionStr_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
scene2(scene2_),
|
||||
sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeSceneTransitionName(const QString &scene1,
|
||||
const QString &scene2,
|
||||
const QString &transition);
|
||||
|
||||
struct DefaultSceneTransition : SceneSwitcherEntry {
|
||||
std::string sceneTransitionStr;
|
||||
|
||||
const char *getType() { return "def_transition"; }
|
||||
|
||||
inline DefaultSceneTransition(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_,
|
||||
std::string sceneTransitionStr_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeDefaultSceneTransitionName(const QString &scene,
|
||||
const QString &transition);
|
||||
33
src/headers/switch-window.hpp
Normal file
33
src/headers/switch-window.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto window_title_func = 5;
|
||||
constexpr auto default_priority_5 = window_title_func;
|
||||
|
||||
struct WindowSceneSwitch : SceneSwitcherEntry {
|
||||
std::string window;
|
||||
bool fullscreen;
|
||||
bool maximized;
|
||||
bool focus;
|
||||
|
||||
const char *getType() { return "window"; }
|
||||
|
||||
inline WindowSceneSwitch(OBSWeakSource scene_, const char *window_,
|
||||
OBSWeakSource transition_, bool fullscreen_,
|
||||
bool maximized_, bool focus_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
window(window_),
|
||||
fullscreen(fullscreen_),
|
||||
maximized(maximized_),
|
||||
focus(focus_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeWindowSwitchName(const QString &scene,
|
||||
const QString &value,
|
||||
const QString &transition,
|
||||
bool fullscreen, bool maximized,
|
||||
bool focus);
|
||||
@@ -1,362 +1,27 @@
|
||||
#pragma once
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <QDateTime>
|
||||
#include <QThread>
|
||||
#include <curl/curl.h>
|
||||
#include "utility.hpp"
|
||||
|
||||
#include "switch-audio.hpp"
|
||||
#include "switch-executable.hpp"
|
||||
#include "switch-file.hpp"
|
||||
#include "switch-idle.hpp"
|
||||
#include "switch-media.hpp"
|
||||
#include "switch-random.hpp"
|
||||
#include "switch-screen-region.hpp"
|
||||
#include "switch-time.hpp"
|
||||
#include "switch-transitions.hpp"
|
||||
#include "switch-window.hpp"
|
||||
#include "swtich-sequence.hpp"
|
||||
|
||||
constexpr auto default_interval = 300;
|
||||
|
||||
constexpr auto default_idle_time = 60;
|
||||
|
||||
constexpr auto previous_scene_name = "Previous Scene";
|
||||
|
||||
constexpr auto read_file_func = 0;
|
||||
constexpr auto round_trip_func = 1;
|
||||
constexpr auto idle_func = 2;
|
||||
constexpr auto exe_func = 3;
|
||||
constexpr auto screen_region_func = 4;
|
||||
constexpr auto window_title_func = 5;
|
||||
constexpr auto media_func = 6;
|
||||
constexpr auto time_func = 7;
|
||||
constexpr auto audio_func = 8;
|
||||
|
||||
constexpr auto default_priority_0 = read_file_func;
|
||||
constexpr auto default_priority_1 = round_trip_func;
|
||||
constexpr auto default_priority_2 = idle_func;
|
||||
constexpr auto default_priority_3 = exe_func;
|
||||
constexpr auto default_priority_4 = screen_region_func;
|
||||
constexpr auto default_priority_5 = window_title_func;
|
||||
constexpr auto default_priority_6 = media_func;
|
||||
constexpr auto default_priority_7 = time_func;
|
||||
constexpr auto default_priority_8 = audio_func;
|
||||
|
||||
/********************************************************************************
|
||||
* Data structs for each scene switching method
|
||||
********************************************************************************/
|
||||
struct WindowSceneSwitch {
|
||||
OBSWeakSource scene;
|
||||
std::string window;
|
||||
OBSWeakSource transition;
|
||||
bool fullscreen;
|
||||
bool focus;
|
||||
|
||||
inline WindowSceneSwitch(OBSWeakSource scene_, const char *window_,
|
||||
OBSWeakSource transition_, bool fullscreen_,
|
||||
bool focus_)
|
||||
: scene(scene_),
|
||||
window(window_),
|
||||
transition(transition_),
|
||||
fullscreen(fullscreen_),
|
||||
focus(focus_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
std::string regionStr;
|
||||
|
||||
inline ScreenRegionSwitch(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_, int minX_,
|
||||
int minY_, int maxX_, int maxY_,
|
||||
std::string regionStr_)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
minX(minX_),
|
||||
minY(minY_),
|
||||
maxX(maxX_),
|
||||
maxY(maxY_),
|
||||
regionStr(regionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneRoundTripSwitch {
|
||||
OBSWeakSource scene1;
|
||||
OBSWeakSource scene2;
|
||||
OBSWeakSource transition;
|
||||
double delay;
|
||||
bool usePreviousScene;
|
||||
std::string sceneRoundTripStr;
|
||||
|
||||
inline SceneRoundTripSwitch(OBSWeakSource scene1_,
|
||||
OBSWeakSource scene2_,
|
||||
OBSWeakSource transition_, double delay_,
|
||||
bool usePreviousScene_, std::string str)
|
||||
: scene1(scene1_),
|
||||
scene2(scene2_),
|
||||
transition(transition_),
|
||||
delay(delay_),
|
||||
usePreviousScene(usePreviousScene_),
|
||||
sceneRoundTripStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct RandomSwitch {
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
double delay;
|
||||
std::string randomSwitchStr;
|
||||
|
||||
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
double delay_, std::string str)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
delay(delay_),
|
||||
randomSwitchStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SceneTransition {
|
||||
OBSWeakSource scene1;
|
||||
OBSWeakSource scene2;
|
||||
OBSWeakSource transition;
|
||||
std::string sceneTransitionStr;
|
||||
|
||||
inline SceneTransition(OBSWeakSource scene1_, OBSWeakSource scene2_,
|
||||
OBSWeakSource transition_,
|
||||
std::string sceneTransitionStr_)
|
||||
: scene1(scene1_),
|
||||
scene2(scene2_),
|
||||
transition(transition_),
|
||||
sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct DefaultSceneTransition {
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
std::string sceneTransitionStr;
|
||||
|
||||
inline DefaultSceneTransition(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_,
|
||||
std::string sceneTransitionStr_)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
sceneTransitionStr(sceneTransitionStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct FileSwitch {
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
std::string file;
|
||||
std::string text;
|
||||
bool remote = false;
|
||||
bool useRegex = false;
|
||||
bool useTime = false;
|
||||
QDateTime lastMod;
|
||||
|
||||
inline FileSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
const char *file_, const char *text_, bool remote_,
|
||||
bool useRegex_, bool useTime_)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
file(file_),
|
||||
text(text_),
|
||||
remote(remote_),
|
||||
useRegex(useRegex_),
|
||||
useTime(useTime_),
|
||||
lastMod()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct FileIOData {
|
||||
bool readEnabled = false;
|
||||
std::string readPath;
|
||||
bool writeEnabled = false;
|
||||
std::string writePath;
|
||||
};
|
||||
|
||||
struct IdleData {
|
||||
bool idleEnable = false;
|
||||
int time = default_idle_time;
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
bool usePreviousScene;
|
||||
bool alreadySwitched = false;
|
||||
};
|
||||
|
||||
struct MediaSwitch {
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource source;
|
||||
OBSWeakSource transition;
|
||||
obs_media_state state;
|
||||
int64_t time;
|
||||
time_restriction restriction;
|
||||
bool matched;
|
||||
bool usePreviousScene;
|
||||
std::string mediaSwitchStr;
|
||||
|
||||
inline MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
|
||||
OBSWeakSource transition_, obs_media_state state_,
|
||||
time_restriction restriction_, uint64_t time_,
|
||||
bool usePreviousScene_, std::string mediaSwitchStr_)
|
||||
: scene(scene_),
|
||||
source(source_),
|
||||
transition(transition_),
|
||||
state(state_),
|
||||
restriction(restriction_),
|
||||
time(time_),
|
||||
usePreviousScene(usePreviousScene_),
|
||||
mediaSwitchStr(mediaSwitchStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct TimeSwitch {
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource transition;
|
||||
timeTrigger trigger;
|
||||
QTime time;
|
||||
bool usePreviousScene;
|
||||
std::string timeSwitchStr;
|
||||
|
||||
inline TimeSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
timeTrigger trigger_, QTime time_,
|
||||
bool usePreviousScene_, std::string timeSwitchStr_)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
trigger(trigger_),
|
||||
time(time_),
|
||||
usePreviousScene(usePreviousScene_),
|
||||
timeSwitchStr(timeSwitchStr_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct AudioSwitch {
|
||||
OBSWeakSource scene;
|
||||
OBSWeakSource audioSource;
|
||||
OBSWeakSource transition;
|
||||
int volumeThreshold;
|
||||
float peak;
|
||||
bool usePreviousScene;
|
||||
obs_volmeter_t *volmeter;
|
||||
std::string audioSwitchStr;
|
||||
|
||||
static void setVolumeLevel(void *data,
|
||||
const float magnitude[MAX_AUDIO_CHANNELS],
|
||||
const float peak[MAX_AUDIO_CHANNELS],
|
||||
const float inputPeak[MAX_AUDIO_CHANNELS])
|
||||
{
|
||||
UNUSED_PARAMETER(magnitude);
|
||||
UNUSED_PARAMETER(inputPeak);
|
||||
AudioSwitch *s = static_cast<AudioSwitch *>(data);
|
||||
|
||||
s->peak = peak[0];
|
||||
for (int i = 1; i < MAX_AUDIO_CHANNELS; i++)
|
||||
if (peak[i] > s->peak)
|
||||
s->peak = peak[i];
|
||||
}
|
||||
|
||||
inline AudioSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
OBSWeakSource audioSource_, int volumeThreshold_,
|
||||
bool usePreviousScene_, std::string audioSwitchStr_)
|
||||
: scene(scene_),
|
||||
transition(transition_),
|
||||
audioSource(audioSource_),
|
||||
volumeThreshold(volumeThreshold_),
|
||||
usePreviousScene(usePreviousScene_),
|
||||
audioSwitchStr(audioSwitchStr_)
|
||||
{
|
||||
volmeter = obs_volmeter_create(OBS_FADER_LOG);
|
||||
obs_volmeter_add_callback(volmeter, setVolumeLevel, this);
|
||||
obs_source_t *as = obs_weak_source_get_source(audioSource);
|
||||
if (!obs_volmeter_attach_source(volmeter, as)) {
|
||||
const char *name = obs_source_get_name(as);
|
||||
blog(LOG_WARNING,
|
||||
"failed to attach volmeter to source %s", name);
|
||||
}
|
||||
obs_source_release(as);
|
||||
}
|
||||
|
||||
AudioSwitch(const AudioSwitch &other)
|
||||
: scene(other.scene),
|
||||
transition(other.transition),
|
||||
audioSource(other.audioSource),
|
||||
volumeThreshold(other.volumeThreshold),
|
||||
usePreviousScene(other.usePreviousScene),
|
||||
audioSwitchStr(other.audioSwitchStr)
|
||||
{
|
||||
volmeter = obs_volmeter_create(OBS_FADER_LOG);
|
||||
obs_volmeter_add_callback(volmeter, setVolumeLevel, this);
|
||||
obs_source_t *as =
|
||||
obs_weak_source_get_source(other.audioSource);
|
||||
if (!obs_volmeter_attach_source(volmeter, as)) {
|
||||
const char *name = obs_source_get_name(as);
|
||||
blog(LOG_WARNING,
|
||||
"failed to attach volmeter to source %s", name);
|
||||
}
|
||||
obs_source_release(as);
|
||||
}
|
||||
|
||||
AudioSwitch(AudioSwitch &&other)
|
||||
: scene(other.scene),
|
||||
transition(other.transition),
|
||||
audioSource(other.audioSource),
|
||||
volumeThreshold(other.volumeThreshold),
|
||||
usePreviousScene(other.usePreviousScene),
|
||||
audioSwitchStr(other.audioSwitchStr),
|
||||
volmeter(other.volmeter)
|
||||
{
|
||||
other.volmeter = nullptr;
|
||||
}
|
||||
|
||||
inline ~AudioSwitch()
|
||||
{
|
||||
obs_volmeter_remove_callback(volmeter, setVolumeLevel, this);
|
||||
obs_volmeter_destroy(volmeter);
|
||||
}
|
||||
|
||||
AudioSwitch &operator=(const AudioSwitch &other)
|
||||
{
|
||||
return *this = AudioSwitch(other);
|
||||
}
|
||||
|
||||
AudioSwitch &operator=(AudioSwitch &&other) noexcept
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
obs_volmeter_destroy(volmeter);
|
||||
volmeter = other.volmeter;
|
||||
other.volmeter = nullptr;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
typedef enum { NO_SWITCH = 0, SWITCH = 1, RANDOM_SWITCH = 2 } NoMatch;
|
||||
typedef enum { PERSIST = 0, START = 1, STOP = 2 } StartupBehavior;
|
||||
typedef enum {
|
||||
@@ -384,7 +49,7 @@ struct SwitcherData {
|
||||
|
||||
int interval = default_interval;
|
||||
|
||||
obs_source_t *waitScene = NULL; //scene during which wait started
|
||||
obs_source_t *waitScene = NULL;
|
||||
OBSWeakSource previousScene = NULL;
|
||||
OBSWeakSource PreviousScene2 = NULL;
|
||||
OBSWeakSource lastRandomScene;
|
||||
@@ -404,8 +69,8 @@ struct SwitcherData {
|
||||
|
||||
std::vector<std::string> ignoreWindowsSwitches;
|
||||
|
||||
std::vector<SceneRoundTripSwitch> sceneRoundTripSwitches;
|
||||
int sceneRoundTripUnitMultiplier = 1;
|
||||
std::vector<SceneSequenceSwitch> sceneSequenceSwitches;
|
||||
int sceneSequenceMultiplier = 1;
|
||||
|
||||
std::vector<RandomSwitch> randomSwitches;
|
||||
|
||||
@@ -479,7 +144,7 @@ struct SwitcherData {
|
||||
void autoStopStreamAndRecording();
|
||||
void autoStartStreamRecording();
|
||||
bool checkPause();
|
||||
void checkSceneRoundTrip(bool &match, OBSWeakSource &scene,
|
||||
void checkSceneSequence(bool &match, OBSWeakSource &scene,
|
||||
OBSWeakSource &transition,
|
||||
std::unique_lock<std::mutex> &lock);
|
||||
void checkIdleSwitch(bool &match, OBSWeakSource &scene,
|
||||
@@ -506,7 +171,7 @@ struct SwitcherData {
|
||||
void saveWindowTitleSwitches(obs_data_t *obj);
|
||||
void saveScreenRegionSwitches(obs_data_t *obj);
|
||||
void savePauseSwitches(obs_data_t *obj);
|
||||
void saveSceneRoundTripSwitches(obs_data_t *obj);
|
||||
void saveSceneSequenceSwitches(obs_data_t *obj);
|
||||
void saveSceneTransitions(obs_data_t *obj);
|
||||
void saveIdleSwitches(obs_data_t *obj);
|
||||
void saveExecutableSwitches(obs_data_t *obj);
|
||||
@@ -520,7 +185,7 @@ struct SwitcherData {
|
||||
void loadWindowTitleSwitches(obs_data_t *obj);
|
||||
void loadScreenRegionSwitches(obs_data_t *obj);
|
||||
void loadPauseSwitches(obs_data_t *obj);
|
||||
void loadSceneRoundTripSwitches(obs_data_t *obj);
|
||||
void loadSceneSequenceSwitches(obs_data_t *obj);
|
||||
void loadSceneTransitions(obs_data_t *obj);
|
||||
void loadIdleSwitches(obs_data_t *obj);
|
||||
void loadExecutableSwitches(obs_data_t *obj);
|
||||
@@ -531,124 +196,7 @@ struct SwitcherData {
|
||||
void loadAudioSwitches(obs_data_t *obj);
|
||||
void loadGeneralSettings(obs_data_t *obj);
|
||||
|
||||
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) ||
|
||||
(!s.usePreviousScene &&
|
||||
!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--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < timeSwitches.size(); i++) {
|
||||
TimeSwitch &s = timeSwitches[i];
|
||||
if ((!s.usePreviousScene &&
|
||||
!WeakSourceValid(s.scene)) ||
|
||||
!WeakSourceValid(s.transition))
|
||||
timeSwitches.erase(timeSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!idleData.usePreviousScene &&
|
||||
!WeakSourceValid(idleData.scene) ||
|
||||
!WeakSourceValid(idleData.transition)) {
|
||||
idleData.idleEnable = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mediaSwitches.size(); i++) {
|
||||
MediaSwitch &s = mediaSwitches[i];
|
||||
if ((!s.usePreviousScene &&
|
||||
!WeakSourceValid(s.scene)) ||
|
||||
!WeakSourceValid(s.source) ||
|
||||
!WeakSourceValid(s.transition))
|
||||
mediaSwitches.erase(mediaSwitches.begin() +
|
||||
i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < audioSwitches.size(); i++) {
|
||||
AudioSwitch &s = audioSwitches[i];
|
||||
if ((!s.usePreviousScene &&
|
||||
!WeakSourceValid(s.scene)) ||
|
||||
!WeakSourceValid(s.transition))
|
||||
audioSwitches.erase(audioSwitches.begin() +
|
||||
i--);
|
||||
}
|
||||
}
|
||||
void Prune();
|
||||
inline ~SwitcherData() { Stop(); }
|
||||
};
|
||||
|
||||
|
||||
44
src/headers/swtich-sequence.hpp
Normal file
44
src/headers/swtich-sequence.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "utility.hpp"
|
||||
#include "switch-generic.hpp"
|
||||
|
||||
constexpr auto round_trip_func = 1;
|
||||
constexpr auto default_priority_1 = round_trip_func;
|
||||
|
||||
struct SceneSequenceSwitch : SceneSwitcherEntry {
|
||||
OBSWeakSource startScene;
|
||||
double delay;
|
||||
std::string sceneSequenceStr;
|
||||
|
||||
const char *getType() { return "sequence"; }
|
||||
|
||||
bool valid()
|
||||
{
|
||||
return WeakSourceValid(startScene) &&
|
||||
(usePreviousScene || WeakSourceValid(scene)) &&
|
||||
WeakSourceValid(transition);
|
||||
}
|
||||
|
||||
void logSleep(int dur)
|
||||
{
|
||||
blog(LOG_INFO, "Advanced Scene Switcher sequence sleep %d",
|
||||
dur);
|
||||
}
|
||||
|
||||
inline SceneSequenceSwitch(OBSWeakSource startScene_,
|
||||
OBSWeakSource scene_,
|
||||
OBSWeakSource transition_, double delay_,
|
||||
bool usePreviousScene_, std::string str)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
startScene(startScene_),
|
||||
delay(delay_),
|
||||
sceneSequenceStr(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static inline QString MakeSceneSequenceSwitchName(const QString &scene1,
|
||||
const QString &scene2,
|
||||
const QString &transition,
|
||||
double delay);
|
||||
@@ -11,232 +11,6 @@ static inline bool WeakSourceValid(obs_weak_source_t *ws)
|
||||
return !!source;
|
||||
}
|
||||
|
||||
static inline QString MakeSwitchName(const QString &scene, const QString &value,
|
||||
const QString &transition, bool fullscreen,
|
||||
bool focus)
|
||||
{
|
||||
QString name = QStringLiteral("[") + scene + QStringLiteral(", ") +
|
||||
transition + QStringLiteral("]: ") + value;
|
||||
|
||||
if (fullscreen || focus) {
|
||||
name += QStringLiteral(" (only if");
|
||||
|
||||
if (fullscreen)
|
||||
name += QStringLiteral(" fullscreen");
|
||||
if (fullscreen && focus)
|
||||
name += QStringLiteral(" and");
|
||||
if (focus)
|
||||
name += QStringLiteral(" focused");
|
||||
|
||||
name += QStringLiteral(")");
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
TIME_RESTRICTION_NONE,
|
||||
TIME_RESTRICTION_SHORTER,
|
||||
TIME_RESTRICTION_LONGER,
|
||||
TIME_RESTRICTION_REMAINING_SHORTER,
|
||||
TIME_RESTRICTION_REMAINING_LONGER,
|
||||
} time_restriction;
|
||||
|
||||
static inline QString
|
||||
MakeMediaSwitchName(const QString &source, const QString &scene,
|
||||
const QString &transition, obs_media_state state,
|
||||
time_restriction restriction, uint64_t time)
|
||||
{
|
||||
QString switchName = QStringLiteral("Switch to ") + scene +
|
||||
QStringLiteral(" using ") + transition +
|
||||
QStringLiteral(" if ") + source +
|
||||
QStringLiteral(" state is ");
|
||||
if (state == OBS_MEDIA_STATE_NONE) {
|
||||
switchName += QStringLiteral("none");
|
||||
} else if (state == OBS_MEDIA_STATE_PLAYING) {
|
||||
switchName += QStringLiteral("playing");
|
||||
} else if (state == OBS_MEDIA_STATE_OPENING) {
|
||||
switchName += QStringLiteral("opening");
|
||||
} else if (state == OBS_MEDIA_STATE_BUFFERING) {
|
||||
switchName += QStringLiteral("buffering");
|
||||
} else if (state == OBS_MEDIA_STATE_PAUSED) {
|
||||
switchName += QStringLiteral("paused");
|
||||
} else if (state == OBS_MEDIA_STATE_STOPPED) {
|
||||
switchName += QStringLiteral("stopped");
|
||||
} else if (state == OBS_MEDIA_STATE_ENDED) {
|
||||
switchName += QStringLiteral("ended");
|
||||
} else if (state == OBS_MEDIA_STATE_ERROR) {
|
||||
switchName += QStringLiteral("error");
|
||||
}
|
||||
if (restriction == TIME_RESTRICTION_SHORTER) {
|
||||
switchName += QStringLiteral(" and time shorter than ");
|
||||
} else if (restriction == TIME_RESTRICTION_LONGER) {
|
||||
switchName += QStringLiteral(" and time longer than ");
|
||||
} else if (restriction == TIME_RESTRICTION_REMAINING_SHORTER) {
|
||||
switchName +=
|
||||
QStringLiteral(" and time remaining shorter than ");
|
||||
} else if (restriction == TIME_RESTRICTION_REMAINING_LONGER) {
|
||||
switchName +=
|
||||
QStringLiteral(" and time remaining longer than ");
|
||||
}
|
||||
if (restriction != TIME_RESTRICTION_NONE) {
|
||||
switchName += std::to_string(time).c_str();
|
||||
switchName += QStringLiteral(" ms");
|
||||
}
|
||||
return switchName;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
ANY_DAY = 0,
|
||||
MONDAY = 1,
|
||||
TUSEDAY = 2,
|
||||
WEDNESDAY = 3,
|
||||
THURSDAY = 4,
|
||||
FRIDAY = 5,
|
||||
SATURDAY = 6,
|
||||
SUNDAY = 7,
|
||||
LIVE = 8
|
||||
} timeTrigger;
|
||||
|
||||
static inline QString MakeTimeSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
const timeTrigger &trigger,
|
||||
const QTime &time)
|
||||
{
|
||||
QString switchName;
|
||||
|
||||
switch (trigger) {
|
||||
case ANY_DAY:
|
||||
switchName = QStringLiteral("On any weekday");
|
||||
break;
|
||||
case MONDAY:
|
||||
switchName = QStringLiteral("Mondays");
|
||||
break;
|
||||
case TUSEDAY:
|
||||
switchName = QStringLiteral("Tusedays");
|
||||
break;
|
||||
case WEDNESDAY:
|
||||
switchName = QStringLiteral("Wednesdays");
|
||||
break;
|
||||
case THURSDAY:
|
||||
switchName = QStringLiteral("Thursdays");
|
||||
break;
|
||||
case FRIDAY:
|
||||
switchName = QStringLiteral("Fridays");
|
||||
break;
|
||||
case SATURDAY:
|
||||
switchName = QStringLiteral("Saturdays");
|
||||
break;
|
||||
case SUNDAY:
|
||||
switchName = QStringLiteral("Sundays");
|
||||
break;
|
||||
case LIVE:
|
||||
switchName = QStringLiteral(
|
||||
"Relative to starting streaming / recording");
|
||||
break;
|
||||
}
|
||||
switchName += QStringLiteral(" at ") + time.toString() +
|
||||
QStringLiteral(" switch to ") + scene +
|
||||
QStringLiteral(" using ") + transition;
|
||||
return switchName;
|
||||
}
|
||||
|
||||
static inline QString MakeAudioSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
const QString &audioSrouce,
|
||||
const int &volume)
|
||||
{
|
||||
QString switchName = QStringLiteral("When volume of ") + audioSrouce +
|
||||
QStringLiteral(" is above ") +
|
||||
QString::number(volume) +
|
||||
QStringLiteral("% switch to ") + scene +
|
||||
QStringLiteral(" using ") + transition;
|
||||
return switchName;
|
||||
}
|
||||
|
||||
static inline std::string GetWeakSourceName(obs_weak_source_t *weak_source)
|
||||
{
|
||||
std::string name;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include <obs-module.h>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
void startHotkeyFunc(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey,
|
||||
|
||||
@@ -247,6 +247,55 @@ std::pair<int, int> getCursorPos()
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool isMaximized(std::string &title)
|
||||
{
|
||||
if (!ewmhIsSupported())
|
||||
return false;
|
||||
|
||||
// Find switch in top level windows
|
||||
std::vector<Window> windows = getTopLevelWindows();
|
||||
for (auto &window : windows) {
|
||||
XTextProperty text;
|
||||
int status = XGetTextProperty(
|
||||
disp(), window, &text,
|
||||
XInternAtom(disp(), "_NET_WM_NAME", true));
|
||||
if (status == 0)
|
||||
status = XGetTextProperty(disp(), window, &text,
|
||||
XInternAtom(disp(), "WM_NAME",
|
||||
true));
|
||||
char *name = reinterpret_cast<char *>(text.value);
|
||||
|
||||
if (status == 0 || name == nullptr)
|
||||
continue;
|
||||
|
||||
// True if switch equals window
|
||||
bool equals = (title == name);
|
||||
// True if switch matches window
|
||||
bool matches = QString::fromStdString(name).contains(
|
||||
QRegularExpression(QString::fromStdString(title)));
|
||||
|
||||
// If found, check if switch is maximized
|
||||
if (equals || matches) {
|
||||
QStringList states = getStates(window);
|
||||
|
||||
if (!states.isEmpty()) {
|
||||
// True if window is maximized vertically
|
||||
bool vertical = states.contains(
|
||||
"_NET_WM_STATE_MAXIMIZED_VERT");
|
||||
// True if window is maximized horizontally
|
||||
bool horizontal = states.contains(
|
||||
"_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
|
||||
return (vertical && horizontal);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isFullscreen(std::string &title)
|
||||
{
|
||||
if (!ewmhIsSupported())
|
||||
@@ -282,14 +331,8 @@ bool isFullscreen(std::string &title)
|
||||
// True if window is fullscreen
|
||||
bool fullscreen = states.contains(
|
||||
"_NET_WM_STATE_FULLSCREEN");
|
||||
// True if window is maximized vertically
|
||||
bool vertical = states.contains(
|
||||
"_NET_WM_STATE_MAXIMIZED_VERT");
|
||||
// True if window is maximized horizontally
|
||||
bool horizontal = states.contains(
|
||||
"_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||
|
||||
return (fullscreen || (vertical && horizontal));
|
||||
return (fullscreen);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -343,4 +386,4 @@ int secondsSinceLastInput()
|
||||
XCloseDisplay(display);
|
||||
|
||||
return idle_time;
|
||||
}
|
||||
}
|
||||
@@ -126,6 +126,13 @@ std::pair<int, int> getCursorPos()
|
||||
return pos;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// not implemented on MacOS as I cannot test it
|
||||
bool isMaximized(std::string &title)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isFullscreen(std::string &title)
|
||||
{
|
||||
// Check for match
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
#include "headers/volume-control.hpp"
|
||||
|
||||
void SceneSwitcher::on_audioSwitches_currentRowChanged(int idx)
|
||||
@@ -193,7 +192,6 @@ void SwitcherData::checkAudioSwitch(bool &match, OBSWeakSource &scene,
|
||||
|
||||
for (AudioSwitch &s : audioSwitches) {
|
||||
obs_source_t *as = obs_weak_source_get_source(s.audioSource);
|
||||
const char *name = obs_source_get_name(as);
|
||||
bool audioActive = obs_source_active(as);
|
||||
obs_source_release(as);
|
||||
|
||||
@@ -207,10 +205,7 @@ void SwitcherData::checkAudioSwitch(bool &match, OBSWeakSource &scene,
|
||||
match = true;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher audio match for %s",
|
||||
name);
|
||||
|
||||
s.logMatch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -325,3 +320,16 @@ void SceneSwitcher::setupAudioTab()
|
||||
item->setData(Qt::UserRole, listText);
|
||||
}
|
||||
}
|
||||
|
||||
static inline QString MakeAudioSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
const QString &audioSrouce,
|
||||
const int &volume)
|
||||
{
|
||||
QString switchName = QStringLiteral("When volume of ") + audioSrouce +
|
||||
QStringLiteral(" is above ") +
|
||||
QString::number(volume) +
|
||||
QStringLiteral("% switch to ") + scene +
|
||||
QStringLiteral(" using ") + transition;
|
||||
return switchName;
|
||||
}
|
||||
@@ -28,15 +28,15 @@ void SceneSwitcher::on_executables_currentRowChanged(int idx)
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
for (auto &s : switcher->executableSwitches) {
|
||||
if (exec.compare(s.mExe) == 0) {
|
||||
QString sceneName = GetWeakSourceName(s.mScene).c_str();
|
||||
if (exec.compare(s.exe) == 0) {
|
||||
QString sceneName = GetWeakSourceName(s.scene).c_str();
|
||||
QString transitionName =
|
||||
GetWeakSourceName(s.mTransition).c_str();
|
||||
GetWeakSourceName(s.transition).c_str();
|
||||
ui->executableScenes->setCurrentText(sceneName);
|
||||
ui->executable->setCurrentText(exec);
|
||||
ui->executableTransitions->setCurrentText(
|
||||
transitionName);
|
||||
ui->requiresFocusCheckBox->setChecked(s.mInFocus);
|
||||
ui->requiresFocusCheckBox->setChecked(s.inFocus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -107,10 +107,10 @@ void SceneSwitcher::on_executableAdd_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
for (auto &s : switcher->executableSwitches) {
|
||||
if (s.mExe == exeName) {
|
||||
s.mScene = source;
|
||||
s.mTransition = transition;
|
||||
s.mInFocus = inFocus;
|
||||
if (s.exe == exeName) {
|
||||
s.scene = source;
|
||||
s.transition = transition;
|
||||
s.inFocus = inFocus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ void SceneSwitcher::on_executableRemove_clicked()
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it) {
|
||||
auto &s = *it;
|
||||
|
||||
if (s.mExe == exe) {
|
||||
if (s.exe == exe) {
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
@@ -172,27 +172,25 @@ void SwitcherData::checkExeSwitch(bool &match, OBSWeakSource &scene,
|
||||
GetProcessList(runningProcesses);
|
||||
for (ExecutableSceneSwitch &s : executableSwitches) {
|
||||
// True if executable switch is running (direct)
|
||||
bool equals = runningProcesses.contains(s.mExe);
|
||||
bool equals = runningProcesses.contains(s.exe);
|
||||
// True if executable switch is running (regex)
|
||||
bool matches = (runningProcesses.indexOf(
|
||||
QRegularExpression(s.mExe)) != -1);
|
||||
QRegularExpression(s.exe)) != -1);
|
||||
// True if focus is disabled OR switch is focused
|
||||
bool focus = (!s.mInFocus || isInFocus(s.mExe));
|
||||
bool focus = (!s.inFocus || isInFocus(s.exe));
|
||||
// True if current window is ignored AND switch equals OR matches last window
|
||||
bool ignore =
|
||||
(ignored && (title == s.mExe.toStdString() ||
|
||||
(ignored && (title == s.exe.toStdString() ||
|
||||
QString::fromStdString(title).contains(
|
||||
QRegularExpression(s.mExe))));
|
||||
QRegularExpression(s.exe))));
|
||||
|
||||
if ((equals || matches) && (focus || ignore)) {
|
||||
match = true;
|
||||
scene = s.mScene;
|
||||
transition = s.mTransition;
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher exec match");
|
||||
|
||||
s.logMatch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -204,9 +202,9 @@ void SwitcherData::saveExecutableSwitches(obs_data_t *obj)
|
||||
for (ExecutableSceneSwitch &s : switcher->executableSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s.mScene);
|
||||
obs_source_t *source = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.mTransition);
|
||||
obs_weak_source_get_source(s.transition);
|
||||
|
||||
if (source && transition) {
|
||||
const char *sceneName = obs_source_get_name(source);
|
||||
@@ -216,8 +214,8 @@ void SwitcherData::saveExecutableSwitches(obs_data_t *obj)
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_string(array_obj, "exefile",
|
||||
s.mExe.toUtf8());
|
||||
obs_data_set_bool(array_obj, "infocus", s.mInFocus);
|
||||
s.exe.toUtf8());
|
||||
obs_data_set_bool(array_obj, "infocus", s.inFocus);
|
||||
obs_data_array_push_back(executableArray, array_obj);
|
||||
obs_source_release(source);
|
||||
obs_source_release(transition);
|
||||
@@ -266,15 +264,28 @@ void SceneSwitcher::setupExecutableTab()
|
||||
ui->executable->addItem(process);
|
||||
|
||||
for (auto &s : switcher->executableSwitches) {
|
||||
std::string sceneName = GetWeakSourceName(s.mScene);
|
||||
std::string transitionName = GetWeakSourceName(s.mTransition);
|
||||
std::string sceneName = GetWeakSourceName(s.scene);
|
||||
std::string transitionName = GetWeakSourceName(s.transition);
|
||||
QString text = MakeSwitchNameExecutable(sceneName.c_str(),
|
||||
s.mExe,
|
||||
s.exe,
|
||||
transitionName.c_str(),
|
||||
s.mInFocus);
|
||||
s.inFocus);
|
||||
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(text, ui->executables);
|
||||
item->setData(Qt::UserRole, s.mExe);
|
||||
item->setData(Qt::UserRole, s.exe);
|
||||
}
|
||||
}
|
||||
|
||||
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 focused)");
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <QDateTime>
|
||||
#include <obs.hpp>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
@@ -129,7 +128,8 @@ std::string getRemoteData(std::string &url)
|
||||
|
||||
if (switcher->curl && f_curl_setopt && f_curl_perform) {
|
||||
f_curl_setopt(switcher->curl, CURLOPT_URL, url.c_str());
|
||||
f_curl_setopt(switcher->curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
f_curl_setopt(switcher->curl, CURLOPT_WRITEFUNCTION,
|
||||
WriteCallback);
|
||||
f_curl_setopt(switcher->curl, CURLOPT_WRITEDATA, &readBuffer);
|
||||
f_curl_perform(switcher->curl);
|
||||
}
|
||||
@@ -217,9 +217,7 @@ void SwitcherData::checkFileContent(bool &match, OBSWeakSource &scene,
|
||||
match = true;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher file match");
|
||||
|
||||
s.logMatch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -310,7 +308,7 @@ void SceneSwitcher::on_fileScenesList_currentRowChanged(int idx)
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
if (switcher->fileSwitches.size() <= idx)
|
||||
if ((int)switcher->fileSwitches.size() <= idx)
|
||||
return;
|
||||
FileSwitch s = switcher->fileSwitches[idx];
|
||||
|
||||
@@ -473,3 +471,27 @@ void SceneSwitcher::setupFileTab()
|
||||
ui->readPathLineEdit->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <regex>
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
void SwitcherData::checkIdleSwitch(bool &match, OBSWeakSource &scene,
|
||||
@@ -43,7 +45,7 @@ void SwitcherData::checkIdleSwitch(bool &match, OBSWeakSource &scene,
|
||||
idleData.alreadySwitched = true;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO, "Advanced Scene Switcher idle match");
|
||||
idleData.logMatch();
|
||||
} else
|
||||
idleData.alreadySwitched = false;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <obs-module.h>
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_mediaSwitches_currentRowChanged(int idx)
|
||||
@@ -167,8 +166,7 @@ void SwitcherData::checkMediaSwitch(bool &match, OBSWeakSource &scene,
|
||||
transition = mediaSwitch.transition;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher meida match");
|
||||
mediaSwitch.logMatch();
|
||||
}
|
||||
mediaSwitch.matched = matched;
|
||||
obs_source_release(source);
|
||||
@@ -299,3 +297,47 @@ void SceneSwitcher::setupMediaTab()
|
||||
item->setData(Qt::UserRole, listText);
|
||||
}
|
||||
}
|
||||
|
||||
static inline QString
|
||||
MakeMediaSwitchName(const QString &source, const QString &scene,
|
||||
const QString &transition, obs_media_state state,
|
||||
time_restriction restriction, uint64_t time)
|
||||
{
|
||||
QString switchName = QStringLiteral("Switch to ") + scene +
|
||||
QStringLiteral(" using ") + transition +
|
||||
QStringLiteral(" if ") + source +
|
||||
QStringLiteral(" state is ");
|
||||
if (state == OBS_MEDIA_STATE_NONE) {
|
||||
switchName += QStringLiteral("none");
|
||||
} else if (state == OBS_MEDIA_STATE_PLAYING) {
|
||||
switchName += QStringLiteral("playing");
|
||||
} else if (state == OBS_MEDIA_STATE_OPENING) {
|
||||
switchName += QStringLiteral("opening");
|
||||
} else if (state == OBS_MEDIA_STATE_BUFFERING) {
|
||||
switchName += QStringLiteral("buffering");
|
||||
} else if (state == OBS_MEDIA_STATE_PAUSED) {
|
||||
switchName += QStringLiteral("paused");
|
||||
} else if (state == OBS_MEDIA_STATE_STOPPED) {
|
||||
switchName += QStringLiteral("stopped");
|
||||
} else if (state == OBS_MEDIA_STATE_ENDED) {
|
||||
switchName += QStringLiteral("ended");
|
||||
} else if (state == OBS_MEDIA_STATE_ERROR) {
|
||||
switchName += QStringLiteral("error");
|
||||
}
|
||||
if (restriction == TIME_RESTRICTION_SHORTER) {
|
||||
switchName += QStringLiteral(" and time shorter than ");
|
||||
} else if (restriction == TIME_RESTRICTION_LONGER) {
|
||||
switchName += QStringLiteral(" and time longer than ");
|
||||
} else if (restriction == TIME_RESTRICTION_REMAINING_SHORTER) {
|
||||
switchName +=
|
||||
QStringLiteral(" and time remaining shorter than ");
|
||||
} else if (restriction == TIME_RESTRICTION_REMAINING_LONGER) {
|
||||
switchName +=
|
||||
QStringLiteral(" and time remaining longer than ");
|
||||
}
|
||||
if (restriction != TIME_RESTRICTION_NONE) {
|
||||
switchName += std::to_string(time).c_str();
|
||||
switchName += QStringLiteral(" ms");
|
||||
}
|
||||
return switchName;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <regex>
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_pauseScenesAdd_clicked()
|
||||
@@ -1,10 +1,11 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_threadPriority_currentTextChanged(const QString &text)
|
||||
{
|
||||
if (loading ||
|
||||
ui->threadPriority->count() != switcher->threadPriorities.size())
|
||||
if (loading || ui->threadPriority->count() !=
|
||||
(int)switcher->threadPriorities.size())
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include <random>
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
void SceneSwitcher::on_randomScenesList_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
@@ -134,8 +135,7 @@ void SwitcherData::checkRandom(bool &match, OBSWeakSource &scene,
|
||||
lastRandomScene = r.scene;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO, "Advanced Scene Switcher random match");
|
||||
|
||||
r.logMatch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -158,8 +158,6 @@ void SwitcherData::saveRandomSwitches(obs_data_t *obj)
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_double(array_obj, "delay", s.delay);
|
||||
obs_data_set_string(array_obj, "str",
|
||||
s.randomSwitchStr.c_str());
|
||||
obs_data_array_push_back(randomArray, array_obj);
|
||||
obs_source_release(source);
|
||||
obs_source_release(transition);
|
||||
@@ -186,11 +184,16 @@ void SwitcherData::loadRandomSwitches(obs_data_t *obj)
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
double delay = obs_data_get_double(array_obj, "delay");
|
||||
const char *str = obs_data_get_string(array_obj, "str");
|
||||
|
||||
std::string randomSwitchStr =
|
||||
MakeRandomSwitchName(scene, transition, delay)
|
||||
.toUtf8()
|
||||
.constData();
|
||||
|
||||
switcher->randomSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
GetWeakTransitionByName(transition), delay, str);
|
||||
GetWeakTransitionByName(transition), delay,
|
||||
randomSwitchStr);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
@@ -213,3 +216,12 @@ void SceneSwitcher::setupRandomTab()
|
||||
item->setData(Qt::UserRole, text);
|
||||
}
|
||||
}
|
||||
|
||||
static inline QString MakeRandomSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
double &delay)
|
||||
{
|
||||
return QStringLiteral("[") + scene + QStringLiteral(", ") + transition +
|
||||
QStringLiteral("]: ") + QString::number(delay) +
|
||||
QStringLiteral(" seconds");
|
||||
}
|
||||
@@ -19,9 +19,7 @@ void SwitcherData::checkScreenRegionSwitch(bool &match, OBSWeakSource &scene,
|
||||
minRegionSize = regionSize;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher region match");
|
||||
|
||||
s.logMatch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -213,8 +211,6 @@ void SwitcherData::saveScreenRegionSwitches(obs_data_t *obj)
|
||||
obs_data_set_int(array_obj, "minY", s.minY);
|
||||
obs_data_set_int(array_obj, "maxX", s.maxX);
|
||||
obs_data_set_int(array_obj, "maxY", s.maxY);
|
||||
obs_data_set_string(array_obj, "screenRegionStr",
|
||||
s.regionStr.c_str());
|
||||
obs_data_array_push_back(screenRegionArray, array_obj);
|
||||
obs_source_release(source);
|
||||
obs_source_release(transition);
|
||||
@@ -246,8 +242,12 @@ void SwitcherData::loadScreenRegionSwitches(obs_data_t *obj)
|
||||
int minY = obs_data_get_int(array_obj, "minY");
|
||||
int maxX = obs_data_get_int(array_obj, "maxX");
|
||||
int maxY = obs_data_get_int(array_obj, "maxY");
|
||||
|
||||
std::string regionStr =
|
||||
obs_data_get_string(array_obj, "screenRegionStr");
|
||||
MakeScreenRegionSwitchName(scene, transition, minX,
|
||||
minY, maxX, maxY)
|
||||
.toUtf8()
|
||||
.constData();
|
||||
|
||||
switcher->screenRegionSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
@@ -282,3 +282,15 @@ void SceneSwitcher::setupRegionTab()
|
||||
SLOT(updateScreenRegionCursorPos()));
|
||||
screenRegionTimer->start(1000);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,24 +1,23 @@
|
||||
#include <QFileDialog>
|
||||
#include <QTextStream>
|
||||
#include <QMessageBox>
|
||||
#include <obs.hpp>
|
||||
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
#define SECONDS_INDEX 0
|
||||
#define MINUTES_INDEX 1
|
||||
#define HOURS_INDEX 2
|
||||
constexpr auto seconds_index = 0;
|
||||
constexpr auto minutes_index = 1;
|
||||
constexpr auto hours_index = 2;
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripDelayUnits_currentIndexChanged(int index)
|
||||
void SceneSwitcher::on_sceneSequenceDelayUnits_currentIndexChanged(int index)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
double val = ui->sceneRoundTripSpinBox->value();
|
||||
double val = ui->sceneSequenceSpinBox->value();
|
||||
|
||||
switch (switcher->sceneRoundTripUnitMultiplier) {
|
||||
switch (switcher->sceneSequenceMultiplier) {
|
||||
case 1:
|
||||
val /= pow(60, index);
|
||||
break;
|
||||
@@ -30,32 +29,32 @@ void SceneSwitcher::on_sceneRoundTripDelayUnits_currentIndexChanged(int index)
|
||||
break;
|
||||
}
|
||||
|
||||
ui->sceneRoundTripSpinBox->setValue(val);
|
||||
ui->sceneSequenceSpinBox->setValue(val);
|
||||
|
||||
switch (index) {
|
||||
case SECONDS_INDEX:
|
||||
switcher->sceneRoundTripUnitMultiplier = 1;
|
||||
case seconds_index:
|
||||
switcher->sceneSequenceMultiplier = 1;
|
||||
break;
|
||||
case MINUTES_INDEX:
|
||||
switcher->sceneRoundTripUnitMultiplier = 60;
|
||||
case minutes_index:
|
||||
switcher->sceneSequenceMultiplier = 60;
|
||||
break;
|
||||
case HOURS_INDEX:
|
||||
switcher->sceneRoundTripUnitMultiplier = 3600;
|
||||
case hours_index:
|
||||
switcher->sceneSequenceMultiplier = 3600;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripAdd_clicked()
|
||||
void SceneSwitcher::on_sceneSequenceAdd_clicked()
|
||||
{
|
||||
QString scene1Name = ui->sceneRoundTripScenes1->currentText();
|
||||
QString scene2Name = ui->sceneRoundTripScenes2->currentText();
|
||||
QString transitionName = ui->sceneRoundTripTransitions->currentText();
|
||||
QString scene1Name = ui->sceneSequenceScenes1->currentText();
|
||||
QString scene2Name = ui->sceneSequenceScenes2->currentText();
|
||||
QString transitionName = ui->sceneSequenceTransitions->currentText();
|
||||
|
||||
if (scene1Name.isEmpty() || scene2Name.isEmpty())
|
||||
return;
|
||||
|
||||
double delay = ui->sceneRoundTripSpinBox->value() *
|
||||
switcher->sceneRoundTripUnitMultiplier;
|
||||
double delay = ui->sceneSequenceSpinBox->value() *
|
||||
switcher->sceneSequenceMultiplier;
|
||||
|
||||
if (scene1Name == scene2Name)
|
||||
return;
|
||||
@@ -64,37 +63,37 @@ void SceneSwitcher::on_sceneRoundTripAdd_clicked()
|
||||
OBSWeakSource source2 = GetWeakSourceByQString(scene2Name);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString text = MakeSceneRoundTripSwitchName(scene1Name, scene2Name,
|
||||
QString text = MakeSceneSequenceSwitchName(scene1Name, scene2Name,
|
||||
transitionName, delay);
|
||||
QVariant v = QVariant::fromValue(text);
|
||||
|
||||
int idx = SceneRoundTripFindByData(scene1Name);
|
||||
int idx = SceneSequenceFindByData(scene1Name);
|
||||
|
||||
if (idx == -1) {
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(text, ui->sceneRoundTrips);
|
||||
new QListWidgetItem(text, ui->sceneSequences);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->sceneRoundTripSwitches.emplace_back(
|
||||
switcher->sceneSequenceSwitches.emplace_back(
|
||||
source1, source2, transition, delay,
|
||||
(scene2Name == QString(previous_scene_name)),
|
||||
text.toUtf8().constData());
|
||||
} else {
|
||||
QListWidgetItem *item = ui->sceneRoundTrips->item(idx);
|
||||
QListWidgetItem *item = ui->sceneSequences->item(idx);
|
||||
item->setText(text);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
for (auto &s : switcher->sceneRoundTripSwitches) {
|
||||
if (s.scene1 == source1) {
|
||||
s.scene2 = source2;
|
||||
for (auto &s : switcher->sceneSequenceSwitches) {
|
||||
if (s.startScene == source1) {
|
||||
s.scene = source2;
|
||||
s.delay = delay;
|
||||
s.transition = transition;
|
||||
s.usePreviousScene =
|
||||
(scene2Name ==
|
||||
QString(previous_scene_name));
|
||||
s.sceneRoundTripStr =
|
||||
s.sceneSequenceStr =
|
||||
text.toUtf8().constData();
|
||||
break;
|
||||
}
|
||||
@@ -103,9 +102,9 @@ void SceneSwitcher::on_sceneRoundTripAdd_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripRemove_clicked()
|
||||
void SceneSwitcher::on_sceneSequenceRemove_clicked()
|
||||
{
|
||||
QListWidgetItem *item = ui->sceneRoundTrips->currentItem();
|
||||
QListWidgetItem *item = ui->sceneSequences->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
@@ -114,12 +113,12 @@ void SceneSwitcher::on_sceneRoundTripRemove_clicked()
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
auto &switches = switcher->sceneRoundTripSwitches;
|
||||
auto &switches = switcher->sceneSequenceSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it) {
|
||||
auto &s = *it;
|
||||
|
||||
if (s.sceneRoundTripStr == text) {
|
||||
if (s.sceneSequenceStr == text) {
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
@@ -129,10 +128,10 @@ void SceneSwitcher::on_sceneRoundTripRemove_clicked()
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripSave_clicked()
|
||||
void SceneSwitcher::on_sceneSequenceSave_clicked()
|
||||
{
|
||||
QString directory = QFileDialog::getSaveFileName(
|
||||
this, tr("Save Scene Round Trip to file ..."),
|
||||
this, tr("Save Scene Sequence to file ..."),
|
||||
QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (directory.isEmpty())
|
||||
return;
|
||||
@@ -141,7 +140,7 @@ void SceneSwitcher::on_sceneRoundTripSave_clicked()
|
||||
return;
|
||||
|
||||
obs_data_t *obj = obs_data_create();
|
||||
switcher->saveSceneRoundTripSwitches(obj);
|
||||
switcher->saveSceneSequenceSwitches(obj);
|
||||
obs_data_save_json(obj, file.fileName().toUtf8().constData());
|
||||
obs_data_release(obj);
|
||||
}
|
||||
@@ -152,7 +151,7 @@ bool oldSceneRoundTripLoad(QFile *file)
|
||||
QTextStream in(file);
|
||||
std::vector<QString> lines;
|
||||
|
||||
std::vector<SceneRoundTripSwitch> newSceneRoundTripSwitch;
|
||||
std::vector<SceneSequenceSwitch> newSceneRoundTripSwitch;
|
||||
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
@@ -168,7 +167,7 @@ bool oldSceneRoundTripLoad(QFile *file)
|
||||
(WeakSourceValid(scene2))) &&
|
||||
WeakSourceValid(transition)) {
|
||||
newSceneRoundTripSwitch.emplace_back(
|
||||
SceneRoundTripSwitch(
|
||||
SceneSequenceSwitch(
|
||||
GetWeakSourceByQString(lines[0]),
|
||||
GetWeakSourceByQString(lines[1]),
|
||||
GetWeakTransitionByQString(
|
||||
@@ -185,17 +184,17 @@ bool oldSceneRoundTripLoad(QFile *file)
|
||||
if (lines.size() != 0 || newSceneRoundTripSwitch.size() == 0)
|
||||
return false;
|
||||
|
||||
switcher->sceneRoundTripSwitches.clear();
|
||||
switcher->sceneRoundTripSwitches = newSceneRoundTripSwitch;
|
||||
switcher->sceneSequenceSwitches.clear();
|
||||
switcher->sceneSequenceSwitches = newSceneRoundTripSwitch;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripLoad_clicked()
|
||||
void SceneSwitcher::on_sceneSequenceLoad_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
QString directory = QFileDialog::getOpenFileName(
|
||||
this, tr("Select a file to read Scene Round Trip from ..."),
|
||||
this, tr("Select a file to read Scene Sequence from ..."),
|
||||
QDir::currentPath(), tr("Text files (*.txt)"));
|
||||
if (directory.isEmpty())
|
||||
return;
|
||||
@@ -228,7 +227,7 @@ void SceneSwitcher::on_sceneRoundTripLoad_clicked()
|
||||
}
|
||||
return;
|
||||
}
|
||||
switcher->loadSceneRoundTripSwitches(obj);
|
||||
switcher->loadSceneSequenceSwitches(obj);
|
||||
obs_data_release(obj);
|
||||
|
||||
QMessageBox Msgbox;
|
||||
@@ -238,25 +237,21 @@ void SceneSwitcher::on_sceneRoundTripLoad_clicked()
|
||||
close();
|
||||
}
|
||||
|
||||
void SwitcherData::checkSceneRoundTrip(bool &match, OBSWeakSource &scene,
|
||||
void SwitcherData::checkSceneSequence(bool &match, OBSWeakSource &scene,
|
||||
OBSWeakSource &transition,
|
||||
std::unique_lock<std::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;
|
||||
for (SceneSequenceSwitch &s : sceneSequenceSwitches) {
|
||||
if (s.startScene == ws) {
|
||||
int dur = s.delay * 1000 - interval;
|
||||
if (dur > 0) {
|
||||
waitScene = currentSource;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher sequence sleep %d",
|
||||
dur);
|
||||
s.logSleep(dur);
|
||||
|
||||
cv.wait_for(lock,
|
||||
std::chrono::milliseconds(dur));
|
||||
@@ -269,8 +264,10 @@ void SwitcherData::checkSceneRoundTrip(bool &match, OBSWeakSource &scene,
|
||||
if (currentSource == currentSource2) {
|
||||
match = true;
|
||||
scene = (s.usePreviousScene) ? previousScene
|
||||
: s.scene2;
|
||||
: s.scene;
|
||||
transition = s.transition;
|
||||
if (verbose)
|
||||
s.logMatch();
|
||||
}
|
||||
obs_source_release(currentSource2);
|
||||
break;
|
||||
@@ -280,46 +277,46 @@ void SwitcherData::checkSceneRoundTrip(bool &match, OBSWeakSource &scene,
|
||||
obs_weak_source_release(ws);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTrips_currentRowChanged(int idx)
|
||||
void SceneSwitcher::on_sceneSequences_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem *item = ui->sceneRoundTrips->item(idx);
|
||||
QListWidgetItem *item = ui->sceneSequences->item(idx);
|
||||
|
||||
QString sceneRoundTrip = item->text();
|
||||
QString sceneSequence = item->text();
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
for (auto &s : switcher->sceneRoundTripSwitches) {
|
||||
if (sceneRoundTrip.compare(s.sceneRoundTripStr.c_str()) == 0) {
|
||||
std::string scene1 = GetWeakSourceName(s.scene1);
|
||||
std::string scene2 = GetWeakSourceName(s.scene2);
|
||||
for (auto &s : switcher->sceneSequenceSwitches) {
|
||||
if (sceneSequence.compare(s.sceneSequenceStr.c_str()) == 0) {
|
||||
std::string scene1 = GetWeakSourceName(s.startScene);
|
||||
std::string scene2 = GetWeakSourceName(s.scene);
|
||||
std::string transitionName =
|
||||
GetWeakSourceName(s.transition);
|
||||
double delay = s.delay /
|
||||
switcher->sceneRoundTripUnitMultiplier;
|
||||
ui->sceneRoundTripScenes1->setCurrentText(
|
||||
switcher->sceneSequenceMultiplier;
|
||||
ui->sceneSequenceScenes1->setCurrentText(
|
||||
scene1.c_str());
|
||||
ui->sceneRoundTripScenes2->setCurrentText(
|
||||
ui->sceneSequenceScenes2->setCurrentText(
|
||||
scene2.c_str());
|
||||
ui->sceneRoundTripTransitions->setCurrentText(
|
||||
ui->sceneSequenceTransitions->setCurrentText(
|
||||
transitionName.c_str());
|
||||
ui->sceneRoundTripSpinBox->setValue(delay);
|
||||
ui->sceneSequenceSpinBox->setValue(delay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int SceneSwitcher::SceneRoundTripFindByData(const QString &scene1)
|
||||
int SceneSwitcher::SceneSequenceFindByData(const QString &scene1)
|
||||
{
|
||||
QRegExp rx(scene1 + " ->.*");
|
||||
int count = ui->sceneRoundTrips->count();
|
||||
int count = ui->sceneSequences->count();
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
QListWidgetItem *item = ui->sceneRoundTrips->item(i);
|
||||
QListWidgetItem *item = ui->sceneSequences->item(i);
|
||||
QString itemString = item->data(Qt::UserRole).toString();
|
||||
|
||||
if (rx.exactMatch(itemString)) {
|
||||
@@ -331,44 +328,45 @@ int SceneSwitcher::SceneRoundTripFindByData(const QString &scene1)
|
||||
return idx;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripUp_clicked()
|
||||
void SceneSwitcher::on_sceneSequenceUp_clicked()
|
||||
{
|
||||
int index = ui->sceneRoundTrips->currentRow();
|
||||
int index = ui->sceneSequences->currentRow();
|
||||
if (index != -1 && index != 0) {
|
||||
ui->sceneRoundTrips->insertItem(
|
||||
index - 1, ui->sceneRoundTrips->takeItem(index));
|
||||
ui->sceneRoundTrips->setCurrentRow(index - 1);
|
||||
ui->sceneSequences->insertItem(
|
||||
index - 1, ui->sceneSequences->takeItem(index));
|
||||
ui->sceneSequences->setCurrentRow(index - 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->sceneRoundTripSwitches.begin() + index,
|
||||
switcher->sceneRoundTripSwitches.begin() + index - 1);
|
||||
iter_swap(switcher->sceneSequenceSwitches.begin() + index,
|
||||
switcher->sceneSequenceSwitches.begin() + index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_sceneRoundTripDown_clicked()
|
||||
void SceneSwitcher::on_sceneSequenceDown_clicked()
|
||||
{
|
||||
int index = ui->sceneRoundTrips->currentRow();
|
||||
if (index != -1 && index != ui->sceneRoundTrips->count() - 1) {
|
||||
ui->sceneRoundTrips->insertItem(
|
||||
index + 1, ui->sceneRoundTrips->takeItem(index));
|
||||
ui->sceneRoundTrips->setCurrentRow(index + 1);
|
||||
int index = ui->sceneSequences->currentRow();
|
||||
if (index != -1 && index != ui->sceneSequences->count() - 1) {
|
||||
ui->sceneSequences->insertItem(
|
||||
index + 1, ui->sceneSequences->takeItem(index));
|
||||
ui->sceneSequences->setCurrentRow(index + 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->sceneRoundTripSwitches.begin() + index,
|
||||
switcher->sceneRoundTripSwitches.begin() + index + 1);
|
||||
iter_swap(switcher->sceneSequenceSwitches.begin() + index,
|
||||
switcher->sceneSequenceSwitches.begin() + index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::saveSceneRoundTripSwitches(obs_data_t *obj)
|
||||
void SwitcherData::saveSceneSequenceSwitches(obs_data_t *obj)
|
||||
{
|
||||
obs_data_array_t *sceneRoundTripArray = obs_data_array_create();
|
||||
for (SceneRoundTripSwitch &s : switcher->sceneRoundTripSwitches) {
|
||||
obs_data_array_t *sceneSequenceArray = obs_data_array_create();
|
||||
for (SceneSequenceSwitch &s : switcher->sceneSequenceSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source1 = obs_weak_source_get_source(s.scene1);
|
||||
obs_source_t *source2 = obs_weak_source_get_source(s.scene2);
|
||||
obs_source_t *source1 =
|
||||
obs_weak_source_get_source(s.startScene);
|
||||
obs_source_t *source2 = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
if (source1 && (s.usePreviousScene || source2) && transition) {
|
||||
@@ -385,9 +383,7 @@ void SwitcherData::saveSceneRoundTripSwitches(obs_data_t *obj)
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_double(array_obj, "delay", s.delay);
|
||||
obs_data_set_string(array_obj, "sceneRoundTripStr",
|
||||
s.sceneRoundTripStr.c_str());
|
||||
obs_data_array_push_back(sceneRoundTripArray,
|
||||
obs_data_array_push_back(sceneSequenceArray,
|
||||
array_obj);
|
||||
obs_source_release(source1);
|
||||
obs_source_release(source2);
|
||||
@@ -396,21 +392,21 @@ void SwitcherData::saveSceneRoundTripSwitches(obs_data_t *obj)
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "sceneRoundTrip", sceneRoundTripArray);
|
||||
obs_data_array_release(sceneRoundTripArray);
|
||||
obs_data_set_array(obj, "sceneRoundTrip", sceneSequenceArray);
|
||||
obs_data_array_release(sceneSequenceArray);
|
||||
}
|
||||
|
||||
void SwitcherData::loadSceneRoundTripSwitches(obs_data_t *obj)
|
||||
void SwitcherData::loadSceneSequenceSwitches(obs_data_t *obj)
|
||||
{
|
||||
switcher->sceneRoundTripSwitches.clear();
|
||||
switcher->sceneSequenceSwitches.clear();
|
||||
|
||||
obs_data_array_t *sceneRoundTripArray =
|
||||
obs_data_array_t *sceneSequenceArray =
|
||||
obs_data_get_array(obj, "sceneRoundTrip");
|
||||
size_t count = obs_data_array_count(sceneRoundTripArray);
|
||||
size_t count = obs_data_array_count(sceneSequenceArray);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj =
|
||||
obs_data_array_item(sceneRoundTripArray, i);
|
||||
obs_data_array_item(sceneSequenceArray, i);
|
||||
|
||||
const char *scene1 =
|
||||
obs_data_get_string(array_obj, "sceneRoundTripScene1");
|
||||
@@ -434,43 +430,43 @@ void SwitcherData::loadSceneRoundTripSwitches(obs_data_t *obj)
|
||||
delay = obs_data_get_double(array_obj, "delay");
|
||||
}
|
||||
|
||||
std::string str = MakeSceneRoundTripSwitchName(
|
||||
std::string str = MakeSceneSequenceSwitchName(
|
||||
scene1, scene2, transition, delay)
|
||||
.toUtf8()
|
||||
.constData();
|
||||
const char *sceneRoundTripStr = str.c_str();
|
||||
const char *sceneSequenceStr = str.c_str();
|
||||
|
||||
switcher->sceneRoundTripSwitches.emplace_back(
|
||||
switcher->sceneSequenceSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene1),
|
||||
GetWeakSourceByName(scene2),
|
||||
GetWeakTransitionByName(transition), delay,
|
||||
(strcmp(scene2, previous_scene_name) == 0),
|
||||
sceneRoundTripStr);
|
||||
sceneSequenceStr);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_array_release(sceneRoundTripArray);
|
||||
obs_data_array_release(sceneSequenceArray);
|
||||
}
|
||||
|
||||
void SceneSwitcher::setupSequenceTab()
|
||||
{
|
||||
populateSceneSelection(ui->sceneRoundTripScenes1, false);
|
||||
populateSceneSelection(ui->sceneRoundTripScenes2, true);
|
||||
populateTransitionSelection(ui->sceneRoundTripTransitions);
|
||||
populateSceneSelection(ui->sceneSequenceScenes1, false);
|
||||
populateSceneSelection(ui->sceneSequenceScenes2, true);
|
||||
populateTransitionSelection(ui->sceneSequenceTransitions);
|
||||
|
||||
double smallestDelay = double(switcher->interval) / 1000;
|
||||
for (auto &s : switcher->sceneRoundTripSwitches) {
|
||||
std::string sceneName1 = GetWeakSourceName(s.scene1);
|
||||
for (auto &s : switcher->sceneSequenceSwitches) {
|
||||
std::string sceneName1 = GetWeakSourceName(s.startScene);
|
||||
std::string sceneName2 = (s.usePreviousScene)
|
||||
? previous_scene_name
|
||||
: GetWeakSourceName(s.scene2);
|
||||
: GetWeakSourceName(s.scene);
|
||||
std::string transitionName = GetWeakSourceName(s.transition);
|
||||
QString text = MakeSceneRoundTripSwitchName(
|
||||
QString text = MakeSceneSequenceSwitchName(
|
||||
sceneName1.c_str(), sceneName2.c_str(),
|
||||
transitionName.c_str(), s.delay);
|
||||
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(text, ui->sceneRoundTrips);
|
||||
new QListWidgetItem(text, ui->sceneSequences);
|
||||
item->setData(Qt::UserRole, text);
|
||||
|
||||
if (s.delay < smallestDelay)
|
||||
@@ -480,21 +476,32 @@ void SceneSwitcher::setupSequenceTab()
|
||||
? ui->intervalWarning->setVisible(true)
|
||||
: ui->intervalWarning->setVisible(false);
|
||||
|
||||
ui->sceneRoundTripDelayUnits->addItem("seconds");
|
||||
ui->sceneRoundTripDelayUnits->addItem("minutes");
|
||||
ui->sceneRoundTripDelayUnits->addItem("hours");
|
||||
ui->sceneSequenceDelayUnits->addItem("seconds");
|
||||
ui->sceneSequenceDelayUnits->addItem("minutes");
|
||||
ui->sceneSequenceDelayUnits->addItem("hours");
|
||||
|
||||
switch (switcher->sceneRoundTripUnitMultiplier) {
|
||||
switch (switcher->sceneSequenceMultiplier) {
|
||||
case 1:
|
||||
ui->sceneRoundTripDelayUnits->setCurrentIndex(0);
|
||||
ui->sceneSequenceDelayUnits->setCurrentIndex(0);
|
||||
break;
|
||||
case 60:
|
||||
ui->sceneRoundTripDelayUnits->setCurrentIndex(1);
|
||||
ui->sceneSequenceDelayUnits->setCurrentIndex(1);
|
||||
break;
|
||||
case 3600:
|
||||
ui->sceneRoundTripDelayUnits->setCurrentIndex(2);
|
||||
ui->sceneSequenceDelayUnits->setCurrentIndex(2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline QString MakeSceneSequenceSwitchName(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)");
|
||||
}
|
||||
@@ -223,9 +223,7 @@ void SwitcherData::checkTimeSwitch(bool &match, OBSWeakSource &scene,
|
||||
match = true;
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher time match");
|
||||
|
||||
s.logMatch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -329,3 +327,46 @@ void SceneSwitcher::setupTimeTab()
|
||||
item->setData(Qt::UserRole, listText);
|
||||
}
|
||||
}
|
||||
|
||||
static inline QString MakeTimeSwitchName(const QString &scene,
|
||||
const QString &transition,
|
||||
const timeTrigger &trigger,
|
||||
const QTime &time)
|
||||
{
|
||||
QString switchName;
|
||||
|
||||
switch (trigger) {
|
||||
case ANY_DAY:
|
||||
switchName = QStringLiteral("On any weekday");
|
||||
break;
|
||||
case MONDAY:
|
||||
switchName = QStringLiteral("Mondays");
|
||||
break;
|
||||
case TUSEDAY:
|
||||
switchName = QStringLiteral("Tusedays");
|
||||
break;
|
||||
case WEDNESDAY:
|
||||
switchName = QStringLiteral("Wednesdays");
|
||||
break;
|
||||
case THURSDAY:
|
||||
switchName = QStringLiteral("Thursdays");
|
||||
break;
|
||||
case FRIDAY:
|
||||
switchName = QStringLiteral("Fridays");
|
||||
break;
|
||||
case SATURDAY:
|
||||
switchName = QStringLiteral("Saturdays");
|
||||
break;
|
||||
case SUNDAY:
|
||||
switchName = QStringLiteral("Sundays");
|
||||
break;
|
||||
case LIVE:
|
||||
switchName = QStringLiteral(
|
||||
"Relative to starting streaming / recording");
|
||||
break;
|
||||
}
|
||||
switchName += QStringLiteral(" at ") + time.toString() +
|
||||
QStringLiteral(" switch to ") + scene +
|
||||
QStringLiteral(" using ") + transition;
|
||||
return switchName;
|
||||
}
|
||||
@@ -38,8 +38,7 @@ void SceneSwitcher::on_transitionsAdd_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
for (auto &s : switcher->sceneTransitions) {
|
||||
if (s.scene1 == source1 &&
|
||||
s.scene2 == source2) {
|
||||
if (s.scene == source1 && s.scene2 == source2) {
|
||||
s.transition = transition;
|
||||
s.sceneTransitionStr =
|
||||
text.toUtf8().constData();
|
||||
@@ -164,8 +163,8 @@ void SwitcherData::setDefaultSceneTransitions()
|
||||
obs_frontend_set_current_transition(transition);
|
||||
|
||||
if (verbose)
|
||||
blog(LOG_INFO,
|
||||
"Advanced Scene Switcher default transition set");
|
||||
if (verbose)
|
||||
s.logMatch();
|
||||
|
||||
obs_source_release(transition);
|
||||
break;
|
||||
@@ -229,7 +228,7 @@ void SceneSwitcher::on_sceneTransitions_currentRowChanged(int idx)
|
||||
for (auto &s : switcher->sceneTransitions) {
|
||||
if (sceneTransition.compare(s.sceneTransitionStr.c_str()) ==
|
||||
0) {
|
||||
std::string scene1 = GetWeakSourceName(s.scene1);
|
||||
std::string scene1 = GetWeakSourceName(s.scene);
|
||||
std::string scene2 = GetWeakSourceName(s.scene2);
|
||||
std::string transitionName =
|
||||
GetWeakSourceName(s.transition);
|
||||
@@ -288,7 +287,7 @@ obs_weak_source_t *getNextTransition(obs_weak_source_t *scene1,
|
||||
obs_weak_source_t *ws = nullptr;
|
||||
if (scene1 && scene2) {
|
||||
for (SceneTransition &t : switcher->sceneTransitions) {
|
||||
if (t.scene1 == scene1 && t.scene2 == scene2)
|
||||
if (t.scene == scene1 && t.scene2 == scene2)
|
||||
ws = t.transition;
|
||||
}
|
||||
obs_weak_source_addref(ws);
|
||||
@@ -359,7 +358,7 @@ void SwitcherData::saveSceneTransitions(obs_data_t *obj)
|
||||
for (SceneTransition &s : switcher->sceneTransitions) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source1 = obs_weak_source_get_source(s.scene1);
|
||||
obs_source_t *source1 = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *source2 = obs_weak_source_get_source(s.scene2);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
@@ -372,8 +371,6 @@ void SwitcherData::saveSceneTransitions(obs_data_t *obj)
|
||||
obs_data_set_string(array_obj, "Scene2", sceneName2);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_string(array_obj, "Str",
|
||||
s.sceneTransitionStr.c_str());
|
||||
obs_data_array_push_back(sceneTransitionsArray,
|
||||
array_obj);
|
||||
obs_source_release(source1);
|
||||
@@ -400,8 +397,6 @@ void SwitcherData::saveSceneTransitions(obs_data_t *obj)
|
||||
obs_data_set_string(array_obj, "Scene", sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_string(array_obj, "Str",
|
||||
s.sceneTransitionStr.c_str());
|
||||
obs_data_array_push_back(defaultTransitionsArray,
|
||||
array_obj);
|
||||
obs_source_release(source);
|
||||
@@ -433,8 +428,11 @@ void SwitcherData::loadSceneTransitions(obs_data_t *obj)
|
||||
const char *scene2 = obs_data_get_string(array_obj, "Scene2");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
const char *sceneTransitionsStr =
|
||||
obs_data_get_string(array_obj, "Str");
|
||||
|
||||
std::string sceneTransitionsStr =
|
||||
MakeSceneTransitionName(scene1, scene2, transition)
|
||||
.toUtf8()
|
||||
.constData();
|
||||
|
||||
switcher->sceneTransitions.emplace_back(
|
||||
GetWeakSourceByName(scene1),
|
||||
@@ -459,8 +457,11 @@ void SwitcherData::loadSceneTransitions(obs_data_t *obj)
|
||||
const char *scene = obs_data_get_string(array_obj, "Scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
const char *sceneTransitionsStr =
|
||||
obs_data_get_string(array_obj, "Str");
|
||||
|
||||
std::string sceneTransitionsStr =
|
||||
MakeDefaultSceneTransitionName(scene, transition)
|
||||
.toUtf8()
|
||||
.constData();
|
||||
|
||||
switcher->defaultSceneTransitions.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
@@ -484,7 +485,7 @@ void SceneSwitcher::setupTransitionsTab()
|
||||
populateTransitionSelection(ui->defaultTransitionsTransitions);
|
||||
|
||||
for (auto &s : switcher->sceneTransitions) {
|
||||
std::string sceneName1 = GetWeakSourceName(s.scene1);
|
||||
std::string sceneName1 = GetWeakSourceName(s.scene);
|
||||
std::string sceneName2 = GetWeakSourceName(s.scene2);
|
||||
std::string transitionName = GetWeakSourceName(s.transition);
|
||||
QString text = MakeSceneTransitionName(sceneName1.c_str(),
|
||||
@@ -495,9 +496,6 @@ void SceneSwitcher::setupTransitionsTab()
|
||||
new QListWidgetItem(text, ui->sceneTransitions);
|
||||
item->setData(Qt::UserRole, text);
|
||||
}
|
||||
//(transitionDurationLongerThanInterval(switcher->interval))
|
||||
// ? ui->transitionWarning->setVisible(true)
|
||||
// : ui->transitionWarning->setVisible(false);
|
||||
|
||||
for (auto &s : switcher->defaultSceneTransitions) {
|
||||
std::string sceneName = GetWeakSourceName(s.scene);
|
||||
@@ -513,3 +511,17 @@ void SceneSwitcher::setupTransitionsTab()
|
||||
ui->transitionOverridecheckBox->setChecked(
|
||||
switcher->tansitionOverrideOverride);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
#include <obs-module.h>
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
|
||||
bool isRunning(std::string &title)
|
||||
@@ -65,6 +64,7 @@ void SceneSwitcher::on_add_clicked()
|
||||
QString windowName = ui->windows->currentText();
|
||||
QString transitionName = ui->transitions->currentText();
|
||||
bool fullscreen = ui->fullscreenCheckBox->isChecked();
|
||||
bool maximized = ui->maximizedCheckBox->isChecked();
|
||||
bool focus = ui->focusCheckBox->isChecked();
|
||||
|
||||
if (windowName.isEmpty() || sceneName.isEmpty())
|
||||
@@ -74,8 +74,9 @@ void SceneSwitcher::on_add_clicked()
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
QVariant v = QVariant::fromValue(windowName);
|
||||
|
||||
QString text = MakeSwitchName(sceneName, windowName, transitionName,
|
||||
fullscreen, focus);
|
||||
QString text = MakeWindowSwitchName(sceneName, windowName,
|
||||
transitionName, fullscreen,
|
||||
maximized, focus);
|
||||
|
||||
int idx = FindByData(windowName);
|
||||
|
||||
@@ -83,7 +84,7 @@ void SceneSwitcher::on_add_clicked()
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->windowSwitches.emplace_back(
|
||||
source, windowName.toUtf8().constData(), transition,
|
||||
fullscreen, focus);
|
||||
fullscreen, maximized, focus);
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem(text, ui->switches);
|
||||
item->setData(Qt::UserRole, v);
|
||||
@@ -100,6 +101,7 @@ void SceneSwitcher::on_add_clicked()
|
||||
s.scene = source;
|
||||
s.transition = transition;
|
||||
s.fullscreen = fullscreen;
|
||||
s.maximized = maximized;
|
||||
s.focus = focus;
|
||||
break;
|
||||
}
|
||||
@@ -239,6 +241,7 @@ void SceneSwitcher::on_switches_currentRowChanged(int idx)
|
||||
ui->windows->setCurrentText(window);
|
||||
ui->transitions->setCurrentText(transitionName.c_str());
|
||||
ui->fullscreenCheckBox->setChecked(s.fullscreen);
|
||||
ui->maximizedCheckBox->setChecked(s.maximized);
|
||||
ui->focusCheckBox->setChecked(s.focus);
|
||||
break;
|
||||
}
|
||||
@@ -293,6 +296,8 @@ void SwitcherData::checkWindowTitleSwitch(bool &match, OBSWeakSource &scene,
|
||||
for (WindowSceneSwitch &s : windowSwitches) {
|
||||
// True if fullscreen is disabled OR current window is fullscreen
|
||||
bool fullscreen = (!s.fullscreen || isFullscreen(s.window));
|
||||
// True if maximized is disabled OR current window is maximized
|
||||
bool max = (!s.maximized || isMaximized(s.window));
|
||||
// True if focus is disabled OR switch is focused
|
||||
bool focus = (!s.focus || isFocused(s.window));
|
||||
// True if current window is ignored AND switch equals OR matches last window
|
||||
@@ -303,11 +308,14 @@ void SwitcherData::checkWindowTitleSwitch(bool &match, OBSWeakSource &scene,
|
||||
QRegularExpression(
|
||||
QString::fromStdString(s.window)))));
|
||||
|
||||
if (isRunning(s.window) && (fullscreen && (focus || ignore))) {
|
||||
if (isRunning(s.window) &&
|
||||
(fullscreen && (max && (focus || ignore)))) {
|
||||
match = true;
|
||||
scene = s.scene;
|
||||
transition = s.transition;
|
||||
|
||||
if (verbose)
|
||||
s.logMatch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -333,6 +341,7 @@ void SwitcherData::saveWindowTitleSwitches(obs_data_t *obj)
|
||||
s.window.c_str());
|
||||
obs_data_set_bool(array_obj, "fullscreen",
|
||||
s.fullscreen);
|
||||
obs_data_set_bool(array_obj, "maximized", s.maximized);
|
||||
obs_data_set_bool(array_obj, "focus", s.focus);
|
||||
obs_data_array_push_back(windowTitleArray, array_obj);
|
||||
obs_source_release(source);
|
||||
@@ -372,12 +381,20 @@ void SwitcherData::loadWindowTitleSwitches(obs_data_t *obj)
|
||||
const char *window =
|
||||
obs_data_get_string(array_obj, "window_title");
|
||||
bool fullscreen = obs_data_get_bool(array_obj, "fullscreen");
|
||||
#if __APPLE__
|
||||
// TODO:
|
||||
// not implemented on MacOS as I cannot test it
|
||||
bool maximized = false;
|
||||
#else
|
||||
bool maximized = obs_data_get_bool(array_obj, "maximized");
|
||||
#endif
|
||||
bool focus = obs_data_get_bool(array_obj, "focus") ||
|
||||
!obs_data_has_user_value(array_obj, "focus");
|
||||
|
||||
switcher->windowSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene), window,
|
||||
GetWeakTransitionByName(transition), fullscreen, focus);
|
||||
GetWeakTransitionByName(transition), fullscreen,
|
||||
maximized, focus);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
@@ -413,10 +430,11 @@ void SceneSwitcher::setupTitleTab()
|
||||
for (auto &s : switcher->windowSwitches) {
|
||||
std::string sceneName = GetWeakSourceName(s.scene);
|
||||
std::string transitionName = GetWeakSourceName(s.transition);
|
||||
QString text = MakeSwitchName(sceneName.c_str(),
|
||||
s.window.c_str(),
|
||||
transitionName.c_str(),
|
||||
s.fullscreen, s.focus);
|
||||
QString text = MakeWindowSwitchName(sceneName.c_str(),
|
||||
s.window.c_str(),
|
||||
transitionName.c_str(),
|
||||
s.fullscreen, s.maximized,
|
||||
s.focus);
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem(text, ui->switches);
|
||||
item->setData(Qt::UserRole, s.window.c_str());
|
||||
@@ -429,4 +447,36 @@ void SceneSwitcher::setupTitleTab()
|
||||
new QListWidgetItem(text, ui->ignoreWindows);
|
||||
item->setData(Qt::UserRole, text);
|
||||
}
|
||||
|
||||
#if __APPLE__
|
||||
// TODO:
|
||||
// not implemented on MacOS as I cannot test it
|
||||
ui->maximizedCheckBox->setDisabled(true);
|
||||
ui->maximizedCheckBox->setVisible(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline QString MakeWindowSwitchName(const QString &scene,
|
||||
const QString &value,
|
||||
const QString &transition,
|
||||
bool fullscreen, bool maximized,
|
||||
bool focus)
|
||||
{
|
||||
QString name = QStringLiteral("[") + scene + QStringLiteral(", ") +
|
||||
transition + QStringLiteral("]: ") + value;
|
||||
|
||||
if (fullscreen || maximized || focus) {
|
||||
name += QStringLiteral(" (only if");
|
||||
|
||||
if (fullscreen)
|
||||
name += QStringLiteral(" fullscreen ");
|
||||
if (maximized)
|
||||
name += QStringLiteral(" maximized ");
|
||||
if (focus)
|
||||
name += QStringLiteral(" focused");
|
||||
|
||||
name += QStringLiteral(")");
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
96
src/switcher-data-structs.cpp
Normal file
96
src/switcher-data-structs.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "headers/switcher-data-structs.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
|
||||
void SwitcherData::Prune()
|
||||
{
|
||||
for (size_t i = 0; i < windowSwitches.size(); i++) {
|
||||
WindowSceneSwitch &s = windowSwitches[i];
|
||||
if (!s.valid())
|
||||
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 (!s.valid())
|
||||
randomSwitches.erase(randomSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < screenRegionSwitches.size(); i++) {
|
||||
ScreenRegionSwitch &s = screenRegionSwitches[i];
|
||||
if (!s.valid())
|
||||
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 < sceneSequenceSwitches.size(); i++) {
|
||||
SceneSequenceSwitch &s = sceneSequenceSwitches[i];
|
||||
if (!s.valid())
|
||||
sceneSequenceSwitches.erase(
|
||||
sceneSequenceSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!WeakSourceValid(autoStopScene)) {
|
||||
autoStopScene = nullptr;
|
||||
autoStopEnable = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sceneTransitions.size(); i++) {
|
||||
SceneTransition &s = sceneTransitions[i];
|
||||
if (!s.valid())
|
||||
sceneTransitions.erase(sceneTransitions.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < defaultSceneTransitions.size(); i++) {
|
||||
DefaultSceneTransition &s = defaultSceneTransitions[i];
|
||||
if (!s.valid())
|
||||
defaultSceneTransitions.erase(
|
||||
defaultSceneTransitions.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < executableSwitches.size(); i++) {
|
||||
ExecutableSceneSwitch &s = executableSwitches[i];
|
||||
if (!s.valid())
|
||||
executableSwitches.erase(executableSwitches.begin() +
|
||||
i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fileSwitches.size(); i++) {
|
||||
FileSwitch &s = fileSwitches[i];
|
||||
if (!s.valid())
|
||||
fileSwitches.erase(fileSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < timeSwitches.size(); i++) {
|
||||
TimeSwitch &s = timeSwitches[i];
|
||||
if (!s.valid())
|
||||
timeSwitches.erase(timeSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
if (!idleData.valid()) {
|
||||
idleData.idleEnable = false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mediaSwitches.size(); i++) {
|
||||
MediaSwitch &s = mediaSwitches[i];
|
||||
if (!s.valid())
|
||||
mediaSwitches.erase(mediaSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < audioSwitches.size(); i++) {
|
||||
AudioSwitch &s = audioSwitches[i];
|
||||
if (!s.valid())
|
||||
audioSwitches.erase(audioSwitches.begin() + i--);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ QWeakPointer<VolumeMeterTimer> VolumeMeter::updateTimer;
|
||||
void VolControl::OBSVolumeChanged(void *data, float db)
|
||||
{
|
||||
Q_UNUSED(db);
|
||||
VolControl *volControl = static_cast<VolControl *>(data);
|
||||
Q_UNUSED(data);
|
||||
}
|
||||
|
||||
void VolControl::OBSVolumeLevel(void *data,
|
||||
@@ -35,6 +35,7 @@ void VolControl::OBSVolumeLevel(void *data,
|
||||
|
||||
void VolControl::SliderChanged(int vol)
|
||||
{
|
||||
Q_UNUSED(vol);
|
||||
updateText();
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ std::pair<int, int> getCursorPos()
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool isFullscreen(std::string &title)
|
||||
bool isMaximized(std::string &title)
|
||||
{
|
||||
RECT appBounds;
|
||||
MONITORINFO monitorInfo = {0};
|
||||
@@ -135,6 +135,39 @@ bool isFullscreen(std::string &title)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isFullscreen(std::string &title)
|
||||
{
|
||||
RECT appBounds;
|
||||
MONITORINFO monitorInfo = {0};
|
||||
|
||||
HWND hwnd = GetWindow(GetDesktopWindow(), GW_CHILD);
|
||||
while (hwnd) {
|
||||
string wtitle;
|
||||
if (WindowValid(hwnd) && GetWindowTitle(hwnd, wtitle) &&
|
||||
(wtitle == title ||
|
||||
QString::fromStdString(wtitle).contains(QRegularExpression(
|
||||
QString::fromStdString(title)))))
|
||||
break;
|
||||
|
||||
hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
|
||||
}
|
||||
|
||||
monitorInfo.cbSize = sizeof(MONITORINFO);
|
||||
GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST),
|
||||
&monitorInfo);
|
||||
|
||||
if (hwnd && hwnd != GetDesktopWindow() && hwnd != GetShellWindow()) {
|
||||
GetWindowRect(hwnd, &appBounds);
|
||||
if (monitorInfo.rcMonitor.bottom == appBounds.bottom &&
|
||||
monitorInfo.rcMonitor.top == appBounds.top &&
|
||||
monitorInfo.rcMonitor.left == appBounds.left &&
|
||||
monitorInfo.rcMonitor.right == appBounds.right) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user