UI: Add t-bar to studio mode
Co-authored-by: Jim <obs.jim@gmail.com>
This commit is contained in:
parent
2d35f863da
commit
68d88fa4c6
@ -1050,3 +1050,36 @@ SceneTree#scenes {
|
||||
* [themeID="replayIconSmall"] {
|
||||
qproperty-icon: url(./Dark/save.svg);
|
||||
}
|
||||
|
||||
/* Studio Mode T-Bar */
|
||||
|
||||
QSlider[themeID="tBarSlider"] {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal[themeID="tBarSlider"] {
|
||||
height: 5px;
|
||||
margin: 0 12px;
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(31,30,31),
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal[themeID="tBarSlider"] {
|
||||
height: 5px;
|
||||
margin: 0 12px;
|
||||
background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(31,30,31),
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal[themeID="tBarSlider"] {
|
||||
background-color: #d2d2d2;
|
||||
width: 25px;
|
||||
height: 80px;
|
||||
margin: -24px -12px;
|
||||
}
|
||||
|
@ -815,3 +815,28 @@ SceneTree {
|
||||
* [themeID="replayIconSmall"] {
|
||||
qproperty-icon: url(./Dark/save.svg);
|
||||
}
|
||||
|
||||
/* Studio Mode T-Bar */
|
||||
|
||||
QSlider[themeID="tBarSlider"] {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal[themeID="tBarSlider"] {
|
||||
border: 1px solid #4c4c4c;
|
||||
height: 5px;
|
||||
background: rgb(31,30,31);;
|
||||
margin: 0 12px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal[themeID="tBarSlider"] {
|
||||
background: rgb(31,30,31);;
|
||||
border: 1px solid #4c4c4c;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal[themeID="tBarSlider"] {
|
||||
background-color: #d2d2d2;
|
||||
width: 25px;
|
||||
height: 80px;
|
||||
margin: -24px -12px;
|
||||
}
|
||||
|
@ -1378,3 +1378,36 @@ SceneTree#scenes {
|
||||
* [themeID="replayIconSmall"] {
|
||||
qproperty-icon: url(./Dark/save.svg);
|
||||
}
|
||||
|
||||
/* Studio Mode T-Bar */
|
||||
|
||||
QSlider[themeID="tBarSlider"] {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal[themeID="tBarSlider"] {
|
||||
height: 5px;
|
||||
margin: 0 12px;
|
||||
background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
|
||||
stop: 0 rgb(35, 38, 41), /* Dark Gray */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal[themeID="tBarSlider"] {
|
||||
height: 5px;
|
||||
margin: 0 12px;
|
||||
background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0,
|
||||
stop: 0 rgb(35, 38, 41), /* Dark Gray */
|
||||
stop: 0.75 rgb(50, 49, 50));
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal[themeID="tBarSlider"] {
|
||||
background-color: #d2d2d2;
|
||||
width: 25px;
|
||||
height: 80px;
|
||||
margin: -24px -12px;
|
||||
}
|
||||
|
@ -246,3 +246,29 @@ SceneTree {
|
||||
* [themeID="replayIconSmall"] {
|
||||
qproperty-icon: url(:res/images/save.svg);
|
||||
}
|
||||
|
||||
/* Studio Mode T-Bar */
|
||||
|
||||
QSlider[themeID="tBarSlider"] {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal[themeID="tBarSlider"] {
|
||||
border: 1px solid #4c4c4c;
|
||||
height: 5px;
|
||||
background: #DCD9D7;
|
||||
margin: 0 12px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal[themeID="tBarSlider"] {
|
||||
background: #DCD9D7;
|
||||
border: 1px solid #4c4c4c;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal[themeID="tBarSlider"] {
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #4c4c4c;
|
||||
width: 25px;
|
||||
height: 80px;
|
||||
margin: -24px -12px;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -502,6 +502,11 @@ private:
|
||||
QIcon GetBrowserIcon() const;
|
||||
QIcon GetDefaultIcon() const;
|
||||
|
||||
QSlider *tBar;
|
||||
bool tBarActive = false;
|
||||
bool tBarDown = false;
|
||||
void EnableTBar();
|
||||
|
||||
public slots:
|
||||
void DeferSaveBegin();
|
||||
void DeferSaveEnd();
|
||||
@ -541,7 +546,8 @@ public slots:
|
||||
void TransitionToScene(OBSScene scene, bool force = false);
|
||||
void TransitionToScene(OBSSource scene, bool force = false,
|
||||
bool quickTransition = false,
|
||||
int quickDuration = 0, bool black = false);
|
||||
int quickDuration = 0, bool black = false,
|
||||
bool manual = false);
|
||||
void SetCurrentScene(OBSSource scene, bool force = false);
|
||||
|
||||
bool AddSceneCollection(bool create_new,
|
||||
@ -645,6 +651,9 @@ private slots:
|
||||
void SetSceneIcon(const QIcon &icon);
|
||||
void SetDefaultIcon(const QIcon &icon);
|
||||
|
||||
void TBarChanged(int value);
|
||||
void TBarReleased();
|
||||
|
||||
private:
|
||||
/* OBS Callbacks */
|
||||
static void SceneReordered(void *data, calldata_t *params);
|
||||
|
Loading…
x
Reference in New Issue
Block a user