diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini
index cadf97da..a04f9f70 100644
--- a/data/locale/de-DE.ini
+++ b/data/locale/de-DE.ini
@@ -193,8 +193,8 @@ AdvSceneSwitcher.sceneSequenceTab.fileType="Text Dateien (*.txt)"
AdvSceneSwitcher.sceneSequenceTab.interruptible="kann unterbrochen werden"
AdvSceneSwitcher.sceneSequenceTab.interruptibleHint="Andere Szenenwechselmethoden können diese Sequenz unterbrechen"
AdvSceneSwitcher.sceneSequenceTab.extendEdit="Szenenfolge erweitern"
-AdvSceneSwitcher.sceneSequenceTab.extendEntry="Nach {{delay}} {{delayUnits}} wechsle zu {{scenes}} mit {{transitions}}"
-AdvSceneSwitcher.sceneSequenceTab.entry="Wenn {{startScenes}} aktiv ist wechsle zu {{scenes}} nach {{delay}} {{delayUnits}} mit {{transitions}} {{interruptible}}"
+AdvSceneSwitcher.sceneSequenceTab.extendEntry="Nach {{delay}} wechsle zu {{scenes}} mit {{transitions}}"
+AdvSceneSwitcher.sceneSequenceTab.entry="Wenn {{startScenes}} aktiv ist wechsle zu {{scenes}} nach {{delay}} mit {{transitions}} {{interruptible}}"
AdvSceneSwitcher.sceneSequenceTab.help="Dieser Tab ermöglicht es automatisiert zu einer anderen Szene zu wechseln, nachdem eine Szene für die konfigurierte Zeit aktiv war.\nZum Beispiel kann so automatisch zwischen zwei Szenen hin und her gewechselt werden.\n\nKlicke auf das markierte Plus Symbol, um einen neuen Eintrag hinzuzufügen."
; Audio Tab
@@ -202,9 +202,9 @@ AdvSceneSwitcher.audioTab.title="Audio"
AdvSceneSwitcher.audioTab.condition.above="über"
AdvSceneSwitcher.audioTab.condition.below="unter"
AdvSceneSwitcher.audioTab.ignoreInactiveSource="außer Audio Quelle ist inaktiv"
-AdvSceneSwitcher.audioTab.entry="Wenn die Lautstärke von {{audioSources}} {{condition}} {{volumeWidget}} ist für {{duration}} wechsle zu {{scenes}} mit {{transitions}} {{ignoreInactiveSource}}"
+AdvSceneSwitcher.audioTab.entry="Wenn die Lautstärke von {{audioSources}} {{condition}} {{volumeWidget}} ist für {{duration}} Sekunden wechsle zu {{scenes}} mit {{transitions}} {{ignoreInactiveSource}}"
AdvSceneSwitcher.audioTab.multiMatchfallbackCondition="Wenn mehrere Einträge zutreffen ..."
-AdvSceneSwitcher.audioTab.multiMatchfallback="... für {{duration}} wechsle zu {{scenes}} mit {{transitions}}"
+AdvSceneSwitcher.audioTab.multiMatchfallback="... für {{duration}} Sekunden wechsle zu {{scenes}} mit {{transitions}}"
AdvSceneSwitcher.audioTab.help="Dieser Tab ermöglicht es basierend auf der Lautstärke von Audioquellen Szenen zu wechseln.\nSo kann zum Beispiel automatisch zu einer Szene gewechselt werden, wenn die Lautstärke eines Mikrofons eine konfigurierte Schwelle überschreitet.\n\nKlicke auf das markierte Plus Symbol, um einen neuen Eintrag hinzuzufügen."
; Video Tab
diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini
index 513af24a..c21692d2 100644
--- a/data/locale/en-US.ini
+++ b/data/locale/en-US.ini
@@ -192,9 +192,9 @@ AdvSceneSwitcher.sceneSequenceTab.loadSuccess="Advanced Scene Switcher settings
AdvSceneSwitcher.sceneSequenceTab.fileType="Text files (*.txt)"
AdvSceneSwitcher.sceneSequenceTab.interruptible="interruptible"
AdvSceneSwitcher.sceneSequenceTab.interruptibleHint="Other switching methods are allowed to interrupt this scene sequence"
-AdvSceneSwitcher.sceneSequenceTab.entry="When {{startScenes}} is active switch to {{scenes}} after {{delay}} {{delayUnits}} using {{transitions}} {{interruptible}}"
+AdvSceneSwitcher.sceneSequenceTab.entry="When {{startScenes}} is active switch to {{scenes}} after {{delay}} using {{transitions}} {{interruptible}}"
AdvSceneSwitcher.sceneSequenceTab.extendEdit="Extend Sequence"
-AdvSceneSwitcher.sceneSequenceTab.extendEntry="After {{delay}} {{delayUnits}} switch to {{scenes}} using {{transitions}}"
+AdvSceneSwitcher.sceneSequenceTab.extendEntry="After {{delay}} switch to {{scenes}} using {{transitions}}"
AdvSceneSwitcher.sceneSequenceTab.help="This tab will allow you to automatically switch to a different scene if a scene was active for a configured period of time.\nFor example, you could automatically cycle back and forth between two scenes automatically.\n\nClick on the highlighted plus symbol to continue."
; Audio Tab
@@ -202,9 +202,9 @@ AdvSceneSwitcher.audioTab.title="Audio"
AdvSceneSwitcher.audioTab.condition.above="above"
AdvSceneSwitcher.audioTab.condition.below="below"
AdvSceneSwitcher.audioTab.ignoreInactiveSource="unless source is inactive"
-AdvSceneSwitcher.audioTab.entry="When the volume of {{audioSources}} is {{condition}} {{volumeWidget}} for {{duration}} switch to {{scenes}} using {{transitions}} {{ignoreInactiveSource}}"
+AdvSceneSwitcher.audioTab.entry="When the volume of {{audioSources}} is {{condition}} {{volumeWidget}} for {{duration}} seconds switch to {{scenes}} using {{transitions}} {{ignoreInactiveSource}}"
AdvSceneSwitcher.audioTab.multiMatchfallbackCondition="If multiple entries match ..."
-AdvSceneSwitcher.audioTab.multiMatchfallback="... for {{duration}} switch to {{scenes}} using {{transitions}}"
+AdvSceneSwitcher.audioTab.multiMatchfallback="... for {{duration}} seconds switch to {{scenes}} using {{transitions}}"
AdvSceneSwitcher.audioTab.help="This tab will allow you to switch scenes based on the volume of sources.\nFor example, you could automatically switch to a different scene if the volume of your microphone reaches a certain threshold.\n\nClick on the highlighted plus symbol to continue."
; Video Tab
diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini
index 13526a89..c3f19f4f 100644
--- a/data/locale/zh-CN.ini
+++ b/data/locale/zh-CN.ini
@@ -168,7 +168,7 @@ AdvSceneSwitcher.sceneSequenceTab.loadTitle="从文件加载序列 ..."
AdvSceneSwitcher.sceneSequenceTab.loadFail="导入失败"
AdvSceneSwitcher.sceneSequenceTab.loadSuccess="导入失败成功"
AdvSceneSwitcher.sceneSequenceTab.fileType="文本文件 (*.txt)"
-AdvSceneSwitcher.sceneSequenceTab.entry="当场景 {{startScenes}} 被激活 {{delay}} {{delayUnits}}后使用转场特效 {{transitions}} 切换到场景 {{scenes}} {{interruptible}}"
+AdvSceneSwitcher.sceneSequenceTab.entry="当场景 {{startScenes}} 被激活 {{delay}} 后使用转场特效 {{transitions}} 切换到场景 {{scenes}} {{interruptible}}"
; Audio Tab
AdvSceneSwitcher.audioTab.title="音频"
diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui
index ba2f0f1f..9507c85d 100644
--- a/forms/advanced-scene-switcher.ui
+++ b/forms/advanced-scene-switcher.ui
@@ -226,7 +226,7 @@
-
-
+
-
@@ -243,22 +243,12 @@
- -
-
-
- s
-
-
- 999999.989999999990687
-
-
-
-
-
+
-
@@ -266,26 +256,6 @@
- -
-
-
- s
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
diff --git a/src/general.cpp b/src/general.cpp
index 5c7fd296..3383d697 100644
--- a/src/general.cpp
+++ b/src/general.cpp
@@ -59,14 +59,44 @@ void AdvSceneSwitcher::on_noMatchRandomSwitch_clicked()
ui->randomDisabledWarning->setVisible(false);
}
-void AdvSceneSwitcher::on_noMatchDelay_valueChanged(double i)
+void AdvSceneSwitcher::NoMatchDelayDurationChanged(double sec)
{
if (loading) {
return;
}
std::lock_guard lock(switcher->m);
- switcher->noMatchDelay = i;
+ switcher->noMatchDelay.seconds = sec;
+}
+
+void AdvSceneSwitcher::NoMatchDelayUnitChanged(DurationUnit unit)
+{
+ if (loading) {
+ return;
+ }
+
+ std::lock_guard lock(switcher->m);
+ switcher->noMatchDelay.displayUnit = unit;
+}
+
+void AdvSceneSwitcher::CooldownDurationChanged(double sec)
+{
+ if (loading) {
+ return;
+ }
+
+ std::lock_guard lock(switcher->m);
+ switcher->cooldown.seconds = sec;
+}
+
+void AdvSceneSwitcher::CooldownUnitChanged(DurationUnit unit)
+{
+ if (loading) {
+ return;
+ }
+
+ std::lock_guard lock(switcher->m);
+ switcher->cooldown.displayUnit = unit;
}
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
@@ -100,16 +130,6 @@ void AdvSceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
UpdateNonMatchingScene(text);
}
-void AdvSceneSwitcher::on_cooldownTime_valueChanged(double i)
-{
- if (loading) {
- return;
- }
-
- std::lock_guard lock(switcher->m);
- switcher->cooldown = i;
-}
-
void AdvSceneSwitcher::on_checkInterval_valueChanged(int value)
{
if (loading) {
@@ -469,9 +489,9 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
obs_data_set_string(obj, "non_matching_scene",
nonMatchingSceneName.c_str());
obs_data_set_int(obj, "switch_if_not_matching", switchIfNotMatching);
- obs_data_set_double(obj, "noMatchDelay", noMatchDelay);
+ noMatchDelay.Save(obj, "noMatchDelay", "noMatchDelayUnit");
- obs_data_set_double(obj, "cooldown", cooldown);
+ cooldown.Save(obj, "cooldown", "cooldownUnit");
obs_data_set_bool(obj, "active", !stop);
obs_data_set_int(obj, "startup_behavior", startupBehavior);
@@ -531,9 +551,9 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
std::string nonMatchingSceneName =
obs_data_get_string(obj, "non_matching_scene");
nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str());
- noMatchDelay = obs_data_get_double(obj, "noMatchDelay");
+ noMatchDelay.Load(obj, "noMatchDelay", "noMatchDelayUnit");
- cooldown = obs_data_get_double(obj, "cooldown");
+ cooldown.Load(obj, "cooldown", "cooldownUnit");
stop = !obs_data_get_bool(obj, "active");
startupBehavior =
@@ -660,12 +680,11 @@ void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
OBSWeakSource &transition, int &sleep)
{
if (match) {
- noMatchCount = 0;
+ noMatchDelay.Reset();
return;
}
- if ((noMatchCount * interval) / 1000.0 < noMatchDelay) {
- noMatchCount++;
+ if (!noMatchDelay.DurationReached()) {
return;
}
@@ -681,21 +700,16 @@ void SwitcherData::checkNoMatchSwitch(bool &match, OBSWeakSource &scene,
void SwitcherData::checkSwitchCooldown(bool &match)
{
- if (!match || cooldown == 0.) {
+ if (!match) {
return;
}
- auto now = std::chrono::high_resolution_clock::now();
- auto timePassed = std::chrono::duration_cast(
- now - lastMatchTime);
-
- if (timePassed.count() > cooldown * 1000) {
- lastMatchTime = now;
- return;
+ if (cooldown.DurationReached()) {
+ cooldown.Reset();
+ } else {
+ match = false;
+ vblog(LOG_INFO, "cooldown active - ignoring match");
}
-
- match = false;
- vblog(LOG_INFO, "cooldown active - ignoring match");
}
void populateStartupBehavior(QComboBox *cb)
@@ -751,14 +765,29 @@ void AdvSceneSwitcher::setupGeneralTab()
}
ui->noMatchSwitchScene->setCurrentText(
GetWeakSourceName(switcher->nonMatchingScene).c_str());
- ui->noMatchDelay->setValue(switcher->noMatchDelay);
- ui->noMatchDelay->setToolTip(obs_module_text(
+
+ DurationSelection *noMatchDelay = new DurationSelection();
+ noMatchDelay->SetDuration(switcher->noMatchDelay);
+ noMatchDelay->setToolTip(obs_module_text(
"AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip"));
+ ui->noMatchLayout->addWidget(noMatchDelay);
+ QWidget::connect(noMatchDelay, SIGNAL(DurationChanged(double)), this,
+ SLOT(NoMatchDelayDurationChanged(double)));
+ QWidget::connect(noMatchDelay, SIGNAL(UnitChanged(DurationUnit)), this,
+ SLOT(NoMatchDelayUnitChanged(DurationUnit)));
+
ui->checkInterval->setValue(switcher->interval);
- ui->cooldownTime->setValue(switcher->cooldown);
- ui->cooldownTime->setToolTip(obs_module_text(
+ DurationSelection *cooldownTime = new DurationSelection();
+ cooldownTime->SetDuration(switcher->cooldown);
+ cooldownTime->setToolTip(obs_module_text(
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
+ ui->cooldownLayout->addWidget(cooldownTime);
+ ui->cooldownLayout->addStretch();
+ QWidget::connect(cooldownTime, SIGNAL(DurationChanged(double)), this,
+ SLOT(CooldownDurationChanged(double)));
+ QWidget::connect(cooldownTime, SIGNAL(UnitChanged(DurationUnit)), this,
+ SLOT(CooldownUnitChanged(DurationUnit)));
ui->verboseLogging->setChecked(switcher->verbose);
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);
diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp
index b923861f..630cbda7 100644
--- a/src/headers/advanced-scene-switcher.hpp
+++ b/src/headers/advanced-scene-switcher.hpp
@@ -115,8 +115,10 @@ public slots:
void on_noMatchDontSwitch_clicked();
void on_noMatchSwitch_clicked();
void on_noMatchRandomSwitch_clicked();
- void on_noMatchDelay_valueChanged(double i);
- void on_cooldownTime_valueChanged(double i);
+ void NoMatchDelayDurationChanged(double);
+ void NoMatchDelayUnitChanged(DurationUnit);
+ void CooldownDurationChanged(double);
+ void CooldownUnitChanged(DurationUnit);
void on_startupBehavior_currentIndexChanged(int index);
void on_autoStartEvent_currentIndexChanged(int index);
void on_noMatchSwitchScene_currentTextChanged(const QString &text);
diff --git a/src/headers/switch-audio.hpp b/src/headers/switch-audio.hpp
index 7eeace18..e393d520 100644
--- a/src/headers/switch-audio.hpp
+++ b/src/headers/switch-audio.hpp
@@ -3,6 +3,7 @@
#include
#include "switch-generic.hpp"
+#include "duration-control.hpp"
#include "volume-control.hpp"
constexpr auto audio_func = 8;
@@ -18,9 +19,8 @@ struct AudioSwitch : virtual SceneSwitcherEntry {
OBSWeakSource audioSource = nullptr;
int volumeThreshold = 0;
audioCondition condition = ABOVE;
- double duration = 0;
+ Duration duration;
bool ignoreInactiveSource = true;
- unsigned int matchCount = 0;
float peak = -std::numeric_limits::infinity();
obs_volmeter_t *volmeter = nullptr;
@@ -50,8 +50,7 @@ struct AudioSwitchFallback : virtual SceneSwitcherEntry {
void load(obs_data_t *obj);
bool enable = false;
- double duration = 0;
- unsigned int matchCount = 0;
+ Duration duration;
};
class AudioSwitchWidget : public SwitchWidget {
@@ -77,7 +76,7 @@ private:
QComboBox *audioSources;
QComboBox *condition;
QSpinBox *audioVolumeThreshold;
- QDoubleSpinBox *duration;
+ DurationSelection *duration;
QCheckBox *ignoreInactiveSource;
VolControl *volMeter;
@@ -94,7 +93,7 @@ private slots:
void DurationChanged(double dur);
private:
- QDoubleSpinBox *duration;
+ DurationSelection *duration;
AudioSwitchFallback *switchData;
};
diff --git a/src/headers/switch-sequence.hpp b/src/headers/switch-sequence.hpp
index 654d4900..ca430ede 100644
--- a/src/headers/switch-sequence.hpp
+++ b/src/headers/switch-sequence.hpp
@@ -2,24 +2,17 @@
#include
#include "switch-generic.hpp"
+#include "duration-control.hpp"
constexpr auto round_trip_func = 1;
constexpr auto default_priority_1 = round_trip_func;
-typedef enum {
- SECONDS,
- MINUTES,
- HOURS,
-} delay_units;
-
struct SceneSequenceSwitch : SceneSwitcherEntry {
static bool pause;
SwitchTargetType startTargetType = SwitchTargetType::Scene;
OBSWeakSource startScene = nullptr;
- double delay = 0;
- int delayMultiplier = 1;
+ Duration delay;
bool interruptible = false;
- unsigned int matchCount = 0;
// nullptr marks start point and reaching end of extended sequence
SceneSequenceSwitch *activeSequence = nullptr;
@@ -57,22 +50,20 @@ public:
static void swapSwitchData(SequenceWidget *s1, SequenceWidget *s2);
- void UpdateDelay();
void UpdateWidgetStatus(bool showExtendText);
void setExtendedSequenceStartScene();
private slots:
void SceneChanged(const QString &text);
void DelayChanged(double delay);
- void DelayUnitsChanged(int idx);
+ void DelayUnitsChanged(DurationUnit);
void StartSceneChanged(const QString &text);
void InterruptibleChanged(int state);
void ExtendClicked();
void ReduceClicked();
protected:
- QDoubleSpinBox *delay;
- QComboBox *delayUnits;
+ DurationSelection *delay;
QComboBox *startScenes;
QCheckBox *interruptible;
QVBoxLayout *extendSequenceLayout;
diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp
index 90670306..b46b21c7 100644
--- a/src/headers/switcher-data-structs.hpp
+++ b/src/headers/switcher-data-structs.hpp
@@ -24,6 +24,8 @@
#include "switch-video.hpp"
#include "switch-network.hpp"
+#include "duration-control.hpp"
+
constexpr auto default_interval = 300;
constexpr auto previous_scene_name = "Previous Scene";
constexpr auto current_transition_name = "Current Transition";
@@ -74,12 +76,11 @@ struct SwitcherData {
SceneGroup *lastRandomSceneGroup;
OBSWeakSource nonMatchingScene;
NoMatch switchIfNotMatching = NO_SWITCH;
- double noMatchDelay = 0;
- double noMatchCount = 0;
+ Duration noMatchDelay;
StartupBehavior startupBehavior = PERSIST;
AutoStartEvent autoStartEvent = AutoStartEvent::NEVER;
- double cooldown = 0.;
+ Duration cooldown;
std::chrono::high_resolution_clock::time_point lastMatchTime;
std::deque windowSwitches;
diff --git a/src/switch-audio.cpp b/src/switch-audio.cpp
index e733f674..03ff4197 100644
--- a/src/switch-audio.cpp
+++ b/src/switch-audio.cpp
@@ -93,13 +93,7 @@ void AdvSceneSwitcher::on_audioFallback_toggled(bool on)
void SwitcherData::checkAudioSwitchFallback(OBSWeakSource &scene,
OBSWeakSource &transition)
{
- bool durationReached =
- ((unsigned long long)audioFallback.matchCount * interval) /
- 1000.0 >=
- audioFallback.duration;
-
- if (durationReached) {
-
+ if (audioFallback.duration.DurationReached()) {
scene = audioFallback.getScene();
transition = audioFallback.transition;
@@ -107,8 +101,6 @@ void SwitcherData::checkAudioSwitchFallback(OBSWeakSource &scene,
audioFallback.logMatch();
}
}
-
- audioFallback.matchCount++;
}
bool SwitcherData::checkAudioSwitch(OBSWeakSource &scene,
@@ -151,18 +143,11 @@ bool SwitcherData::checkAudioSwitch(OBSWeakSource &scene,
// Reset for next check
s.peak = -FLT_MAX;
- if (volumeThresholdreached) {
- s.matchCount++;
- } else {
- s.matchCount = 0;
+ if (!volumeThresholdreached) {
+ s.duration.Reset();
}
- bool durationReached =
- ((unsigned long long)s.matchCount * interval) /
- 1000.0 >=
- s.duration;
-
- if (volumeThresholdreached && durationReached) {
+ if (volumeThresholdreached && s.duration.DurationReached()) {
if (match) {
checkAudioSwitchFallback(scene, transition);
fallbackChecked = true;
@@ -184,7 +169,7 @@ bool SwitcherData::checkAudioSwitch(OBSWeakSource &scene,
}
if (!fallbackChecked) {
- audioFallback.matchCount = 0;
+ audioFallback.duration.Reset();
}
return match;
@@ -310,7 +295,7 @@ void AudioSwitch::save(obs_data_t *obj)
obs_data_set_int(obj, "volume", volumeThreshold);
obs_data_set_int(obj, "condition", condition);
- obs_data_set_double(obj, "duration", duration);
+ duration.Save(obj, "duration");
obs_data_set_bool(obj, "ignoreInactiveSource", ignoreInactiveSource);
}
@@ -323,7 +308,7 @@ void AudioSwitch::load(obs_data_t *obj)
volumeThreshold = obs_data_get_int(obj, "volume");
condition = (audioCondition)obs_data_get_int(obj, "condition");
- duration = obs_data_get_double(obj, "duration");
+ duration.Load(obj, "duration");
ignoreInactiveSource = obs_data_get_bool(obj, "ignoreInactiveSource");
volmeter = AddVolmeterToSource(this, audioSource);
@@ -336,7 +321,7 @@ void AudioSwitchFallback::save(obs_data_t *obj)
"audioFallbackTransition");
obs_data_set_bool(obj, "audioFallbackEnable", enable);
- obs_data_set_double(obj, "audioFallbackDuration", duration);
+ duration.Save(obj, "audioFallbackDuration");
}
void AudioSwitchFallback::load(obs_data_t *obj)
@@ -346,7 +331,7 @@ void AudioSwitchFallback::load(obs_data_t *obj)
"audioFallbackTransition");
enable = obs_data_get_bool(obj, "audioFallbackEnable");
- duration = obs_data_get_double(obj, "audioFallbackDuration");
+ duration.Load(obj, "audioFallbackDuration");
}
AudioSwitch::AudioSwitch(const AudioSwitch &other)
@@ -431,7 +416,7 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
audioSources = new QComboBox();
condition = new QComboBox();
audioVolumeThreshold = new QSpinBox();
- duration = new QDoubleSpinBox();
+ duration = new DurationSelection(this, false);
ignoreInactiveSource = new QCheckBox(obs_module_text(
"AdvSceneSwitcher.audioTab.ignoreInactiveSource"));
@@ -446,10 +431,6 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
audioVolumeThreshold->setMaximum(100);
audioVolumeThreshold->setMinimum(0);
- duration->setMinimum(0.0);
- duration->setMaximum(99.000000);
- duration->setSuffix("s");
-
QWidget::connect(volMeter->GetSlider(), SIGNAL(valueChanged(int)),
audioVolumeThreshold, SLOT(setValue(int)));
QWidget::connect(audioVolumeThreshold, SIGNAL(valueChanged(int)),
@@ -458,7 +439,7 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
SLOT(VolumeThresholdChanged(int)));
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
- QWidget::connect(duration, SIGNAL(valueChanged(double)), this,
+ QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
SLOT(DurationChanged(double)));
QWidget::connect(audioSources,
SIGNAL(currentTextChanged(const QString &)), this,
@@ -474,7 +455,7 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
GetWeakSourceName(s->audioSource).c_str());
audioVolumeThreshold->setValue(s->volumeThreshold);
condition->setCurrentIndex(s->condition);
- duration->setValue(s->duration);
+ duration->SetDuration(s->duration);
ignoreInactiveSource->setChecked(s->ignoreInactiveSource);
}
@@ -574,14 +555,14 @@ void AudioSwitchWidget::ConditionChanged(int cond)
switchData->condition = (audioCondition)cond;
}
-void AudioSwitchWidget::DurationChanged(double dur)
+void AudioSwitchWidget::DurationChanged(double sec)
{
if (loading || !switchData) {
return;
}
std::lock_guard lock(switcher->m);
- switchData->duration = dur;
+ switchData->duration.seconds = sec;
}
void AudioSwitchWidget::IgnoreInactiveChanged(int state)
@@ -598,17 +579,13 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
AudioSwitchFallback *s)
: SwitchWidget(parent, s, true, true)
{
- duration = new QDoubleSpinBox();
+ duration = new DurationSelection(this, false);
- duration->setMinimum(0.0);
- duration->setMaximum(99.000000);
- duration->setSuffix("s");
-
- QWidget::connect(duration, SIGNAL(valueChanged(double)), this,
+ QWidget::connect(duration, SIGNAL(DurationChanged(double)), this,
SLOT(DurationChanged(double)));
if (s) {
- duration->setValue(s->duration);
+ duration->SetDuration(s->duration);
}
QHBoxLayout *mainLayout = new QHBoxLayout;
@@ -626,12 +603,12 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
loading = false;
}
-void AudioSwitchFallbackWidget::DurationChanged(double dur)
+void AudioSwitchFallbackWidget::DurationChanged(double sec)
{
if (loading || !switchData) {
return;
}
std::lock_guard lock(switcher->m);
- switchData->duration = dur;
+ switchData->duration.seconds = sec;
}
diff --git a/src/switch-sequence.cpp b/src/switch-sequence.cpp
index 9900bb6c..abdb675a 100644
--- a/src/switch-sequence.cpp
+++ b/src/switch-sequence.cpp
@@ -315,8 +315,7 @@ void SceneSequenceSwitch::save(obs_data_t *obj, bool saveExt)
static_cast(startTargetType));
obs_data_set_string(obj, "startScene",
GetWeakSourceName(startScene).c_str());
- obs_data_set_double(obj, "delay", delay);
- obs_data_set_int(obj, "delayMultiplier", delayMultiplier);
+ delay.Save(obj, "delay");
obs_data_set_bool(obj, "interruptible", interruptible);
if (saveExt) {
@@ -342,13 +341,7 @@ void SceneSequenceSwitch::load(obs_data_t *obj, bool saveExt)
obs_data_get_int(obj, "startTargetType"));
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;
+ delay.Load(obj, "delay");
interruptible = obs_data_get_bool(obj, "interruptible");
@@ -422,7 +415,7 @@ bool SceneSequenceSwitch::checkMatch(OBSWeakSource currentScene, int &linger,
prepareUninterruptibleMatch(currentScene, linger);
}
} else {
- matchCount = 0;
+ delay.Reset();
if (root) {
root->activeSequence = nullptr;
@@ -435,11 +428,8 @@ bool SceneSequenceSwitch::checkMatch(OBSWeakSource currentScene, int &linger,
bool SceneSequenceSwitch::checkDurationMatchInterruptible()
{
- bool durationReached = matchCount * (switcher->interval / 1000.0) >=
- delay;
- matchCount++;
- if (durationReached) {
- matchCount = 0;
+ if (delay.DurationReached()) {
+ delay.Reset();
return true;
}
return false;
@@ -448,7 +438,7 @@ bool SceneSequenceSwitch::checkDurationMatchInterruptible()
void SceneSequenceSwitch::prepareUninterruptibleMatch(
OBSWeakSource currentScene, int &linger)
{
- int dur = delay * 1000;
+ int dur = delay.seconds * 1000;
if (dur > 0) {
switcher->waitScene = obs_weak_source_get_source(currentScene);
obs_source_release(switcher->waitScene);
@@ -493,8 +483,8 @@ void SceneSequenceSwitch::advanceActiveSequence()
return;
}
- // Reinit old matchCount value in case it was previously set
- activeSequence->matchCount = 0;
+ // Reinit delay in case it was previously set
+ activeSequence->delay.Reset();
}
}
@@ -521,19 +511,6 @@ void SceneSequenceSwitch::logSequenceCanceled()
blog(LOG_INFO, "unexpected scene change - cancel sequence");
}
-QString delayMultiplierToString(int delayMultiplier)
-{
- switch (delayMultiplier) {
- case 1:
- return obs_module_text("AdvSceneSwitcher.unit.secends");
- case 60:
- return obs_module_text("AdvSceneSwitcher.unit.minutes");
- case 60 * 60:
- return obs_module_text("AdvSceneSwitcher.unit.hours");
- }
- return "???";
-}
-
QString makeExtendText(SceneSequenceSwitch *s, int curLen = 0)
{
if (!s) {
@@ -542,8 +519,7 @@ QString makeExtendText(SceneSequenceSwitch *s, int curLen = 0)
QString ext = "";
- ext = QString::number(s->delay / s->delayMultiplier) + " ";
- ext += delayMultiplierToString(s->delayMultiplier);
+ ext = QString::fromStdString(s->delay.ToString()) + " ";
QString sceneName = GetWeakSourceName(s->scene).c_str();
if (s->targetType == SwitchTargetType::SceneGroup && s->group) {
@@ -567,13 +543,6 @@ QString makeExtendText(SceneSequenceSwitch *s, int curLen = 0)
}
}
-void populateDelayUnits(QComboBox *list)
-{
- list->addItem(obs_module_text("AdvSceneSwitcher.unit.secends"));
- list->addItem(obs_module_text("AdvSceneSwitcher.unit.minutes"));
- list->addItem(obs_module_text("AdvSceneSwitcher.unit.hours"));
-}
-
SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
bool extendSequence, bool editExtendMode,
bool showExtendText)
@@ -581,8 +550,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
{
this->setParent(parent);
- delay = new QDoubleSpinBox();
- delayUnits = new QComboBox();
+ delay = new DurationSelection();
startScenes = new QComboBox();
interruptible = new QCheckBox(obs_module_text(
"AdvSceneSwitcher.sceneSequenceTab.interruptible"));
@@ -605,10 +573,10 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SceneChanged(const QString &)));
- QWidget::connect(delay, SIGNAL(valueChanged(double)), this,
+ QWidget::connect(delay, SIGNAL(DurationChanged(double)), this,
SLOT(DelayChanged(double)));
- QWidget::connect(delayUnits, SIGNAL(currentIndexChanged(int)), this,
- SLOT(DelayUnitsChanged(int)));
+ QWidget::connect(delay, SIGNAL(UnitChanged(DurationUnit)), this,
+ SLOT(DelayUnitsChanged(DurationUnit)));
QWidget::connect(startScenes,
SIGNAL(currentTextChanged(const QString &)), this,
SLOT(StartSceneChanged(const QString &)));
@@ -620,9 +588,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
QWidget::connect(reduce, SIGNAL(clicked()), this,
SLOT(ReduceClicked()));
- delay->setMaximum(99999.000000);
AdvSceneSwitcher::populateSceneSelection(startScenes, false);
- populateDelayUnits(delayUnits);
interruptible->setToolTip(obs_module_text(
"AdvSceneSwitcher.sceneSequenceTab.interruptibleHint"));
@@ -633,7 +599,6 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
std::unordered_map widgetPlaceholders = {
{"{{scenes}}", scenes},
{"{{delay}}", delay},
- {"{{delayUnits}}", delayUnits},
{"{{transitions}}", transitions}};
placeWidgets(
obs_module_text(
@@ -646,7 +611,6 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
{"{{startScenes}}", startScenes},
{"{{scenes}}", scenes},
{"{{delay}}", delay},
- {"{{delayUnits}}", delayUnits},
{"{{transitions}}", transitions},
{"{{interruptible}}", interruptible}};
placeWidgets(obs_module_text(
@@ -710,46 +674,24 @@ void SequenceWidget::swapSwitchData(SequenceWidget *s1, SequenceWidget *s2)
s2->setSwitchData(t);
}
-void SequenceWidget::UpdateDelay()
-{
- if (switchData) {
- delay->setValue(switchData->delay /
- switchData->delayMultiplier);
- }
-}
-
-void SequenceWidget::DelayChanged(double delay)
+void SequenceWidget::DelayChanged(double sec)
{
if (loading || !switchData) {
return;
}
- switchData->delay = delay * switchData->delayMultiplier;
+ std::lock_guard lock(switcher->m);
+ switchData->delay.seconds = sec;
}
-void SequenceWidget::DelayUnitsChanged(int idx)
+void SequenceWidget::DelayUnitsChanged(DurationUnit unit)
{
if (loading || !switchData) {
return;
}
- delay_units unit = (delay_units)idx;
-
- switch (unit) {
- case SECONDS:
- switchData->delayMultiplier = 1;
- break;
- case MINUTES:
- switchData->delayMultiplier = 60;
- break;
- case HOURS:
- switchData->delayMultiplier = 60 * 60;
- break;
- default:
- break;
- }
-
- UpdateDelay();
+ std::lock_guard lock(switcher->m);
+ switchData->delay.displayUnit = unit;
}
void SequenceWidget::setExtendedSequenceStartScene()
@@ -811,21 +753,7 @@ void SequenceWidget::UpdateWidgetStatus(bool showExtendText)
makeExtendText(switchData->extendedSequence.get()));
}
- switch (switchData->delayMultiplier) {
- case 1:
- delayUnits->setCurrentIndex(0);
- break;
- case 60:
- delayUnits->setCurrentIndex(1);
- break;
- case 3600:
- delayUnits->setCurrentIndex(2);
- break;
- default:
- delayUnits->setCurrentIndex(0);
- }
- UpdateDelay();
-
+ delay->SetDuration(switchData->delay);
startScenes->setCurrentText(
GetWeakSourceName(switchData->startScene).c_str());
interruptible->setChecked(switchData->interruptible);