mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-26 03:06:17 -05:00
Add option to set transition when changing scene item visibility
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "macro-action-scene-visibility.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "transition-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -21,9 +22,74 @@ const static std::map<MacroActionSceneVisibility::Action, std::string>
|
||||
"AdvSceneSwitcher.action.sceneVisibility.type.toggle"},
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
struct TransitionRestoreContext {
|
||||
obs_sceneitem_t *item;
|
||||
bool wasVisible;
|
||||
|
||||
bool restoreTransition;
|
||||
OBSSource originalTransition;
|
||||
bool restoreDuration;
|
||||
uint32_t originalDuration;
|
||||
|
||||
signal_handler_t *sh = nullptr;
|
||||
|
||||
~TransitionRestoreContext()
|
||||
{
|
||||
if (!sh) {
|
||||
return;
|
||||
}
|
||||
|
||||
signal_handler_disconnect(
|
||||
sh, "transition_stop",
|
||||
&TransitionRestoreContext::ResetSceneItemTransition,
|
||||
this);
|
||||
}
|
||||
|
||||
static void ResetSceneItemTransition(void *param, calldata_t *)
|
||||
{
|
||||
auto *ctx = static_cast<TransitionRestoreContext *>(param);
|
||||
SetSceneItemTransition(ctx->item, ctx->originalTransition,
|
||||
!ctx->wasVisible);
|
||||
|
||||
obs_sceneitem_set_transition_duration(
|
||||
ctx->item, !ctx->wasVisible, ctx->originalDuration);
|
||||
delete ctx;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static void setSceneItemVisibility(obs_sceneitem_t *item,
|
||||
const bool setTransition,
|
||||
const OBSWeakSource &transitionWeak,
|
||||
const bool setDuration,
|
||||
const Duration &duration,
|
||||
MacroActionSceneVisibility::Action action)
|
||||
{
|
||||
const OBSSourceAutoRelease transition = OBSGetStrongRef(transitionWeak);
|
||||
const bool itemIsVisible = obs_sceneitem_visible(item);
|
||||
|
||||
const OBSSource currentTransition =
|
||||
obs_sceneitem_get_transition(item, !itemIsVisible);
|
||||
const uint32_t currentTransitionDuration =
|
||||
obs_sceneitem_get_transition_duration(item, !itemIsVisible);
|
||||
|
||||
obs_source_t *privateTransitionSource = nullptr;
|
||||
if (setTransition) {
|
||||
privateTransitionSource = SetSceneItemTransition(
|
||||
item, transition, !itemIsVisible);
|
||||
} else {
|
||||
privateTransitionSource =
|
||||
obs_sceneitem_get_transition(item, !itemIsVisible);
|
||||
}
|
||||
|
||||
if (setDuration) {
|
||||
obs_sceneitem_set_transition_duration(item, !itemIsVisible,
|
||||
duration.Milliseconds());
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case MacroActionSceneVisibility::Action::SHOW:
|
||||
obs_sceneitem_set_visible(item, true);
|
||||
@@ -32,16 +98,48 @@ static void setSceneItemVisibility(obs_sceneitem_t *item,
|
||||
obs_sceneitem_set_visible(item, false);
|
||||
break;
|
||||
case MacroActionSceneVisibility::Action::TOGGLE:
|
||||
obs_sceneitem_set_visible(item, !obs_sceneitem_visible(item));
|
||||
obs_sceneitem_set_visible(item, !itemIsVisible);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!privateTransitionSource) {
|
||||
if (setTransition) {
|
||||
SetSceneItemTransition(item, currentTransition,
|
||||
!itemIsVisible);
|
||||
}
|
||||
if (setDuration) {
|
||||
obs_sceneitem_set_transition_duration(
|
||||
item, !itemIsVisible,
|
||||
currentTransitionDuration);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto sh = obs_source_get_signal_handler(privateTransitionSource);
|
||||
if (!sh) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto ctx = new TransitionRestoreContext{item,
|
||||
itemIsVisible,
|
||||
setTransition,
|
||||
currentTransition,
|
||||
setDuration,
|
||||
currentTransitionDuration,
|
||||
sh};
|
||||
|
||||
signal_handler_connect(
|
||||
sh, "transition_stop",
|
||||
&TransitionRestoreContext::ResetSceneItemTransition, ctx);
|
||||
}
|
||||
|
||||
bool MacroActionSceneVisibility::PerformAction()
|
||||
{
|
||||
auto items = _source.GetSceneItems(_scene);
|
||||
for (const auto &item : items) {
|
||||
setSceneItemVisibility(item, _action);
|
||||
setSceneItemVisibility(item, _updateTransition,
|
||||
_transition.GetTransition(),
|
||||
_updateDuration, _duration, _action);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -66,6 +164,10 @@ bool MacroActionSceneVisibility::Save(obs_data_t *obj) const
|
||||
MacroAction::Save(obj);
|
||||
_scene.Save(obj);
|
||||
_source.Save(obj);
|
||||
obs_data_set_bool(obj, "updateTransition", _updateTransition);
|
||||
_transition.Save(obj);
|
||||
obs_data_set_bool(obj, "updateDuration", _updateDuration);
|
||||
_duration.Save(obj);
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
return true;
|
||||
}
|
||||
@@ -82,6 +184,10 @@ bool MacroActionSceneVisibility::Load(obs_data_t *obj)
|
||||
MacroAction::Load(obj);
|
||||
_scene.Load(obj);
|
||||
_source.Load(obj);
|
||||
_updateTransition = obs_data_get_bool(obj, "updateTransition");
|
||||
_transition.Load(obj);
|
||||
_updateDuration = obs_data_get_bool(obj, "updateDuration");
|
||||
_duration.Load(obj);
|
||||
_action = static_cast<MacroActionSceneVisibility::Action>(
|
||||
obs_data_get_int(obj, "action"));
|
||||
|
||||
@@ -141,10 +247,17 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
|
||||
SceneItemSelection::Type::ALL,
|
||||
},
|
||||
SceneItemSelectionWidget::NameClashMode::ALL)),
|
||||
_updateTransition(new QCheckBox(this)),
|
||||
_transitions(new TransitionSelectionWidget(this, false, false)),
|
||||
_updateDuration(new QCheckBox(this)),
|
||||
_duration(new DurationSelection(this, false)),
|
||||
_durationLayout(new QHBoxLayout),
|
||||
_actions(new QComboBox())
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
|
||||
_duration->SpinBox()->setSpecialValueText("-");
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
||||
@@ -154,18 +267,49 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
|
||||
this, SLOT(SourceChanged(const SceneItemSelection &)));
|
||||
QWidget::connect(_updateTransition, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(UpdateTransitionChanged(int)));
|
||||
QWidget::connect(_transitions,
|
||||
SIGNAL(TransitionChanged(const TransitionSelection &)),
|
||||
this,
|
||||
SLOT(TransitionChanged(const TransitionSelection &)));
|
||||
QWidget::connect(_updateDuration, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(UpdateDurationChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
|
||||
auto layout = new QHBoxLayout;
|
||||
auto sceneItemLayout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.action.sceneVisibility.entry"),
|
||||
layout,
|
||||
"AdvSceneSwitcher.action.sceneVisibility.layout"),
|
||||
sceneItemLayout,
|
||||
{{"{{scenes}}", _scenes},
|
||||
{"{{sources}}", _sources},
|
||||
{"{{actions}}", _actions}});
|
||||
|
||||
auto transitionLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.sceneVisibility.layout.transition"),
|
||||
transitionLayout,
|
||||
{{"{{updateTransition}}", _updateTransition},
|
||||
{"{{transitions}}", _transitions}});
|
||||
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.sceneVisibility.layout.duration"),
|
||||
_durationLayout,
|
||||
{{"{{updateDuration}}", _updateDuration},
|
||||
{"{{duration}}", _duration}});
|
||||
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->addLayout(sceneItemLayout);
|
||||
layout->addLayout(transitionLayout);
|
||||
layout->addLayout(_durationLayout);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
SetWidgetVisibility();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
@@ -177,7 +321,11 @@ void MacroActionSceneVisibilityEdit::UpdateEntryData()
|
||||
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_scenes->SetScene(_entryData->_scene);
|
||||
_sources->SetSceneItem((_entryData->_source));
|
||||
_sources->SetSceneItem(_entryData->_source);
|
||||
_updateTransition->setChecked(_entryData->_updateTransition);
|
||||
_transitions->SetTransition(_entryData->_transition);
|
||||
_updateDuration->setChecked(_entryData->_updateDuration);
|
||||
_duration->SetDuration(_entryData->_duration);
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::SceneChanged(const SceneSelection &s)
|
||||
@@ -197,6 +345,33 @@ void MacroActionSceneVisibilityEdit::SourceChanged(
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::UpdateTransitionChanged(int state)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_updateTransition = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::TransitionChanged(
|
||||
const TransitionSelection &t)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_transition = t;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::UpdateDurationChanged(int state)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_updateDuration = state;
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::ActionChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
@@ -204,4 +379,20 @@ void MacroActionSceneVisibilityEdit::ActionChanged(int value)
|
||||
static_cast<MacroActionSceneVisibility::Action>(value);
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::SetWidgetVisibility()
|
||||
{
|
||||
const bool hideDurationSelection =
|
||||
_entryData->_updateTransition &&
|
||||
IsFixedLengthTransition(
|
||||
_entryData->_transition.GetTransition());
|
||||
|
||||
SetLayoutVisible(_durationLayout, !hideDurationSelection);
|
||||
|
||||
_transitions->setEnabled(_entryData->_updateTransition);
|
||||
_duration->setEnabled(_entryData->_updateDuration);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
Reference in New Issue
Block a user