diff --git a/forms/advanced-scene-switcher.ui b/forms/advanced-scene-switcher.ui index 31e7157e..8a5f9ef9 100644 --- a/forms/advanced-scene-switcher.ui +++ b/forms/advanced-scene-switcher.ui @@ -3140,7 +3140,7 @@ Sequence - + @@ -3199,13 +3199,16 @@ - s + - 1000000.000000000000000 + 999999999.000000000000000 + + + diff --git a/src/advanced-scene-switcher.cpp b/src/advanced-scene-switcher.cpp index bc2f24a9..7904f436 100644 --- a/src/advanced-scene-switcher.cpp +++ b/src/advanced-scene-switcher.cpp @@ -236,7 +236,7 @@ void SceneSwitcher::loadUI() std::string transitionName = GetWeakSourceName(s.transition); QString text = MakeSceneRoundTripSwitchName( sceneName1.c_str(), sceneName2.c_str(), - transitionName.c_str(), (double)s.delay / 1000); + transitionName.c_str(), s.delay); QListWidgetItem *item = new QListWidgetItem(text, ui->sceneRoundTrips); @@ -245,10 +245,14 @@ void SceneSwitcher::loadUI() if (s.delay < smallestDelay) smallestDelay = s.delay; } - (smallestDelay < switcher->interval) + (smallestDelay * 1000 < switcher->interval) ? ui->intervalWarning->setVisible(true) : ui->intervalWarning->setVisible(false); + ui->sceneRoundTripDelayUnits->addItem("seconds"); + ui->sceneRoundTripDelayUnits->addItem("minutes"); + ui->sceneRoundTripDelayUnits->addItem("hours"); + for (auto &s : switcher->sceneTransitions) { std::string sceneName1 = GetWeakSourceName(s.scene1); std::string sceneName2 = GetWeakSourceName(s.scene2); diff --git a/src/general.cpp b/src/general.cpp index cd69e0d3..6a2a5c91 100644 --- a/src/general.cpp +++ b/src/general.cpp @@ -171,30 +171,31 @@ void SceneSwitcher::on_exportSettings_clicked() QString directory = QFileDialog::getSaveFileName( this, tr("Export Advanced Scene Switcher settings to file ..."), QDir::currentPath(), tr("Text files (*.txt)")); - if (!directory.isEmpty()) { - QFile file(directory); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return; + if (directory.isEmpty()) + return; - obs_data_t *obj = obs_data_create(); + QFile file(directory); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return; - switcher->saveWindowTitleSwitches(obj); - switcher->saveScreenRegionSwitches(obj); - switcher->savePauseSwitches(obj); - switcher->saveSceneRoundTripSwitches(obj); - switcher->saveSceneTransitions(obj); - switcher->saveIdleSwitches(obj); - switcher->saveExecutableSwitches(obj); - switcher->saveRandomSwitches(obj); - switcher->saveFileSwitches(obj); - switcher->saveMediaSwitches(obj); - switcher->saveTimeSwitches(obj); - switcher->saveGeneralSettings(obj); + obs_data_t *obj = obs_data_create(); - obs_data_save_json(obj, file.fileName().toUtf8().constData()); + switcher->saveWindowTitleSwitches(obj); + switcher->saveScreenRegionSwitches(obj); + switcher->savePauseSwitches(obj); + switcher->saveSceneRoundTripSwitches(obj); + switcher->saveSceneTransitions(obj); + switcher->saveIdleSwitches(obj); + switcher->saveExecutableSwitches(obj); + switcher->saveRandomSwitches(obj); + switcher->saveFileSwitches(obj); + switcher->saveMediaSwitches(obj); + switcher->saveTimeSwitches(obj); + switcher->saveGeneralSettings(obj); - obs_data_release(obj); - } + obs_data_save_json(obj, file.fileName().toUtf8().constData()); + + obs_data_release(obj); } void SceneSwitcher::on_importSettings_clicked() @@ -205,45 +206,44 @@ void SceneSwitcher::on_importSettings_clicked() this, tr("Import Advanced Scene Switcher settings from file ..."), QDir::currentPath(), tr("Text files (*.txt)")); - if (!directory.isEmpty()) { - QFile file(directory); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; + if (directory.isEmpty()) + return; - QTextStream in(&file); + QFile file(directory); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return; - obs_data_t *obj = obs_data_create_from_json_file( - file.fileName().toUtf8().constData()); - - if (!obj) { - QMessageBox Msgbox; - Msgbox.setText( - "Advanced Scene Switcher failed to import settings"); - Msgbox.exec(); - return; - } - - switcher->loadWindowTitleSwitches(obj); - switcher->loadScreenRegionSwitches(obj); - switcher->loadPauseSwitches(obj); - switcher->loadSceneRoundTripSwitches(obj); - switcher->loadSceneTransitions(obj); - switcher->loadIdleSwitches(obj); - switcher->loadExecutableSwitches(obj); - switcher->loadRandomSwitches(obj); - switcher->loadFileSwitches(obj); - switcher->loadMediaSwitches(obj); - switcher->loadTimeSwitches(obj); - switcher->loadGeneralSettings(obj); - - obs_data_release(obj); + obs_data_t *obj = obs_data_create_from_json_file( + file.fileName().toUtf8().constData()); + if (!obj) { QMessageBox Msgbox; Msgbox.setText( - "Advanced Scene Switcher settings imported successfully"); + "Advanced Scene Switcher failed to import settings"); Msgbox.exec(); - close(); + return; } + + switcher->loadWindowTitleSwitches(obj); + switcher->loadScreenRegionSwitches(obj); + switcher->loadPauseSwitches(obj); + switcher->loadSceneRoundTripSwitches(obj); + switcher->loadSceneTransitions(obj); + switcher->loadIdleSwitches(obj); + switcher->loadExecutableSwitches(obj); + switcher->loadRandomSwitches(obj); + switcher->loadFileSwitches(obj); + switcher->loadMediaSwitches(obj); + switcher->loadTimeSwitches(obj); + switcher->loadGeneralSettings(obj); + + obs_data_release(obj); + + QMessageBox Msgbox; + Msgbox.setText( + "Advanced Scene Switcher settings imported successfully"); + Msgbox.exec(); + close(); } int findTabIndex(QTabBar *bar, int pos) @@ -452,18 +452,28 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj) obs_data_set_default_int(obj, "idleTabPos", 10); obs_data_set_default_int(obj, "sequenceTabPos", 11); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "generalTabPos"))); - switcher->tabOrder.emplace_back((int)( - obs_data_get_int(obj, "transitionTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "pauseTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "titleTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "exeTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "regionTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "mediaTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "fileTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "randomTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "timeTabPos"))); - switcher->tabOrder.emplace_back((int)(obs_data_get_int(obj, "idleTabPos"))); - switcher->tabOrder.emplace_back((int)( - obs_data_get_int(obj, "sequenceTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "generalTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "transitionTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "pauseTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "titleTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "exeTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "regionTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "mediaTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "fileTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "randomTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "timeTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "idleTabPos"))); + switcher->tabOrder.emplace_back( + (int)(obs_data_get_int(obj, "sequenceTabPos"))); } diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 333fa749..166f9c09 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -92,6 +92,7 @@ public slots: void on_sceneRoundTripLoad_clicked(); void on_sceneRoundTripUp_clicked(); void on_sceneRoundTripDown_clicked(); + void on_sceneRoundTripDelayUnits_currentIndexChanged(int index); void on_autoStopSceneCheckBox_stateChanged(int state); void on_autoStopScenes_currentTextChanged(const QString &text); diff --git a/src/headers/switcher-data-structs.hpp b/src/headers/switcher-data-structs.hpp index 8f6e12f8..61e6c996 100644 --- a/src/headers/switcher-data-structs.hpp +++ b/src/headers/switcher-data-structs.hpp @@ -98,7 +98,7 @@ struct SceneRoundTripSwitch { OBSWeakSource scene1; OBSWeakSource scene2; OBSWeakSource transition; - int delay; + double delay; bool usePreviousScene; std::string sceneRoundTripStr; @@ -294,6 +294,7 @@ struct SwitcherData { std::vector ignoreWindowsSwitches; std::vector sceneRoundTripSwitches; + int sceneRoundTripUnitMultiplier = 1; std::vector randomSwitches; diff --git a/src/scene-round-trip.cpp b/src/scene-round-trip.cpp index 41b6c156..1ef12a2e 100644 --- a/src/scene-round-trip.cpp +++ b/src/scene-round-trip.cpp @@ -1,9 +1,50 @@ #include #include +#include #include #include "headers/advanced-scene-switcher.hpp" +#define SECONDS_INDEX 0 +#define MINUTES_INDEX 1 +#define HOURS_INDEX 2 + +void SceneSwitcher::on_sceneRoundTripDelayUnits_currentIndexChanged(int index) +{ + if (loading) + return; + + std::lock_guard lock(switcher->m); + + double val = ui->sceneRoundTripSpinBox->value(); + + switch (switcher->sceneRoundTripUnitMultiplier) { + case 1: + val /= pow(60, index); + break; + case 60: + val /= pow(60, index - 1); + break; + case 3600: + val /= pow(60, index - 2); + break; + } + + ui->sceneRoundTripSpinBox->setValue(val); + + switch (index) { + case SECONDS_INDEX: + switcher->sceneRoundTripUnitMultiplier = 1; + break; + case MINUTES_INDEX: + switcher->sceneRoundTripUnitMultiplier = 60; + break; + case HOURS_INDEX: + switcher->sceneRoundTripUnitMultiplier = 3600; + break; + } +} + void SceneSwitcher::on_sceneRoundTripAdd_clicked() { QString scene1Name = ui->sceneRoundTripScenes1->currentText(); @@ -13,7 +54,8 @@ void SceneSwitcher::on_sceneRoundTripAdd_clicked() if (scene1Name.isEmpty() || scene2Name.isEmpty()) return; - double delay = ui->sceneRoundTripSpinBox->value(); + double delay = ui->sceneRoundTripSpinBox->value() * + switcher->sceneRoundTripUnitMultiplier; if (scene1Name == scene2Name) return; @@ -35,7 +77,7 @@ void SceneSwitcher::on_sceneRoundTripAdd_clicked() std::lock_guard lock(switcher->m); switcher->sceneRoundTripSwitches.emplace_back( - source1, source2, transition, int(delay * 1000), + source1, source2, transition, delay, (scene2Name == QString(PREVIOUS_SCENE_NAME)), text.toUtf8().constData()); } else { @@ -47,7 +89,7 @@ void SceneSwitcher::on_sceneRoundTripAdd_clicked() for (auto &s : switcher->sceneRoundTripSwitches) { if (s.scene1 == source1) { s.scene2 = source2; - s.delay = int(delay * 1000); + s.delay = delay; s.transition = transition; s.usePreviousScene = (scene2Name == @@ -94,30 +136,16 @@ void SceneSwitcher::on_sceneRoundTripSave_clicked() QString directory = QFileDialog::getSaveFileName( this, tr("Save Scene Round Trip to file ..."), QDir::currentPath(), tr("Text files (*.txt)")); - if (!directory.isEmpty()) { - QFile file(directory); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return; - QTextStream out(&file); - for (SceneRoundTripSwitch s : - switcher->sceneRoundTripSwitches) { - out << QString::fromStdString( - GetWeakSourceName(s.scene1)) - << "\n"; - if (s.usePreviousScene) - out << (PREVIOUS_SCENE_NAME) << "\n"; - else - out << QString::fromStdString( - GetWeakSourceName(s.scene2)) - << "\n"; - out << s.delay << "\n"; - out << QString::fromStdString(s.sceneRoundTripStr) - << "\n"; - out << QString::fromStdString( - GetWeakSourceName(s.transition)) - << "\n"; - } - } + if (directory.isEmpty()) + return; + QFile file(directory); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return; + + obs_data_t *obj = obs_data_create(); + switcher->saveSceneRoundTripSwitches(obj); + obs_data_save_json(obj, file.fileName().toUtf8().constData()); + obs_data_release(obj); } void SceneSwitcher::on_sceneRoundTripLoad_clicked() @@ -127,65 +155,31 @@ void SceneSwitcher::on_sceneRoundTripLoad_clicked() QString directory = QFileDialog::getOpenFileName( this, tr("Select a file to read Scene Round Trip from ..."), QDir::currentPath(), tr("Text files (*.txt)")); - if (!directory.isEmpty()) { - QFile file(directory); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; + if (directory.isEmpty()) + return; - QTextStream in(&file); - std::vector lines; + QFile file(directory); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return; - std::vector newSceneRoundTripSwitch; + obs_data_t *obj = obs_data_create_from_json_file( + file.fileName().toUtf8().constData()); - while (!in.atEnd()) { - QString line = in.readLine(); - lines.push_back(line); - if (lines.size() == 5) { - OBSWeakSource scene1 = - GetWeakSourceByQString(lines[0]); - OBSWeakSource scene2 = - GetWeakSourceByQString(lines[1]); - OBSWeakSource transition = - GetWeakTransitionByQString(lines[4]); - - if (WeakSourceValid(scene1) && - ((lines[1] == - QString(PREVIOUS_SCENE_NAME)) || - (WeakSourceValid(scene2))) && - WeakSourceValid(transition)) { - newSceneRoundTripSwitch.emplace_back( - SceneRoundTripSwitch( - GetWeakSourceByQString( - lines[0]), - GetWeakSourceByQString( - lines[1]), - GetWeakTransitionByQString( - lines[4]), - lines[2].toInt(), - (lines[1] == - QString(PREVIOUS_SCENE_NAME)), - lines[3].toStdString())); - } - lines.clear(); - } - } - - if (lines.size() != 0 || newSceneRoundTripSwitch.size() == 0) - return; - - switcher->sceneRoundTripSwitches.clear(); - ui->sceneRoundTrips->clear(); - switcher->sceneRoundTripSwitches = newSceneRoundTripSwitch; - for (SceneRoundTripSwitch s : - switcher->sceneRoundTripSwitches) { - QListWidgetItem *item = new QListWidgetItem( - QString::fromStdString(s.sceneRoundTripStr), - ui->sceneRoundTrips); - item->setData( - Qt::UserRole, - QString::fromStdString(s.sceneRoundTripStr)); - } + if (!obj) { + QMessageBox Msgbox; + Msgbox.setText( + "Advanced Scene Switcher failed to import settings (try import with previous version of the plugin)"); + Msgbox.exec(); + return; } + switcher->loadSceneRoundTripSwitches(obj); + obs_data_release(obj); + + QMessageBox Msgbox; + Msgbox.setText( + "Advanced Scene Switcher settings imported successfully"); + Msgbox.exec(); + close(); } void SwitcherData::checkSceneRoundTrip(bool &match, OBSWeakSource &scene, @@ -199,7 +193,7 @@ void SwitcherData::checkSceneRoundTrip(bool &match, OBSWeakSource &scene, for (SceneRoundTripSwitch &s : sceneRoundTripSwitches) { if (s.scene1 == ws) { sceneRoundTripActive = true; - int dur = s.delay - interval; + int dur = s.delay * 1000 - interval; if (dur > 0) { waitScene = currentSource; @@ -247,15 +241,15 @@ void SceneSwitcher::on_sceneRoundTrips_currentRowChanged(int idx) std::string scene2 = GetWeakSourceName(s.scene2); std::string transitionName = GetWeakSourceName(s.transition); - int delay = s.delay; + double delay = s.delay / + switcher->sceneRoundTripUnitMultiplier; ui->sceneRoundTripScenes1->setCurrentText( scene1.c_str()); ui->sceneRoundTripScenes2->setCurrentText( scene2.c_str()); ui->sceneRoundTripTransitions->setCurrentText( transitionName.c_str()); - ui->sceneRoundTripSpinBox->setValue((double)delay / - 1000); + ui->sceneRoundTripSpinBox->setValue(delay); break; } } @@ -333,14 +327,7 @@ void SwitcherData::saveSceneRoundTripSwitches(obs_data_t *obj) : sceneName2); obs_data_set_string(array_obj, "transition", transitionName); - obs_data_set_int( - array_obj, "sceneRoundTripDelay", - s.delay / - 1000); //delay stored in two separate values - obs_data_set_int( - array_obj, "sceneRoundTripDelayMs", - s.delay % - 1000); //to be compatible with older versions + obs_data_set_double(array_obj, "delay", s.delay); obs_data_set_string(array_obj, "sceneRoundTripStr", s.sceneRoundTripStr.c_str()); obs_data_array_push_back(sceneRoundTripArray, @@ -374,18 +361,25 @@ void SwitcherData::loadSceneRoundTripSwitches(obs_data_t *obj) obs_data_get_string(array_obj, "sceneRoundTripScene2"); const char *transition = obs_data_get_string(array_obj, "transition"); - int delay = obs_data_get_int( - array_obj, - "sceneRoundTripDelay"); //delay stored in two separate values - delay = delay * 1000 + - obs_data_get_int( - array_obj, - "sceneRoundTripDelayMs"); //to be compatible with older versions - std::string str = - MakeSceneRoundTripSwitchName(scene1, scene2, transition, - ((double)delay) / 1000.0) - .toUtf8() - .constData(); + + double delay = 0; + + // To be removed in future version + // to be compatible with older versions + if (!obs_data_has_user_value(array_obj, "delay")) { + delay = obs_data_get_int(array_obj, + "sceneRoundTripDelay"); + delay = delay * 1000 + + obs_data_get_int(array_obj, + "sceneRoundTripDelayMs"); + } else { + delay = obs_data_get_double(array_obj, "delay"); + } + + std::string str = MakeSceneRoundTripSwitchName( + scene1, scene2, transition, delay) + .toUtf8() + .constData(); const char *sceneRoundTripStr = str.c_str(); switcher->sceneRoundTripSwitches.emplace_back(