diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui index 212e32fa..e9251f69 100644 --- a/forms/advanced-scene-switcher.ui +++ b/forms/advanced-scene-switcher.ui @@ -2546,81 +2546,14 @@ - - - - - If no switch condition is met switch to - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - - - - using the - - - - - - - - - - transition for a duration of - - - - - - - s - - - 999999999.990000009536743 - - - - - - - or any of the options below: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + Functionality disabled - To activate select "If no switch condition is met switch to any scene in Random tab" on General tab + + - + 0 @@ -2628,7 +2561,7 @@ - true + false diff --git a/src/general.cpp b/src/general.cpp index f2d1c646..38392b6e 100644 --- a/src/general.cpp +++ b/src/general.cpp @@ -31,6 +31,7 @@ void SceneSwitcher::on_noMatchDontSwitch_clicked() std::lock_guard lock(switcher->m); switcher->switchIfNotMatching = NO_SWITCH; ui->noMatchSwitchScene->setEnabled(false); + ui->randomDisabledWarning->setVisible(true); } void SceneSwitcher::on_noMatchSwitch_clicked() @@ -42,6 +43,7 @@ void SceneSwitcher::on_noMatchSwitch_clicked() switcher->switchIfNotMatching = SWITCH; ui->noMatchSwitchScene->setEnabled(true); UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText()); + ui->randomDisabledWarning->setVisible(true); } void SceneSwitcher::on_noMatchRandomSwitch_clicked() @@ -52,6 +54,7 @@ void SceneSwitcher::on_noMatchRandomSwitch_clicked() std::lock_guard lock(switcher->m); switcher->switchIfNotMatching = RANDOM_SWITCH; ui->noMatchSwitchScene->setEnabled(false); + ui->randomDisabledWarning->setVisible(false); } void SceneSwitcher::on_startupBehavior_currentIndexChanged(int index) diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 77eb86c0..75d8a486 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -43,7 +43,6 @@ public: const QString &scene2); int DefaultTransitionsFindByData(const QString &scene); int IgnoreIdleWindowsFindByData(const QString &window); - int randomFindByData(const QString &scene); void UpdateNonMatchingScene(const QString &name); void UpdateAutoStopScene(const QString &name); @@ -171,7 +170,6 @@ public slots: void on_randomAdd_clicked(); void on_randomRemove_clicked(); - void on_randomScenesList_currentRowChanged(int idx); void on_fileAdd_clicked(); void on_fileRemove_clicked(); diff --git a/src/headers/switch-random.hpp b/src/headers/switch-random.hpp index 7090aa56..dc1bf826 100644 --- a/src/headers/switch-random.hpp +++ b/src/headers/switch-random.hpp @@ -1,23 +1,40 @@ #pragma once -#include #include "utility.hpp" #include "switch-generic.hpp" struct RandomSwitch : SceneSwitcherEntry { - double delay; - std::string randomSwitchStr; + double delay = 0.0; const char *getType() { return "random"; } + inline RandomSwitch() {} inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_, - double delay_, std::string str) - : SceneSwitcherEntry(scene_, transition_), - delay(delay_), - randomSwitchStr(str) + double delay_) + : SceneSwitcherEntry(scene_, transition_), delay(delay_) { } }; -static inline QString MakeRandomSwitchName(const QString &scene, - const QString &transition, - double &delay); +class RandomSwitchWidget : public SwitchWidget { + Q_OBJECT + +public: + RandomSwitchWidget(RandomSwitch *s); + RandomSwitch *getSwitchData(); + void setSwitchData(RandomSwitch *s); + + static void swapSwitchData(RandomSwitchWidget *s1, + RandomSwitchWidget *s2); + +private slots: + void DelayChanged(double d); + +private: + QDoubleSpinBox *delay; + + QLabel *switchLabel; + QLabel *usingLabel; + QLabel *forLabel; + + RandomSwitch *switchData; +}; diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp index 609ee0ff..da0b0be6 100644 --- a/src/headers/switcher-data-structs.hpp +++ b/src/headers/switcher-data-structs.hpp @@ -73,7 +73,7 @@ struct SwitcherData { std::vector sceneSequenceSwitches; int sceneSequenceMultiplier = 1; - std::vector randomSwitches; + std::deque randomSwitches; FileIOData fileIO; IdleData idleData; diff --git a/src/switch-random.cpp b/src/switch-random.cpp index fe71c156..b3dc1af6 100644 --- a/src/switch-random.cpp +++ b/src/switch-random.cpp @@ -2,114 +2,35 @@ #include "headers/advanced-scene-switcher.hpp" -void SceneSwitcher::on_randomScenesList_currentRowChanged(int idx) -{ - if (loading) - return; - if (idx == -1) - return; - - QListWidgetItem *item = ui->randomScenesList->item(idx); - - QString randomSceneStr = item->data(Qt::UserRole).toString(); - - std::lock_guard lock(switcher->m); - for (auto &s : switcher->randomSwitches) { - if (randomSceneStr.compare(s.randomSwitchStr.c_str()) == 0) { - QString sceneName = GetWeakSourceName(s.scene).c_str(); - QString transitionName = - GetWeakSourceName(s.transition).c_str(); - ui->randomScenes->setCurrentText(sceneName); - ui->randomSpinBox->setValue(s.delay); - ui->randomTransitions->setCurrentText(transitionName); - break; - } - } -} - -int SceneSwitcher::randomFindByData(const QString &randomStr) -{ - int count = ui->randomScenesList->count(); - - for (int i = 0; i < count; i++) { - QListWidgetItem *item = ui->randomScenesList->item(i); - QString str = item->data(Qt::UserRole).toString(); - - if (str == randomStr) - return i; - } - - return -1; -} +static QMetaObject::Connection addPulse; void SceneSwitcher::on_randomAdd_clicked() { - QString sceneName = ui->randomScenes->currentText(); - QString transitionName = ui->randomTransitions->currentText(); - double delay = ui->randomSpinBox->value(); + ui->randomAdd->disconnect(addPulse); - if (sceneName.isEmpty()) - return; + std::lock_guard lock(switcher->m); + switcher->randomSwitches.emplace_back(); - OBSWeakSource source = GetWeakSourceByQString(sceneName); - OBSWeakSource transition = GetWeakTransitionByQString(transitionName); - - QString text = MakeRandomSwitchName(sceneName, transitionName, delay); - QVariant v = QVariant::fromValue(text); - - int idx = randomFindByData(text); - - if (idx == -1) { - std::lock_guard lock(switcher->m); - switcher->randomSwitches.emplace_back( - source, transition, delay, text.toUtf8().constData()); - - QListWidgetItem *item = - new QListWidgetItem(text, ui->randomScenesList); - item->setData(Qt::UserRole, v); - } else { - QListWidgetItem *item = ui->randomScenesList->item(idx); - item->setText(text); - - { - std::lock_guard lock(switcher->m); - for (auto &s : switcher->randomSwitches) { - if (s.scene == source) { - s.delay = delay; - s.transition = transition; - s.randomSwitchStr = - text.toUtf8().constData(); - ; - break; - } - } - } - - ui->randomScenesList->sortItems(); - } + QListWidgetItem *item; + item = new QListWidgetItem(ui->randomSwitches); + ui->randomSwitches->addItem(item); + RandomSwitchWidget *sw = + new RandomSwitchWidget(&switcher->randomSwitches.back()); + item->setSizeHint(sw->minimumSizeHint()); + ui->randomSwitches->setItemWidget(item, sw); } void SceneSwitcher::on_randomRemove_clicked() { - QListWidgetItem *item = ui->randomScenesList->currentItem(); + QListWidgetItem *item = ui->randomSwitches->currentItem(); if (!item) return; - std::string text = - item->data(Qt::UserRole).toString().toUtf8().constData(); - { std::lock_guard lock(switcher->m); + int idx = ui->randomSwitches->currentRow(); auto &switches = switcher->randomSwitches; - - for (auto it = switches.begin(); it != switches.end(); ++it) { - auto &s = *it; - - if (s.randomSwitchStr == text) { - switches.erase(it); - break; - } - } + switches.erase(switches.begin() + idx); } delete item; @@ -121,7 +42,7 @@ void SwitcherData::checkRandom(bool &match, OBSWeakSource &scene, if (randomSwitches.size() == 0) return; - std::vector rs(randomSwitches); + std::deque rs(randomSwitches); std::random_device rng; std::mt19937 urng(rng()); std::shuffle(rs.begin(), rs.end(), urng); @@ -185,15 +106,9 @@ void SwitcherData::loadRandomSwitches(obs_data_t *obj) obs_data_get_string(array_obj, "transition"); double delay = obs_data_get_double(array_obj, "delay"); - std::string randomSwitchStr = - MakeRandomSwitchName(scene, transition, delay) - .toUtf8() - .constData(); - switcher->randomSwitches.emplace_back( GetWeakSourceByName(scene), - GetWeakTransitionByName(transition), delay, - randomSwitchStr); + GetWeakTransitionByName(transition), delay); obs_data_release(array_obj); } @@ -202,26 +117,86 @@ void SwitcherData::loadRandomSwitches(obs_data_t *obj) void SceneSwitcher::setupRandomTab() { - populateSceneSelection(ui->randomScenes, false); - populateTransitionSelection(ui->randomTransitions); - for (auto &s : switcher->randomSwitches) { - std::string sceneName = GetWeakSourceName(s.scene); - std::string transitionName = GetWeakSourceName(s.transition); - QString text = MakeRandomSwitchName( - sceneName.c_str(), transitionName.c_str(), s.delay); - - QListWidgetItem *item = - new QListWidgetItem(text, ui->randomScenesList); - item->setData(Qt::UserRole, text); + QListWidgetItem *item; + item = new QListWidgetItem(ui->randomSwitches); + ui->randomSwitches->addItem(item); + RandomSwitchWidget *sw = new RandomSwitchWidget(&s); + item->setSizeHint(sw->minimumSizeHint()); + ui->randomSwitches->setItemWidget(item, sw); } + + if (switcher->randomSwitches.size() == 0) + addPulse = PulseWidget(ui->randomAdd, QColor(Qt::green)); + + if (switcher->switchIfNotMatching != RANDOM_SWITCH) + PulseWidget(ui->randomDisabledWarning, QColor(Qt::red), + QColor(0, 0, 0, 0), "QLabel "); + else + ui->randomDisabledWarning->setVisible(false); } -static inline QString MakeRandomSwitchName(const QString &scene, - const QString &transition, - double &delay) +RandomSwitchWidget::RandomSwitchWidget(RandomSwitch *s) : SwitchWidget(s, false) { - return QStringLiteral("[") + scene + QStringLiteral(", ") + transition + - QStringLiteral("]: ") + QString::number(delay) + - QStringLiteral(" seconds"); + delay = new QDoubleSpinBox(); + + switchLabel = new QLabel("If no switch condition is met switch to "); + usingLabel = new QLabel("using"); + forLabel = new QLabel("for"); + + QWidget::connect(delay, SIGNAL(valueChanged(double)), this, + SLOT(DelayChanged(double))); + + delay->setSuffix("s"); + delay->setMaximum(999999999.9); + + if (s) { + delay->setValue(s->delay); + } + + setStyleSheet("* { background-color: transparent; }"); + + QHBoxLayout *mainLayout = new QHBoxLayout; + + mainLayout->addWidget(switchLabel); + mainLayout->addWidget(scenes); + mainLayout->addWidget(usingLabel); + mainLayout->addWidget(transitions); + mainLayout->addWidget(forLabel); + mainLayout->addWidget(delay); + mainLayout->addStretch(); + + setLayout(mainLayout); + + switchData = s; + + loading = false; +} + +RandomSwitch *RandomSwitchWidget::getSwitchData() +{ + return switchData; +} + +void RandomSwitchWidget::setSwitchData(RandomSwitch *s) +{ + switchData = s; +} + +void RandomSwitchWidget::swapSwitchData(RandomSwitchWidget *s1, + RandomSwitchWidget *s2) +{ + SwitchWidget::swapSwitchData(s1, s2); + + RandomSwitch *t = s1->getSwitchData(); + s1->setSwitchData(s2->getSwitchData()); + s2->setSwitchData(t); +} + +void RandomSwitchWidget::DelayChanged(double d) +{ + if (loading || !switchData) + return; + std::lock_guard lock(switcher->m); + switchData->delay = d; }