|
|
@@ -306,7 +306,7 @@ void OBSBasic::TransitionFullyStopped()
|
|
|
|
|
|
void OBSBasic::TransitionToScene(OBSSource source, bool force,
|
|
|
bool quickTransition, int quickDuration,
|
|
|
- bool black)
|
|
|
+ bool black, bool manual)
|
|
|
{
|
|
|
obs_scene_t *scene = obs_scene_from_source(source);
|
|
|
bool usingPreviewProgram = IsPreviewProgramMode();
|
|
|
@@ -316,7 +316,8 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force,
|
|
|
OBSWeakSource lastProgramScene;
|
|
|
|
|
|
if (usingPreviewProgram) {
|
|
|
- lastProgramScene = programScene;
|
|
|
+ if (!tBarActive)
|
|
|
+ lastProgramScene = programScene;
|
|
|
programScene = OBSGetWeakRef(source);
|
|
|
|
|
|
if (swapScenesMode && !force && !black) {
|
|
|
@@ -341,12 +342,16 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force,
|
|
|
OBSSource transition = obs_get_output_source(0);
|
|
|
obs_source_release(transition);
|
|
|
|
|
|
- bool stillTransitioning = obs_transition_get_time(transition) < 1.0f;
|
|
|
+ float t = obs_transition_get_time(transition);
|
|
|
+ bool stillTransitioning = (!tBarActive && t < 1.0f) ||
|
|
|
+ (tBarActive && t > 0.0f) || tBarDown;
|
|
|
|
|
|
// If actively transitioning, block new transitions from starting
|
|
|
if (usingPreviewProgram && stillTransitioning)
|
|
|
goto cleanup;
|
|
|
|
|
|
+ tBarActive = false;
|
|
|
+
|
|
|
if (force) {
|
|
|
obs_transition_set(transition, source);
|
|
|
if (api)
|
|
|
@@ -390,8 +395,13 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force,
|
|
|
if (quickTransition)
|
|
|
duration = quickDuration;
|
|
|
|
|
|
- bool success = obs_transition_start(
|
|
|
- transition, OBS_TRANSITION_MODE_AUTO, duration, source);
|
|
|
+ enum obs_transition_mode mode =
|
|
|
+ manual ? OBS_TRANSITION_MODE_MANUAL
|
|
|
+ : OBS_TRANSITION_MODE_AUTO;
|
|
|
+
|
|
|
+ bool success = obs_transition_start(transition, mode, duration,
|
|
|
+ source);
|
|
|
+
|
|
|
if (!success)
|
|
|
TransitionFullyStopped();
|
|
|
}
|
|
|
@@ -444,6 +454,8 @@ void OBSBasic::SetTransition(OBSSource transition)
|
|
|
ui->transitionRemove->setEnabled(configurable);
|
|
|
ui->transitionProps->setEnabled(configurable);
|
|
|
|
|
|
+ EnableTBar();
|
|
|
+
|
|
|
if (api)
|
|
|
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_CHANGED);
|
|
|
}
|
|
|
@@ -765,6 +777,10 @@ void OBSBasic::TransitionClicked()
|
|
|
TransitionToScene(GetCurrentScene());
|
|
|
}
|
|
|
|
|
|
+#define T_BAR_PRECISION 1024
|
|
|
+#define T_BAR_PRECISION_F ((float)T_BAR_PRECISION)
|
|
|
+#define T_BAR_CLAMP (T_BAR_PRECISION / 10)
|
|
|
+
|
|
|
void OBSBasic::CreateProgramOptions()
|
|
|
{
|
|
|
programOptions = new QWidget();
|
|
|
@@ -796,9 +812,19 @@ void OBSBasic::CreateProgramOptions()
|
|
|
mainButtonLayout->addWidget(transitionButton);
|
|
|
mainButtonLayout->addWidget(configTransitions);
|
|
|
|
|
|
+ tBar = new QSlider(Qt::Horizontal);
|
|
|
+ tBar->setMinimum(0);
|
|
|
+ tBar->setMaximum(T_BAR_PRECISION - 1);
|
|
|
+
|
|
|
+ tBar->setProperty("themeID", "tBarSlider");
|
|
|
+
|
|
|
+ connect(tBar, SIGNAL(sliderMoved(int)), this, SLOT(TBarChanged(int)));
|
|
|
+ connect(tBar, SIGNAL(sliderReleased()), this, SLOT(TBarReleased()));
|
|
|
+
|
|
|
layout->addStretch(0);
|
|
|
layout->addLayout(mainButtonLayout);
|
|
|
layout->addLayout(quickTransitions);
|
|
|
+ layout->addWidget(tBar);
|
|
|
layout->addStretch(0);
|
|
|
|
|
|
programOptions->setLayout(layout);
|
|
|
@@ -871,6 +897,58 @@ void OBSBasic::CreateProgramOptions()
|
|
|
connect(configTransitions, &QAbstractButton::clicked, onConfig);
|
|
|
}
|
|
|
|
|
|
+void OBSBasic::TBarReleased()
|
|
|
+{
|
|
|
+ int val = tBar->value();
|
|
|
+
|
|
|
+ if ((tBar->maximum() - val) <= T_BAR_CLAMP) {
|
|
|
+ obs_transition_set_manual_time(GetCurrentTransition(), 1.0f);
|
|
|
+ tBar->blockSignals(true);
|
|
|
+ tBar->setValue(0);
|
|
|
+ tBar->blockSignals(false);
|
|
|
+ tBarActive = false;
|
|
|
+
|
|
|
+ } else if (val <= T_BAR_CLAMP) {
|
|
|
+ obs_transition_set_manual_time(GetCurrentTransition(), 0.0f);
|
|
|
+ tBar->blockSignals(true);
|
|
|
+ tBar->setValue(0);
|
|
|
+ tBar->blockSignals(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ tBarDown = false;
|
|
|
+}
|
|
|
+
|
|
|
+void OBSBasic::TBarChanged(int value)
|
|
|
+{
|
|
|
+ if (!tBarDown) {
|
|
|
+ obs_transition_set_manual_torque(GetCurrentTransition(), 8.0f,
|
|
|
+ 0.05f);
|
|
|
+ TransitionToScene(GetCurrentSceneSource(), false, false, false,
|
|
|
+ 0, true);
|
|
|
+ tBarActive = true;
|
|
|
+ tBarDown = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ obs_transition_set_manual_time(GetCurrentTransition(),
|
|
|
+ (float)value / T_BAR_PRECISION_F);
|
|
|
+}
|
|
|
+
|
|
|
+void OBSBasic::EnableTBar()
|
|
|
+{
|
|
|
+ if (!previewProgramMode)
|
|
|
+ return;
|
|
|
+
|
|
|
+ const char *id = obs_source_get_id(GetCurrentTransition());
|
|
|
+
|
|
|
+ if (!id || strcmp(id, "cut_transition") == 0 ||
|
|
|
+ strcmp(id, "obs_stinger_transition") == 0) {
|
|
|
+ tBar->setValue(0);
|
|
|
+ tBar->setEnabled(false);
|
|
|
+ } else {
|
|
|
+ tBar->setEnabled(true);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void OBSBasic::on_modeSwitch_clicked()
|
|
|
{
|
|
|
SetPreviewProgramMode(!IsPreviewProgramMode());
|
|
|
@@ -1137,6 +1215,8 @@ void OBSBasic::QuickTransitionChange()
|
|
|
qt->source = GetTransitionComboItem(ui->transitions, trIdx);
|
|
|
ResetQuickTransitionText(qt);
|
|
|
}
|
|
|
+
|
|
|
+ EnableTBar();
|
|
|
}
|
|
|
|
|
|
void OBSBasic::QuickTransitionChangeDuration(int value)
|
|
|
@@ -1258,6 +1338,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
|
|
|
|
|
|
CreateProgramDisplay();
|
|
|
CreateProgramOptions();
|
|
|
+ EnableTBar();
|
|
|
|
|
|
OBSScene curScene = GetCurrentScene();
|
|
|
|