提交 60e1d7e9 编写于 作者: C cg2121 提交者: jp9000

UI: Implement per-scene transition overriding

Allows the ability to override what specific transition a scene may use
when transitioning to it.

(Original proposal by cg2121, reworked by Jim)

Closes jp9000/obs-studio#1052
上级 e70b226e
...@@ -76,6 +76,8 @@ Next="Next" ...@@ -76,6 +76,8 @@ Next="Next"
Back="Back" Back="Back"
Defaults="Defaults" Defaults="Defaults"
HideMixer="Hide in Mixer" HideMixer="Hide in Mixer"
TransitionOverride="Transition Override"
None="None"
# warning if program already open # warning if program already open
AlreadyRunning.Title="OBS is already running" AlreadyRunning.Title="OBS is already running"
......
...@@ -127,9 +127,17 @@ void OBSBasic::InitTransition(obs_source_t *transition) ...@@ -127,9 +127,17 @@ void OBSBasic::InitTransition(obs_source_t *transition)
Qt::QueuedConnection); Qt::QueuedConnection);
}; };
auto onTransitionFullStop = [] (void *data, calldata_t*) {
OBSBasic *window = (OBSBasic*)data;
QMetaObject::invokeMethod(window, "TransitionFullyStopped",
Qt::QueuedConnection);
};
signal_handler_t *handler = obs_source_get_signal_handler(transition); signal_handler_t *handler = obs_source_get_signal_handler(transition);
signal_handler_connect(handler, "transition_video_stop", signal_handler_connect(handler, "transition_video_stop",
onTransitionStop, this); onTransitionStop, this);
signal_handler_connect(handler, "transition_stop",
onTransitionFullStop, this);
} }
static inline OBSSource GetTransitionComboItem(QComboBox *combo, int idx) static inline OBSSource GetTransitionComboItem(QComboBox *combo, int idx)
...@@ -242,6 +250,27 @@ void OBSBasic::TransitionStopped() ...@@ -242,6 +250,27 @@ void OBSBasic::TransitionStopped()
swapScene = nullptr; swapScene = nullptr;
} }
static void OverrideTransition(OBSSource transition)
{
obs_source_t *oldTransition = obs_get_output_source(0);
if (transition != oldTransition) {
obs_transition_swap_begin(transition, oldTransition);
obs_set_output_source(0, transition);
obs_transition_swap_end(transition, oldTransition);
}
obs_source_release(oldTransition);
}
void OBSBasic::TransitionFullyStopped()
{
if (overridingTransition) {
OverrideTransition(GetCurrentTransition());
overridingTransition = false;
}
}
void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct) void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct)
{ {
obs_scene_t *scene = obs_scene_from_source(source); obs_scene_t *scene = obs_scene_from_source(source);
...@@ -274,21 +303,43 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct) ...@@ -274,21 +303,43 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct)
source = obs_scene_get_source(scene); source = obs_scene_get_source(scene);
} }
obs_source_t *transition = obs_get_output_source(0); OBSSource transition = obs_get_output_source(0);
obs_source_release(transition);
if (force) { if (force) {
obs_transition_set(transition, source); obs_transition_set(transition, source);
if (api) if (api)
api->on_event(OBS_FRONTEND_EVENT_SCENE_CHANGED); api->on_event(OBS_FRONTEND_EVENT_SCENE_CHANGED);
} else { } else {
/* check for scene override */
OBSData data = obs_source_get_private_settings(source);
obs_data_release(data);
const char *trOverrideName = obs_data_get_string(data,
"transition");
int duration = ui->transitionDuration->value();
if (trOverrideName && *trOverrideName) {
OBSSource trOverride = FindTransition(trOverrideName);
if (trOverride) {
transition = trOverride;
obs_data_set_default_int(data,
"transition_duration", 300);
duration = (int)obs_data_get_int(data,
"transition_duration");
OverrideTransition(trOverride);
overridingTransition = true;
}
}
obs_transition_start(transition, OBS_TRANSITION_MODE_AUTO, obs_transition_start(transition, OBS_TRANSITION_MODE_AUTO,
ui->transitionDuration->value(), source); duration, source);
} }
if (usingPreviewProgram && sceneDuplicationMode && !direct) if (usingPreviewProgram && sceneDuplicationMode && !direct)
obs_scene_release(scene); obs_scene_release(scene);
obs_source_release(transition);
} }
static inline void SetComboTransition(QComboBox *combo, obs_source_t *tr) static inline void SetComboTransition(QComboBox *combo, obs_source_t *tr)
...@@ -754,6 +805,88 @@ static inline void ResetQuickTransitionText(QuickTransition *qt) ...@@ -754,6 +805,88 @@ static inline void ResetQuickTransitionText(QuickTransition *qt)
qt->button->setText(MakeQuickTransitionText(qt)); qt->button->setText(MakeQuickTransitionText(qt));
} }
QMenu *OBSBasic::CreatePerSceneTransitionMenu()
{
OBSSource scene = GetCurrentSceneSource();
QMenu *menu = new QMenu(QTStr("TransitionOverride"));
QAction *action;
OBSData data = obs_source_get_private_settings(scene);
obs_data_release(data);
obs_data_set_default_int(data, "transition_duration", 300);
const char *curTransition = obs_data_get_string(data, "transition");
int curDuration = (int)obs_data_get_int(data, "transition_duration");
QSpinBox *duration = new QSpinBox(menu);
duration->setMinimum(50);
duration->setSuffix("ms");
duration->setMaximum(20000);
duration->setSingleStep(50);
duration->setValue(curDuration);
auto setTransition = [this] (QAction *action)
{
int idx = action->property("transition_index").toInt();
OBSSource scene = GetCurrentSceneSource();
OBSData data = obs_source_get_private_settings(scene);
obs_data_release(data);
if (idx == -1) {
obs_data_set_string(data, "transition", "");
return;
}
OBSSource tr = GetTransitionComboItem(ui->transitions, idx);
const char *name = obs_source_get_name(tr);
obs_data_set_string(data, "transition", name);
};
auto setDuration = [this] (int duration)
{
OBSSource scene = GetCurrentSceneSource();
OBSData data = obs_source_get_private_settings(scene);
obs_data_release(data);
obs_data_set_int(data, "transition_duration", duration);
};
connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
setDuration);
for (int i = -1; i < ui->transitions->count(); i++) {
const char *name = "";
if (i >= 0) {
OBSSource tr;
tr = GetTransitionComboItem(ui->transitions, i);
name = obs_source_get_name(tr);
}
bool match = (name && strcmp(name, curTransition) == 0);
if (!name || !*name)
name = Str("None");
action = menu->addAction(QT_UTF8(name));
action->setProperty("transition_index", i);
action->setCheckable(true);
action->setChecked(match);
connect(action, &QAction::triggered,
std::bind(setTransition, action));
}
QWidgetAction *durationAction = new QWidgetAction(menu);
durationAction->setDefaultWidget(duration);
menu->addSeparator();
menu->addAction(durationAction);
return menu;
}
QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt) QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
{ {
QMenu *menu = new QMenu(parent); QMenu *menu = new QMenu(parent);
......
...@@ -3470,6 +3470,11 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) ...@@ -3470,6 +3470,11 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
popup.addSeparator(); popup.addSeparator();
popup.addAction(QTStr("Filters"), this, popup.addAction(QTStr("Filters"), this,
SLOT(OpenSceneFilters())); SLOT(OpenSceneFilters()));
popup.addSeparator();
QMenu *transitionMenu = CreatePerSceneTransitionMenu();
popup.addMenu(transitionMenu);
} }
popup.exec(QCursor::pos()); popup.exec(QCursor::pos());
......
...@@ -289,6 +289,8 @@ private: ...@@ -289,6 +289,8 @@ private:
void RefreshQuickTransitions(); void RefreshQuickTransitions();
void CreateDefaultQuickTransitions(); void CreateDefaultQuickTransitions();
QMenu *CreatePerSceneTransitionMenu();
QuickTransition *GetQuickTransition(int id); QuickTransition *GetQuickTransition(int id);
int GetQuickTransitionIdx(int id); int GetQuickTransitionIdx(int id);
QMenu *CreateTransitionMenu(QWidget *parent, QuickTransition *qt); QMenu *CreateTransitionMenu(QWidget *parent, QuickTransition *qt);
...@@ -317,6 +319,7 @@ private: ...@@ -317,6 +319,7 @@ private:
obs_hotkey_id togglePreviewProgramHotkey = 0; obs_hotkey_id togglePreviewProgramHotkey = 0;
obs_hotkey_id transitionHotkey = 0; obs_hotkey_id transitionHotkey = 0;
int quickTransitionIdCounter = 1; int quickTransitionIdCounter = 1;
bool overridingTransition = false;
int programX = 0, programY = 0; int programX = 0, programY = 0;
int programCX = 0, programCY = 0; int programCX = 0, programCY = 0;
...@@ -427,6 +430,7 @@ private slots: ...@@ -427,6 +430,7 @@ private slots:
void RenameTransition(); void RenameTransition();
void TransitionClicked(); void TransitionClicked();
void TransitionStopped(); void TransitionStopped();
void TransitionFullyStopped();
void TriggerQuickTransition(int id); void TriggerQuickTransition(int id);
void SetDeinterlacingMode(); void SetDeinterlacingMode();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册