mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-04-18 16:17:23 -05:00
Add scene groups and rework save and load (#103)
This commit is contained in:
parent
1f4679433e
commit
d989c2b570
|
|
@ -52,6 +52,7 @@ set(advanced-scene-switcher_HEADERS
|
|||
src/headers/utility.hpp
|
||||
src/headers/curl-helper.hpp
|
||||
src/headers/volume-control.hpp
|
||||
src/headers/scene-group.hpp
|
||||
src/headers/switch-audio.hpp
|
||||
src/headers/switch-executable.hpp
|
||||
src/headers/switch-file.hpp
|
||||
|
|
@ -73,6 +74,7 @@ set(advanced-scene-switcher_SOURCES
|
|||
src/advanced-scene-switcher.cpp
|
||||
src/advanced-scene-switcher-module.c
|
||||
src/switcher-data-structs.cpp
|
||||
src/scene-group.cpp
|
||||
src/switch-transitions.cpp
|
||||
src/switch-screen-region.cpp
|
||||
src/switch-priority.cpp
|
||||
|
|
|
|||
|
|
@ -190,6 +190,23 @@ AdvSceneSwitcher.audioTab.entry="Wenn die Lautstärke von {{audioSources}} {{con
|
|||
AdvSceneSwitcher.audioTab.multiMatchfallbackCondition="Wenn mehrere Einträge zutreffen ..."
|
||||
AdvSceneSwitcher.audioTab.multiMatchfallback="... für {{duration}} wechsle zu {{scenes}} mit {{transitions}}"
|
||||
|
||||
; Scene Group Tab
|
||||
AdvSceneSwitcher.sceneGroupTab.title="Szenengruppe"
|
||||
AdvSceneSwitcher.sceneGroupTab.list="Szenengruppen"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit="Szenengruppe bearbeiten"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.name="Name:"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.type="Typ: {{type}}"
|
||||
AdvSceneSwitcher.sceneGroupTab.type.count="Anzahl"
|
||||
AdvSceneSwitcher.sceneGroupTab.type.time="Zeit"
|
||||
AdvSceneSwitcher.sceneGroupTab.type.random="Zufall"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.count="Schreite zur nächsten Szene in dieser Gruppe fort nach {{count}} Szenewechseln"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.time="Schreite zur nächsten Szene in dieser Gruppe fort nach {{time}}"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.random="Wähle eine zufällig Szene in der Liste aus"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.repeat="Beginne von vorne wenn Ende der Szenenliste erreicht ist"
|
||||
AdvSceneSwitcher.sceneGroupTab.add="Szenengruppe hinzufügen"
|
||||
AdvSceneSwitcher.sceneGroupTab.defaultname="Szenengruppe %1"
|
||||
AdvSceneSwitcher.sceneGroupTab.exists="Szenengruppen- oder Szenenname existiert bereits"
|
||||
|
||||
; Hotkey
|
||||
AdvSceneSwitcher.hotkey.startSwitcherHotkey="Starte den Erweiteren Szenenwechsler"
|
||||
AdvSceneSwitcher.hotkey.stopSwitcherHotkey="Stoppe den Erweiteren Szenenwechsler"
|
||||
|
|
|
|||
|
|
@ -190,6 +190,23 @@ AdvSceneSwitcher.audioTab.entry="When the volume of {{audioSources}} is {{condit
|
|||
AdvSceneSwitcher.audioTab.multiMatchfallbackCondition="If multiple entries match ..."
|
||||
AdvSceneSwitcher.audioTab.multiMatchfallback="... for {{duration}} switch to {{scenes}} using {{transitions}}"
|
||||
|
||||
; Scene Group Tab
|
||||
AdvSceneSwitcher.sceneGroupTab.title="Scene Group"
|
||||
AdvSceneSwitcher.sceneGroupTab.list="Scene Groups"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit="Edit Scene Groups"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.name="Name:"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.type="Type: {{type}}"
|
||||
AdvSceneSwitcher.sceneGroupTab.type.count="Count"
|
||||
AdvSceneSwitcher.sceneGroupTab.type.time="Time"
|
||||
AdvSceneSwitcher.sceneGroupTab.type.random="Random"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.count="Advance to next scene in list after {{count}} matches"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.time="Advance to next scene in list after {{time}} has passed"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.random="Choose next scene in list at random"
|
||||
AdvSceneSwitcher.sceneGroupTab.edit.repeat="Start from beginning if end of scene list is reached"
|
||||
AdvSceneSwitcher.sceneGroupTab.add="Add Scene Group"
|
||||
AdvSceneSwitcher.sceneGroupTab.defaultname="Scene Group %1"
|
||||
AdvSceneSwitcher.sceneGroupTab.exists="Scene Group or Scene name exists already"
|
||||
|
||||
; Hotkey
|
||||
AdvSceneSwitcher.hotkey.startSwitcherHotkey="Start the Advanced Scene Switcher"
|
||||
AdvSceneSwitcher.hotkey.stopSwitcherHotkey="Stop the Advanced Scene Switcher"
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@
|
|||
<widget class="QComboBox" name="autoStopType"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.automaticallyStop2</string>
|
||||
</property>
|
||||
|
|
@ -3046,6 +3046,355 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="sceneGroupTab">
|
||||
<attribute name="title">
|
||||
<string>AdvSceneSwitcher.sceneGroupTab.title</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>AdvSceneSwitcher.sceneGroupTab.list</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_24">
|
||||
<item>
|
||||
<widget class="QListWidget" name="sceneGroups"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_54">
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupAdd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupRemove">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_117">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_39">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_116">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupUp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>../../../forms/images/up.svg</normaloff>../../../forms/images/up.svg</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string>upArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupDown">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>../../../forms/images/down.svg</normaloff>../../../forms/images/down.svg</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string>downArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_58">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="sceneGroupEdit">
|
||||
<property name="title">
|
||||
<string>AdvSceneSwitcher.sceneGroupTab.edit</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_25">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.sceneGroupTab.edit.name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="sceneGroupName"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="sceneGroupTypeEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QComboBox" name="sceneGroupSceneSelection"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="sceneGroupScenes"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_55">
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupSceneAdd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupSceneRemove">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_119">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_40">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_118">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupSceneUp">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>../../../forms/images/up.svg</normaloff>../../../forms/images/up.svg</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string>upArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="sceneGroupSceneDown">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>../../../forms/images/down.svg</normaloff>../../../forms/images/down.svg</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string>downArrowIconSmall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_59">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ void AdvSceneSwitcher::loadUI()
|
|||
setupFileTab();
|
||||
setupTimeTab();
|
||||
setupAudioTab();
|
||||
setupSceneGroupTab();
|
||||
|
||||
setTabOrder();
|
||||
|
||||
|
|
@ -109,8 +110,11 @@ void addSelectionEntry(QComboBox *sel, const char *description,
|
|||
}
|
||||
|
||||
void AdvSceneSwitcher::populateSceneSelection(QComboBox *sel, bool addPrevious,
|
||||
bool addSceneGroup,
|
||||
bool addSelect)
|
||||
{
|
||||
sel->clear();
|
||||
|
||||
if (addSelect)
|
||||
addSelectionEntry(
|
||||
sel, obs_module_text("AdvSceneSwitcher.selectScene"),
|
||||
|
|
@ -128,6 +132,12 @@ void AdvSceneSwitcher::populateSceneSelection(QComboBox *sel, bool addPrevious,
|
|||
if (addPrevious)
|
||||
sel->addItem(obs_module_text(
|
||||
"AdvSceneSwitcher.selectPreviousScene"));
|
||||
|
||||
if (addSceneGroup) {
|
||||
for (auto &sg : switcher->sceneGroups) {
|
||||
sel->addItem(QString::fromStdString(sg.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::populateTransitionSelection(QComboBox *sel,
|
||||
|
|
@ -347,6 +357,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||
|
||||
obs_data_t *obj = obs_data_create();
|
||||
|
||||
switcher->saveSceneGroups(obj);
|
||||
switcher->saveWindowTitleSwitches(obj);
|
||||
switcher->saveScreenRegionSwitches(obj);
|
||||
switcher->savePauseSwitches(obj);
|
||||
|
|
@ -377,6 +388,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
|||
if (switcher->versionChanged(obj, g_GIT_SHA1))
|
||||
AdvSceneSwitcher::AskBackup(obj);
|
||||
|
||||
switcher->loadSceneGroups(obj);
|
||||
switcher->loadWindowTitleSwitches(obj);
|
||||
switcher->loadScreenRegionSwitches(obj);
|
||||
switcher->loadPauseSwitches(obj);
|
||||
|
|
@ -546,6 +558,11 @@ endLoop:
|
|||
void switchScene(OBSWeakSource &scene, OBSWeakSource &transition,
|
||||
bool &transitionOverrideOverride)
|
||||
{
|
||||
if (!scene && switcher->verbose) {
|
||||
blog(LOG_INFO, "nothing to switch to");
|
||||
return;
|
||||
}
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(scene);
|
||||
obs_source_t *currentSource = obs_frontend_get_current_scene();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
|
||||
constexpr auto tab_count = 14;
|
||||
|
||||
QMetaObject::Connection inactivePluse;
|
||||
|
||||
void AdvSceneSwitcher::on_close_clicked()
|
||||
|
|
@ -468,6 +470,9 @@ int findTabIndex(QTabWidget *tabWidget, int pos)
|
|||
case 12:
|
||||
tabName = "audioTab";
|
||||
break;
|
||||
case 13:
|
||||
tabName = "sceneGroupTab";
|
||||
break;
|
||||
}
|
||||
|
||||
QWidget *page = tabWidget->findChild<QWidget *>(tabName);
|
||||
|
|
@ -567,8 +572,8 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
|||
|
||||
// After fresh install of OBS the vector can be empty
|
||||
// as save() might be called before first load()
|
||||
if (switcher->tabOrder.size() < 13) {
|
||||
switcher->tabOrder = std::vector<int>(13);
|
||||
if (switcher->tabOrder.size() < tab_count) {
|
||||
switcher->tabOrder = std::vector<int>(tab_count);
|
||||
std::iota(switcher->tabOrder.begin(), switcher->tabOrder.end(),
|
||||
0);
|
||||
}
|
||||
|
|
@ -586,6 +591,7 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
|
|||
obs_data_set_int(obj, "idleTabPos", switcher->tabOrder[10]);
|
||||
obs_data_set_int(obj, "sequenceTabPos", switcher->tabOrder[11]);
|
||||
obs_data_set_int(obj, "audioTabPos", switcher->tabOrder[12]);
|
||||
obs_data_set_int(obj, "sceneGroupTabPos", switcher->tabOrder[13]);
|
||||
}
|
||||
|
||||
void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
||||
|
|
@ -686,6 +692,7 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
|||
obs_data_set_default_int(obj, "idleTabPos", 10);
|
||||
obs_data_set_default_int(obj, "sequenceTabPos", 11);
|
||||
obs_data_set_default_int(obj, "audioTabPos", 12);
|
||||
obs_data_set_default_int(obj, "sceneGroupTabPos", 13);
|
||||
|
||||
switcher->tabOrder.emplace_back(
|
||||
(int)(obs_data_get_int(obj, "generalTabPos")));
|
||||
|
|
@ -713,6 +720,8 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
|
|||
(int)(obs_data_get_int(obj, "sequenceTabPos")));
|
||||
switcher->tabOrder.emplace_back(
|
||||
(int)(obs_data_get_int(obj, "audioTabPos")));
|
||||
switcher->tabOrder.emplace_back(
|
||||
(int)(obs_data_get_int(obj, "sceneGroupTabPos")));
|
||||
}
|
||||
|
||||
void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
void UpdateAutoStartScene(const QString &name);
|
||||
void UpdateIdleDataTransition(const QString &name);
|
||||
void UpdateIdleDataScene(const QString &name);
|
||||
void SetEditSceneGroup(SceneGroup &sg);
|
||||
|
||||
void loadUI();
|
||||
void setupGeneralTab();
|
||||
|
|
@ -54,13 +55,17 @@ public:
|
|||
void setupFileTab();
|
||||
void setupTimeTab();
|
||||
void setupAudioTab();
|
||||
void setupSceneGroupTab();
|
||||
void setTabOrder();
|
||||
|
||||
static bool DisplayMessage(QString msg, bool question = false);
|
||||
static void AskBackup(obs_data_t *obj);
|
||||
|
||||
static void populateSceneSelection(QComboBox *sel,
|
||||
bool addPrevious = false,
|
||||
bool addSceneGroup = false,
|
||||
bool addSelect = true);
|
||||
|
||||
static void populateTransitionSelection(QComboBox *sel,
|
||||
bool addSelect = true);
|
||||
static void populateWindowSelection(QComboBox *sel,
|
||||
|
|
@ -81,6 +86,11 @@ public:
|
|||
bool listMoveUp(QListWidget *list);
|
||||
bool listMoveDown(QListWidget *list);
|
||||
|
||||
signals:
|
||||
void SceneGroupAdded(const QString &name);
|
||||
void SceneGroupRemoved(const QString &name);
|
||||
void SceneGroupRenamed(const QString &oldName, const QString newName);
|
||||
|
||||
public slots:
|
||||
void on_windowUp_clicked();
|
||||
void on_windowDown_clicked();
|
||||
|
|
@ -189,6 +199,18 @@ public slots:
|
|||
void on_audioDown_clicked();
|
||||
void on_audioFallback_toggled(bool on);
|
||||
|
||||
void on_sceneGroupAdd_clicked();
|
||||
void on_sceneGroupRemove_clicked();
|
||||
void on_sceneGroupUp_clicked();
|
||||
void on_sceneGroupDown_clicked();
|
||||
void on_sceneGroupName_editingFinished();
|
||||
void on_sceneGroups_currentRowChanged(int idx);
|
||||
|
||||
void on_sceneGroupSceneAdd_clicked();
|
||||
void on_sceneGroupSceneRemove_clicked();
|
||||
void on_sceneGroupSceneUp_clicked();
|
||||
void on_sceneGroupSceneDown_clicked();
|
||||
|
||||
void on_priorityUp_clicked();
|
||||
void on_priorityDown_clicked();
|
||||
void on_threadPriority_currentTextChanged(const QString &text);
|
||||
|
|
|
|||
107
src/headers/scene-group.hpp
Normal file
107
src/headers/scene-group.hpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QSpinBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QCheckBox>
|
||||
#include <obs.hpp>
|
||||
|
||||
auto constexpr invalid_scene_group_name = "invalid-scene-group";
|
||||
|
||||
enum class AdvanceCondition {
|
||||
Count,
|
||||
Time,
|
||||
Random,
|
||||
};
|
||||
|
||||
struct SceneGroup {
|
||||
OBSWeakSource getNextScene();
|
||||
OBSWeakSource getNextSceneCount();
|
||||
OBSWeakSource getNextSceneTime();
|
||||
OBSWeakSource getNextSceneRandom();
|
||||
void advanceIdx();
|
||||
|
||||
std::string name = invalid_scene_group_name;
|
||||
AdvanceCondition type = AdvanceCondition::Count;
|
||||
std::vector<OBSWeakSource> scenes = {};
|
||||
int count = 1;
|
||||
double time = 0;
|
||||
bool repeat = false;
|
||||
|
||||
size_t currentIdx = 0;
|
||||
|
||||
int currentCount = -1;
|
||||
std::chrono::high_resolution_clock::time_point lastAdvTime;
|
||||
OBSWeakSource lastRandomScene = nullptr;
|
||||
|
||||
inline SceneGroup(){};
|
||||
inline SceneGroup(std::string name_) : name(name_){};
|
||||
inline SceneGroup(std::string name_, AdvanceCondition type_,
|
||||
std::vector<OBSWeakSource> scenes_, int count_,
|
||||
double time_, bool repeat_)
|
||||
: name(name_),
|
||||
type(type_),
|
||||
scenes(scenes_),
|
||||
count(count_),
|
||||
time(time_),
|
||||
repeat(repeat_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
enum class SwitchTargetType {
|
||||
Scene,
|
||||
SceneGroup,
|
||||
};
|
||||
|
||||
class SceneGroupEditWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SceneGroupEditWidget();
|
||||
void SetEditSceneGroup(SceneGroup *sg);
|
||||
void ShowCurrentTypeEdit();
|
||||
|
||||
private slots:
|
||||
void TypeChanged(int type);
|
||||
void CountChanged(int count);
|
||||
void TimeChanged(double time);
|
||||
void RepeatChanged(int state);
|
||||
|
||||
private:
|
||||
QComboBox *type;
|
||||
|
||||
QWidget *timeEdit;
|
||||
QWidget *countEdit;
|
||||
|
||||
QSpinBox *count;
|
||||
QDoubleSpinBox *time;
|
||||
QLabel *random;
|
||||
|
||||
QCheckBox *repeat;
|
||||
|
||||
SceneGroup *sceneGroup = nullptr;
|
||||
};
|
||||
|
||||
// Based on OBS's NameDialog
|
||||
class SGNameDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SGNameDialog(QWidget *parent);
|
||||
|
||||
// Returns true if user clicks OK, false otherwise
|
||||
// userTextInput returns string that user typed into dialog
|
||||
static bool AskForName(QWidget *parent, const QString &title,
|
||||
const QString &text, std::string &userTextInput,
|
||||
const QString &placeHolder = QString(""),
|
||||
int maxSize = 170);
|
||||
|
||||
private:
|
||||
QLabel *label;
|
||||
QLineEdit *userText;
|
||||
};
|
||||
|
|
@ -25,6 +25,8 @@ struct AudioSwitch : virtual SceneSwitcherEntry {
|
|||
const char *getType() { return "audio"; }
|
||||
bool initialized();
|
||||
bool valid();
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
static void setVolumeLevel(void *data,
|
||||
const float magnitude[MAX_AUDIO_CHANNELS],
|
||||
const float peak[MAX_AUDIO_CHANNELS],
|
||||
|
|
@ -32,10 +34,6 @@ struct AudioSwitch : virtual SceneSwitcherEntry {
|
|||
void resetVolmeter();
|
||||
|
||||
AudioSwitch(){};
|
||||
AudioSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
OBSWeakSource audioSource_, int volumeThreshold_,
|
||||
audioCondition condition_, double duration_,
|
||||
bool usePreviousScene_);
|
||||
AudioSwitch(const AudioSwitch &other);
|
||||
AudioSwitch(AudioSwitch &&other);
|
||||
~AudioSwitch();
|
||||
|
|
@ -46,6 +44,9 @@ struct AudioSwitch : virtual SceneSwitcherEntry {
|
|||
|
||||
struct AudioSwitchFallback : virtual SceneSwitcherEntry {
|
||||
const char *getType() { return "audio_fallback"; }
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
|
||||
bool enable = false;
|
||||
double duration = 0;
|
||||
unsigned int matchCount = 0;
|
||||
|
|
@ -55,7 +56,7 @@ class AudioSwitchWidget : public SwitchWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioSwitchWidget(AudioSwitch *s);
|
||||
AudioSwitchWidget(QWidget *parent, AudioSwitch *s);
|
||||
void UpdateVolmeterSource();
|
||||
AudioSwitch *getSwitchData();
|
||||
void setSwitchData(AudioSwitch *s);
|
||||
|
|
@ -83,7 +84,7 @@ class AudioSwitchFallbackWidget : public SwitchWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioSwitchFallbackWidget(AudioSwitchFallback *s);
|
||||
AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s);
|
||||
|
||||
private slots:
|
||||
void DurationChanged(double dur);
|
||||
|
|
|
|||
|
|
@ -11,22 +11,15 @@ struct ExecutableSwitch : SceneSwitcherEntry {
|
|||
bool inFocus = false;
|
||||
|
||||
const char *getType() { return "exec"; }
|
||||
|
||||
inline ExecutableSwitch(){};
|
||||
inline ExecutableSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
const QString &exe_, bool inFocus_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
exe(exe_),
|
||||
inFocus(inFocus_)
|
||||
{
|
||||
}
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
||||
class ExecutableSwitchWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExecutableSwitchWidget(ExecutableSwitch *s);
|
||||
ExecutableSwitchWidget(QWidget *parent, ExecutableSwitch *s);
|
||||
ExecutableSwitch *getSwitchData();
|
||||
void setSwitchData(ExecutableSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,29 +23,15 @@ struct FileSwitch : SceneSwitcherEntry {
|
|||
size_t lastHash = 0;
|
||||
|
||||
const char *getType() { return "file"; }
|
||||
|
||||
inline FileSwitch(){};
|
||||
inline FileSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
const char *file_, const char *text_, bool remote_,
|
||||
bool useRegex_, bool useTime_,
|
||||
bool onlyMatchIfChanged_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
file(file_),
|
||||
text(text_),
|
||||
remote(remote_),
|
||||
useRegex(useRegex_),
|
||||
useTime(useTime_),
|
||||
onlyMatchIfChanged(onlyMatchIfChanged_),
|
||||
lastMod()
|
||||
{
|
||||
}
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
||||
class FileSwitchWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileSwitchWidget(FileSwitch *s);
|
||||
FileSwitchWidget(QWidget *parent, FileSwitch *s);
|
||||
FileSwitch *getSwitchData();
|
||||
void setSwitchData(FileSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
#include <QComboBox>
|
||||
|
||||
struct SceneSwitcherEntry {
|
||||
SwitchTargetType targetType = SwitchTargetType::Scene;
|
||||
SceneGroup *group = nullptr;
|
||||
OBSWeakSource scene = nullptr;
|
||||
OBSWeakSource transition = nullptr;
|
||||
bool usePreviousScene = false;
|
||||
|
|
@ -10,7 +12,18 @@ struct SceneSwitcherEntry {
|
|||
virtual const char *getType() = 0;
|
||||
virtual bool initialized();
|
||||
virtual bool valid();
|
||||
virtual void logMatchScene();
|
||||
virtual void logMatchSceneGroup();
|
||||
virtual void logMatch();
|
||||
virtual OBSWeakSource getScene();
|
||||
virtual void save(obs_data_t *obj,
|
||||
const char *targetTypeSaveName = "targetType",
|
||||
const char *targetSaveName = "target",
|
||||
const char *transitionSaveName = "transition");
|
||||
virtual void load(obs_data_t *obj,
|
||||
const char *targetTypeLoadName = "targetType",
|
||||
const char *targetLoadName = "target",
|
||||
const char *transitionLoadName = "transition");
|
||||
|
||||
inline SceneSwitcherEntry() {}
|
||||
|
||||
|
|
@ -23,6 +36,26 @@ struct SceneSwitcherEntry {
|
|||
{
|
||||
}
|
||||
|
||||
inline SceneSwitcherEntry(SceneGroup *group_, OBSWeakSource transition_,
|
||||
bool usePreviousScene_ = false)
|
||||
: group(group_),
|
||||
transition(transition_),
|
||||
usePreviousScene(usePreviousScene_)
|
||||
{
|
||||
}
|
||||
|
||||
inline SceneSwitcherEntry(SwitchTargetType targetType_,
|
||||
SceneGroup *group_, OBSWeakSource scene_,
|
||||
OBSWeakSource transition_,
|
||||
bool usePreviousScene_ = false)
|
||||
: targetType(targetType_),
|
||||
group(group_),
|
||||
scene(scene_),
|
||||
transition(transition_),
|
||||
usePreviousScene(usePreviousScene_)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SceneSwitcherEntry() {}
|
||||
};
|
||||
|
||||
|
|
@ -30,7 +63,8 @@ class SwitchWidget : public QWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SwitchWidget(SceneSwitcherEntry *s, bool usePreviousScene = true);
|
||||
SwitchWidget(QWidget *parent, SceneSwitcherEntry *s,
|
||||
bool usePreviousScene = true, bool addSceneGroup = false);
|
||||
virtual SceneSwitcherEntry *getSwitchData();
|
||||
virtual void setSwitchData(SceneSwitcherEntry *s);
|
||||
|
||||
|
|
@ -39,6 +73,9 @@ public:
|
|||
private slots:
|
||||
void SceneChanged(const QString &text);
|
||||
void TransitionChanged(const QString &text);
|
||||
void SceneGroupAdd(const QString &name);
|
||||
void SceneGroupRemove(const QString &name);
|
||||
void SceneGroupRename(const QString &oldName, const QString &newName);
|
||||
|
||||
protected:
|
||||
bool loading = true;
|
||||
|
|
|
|||
|
|
@ -12,4 +12,6 @@ struct IdleData : SceneSwitcherEntry {
|
|||
bool alreadySwitched = false;
|
||||
|
||||
const char *getType() { return "idle"; }
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ struct MediaSwitch : SceneSwitcherEntry {
|
|||
const char *getType() { return "media"; }
|
||||
bool initialized();
|
||||
bool valid();
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
|
||||
void clearSignalHandler();
|
||||
void resetSignalHandler();
|
||||
|
|
@ -41,10 +43,7 @@ struct MediaSwitch : SceneSwitcherEntry {
|
|||
static void MediaEnded(void *data, calldata_t *);
|
||||
|
||||
inline MediaSwitch(){};
|
||||
inline MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
|
||||
OBSWeakSource transition_, obs_media_state state_,
|
||||
time_restriction restriction_, uint64_t time_,
|
||||
bool usePreviousScene_);
|
||||
|
||||
MediaSwitch(const MediaSwitch &other);
|
||||
MediaSwitch(MediaSwitch &&other);
|
||||
~MediaSwitch();
|
||||
|
|
@ -57,7 +56,7 @@ class MediaSwitchWidget : public SwitchWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MediaSwitchWidget(MediaSwitch *s);
|
||||
MediaSwitchWidget(QWidget *parent, MediaSwitch *s);
|
||||
MediaSwitch *getSwitchData();
|
||||
void setSwitchData(MediaSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class PauseEntryWidget : public SwitchWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PauseEntryWidget(PauseEntry *s);
|
||||
PauseEntryWidget(QWidget *parent, PauseEntry *s);
|
||||
PauseEntry *getSwitchData();
|
||||
void setSwitchData(PauseEntry *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,20 +6,15 @@ struct RandomSwitch : SceneSwitcherEntry {
|
|||
double delay = 0.0;
|
||||
|
||||
const char *getType() { return "random"; }
|
||||
|
||||
inline RandomSwitch() {}
|
||||
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
double delay_)
|
||||
: SceneSwitcherEntry(scene_, transition_), delay(delay_)
|
||||
{
|
||||
}
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
||||
class RandomSwitchWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RandomSwitchWidget(RandomSwitch *s);
|
||||
RandomSwitchWidget(QWidget *parent, RandomSwitch *s);
|
||||
RandomSwitch *getSwitchData();
|
||||
void setSwitchData(RandomSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,25 +10,15 @@ struct ScreenRegionSwitch : SceneSwitcherEntry {
|
|||
int minX = 0, minY = 0, maxX = 0, maxY = 0;
|
||||
|
||||
const char *getType() { return "region"; }
|
||||
|
||||
inline ScreenRegionSwitch(){};
|
||||
inline ScreenRegionSwitch(OBSWeakSource scene_,
|
||||
OBSWeakSource transition_, int minX_,
|
||||
int minY_, int maxX_, int maxY_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
minX(minX_),
|
||||
minY(minY_),
|
||||
maxX(maxX_),
|
||||
maxY(maxY_)
|
||||
{
|
||||
}
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
||||
class ScreenRegionWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScreenRegionWidget(ScreenRegionSwitch *s);
|
||||
ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s);
|
||||
ScreenRegionSwitch *getSwitchData();
|
||||
void setSwitchData(ScreenRegionSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,27 +22,15 @@ struct SceneSequenceSwitch : SceneSwitcherEntry {
|
|||
bool initialized();
|
||||
bool valid();
|
||||
void logSleep(int dur);
|
||||
|
||||
inline SceneSequenceSwitch(){};
|
||||
inline SceneSequenceSwitch(OBSWeakSource startScene_,
|
||||
OBSWeakSource scene_,
|
||||
OBSWeakSource transition_, double delay_,
|
||||
int delayMultiplier_, bool interruptible_,
|
||||
bool usePreviousScene_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
startScene(startScene_),
|
||||
delay(delay_),
|
||||
delayMultiplier(delayMultiplier_),
|
||||
interruptible(interruptible_)
|
||||
{
|
||||
}
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
||||
class SequenceWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SequenceWidget(SceneSequenceSwitch *s);
|
||||
SequenceWidget(QWidget *parent, SceneSequenceSwitch *s);
|
||||
SceneSequenceSwitch *getSwitchData();
|
||||
void setSwitchData(SceneSequenceSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,23 +24,15 @@ struct TimeSwitch : SceneSwitcherEntry {
|
|||
QTime time = QTime(0, 0);
|
||||
|
||||
const char *getType() { return "time"; }
|
||||
|
||||
inline TimeSwitch(){};
|
||||
inline TimeSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
timeTrigger trigger_, QTime time_,
|
||||
bool usePreviousScene_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
trigger(trigger_),
|
||||
time(time_)
|
||||
{
|
||||
}
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
||||
class TimeSwitchWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TimeSwitchWidget(TimeSwitch *s);
|
||||
TimeSwitchWidget(QWidget *parent, TimeSwitch *s);
|
||||
TimeSwitch *getSwitchData();
|
||||
void setSwitchData(TimeSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class TransitionSwitchWidget : public SwitchWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TransitionSwitchWidget(SceneTransition *s);
|
||||
TransitionSwitchWidget(QWidget *parent, SceneTransition *s);
|
||||
SceneTransition *getSwitchData();
|
||||
void setSwitchData(SceneTransition *s);
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ class DefTransitionSwitchWidget : public SwitchWidget {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DefTransitionSwitchWidget(DefaultSceneTransition *s);
|
||||
DefTransitionSwitchWidget(QWidget *parent, DefaultSceneTransition *s);
|
||||
DefaultSceneTransition *getSwitchData();
|
||||
void setSwitchData(DefaultSceneTransition *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,25 +12,15 @@ struct WindowSwitch : SceneSwitcherEntry {
|
|||
bool focus = true;
|
||||
|
||||
const char *getType() { return "window"; }
|
||||
|
||||
inline WindowSwitch() {}
|
||||
inline WindowSwitch(OBSWeakSource scene_, const char *window_,
|
||||
OBSWeakSource transition_, bool fullscreen_,
|
||||
bool maximized_, bool focus_)
|
||||
: SceneSwitcherEntry(scene_, transition_),
|
||||
window(window_),
|
||||
fullscreen(fullscreen_),
|
||||
maximized(maximized_),
|
||||
focus(focus_)
|
||||
{
|
||||
}
|
||||
void save(obs_data_t *obj);
|
||||
void load(obs_data_t *obj);
|
||||
};
|
||||
|
||||
class WindowSwitchWidget : public SwitchWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WindowSwitchWidget(WindowSwitch *s);
|
||||
WindowSwitchWidget(QWidget *parent, WindowSwitch *s);
|
||||
WindowSwitch *getSwitchData();
|
||||
void setSwitchData(WindowSwitch *s);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <QThread>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "scene-group.hpp"
|
||||
#include "switch-audio.hpp"
|
||||
#include "switch-executable.hpp"
|
||||
#include "switch-file.hpp"
|
||||
|
|
@ -114,6 +115,8 @@ struct SwitcherData {
|
|||
std::deque<AudioSwitch> audioSwitches;
|
||||
AudioSwitchFallback audioFallback;
|
||||
|
||||
std::deque<SceneGroup> sceneGroups;
|
||||
|
||||
std::vector<int> functionNamesByPriority = std::vector<int>{
|
||||
default_priority_0, default_priority_1, default_priority_2,
|
||||
default_priority_3, default_priority_4, default_priority_5,
|
||||
|
|
@ -210,6 +213,7 @@ struct SwitcherData {
|
|||
void saveMediaSwitches(obs_data_t *obj);
|
||||
void saveTimeSwitches(obs_data_t *obj);
|
||||
void saveAudioSwitches(obs_data_t *obj);
|
||||
void saveSceneGroups(obs_data_t *obj);
|
||||
void saveGeneralSettings(obs_data_t *obj);
|
||||
void saveHotkeys(obs_data_t *obj);
|
||||
void saveVersion(obs_data_t *obj, std::string currentVersion);
|
||||
|
|
@ -227,6 +231,7 @@ struct SwitcherData {
|
|||
void loadMediaSwitches(obs_data_t *obj);
|
||||
void loadTimeSwitches(obs_data_t *obj);
|
||||
void loadAudioSwitches(obs_data_t *obj);
|
||||
void loadSceneGroups(obs_data_t *obj);
|
||||
void loadGeneralSettings(obs_data_t *obj);
|
||||
void loadHotkeys(obs_data_t *obj);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@
|
|||
#include <obs-module.h>
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
static inline bool SceneGroupValid(SceneGroup *group)
|
||||
{
|
||||
if (group)
|
||||
return group->name != invalid_scene_group_name;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool WeakSourceValid(obs_weak_source_t *ws)
|
||||
{
|
||||
obs_source_t *source = obs_weak_source_get_source(ws);
|
||||
|
|
@ -30,6 +37,25 @@ static inline std::string GetWeakSourceName(obs_weak_source_t *weak_source)
|
|||
return name;
|
||||
}
|
||||
|
||||
static inline SceneGroup *GetSceneGroupByName(const char *name)
|
||||
{
|
||||
if (!switcher)
|
||||
return nullptr;
|
||||
|
||||
for (SceneGroup &sg : switcher->sceneGroups) {
|
||||
if (sg.name == name) {
|
||||
return &sg;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static inline SceneGroup *GetSceneGroupByQString(const QString &name)
|
||||
{
|
||||
return GetSceneGroupByName(name.toUtf8().constData());
|
||||
}
|
||||
|
||||
static inline OBSWeakSource GetWeakSourceByName(const char *name)
|
||||
{
|
||||
OBSWeakSource weak;
|
||||
|
|
|
|||
697
src/scene-group.cpp
Normal file
697
src/scene-group.cpp
Normal file
|
|
@ -0,0 +1,697 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <QDialogButtonBox>
|
||||
#include <random>
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
|
||||
static QMetaObject::Connection addPulse;
|
||||
SceneGroupEditWidget *typeEdit = nullptr;
|
||||
|
||||
void SceneGroup::advanceIdx()
|
||||
{
|
||||
currentIdx++;
|
||||
|
||||
if (currentIdx >= scenes.size()) {
|
||||
if (repeat)
|
||||
currentIdx = 0;
|
||||
else
|
||||
currentIdx = scenes.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
OBSWeakSource SceneGroup::getNextSceneCount()
|
||||
{
|
||||
currentCount++;
|
||||
if (currentCount >= count) {
|
||||
advanceIdx();
|
||||
currentCount = 0;
|
||||
}
|
||||
return scenes[currentIdx];
|
||||
}
|
||||
|
||||
OBSWeakSource SceneGroup::getNextSceneTime()
|
||||
{
|
||||
if (lastAdvTime.time_since_epoch().count() == 0)
|
||||
lastAdvTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
auto passedTime = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now - lastAdvTime);
|
||||
|
||||
if (passedTime.count() >= time * 1000) {
|
||||
advanceIdx();
|
||||
lastAdvTime = now;
|
||||
}
|
||||
|
||||
return scenes[currentIdx];
|
||||
}
|
||||
|
||||
OBSWeakSource SceneGroup::getNextSceneRandom()
|
||||
{
|
||||
if (scenes.size() == 1)
|
||||
return *scenes.begin();
|
||||
|
||||
std::vector<OBSWeakSource> rs(scenes);
|
||||
std::random_device rng;
|
||||
std::mt19937 urng(rng());
|
||||
std::shuffle(rs.begin(), rs.end(), urng);
|
||||
for (OBSWeakSource &s : rs) {
|
||||
if (s == lastRandomScene)
|
||||
continue;
|
||||
lastRandomScene = s;
|
||||
|
||||
return s;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OBSWeakSource SceneGroup::getNextScene()
|
||||
{
|
||||
if (scenes.empty())
|
||||
return nullptr;
|
||||
|
||||
switch (type) {
|
||||
case AdvanceCondition::Count:
|
||||
return getNextSceneCount();
|
||||
break;
|
||||
case AdvanceCondition::Time:
|
||||
return getNextSceneTime();
|
||||
break;
|
||||
case AdvanceCondition::Random:
|
||||
return getNextSceneRandom();
|
||||
break;
|
||||
}
|
||||
|
||||
blog(LOG_INFO, "unknown scene group type!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool sceneGroupNameExists(std::string name)
|
||||
{
|
||||
obs_source_t *source = obs_get_source_by_name(name.c_str());
|
||||
if (source) {
|
||||
obs_source_release(source);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (SceneGroup &sg : switcher->sceneGroups) {
|
||||
if (sg.name == name)
|
||||
return true;
|
||||
}
|
||||
|
||||
return (name == obs_module_text(
|
||||
"AdvSceneSwitcher.selectPreviousScene") ||
|
||||
(name == invalid_scene_group_name));
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupAdd_clicked()
|
||||
{
|
||||
std::string name;
|
||||
QString format{
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.defaultname")};
|
||||
|
||||
int i = 1;
|
||||
QString placeHolderText = format.arg(i);
|
||||
while ((sceneGroupNameExists(placeHolderText.toUtf8().constData()))) {
|
||||
placeHolderText = format.arg(++i);
|
||||
}
|
||||
|
||||
bool accepted = SGNameDialog::AskForName(
|
||||
this, obs_module_text("AdvSceneSwitcher.sceneGroupTab.add"),
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.add"), name,
|
||||
placeHolderText);
|
||||
|
||||
if (!accepted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sceneGroupNameExists(name)) {
|
||||
DisplayMessage(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneGroupTab.exists"));
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->sceneGroups.emplace_back(name);
|
||||
}
|
||||
QString text = QString::fromStdString(name);
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem(text, ui->sceneGroups);
|
||||
item->setData(Qt::UserRole, text);
|
||||
ui->sceneGroups->setCurrentItem(item);
|
||||
|
||||
ui->sceneGroupAdd->disconnect(addPulse);
|
||||
|
||||
emit SceneGroupAdded(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupRemove_clicked()
|
||||
{
|
||||
QListWidgetItem *item = ui->sceneGroups->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QString name;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
int idx = ui->sceneGroups->currentRow();
|
||||
auto &sg = switcher->sceneGroups;
|
||||
name = QString::fromStdString(sg[idx].name);
|
||||
sg.erase(sg.begin() + idx);
|
||||
}
|
||||
|
||||
delete item;
|
||||
|
||||
emit SceneGroupRemoved(name);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupUp_clicked()
|
||||
{
|
||||
int index = ui->sceneGroups->currentRow();
|
||||
if (index != -1 && index != 0) {
|
||||
ui->sceneGroups->insertItem(index - 1,
|
||||
ui->sceneGroups->takeItem(index));
|
||||
ui->sceneGroups->setCurrentRow(index - 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->sceneGroups.begin() + index,
|
||||
switcher->sceneGroups.begin() + index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupDown_clicked()
|
||||
{
|
||||
int index = ui->sceneGroups->currentRow();
|
||||
if (index != -1 && index != ui->sceneGroups->count() - 1) {
|
||||
ui->sceneGroups->insertItem(index + 1,
|
||||
ui->sceneGroups->takeItem(index));
|
||||
ui->sceneGroups->setCurrentRow(index + 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->sceneGroups.begin() + index,
|
||||
switcher->sceneGroups.begin() + index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
SceneGroup *getSelectedSG(Ui_AdvSceneSwitcher *ui)
|
||||
{
|
||||
SceneGroup *currentSG = nullptr;
|
||||
QListWidgetItem *sgItem = ui->sceneGroups->currentItem();
|
||||
|
||||
if (!sgItem)
|
||||
return currentSG;
|
||||
|
||||
QString sgName = sgItem->data(Qt::UserRole).toString();
|
||||
for (auto &sg : switcher->sceneGroups) {
|
||||
if (sgName.compare(sg.name.c_str()) == 0) {
|
||||
currentSG = &sg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return currentSG;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupName_editingFinished()
|
||||
{
|
||||
bool nameValid = true;
|
||||
|
||||
SceneGroup *currentSG = getSelectedSG(ui.get());
|
||||
if (!currentSG)
|
||||
return;
|
||||
|
||||
QString newName = ui->sceneGroupName->text();
|
||||
QString oldName = QString::fromStdString(currentSG->name);
|
||||
|
||||
if (newName.isEmpty() || newName == oldName) {
|
||||
nameValid = false;
|
||||
}
|
||||
|
||||
if (nameValid && sceneGroupNameExists(newName.toUtf8().constData())) {
|
||||
DisplayMessage(obs_module_text(
|
||||
"AdvSceneSwitcher.sceneGroupTab.exists"));
|
||||
nameValid = false;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
if (nameValid) {
|
||||
currentSG->name = newName.toUtf8().constData();
|
||||
QListWidgetItem *sgItem =
|
||||
ui->sceneGroups->currentItem();
|
||||
sgItem->setData(Qt::UserRole, newName);
|
||||
sgItem->setText(newName);
|
||||
} else {
|
||||
ui->sceneGroupName->setText(oldName);
|
||||
}
|
||||
}
|
||||
emit SceneGroupRenamed(oldName, newName);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::SetEditSceneGroup(SceneGroup &sg)
|
||||
{
|
||||
ui->sceneGroupName->setText(sg.name.c_str());
|
||||
ui->sceneGroupScenes->clear();
|
||||
|
||||
for (auto &s : sg.scenes) {
|
||||
QString sceneName =
|
||||
QString::fromStdString(GetWeakSourceName(s));
|
||||
QVariant v = QVariant::fromValue(sceneName);
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(sceneName, ui->sceneGroupScenes);
|
||||
item->setData(Qt::UserRole, v);
|
||||
}
|
||||
|
||||
ui->sceneGroupEdit->setDisabled(false);
|
||||
typeEdit->SetEditSceneGroup(&sg);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroups_currentRowChanged(int idx)
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1) {
|
||||
ui->sceneGroupEdit->setDisabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
QListWidgetItem *item = ui->sceneGroups->item(idx);
|
||||
QString sgName = item->data(Qt::UserRole).toString();
|
||||
|
||||
for (auto &sg : switcher->sceneGroups) {
|
||||
if (sgName.compare(sg.name.c_str()) == 0) {
|
||||
SetEditSceneGroup(sg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupSceneAdd_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
SceneGroup *currentSG = getSelectedSG(ui.get());
|
||||
if (!currentSG)
|
||||
return;
|
||||
|
||||
QString sceneName = ui->sceneGroupSceneSelection->currentText();
|
||||
|
||||
if (sceneName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sceneName);
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
QVariant v = QVariant::fromValue(sceneName);
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(sceneName, ui->sceneGroupScenes);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
currentSG->scenes.emplace_back(source);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupSceneRemove_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
SceneGroup *currentSG = getSelectedSG(ui.get());
|
||||
if (!currentSG)
|
||||
return;
|
||||
|
||||
int idx = ui->sceneGroupScenes->currentRow();
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
auto &scenes = currentSG->scenes;
|
||||
scenes.erase(scenes.begin() + idx);
|
||||
|
||||
auto item = ui->sceneGroupScenes->currentItem();
|
||||
delete item;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupSceneUp_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
SceneGroup *currentSG = getSelectedSG(ui.get());
|
||||
if (!currentSG)
|
||||
return;
|
||||
|
||||
int index = ui->sceneGroupScenes->currentRow();
|
||||
if (index != -1 && index != 0) {
|
||||
ui->sceneGroupScenes->insertItem(
|
||||
index - 1, ui->sceneGroupScenes->takeItem(index));
|
||||
ui->sceneGroupScenes->setCurrentRow(index - 1);
|
||||
|
||||
iter_swap(currentSG->scenes.begin() + index,
|
||||
currentSG->scenes.begin() + index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneGroupSceneDown_clicked()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
SceneGroup *currentSG = getSelectedSG(ui.get());
|
||||
if (!currentSG)
|
||||
return;
|
||||
|
||||
int index = ui->sceneGroupScenes->currentRow();
|
||||
if (index != -1 && index != ui->sceneGroupScenes->count() - 1) {
|
||||
ui->sceneGroupScenes->insertItem(
|
||||
index + 1, ui->sceneGroupScenes->takeItem(index));
|
||||
ui->sceneGroupScenes->setCurrentRow(index + 1);
|
||||
|
||||
iter_swap(currentSG->scenes.begin() + index,
|
||||
currentSG->scenes.begin() + index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SwitcherData::saveSceneGroups(obs_data_t *obj)
|
||||
{
|
||||
obs_data_array_t *sceneGroupArray = obs_data_array_create();
|
||||
for (SceneGroup &sg : switcher->sceneGroups) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_data_set_string(array_obj, "name", sg.name.c_str());
|
||||
obs_data_set_int(array_obj, "type", static_cast<int>(sg.type));
|
||||
|
||||
obs_data_array_t *scenesArray = obs_data_array_create();
|
||||
|
||||
for (OBSWeakSource s : sg.scenes) {
|
||||
obs_data_t *sceneArray_obj = obs_data_create();
|
||||
obs_source_t *source = obs_weak_source_get_source(s);
|
||||
|
||||
if (source) {
|
||||
const char *name = obs_source_get_name(source);
|
||||
obs_data_set_string(sceneArray_obj, "scene",
|
||||
name);
|
||||
}
|
||||
|
||||
obs_source_release(source);
|
||||
|
||||
obs_data_array_push_back(scenesArray, sceneArray_obj);
|
||||
obs_data_release(sceneArray_obj);
|
||||
}
|
||||
obs_data_set_array(array_obj, "scenes", scenesArray);
|
||||
obs_data_array_release(scenesArray);
|
||||
|
||||
obs_data_set_int(array_obj, "count", sg.count);
|
||||
obs_data_set_double(array_obj, "time", sg.time);
|
||||
obs_data_set_bool(array_obj, "repeat", sg.repeat);
|
||||
|
||||
obs_data_array_push_back(sceneGroupArray, array_obj);
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "sceneGroups", sceneGroupArray);
|
||||
obs_data_array_release(sceneGroupArray);
|
||||
}
|
||||
|
||||
void SwitcherData::loadSceneGroups(obs_data_t *obj)
|
||||
{
|
||||
switcher->sceneGroups.clear();
|
||||
|
||||
obs_data_array_t *sceneGroupArray =
|
||||
obs_data_get_array(obj, "sceneGroups");
|
||||
size_t count = obs_data_array_count(sceneGroupArray);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(sceneGroupArray, i);
|
||||
|
||||
const char *name = obs_data_get_string(array_obj, "name");
|
||||
AdvanceCondition type = static_cast<AdvanceCondition>(
|
||||
obs_data_get_int(array_obj, "type"));
|
||||
|
||||
std::vector<OBSWeakSource> scenes;
|
||||
obs_data_array_t *scenesArray =
|
||||
obs_data_get_array(array_obj, "scenes");
|
||||
size_t scenesCount = obs_data_array_count(scenesArray);
|
||||
for (size_t j = 0; j < scenesCount; j++) {
|
||||
obs_data_t *scenesArray_obj =
|
||||
obs_data_array_item(scenesArray, j);
|
||||
const char *scene =
|
||||
obs_data_get_string(scenesArray_obj, "scene");
|
||||
scenes.emplace_back(GetWeakSourceByName(scene));
|
||||
obs_data_release(scenesArray_obj);
|
||||
}
|
||||
obs_data_array_release(scenesArray);
|
||||
|
||||
int count = obs_data_get_int(array_obj, "count");
|
||||
double time = obs_data_get_double(array_obj, "time");
|
||||
bool repeat = obs_data_get_bool(array_obj, "repeat");
|
||||
|
||||
switcher->sceneGroups.emplace_back(name, type, scenes, count,
|
||||
time, repeat);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_array_release(sceneGroupArray);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::setupSceneGroupTab()
|
||||
{
|
||||
populateSceneSelection(ui->sceneGroupSceneSelection);
|
||||
|
||||
for (auto &sg : switcher->sceneGroups) {
|
||||
QString text = QString::fromStdString(sg.name);
|
||||
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(text, ui->sceneGroups);
|
||||
item->setData(Qt::UserRole, text);
|
||||
}
|
||||
|
||||
if (switcher->sceneGroups.size() == 0)
|
||||
addPulse = PulseWidget(ui->sceneGroupAdd, QColor(Qt::green));
|
||||
|
||||
typeEdit = new SceneGroupEditWidget();
|
||||
ui->sceneGroupTypeEdit->addWidget(typeEdit);
|
||||
|
||||
ui->sceneGroupEdit->setDisabled(true);
|
||||
}
|
||||
|
||||
SGNameDialog::SGNameDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setModal(true);
|
||||
setWindowModality(Qt::WindowModality::WindowModal);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setFixedWidth(555);
|
||||
setMinimumHeight(100);
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
setLayout(layout);
|
||||
|
||||
label = new QLabel(this);
|
||||
layout->addWidget(label);
|
||||
label->setText("Set Text");
|
||||
|
||||
userText = new QLineEdit(this);
|
||||
layout->addWidget(userText);
|
||||
|
||||
QDialogButtonBox *buttonbox = new QDialogButtonBox(
|
||||
QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
layout->addWidget(buttonbox);
|
||||
buttonbox->setCenterButtons(true);
|
||||
connect(buttonbox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttonbox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
}
|
||||
|
||||
static bool IsWhitespace(char ch)
|
||||
{
|
||||
return ch == ' ' || ch == '\t';
|
||||
}
|
||||
|
||||
static void CleanWhitespace(std::string &str)
|
||||
{
|
||||
while (str.size() && IsWhitespace(str.back()))
|
||||
str.erase(str.end() - 1);
|
||||
while (str.size() && IsWhitespace(str.front()))
|
||||
str.erase(str.begin());
|
||||
}
|
||||
|
||||
bool SGNameDialog::AskForName(QWidget *parent, const QString &title,
|
||||
const QString &text, std::string &userTextInput,
|
||||
const QString &placeHolder, int maxSize)
|
||||
{
|
||||
if (maxSize <= 0 || maxSize > 32767)
|
||||
maxSize = 170;
|
||||
|
||||
SGNameDialog dialog(parent);
|
||||
dialog.setWindowTitle(title);
|
||||
|
||||
dialog.label->setText(text);
|
||||
dialog.userText->setMaxLength(maxSize);
|
||||
dialog.userText->setText(placeHolder);
|
||||
dialog.userText->selectAll();
|
||||
|
||||
if (dialog.exec() != DialogCode::Accepted) {
|
||||
return false;
|
||||
}
|
||||
userTextInput = dialog.userText->text().toUtf8().constData();
|
||||
CleanWhitespace(userTextInput);
|
||||
return true;
|
||||
}
|
||||
|
||||
void populateTypeSelection(QComboBox *list)
|
||||
{
|
||||
list->addItem(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.type.count"));
|
||||
list->addItem(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.type.time"));
|
||||
list->addItem(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.type.random"));
|
||||
}
|
||||
|
||||
SceneGroupEditWidget::SceneGroupEditWidget()
|
||||
{
|
||||
//w->setContentsMargins(0, 0, 0, 0);
|
||||
type = new QComboBox();
|
||||
populateTypeSelection(type);
|
||||
|
||||
QWidget::connect(type, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(TypeChanged(int)));
|
||||
|
||||
QHBoxLayout *typeLayout = new QHBoxLayout();
|
||||
typeLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{type}}", type}};
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.type"),
|
||||
typeLayout, widgetPlaceholders);
|
||||
|
||||
countEdit = new QWidget();
|
||||
count = new QSpinBox();
|
||||
|
||||
count->setMinimum(1);
|
||||
count->setMaximum(999);
|
||||
|
||||
QWidget::connect(count, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(CountChanged(int)));
|
||||
|
||||
QHBoxLayout *countLayout = new QHBoxLayout(countEdit);
|
||||
countLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
widgetPlaceholders = {{"{{count}}", count}};
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.count"),
|
||||
countLayout, widgetPlaceholders);
|
||||
|
||||
timeEdit = new QWidget();
|
||||
time = new QDoubleSpinBox();
|
||||
|
||||
time->setMinimum(0.0);
|
||||
time->setMaximum(99999999.00);
|
||||
time->setSuffix("s");
|
||||
|
||||
QWidget::connect(time, SIGNAL(valueChanged(double)), this,
|
||||
SLOT(TimeChanged(double)));
|
||||
|
||||
QHBoxLayout *timeLayout = new QHBoxLayout(timeEdit);
|
||||
timeLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
widgetPlaceholders = {{"{{time}}", time}};
|
||||
placeWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.time"),
|
||||
timeLayout, widgetPlaceholders);
|
||||
|
||||
repeat = new QCheckBox(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.repeat"));
|
||||
|
||||
QWidget::connect(repeat, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(RepeatChanged(int)));
|
||||
|
||||
random = new QLabel(
|
||||
obs_module_text("AdvSceneSwitcher.sceneGroupTab.edit.random"));
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->addLayout(typeLayout);
|
||||
mainLayout->addWidget(countEdit);
|
||||
mainLayout->addWidget(timeEdit);
|
||||
mainLayout->addWidget(repeat);
|
||||
mainLayout->addWidget(random);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
countEdit->setVisible(false);
|
||||
timeEdit->setVisible(false);
|
||||
repeat->setVisible(false);
|
||||
random->setVisible(false);
|
||||
|
||||
sceneGroup = nullptr;
|
||||
}
|
||||
|
||||
void SceneGroupEditWidget::ShowCurrentTypeEdit()
|
||||
{
|
||||
if (!sceneGroup)
|
||||
return;
|
||||
|
||||
countEdit->setVisible(false);
|
||||
timeEdit->setVisible(false);
|
||||
repeat->setVisible(false);
|
||||
random->setVisible(false);
|
||||
|
||||
switch (sceneGroup->type) {
|
||||
case AdvanceCondition::Count:
|
||||
countEdit->setVisible(true);
|
||||
repeat->setVisible(true);
|
||||
break;
|
||||
case AdvanceCondition::Time:
|
||||
timeEdit->setVisible(true);
|
||||
repeat->setVisible(true);
|
||||
break;
|
||||
case AdvanceCondition::Random:
|
||||
random->setVisible(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneGroupEditWidget::SetEditSceneGroup(SceneGroup *sg)
|
||||
{
|
||||
if (!sg)
|
||||
return;
|
||||
sceneGroup = sg;
|
||||
type->setCurrentIndex(static_cast<int>(sg->type));
|
||||
count->setValue(sg->count);
|
||||
time->setValue(sg->time);
|
||||
repeat->setChecked(sg->repeat);
|
||||
ShowCurrentTypeEdit();
|
||||
}
|
||||
|
||||
void SceneGroupEditWidget::TypeChanged(int type)
|
||||
{
|
||||
if (!sceneGroup)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
sceneGroup->type = static_cast<AdvanceCondition>(type);
|
||||
|
||||
ShowCurrentTypeEdit();
|
||||
}
|
||||
|
||||
void SceneGroupEditWidget::CountChanged(int count)
|
||||
{
|
||||
if (!sceneGroup)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
sceneGroup->count = count;
|
||||
}
|
||||
|
||||
void SceneGroupEditWidget::TimeChanged(double time)
|
||||
{
|
||||
if (!sceneGroup)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
sceneGroup->time = time;
|
||||
}
|
||||
|
||||
void SceneGroupEditWidget::RepeatChanged(int state)
|
||||
{
|
||||
if (!sceneGroup)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
sceneGroup->repeat = state;
|
||||
}
|
||||
|
|
@ -12,9 +12,10 @@ void AdvSceneSwitcher::on_audioAdd_clicked()
|
|||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->audioSwitches.emplace_back();
|
||||
|
||||
listAddClicked(ui->audioSwitches,
|
||||
new AudioSwitchWidget(&switcher->audioSwitches.back()),
|
||||
ui->audioAdd, &addPulse);
|
||||
AudioSwitchWidget *sw =
|
||||
new AudioSwitchWidget(this, &switcher->audioSwitches.back());
|
||||
|
||||
listAddClicked(ui->audioSwitches, sw, ui->audioAdd, &addPulse);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_audioRemove_clicked()
|
||||
|
|
@ -92,8 +93,7 @@ void SwitcherData::checkAudioSwitchFallback(OBSWeakSource &scene,
|
|||
|
||||
if (durationReached) {
|
||||
|
||||
scene = (audioFallback.usePreviousScene) ? previousScene
|
||||
: audioFallback.scene;
|
||||
scene = audioFallback.getScene();
|
||||
transition = audioFallback.transition;
|
||||
|
||||
if (verbose)
|
||||
|
|
@ -150,7 +150,7 @@ void SwitcherData::checkAudioSwitch(bool &match, OBSWeakSource &scene,
|
|||
break;
|
||||
}
|
||||
|
||||
scene = (s.usePreviousScene) ? previousScene : s.scene;
|
||||
scene = s.getScene();
|
||||
transition = s.transition;
|
||||
match = true;
|
||||
|
||||
|
|
@ -166,91 +166,21 @@ void SwitcherData::checkAudioSwitch(bool &match, OBSWeakSource &scene,
|
|||
audioFallback.matchCount = 0;
|
||||
}
|
||||
|
||||
void saveAudioFallback(obs_data_t *obj, AudioSwitchFallback &audioFallback)
|
||||
{
|
||||
obs_source_t *fallbackSceneSource =
|
||||
obs_weak_source_get_source(audioFallback.scene);
|
||||
obs_source_t *fallbackTransition =
|
||||
obs_weak_source_get_source(audioFallback.transition);
|
||||
|
||||
const char *fallbackSceneName =
|
||||
obs_source_get_name(fallbackSceneSource);
|
||||
const char *fallbackTransitionName =
|
||||
obs_source_get_name(fallbackTransition);
|
||||
|
||||
obs_data_set_bool(obj, "audioFallbackEnable", audioFallback.enable);
|
||||
obs_data_set_string(obj, "audioFallbackScene",
|
||||
audioFallback.usePreviousScene ? previous_scene_name
|
||||
: fallbackSceneName);
|
||||
obs_data_set_string(obj, "audioFallbackTransition",
|
||||
fallbackTransitionName);
|
||||
obs_data_set_double(obj, "audioFallbackDuration",
|
||||
audioFallback.duration);
|
||||
|
||||
obs_source_release(fallbackSceneSource);
|
||||
obs_source_release(fallbackTransition);
|
||||
}
|
||||
|
||||
void SwitcherData::saveAudioSwitches(obs_data_t *obj)
|
||||
{
|
||||
obs_data_array_t *audioArray = obs_data_array_create();
|
||||
for (AudioSwitch &s : switcher->audioSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *sceneSource = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
obs_source_t *audioSrouce =
|
||||
obs_weak_source_get_source(s.audioSource);
|
||||
if ((s.usePreviousScene || sceneSource) && transition &&
|
||||
audioSrouce) {
|
||||
const char *sceneName =
|
||||
obs_source_get_name(sceneSource);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
const char *audioSourceName =
|
||||
obs_source_get_name(audioSrouce);
|
||||
obs_data_set_string(array_obj, "scene",
|
||||
s.usePreviousScene
|
||||
? previous_scene_name
|
||||
: sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_string(array_obj, "audioSource",
|
||||
audioSourceName);
|
||||
obs_data_set_int(array_obj, "volume",
|
||||
s.volumeThreshold);
|
||||
obs_data_set_int(array_obj, "condition", s.condition);
|
||||
obs_data_set_double(array_obj, "duration", s.duration);
|
||||
obs_data_array_push_back(audioArray, array_obj);
|
||||
}
|
||||
obs_source_release(sceneSource);
|
||||
obs_source_release(transition);
|
||||
obs_source_release(audioSrouce);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(audioArray, array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "audioSwitches", audioArray);
|
||||
obs_data_array_release(audioArray);
|
||||
|
||||
saveAudioFallback(obj, audioFallback);
|
||||
}
|
||||
|
||||
void loadAudioFallback(obs_data_t *obj, AudioSwitchFallback &audioFallback)
|
||||
{
|
||||
const char *fallbackSceneName =
|
||||
obs_data_get_string(obj, "audioFallbackScene");
|
||||
const char *fallbackTransitionName =
|
||||
obs_data_get_string(obj, "audioFallbackTransition");
|
||||
|
||||
audioFallback.enable = obs_data_get_bool(obj, "audioFallbackEnable");
|
||||
audioFallback.duration =
|
||||
obs_data_get_double(obj, "audioFallbackDuration");
|
||||
audioFallback.scene = GetWeakSourceByName(fallbackSceneName);
|
||||
audioFallback.transition =
|
||||
GetWeakTransitionByName(fallbackTransitionName);
|
||||
audioFallback.usePreviousScene =
|
||||
strcmp(fallbackSceneName, previous_scene_name) == 0;
|
||||
audioFallback.save(obj);
|
||||
}
|
||||
|
||||
void SwitcherData::loadAudioSwitches(obs_data_t *obj)
|
||||
|
|
@ -263,27 +193,14 @@ void SwitcherData::loadAudioSwitches(obs_data_t *obj)
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(audioArray, i);
|
||||
|
||||
const char *scene = obs_data_get_string(array_obj, "scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
const char *audioSource =
|
||||
obs_data_get_string(array_obj, "audioSource");
|
||||
int vol = obs_data_get_int(array_obj, "volume");
|
||||
audioCondition condition = (audioCondition)obs_data_get_int(
|
||||
array_obj, "condition");
|
||||
double duration = obs_data_get_double(array_obj, "duration");
|
||||
|
||||
switcher->audioSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
GetWeakTransitionByName(transition),
|
||||
GetWeakSourceByName(audioSource), vol, condition,
|
||||
duration, (strcmp(scene, previous_scene_name) == 0));
|
||||
switcher->audioSwitches.emplace_back();
|
||||
audioSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_array_release(audioArray);
|
||||
|
||||
loadAudioFallback(obj, audioFallback);
|
||||
audioFallback.load(obj);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::setupAudioTab()
|
||||
|
|
@ -292,7 +209,7 @@ void AdvSceneSwitcher::setupAudioTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->audioSwitches);
|
||||
ui->audioSwitches->addItem(item);
|
||||
AudioSwitchWidget *sw = new AudioSwitchWidget(&s);
|
||||
AudioSwitchWidget *sw = new AudioSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->audioSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -301,7 +218,7 @@ void AdvSceneSwitcher::setupAudioTab()
|
|||
addPulse = PulseWidget(ui->audioAdd, QColor(Qt::green));
|
||||
|
||||
AudioSwitchFallbackWidget *fb =
|
||||
new AudioSwitchFallbackWidget(&switcher->audioFallback);
|
||||
new AudioSwitchFallbackWidget(this, &switcher->audioFallback);
|
||||
ui->audioFallbackLayout->addWidget(fb);
|
||||
ui->audioFallback->setChecked(switcher->audioFallback.enable);
|
||||
}
|
||||
|
|
@ -354,22 +271,87 @@ bool AudioSwitch::valid()
|
|||
(SceneSwitcherEntry::valid() && WeakSourceValid(audioSource));
|
||||
}
|
||||
|
||||
AudioSwitch::AudioSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
|
||||
OBSWeakSource audioSource_, int volumeThreshold_,
|
||||
audioCondition condition_, double duration_,
|
||||
bool usePreviousScene_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
audioSource(audioSource_),
|
||||
volumeThreshold(volumeThreshold_),
|
||||
condition(condition_),
|
||||
duration(duration_)
|
||||
void AudioSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(audioSource);
|
||||
const char *audioSourceName = obs_source_get_name(source);
|
||||
obs_data_set_string(obj, "audioSource", audioSourceName);
|
||||
obs_source_release(source);
|
||||
|
||||
obs_data_set_int(obj, "volume", volumeThreshold);
|
||||
obs_data_set_int(obj, "condition", condition);
|
||||
obs_data_set_double(obj, "duration", duration);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldAudio(obs_data_t *obj, AudioSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "scene");
|
||||
|
||||
if (strcmp(scene, "") == 0)
|
||||
return false;
|
||||
|
||||
s->scene = GetWeakSourceByName(scene);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
const char *audioSource = obs_data_get_string(obj, "audioSource");
|
||||
s->audioSource = GetWeakSourceByName(audioSource);
|
||||
|
||||
s->volumeThreshold = obs_data_get_int(obj, "volume");
|
||||
s->condition = (audioCondition)obs_data_get_int(obj, "condition");
|
||||
s->duration = obs_data_get_double(obj, "duration");
|
||||
s->usePreviousScene = strcmp(scene, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
if (loadOldAudio(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
const char *audioSourceName = obs_data_get_string(obj, "audioSource");
|
||||
audioSource = GetWeakSourceByName(audioSourceName);
|
||||
|
||||
volumeThreshold = obs_data_get_int(obj, "volume");
|
||||
condition = (audioCondition)obs_data_get_int(obj, "condition");
|
||||
duration = obs_data_get_double(obj, "duration");
|
||||
|
||||
volmeter = AddVolmeterToSource(this, audioSource);
|
||||
}
|
||||
|
||||
void AudioSwitchFallback::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj, "audioFallbackTargetType",
|
||||
"audioFallbackScene",
|
||||
"audioFallbackTransition");
|
||||
|
||||
obs_data_set_bool(obj, "audioFallbackEnable", enable);
|
||||
obs_data_set_double(obj, "audioFallbackDuration", duration);
|
||||
}
|
||||
|
||||
void AudioSwitchFallback::load(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::load(obj, "audioFallbackTargetType",
|
||||
"audioFallbackScene",
|
||||
"audioFallbackTransition");
|
||||
|
||||
enable = obs_data_get_bool(obj, "audioFallbackEnable");
|
||||
duration = obs_data_get_double(obj, "audioFallbackDuration");
|
||||
}
|
||||
|
||||
AudioSwitch::AudioSwitch(const AudioSwitch &other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
: SceneSwitcherEntry(other.targetType, other.group, other.scene,
|
||||
other.transition, other.usePreviousScene),
|
||||
audioSource(other.audioSource),
|
||||
volumeThreshold(other.volumeThreshold),
|
||||
condition(other.condition),
|
||||
|
|
@ -379,8 +361,8 @@ AudioSwitch::AudioSwitch(const AudioSwitch &other)
|
|||
}
|
||||
|
||||
AudioSwitch::AudioSwitch(AudioSwitch &&other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
: SceneSwitcherEntry(other.targetType, other.group, other.scene,
|
||||
other.transition, other.usePreviousScene),
|
||||
audioSource(other.audioSource),
|
||||
volumeThreshold(other.volumeThreshold),
|
||||
condition(other.condition),
|
||||
|
|
@ -420,6 +402,8 @@ AudioSwitch &AudioSwitch::operator=(AudioSwitch &&other) noexcept
|
|||
|
||||
void swap(AudioSwitch &first, AudioSwitch &second)
|
||||
{
|
||||
std::swap(first.targetType, second.targetType);
|
||||
std::swap(first.group, second.group);
|
||||
std::swap(first.scene, second.scene);
|
||||
std::swap(first.transition, second.transition);
|
||||
std::swap(first.usePreviousScene, second.usePreviousScene);
|
||||
|
|
@ -441,7 +425,8 @@ void populateConditionSelection(QComboBox *list)
|
|||
obs_module_text("AdvSceneSwitcher.audioTab.condition.below"));
|
||||
}
|
||||
|
||||
AudioSwitchWidget::AudioSwitchWidget(AudioSwitch *s) : SwitchWidget(s)
|
||||
AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
|
||||
: SwitchWidget(parent, s, true, true)
|
||||
{
|
||||
audioSources = new QComboBox();
|
||||
condition = new QComboBox();
|
||||
|
|
@ -584,8 +569,9 @@ void AudioSwitchWidget::DurationChanged(double dur)
|
|||
switchData->duration = dur;
|
||||
}
|
||||
|
||||
AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(AudioSwitchFallback *s)
|
||||
: SwitchWidget(s)
|
||||
AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
|
||||
AudioSwitchFallback *s)
|
||||
: SwitchWidget(parent, s, true, true)
|
||||
{
|
||||
duration = new QDoubleSpinBox();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ void AdvSceneSwitcher::on_executableAdd_clicked()
|
|||
|
||||
listAddClicked(ui->executables,
|
||||
new ExecutableSwitchWidget(
|
||||
&switcher->executableSwitches.back()),
|
||||
this, &switcher->executableSwitches.back()),
|
||||
ui->executableAdd, &addPulse);
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ void SwitcherData::checkExeSwitch(bool &match, OBSWeakSource &scene,
|
|||
|
||||
if ((equals || matches) && (focus || ignore)) {
|
||||
match = true;
|
||||
scene = s.scene;
|
||||
scene = s.getScene();
|
||||
transition = s.transition;
|
||||
|
||||
if (verbose)
|
||||
|
|
@ -136,24 +136,9 @@ void SwitcherData::saveExecutableSwitches(obs_data_t *obj)
|
|||
for (ExecutableSwitch &s : switcher->executableSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(executableArray, array_obj);
|
||||
|
||||
if (source && transition) {
|
||||
const char *sceneName = obs_source_get_name(source);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "scene", sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_string(array_obj, "exefile",
|
||||
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);
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "executableSwitches", executableArray);
|
||||
|
|
@ -171,15 +156,8 @@ void SwitcherData::loadExecutableSwitches(obs_data_t *obj)
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(executableArray, i);
|
||||
|
||||
const char *scene = obs_data_get_string(array_obj, "scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
const char *exe = obs_data_get_string(array_obj, "exefile");
|
||||
bool infocus = obs_data_get_bool(array_obj, "infocus");
|
||||
|
||||
switcher->executableSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
GetWeakTransitionByName(transition), exe, infocus);
|
||||
switcher->executableSwitches.emplace_back();
|
||||
executableSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -192,7 +170,8 @@ void AdvSceneSwitcher::setupExecutableTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->executables);
|
||||
ui->executables->addItem(item);
|
||||
ExecutableSwitchWidget *sw = new ExecutableSwitchWidget(&s);
|
||||
ExecutableSwitchWidget *sw =
|
||||
new ExecutableSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->executables->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -201,8 +180,51 @@ void AdvSceneSwitcher::setupExecutableTab()
|
|||
addPulse = PulseWidget(ui->executableAdd, QColor(Qt::green));
|
||||
}
|
||||
|
||||
ExecutableSwitchWidget::ExecutableSwitchWidget(ExecutableSwitch *s)
|
||||
: SwitchWidget(s, false)
|
||||
void ExecutableSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_data_set_string(obj, "exefile", exe.toUtf8());
|
||||
obs_data_set_bool(obj, "infocus", inFocus);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldExe(obs_data_t *obj, ExecutableSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "scene");
|
||||
|
||||
if (strcmp(scene, "") == 0)
|
||||
return false;
|
||||
|
||||
s->scene = GetWeakSourceByName(scene);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
s->exe = obs_data_get_string(obj, "exefile");
|
||||
s->inFocus = obs_data_get_bool(obj, "infocus");
|
||||
s->usePreviousScene = strcmp(scene, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExecutableSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
if (loadOldExe(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
exe = obs_data_get_string(obj, "exefile");
|
||||
inFocus = obs_data_get_bool(obj, "infocus");
|
||||
}
|
||||
|
||||
ExecutableSwitchWidget::ExecutableSwitchWidget(QWidget *parent,
|
||||
ExecutableSwitch *s)
|
||||
: SwitchWidget(parent, s, false, true)
|
||||
{
|
||||
processes = new QComboBox();
|
||||
requiresFocus = new QCheckBox(obs_module_text(
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ void SwitcherData::checkFileContent(bool &match, OBSWeakSource &scene,
|
|||
}
|
||||
|
||||
if (equal) {
|
||||
scene = s.scene;
|
||||
scene = s.getScene();
|
||||
transition = s.transition;
|
||||
match = true;
|
||||
|
||||
|
|
@ -262,7 +262,8 @@ void AdvSceneSwitcher::on_fileAdd_clicked()
|
|||
switcher->fileSwitches.emplace_back();
|
||||
|
||||
listAddClicked(ui->fileSwitches,
|
||||
new FileSwitchWidget(&switcher->fileSwitches.back()),
|
||||
new FileSwitchWidget(this,
|
||||
&switcher->fileSwitches.back()),
|
||||
ui->fileAdd, &addPulse);
|
||||
}
|
||||
|
||||
|
|
@ -343,28 +344,9 @@ void SwitcherData::saveFileSwitches(obs_data_t *obj)
|
|||
for (FileSwitch &s : switcher->fileSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(fileArray, array_obj);
|
||||
|
||||
if (source && transition) {
|
||||
const char *sceneName = obs_source_get_name(source);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "scene", sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_string(array_obj, "file", s.file.c_str());
|
||||
obs_data_set_string(array_obj, "text", s.text.c_str());
|
||||
obs_data_set_bool(array_obj, "remote", s.remote);
|
||||
obs_data_set_bool(array_obj, "useRegex", s.useRegex);
|
||||
obs_data_set_bool(array_obj, "useTime", s.useTime);
|
||||
obs_data_set_bool(array_obj, "onlyMatchIfChanged",
|
||||
s.onlyMatchIfChanged);
|
||||
obs_data_array_push_back(fileArray, array_obj);
|
||||
}
|
||||
obs_source_release(source);
|
||||
obs_source_release(transition);
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "fileSwitches", fileArray);
|
||||
|
|
@ -386,21 +368,8 @@ void SwitcherData::loadFileSwitches(obs_data_t *obj)
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(fileArray, i);
|
||||
|
||||
const char *scene = obs_data_get_string(array_obj, "scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
const char *file = obs_data_get_string(array_obj, "file");
|
||||
const char *text = obs_data_get_string(array_obj, "text");
|
||||
bool remote = obs_data_get_bool(array_obj, "remote");
|
||||
bool useRegex = obs_data_get_bool(array_obj, "useRegex");
|
||||
bool useTime = obs_data_get_bool(array_obj, "useTime");
|
||||
bool onlyMatchIfChanged =
|
||||
obs_data_get_bool(array_obj, "onlyMatchIfChanged");
|
||||
|
||||
switcher->fileSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
GetWeakTransitionByName(transition), file, text, remote,
|
||||
useRegex, useTime, onlyMatchIfChanged);
|
||||
switcher->fileSwitches.emplace_back();
|
||||
fileSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -429,7 +398,7 @@ void AdvSceneSwitcher::setupFileTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->fileSwitches);
|
||||
ui->fileSwitches->addItem(item);
|
||||
FileSwitchWidget *sw = new FileSwitchWidget(&s);
|
||||
FileSwitchWidget *sw = new FileSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->fileSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -452,7 +421,62 @@ void AdvSceneSwitcher::setupFileTab()
|
|||
}
|
||||
}
|
||||
|
||||
FileSwitchWidget::FileSwitchWidget(FileSwitch *s) : SwitchWidget(s, false)
|
||||
void FileSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_data_set_string(obj, "file", file.c_str());
|
||||
obs_data_set_string(obj, "text", text.c_str());
|
||||
obs_data_set_bool(obj, "remote", remote);
|
||||
obs_data_set_bool(obj, "useRegex", useRegex);
|
||||
obs_data_set_bool(obj, "useTime", useTime);
|
||||
obs_data_set_bool(obj, "onlyMatchIfChanged", onlyMatchIfChanged);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldFile(obs_data_t *obj, FileSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "scene");
|
||||
|
||||
if (strcmp(scene, "") == 0)
|
||||
return false;
|
||||
|
||||
s->scene = GetWeakSourceByName(scene);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
s->file = obs_data_get_string(obj, "file");
|
||||
s->text = obs_data_get_string(obj, "text");
|
||||
s->remote = obs_data_get_bool(obj, "remote");
|
||||
s->useRegex = obs_data_get_bool(obj, "useRegex");
|
||||
s->useTime = obs_data_get_bool(obj, "useTime");
|
||||
s->onlyMatchIfChanged = obs_data_get_bool(obj, "onlyMatchIfChanged");
|
||||
s->usePreviousScene = strcmp(scene, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
if (loadOldFile(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
file = obs_data_get_string(obj, "file");
|
||||
text = obs_data_get_string(obj, "text");
|
||||
remote = obs_data_get_bool(obj, "remote");
|
||||
useRegex = obs_data_get_bool(obj, "useRegex");
|
||||
useTime = obs_data_get_bool(obj, "useTime");
|
||||
onlyMatchIfChanged = obs_data_get_bool(obj, "onlyMatchIfChanged");
|
||||
}
|
||||
|
||||
FileSwitchWidget::FileSwitchWidget(QWidget *parent, FileSwitch *s)
|
||||
: SwitchWidget(parent, s, false, true)
|
||||
{
|
||||
fileType = new QComboBox();
|
||||
filePath = new QLineEdit();
|
||||
|
|
|
|||
|
|
@ -3,17 +3,19 @@
|
|||
|
||||
bool SceneSwitcherEntry::initialized()
|
||||
{
|
||||
return (usePreviousScene || WeakSourceValid(scene)) && transition;
|
||||
return (usePreviousScene || WeakSourceValid(scene) ||
|
||||
SceneGroupValid(group)) &&
|
||||
transition;
|
||||
}
|
||||
|
||||
bool SceneSwitcherEntry::valid()
|
||||
{
|
||||
return !initialized() ||
|
||||
((usePreviousScene || WeakSourceValid(scene)) &&
|
||||
WeakSourceValid(transition));
|
||||
return !initialized() || ((usePreviousScene || WeakSourceValid(scene) ||
|
||||
SceneGroupValid(group)) &&
|
||||
WeakSourceValid(transition));
|
||||
}
|
||||
|
||||
void SceneSwitcherEntry::logMatch()
|
||||
void SceneSwitcherEntry::logMatchScene()
|
||||
{
|
||||
const char *sceneName = previous_scene_name;
|
||||
if (!usePreviousScene) {
|
||||
|
|
@ -25,7 +27,152 @@ void SceneSwitcherEntry::logMatch()
|
|||
sceneName);
|
||||
}
|
||||
|
||||
SwitchWidget::SwitchWidget(SceneSwitcherEntry *s, bool usePreviousScene)
|
||||
void SceneSwitcherEntry::logMatchSceneGroup()
|
||||
{
|
||||
if (group->scenes.empty()) {
|
||||
blog(LOG_INFO,
|
||||
"match for '%s' - but no scenes specified in '%s'",
|
||||
getType(), group->name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const char *sceneName = previous_scene_name;
|
||||
obs_source_t *s =
|
||||
obs_weak_source_get_source(group->scenes[group->currentIdx]);
|
||||
sceneName = obs_source_get_name(s);
|
||||
obs_source_release(s);
|
||||
|
||||
blog(LOG_INFO, "match for '%s' - switch to scene '%s' using '%s'",
|
||||
getType(), sceneName, group->name.c_str());
|
||||
}
|
||||
|
||||
void SceneSwitcherEntry::logMatch()
|
||||
{
|
||||
if (targetType == SwitchTargetType::Scene) {
|
||||
logMatchScene();
|
||||
} else if (targetType == SwitchTargetType::SceneGroup) {
|
||||
logMatchSceneGroup();
|
||||
}
|
||||
}
|
||||
|
||||
OBSWeakSource SceneSwitcherEntry::getScene()
|
||||
{
|
||||
if (targetType == SwitchTargetType::Scene) {
|
||||
if (usePreviousScene && switcher)
|
||||
return switcher->previousScene;
|
||||
return scene;
|
||||
} else if (targetType == SwitchTargetType::SceneGroup) {
|
||||
return group->getNextScene();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SceneSwitcherEntry::save(obs_data_t *obj, const char *targetTypeSaveName,
|
||||
const char *targetSaveName,
|
||||
const char *transitionSaveName)
|
||||
{
|
||||
obs_data_set_int(obj, targetTypeSaveName, static_cast<int>(targetType));
|
||||
|
||||
const char *targetName = "";
|
||||
|
||||
if (targetType == SwitchTargetType::Scene) {
|
||||
if (usePreviousScene) {
|
||||
targetName = previous_scene_name;
|
||||
} else {
|
||||
obs_source_t *sceneSource =
|
||||
obs_weak_source_get_source(scene);
|
||||
targetName = obs_source_get_name(sceneSource);
|
||||
obs_source_release(sceneSource);
|
||||
}
|
||||
} else if (targetType == SwitchTargetType::SceneGroup) {
|
||||
targetName = group->name.c_str();
|
||||
}
|
||||
|
||||
obs_data_set_string(obj, targetSaveName, targetName);
|
||||
|
||||
obs_source_t *transitionSource = obs_weak_source_get_source(transition);
|
||||
const char *transitionName = obs_source_get_name(transitionSource);
|
||||
obs_source_release(transitionSource);
|
||||
|
||||
obs_data_set_string(obj, transitionSaveName, transitionName);
|
||||
}
|
||||
|
||||
void SceneSwitcherEntry::load(obs_data_t *obj, const char *targetTypeLoadName,
|
||||
const char *targetLoadName,
|
||||
const char *transitionLoadName)
|
||||
{
|
||||
targetType = static_cast<SwitchTargetType>(
|
||||
obs_data_get_int(obj, targetTypeLoadName));
|
||||
|
||||
const char *targetName = obs_data_get_string(obj, targetLoadName);
|
||||
|
||||
if (targetType == SwitchTargetType::Scene) {
|
||||
usePreviousScene = strcmp(targetName, previous_scene_name) == 0;
|
||||
if (!usePreviousScene)
|
||||
scene = GetWeakSourceByName(targetName);
|
||||
} else if (targetType == SwitchTargetType::SceneGroup) {
|
||||
group = GetSceneGroupByName(targetName);
|
||||
}
|
||||
|
||||
const char *transitionName =
|
||||
obs_data_get_string(obj, transitionLoadName);
|
||||
transition = GetWeakTransitionByName(transitionName);
|
||||
|
||||
usePreviousScene = strcmp(targetName, previous_scene_name) == 0;
|
||||
}
|
||||
|
||||
void SwitchWidget::SceneGroupAdd(const QString &name)
|
||||
{
|
||||
if (!scenes)
|
||||
return;
|
||||
|
||||
scenes->addItem(name);
|
||||
}
|
||||
|
||||
void SwitchWidget::SceneGroupRemove(const QString &name)
|
||||
{
|
||||
if (!scenes)
|
||||
return;
|
||||
|
||||
int idx = scenes->findText(name);
|
||||
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
scenes->removeItem(idx);
|
||||
|
||||
if (switchData && switchData->group == GetSceneGroupByQString(name)) {
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->targetType = SwitchTargetType::Scene;
|
||||
switchData->scene = nullptr;
|
||||
}
|
||||
|
||||
scenes->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void SwitchWidget::SceneGroupRename(const QString &oldName,
|
||||
const QString &newName)
|
||||
{
|
||||
if (!scenes)
|
||||
return;
|
||||
|
||||
bool renameSelected = scenes->currentText() == oldName;
|
||||
int idx = scenes->findText(oldName);
|
||||
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
scenes->removeItem(idx);
|
||||
scenes->insertItem(idx, newName);
|
||||
|
||||
if (renameSelected)
|
||||
scenes->setCurrentIndex(scenes->findText(newName));
|
||||
}
|
||||
|
||||
SwitchWidget::SwitchWidget(QWidget *parent, SceneSwitcherEntry *s,
|
||||
bool usePreviousScene, bool addSceneGroup)
|
||||
{
|
||||
scenes = new QComboBox();
|
||||
transitions = new QComboBox();
|
||||
|
|
@ -42,16 +189,31 @@ SwitchWidget::SwitchWidget(SceneSwitcherEntry *s, bool usePreviousScene)
|
|||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(TransitionChanged(const QString &)));
|
||||
|
||||
AdvSceneSwitcher::populateSceneSelection(scenes, usePreviousScene);
|
||||
QWidget::connect(parent, SIGNAL(SceneGroupAdded(const QString &)), this,
|
||||
SLOT(SceneGroupAdd(const QString &)));
|
||||
QWidget::connect(parent, SIGNAL(SceneGroupRemoved(const QString &)),
|
||||
this, SLOT(SceneGroupRemove(const QString &)));
|
||||
QWidget::connect(
|
||||
parent,
|
||||
SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
|
||||
this, SLOT(SceneGroupRename(const QString &, const QString &)));
|
||||
|
||||
AdvSceneSwitcher::populateSceneSelection(scenes, usePreviousScene,
|
||||
addSceneGroup);
|
||||
AdvSceneSwitcher::populateTransitionSelection(transitions);
|
||||
|
||||
if (s) {
|
||||
if (s->usePreviousScene)
|
||||
if (s->usePreviousScene) {
|
||||
scenes->setCurrentText(obs_module_text(
|
||||
"AdvSceneSwitcher.selectPreviousScene"));
|
||||
else
|
||||
} else {
|
||||
scenes->setCurrentText(
|
||||
GetWeakSourceName(s->scene).c_str());
|
||||
if (s->targetType == SwitchTargetType::SceneGroup &&
|
||||
s->group)
|
||||
scenes->setCurrentText(
|
||||
QString::fromStdString(s->group->name));
|
||||
}
|
||||
transitions->setCurrentText(
|
||||
GetWeakSourceName(s->transition).c_str());
|
||||
}
|
||||
|
|
@ -87,10 +249,20 @@ void SwitchWidget::SceneChanged(const QString &text)
|
|||
if (loading || !switchData)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
switchData->usePreviousScene = isPreviousScene(text);
|
||||
if (switchData->usePreviousScene)
|
||||
if (switchData->usePreviousScene) {
|
||||
switchData->targetType = SwitchTargetType::Scene;
|
||||
return;
|
||||
}
|
||||
|
||||
switchData->scene = GetWeakSourceByQString(text);
|
||||
switchData->targetType = SwitchTargetType::Scene;
|
||||
|
||||
if (!switchData->scene) {
|
||||
switchData->group = GetSceneGroupByQString(text);
|
||||
switchData->targetType = SwitchTargetType::SceneGroup;
|
||||
}
|
||||
}
|
||||
|
||||
void SwitchWidget::TransitionChanged(const QString &text)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ void SwitcherData::checkIdleSwitch(bool &match, OBSWeakSource &scene,
|
|||
|
||||
std::string title;
|
||||
bool ignoreIdle = false;
|
||||
//lock.unlock();
|
||||
GetCurrentWindowTitle(title);
|
||||
//lock.lock();
|
||||
|
||||
for (std::string &window : ignoreIdleWindows) {
|
||||
if (window == title) {
|
||||
|
|
@ -41,8 +39,7 @@ void SwitcherData::checkIdleSwitch(bool &match, OBSWeakSource &scene,
|
|||
if (!ignoreIdle && secondsSinceLastInput() > idleData.time) {
|
||||
if (idleData.alreadySwitched)
|
||||
return;
|
||||
scene = (idleData.usePreviousScene) ? previousScene
|
||||
: idleData.scene;
|
||||
scene = idleData.getScene();
|
||||
transition = idleData.transition;
|
||||
match = true;
|
||||
idleData.alreadySwitched = true;
|
||||
|
|
@ -222,17 +219,7 @@ void SwitcherData::saveIdleSwitches(obs_data_t *obj)
|
|||
obs_data_set_array(obj, "ignoreIdleWindows", ignoreIdleWindowsArray);
|
||||
obs_data_array_release(ignoreIdleWindowsArray);
|
||||
|
||||
std::string idleSceneName = GetWeakSourceName(switcher->idleData.scene);
|
||||
std::string idleTransitionName =
|
||||
GetWeakSourceName(switcher->idleData.transition);
|
||||
obs_data_set_bool(obj, "idleEnable", switcher->idleData.idleEnable);
|
||||
obs_data_set_string(obj, "idleSceneName",
|
||||
switcher->idleData.usePreviousScene
|
||||
? previous_scene_name
|
||||
: idleSceneName.c_str());
|
||||
obs_data_set_string(obj, "idleTransitionName",
|
||||
idleTransitionName.c_str());
|
||||
obs_data_set_int(obj, "idleTime", switcher->idleData.time);
|
||||
idleData.save(obj);
|
||||
}
|
||||
|
||||
void SwitcherData::loadIdleSwitches(obs_data_t *obj)
|
||||
|
|
@ -255,23 +242,15 @@ void SwitcherData::loadIdleSwitches(obs_data_t *obj)
|
|||
}
|
||||
obs_data_array_release(ignoreIdleWindowsArray);
|
||||
|
||||
std::string idleSceneName = obs_data_get_string(obj, "idleSceneName");
|
||||
std::string idleTransitionName =
|
||||
obs_data_get_string(obj, "idleTransitionName");
|
||||
switcher->idleData.scene = GetWeakSourceByName(idleSceneName.c_str());
|
||||
switcher->idleData.transition =
|
||||
GetWeakTransitionByName(idleTransitionName.c_str());
|
||||
obs_data_set_default_bool(obj, "idleEnable", false);
|
||||
switcher->idleData.idleEnable = obs_data_get_bool(obj, "idleEnable");
|
||||
obs_data_set_default_int(obj, "idleTime", default_idle_time);
|
||||
switcher->idleData.time = obs_data_get_int(obj, "idleTime");
|
||||
switcher->idleData.usePreviousScene =
|
||||
(idleSceneName == previous_scene_name);
|
||||
|
||||
idleData.load(obj);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::setupIdleTab()
|
||||
{
|
||||
populateSceneSelection(ui->idleScenes, true);
|
||||
populateSceneSelection(ui->idleScenes, true, false);
|
||||
populateTransitionSelection(ui->idleTransitions);
|
||||
populateWindowSelection(ui->ignoreIdleWindowsWindows);
|
||||
|
||||
|
|
@ -305,3 +284,21 @@ void AdvSceneSwitcher::setupIdleTab()
|
|||
ui->idleTransitions->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void IdleData::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj, "idleTargetType", "idleSceneName",
|
||||
"idleTransitionName");
|
||||
|
||||
obs_data_set_bool(obj, "idleEnable", idleEnable);
|
||||
obs_data_set_int(obj, "idleTime", time);
|
||||
}
|
||||
|
||||
void IdleData::load(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::load(obj, "idleTargetType", "idleSceneName",
|
||||
"idleTransitionName");
|
||||
|
||||
idleEnable = obs_data_get_bool(obj, "idleEnable");
|
||||
time = obs_data_get_int(obj, "idleTime");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ void AdvSceneSwitcher::on_mediaAdd_clicked()
|
|||
switcher->mediaSwitches.emplace_back();
|
||||
|
||||
listAddClicked(ui->mediaSwitches,
|
||||
new MediaSwitchWidget(&switcher->mediaSwitches.back()),
|
||||
new MediaSwitchWidget(this,
|
||||
&switcher->mediaSwitches.back()),
|
||||
ui->mediaAdd, &addPulse);
|
||||
}
|
||||
|
||||
|
|
@ -173,9 +174,7 @@ void SwitcherData::checkMediaSwitch(bool &match, OBSWeakSource &scene,
|
|||
|
||||
if (matched && !mediaSwitch.matched) {
|
||||
match = true;
|
||||
scene = (mediaSwitch.usePreviousScene)
|
||||
? previousScene
|
||||
: mediaSwitch.scene;
|
||||
scene = mediaSwitch.getScene();
|
||||
transition = mediaSwitch.transition;
|
||||
|
||||
if (verbose)
|
||||
|
|
@ -195,33 +194,8 @@ void SwitcherData::saveMediaSwitches(obs_data_t *obj)
|
|||
for (MediaSwitch &s : switcher->mediaSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s.source);
|
||||
obs_source_t *sceneSource = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
if ((s.usePreviousScene || sceneSource) && source &&
|
||||
transition) {
|
||||
const char *sourceName = obs_source_get_name(source);
|
||||
const char *sceneName =
|
||||
obs_source_get_name(sceneSource);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "source", sourceName);
|
||||
obs_data_set_string(array_obj, "scene",
|
||||
s.usePreviousScene
|
||||
? previous_scene_name
|
||||
: sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_int(array_obj, "state", s.state);
|
||||
obs_data_set_int(array_obj, "restriction",
|
||||
s.restriction);
|
||||
obs_data_set_int(array_obj, "time", s.time);
|
||||
obs_data_array_push_back(mediaArray, array_obj);
|
||||
}
|
||||
obs_source_release(source);
|
||||
obs_source_release(sceneSource);
|
||||
obs_source_release(transition);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(mediaArray, array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -238,21 +212,8 @@ void SwitcherData::loadMediaSwitches(obs_data_t *obj)
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(mediaArray, i);
|
||||
|
||||
const char *source = obs_data_get_string(array_obj, "source");
|
||||
const char *scene = obs_data_get_string(array_obj, "scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
obs_media_state state =
|
||||
(obs_media_state)obs_data_get_int(array_obj, "state");
|
||||
time_restriction restriction =
|
||||
(time_restriction)obs_data_get_int(array_obj,
|
||||
"restriction");
|
||||
uint64_t time = obs_data_get_int(array_obj, "time");
|
||||
|
||||
switcher->mediaSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene), GetWeakSourceByName(source),
|
||||
GetWeakTransitionByName(transition), state, restriction,
|
||||
time, (strcmp(scene, previous_scene_name) == 0));
|
||||
switcher->mediaSwitches.emplace_back();
|
||||
mediaSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -265,7 +226,7 @@ void AdvSceneSwitcher::setupMediaTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->mediaSwitches);
|
||||
ui->mediaSwitches->addItem(item);
|
||||
MediaSwitchWidget *sw = new MediaSwitchWidget(&s);
|
||||
MediaSwitchWidget *sw = new MediaSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->mediaSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -285,6 +246,70 @@ bool MediaSwitch::valid()
|
|||
(SceneSwitcherEntry::valid() && WeakSourceValid(source));
|
||||
}
|
||||
|
||||
void MediaSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_source_t *s = obs_weak_source_get_source(source);
|
||||
const char *sourceName = obs_source_get_name(s);
|
||||
obs_data_set_string(obj, "source", sourceName);
|
||||
obs_source_release(s);
|
||||
|
||||
obs_data_set_int(obj, "state", state);
|
||||
obs_data_set_int(obj, "restriction", restriction);
|
||||
obs_data_set_int(obj, "time", time);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldMedia(obs_data_t *obj, MediaSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "scene");
|
||||
|
||||
if (strcmp(scene, "") == 0)
|
||||
return false;
|
||||
|
||||
s->scene = GetWeakSourceByName(scene);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
const char *source = obs_data_get_string(obj, "source");
|
||||
s->source = GetWeakSourceByName(source);
|
||||
|
||||
s->state = (obs_media_state)obs_data_get_int(obj, "state");
|
||||
s->restriction = (time_restriction)obs_data_get_int(obj, "restriction");
|
||||
s->time = obs_data_get_int(obj, "time");
|
||||
s->usePreviousScene = strcmp(scene, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MediaSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
|
||||
if (loadOldMedia(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
const char *sourceName = obs_data_get_string(obj, "source");
|
||||
source = GetWeakSourceByName(sourceName);
|
||||
|
||||
state = (obs_media_state)obs_data_get_int(obj, "state");
|
||||
restriction = (time_restriction)obs_data_get_int(obj, "restriction");
|
||||
time = obs_data_get_int(obj, "time");
|
||||
|
||||
anyState = state == media_any_idx;
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_connect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_connect(sh, "media_ended", MediaEnded, this);
|
||||
obs_source_release(mediasource);
|
||||
}
|
||||
|
||||
void MediaSwitch::clearSignalHandler()
|
||||
{
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
|
|
@ -317,28 +342,9 @@ void MediaSwitch::MediaEnded(void *data, calldata_t *)
|
|||
media->ended = true;
|
||||
}
|
||||
|
||||
inline MediaSwitch::MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
|
||||
OBSWeakSource transition_,
|
||||
obs_media_state state_,
|
||||
time_restriction restriction_, uint64_t time_,
|
||||
bool usePreviousScene_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
source(source_),
|
||||
state(state_),
|
||||
restriction(restriction_),
|
||||
time(time_)
|
||||
{
|
||||
anyState = state == media_any_idx;
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_connect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_connect(sh, "media_ended", MediaEnded, this);
|
||||
obs_source_release(mediasource);
|
||||
}
|
||||
|
||||
MediaSwitch::MediaSwitch(const MediaSwitch &other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
: SceneSwitcherEntry(other.targetType, other.group, other.scene,
|
||||
other.transition, other.usePreviousScene),
|
||||
source(other.source),
|
||||
state(other.state),
|
||||
restriction(other.restriction),
|
||||
|
|
@ -353,8 +359,8 @@ MediaSwitch::MediaSwitch(const MediaSwitch &other)
|
|||
}
|
||||
|
||||
MediaSwitch::MediaSwitch(MediaSwitch &&other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
: SceneSwitcherEntry(other.targetType, other.group, other.scene,
|
||||
other.transition, other.usePreviousScene),
|
||||
source(other.source),
|
||||
state(other.state),
|
||||
anyState(other.anyState),
|
||||
|
|
@ -398,6 +404,8 @@ MediaSwitch &MediaSwitch::operator=(MediaSwitch &&other) noexcept
|
|||
|
||||
void swap(MediaSwitch &first, MediaSwitch &second)
|
||||
{
|
||||
std::swap(first.targetType, second.targetType);
|
||||
std::swap(first.group, second.group);
|
||||
std::swap(first.scene, second.scene);
|
||||
std::swap(first.transition, second.transition);
|
||||
std::swap(first.usePreviousScene, second.usePreviousScene);
|
||||
|
|
@ -446,7 +454,8 @@ void populateTimeRestrictions(QComboBox *list)
|
|||
"AdvSceneSwitcher.mediaTab.timeRestriction.remainLonger"));
|
||||
}
|
||||
|
||||
MediaSwitchWidget::MediaSwitchWidget(MediaSwitch *s) : SwitchWidget(s)
|
||||
MediaSwitchWidget::MediaSwitchWidget(QWidget *parent, MediaSwitch *s)
|
||||
: SwitchWidget(parent, s, true, true)
|
||||
{
|
||||
mediaSources = new QComboBox();
|
||||
states = new QComboBox();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ void AdvSceneSwitcher::on_pauseAdd_clicked()
|
|||
switcher->pauseEntries.emplace_back();
|
||||
|
||||
listAddClicked(ui->pauseEntries,
|
||||
new PauseEntryWidget(&switcher->pauseEntries.back()),
|
||||
new PauseEntryWidget(this,
|
||||
&switcher->pauseEntries.back()),
|
||||
ui->pauseAdd, &addPulse);
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +308,7 @@ void AdvSceneSwitcher::setupPauseTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->pauseEntries);
|
||||
ui->pauseEntries->addItem(item);
|
||||
PauseEntryWidget *sw = new PauseEntryWidget(&s);
|
||||
PauseEntryWidget *sw = new PauseEntryWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->pauseEntries->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -343,7 +344,8 @@ void populatePauseTargets(QComboBox *list)
|
|||
list->addItem(obs_module_text("AdvSceneSwitcher.audioTab.title"));
|
||||
}
|
||||
|
||||
PauseEntryWidget::PauseEntryWidget(PauseEntry *s) : SwitchWidget(s, false)
|
||||
PauseEntryWidget::PauseEntryWidget(QWidget *parent, PauseEntry *s)
|
||||
: SwitchWidget(parent, s, false, false)
|
||||
{
|
||||
pauseTypes = new QComboBox();
|
||||
pauseTargets = new QComboBox();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ void AdvSceneSwitcher::on_randomAdd_clicked()
|
|||
switcher->randomSwitches.emplace_back();
|
||||
|
||||
listAddClicked(ui->randomSwitches,
|
||||
new RandomSwitchWidget(&switcher->randomSwitches.back()),
|
||||
new RandomSwitchWidget(this,
|
||||
&switcher->randomSwitches.back()),
|
||||
ui->randomAdd, &addPulse);
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ void SwitcherData::checkRandom(bool &match, OBSWeakSource &scene,
|
|||
|
||||
if (r.scene == lastRandomScene && randomSwitches.size() != 1)
|
||||
continue;
|
||||
scene = r.scene;
|
||||
scene = r.getScene();
|
||||
transition = r.transition;
|
||||
delay = (int)r.delay * 1000;
|
||||
match = true;
|
||||
|
|
@ -66,22 +67,9 @@ void SwitcherData::saveRandomSwitches(obs_data_t *obj)
|
|||
for (RandomSwitch &s : switcher->randomSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(randomArray, array_obj);
|
||||
|
||||
if (source && transition) {
|
||||
const char *sceneName = obs_source_get_name(source);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "scene", sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_double(array_obj, "delay", s.delay);
|
||||
obs_data_array_push_back(randomArray, array_obj);
|
||||
}
|
||||
obs_source_release(source);
|
||||
obs_source_release(transition);
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "randomSwitches", randomArray);
|
||||
|
|
@ -99,14 +87,8 @@ void SwitcherData::loadRandomSwitches(obs_data_t *obj)
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(randomArray, i);
|
||||
|
||||
const char *scene = obs_data_get_string(array_obj, "scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
double delay = obs_data_get_double(array_obj, "delay");
|
||||
|
||||
switcher->randomSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
GetWeakTransitionByName(transition), delay);
|
||||
switcher->randomSwitches.emplace_back();
|
||||
randomSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -119,7 +101,7 @@ void AdvSceneSwitcher::setupRandomTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->randomSwitches);
|
||||
ui->randomSwitches->addItem(item);
|
||||
RandomSwitchWidget *sw = new RandomSwitchWidget(&s);
|
||||
RandomSwitchWidget *sw = new RandomSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->randomSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -134,7 +116,20 @@ void AdvSceneSwitcher::setupRandomTab()
|
|||
ui->randomDisabledWarning->setVisible(false);
|
||||
}
|
||||
|
||||
RandomSwitchWidget::RandomSwitchWidget(RandomSwitch *s) : SwitchWidget(s, false)
|
||||
void RandomSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj, "targetType", "scene");
|
||||
obs_data_set_double(obj, "delay", delay);
|
||||
}
|
||||
|
||||
void RandomSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::load(obj, "targetType", "scene");
|
||||
delay = obs_data_get_double(obj, "delay");
|
||||
}
|
||||
|
||||
RandomSwitchWidget::RandomSwitchWidget(QWidget *parent, RandomSwitch *s)
|
||||
: SwitchWidget(parent, s, false, false)
|
||||
{
|
||||
delay = new QDoubleSpinBox();
|
||||
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ void AdvSceneSwitcher::on_screenRegionAdd_clicked()
|
|||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->screenRegionSwitches.emplace_back();
|
||||
|
||||
listAddClicked(
|
||||
ui->screenRegionSwitches,
|
||||
new ScreenRegionWidget(&switcher->screenRegionSwitches.back()),
|
||||
ui->screenRegionAdd, &addPulse);
|
||||
listAddClicked(ui->screenRegionSwitches,
|
||||
new ScreenRegionWidget(
|
||||
this, &switcher->screenRegionSwitches.back()),
|
||||
ui->screenRegionAdd, &addPulse);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_screenRegionRemove_clicked()
|
||||
|
|
@ -148,7 +148,7 @@ void SwitcherData::checkScreenRegionSwitch(bool &match, OBSWeakSource &scene,
|
|||
int regionSize = (s.maxX - s.minX) + (s.maxY - s.minY);
|
||||
if (regionSize < minRegionSize) {
|
||||
match = true;
|
||||
scene = s.scene;
|
||||
scene = s.getScene();
|
||||
transition = s.transition;
|
||||
minRegionSize = regionSize;
|
||||
|
||||
|
|
@ -173,25 +173,9 @@ void SwitcherData::saveScreenRegionSwitches(obs_data_t *obj)
|
|||
for (ScreenRegionSwitch &s : switcher->screenRegionSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
if (source && transition) {
|
||||
const char *sceneName = obs_source_get_name(source);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "screenRegionScene",
|
||||
sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_int(array_obj, "minX", s.minX);
|
||||
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_array_push_back(screenRegionArray, array_obj);
|
||||
}
|
||||
obs_source_release(source);
|
||||
obs_source_release(transition);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(screenRegionArray, array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "screenRegion", screenRegionArray);
|
||||
|
|
@ -210,19 +194,8 @@ void SwitcherData::loadScreenRegionSwitches(obs_data_t *obj)
|
|||
obs_data_t *array_obj =
|
||||
obs_data_array_item(screenRegionArray, i);
|
||||
|
||||
const char *scene =
|
||||
obs_data_get_string(array_obj, "screenRegionScene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
int minX = obs_data_get_int(array_obj, "minX");
|
||||
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");
|
||||
|
||||
switcher->screenRegionSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
GetWeakTransitionByName(transition), minX, minY, maxX,
|
||||
maxY);
|
||||
switcher->screenRegionSwitches.emplace_back();
|
||||
screenRegionSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -235,7 +208,7 @@ void AdvSceneSwitcher::setupRegionTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->screenRegionSwitches);
|
||||
ui->screenRegionSwitches->addItem(item);
|
||||
ScreenRegionWidget *sw = new ScreenRegionWidget(&s);
|
||||
ScreenRegionWidget *sw = new ScreenRegionWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->screenRegionSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -250,8 +223,57 @@ void AdvSceneSwitcher::setupRegionTab()
|
|||
screenRegionTimer->start(1000);
|
||||
}
|
||||
|
||||
ScreenRegionWidget::ScreenRegionWidget(ScreenRegionSwitch *s)
|
||||
: SwitchWidget(s, false)
|
||||
void ScreenRegionSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_data_set_int(obj, "minX", minX);
|
||||
obs_data_set_int(obj, "minY", minY);
|
||||
obs_data_set_int(obj, "maxX", maxX);
|
||||
obs_data_set_int(obj, "maxY", maxY);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldRegion(obs_data_t *obj, ScreenRegionSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "screenRegionScene");
|
||||
|
||||
if (strcmp(scene, "") == 0)
|
||||
return false;
|
||||
|
||||
s->scene = GetWeakSourceByName(scene);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
s->minX = obs_data_get_int(obj, "minX");
|
||||
s->minY = obs_data_get_int(obj, "minY");
|
||||
s->maxX = obs_data_get_int(obj, "maxX");
|
||||
s->maxY = obs_data_get_int(obj, "maxY");
|
||||
|
||||
s->usePreviousScene = strcmp(scene, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScreenRegionSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
if (loadOldRegion(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
minX = obs_data_get_int(obj, "minX");
|
||||
minY = obs_data_get_int(obj, "minY");
|
||||
maxX = obs_data_get_int(obj, "maxX");
|
||||
maxY = obs_data_get_int(obj, "maxY");
|
||||
}
|
||||
|
||||
ScreenRegionWidget::ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s)
|
||||
: SwitchWidget(parent, s, false, true)
|
||||
{
|
||||
minX = new QSpinBox();
|
||||
minY = new QSpinBox();
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ void AdvSceneSwitcher::on_sceneSequenceAdd_clicked()
|
|||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->sceneSequenceSwitches.emplace_back();
|
||||
|
||||
listAddClicked(
|
||||
ui->sceneSequenceSwitches,
|
||||
new SequenceWidget(&switcher->sceneSequenceSwitches.back()),
|
||||
ui->sceneSequenceAdd, &addPulse);
|
||||
listAddClicked(ui->sceneSequenceSwitches,
|
||||
new SequenceWidget(
|
||||
this, &switcher->sceneSequenceSwitches.back()),
|
||||
ui->sceneSequenceAdd, &addPulse);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_sceneSequenceRemove_clicked()
|
||||
|
|
@ -148,9 +148,7 @@ void AdvSceneSwitcher::on_sceneSequenceLoad_clicked()
|
|||
close();
|
||||
}
|
||||
|
||||
void matchInterruptible(SwitcherData *switcher, SceneSequenceSwitch &s,
|
||||
bool &match, OBSWeakSource &scene,
|
||||
OBSWeakSource &transition)
|
||||
bool matchInterruptible(SwitcherData *switcher, SceneSequenceSwitch &s)
|
||||
{
|
||||
bool durationReached = s.matchCount * (switcher->interval / 1000.0) >=
|
||||
s.delay;
|
||||
|
|
@ -158,20 +156,16 @@ void matchInterruptible(SwitcherData *switcher, SceneSequenceSwitch &s,
|
|||
s.matchCount++;
|
||||
|
||||
if (durationReached) {
|
||||
match = true;
|
||||
scene = (s.usePreviousScene) ? switcher->previousScene
|
||||
: s.scene;
|
||||
transition = s.transition;
|
||||
if (switcher->verbose)
|
||||
s.logMatch();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void matchUninterruptible(SwitcherData *switcher, SceneSequenceSwitch &s,
|
||||
bool matchUninterruptible(SwitcherData *switcher, SceneSequenceSwitch &s,
|
||||
obs_source_t *currentSource,
|
||||
std::unique_lock<std::mutex> &lock, bool &match,
|
||||
OBSWeakSource &scene, OBSWeakSource &transition)
|
||||
std::unique_lock<std::mutex> &lock)
|
||||
{
|
||||
bool ret = false;
|
||||
// scene was already active for the previous cycle so remove this time
|
||||
int dur = s.delay * 1000 - switcher->interval;
|
||||
if (dur > 0) {
|
||||
|
|
@ -187,17 +181,13 @@ void matchUninterruptible(SwitcherData *switcher, SceneSequenceSwitch &s,
|
|||
|
||||
// only switch if user hasn't changed scene manually
|
||||
if (currentSource == currentSource2) {
|
||||
match = true;
|
||||
scene = (s.usePreviousScene) ? switcher->previousScene
|
||||
: s.scene;
|
||||
transition = s.transition;
|
||||
if (switcher->verbose)
|
||||
s.logMatch();
|
||||
ret = true;
|
||||
} else if (switcher->verbose) {
|
||||
blog(LOG_INFO, "sequence canceled");
|
||||
}
|
||||
|
||||
obs_source_release(currentSource2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SwitcherData::checkSceneSequence(bool &match, OBSWeakSource &scene,
|
||||
|
|
@ -217,13 +207,20 @@ void SwitcherData::checkSceneSequence(bool &match, OBSWeakSource &scene,
|
|||
if (s.startScene == ws) {
|
||||
if (!match) {
|
||||
if (s.interruptible) {
|
||||
matchInterruptible(switcher, s, match,
|
||||
scene, transition);
|
||||
match = matchInterruptible(switcher, s);
|
||||
} else {
|
||||
matchUninterruptible(switcher, s,
|
||||
currentSource,
|
||||
lock, match, scene,
|
||||
transition);
|
||||
match = matchUninterruptible(
|
||||
switcher, s, currentSource,
|
||||
lock);
|
||||
}
|
||||
|
||||
if (match) {
|
||||
scene = (s.usePreviousScene)
|
||||
? switcher->previousScene
|
||||
: s.getScene();
|
||||
transition = s.transition;
|
||||
if (switcher->verbose)
|
||||
s.logMatch();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -240,35 +237,9 @@ void SwitcherData::saveSceneSequenceSwitches(obs_data_t *obj)
|
|||
for (SceneSequenceSwitch &s : switcher->sceneSequenceSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
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) {
|
||||
const char *sceneName1 = obs_source_get_name(source1);
|
||||
const char *sceneName2 = obs_source_get_name(source2);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "sceneRoundTripScene1",
|
||||
sceneName1);
|
||||
obs_data_set_string(array_obj, "sceneRoundTripScene2",
|
||||
s.usePreviousScene
|
||||
? previous_scene_name
|
||||
: sceneName2);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_double(array_obj, "delay", s.delay);
|
||||
obs_data_set_int(array_obj, "delayMultiplier",
|
||||
s.delayMultiplier);
|
||||
obs_data_set_bool(array_obj, "interruptible",
|
||||
s.interruptible);
|
||||
obs_data_array_push_back(sceneSequenceArray, array_obj);
|
||||
}
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(sceneSequenceArray, array_obj);
|
||||
|
||||
obs_source_release(source1);
|
||||
obs_source_release(source2);
|
||||
obs_source_release(transition);
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "sceneRoundTrip", sceneSequenceArray);
|
||||
|
|
@ -287,27 +258,8 @@ void SwitcherData::loadSceneSequenceSwitches(obs_data_t *obj)
|
|||
obs_data_t *array_obj =
|
||||
obs_data_array_item(sceneSequenceArray, i);
|
||||
|
||||
const char *scene1 =
|
||||
obs_data_get_string(array_obj, "sceneRoundTripScene1");
|
||||
const char *scene2 =
|
||||
obs_data_get_string(array_obj, "sceneRoundTripScene2");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
double delay = obs_data_get_double(array_obj, "delay");
|
||||
int delayMultiplier =
|
||||
obs_data_get_int(array_obj, "delayMultiplier");
|
||||
if (delayMultiplier == 0 ||
|
||||
(delayMultiplier != 1 && delayMultiplier % 60 != 0))
|
||||
delayMultiplier = 1;
|
||||
bool interruptible =
|
||||
obs_data_get_bool(array_obj, "interruptible");
|
||||
|
||||
switcher->sceneSequenceSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene1),
|
||||
GetWeakSourceByName(scene2),
|
||||
GetWeakTransitionByName(transition), delay,
|
||||
delayMultiplier, interruptible,
|
||||
(strcmp(scene2, previous_scene_name) == 0));
|
||||
switcher->sceneSequenceSwitches.emplace_back();
|
||||
sceneSequenceSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -320,7 +272,7 @@ void AdvSceneSwitcher::setupSequenceTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->sceneSequenceSwitches);
|
||||
ui->sceneSequenceSwitches->addItem(item);
|
||||
SequenceWidget *sw = new SequenceWidget(&s);
|
||||
SequenceWidget *sw = new SequenceWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->sceneSequenceSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -345,6 +297,76 @@ void SceneSequenceSwitch::logSleep(int dur)
|
|||
blog(LOG_INFO, "sequence sleep %d", dur);
|
||||
}
|
||||
|
||||
void SceneSequenceSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(startScene);
|
||||
const char *startSceneName = obs_source_get_name(source);
|
||||
obs_data_set_string(obj, "startScene", startSceneName);
|
||||
obs_source_release(source);
|
||||
|
||||
obs_data_set_double(obj, "delay", delay);
|
||||
|
||||
obs_data_set_int(obj, "delayMultiplier", delayMultiplier);
|
||||
|
||||
obs_data_set_bool(obj, "interruptible", interruptible);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldScequence(obs_data_t *obj, SceneSequenceSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene1 = obs_data_get_string(obj, "sceneRoundTripScene1");
|
||||
|
||||
if (strcmp(scene1, "") == 0)
|
||||
return false;
|
||||
|
||||
s->startScene = GetWeakSourceByName(scene1);
|
||||
|
||||
const char *scene2 = obs_data_get_string(obj, "sceneRoundTripScene2");
|
||||
s->scene = GetWeakSourceByName(scene2);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
s->delay = obs_data_get_double(obj, "delay");
|
||||
|
||||
int delayMultiplier = obs_data_get_int(obj, "delayMultiplier");
|
||||
if (delayMultiplier == 0 ||
|
||||
(delayMultiplier != 1 && delayMultiplier % 60 != 0))
|
||||
delayMultiplier = 1;
|
||||
s->delayMultiplier = delayMultiplier;
|
||||
|
||||
s->interruptible = obs_data_get_bool(obj, "interruptible");
|
||||
|
||||
s->usePreviousScene = strcmp(scene2, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SceneSequenceSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
if (loadOldScequence(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "startScene");
|
||||
startScene = GetWeakSourceByName(scene);
|
||||
|
||||
delay = obs_data_get_double(obj, "delay");
|
||||
|
||||
delayMultiplier = obs_data_get_int(obj, "delayMultiplier");
|
||||
if (delayMultiplier == 0 ||
|
||||
(delayMultiplier != 1 && delayMultiplier % 60 != 0))
|
||||
delayMultiplier = 1;
|
||||
|
||||
interruptible = obs_data_get_bool(obj, "interruptible");
|
||||
}
|
||||
|
||||
void populateDelayUnits(QComboBox *list)
|
||||
{
|
||||
list->addItem(obs_module_text("AdvSceneSwitcher.unit.secends"));
|
||||
|
|
@ -352,7 +374,8 @@ void populateDelayUnits(QComboBox *list)
|
|||
list->addItem(obs_module_text("AdvSceneSwitcher.unit.hours"));
|
||||
}
|
||||
|
||||
SequenceWidget::SequenceWidget(SceneSequenceSwitch *s) : SwitchWidget(s)
|
||||
SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s)
|
||||
: SwitchWidget(parent, s, true, true)
|
||||
{
|
||||
delay = new QDoubleSpinBox();
|
||||
delayUnits = new QComboBox();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ void AdvSceneSwitcher::on_timeAdd_clicked()
|
|||
switcher->timeSwitches.emplace_back();
|
||||
|
||||
listAddClicked(ui->timeSwitches,
|
||||
new TimeSwitchWidget(&switcher->timeSwitches.back()),
|
||||
new TimeSwitchWidget(this,
|
||||
&switcher->timeSwitches.back()),
|
||||
ui->timeAdd, &addPulse);
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +122,7 @@ void SwitcherData::checkTimeSwitch(bool &match, OBSWeakSource &scene,
|
|||
match = checkRegularTime(s, interval);
|
||||
|
||||
if (match) {
|
||||
scene = (s.usePreviousScene) ? previousScene : s.scene;
|
||||
scene = s.getScene();
|
||||
transition = s.transition;
|
||||
match = true;
|
||||
|
||||
|
|
@ -138,28 +139,8 @@ void SwitcherData::saveTimeSwitches(obs_data_t *obj)
|
|||
for (TimeSwitch &s : switcher->timeSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *sceneSource = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
if ((s.usePreviousScene || sceneSource) && transition) {
|
||||
const char *sceneName =
|
||||
obs_source_get_name(sceneSource);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "scene",
|
||||
s.usePreviousScene
|
||||
? previous_scene_name
|
||||
: sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_int(array_obj, "trigger", s.trigger);
|
||||
obs_data_set_string(
|
||||
array_obj, "time",
|
||||
s.time.toString().toStdString().c_str());
|
||||
obs_data_array_push_back(timeArray, array_obj);
|
||||
}
|
||||
obs_source_release(sceneSource);
|
||||
obs_source_release(transition);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(timeArray, array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -177,18 +158,8 @@ void SwitcherData::loadTimeSwitches(obs_data_t *obj)
|
|||
for (size_t i = 0; i < count; i++) {
|
||||
obs_data_t *array_obj = obs_data_array_item(timeArray, i);
|
||||
|
||||
const char *scene = obs_data_get_string(array_obj, "scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
timeTrigger trigger =
|
||||
(timeTrigger)obs_data_get_int(array_obj, "trigger");
|
||||
QTime time = QTime::fromString(
|
||||
obs_data_get_string(array_obj, "time"));
|
||||
|
||||
switcher->timeSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene),
|
||||
GetWeakTransitionByName(transition), trigger, time,
|
||||
(strcmp(scene, previous_scene_name) == 0));
|
||||
switcher->timeSwitches.emplace_back();
|
||||
timeSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -201,7 +172,7 @@ void AdvSceneSwitcher::setupTimeTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->timeSwitches);
|
||||
ui->timeSwitches->addItem(item);
|
||||
TimeSwitchWidget *sw = new TimeSwitchWidget(&s);
|
||||
TimeSwitchWidget *sw = new TimeSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->timeSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -210,6 +181,48 @@ void AdvSceneSwitcher::setupTimeTab()
|
|||
addPulse = PulseWidget(ui->timeAdd, QColor(Qt::green));
|
||||
}
|
||||
|
||||
void TimeSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_data_set_int(obj, "trigger", trigger);
|
||||
obs_data_set_string(obj, "time", time.toString().toStdString().c_str());
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldTime(obs_data_t *obj, TimeSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "scene");
|
||||
|
||||
if (strcmp(scene, "") == 0)
|
||||
return false;
|
||||
|
||||
s->scene = GetWeakSourceByName(scene);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
s->trigger = (timeTrigger)obs_data_get_int(obj, "trigger");
|
||||
s->time = QTime::fromString(obs_data_get_string(obj, "time"));
|
||||
s->usePreviousScene = strcmp(scene, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TimeSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
if (loadOldTime(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
trigger = (timeTrigger)obs_data_get_int(obj, "trigger");
|
||||
time = QTime::fromString(obs_data_get_string(obj, "time"));
|
||||
}
|
||||
|
||||
void populateTriggers(QComboBox *list)
|
||||
{
|
||||
list->addItem(obs_module_text("AdvSceneSwitcher.timeTab.anyDay"));
|
||||
|
|
@ -227,7 +240,8 @@ void populateTriggers(QComboBox *list)
|
|||
Qt::ToolTipRole);
|
||||
}
|
||||
|
||||
TimeSwitchWidget::TimeSwitchWidget(TimeSwitch *s) : SwitchWidget(s)
|
||||
TimeSwitchWidget::TimeSwitchWidget(QWidget *parent, TimeSwitch *s)
|
||||
: SwitchWidget(parent, s, true, true)
|
||||
{
|
||||
triggers = new QComboBox();
|
||||
time = new QTimeEdit();
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ void AdvSceneSwitcher::on_transitionsAdd_clicked()
|
|||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->sceneTransitions.emplace_back();
|
||||
|
||||
listAddClicked(
|
||||
ui->sceneTransitions,
|
||||
new TransitionSwitchWidget(&switcher->sceneTransitions.back()));
|
||||
listAddClicked(ui->sceneTransitions,
|
||||
new TransitionSwitchWidget(
|
||||
this, &switcher->sceneTransitions.back()));
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_transitionsRemove_clicked()
|
||||
|
|
@ -77,6 +77,7 @@ void AdvSceneSwitcher::on_defaultTransitionsAdd_clicked()
|
|||
|
||||
listAddClicked(ui->defaultTransitions,
|
||||
new DefTransitionSwitchWidget(
|
||||
this,
|
||||
&switcher->defaultSceneTransitions.back()));
|
||||
}
|
||||
|
||||
|
|
@ -377,7 +378,8 @@ void AdvSceneSwitcher::setupTransitionsTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->sceneTransitions);
|
||||
ui->sceneTransitions->addItem(item);
|
||||
TransitionSwitchWidget *sw = new TransitionSwitchWidget(&s);
|
||||
TransitionSwitchWidget *sw =
|
||||
new TransitionSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->sceneTransitions->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -387,7 +389,7 @@ void AdvSceneSwitcher::setupTransitionsTab()
|
|||
item = new QListWidgetItem(ui->defaultTransitions);
|
||||
ui->defaultTransitions->addItem(item);
|
||||
DefTransitionSwitchWidget *sw =
|
||||
new DefTransitionSwitchWidget(&s);
|
||||
new DefTransitionSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->defaultTransitions->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -407,8 +409,9 @@ bool SceneTransition::valid()
|
|||
(SceneSwitcherEntry::valid() && WeakSourceValid(scene2));
|
||||
}
|
||||
|
||||
TransitionSwitchWidget::TransitionSwitchWidget(SceneTransition *s)
|
||||
: SwitchWidget(s, false)
|
||||
TransitionSwitchWidget::TransitionSwitchWidget(QWidget *parent,
|
||||
SceneTransition *s)
|
||||
: SwitchWidget(parent, s, false)
|
||||
{
|
||||
scenes2 = new QComboBox();
|
||||
|
||||
|
|
@ -463,8 +466,9 @@ void TransitionSwitchWidget::Scene2Changed(const QString &text)
|
|||
switchData->scene2 = GetWeakSourceByQString(text);
|
||||
}
|
||||
|
||||
DefTransitionSwitchWidget::DefTransitionSwitchWidget(DefaultSceneTransition *s)
|
||||
: SwitchWidget(s, false)
|
||||
DefTransitionSwitchWidget::DefTransitionSwitchWidget(QWidget *parent,
|
||||
DefaultSceneTransition *s)
|
||||
: SwitchWidget(parent, s, false)
|
||||
{
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ void AdvSceneSwitcher::on_windowAdd_clicked()
|
|||
switcher->windowSwitches.emplace_back();
|
||||
|
||||
listAddClicked(ui->windowSwitches,
|
||||
new WindowSwitchWidget(&switcher->windowSwitches.back()),
|
||||
new WindowSwitchWidget(this,
|
||||
&switcher->windowSwitches.back()),
|
||||
ui->windowAdd, &addPulse);
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +235,7 @@ void SwitcherData::checkWindowTitleSwitch(bool &match, OBSWeakSource &scene,
|
|||
if (isRunning(s.window) &&
|
||||
(fullscreen && (max && (focus || ignore)))) {
|
||||
match = true;
|
||||
scene = s.scene;
|
||||
scene = s.getScene();
|
||||
transition = s.transition;
|
||||
|
||||
if (verbose)
|
||||
|
|
@ -250,26 +251,9 @@ void SwitcherData::saveWindowTitleSwitches(obs_data_t *obj)
|
|||
for (WindowSwitch &s : switcher->windowSwitches) {
|
||||
obs_data_t *array_obj = obs_data_create();
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s.scene);
|
||||
obs_source_t *transition =
|
||||
obs_weak_source_get_source(s.transition);
|
||||
if (source && transition) {
|
||||
const char *sceneName = obs_source_get_name(source);
|
||||
const char *transitionName =
|
||||
obs_source_get_name(transition);
|
||||
obs_data_set_string(array_obj, "scene", sceneName);
|
||||
obs_data_set_string(array_obj, "transition",
|
||||
transitionName);
|
||||
obs_data_set_string(array_obj, "window_title",
|
||||
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);
|
||||
obs_source_release(transition);
|
||||
s.save(array_obj);
|
||||
obs_data_array_push_back(windowTitleArray, array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_set_array(obj, "switches", windowTitleArray);
|
||||
|
|
@ -298,26 +282,8 @@ void SwitcherData::loadWindowTitleSwitches(obs_data_t *obj)
|
|||
obs_data_t *array_obj =
|
||||
obs_data_array_item(windowTitleArray, i);
|
||||
|
||||
const char *scene = obs_data_get_string(array_obj, "scene");
|
||||
const char *transition =
|
||||
obs_data_get_string(array_obj, "transition");
|
||||
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,
|
||||
maximized, focus);
|
||||
switcher->windowSwitches.emplace_back();
|
||||
windowSwitches.back().load(array_obj);
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
|
|
@ -349,7 +315,7 @@ void AdvSceneSwitcher::setupTitleTab()
|
|||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->windowSwitches);
|
||||
ui->windowSwitches->addItem(item);
|
||||
WindowSwitchWidget *sw = new WindowSwitchWidget(&s);
|
||||
WindowSwitchWidget *sw = new WindowSwitchWidget(this, &s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->windowSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
|
@ -368,7 +334,70 @@ void AdvSceneSwitcher::setupTitleTab()
|
|||
}
|
||||
}
|
||||
|
||||
WindowSwitchWidget::WindowSwitchWidget(WindowSwitch *s) : SwitchWidget(s, false)
|
||||
void WindowSwitch::save(obs_data_t *obj)
|
||||
{
|
||||
SceneSwitcherEntry::save(obj);
|
||||
|
||||
obs_data_set_string(obj, "windowTitle", window.c_str());
|
||||
obs_data_set_bool(obj, "fullscreen", fullscreen);
|
||||
obs_data_set_bool(obj, "maximized", maximized);
|
||||
obs_data_set_bool(obj, "focus", focus);
|
||||
}
|
||||
|
||||
// To be removed in future version
|
||||
bool loadOldWindow(obs_data_t *obj, WindowSwitch *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
const char *scene = obs_data_get_string(obj, "scene");
|
||||
|
||||
if (strcmp(scene, "") == 0)
|
||||
return false;
|
||||
|
||||
s->scene = GetWeakSourceByName(scene);
|
||||
|
||||
const char *transition = obs_data_get_string(obj, "transition");
|
||||
s->transition = GetWeakTransitionByName(transition);
|
||||
|
||||
s->window = obs_data_get_string(obj, "window_title");
|
||||
s->fullscreen = obs_data_get_bool(obj, "fullscreen");
|
||||
#if __APPLE__
|
||||
// TODO:
|
||||
// not implemented on MacOS as I cannot test it
|
||||
s->maximized = false;
|
||||
#else
|
||||
s->maximized = obs_data_get_bool(obj, "maximized");
|
||||
#endif
|
||||
s->focus = obs_data_get_bool(obj, "focus") ||
|
||||
!obs_data_has_user_value(obj, "focus");
|
||||
s->usePreviousScene = strcmp(scene, previous_scene_name) == 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WindowSwitch::load(obs_data_t *obj)
|
||||
{
|
||||
if (loadOldWindow(obj, this))
|
||||
return;
|
||||
|
||||
SceneSwitcherEntry::load(obj);
|
||||
|
||||
window = obs_data_get_string(obj, "windowTitle");
|
||||
fullscreen = obs_data_get_bool(obj, "fullscreen");
|
||||
#if __APPLE__
|
||||
// TODO:
|
||||
// not implemented on MacOS as I cannot test it
|
||||
maximized = false;
|
||||
#else
|
||||
maximized = obs_data_get_bool(obj, "maximized");
|
||||
#endif
|
||||
focus = obs_data_get_bool(obj, "focus") ||
|
||||
!obs_data_has_user_value(obj, "focus");
|
||||
}
|
||||
|
||||
WindowSwitchWidget::WindowSwitchWidget(QWidget *parent, WindowSwitch *s)
|
||||
: SwitchWidget(parent, s, false, true)
|
||||
{
|
||||
windows = new QComboBox();
|
||||
fullscreen = new QCheckBox(
|
||||
|
|
|
|||
|
|
@ -92,6 +92,12 @@ void SwitcherData::Prune()
|
|||
if (!s.valid())
|
||||
audioSwitches.erase(audioSwitches.begin() + i--);
|
||||
}
|
||||
|
||||
for (auto &sg : sceneGroups) {
|
||||
for (size_t i = 0; i < sg.scenes.size(); i++)
|
||||
if (!WeakSourceValid(sg.scenes[i]))
|
||||
sg.scenes.erase(sg.scenes.begin() + i--);
|
||||
}
|
||||
}
|
||||
|
||||
bool SwitcherData::versionChanged(obs_data_t *obj, std::string currentVersion)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user