mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-16 06:08:12 -05:00
Add slide show condition
It allows you to check ... * if the slide changed * the current slide index * the current slide path Important limitation: Its internal state is only updated whenever the "slide_changed" signal is sent by the particular source.
This commit is contained in:
@@ -203,6 +203,8 @@ target_sources(
|
||||
src/macro-core/macro-condition-scene-transform.hpp
|
||||
src/macro-core/macro-condition-scene-visibility.cpp
|
||||
src/macro-core/macro-condition-scene-visibility.hpp
|
||||
src/macro-core/macro-condition-slideshow.cpp
|
||||
src/macro-core/macro-condition-slideshow.hpp
|
||||
src/macro-core/macro-condition-scene.cpp
|
||||
src/macro-core/macro-condition-scene.hpp
|
||||
src/macro-core/macro-condition-source.cpp
|
||||
|
||||
@@ -466,6 +466,12 @@ AdvSceneSwitcher.condition.display="Display"
|
||||
AdvSceneSwitcher.condition.display.type.displayName="Name of connected displays matches"
|
||||
AdvSceneSwitcher.condition.display.type.displayCount="Number of connected displays is"
|
||||
AdvSceneSwitcher.condition.display.entry="{{conditions}}{{displays}}{{regex}}{{displayCount}}"
|
||||
AdvSceneSwitcher.condition.slideshow="Slide Show"
|
||||
AdvSceneSwitcher.condition.slideshow.condition.slideChanged="Slide changed"
|
||||
AdvSceneSwitcher.condition.slideshow.condition.slideIndex="Current slide number is"
|
||||
AdvSceneSwitcher.condition.slideshow.condition.slidePath="Current slide path is"
|
||||
AdvSceneSwitcher.condition.slideshow.updateIntervalTooltip="Information about the slide show status will only be updated based on the configured time between slides"
|
||||
AdvSceneSwitcher.condition.slideshow.entry="{{sources}}{{conditions}}{{index}}{{path}}"
|
||||
|
||||
; Macro Actions
|
||||
AdvSceneSwitcher.action.switchScene="Switch scene"
|
||||
|
||||
312
src/macro-core/macro-condition-slideshow.cpp
Normal file
312
src/macro-core/macro-condition-slideshow.cpp
Normal file
@@ -0,0 +1,312 @@
|
||||
#include "macro-condition-slideshow.hpp"
|
||||
#include "macro.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroConditionSlideshow::id = "slideshow";
|
||||
|
||||
bool MacroConditionSlideshow::_registered = MacroConditionFactory::Register(
|
||||
MacroConditionSlideshow::id,
|
||||
{MacroConditionSlideshow::Create, MacroConditionSlideshowEdit::Create,
|
||||
"AdvSceneSwitcher.condition.slideshow"});
|
||||
|
||||
static const std::map<MacroConditionSlideshow::Condition, std::string>
|
||||
conditions = {
|
||||
{MacroConditionSlideshow::Condition::SLIDE_CHANGED,
|
||||
"AdvSceneSwitcher.condition.slideshow.condition.slideChanged"},
|
||||
{MacroConditionSlideshow::Condition::SLIDE_INDEX,
|
||||
"AdvSceneSwitcher.condition.slideshow.condition.slideIndex"},
|
||||
{MacroConditionSlideshow::Condition::SLIDE_PATH,
|
||||
"AdvSceneSwitcher.condition.slideshow.condition.slidePath"},
|
||||
};
|
||||
|
||||
MacroConditionSlideshow::MacroConditionSlideshow(Macro *m)
|
||||
: MacroCondition(m, true)
|
||||
{
|
||||
}
|
||||
|
||||
MacroConditionSlideshow::~MacroConditionSlideshow()
|
||||
{
|
||||
RemoveSignalHandler();
|
||||
}
|
||||
|
||||
bool MacroConditionSlideshow::CheckCondition()
|
||||
{
|
||||
auto source = _source.GetSource();
|
||||
if (_currentSignalSource != source) {
|
||||
Reset();
|
||||
RemoveSignalHandler();
|
||||
AddSignalHandler(source);
|
||||
}
|
||||
|
||||
if (!source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (_condition) {
|
||||
case MacroConditionSlideshow::Condition::SLIDE_CHANGED:
|
||||
if (!_slideChanged) {
|
||||
SetVariableValue("false");
|
||||
return false;
|
||||
}
|
||||
_slideChanged = false;
|
||||
SetVariableValue("true");
|
||||
return true;
|
||||
case MacroConditionSlideshow::Condition::SLIDE_INDEX:
|
||||
if (_currentIndex == -1) {
|
||||
SetVariableValue("-1");
|
||||
return false;
|
||||
}
|
||||
SetVariableValue(std::to_string(_currentIndex + 1));
|
||||
return _currentIndex == _index - 1;
|
||||
case MacroConditionSlideshow::Condition::SLIDE_PATH:
|
||||
if (_currentPath[0] == '\0') {
|
||||
SetVariableValue("");
|
||||
return false;
|
||||
}
|
||||
SetVariableValue(_currentPath);
|
||||
return std::string(_path) == std::string(_currentPath);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionSlideshow::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
_source.Save(obj);
|
||||
_index.Save(obj, "index");
|
||||
_path.Save(obj, "path");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionSlideshow::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
|
||||
_source.Load(obj);
|
||||
_index.Load(obj, "index");
|
||||
_path.Load(obj, "path");
|
||||
|
||||
auto s = _source.GetSource();
|
||||
AddSignalHandler(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionSlideshow::GetShortDesc() const
|
||||
{
|
||||
return _source.ToString();
|
||||
}
|
||||
|
||||
void MacroConditionSlideshow::SetSource(const SourceSelection &source)
|
||||
{
|
||||
Reset();
|
||||
_source = source;
|
||||
RemoveSignalHandler();
|
||||
auto s = _source.GetSource();
|
||||
AddSignalHandler(s);
|
||||
}
|
||||
|
||||
const SourceSelection &MacroConditionSlideshow::GetSource() const
|
||||
{
|
||||
return _source;
|
||||
}
|
||||
|
||||
void MacroConditionSlideshow::SlideChanged(void *c, calldata_t *data)
|
||||
{
|
||||
auto condition = static_cast<MacroConditionSlideshow *>(c);
|
||||
const auto macro = condition->GetMacro();
|
||||
if (macro && macro->Paused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
long long newIndex = 0;
|
||||
if (!calldata_get_int(data, "index", &newIndex)) {
|
||||
condition->_currentIndex = -1;
|
||||
}
|
||||
|
||||
// Function will be called every time the slide_time timeout is reached
|
||||
// regardless of if there was actually a change in slide index.
|
||||
//
|
||||
// Thus we need to manually check if the slide index really changed.
|
||||
if (newIndex != condition->_currentIndex) {
|
||||
condition->_slideChanged = true;
|
||||
}
|
||||
condition->_currentIndex = newIndex;
|
||||
|
||||
if (!calldata_get_string(data, "path", &condition->_currentPath)) {
|
||||
condition->_currentPath = "";
|
||||
}
|
||||
}
|
||||
|
||||
void MacroConditionSlideshow::RemoveSignalHandler()
|
||||
{
|
||||
obs_source_t *source = obs_weak_source_get_source(_currentSignalSource);
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(source);
|
||||
signal_handler_disconnect(sh, "slide_changed", SlideChanged, this);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void MacroConditionSlideshow::AddSignalHandler(const OBSWeakSource &s)
|
||||
{
|
||||
_currentSignalSource = s;
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
|
||||
obs_source_t *source = obs_weak_source_get_source(s);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(source);
|
||||
signal_handler_connect(sh, "slide_changed", SlideChanged, this);
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void MacroConditionSlideshow::Reset()
|
||||
{
|
||||
_slideChanged = false;
|
||||
_currentIndex = -1;
|
||||
_currentPath = "";
|
||||
}
|
||||
|
||||
static void populateConditionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[_, name] : conditions) {
|
||||
list->addItem(obs_module_text(name.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getSlideshowNames()
|
||||
{
|
||||
auto sourceEnum = [](void *param, obs_source_t *source) -> bool /* -- */
|
||||
{
|
||||
QStringList *list = reinterpret_cast<QStringList *>(param);
|
||||
std::string sourceId = obs_source_get_id(source);
|
||||
if (sourceId.compare("slideshow") == 0) {
|
||||
*list << obs_source_get_name(source);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
QStringList list;
|
||||
obs_enum_sources(sourceEnum, &list);
|
||||
return list;
|
||||
}
|
||||
|
||||
MacroConditionSlideshowEdit::MacroConditionSlideshowEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionSlideshow> entryData)
|
||||
: QWidget(parent),
|
||||
_conditions(new QComboBox(this)),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_index(new VariableSpinBox(this)),
|
||||
_path(new VariableLineEdit(this))
|
||||
{
|
||||
setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.slideshow.updateIntervalTooltip"));
|
||||
_index->setMinimum(1);
|
||||
populateConditionSelection(_conditions);
|
||||
|
||||
auto sources = getSlideshowNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||
SLOT(SourceChanged(const SourceSelection &)));
|
||||
QWidget::connect(
|
||||
_index,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(IndexChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_path, SIGNAL(editingFinished()), this,
|
||||
SLOT(PathChanged()));
|
||||
|
||||
auto layout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.slideshow.entry"),
|
||||
layout,
|
||||
{{"{{conditions}}", _conditions},
|
||||
{"{{sources}}", _sources},
|
||||
{"{{index}}", _index},
|
||||
{"{{path}}", _path}});
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionSlideshowEdit::ConditionChanged(int index)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_condition =
|
||||
static_cast<MacroConditionSlideshow::Condition>(index);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionSlideshowEdit::SourceChanged(const SourceSelection &source)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->SetSource(source);
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionSlideshowEdit::IndexChanged(const NumberVariable<int> &value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_index = value;
|
||||
}
|
||||
|
||||
void MacroConditionSlideshowEdit::PathChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_entryData->_path = _path->text().toStdString();
|
||||
}
|
||||
|
||||
void MacroConditionSlideshowEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
_sources->SetSource(_entryData->GetSource());
|
||||
_index->SetValue(_entryData->_index);
|
||||
_path->setText(_entryData->_path);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionSlideshowEdit::SetWidgetVisibility()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_index->setVisible(_entryData->_condition ==
|
||||
MacroConditionSlideshow::Condition::SLIDE_INDEX);
|
||||
_path->setVisible(_entryData->_condition ==
|
||||
MacroConditionSlideshow::Condition::SLIDE_PATH);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
88
src/macro-core/macro-condition-slideshow.hpp
Normal file
88
src/macro-core/macro-condition-slideshow.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "source-selection.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroConditionSlideshow : public MacroCondition {
|
||||
public:
|
||||
MacroConditionSlideshow(Macro *m);
|
||||
~MacroConditionSlideshow();
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetShortDesc() const;
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroConditionSlideshow>(m);
|
||||
}
|
||||
|
||||
void SetSource(const SourceSelection &source);
|
||||
const SourceSelection &GetSource() const;
|
||||
|
||||
enum class Condition {
|
||||
SLIDE_CHANGED,
|
||||
SLIDE_INDEX,
|
||||
SLIDE_PATH,
|
||||
};
|
||||
Condition _condition = Condition::SLIDE_CHANGED;
|
||||
IntVariable _index;
|
||||
StringVariable _path;
|
||||
|
||||
private:
|
||||
static void SlideChanged(void *condition, calldata_t *);
|
||||
void RemoveSignalHandler();
|
||||
void AddSignalHandler(const OBSWeakSource &);
|
||||
void Reset();
|
||||
|
||||
SourceSelection _source;
|
||||
OBSWeakSource _currentSignalSource;
|
||||
bool _slideChanged = false;
|
||||
long long _currentIndex = -1;
|
||||
const char *_currentPath = "";
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroConditionSlideshowEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroConditionSlideshowEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroConditionSlideshow> cond = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroCondition> cond)
|
||||
{
|
||||
return new MacroConditionSlideshowEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroConditionSlideshow>(
|
||||
cond));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ConditionChanged(int index);
|
||||
void SourceChanged(const SourceSelection &);
|
||||
void IndexChanged(const NumberVariable<int> &);
|
||||
void PathChanged();
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QComboBox *_conditions;
|
||||
VariableSpinBox *_index;
|
||||
VariableLineEdit *_path;
|
||||
SourceSelectionWidget *_sources;
|
||||
|
||||
std::shared_ptr<MacroConditionSlideshow> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
Reference in New Issue
Block a user