diff --git a/CMakeLists.txt b/CMakeLists.txt index 080f6517..9d3145e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ if(BUILD_OUT_OF_TREE) src/headers/switch-file.hpp src/headers/switch-idle.hpp src/headers/switch-media.hpp + src/headers/switch-pause.hpp src/headers/switch-random.hpp src/headers/switch-screen-region.hpp src/headers/switch-time.hpp @@ -206,6 +207,7 @@ else () src/headers/switch-file.hpp src/headers/switch-idle.hpp src/headers/switch-media.hpp + src/headers/switch-pause.hpp src/headers/switch-random.hpp src/headers/switch-screen-region.hpp src/headers/switch-time.hpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 206ef692..2f769da1 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -59,10 +59,14 @@ AdvSceneSwitcher.transitionTab.entry="Switch from {{scenes}} to {{scenes2}} usin AdvSceneSwitcher.transitionTab.defaultTransitionEntry="When scene {{scenes}} is active change default scene transition to {{transitions}}" ; Pause Scenes Tab -AdvSceneSwitcher.pauseScenesTab.title="Pause" -AdvSceneSwitcher.pauseScenesTab.pauseOnScene="Pause the Scene Switcher on scene" -AdvSceneSwitcher.pauseScenesTab.pauseInFocus1="Pause the Scene Switcher when " -AdvSceneSwitcher.pauseScenesTab.pauseInFocus2="is in focus" +AdvSceneSwitcher.pauseTab.title="Pause" +AdvSceneSwitcher.pauseTab.pauseOnScene="Pause the Scene Switcher on scene" +AdvSceneSwitcher.pauseTab.pauseInFocus1="Pause the Scene Switcher when " +AdvSceneSwitcher.pauseTab.pauseInFocus2="is in focus" +AdvSceneSwitcher.pauseTab.pauseTypeScene="scene is active" +AdvSceneSwitcher.pauseTab.pauseTypeWindow="window is in focus" +AdvSceneSwitcher.pauseTab.pauseTargetAll="all" +AdvSceneSwitcher.pauseTab.pauseEntry="Pause {{pauseTargets}} checks when {{pauseTypes}} {{scenes}} {{windows}}" ; Window Title Tab AdvSceneSwitcher.windowTitleTab.title="Title" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 5e0a1b7c..73f05d52 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -60,10 +60,10 @@ AdvSceneSwitcher.transitionTab.entry="从场景 {{scenes}} 切换到场景 {{sce AdvSceneSwitcher.transitionTab.defaultTransitionEntry="当场景 {{scenes}} 被激活时更改默认转场特效为 {{transitions}}" ; Pause Scenes Tab -AdvSceneSwitcher.pauseScenesTab.title="暂停" -AdvSceneSwitcher.pauseScenesTab.pauseOnScene="当切换到这个场景时暂停场景切换器" -AdvSceneSwitcher.pauseScenesTab.pauseInFocus1="当窗口" -AdvSceneSwitcher.pauseScenesTab.pauseInFocus2="获得焦点时暂停场景切换器" +AdvSceneSwitcher.pauseTab.title="暂停" +AdvSceneSwitcher.pauseTab.pauseOnScene="当切换到这个场景时暂停场景切换器" +AdvSceneSwitcher.pauseTab.pauseInFocus1="当窗口" +AdvSceneSwitcher.pauseTab.pauseInFocus2="获得焦点时暂停场景切换器" ; Window Title Tab AdvSceneSwitcher.windowTitleTab.title="窗口标题" diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui index 1ee2f512..dab2b61e 100644 --- a/forms/advanced-scene-switcher.ui +++ b/forms/advanced-scene-switcher.ui @@ -944,53 +944,13 @@ - + - AdvSceneSwitcher.pauseScenesTab.title + AdvSceneSwitcher.pauseTab.title - - - - - AdvSceneSwitcher.pauseScenesTab.pauseOnScene - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + 0 @@ -998,17 +958,17 @@ - true + false - + 4 - + 22 @@ -1024,7 +984,7 @@ - + 22 @@ -1040,126 +1000,92 @@ - + Qt::Horizontal + + QSizePolicy::Fixed + - 40 + 5 20 - - - - - - Qt::Horizontal - - - - - - - - AdvSceneSwitcher.pauseScenesTab.pauseInFocus1 + + + Qt::Vertical - - - - 0 - 0 - - - - - 100 - 0 - - - - true - - - - - - - AdvSceneSwitcher.pauseScenesTab.pauseInFocus2 - - - - - + Qt::Horizontal + + QSizePolicy::Fixed + - 40 + 5 20 - - - - - - - 0 - 0 - - - - true - - - - - - + 22 22 + + + + + + ../../../forms/images/up.svg../../../forms/images/up.svg + true - addIconSmall + upArrowIconSmall - + 22 22 + + + + + + ../../../forms/images/down.svg../../../forms/images/down.svg + true - removeIconSmall + downArrowIconSmall - + Qt::Horizontal diff --git a/src/general.cpp b/src/general.cpp index 0a6dcf4c..9de405a9 100644 --- a/src/general.cpp +++ b/src/general.cpp @@ -385,7 +385,7 @@ int findTabIndex(QTabWidget *tabWidget, int pos) tabName = "transitionsTab"; break; case 2: - tabName = "pauseScenesTab"; + tabName = "pauseTab"; break; case 3: tabName = "windowTitleTab"; diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 51f28d30..ad913a8e 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -31,8 +31,6 @@ public: void SetHideFrames(); void clearFrames(QListWidget *list); - int PauseScenesFindByData(const QString &scene); - int PauseWindowsFindByData(const QString &window); int IgnoreWindowsFindByData(const QString &window); int IgnoreIdleWindowsFindByData(const QString &window); @@ -104,13 +102,10 @@ public slots: void on_screenRegionUp_clicked(); void on_screenRegionDown_clicked(); - void on_pauseScenes_currentRowChanged(int idx); - void on_pauseScenesAdd_clicked(); - void on_pauseScenesRemove_clicked(); - - void on_pauseWindows_currentRowChanged(int idx); - void on_pauseWindowsAdd_clicked(); - void on_pauseWindowsRemove_clicked(); + void on_pauseUp_clicked(); + void on_pauseDown_clicked(); + void on_pauseAdd_clicked(); + void on_pauseRemove_clicked(); void on_ignoreWindows_currentRowChanged(int idx); void on_ignoreWindowsAdd_clicked(); diff --git a/src/headers/switch-audio.hpp b/src/headers/switch-audio.hpp index e920787b..26d94060 100644 --- a/src/headers/switch-audio.hpp +++ b/src/headers/switch-audio.hpp @@ -13,6 +13,7 @@ typedef enum { } audioCondition; struct AudioSwitch : virtual SceneSwitcherEntry { + static bool pause; OBSWeakSource audioSource = nullptr; int volumeThreshold = 0; audioCondition condition = ABOVE; diff --git a/src/headers/switch-executable.hpp b/src/headers/switch-executable.hpp index 71a3f2ed..591bbbb7 100644 --- a/src/headers/switch-executable.hpp +++ b/src/headers/switch-executable.hpp @@ -6,6 +6,7 @@ constexpr auto exe_func = 3; constexpr auto default_priority_3 = exe_func; struct ExecutableSwitch : SceneSwitcherEntry { + static bool pause; QString exe = ""; bool inFocus = false; diff --git a/src/headers/switch-file.hpp b/src/headers/switch-file.hpp index f98b2152..245f8736 100644 --- a/src/headers/switch-file.hpp +++ b/src/headers/switch-file.hpp @@ -12,6 +12,7 @@ typedef enum { } file_type; struct FileSwitch : SceneSwitcherEntry { + static bool pause; std::string file = obs_module_text("AdvSceneSwitcher.enterPath"); std::string text = obs_module_text("AdvSceneSwitcher.enterText"); bool remote = false; diff --git a/src/headers/switch-idle.hpp b/src/headers/switch-idle.hpp index 38497035..4d60e19b 100644 --- a/src/headers/switch-idle.hpp +++ b/src/headers/switch-idle.hpp @@ -6,6 +6,7 @@ constexpr auto idle_func = 2; constexpr auto default_priority_2 = idle_func; struct IdleData : SceneSwitcherEntry { + static bool pause; bool idleEnable = false; int time = default_idle_time; bool alreadySwitched = false; diff --git a/src/headers/switch-media.hpp b/src/headers/switch-media.hpp index 7f710d7d..b97f8567 100644 --- a/src/headers/switch-media.hpp +++ b/src/headers/switch-media.hpp @@ -13,6 +13,7 @@ typedef enum { } time_restriction; struct MediaSwitch : SceneSwitcherEntry { + static bool pause; OBSWeakSource source = nullptr; obs_media_state state = OBS_MEDIA_STATE_NONE; bool anyState = false; diff --git a/src/headers/switch-pause.hpp b/src/headers/switch-pause.hpp new file mode 100644 index 00000000..a233da02 --- /dev/null +++ b/src/headers/switch-pause.hpp @@ -0,0 +1,64 @@ +#pragma once +#include "switch-generic.hpp" + +enum class PauseType { + Scene, + Window, +}; + +enum class PauseTarget { + All, + Transition, + Window, + Executable, + Region, + Media, + File, + Random, + Time, + Idle, + Sequence, + Audio, +}; + +struct PauseEntry : SceneSwitcherEntry { + PauseType pauseType = PauseType::Scene; + PauseTarget pauseTarget = PauseTarget::All; + std::string window = ""; + + const char *getType() { return "pause"; } + bool valid(); + + inline PauseEntry(){}; + inline PauseEntry(OBSWeakSource scene_, PauseType pauseType_, + PauseTarget pauseTarget_, const std::string &window_) + : SceneSwitcherEntry(scene_, nullptr), + pauseType(pauseType_), + pauseTarget(pauseTarget_), + window(window_) + { + } +}; + +class PauseEntryWidget : public SwitchWidget { + Q_OBJECT + +public: + PauseEntryWidget(PauseEntry *s); + PauseEntry *getSwitchData(); + void setSwitchData(PauseEntry *s); + + static void swapSwitchData(PauseEntryWidget *s1, PauseEntryWidget *s2); + +private slots: + void PauseTypeChanged(int index); + void PauseTargetChanged(int index); + void WindowChanged(const QString &text); + +private: + QComboBox *pauseTypes; + QComboBox *pauseTargets; + QComboBox *windows; + + PauseEntry *switchData; +}; diff --git a/src/headers/switch-random.hpp b/src/headers/switch-random.hpp index a277d8af..6cb0f5bc 100644 --- a/src/headers/switch-random.hpp +++ b/src/headers/switch-random.hpp @@ -2,6 +2,7 @@ #include "switch-generic.hpp" struct RandomSwitch : SceneSwitcherEntry { + static bool pause; double delay = 0.0; const char *getType() { return "random"; } diff --git a/src/headers/switch-screen-region.hpp b/src/headers/switch-screen-region.hpp index 880ef7d8..a6f3555d 100644 --- a/src/headers/switch-screen-region.hpp +++ b/src/headers/switch-screen-region.hpp @@ -6,6 +6,7 @@ constexpr auto screen_region_func = 4; constexpr auto default_priority_4 = screen_region_func; struct ScreenRegionSwitch : SceneSwitcherEntry { + static bool pause; int minX = 0, minY = 0, maxX = 0, maxY = 0; const char *getType() { return "region"; } diff --git a/src/headers/switch-sequence.hpp b/src/headers/switch-sequence.hpp index 7f1c8108..d8db9ef1 100644 --- a/src/headers/switch-sequence.hpp +++ b/src/headers/switch-sequence.hpp @@ -11,6 +11,7 @@ typedef enum { } delay_units; struct SceneSequenceSwitch : SceneSwitcherEntry { + static bool pause; OBSWeakSource startScene = nullptr; double delay = 0; int delayMultiplier = 1; diff --git a/src/headers/switch-time.hpp b/src/headers/switch-time.hpp index 888db150..21a603d8 100644 --- a/src/headers/switch-time.hpp +++ b/src/headers/switch-time.hpp @@ -19,6 +19,7 @@ typedef enum { } timeTrigger; struct TimeSwitch : SceneSwitcherEntry { + static bool pause; timeTrigger trigger = ANY_DAY; QTime time = QTime(0, 0); diff --git a/src/headers/switch-transitions.hpp b/src/headers/switch-transitions.hpp index b835c02b..86f028e7 100644 --- a/src/headers/switch-transitions.hpp +++ b/src/headers/switch-transitions.hpp @@ -17,6 +17,7 @@ struct SceneTransition : SceneSwitcherEntry { }; struct DefaultSceneTransition : SceneSwitcherEntry { + static bool pause; const char *getType() { return "def_transition"; } diff --git a/src/headers/switch-window.hpp b/src/headers/switch-window.hpp index acde8de0..dd30836e 100644 --- a/src/headers/switch-window.hpp +++ b/src/headers/switch-window.hpp @@ -5,6 +5,7 @@ constexpr auto window_title_func = 5; constexpr auto default_priority_5 = window_title_func; struct WindowSwitch : SceneSwitcherEntry { + static bool pause; std::string window = ""; bool fullscreen = false; bool maximized = false; diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp index 159882cc..8841bbc4 100644 --- a/src/headers/switcher-data-structs.hpp +++ b/src/headers/switcher-data-structs.hpp @@ -12,6 +12,7 @@ #include "switch-file.hpp" #include "switch-idle.hpp" #include "switch-media.hpp" +#include "switch-pause.hpp" #include "switch-random.hpp" #include "switch-screen-region.hpp" #include "switch-time.hpp" @@ -73,10 +74,6 @@ struct SwitcherData { std::deque screenRegionSwitches; - std::vector pauseScenesSwitches; - - std::vector pauseWindowsSwitches; - std::vector ignoreWindowsSwitches; std::deque sceneSequenceSwitches; @@ -105,6 +102,8 @@ struct SwitcherData { std::deque mediaSwitches; + std::deque pauseEntries; + std::deque timeSwitches; QDateTime liveTime; @@ -207,6 +206,7 @@ struct SwitcherData { void loadWindowTitleSwitches(obs_data_t *obj); void loadScreenRegionSwitches(obs_data_t *obj); void loadPauseSwitches(obs_data_t *obj); + void loadOldPauseSwitches(obs_data_t *obj); void loadSceneSequenceSwitches(obs_data_t *obj); void loadSceneTransitions(obs_data_t *obj); void loadIdleSwitches(obs_data_t *obj); diff --git a/src/switch-audio.cpp b/src/switch-audio.cpp index 4a1a8810..bf5e1db3 100644 --- a/src/switch-audio.cpp +++ b/src/switch-audio.cpp @@ -2,6 +2,7 @@ #include "headers/volume-control.hpp" #include "headers/utility.hpp" +bool AudioSwitch::pause = false; static QMetaObject::Connection addPulse; void AdvSceneSwitcher::on_audioAdd_clicked() @@ -74,7 +75,7 @@ void AdvSceneSwitcher::on_audioDown_clicked() void SwitcherData::checkAudioSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { - if (audioSwitches.size() == 0) + if (AudioSwitch::pause) return; for (AudioSwitch &s : audioSwitches) { diff --git a/src/switch-executable.cpp b/src/switch-executable.cpp index 0c1877d5..b9d72237 100644 --- a/src/switch-executable.cpp +++ b/src/switch-executable.cpp @@ -1,6 +1,7 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool ExecutableSwitch::pause = false; static QMetaObject::Connection addPulse; void AdvSceneSwitcher::on_executableAdd_clicked() @@ -74,6 +75,9 @@ void AdvSceneSwitcher::on_executableDown_clicked() void SwitcherData::checkExeSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { + if (executableSwitches.size() == 0 || ExecutableSwitch::pause) + return; + std::string title; QStringList runningProcesses; bool ignored = false; diff --git a/src/switch-file.cpp b/src/switch-file.cpp index 44477a35..2b591c9a 100644 --- a/src/switch-file.cpp +++ b/src/switch-file.cpp @@ -8,6 +8,7 @@ #include "headers/curl-helper.hpp" #include "headers/utility.hpp" +bool FileSwitch::pause = false; static QMetaObject::Connection addPulse; static std::hash strHash; @@ -229,6 +230,9 @@ bool checkLocalFileContent(FileSwitch &s) void SwitcherData::checkFileContent(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { + if (FileSwitch::pause) + return; + for (FileSwitch &s : fileSwitches) { if (!s.initialized()) continue; diff --git a/src/switch-idle.cpp b/src/switch-idle.cpp index 844836d3..078141d3 100644 --- a/src/switch-idle.cpp +++ b/src/switch-idle.cpp @@ -3,10 +3,12 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool IdleData::pause = false; + void SwitcherData::checkIdleSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { - if (!idleData.idleEnable) + if (!idleData.idleEnable || IdleData::pause) return; std::string title; diff --git a/src/switch-media.cpp b/src/switch-media.cpp index 310d5c4c..9341cfb6 100644 --- a/src/switch-media.cpp +++ b/src/switch-media.cpp @@ -1,6 +1,7 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool MediaSwitch::pause = false; static QMetaObject::Connection addPulse; constexpr auto media_played_to_end_idx = 8; @@ -76,6 +77,9 @@ void AdvSceneSwitcher::on_mediaDown_clicked() void SwitcherData::checkMediaSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { + if (MediaSwitch::pause) + return; + for (MediaSwitch &mediaSwitch : mediaSwitches) { if (!mediaSwitch.initialized()) continue; diff --git a/src/switch-pause.cpp b/src/switch-pause.cpp index 7aebcbcf..c7d8d99a 100644 --- a/src/switch-pause.cpp +++ b/src/switch-pause.cpp @@ -3,264 +3,265 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" -void AdvSceneSwitcher::on_pauseScenesAdd_clicked() +static QMetaObject::Connection addPulse; + +void AdvSceneSwitcher::on_pauseAdd_clicked() { - QString sceneName = ui->pauseScenesScenes->currentText(); + std::lock_guard lock(switcher->m); + switcher->pauseEntries.emplace_back(); - if (sceneName.isEmpty()) - return; - - OBSWeakSource source = GetWeakSourceByQString(sceneName); - QVariant v = QVariant::fromValue(sceneName); - - QList items = - ui->pauseScenes->findItems(sceneName, Qt::MatchExactly); - - if (items.size() == 0) { - QListWidgetItem *item = - new QListWidgetItem(sceneName, ui->pauseScenes); - item->setData(Qt::UserRole, v); - - std::lock_guard lock(switcher->m); - switcher->pauseScenesSwitches.emplace_back(source); - ui->pauseScenes->sortItems(); - } + listAddClicked(ui->pauseEntries, + new PauseEntryWidget(&switcher->pauseEntries.back()), + ui->pauseAdd, &addPulse); } -void AdvSceneSwitcher::on_pauseScenesRemove_clicked() +void AdvSceneSwitcher::on_pauseRemove_clicked() { - QListWidgetItem *item = ui->pauseScenes->currentItem(); + QListWidgetItem *item = ui->pauseEntries->currentItem(); if (!item) return; - QString pauseScene = item->data(Qt::UserRole).toString(); - { std::lock_guard lock(switcher->m); - auto &switches = switcher->pauseScenesSwitches; - - for (auto it = switches.begin(); it != switches.end(); ++it) { - auto &s = *it; - - if (s == GetWeakSourceByQString(pauseScene)) { - switches.erase(it); - break; - } - } + int idx = ui->pauseEntries->currentRow(); + auto &switches = switcher->pauseEntries; + switches.erase(switches.begin() + idx); } delete item; } -void AdvSceneSwitcher::on_pauseWindowsAdd_clicked() +void AdvSceneSwitcher::on_pauseUp_clicked() { - QString windowName = ui->pauseWindowsWindows->currentText(); - - if (windowName.isEmpty()) + int index = ui->pauseEntries->currentRow(); + if (!listMoveUp(ui->pauseEntries)) return; - QVariant v = QVariant::fromValue(windowName); - - QList items = - ui->pauseWindows->findItems(windowName, Qt::MatchExactly); - - if (items.size() == 0) { - QListWidgetItem *item = - new QListWidgetItem(windowName, ui->pauseWindows); - item->setData(Qt::UserRole, v); - - std::lock_guard lock(switcher->m); - switcher->pauseWindowsSwitches.emplace_back( - windowName.toUtf8().constData()); - ui->pauseWindows->sortItems(); - } -} - -void AdvSceneSwitcher::on_pauseWindowsRemove_clicked() -{ - QListWidgetItem *item = ui->pauseWindows->currentItem(); - if (!item) - return; - - QString windowName = item->data(Qt::UserRole).toString(); - - { - std::lock_guard lock(switcher->m); - auto &switches = switcher->pauseWindowsSwitches; - - for (auto it = switches.begin(); it != switches.end(); ++it) { - auto &s = *it; - - if (s == windowName.toUtf8().constData()) { - switches.erase(it); - break; - } - } - } - - delete item; -} - -void AdvSceneSwitcher::on_pauseScenes_currentRowChanged(int idx) -{ - if (loading) - return; - if (idx == -1) - return; - - QListWidgetItem *item = ui->pauseScenes->item(idx); - - QString scene = item->data(Qt::UserRole).toString(); + PauseEntryWidget *s1 = (PauseEntryWidget *)ui->pauseEntries->itemWidget( + ui->pauseEntries->item(index)); + PauseEntryWidget *s2 = (PauseEntryWidget *)ui->pauseEntries->itemWidget( + ui->pauseEntries->item(index - 1)); + PauseEntryWidget::swapSwitchData(s1, s2); std::lock_guard lock(switcher->m); - for (auto &s : switcher->pauseScenesSwitches) { - std::string name = GetWeakSourceName(s); - if (scene.compare(name.c_str()) == 0) { - ui->pauseScenesScenes->setCurrentText(name.c_str()); - break; - } - } + + std::swap(switcher->pauseEntries[index], + switcher->pauseEntries[index - 1]); } -void AdvSceneSwitcher::on_pauseWindows_currentRowChanged(int idx) +void AdvSceneSwitcher::on_pauseDown_clicked() { - if (loading) - return; - if (idx == -1) + int index = ui->pauseEntries->currentRow(); + + if (!listMoveDown(ui->pauseEntries)) return; - QListWidgetItem *item = ui->pauseWindows->item(idx); - - QString window = item->data(Qt::UserRole).toString(); + PauseEntryWidget *s1 = (PauseEntryWidget *)ui->pauseEntries->itemWidget( + ui->pauseEntries->item(index)); + PauseEntryWidget *s2 = (PauseEntryWidget *)ui->pauseEntries->itemWidget( + ui->pauseEntries->item(index + 1)); + PauseEntryWidget::swapSwitchData(s1, s2); std::lock_guard lock(switcher->m); - for (auto &s : switcher->pauseWindowsSwitches) { - if (window.compare(s.c_str()) == 0) { - ui->pauseWindowsWindows->setCurrentText(s.c_str()); - break; - } + + std::swap(switcher->pauseEntries[index], + switcher->pauseEntries[index + 1]); +} + +void resetPause() +{ + DefaultSceneTransition::pause = false; + WindowSwitch::pause = false; + ExecutableSwitch::pause = false; + ScreenRegionSwitch::pause = false; + MediaSwitch::pause = false; + FileSwitch::pause = false; + RandomSwitch::pause = false; + TimeSwitch::pause = false; + IdleData::pause = false; + SceneSequenceSwitch::pause = false; + AudioSwitch::pause = false; +} + +void setPauseTarget(PauseTarget &target, bool &verbose) +{ + switch (target) { + case PauseTarget::All: + if (verbose) + blog(LOG_INFO, "pause all switching"); + break; + case PauseTarget::Transition: + if (verbose) + blog(LOG_INFO, "pause def_transition switching"); + DefaultSceneTransition::pause = true; + break; + case PauseTarget::Window: + if (verbose) + blog(LOG_INFO, "pause window switching"); + WindowSwitch::pause = true; + break; + case PauseTarget::Executable: + if (verbose) + blog(LOG_INFO, "pause exec switching"); + ExecutableSwitch::pause = true; + break; + case PauseTarget::Region: + if (verbose) + blog(LOG_INFO, "pause region switching"); + ScreenRegionSwitch::pause = true; + break; + case PauseTarget::Media: + if (verbose) + blog(LOG_INFO, "pause media switching"); + MediaSwitch::pause = true; + break; + case PauseTarget::File: + if (verbose) + blog(LOG_INFO, "pause file switching"); + FileSwitch::pause = true; + break; + case PauseTarget::Random: + if (verbose) + blog(LOG_INFO, "pause random switching"); + RandomSwitch::pause = true; + break; + case PauseTarget::Time: + if (verbose) + blog(LOG_INFO, "pause time switching"); + TimeSwitch::pause = true; + break; + case PauseTarget::Idle: + if (verbose) + blog(LOG_INFO, "pause idle switching"); + IdleData::pause = true; + break; + case PauseTarget::Sequence: + if (verbose) + blog(LOG_INFO, "pause sequence switching"); + SceneSequenceSwitch::pause = true; + break; + case PauseTarget::Audio: + if (verbose) + blog(LOG_INFO, "pause audio switching"); + AudioSwitch::pause = true; + break; } } -int AdvSceneSwitcher::PauseScenesFindByData(const QString &scene) +bool checkPauseScene(obs_weak_source_t *currentScene, obs_weak_source_t *scene, + PauseTarget &target, bool &verbose) { - int count = ui->pauseScenes->count(); - int idx = -1; + if (currentScene != scene) + return false; - for (int i = 0; i < count; i++) { - QListWidgetItem *item = ui->pauseScenes->item(i); - QString itemRegion = item->data(Qt::UserRole).toString(); - - if (itemRegion == scene) { - idx = i; - break; - } - } - - return idx; + setPauseTarget(target, verbose); + if (target == PauseTarget::All) + return true; + return false; } - -int AdvSceneSwitcher::PauseWindowsFindByData(const QString &window) +bool checkPauseWindow(std::string ¤tTitle, std::string &title, + PauseTarget &target, bool &verbose) { - int count = ui->pauseWindows->count(); - int idx = -1; + if (currentTitle != title) + return false; - for (int i = 0; i < count; i++) { - QListWidgetItem *item = ui->pauseWindows->item(i); - QString itemRegion = item->data(Qt::UserRole).toString(); - - if (itemRegion == window) { - idx = i; - break; - } - } - - return idx; + setPauseTarget(target, verbose); + if (target == PauseTarget::All) + return true; + return false; } bool SwitcherData::checkPause() { - bool pause = false; + bool pauseAll = false; + + std::string title; + GetCurrentWindowTitle(title); + + resetPause(); + obs_source_t *currentSource = obs_frontend_get_current_scene(); obs_weak_source_t *ws = obs_source_get_weak_source(currentSource); - for (OBSWeakSource &s : pauseScenesSwitches) { - if (s == ws) { - pause = true; + for (PauseEntry &s : pauseEntries) { + if (s.pauseType == PauseType::Scene) + pauseAll = checkPauseScene(ws, s.scene, s.pauseTarget, + verbose); + else + pauseAll = checkPauseWindow(title, s.window, + s.pauseTarget, verbose); + if (pauseAll) break; - } } + obs_source_release(currentSource); obs_weak_source_release(ws); - std::string title; - if (!pause) { - //lock.unlock(); - GetCurrentWindowTitle(title); - //lock.lock(); - for (std::string &window : pauseWindowsSwitches) { - if (window == title) { - pause = true; - break; - } - } - } - - if (!pause) { - //lock.unlock(); - GetCurrentWindowTitle(title); - //lock.lock(); - for (std::string &window : pauseWindowsSwitches) { - try { - bool matches = std::regex_match( - title, std::regex(window)); - if (matches) { - pause = true; - break; - } - } catch (const std::regex_error &) { - } - } - } - - if (verbose && pause) - blog(LOG_INFO, "pause match"); - - return pause; + return pauseAll; } void SwitcherData::savePauseSwitches(obs_data_t *obj) { obs_data_array_t *pauseScenesArray = obs_data_array_create(); - for (OBSWeakSource &scene : switcher->pauseScenesSwitches) { + for (PauseEntry &s : switcher->pauseEntries) { obs_data_t *array_obj = obs_data_create(); - obs_source_t *source = obs_weak_source_get_source(scene); + obs_data_set_int(array_obj, "pauseType", + static_cast(s.pauseType)); + obs_data_set_int(array_obj, "pauseTarget", + static_cast(s.pauseTarget)); + obs_data_set_string(array_obj, "pauseWindow", s.window.c_str()); + + obs_source_t *source = obs_weak_source_get_source(s.scene); if (source) { const char *n = obs_source_get_name(source); obs_data_set_string(array_obj, "pauseScene", n); - obs_data_array_push_back(pauseScenesArray, array_obj); } + + obs_data_array_push_back(pauseScenesArray, array_obj); + obs_source_release(source); obs_data_release(array_obj); } - obs_data_set_array(obj, "pauseScenes", pauseScenesArray); + obs_data_set_array(obj, "pauseEntries", pauseScenesArray); + obs_data_set_int(obj, "oldPauseValuesImported", 1); obs_data_array_release(pauseScenesArray); - - obs_data_array_t *pauseWindowsArray = obs_data_array_create(); - for (std::string &window : switcher->pauseWindowsSwitches) { - obs_data_t *array_obj = obs_data_create(); - obs_data_set_string(array_obj, "pauseWindow", window.c_str()); - obs_data_array_push_back(pauseWindowsArray, array_obj); - obs_data_release(array_obj); - } - obs_data_set_array(obj, "pauseWindows", pauseWindowsArray); - obs_data_array_release(pauseWindowsArray); } void SwitcherData::loadPauseSwitches(obs_data_t *obj) { - switcher->pauseScenesSwitches.clear(); + switcher->pauseEntries.clear(); + + // To be removed in future builds once most users have migrated + loadOldPauseSwitches(obj); + + obs_data_array_t *pauseArray = obs_data_get_array(obj, "pauseEntries"); + size_t count = obs_data_array_count(pauseArray); + + for (size_t i = 0; i < count; i++) { + obs_data_t *array_obj = obs_data_array_item(pauseArray, i); + + PauseType type = static_cast( + obs_data_get_int(array_obj, "pauseType")); + PauseTarget target = static_cast( + obs_data_get_int(array_obj, "pauseTarget")); + const char *scene = + obs_data_get_string(array_obj, "pauseScene"); + const char *window = + obs_data_get_string(array_obj, "pauseWindow"); + + switcher->pauseEntries.emplace_back(GetWeakSourceByName(scene), + type, target, window); + + obs_data_release(array_obj); + } + obs_data_array_release(pauseArray); +} + +void SwitcherData::loadOldPauseSwitches(obs_data_t *obj) +{ + if (obs_data_get_int(obj, "oldPauseValuesImported")) + return; obs_data_array_t *pauseScenesArray = obs_data_get_array(obj, "pauseScenes"); @@ -273,15 +274,14 @@ void SwitcherData::loadPauseSwitches(obs_data_t *obj) const char *scene = obs_data_get_string(array_obj, "pauseScene"); - switcher->pauseScenesSwitches.emplace_back( - GetWeakSourceByName(scene)); + switcher->pauseEntries.emplace_back(GetWeakSourceByName(scene), + PauseType::Scene, + PauseTarget::All, ""); obs_data_release(array_obj); } obs_data_array_release(pauseScenesArray); - switcher->pauseWindowsSwitches.clear(); - obs_data_array_t *pauseWindowsArray = obs_data_get_array(obj, "pauseWindows"); count = obs_data_array_count(pauseWindowsArray); @@ -293,7 +293,8 @@ void SwitcherData::loadPauseSwitches(obs_data_t *obj) const char *window = obs_data_get_string(array_obj, "pauseWindow"); - switcher->pauseWindowsSwitches.emplace_back(window); + switcher->pauseEntries.emplace_back(nullptr, PauseType::Window, + PauseTarget::All, window); obs_data_release(array_obj); } @@ -302,23 +303,153 @@ void SwitcherData::loadPauseSwitches(obs_data_t *obj) void AdvSceneSwitcher::setupPauseTab() { - populateSceneSelection(ui->pauseScenesScenes, false); - populateWindowSelection(ui->pauseWindowsWindows); - - for (auto &scene : switcher->pauseScenesSwitches) { - std::string sceneName = GetWeakSourceName(scene); - QString text = QString::fromStdString(sceneName); - - QListWidgetItem *item = - new QListWidgetItem(text, ui->pauseScenes); - item->setData(Qt::UserRole, text); + for (auto &s : switcher->pauseEntries) { + QListWidgetItem *item; + item = new QListWidgetItem(ui->pauseEntries); + ui->pauseEntries->addItem(item); + PauseEntryWidget *sw = new PauseEntryWidget(&s); + item->setSizeHint(sw->minimumSizeHint()); + ui->pauseEntries->setItemWidget(item, sw); } - for (auto &window : switcher->pauseWindowsSwitches) { - QString text = QString::fromStdString(window); + if (switcher->pauseEntries.size() == 0) + addPulse = PulseWidget(ui->pauseAdd, QColor(Qt::green)); +} - QListWidgetItem *item = - new QListWidgetItem(text, ui->pauseWindows); - item->setData(Qt::UserRole, text); +void populatePauseTypes(QComboBox *list) +{ + list->addItem( + obs_module_text("AdvSceneSwitcher.pauseTab.pauseTypeScene")); + list->addItem( + obs_module_text("AdvSceneSwitcher.pauseTab.pauseTypeWindow")); +} + +void populatePauseTargets(QComboBox *list) +{ + list->addItem( + obs_module_text("AdvSceneSwitcher.pauseTab.pauseTargetAll")); + list->addItem(obs_module_text("AdvSceneSwitcher.transitionTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.windowTitleTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.executableTab.title")); + list->addItem( + obs_module_text("AdvSceneSwitcher.screenRegionTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.mediaTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.fileTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.randomTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.timeTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.idleTab.title")); + list->addItem( + obs_module_text("AdvSceneSwitcher.sceneSequenceTab.title")); + list->addItem(obs_module_text("AdvSceneSwitcher.audioTab.title")); +} + +PauseEntryWidget::PauseEntryWidget(PauseEntry *s) : SwitchWidget(s, false) +{ + pauseTypes = new QComboBox(); + pauseTargets = new QComboBox(); + windows = new QComboBox(); + + QWidget::connect(pauseTypes, SIGNAL(currentIndexChanged(int)), this, + SLOT(PauseTypeChanged(int))); + QWidget::connect(pauseTargets, SIGNAL(currentIndexChanged(int)), this, + SLOT(PauseTargetChanged(int))); + QWidget::connect(windows, SIGNAL(currentTextChanged(const QString &)), + this, SLOT(WindowChanged(const QString &))); + + populatePauseTypes(pauseTypes); + populatePauseTargets(pauseTargets); + AdvSceneSwitcher::populateWindowSelection(windows); + + windows->setEditable(true); + windows->setMaxVisibleItems(20); + + if (s) { + scenes->setCurrentText(GetWeakSourceName(s->scene).c_str()); + pauseTypes->setCurrentIndex(static_cast(s->pauseType)); + pauseTargets->setCurrentIndex(static_cast(s->pauseTarget)); + windows->setCurrentText(s->window.c_str()); + if (s->pauseType == PauseType::Scene) { + windows->setDisabled(true); + windows->setVisible(false); + } else { + scenes->setDisabled(true); + scenes->setVisible(false); + } + } + + QHBoxLayout *mainLayout = new QHBoxLayout; + std::unordered_map widgetPlaceholders = { + {"{{scenes}}", scenes}, + {"{{pauseTypes}}", pauseTypes}, + {"{{pauseTargets}}", pauseTargets}, + {"{{windows}}", windows}}; + + placeWidgets(obs_module_text("AdvSceneSwitcher.pauseTab.pauseEntry"), + mainLayout, widgetPlaceholders); + setLayout(mainLayout); + + switchData = s; + + loading = false; +} + +PauseEntry *PauseEntryWidget::getSwitchData() +{ + return switchData; +} + +void PauseEntryWidget::setSwitchData(PauseEntry *s) +{ + switchData = s; +} + +void PauseEntryWidget::swapSwitchData(PauseEntryWidget *s1, + PauseEntryWidget *s2) +{ + SwitchWidget::swapSwitchData(s1, s2); + + PauseEntry *t = s1->getSwitchData(); + s1->setSwitchData(s2->getSwitchData()); + s2->setSwitchData(t); +} + +void PauseEntryWidget::PauseTypeChanged(int index) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->pauseType = static_cast(index); + + if (switchData->pauseType == PauseType::Scene) { + windows->setDisabled(true); + windows->setVisible(false); + scenes->setDisabled(false); + scenes->setVisible(true); + } else { + scenes->setDisabled(true); + scenes->setVisible(false); + windows->setDisabled(false); + windows->setVisible(true); } } + +void PauseEntryWidget::PauseTargetChanged(int index) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->pauseTarget = static_cast(index); +} + +void PauseEntryWidget::WindowChanged(const QString &text) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->window = text.toStdString(); +} + +bool PauseEntry::valid() +{ + return true; +} diff --git a/src/switch-random.cpp b/src/switch-random.cpp index c8367f5b..2a79b024 100644 --- a/src/switch-random.cpp +++ b/src/switch-random.cpp @@ -3,6 +3,7 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool RandomSwitch::pause = false; static QMetaObject::Connection addPulse; void AdvSceneSwitcher::on_randomAdd_clicked() @@ -34,7 +35,7 @@ void AdvSceneSwitcher::on_randomRemove_clicked() void SwitcherData::checkRandom(bool &match, OBSWeakSource &scene, OBSWeakSource &transition, int &delay) { - if (randomSwitches.size() == 0) + if (randomSwitches.size() == 0 || RandomSwitch::pause) return; std::deque rs(randomSwitches); diff --git a/src/switch-screen-region.cpp b/src/switch-screen-region.cpp index 8adc3958..f3b29543 100644 --- a/src/switch-screen-region.cpp +++ b/src/switch-screen-region.cpp @@ -3,6 +3,7 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool ScreenRegionSwitch::pause = false; static QMetaObject::Connection addPulse; void AdvSceneSwitcher::clearFrames(QListWidget *list) @@ -132,6 +133,9 @@ void AdvSceneSwitcher::on_screenRegionDown_clicked() void SwitcherData::checkScreenRegionSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { + if (ScreenRegionSwitch::pause) + return; + std::pair cursorPos = getCursorPos(); int minRegionSize = 99999; diff --git a/src/switch-sequence.cpp b/src/switch-sequence.cpp index 10a7676d..080e433e 100644 --- a/src/switch-sequence.cpp +++ b/src/switch-sequence.cpp @@ -5,6 +5,7 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool SceneSequenceSwitch::pause = false; static QMetaObject::Connection addPulse; void AdvSceneSwitcher::on_sceneSequenceAdd_clicked() @@ -156,6 +157,9 @@ void SwitcherData::checkSceneSequence(bool &match, OBSWeakSource &scene, OBSWeakSource &transition, std::unique_lock &lock) { + if (SceneSequenceSwitch::pause) + return; + obs_source_t *currentSource = obs_frontend_get_current_scene(); obs_weak_source_t *ws = obs_source_get_weak_source(currentSource); diff --git a/src/switch-time.cpp b/src/switch-time.cpp index 9957de29..5fb72279 100644 --- a/src/switch-time.cpp +++ b/src/switch-time.cpp @@ -1,6 +1,7 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool TimeSwitch::pause = false; static QMetaObject::Connection addPulse; void AdvSceneSwitcher::on_timeAdd_clicked() @@ -107,7 +108,7 @@ bool checkRegularTime(TimeSwitch &s, int &interval) void SwitcherData::checkTimeSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { - if (timeSwitches.size() == 0) + if (TimeSwitch::pause) return; for (TimeSwitch &s : timeSwitches) { diff --git a/src/switch-transitions.cpp b/src/switch-transitions.cpp index b8f1c7c8..8db54672 100644 --- a/src/switch-transitions.cpp +++ b/src/switch-transitions.cpp @@ -1,6 +1,8 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool DefaultSceneTransition::pause = false; + void AdvSceneSwitcher::on_transitionsAdd_clicked() { std::lock_guard lock(switcher->m); @@ -138,7 +140,7 @@ void AdvSceneSwitcher::on_defaultTransitionsDown_clicked() void SwitcherData::checkDefaultSceneTransitions(bool &match, OBSWeakSource &transition) { - if (checkedDefTransition) + if (checkedDefTransition || DefaultSceneTransition::pause) return; obs_source_t *currentSource = obs_frontend_get_current_scene(); diff --git a/src/switch-window.cpp b/src/switch-window.cpp index 0df65ec3..df1dc320 100644 --- a/src/switch-window.cpp +++ b/src/switch-window.cpp @@ -1,6 +1,7 @@ #include "headers/advanced-scene-switcher.hpp" #include "headers/utility.hpp" +bool WindowSwitch::pause = false; static QMetaObject::Connection addPulse; void AdvSceneSwitcher::on_windowAdd_clicked() @@ -187,6 +188,9 @@ bool isFocused(std::string &title) void SwitcherData::checkWindowTitleSwitch(bool &match, OBSWeakSource &scene, OBSWeakSource &transition) { + if (WindowSwitch::pause) + return; + std::string title; bool ignored = false; diff --git a/src/switcher-data-structs.cpp b/src/switcher-data-structs.cpp index e2555917..53389268 100644 --- a/src/switcher-data-structs.cpp +++ b/src/switcher-data-structs.cpp @@ -27,11 +27,10 @@ void SwitcherData::Prune() 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 < pauseEntries.size(); i++) { + PauseEntry &s = pauseEntries[i]; + if (!s.valid()) + pauseEntries.erase(pauseEntries.begin() + i--); } for (size_t i = 0; i < sceneSequenceSwitches.size(); i++) {