diff --git a/frontend/OBSStudioAPI.cpp b/frontend/OBSStudioAPI.cpp index 7e8ab72bb9eff3..d6561cfac34c27 100644 --- a/frontend/OBSStudioAPI.cpp +++ b/frontend/OBSStudioAPI.cpp @@ -90,7 +90,7 @@ obs_source_t *OBSStudioAPI::obs_frontend_get_current_transition() void OBSStudioAPI::obs_frontend_set_current_transition(obs_source_t *transition) { - QMetaObject::invokeMethod(main, "SetTransition", Q_ARG(OBSSource, OBSSource(transition))); + QMetaObject::invokeMethod(main, "studioAPISetTransition", Q_ARG(OBSSource, OBSSource(transition))); } int OBSStudioAPI::obs_frontend_get_transition_duration() diff --git a/frontend/cmake/ui-qt.cmake b/frontend/cmake/ui-qt.cmake index 4995cb5fa2e321..1def1983bab06c 100644 --- a/frontend/cmake/ui-qt.cmake +++ b/frontend/cmake/ui-qt.cmake @@ -40,6 +40,7 @@ target_sources( forms/OBSBasicProperties.ui forms/OBSBasicSettings.ui forms/OBSBasicSourceSelect.ui + forms/OBSBasicTransitions.ui forms/OBSBasicVCamConfig.ui forms/OBSExtraBrowsers.ui forms/OBSImporter.ui diff --git a/frontend/cmake/ui-widgets.cmake b/frontend/cmake/ui-widgets.cmake index 4eeec39409f3a3..1f6147af440ce6 100644 --- a/frontend/cmake/ui-widgets.cmake +++ b/frontend/cmake/ui-widgets.cmake @@ -51,6 +51,8 @@ target_sources( widgets/OBSBasicStats.hpp widgets/OBSBasicStatusBar.cpp widgets/OBSBasicStatusBar.hpp + widgets/OBSBasicTransitions.cpp + widgets/OBSBasicTransitions.hpp widgets/OBSMainWindow.hpp widgets/OBSProjector.cpp widgets/OBSProjector.hpp diff --git a/frontend/components/OBSAdvAudioCtrl.cpp b/frontend/components/OBSAdvAudioCtrl.cpp index 33a6385aecbb44..754a36b1dfc577 100644 --- a/frontend/components/OBSAdvAudioCtrl.cpp +++ b/frontend/components/OBSAdvAudioCtrl.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "moc_OBSAdvAudioCtrl.cpp" diff --git a/frontend/forms/OBSBasic.ui b/frontend/forms/OBSBasic.ui index e3c0600e59104e..3a577805602cdd 100644 --- a/frontend/forms/OBSBasic.ui +++ b/frontend/forms/OBSBasic.ui @@ -1401,238 +1401,6 @@ - - - QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable - - - Basic.SceneTransitions - - - 8 - - - - - 0 - - - 1 - - - 0 - - - 1 - - - 1 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 120 - 0 - - - - Transition - - - - - - - 4 - - - - - - 0 - 0 - - - - Basic.TransitionDuration - - - transitionDuration - - - - - - - Basic.TransitionDuration - - - ms - - - 50 - - - 20000 - - - 50 - - - 300 - - - - - - - - - 4 - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - Basic.AddTransition - - - Basic.AddTransition - - - - - - - :/res/images/plus.svg:/res/images/plus.svg - - - false - - - btn-tool icon-plus - - - - - - - - 0 - 0 - - - - Basic.RemoveTransition - - - Basic.RemoveTransition - - - - - - - :/res/images/minus.svg:/res/images/minus.svg - - - false - - - btn-tool icon-trash - - - - - - - - 0 - 0 - - - - Basic.TransitionProperties - - - Basic.TransitionProperties - - - - - - - :/settings/images/settings/general.svg:/settings/images/settings/general.svg - - - false - - - btn-tool icon-dots-vert - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - diff --git a/frontend/forms/OBSBasicTransitions.ui b/frontend/forms/OBSBasicTransitions.ui new file mode 100644 index 00000000000000..a3a2367ce52c53 --- /dev/null +++ b/frontend/forms/OBSBasicTransitions.ui @@ -0,0 +1,237 @@ + + + OBSBasicTransitions + + + + 0 + 0 + 283 + 127 + + + + + 0 + + + 1 + + + 0 + + + 1 + + + 1 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 120 + 0 + + + + Transition + + + + + + + 4 + + + + + + 0 + 0 + + + + Basic.TransitionDuration + + + transitionDuration + + + + + + + Basic.TransitionDuration + + + ms + + + 50 + + + 20000 + + + 50 + + + 300 + + + + + + + + + 4 + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Basic.AddTransition + + + Basic.AddTransition + + + + + + + :/res/images/plus.svg:/res/images/plus.svg + + + false + + + btn-tool icon-plus + + + + + + + + 0 + 0 + + + + Basic.RemoveTransition + + + Basic.RemoveTransition + + + + + + + :/res/images/minus.svg:/res/images/minus.svg + + + false + + + btn-tool icon-trash + + + + + + + + 0 + 0 + + + + Basic.TransitionProperties + + + Basic.TransitionProperties + + + + + + + :/settings/images/settings/general.svg:/settings/images/settings/general.svg + + + false + + + btn-tool icon-dots-vert + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + diff --git a/frontend/widgets/OBSBasic.cpp b/frontend/widgets/OBSBasic.cpp index 4e25e91e6c7712..d4cb2dc93edd06 100644 --- a/frontend/widgets/OBSBasic.cpp +++ b/frontend/widgets/OBSBasic.cpp @@ -22,6 +22,7 @@ #include "ColorSelect.hpp" #include "OBSBasicControls.hpp" #include "OBSBasicStats.hpp" +#include "OBSBasicTransitions.hpp" #include "plugin-manager/PluginManager.hpp" #include "VolControl.hpp" @@ -278,6 +279,37 @@ OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow(parent), undo_s(ui), ui(new }, Qt::DirectConnection); + /* Set up transition connections */ + connect( + this, &OBSBasic::CurrentTransitionChanged, this, + [this]() { OnEvent(OBS_FRONTEND_EVENT_TRANSITION_CHANGED); }, Qt::DirectConnection); + + connect( + this, &OBSBasic::TransitionDurationChanged, this, + [this]() { OnEvent(OBS_FRONTEND_EVENT_TRANSITION_DURATION_CHANGED); }, Qt::DirectConnection); + + /* Add transitions dock */ + OBSBasicTransitions *transitionsWidget = new OBSBasicTransitions(this); + transitionsDock = new OBSDock(this); + transitionsDock->setObjectName(QString::fromUtf8("transitionsDock")); + transitionsDock->setWindowTitle(QTStr("Basic.SceneTransitions")); + /* Parenting is done there so transitions will be deleted alongside transitionsDock */ + transitionsDock->setWidget(transitionsWidget); + addDockWidget(Qt::BottomDockWidgetArea, transitionsDock); + + connect(transitionsWidget, &OBSBasicTransitions::transitionChanged, this, + &OBSBasic::setCurrentTransitionQString); + + connect(transitionsWidget, &OBSBasicTransitions::transitionDurationChanged, this, + &OBSBasic::SetTransitionDuration); + + connect(transitionsWidget, &OBSBasicTransitions::addTransitionClicked, this, + &OBSBasic::createAddTransitionMenu); + connect(transitionsWidget, &OBSBasicTransitions::removeCurrentTransitionClicked, this, + &OBSBasic::removeCurrentTransition); + connect(transitionsWidget, &OBSBasicTransitions::currentTransitionPropertiesMenuClicked, this, + &OBSBasic::createCurrentTransitionPropertiesMenu); + /* Add controls dock */ OBSBasicControls *controls = new OBSBasicControls(this); controlsDock = new OBSDock(this); @@ -308,40 +340,6 @@ OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow(parent), undo_s(ui), ui(new connect(controls, &OBSBasicControls::SettingsButtonClicked, this, &OBSBasic::on_action_Settings_triggered); - /* Set up transitions combobox connections */ - connect(this, &OBSBasic::TransitionAdded, this, [this](const QString &name, const QString &uuid) { - QSignalBlocker sb(ui->transitions); - ui->transitions->addItem(name, uuid); - }); - connect(this, &OBSBasic::TransitionRenamed, this, [this](const QString &uuid, const QString &newName) { - QSignalBlocker sb(ui->transitions); - ui->transitions->setItemText(ui->transitions->findData(uuid), newName); - }); - connect(this, &OBSBasic::TransitionRemoved, this, [this](const QString &uuid) { - QSignalBlocker sb(ui->transitions); - ui->transitions->removeItem(ui->transitions->findData(uuid)); - }); - connect(this, &OBSBasic::TransitionsCleared, this, [this]() { - QSignalBlocker sb(ui->transitions); - ui->transitions->clear(); - }); - - connect(this, &OBSBasic::CurrentTransitionChanged, this, [this](const QString &uuid) { - QSignalBlocker sb(ui->transitions); - ui->transitions->setCurrentIndex(ui->transitions->findData(uuid)); - }); - - connect(ui->transitions, &QComboBox::currentIndexChanged, this, - [this]() { SetCurrentTransition(ui->transitions->currentData().toString()); }); - - connect(this, &OBSBasic::TransitionDurationChanged, this, [this](int duration) { - QSignalBlocker sb(ui->transitionDuration); - ui->transitionDuration->setValue(duration); - }); - - connect(ui->transitionDuration, &QSpinBox::valueChanged, this, - [this](int value) { SetTransitionDuration(value); }); - startingDockLayout = saveState(); statsDock = new OBSDock(); @@ -508,7 +506,7 @@ OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow(parent), undo_s(ui), ui(new SETUP_DOCK(ui->scenesDock); SETUP_DOCK(ui->sourcesDock); SETUP_DOCK(ui->mixerDock); - SETUP_DOCK(ui->transitionsDock); + SETUP_DOCK(transitionsDock); SETUP_DOCK(controlsDock); SETUP_DOCK(statsDock); #undef SETUP_DOCK diff --git a/frontend/widgets/OBSBasic.hpp b/frontend/widgets/OBSBasic.hpp index 283e24c0005e96..f3fe6fb5547198 100644 --- a/frontend/widgets/OBSBasic.hpp +++ b/frontend/widgets/OBSBasic.hpp @@ -449,6 +449,7 @@ public slots: QStringList extraCustomDockNames; QList> extraCustomDocks; + QPointer transitionsDock; QPointer controlsDock; public: @@ -1500,8 +1501,8 @@ private slots: std::unordered_map transitionNameToUuids; int transitionDuration; std::string currentTransitionUuid; - obs_source_t *fadeTransition; - obs_source_t *cutTransition; + std::string fadeTransitionUuid; + std::string cutTransitionUuid; std::vector quickTransitions; bool swapScenesMode = true; @@ -1515,6 +1516,8 @@ private slots: OBSSource prevFTBSource = nullptr; + bool transitionsControlLocked = false; + void InitDefaultTransitions(); void InitTransition(obs_source_t *transition); obs_source_t *FindTransition(const char *name); @@ -1553,25 +1556,26 @@ private slots: void PasteShowHideTransition(obs_sceneitem_t *item, bool show, obs_source_t *tr, int duration); - void UpdateCurrentTransition(const std::string &uuid, bool setTransition); + void setTransitionInternal(OBSSource transition); + void setCurrentTransition(const std::string &uuid); public slots: void SetCurrentScene(OBSSource scene, bool force = false); - void SetTransition(OBSSource transition); + void studioAPISetTransition(OBSSource transition); void OverrideTransition(OBSSource transition); void TransitionToScene(OBSScene scene, bool force = false); void TransitionToScene(OBSSource scene, bool force = false, bool quickTransition = false, int quickDuration = 0, bool black = false, bool manual = false); - void SetCurrentTransition(const QString &uuid); - void SetTransitionDuration(int duration); private slots: void AddTransition(const char *id); void RenameTransition(OBSSource transition); + void setCurrentTransitionQString(const QString &uuid); + void TransitionClicked(); void TransitionStopped(); void TransitionFullyStopped(); @@ -1580,20 +1584,22 @@ private slots: void TBarChanged(int value); void TBarReleased(); - void on_transitionAdd_clicked(); - void on_transitionRemove_clicked(); - void on_transitionProps_clicked(); + void createAddTransitionMenu(); + void removeCurrentTransition(); + void createCurrentTransitionPropertiesMenu(); void ShowTransitionProperties(); void HideTransitionProperties(); signals: + void transitionsControlChanged(bool locked); + void TransitionAdded(const QString &name, const QString &uuid); void TransitionRenamed(const QString &uuid, const QString &newName); void TransitionRemoved(const QString &uuid); void TransitionsCleared(); - void CurrentTransitionChanged(const QString &uuid); + void CurrentTransitionChanged(const QString &uuid, bool fixed, bool configurable); void TransitionDurationChanged(const int &duration); diff --git a/frontend/widgets/OBSBasicTransitions.cpp b/frontend/widgets/OBSBasicTransitions.cpp new file mode 100644 index 00000000000000..d18d8db908ef21 --- /dev/null +++ b/frontend/widgets/OBSBasicTransitions.cpp @@ -0,0 +1,94 @@ +#include "OBSBasicTransitions.hpp" +#include "OBSBasic.hpp" + +#include "moc_OBSBasicTransitions.cpp" + +OBSBasicTransitions::OBSBasicTransitions(OBSBasic *main) : QFrame(nullptr), ui(new Ui::OBSBasicTransitions) +{ + /* Create UI elements */ + ui->setupUi(this); + + /* Transfer widget signals as OBSBasicTransitions signals */ + connect( + ui->transitions, &QComboBox::currentIndexChanged, this, + [this]() { emit this->transitionChanged(ui->transitions->currentData().toString()); }, + Qt::DirectConnection); + + connect( + ui->transitionDuration, &QSpinBox::valueChanged, this, + [this](int duration) { emit this->transitionDurationChanged(duration); }, Qt::DirectConnection); + + connect( + ui->transitionAdd, &QPushButton::clicked, this, [this]() { emit this->addTransitionClicked(); }, + Qt::DirectConnection); + + connect( + ui->transitionRemove, &QPushButton::clicked, this, + [this]() { emit this->removeCurrentTransitionClicked(); }, Qt::DirectConnection); + + connect( + ui->transitionProps, &QPushButton::clicked, this, + [this]() { emit this->currentTransitionPropertiesMenuClicked(); }, Qt::DirectConnection); + + /* Set up state update connections */ + connect(main, &OBSBasic::TransitionAdded, this, &OBSBasicTransitions::transitionAdded); + connect(main, &OBSBasic::TransitionRenamed, this, &OBSBasicTransitions::transitionRenamed); + connect(main, &OBSBasic::TransitionRemoved, this, &OBSBasicTransitions::transitionRemoved); + connect(main, &OBSBasic::TransitionsCleared, this, &OBSBasicTransitions::transitionsCleared); + + connect(main, &OBSBasic::CurrentTransitionChanged, this, &OBSBasicTransitions::currentTransitionChanged); + + connect(main, &OBSBasic::TransitionDurationChanged, this, &OBSBasicTransitions::durationChanged); + + connect(main, &OBSBasic::transitionsControlChanged, this, &OBSBasicTransitions::transitionsControlChanged); +} + +void OBSBasicTransitions::transitionAdded(const QString &name, const QString &uuid) +{ + QSignalBlocker sb(ui->transitions); + ui->transitions->addItem(name, uuid); +} + +void OBSBasicTransitions::transitionRenamed(const QString &uuid, const QString &newName) +{ + QSignalBlocker sb(ui->transitions); + ui->transitions->setItemText(ui->transitions->findData(uuid), newName); +} + +void OBSBasicTransitions::transitionRemoved(const QString &uuid) +{ + QSignalBlocker sb(ui->transitions); + ui->transitions->removeItem(ui->transitions->findData(uuid)); +} + +void OBSBasicTransitions::transitionsCleared() +{ + QSignalBlocker sb(ui->transitions); + ui->transitions->clear(); +} + +void OBSBasicTransitions::currentTransitionChanged(const QString &uuid, bool fixed, bool configurable) +{ + QSignalBlocker sb(ui->transitions); + ui->transitions->setCurrentIndex(ui->transitions->findData(uuid)); + + ui->transitionDurationLabel->setVisible(!fixed); + ui->transitionDuration->setVisible(!fixed); + + ui->transitionRemove->setEnabled(configurable); + ui->transitionProps->setEnabled(configurable); + + transitionConfigurable = configurable; +} + +void OBSBasicTransitions::durationChanged(const int &duration) +{ + QSignalBlocker sb(ui->transitionDuration); + ui->transitionDuration->setValue(duration); +} + +void OBSBasicTransitions::transitionsControlChanged(bool locked) +{ + ui->transitions->setDisabled(locked); + ui->transitionProps->setDisabled(locked ? true : transitionConfigurable); +} diff --git a/frontend/widgets/OBSBasicTransitions.hpp b/frontend/widgets/OBSBasicTransitions.hpp new file mode 100644 index 00000000000000..34ac86fb33095f --- /dev/null +++ b/frontend/widgets/OBSBasicTransitions.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "ui_OBSBasicTransitions.h" + +#include + +#include + +class OBSBasic; + +class OBSBasicTransitions : public QFrame { + Q_OBJECT + + std::unique_ptr ui; + + bool transitionConfigurable; + +private slots: + void transitionAdded(const QString &name, const QString &uuid); + void transitionRenamed(const QString &uuid, const QString &newName); + void transitionRemoved(const QString &uuid); + void transitionsCleared(); + + void currentTransitionChanged(const QString &uuid, bool fixed, bool configurable); + + void durationChanged(const int &duration); + + void transitionsControlChanged(bool locked); + +public: + OBSBasicTransitions(OBSBasic *main); + inline ~OBSBasicTransitions() {} + +signals: + void transitionChanged(const QString &uuid); + void transitionDurationChanged(int duration); + + void addTransitionClicked(); + void removeCurrentTransitionClicked(); + void currentTransitionPropertiesMenuClicked(); +}; diff --git a/frontend/widgets/OBSBasic_Docks.cpp b/frontend/widgets/OBSBasic_Docks.cpp index 670ed5a25f730d..1a79a53bb073ac 100644 --- a/frontend/widgets/OBSBasic_Docks.cpp +++ b/frontend/widgets/OBSBasic_Docks.cpp @@ -86,14 +86,14 @@ void OBSBasic::on_resetDocks_triggered(bool force) int mixerSize = cx - (cx22_5 * 2 + cx5 + cx21); - QList docks{ui->scenesDock, ui->sourcesDock, ui->mixerDock, ui->transitionsDock, controlsDock}; + QList docks{ui->scenesDock, ui->sourcesDock, ui->mixerDock, transitionsDock, controlsDock}; QList sizes{cx22_5, cx22_5, mixerSize, cx5, cx21}; ui->scenesDock->setVisible(true); ui->sourcesDock->setVisible(true); ui->mixerDock->setVisible(true); - ui->transitionsDock->setVisible(true); + transitionsDock->setVisible(true); controlsDock->setVisible(true); statsDock->setVisible(false); statsDock->setFloating(true); @@ -117,7 +117,7 @@ void OBSBasic::on_lockDocks_toggled(bool lock) ui->scenesDock->setFeatures(mainFeatures); ui->sourcesDock->setFeatures(mainFeatures); ui->mixerDock->setFeatures(mainFeatures); - ui->transitionsDock->setFeatures(mainFeatures); + transitionsDock->setFeatures(mainFeatures); controlsDock->setFeatures(mainFeatures); statsDock->setFeatures(features); diff --git a/frontend/widgets/OBSBasic_SceneCollections.cpp b/frontend/widgets/OBSBasic_SceneCollections.cpp index a18e69939de338..ad40935dde6a9b 100644 --- a/frontend/widgets/OBSBasic_SceneCollections.cpp +++ b/frontend/widgets/OBSBasic_SceneCollections.cpp @@ -1004,7 +1004,7 @@ void OBSBasic::CreateDefaultScene(bool firstStart) InitDefaultTransitions(); CreateDefaultQuickTransitions(); SetTransitionDuration(300); - SetTransition(fadeTransition); + setCurrentTransition(fadeTransitionUuid); updateRemigrationMenuItem(SceneCoordinateMode::Relative, ui->actionRemigrateSceneCollection); @@ -1188,7 +1188,7 @@ void OBSBasic::LoadData(obs_data_t *data, SceneCollection &collection) newDuration = 300; if (!transitionName) - transitionName = obs_source_get_name(fadeTransition); + transitionName = obs_source_get_name(transitions.at(fadeTransitionUuid)); const char *curSceneCollection = config_get_string(App()->GetUserConfig(), "Basic", "SceneCollection"); @@ -1300,11 +1300,9 @@ void OBSBasic::LoadData(obs_data_t *data, SceneCollection &collection) LoadSceneListOrder(sceneOrder); curTransition = FindTransition(transitionName); - if (!curTransition) - curTransition = fadeTransition; SetTransitionDuration(newDuration); - SetTransition(curTransition); + setCurrentTransition(curTransition ? obs_source_get_uuid(curTransition) : fadeTransitionUuid); retryScene: curScene = obs_get_source_by_name(sceneName); diff --git a/frontend/widgets/OBSBasic_StudioMode.cpp b/frontend/widgets/OBSBasic_StudioMode.cpp index d492f8f298785c..85b136ff0ffed4 100644 --- a/frontend/widgets/OBSBasic_StudioMode.cpp +++ b/frontend/widgets/OBSBasic_StudioMode.cpp @@ -270,9 +270,10 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) if (!previewEnabled) EnablePreviewDisplay(false); - ui->transitions->setEnabled(true); tBarActive = false; + emit transitionsControlChanged(transitionsControlLocked); + OnEvent(OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED); blog(LOG_INFO, "Switched to regular Preview mode"); diff --git a/frontend/widgets/OBSBasic_Transitions.cpp b/frontend/widgets/OBSBasic_Transitions.cpp index b76f433762fc73..0449d744365ab4 100644 --- a/frontend/widgets/OBSBasic_Transitions.cpp +++ b/frontend/widgets/OBSBasic_Transitions.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -64,9 +65,9 @@ void OBSBasic::InitDefaultTransitions() defaultTransitions.emplace_back(tr); if (strcmp(id, "fade_transition") == 0) - fadeTransition = tr; + fadeTransitionUuid = obs_source_get_uuid(tr); else if (strcmp(id, "cut_transition") == 0) - cutTransition = tr; + cutTransitionUuid = obs_source_get_uuid(tr); } } @@ -80,7 +81,7 @@ void OBSBasic::InitDefaultTransitions() emit TransitionAdded(QT_UTF8(obs_source_get_name(tr)), QString::fromStdString(uuid)); } - UpdateCurrentTransition(transitionUuids.back(), true); + setCurrentTransition(transitionUuids.back()); } void OBSBasic::AddQuickTransitionHotkey(QuickTransition *qt) @@ -151,9 +152,9 @@ void OBSBasic::CreateDefaultQuickTransitions() { /* non-configurable transitions are always available, so add them * to the "default quick transitions" list */ - quickTransitions.emplace_back(cutTransition, 300, quickTransitionIdCounter++); - quickTransitions.emplace_back(fadeTransition, 300, quickTransitionIdCounter++); - quickTransitions.emplace_back(fadeTransition, 300, quickTransitionIdCounter++, true); + quickTransitions.emplace_back(transitions.at(cutTransitionUuid), 300, quickTransitionIdCounter++); + quickTransitions.emplace_back(transitions.at(fadeTransitionUuid), 300, quickTransitionIdCounter++); + quickTransitions.emplace_back(transitions.at(fadeTransitionUuid), 300, quickTransitionIdCounter++, true); } void OBSBasic::LoadQuickTransitions(obs_data_array_t *array) @@ -383,30 +384,30 @@ static inline void SetComboTransition(QComboBox *combo, obs_source_t *tr) } } -void OBSBasic::SetTransition(OBSSource transition) +void OBSBasic::studioAPISetTransition(OBSSource transition) { - OBSSourceAutoRelease oldTransition = obs_get_output_source(0); - - if (oldTransition && transition) { + if (transition) { std::string uuid = obs_source_get_uuid(transition); - obs_transition_swap_begin(transition, oldTransition); - if (currentTransitionUuid != uuid) - UpdateCurrentTransition(uuid, false); - obs_set_output_source(0, transition); - obs_transition_swap_end(transition, oldTransition); - } else { - obs_set_output_source(0, transition); - } - bool fixed = transition ? obs_transition_fixed(transition) : false; - ui->transitionDurationLabel->setVisible(!fixed); - ui->transitionDuration->setVisible(!fixed); + if (transition && transitions.find(uuid) != transitions.end()) { + setCurrentTransition(uuid); + return; + } - bool configurable = transition ? obs_source_configurable(transition) : false; - ui->transitionRemove->setEnabled(configurable); - ui->transitionProps->setEnabled(configurable); + if (OBSSourceAutoRelease oldTransition = obs_get_output_source(0)) { + std::string uuid = obs_source_get_uuid(transition); + obs_transition_swap_begin(transition, oldTransition); + obs_set_output_source(0, transition); + obs_transition_swap_end(transition, oldTransition); - OnEvent(OBS_FRONTEND_EVENT_TRANSITION_CHANGED); + emit CurrentTransitionChanged(QString::fromStdString(uuid), obs_transition_fixed(transition), + obs_source_configurable(transition)); + } + } else { + obs_set_output_source(0, transition); + + emit CurrentTransitionChanged({}, false, false); + } } OBSSource OBSBasic::GetCurrentTransition() @@ -461,7 +462,7 @@ void OBSBasic::AddTransition(const char *id) emit TransitionAdded(QString::fromStdString(name), QString::fromStdString(uuid)); - UpdateCurrentTransition(uuid, true); + setCurrentTransition(uuid); CreatePropertiesWindow(source); obs_source_release(source); @@ -473,13 +474,16 @@ void OBSBasic::AddTransition(const char *id) } } -void OBSBasic::on_transitionAdd_clicked() +void OBSBasic::createAddTransitionMenu() { bool foundConfigurableTransitions = false; QMenu menu(this); size_t idx = 0; const char *id; + if (transitionsControlLocked) + return; + while (obs_enum_transition_types(idx++, &id)) { if (obs_is_source_configurable(id)) { const char *name = obs_source_get_display_name(id); @@ -496,12 +500,15 @@ void OBSBasic::on_transitionAdd_clicked() menu.exec(QCursor::pos()); } -void OBSBasic::on_transitionRemove_clicked() +void OBSBasic::removeCurrentTransition() { auto transitionIterator = transitions.find(currentTransitionUuid); OBSSource tr; const char *name; + if (transitionsControlLocked) + return; + if (transitionIterator == transitions.end()) return; @@ -528,7 +535,7 @@ void OBSBasic::on_transitionRemove_clicked() transitions.erase(currentTransitionUuid); emit TransitionRemoved(QString::fromStdString(currentTransitionUuid)); - UpdateCurrentTransition(transitionUuids.back(), true); + setCurrentTransition(transitionUuids.back()); OnEvent(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED); @@ -579,10 +586,13 @@ void OBSBasic::RenameTransition(OBSSource transition) RefreshQuickTransitions(); } -void OBSBasic::on_transitionProps_clicked() +void OBSBasic::createCurrentTransitionPropertiesMenu() { OBSSource source = GetCurrentTransition(); + if (transitionsControlLocked) + return; + if (!obs_source_configurable(source)) return; @@ -1164,7 +1174,7 @@ void OBSBasic::AddQuickTransition() if (!fadeToBlack && (transitionIter == transitions.end())) return; - transition = fadeToBlack ? OBSSource(fadeTransition) : transitionIter->second; + transition = fadeToBlack ? transitions.at(fadeTransitionUuid) : transitionIter->second; if (!transition) return; @@ -1226,7 +1236,7 @@ void OBSBasic::QuickTransitionChange() if (!fadeToBlack && (transitionIter == transitions.end())) return; - tr = fadeToBlack ? OBSSource(fadeTransition) : transitionIter->second; + tr = fadeToBlack ? transitions.at(fadeTransitionUuid) : transitionIter->second; if (tr) { qt->source = tr; @@ -1298,34 +1308,28 @@ void OBSBasic::RefreshQuickTransitions() void OBSBasic::EnableTransitionWidgets(bool enable) { - ui->transitions->setEnabled(enable); - - if (!enable) { - ui->transitionProps->setEnabled(false); - } else { - bool configurable = obs_source_configurable(GetCurrentTransition()); - ui->transitionProps->setEnabled(configurable); - } + if (IsPreviewProgramMode()) { - if (!IsPreviewProgramMode()) - return; + QVBoxLayout *programLayout = reinterpret_cast(programOptions->layout()); - QVBoxLayout *programLayout = reinterpret_cast(programOptions->layout()); + for (int idx = 0;; idx++) { + QLayoutItem *item = programLayout->itemAt(idx); + if (!item) + break; - for (int idx = 0;; idx++) { - QLayoutItem *item = programLayout->itemAt(idx); - if (!item) - break; + QPushButton *button = qobject_cast(item->widget()); + if (!button) + continue; - QPushButton *button = qobject_cast(item->widget()); - if (!button) - continue; + button->setEnabled(enable); + } - button->setEnabled(enable); + if (transitionButton) + transitionButton->setEnabled(enable); } - if (transitionButton) - transitionButton->setEnabled(enable); + transitionsControlLocked = !enable; + emit transitionsControlChanged(!enable); } obs_data_array_t *OBSBasic::SaveTransitions() @@ -1382,7 +1386,7 @@ void OBSBasic::LoadTransitions(obs_data_array_t *transitionsData, obs_load_sourc } } - UpdateCurrentTransition(transitionUuids.back(), true); + setCurrentTransition(transitionUuids.back()); } OBSSource OBSBasic::GetOverrideTransition(OBSSource source) @@ -1418,7 +1422,21 @@ int OBSBasic::GetTransitionDuration() return transitionDuration; } -void OBSBasic::UpdateCurrentTransition(const std::string &uuid, bool setTransition) +void OBSBasic::setTransitionInternal(OBSSource transition) +{ + OBSSourceAutoRelease oldTransition = obs_get_output_source(0); + + if (oldTransition) { + std::string uuid = obs_source_get_uuid(transition); + obs_transition_swap_begin(transition, oldTransition); + obs_set_output_source(0, transition); + obs_transition_swap_end(transition, oldTransition); + } else { + obs_set_output_source(0, transition); + } +} + +void OBSBasic::setCurrentTransition(const std::string &uuid) { auto transitionIter = transitions.find(uuid); @@ -1426,14 +1444,13 @@ void OBSBasic::UpdateCurrentTransition(const std::string &uuid, bool setTransiti return; currentTransitionUuid = uuid; + setTransitionInternal(transitionIter->second); - if (setTransition) - SetTransition(transitionIter->second); - - emit CurrentTransitionChanged(QString::fromStdString(uuid)); + emit CurrentTransitionChanged(QString::fromStdString(uuid), obs_transition_fixed(transitionIter->second), + obs_source_configurable(transitionIter->second)); } -void OBSBasic::SetCurrentTransition(const QString &uuid) +void OBSBasic::setCurrentTransitionQString(const QString &uuid) { auto transitionIter = transitions.find(uuid.toStdString()); @@ -1441,9 +1458,10 @@ void OBSBasic::SetCurrentTransition(const QString &uuid) return; currentTransitionUuid = uuid.toStdString(); - SetTransition(transitionIter->second); + setTransitionInternal(transitionIter->second); - emit CurrentTransitionChanged(uuid); + emit CurrentTransitionChanged(uuid, obs_transition_fixed(transitionIter->second), + obs_source_configurable(transitionIter->second)); } void OBSBasic::SetTransitionDuration(int duration) @@ -1457,6 +1475,4 @@ void OBSBasic::SetTransitionDuration(int duration) transitionDuration = duration; emit TransitionDurationChanged(transitionDuration); - - OnEvent(OBS_FRONTEND_EVENT_TRANSITION_DURATION_CHANGED); }