mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-05-05 20:36:33 -05:00
Add option to directly map temp var values to variables
This commit is contained in:
parent
f090dea136
commit
dec5c2d763
|
|
@ -1795,6 +1795,10 @@ AdvSceneSwitcher.script.file.layout="Script file:{{path}}{{open}}"
|
|||
|
||||
AdvSceneSwitcher.tempVar.select="--select value--"
|
||||
AdvSceneSwitcher.tempVar.selectionInfo.lastValues="Last values:"
|
||||
AdvSceneSwitcher.tempVar.outputMappings="Save outputs to variables:"
|
||||
AdvSceneSwitcher.tempVar.outputMappings.add="+ Add output mapping"
|
||||
AdvSceneSwitcher.tempVar.outputMappings.toggle="Assign outputs to variables"
|
||||
AdvSceneSwitcher.tempVar.outputMappings.remove="Remove output mapping"
|
||||
|
||||
AdvSceneSwitcher.tempVar.twitch.broadcaster_user_id="Twitch broadcaster user ID"
|
||||
AdvSceneSwitcher.tempVar.twitch.broadcaster_user_id.description="The numerical Twitch user ID of the broadcaster."
|
||||
|
|
|
|||
10
data/res/images/DarkVariable.svg
Normal file
10
data/res/images/DarkVariable.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="#fefefe" xmlns="http://www.w3.org/2000/svg"
|
||||
width="800px" height="800px" viewBox="0 0 52 52" enable-background="new 0 0 52 52" xml:space="preserve">
|
||||
<path d="M42.6,17.8c2.4,0,7.2-2,7.2-8.4c0-6.4-4.6-6.8-6.1-6.8c-2.8,0-5.6,2-8.1,6.3c-2.5,4.4-5.3,9.1-5.3,9.1
|
||||
l-0.1,0c-0.6-3.1-1.1-5.6-1.3-6.7c-0.5-2.7-3.6-8.4-9.9-8.4c-6.4,0-12.2,3.7-12.2,3.7l0,0C5.8,7.3,5.1,8.5,5.1,9.9
|
||||
c0,2.1,1.7,3.9,3.9,3.9c0.6,0,1.2-0.2,1.7-0.4l0,0c0,0,4.8-2.7,5.9,0c0.3,0.8,0.6,1.7,0.9,2.7c1.2,4.2,2.4,9.1,3.3,13.5l-4.2,6
|
||||
c0,0-4.7-1.7-7.1-1.7s-7.2,2-7.2,8.4s4.6,6.8,6.1,6.8c2.8,0,5.6-2,8.1-6.3c2.5-4.4,5.3-9.1,5.3-9.1c0.8,4,1.5,7.1,1.9,8.5
|
||||
c1.6,4.5,5.3,7.2,10.1,7.2c0,0,5,0,10.9-3.3c1.4-0.6,2.4-2,2.4-3.6c0-2.1-1.7-3.9-3.9-3.9c-0.6,0-1.2,0.2-1.7,0.4l0,0
|
||||
c0,0-4.2,2.4-5.6,0.5c-1-2-1.9-4.6-2.6-7.8c-0.6-2.8-1.3-6.2-2-9.5l4.3-6.2C35.5,16.1,40.2,17.8,42.6,17.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 973 B |
10
data/res/images/LightVariable.svg
Normal file
10
data/res/images/LightVariable.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="#202020" xmlns="http://www.w3.org/2000/svg"
|
||||
width="800px" height="800px" viewBox="0 0 52 52" enable-background="new 0 0 52 52" xml:space="preserve">
|
||||
<path d="M42.6,17.8c2.4,0,7.2-2,7.2-8.4c0-6.4-4.6-6.8-6.1-6.8c-2.8,0-5.6,2-8.1,6.3c-2.5,4.4-5.3,9.1-5.3,9.1
|
||||
l-0.1,0c-0.6-3.1-1.1-5.6-1.3-6.7c-0.5-2.7-3.6-8.4-9.9-8.4c-6.4,0-12.2,3.7-12.2,3.7l0,0C5.8,7.3,5.1,8.5,5.1,9.9
|
||||
c0,2.1,1.7,3.9,3.9,3.9c0.6,0,1.2-0.2,1.7-0.4l0,0c0,0,4.8-2.7,5.9,0c0.3,0.8,0.6,1.7,0.9,2.7c1.2,4.2,2.4,9.1,3.3,13.5l-4.2,6
|
||||
c0,0-4.7-1.7-7.1-1.7s-7.2,2-7.2,8.4s4.6,6.8,6.1,6.8c2.8,0,5.6-2,8.1-6.3c2.5-4.4,5.3-9.1,5.3-9.1c0.8,4,1.5,7.1,1.9,8.5
|
||||
c1.6,4.5,5.3,7.2,10.1,7.2c0,0,5,0,10.9-3.3c1.4-0.6,2.4-2,2.4-3.6c0-2.1-1.7-3.9-3.9-3.9c-0.6,0-1.2,0.2-1.7,0.4l0,0
|
||||
c0,0-4.2,2.4-5.6,0.5c-1-2-1.9-4.6-2.6-7.8c-0.6-2.8-1.3-6.2-2-9.5l4.3-6.2C35.5,16.1,40.2,17.8,42.6,17.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 973 B |
|
|
@ -49,10 +49,12 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
|||
_section->AddHeaderWidget(_enable);
|
||||
_section->AddHeaderWidget(_actionSelection);
|
||||
_section->AddHeaderWidget(_headerInfo);
|
||||
_section->AddHeaderWidget(_varMappingToggle);
|
||||
|
||||
auto actionLayout = new QVBoxLayout;
|
||||
actionLayout->setContentsMargins({7, 7, 7, 7});
|
||||
actionLayout->addWidget(_section);
|
||||
actionLayout->addWidget(_outputMappings);
|
||||
_contentLayout->addLayout(actionLayout);
|
||||
|
||||
auto mainLayout = new QHBoxLayout;
|
||||
|
|
@ -61,7 +63,6 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
|||
mainLayout->addWidget(_frame);
|
||||
setLayout(mainLayout);
|
||||
|
||||
_entryData = entryData;
|
||||
SetupWidgets(true);
|
||||
|
||||
actionStateTimer->start(300);
|
||||
|
|
@ -90,7 +91,10 @@ void MacroActionEdit::SetupWidgets(bool basicSetup)
|
|||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
||||
SLOT(ShowVariableMappings(bool)));
|
||||
_section->SetContent(widget, (*_entryData)->GetCollapsed());
|
||||
SetupVarMappings((*_entryData).get());
|
||||
SetFocusPolicyOfWidgets();
|
||||
|
||||
_allWidgetsAreSetup = true;
|
||||
|
|
@ -121,7 +125,10 @@ void MacroActionEdit::ActionSelectionChanged(const QString &text)
|
|||
auto widget = MacroActionFactory::CreateWidget(id, this, *_entryData);
|
||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
||||
SLOT(ShowVariableMappings(bool)));
|
||||
_section->SetContent(widget);
|
||||
SetupVarMappings((*_entryData).get());
|
||||
SetFocusPolicyOfWidgets();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,11 @@ const std::string MacroActionVariable::id = "variable";
|
|||
|
||||
std::vector<TempVariableRef> MacroActionVariable::GetTempVarRefs() const
|
||||
{
|
||||
if (!_tempVar.HasValidID()) {
|
||||
return {};
|
||||
auto refs = MacroSegment::GetTempVarRefs();
|
||||
if (_tempVar.HasValidID()) {
|
||||
refs.push_back(_tempVar);
|
||||
}
|
||||
return {_tempVar};
|
||||
return refs;
|
||||
}
|
||||
|
||||
bool MacroActionVariable::_registered = MacroActionFactory::Register(
|
||||
|
|
|
|||
|
|
@ -126,10 +126,12 @@ MacroConditionEdit::MacroConditionEdit(
|
|||
_section->AddHeaderWidget(_conditionSelection);
|
||||
_section->AddHeaderWidget(_headerInfo);
|
||||
_section->AddHeaderWidget(_dur);
|
||||
_section->AddHeaderWidget(_varMappingToggle);
|
||||
|
||||
QVBoxLayout *conditionLayout = new QVBoxLayout;
|
||||
conditionLayout->setContentsMargins({7, 7, 7, 7});
|
||||
conditionLayout->addWidget(_section);
|
||||
conditionLayout->addWidget(_outputMappings);
|
||||
_contentLayout->addLayout(conditionLayout);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
|
|
@ -204,7 +206,10 @@ void MacroConditionEdit::SetupWidgets(bool basicSetup)
|
|||
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
||||
SLOT(ShowVariableMappings(bool)));
|
||||
_section->SetContent(widget, (*_entryData)->GetCollapsed());
|
||||
SetupVarMappings((*_entryData).get());
|
||||
SetFocusPolicyOfWidgets();
|
||||
|
||||
_allWidgetsAreSetup = true;
|
||||
|
|
@ -245,7 +250,10 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
|
|||
MacroConditionFactory::CreateWidget(id, this, *_entryData);
|
||||
QWidget::connect(widget, SIGNAL(HeaderInfoChanged(const QString &)),
|
||||
this, SLOT(HeaderInfoChanged(const QString &)));
|
||||
QWidget::connect(widget, SIGNAL(ShowVariableMappings(bool)), this,
|
||||
SLOT(ShowVariableMappings(bool)));
|
||||
_section->SetContent(widget);
|
||||
SetupVarMappings((*_entryData).get());
|
||||
_dur->setVisible(MacroConditionFactory::UsesDurationModifier(id));
|
||||
SetFocusPolicyOfWidgets();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ const std::string MacroConditionTempVar::id = "temp_var";
|
|||
|
||||
std::vector<TempVariableRef> MacroConditionTempVar::GetTempVarRefs() const
|
||||
{
|
||||
if (!_tempVar.HasValidID()) {
|
||||
return {};
|
||||
auto refs = MacroSegment::GetTempVarRefs();
|
||||
if (_tempVar.HasValidID()) {
|
||||
refs.push_back(_tempVar);
|
||||
}
|
||||
return {_tempVar};
|
||||
return refs;
|
||||
}
|
||||
|
||||
bool MacroConditionTempVar::_registered = MacroConditionFactory::Register(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#include "macro-segment.hpp"
|
||||
#include "macro.hpp"
|
||||
#include "mouse-wheel-guard.hpp"
|
||||
#include "path-helpers.hpp"
|
||||
#include "section.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
#include "variable.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QEvent>
|
||||
|
|
@ -15,7 +17,48 @@ namespace advss {
|
|||
|
||||
std::vector<TempVariableRef> MacroSegment::GetTempVarRefs() const
|
||||
{
|
||||
return {};
|
||||
std::vector<TempVariableRef> refs;
|
||||
for (const auto &mapping : _varMappings) {
|
||||
if (mapping.tempVar.HasValidID()) {
|
||||
refs.push_back(mapping.tempVar);
|
||||
}
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
void MacroSegment::ApplyVarMappings()
|
||||
{
|
||||
auto macro = GetMacro();
|
||||
for (const auto &mapping : _varMappings) {
|
||||
auto var = mapping.variable.lock();
|
||||
if (!var) {
|
||||
continue;
|
||||
}
|
||||
const auto tempVar = mapping.tempVar.GetTempVariable(macro);
|
||||
if (!tempVar) {
|
||||
continue;
|
||||
}
|
||||
const auto value = tempVar->Value();
|
||||
if (!value) {
|
||||
continue;
|
||||
}
|
||||
var->SetValue(*value);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<VarMapping> &MacroSegment::GetVarMappings() const
|
||||
{
|
||||
return _varMappings;
|
||||
}
|
||||
|
||||
void MacroSegment::SetVarMappings(const std::vector<VarMapping> &mappings)
|
||||
{
|
||||
_varMappings = mappings;
|
||||
}
|
||||
|
||||
std::vector<TempVariable> MacroSegment::GetOwnTempVars() const
|
||||
{
|
||||
return _tempVariables;
|
||||
}
|
||||
|
||||
MacroSegment::MacroSegment(Macro *m, bool supportsVariableValue)
|
||||
|
|
@ -24,14 +67,32 @@ MacroSegment::MacroSegment(Macro *m, bool supportsVariableValue)
|
|||
{
|
||||
}
|
||||
|
||||
void MacroSegment::SetVarMappingExpanded(bool expanded)
|
||||
{
|
||||
_varMappingExpanded = expanded;
|
||||
}
|
||||
|
||||
bool MacroSegment::Save(obs_data_t *obj) const
|
||||
{
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_bool(data, "collapsed", _collapsed);
|
||||
obs_data_set_bool(data, "varMappingExpanded", _varMappingExpanded);
|
||||
obs_data_set_bool(data, "useCustomLabel", _useCustomLabel);
|
||||
obs_data_set_string(data, "customLabel", _customLabel.c_str());
|
||||
obs_data_set_bool(data, "enabled", _enabled);
|
||||
obs_data_set_int(data, "version", 1);
|
||||
|
||||
OBSDataArrayAutoRelease mappingsArray = obs_data_array_create();
|
||||
for (const auto &mapping : _varMappings) {
|
||||
OBSDataAutoRelease item = obs_data_create();
|
||||
mapping.tempVar.Save(item, GetMacro(), "tempVar");
|
||||
obs_data_set_string(
|
||||
item, "variable",
|
||||
GetWeakVariableName(mapping.variable).c_str());
|
||||
obs_data_array_push_back(mappingsArray, item);
|
||||
}
|
||||
obs_data_set_array(data, "varMappings", mappingsArray);
|
||||
|
||||
obs_data_set_obj(obj, "segmentSettings", data);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -40,6 +101,7 @@ bool MacroSegment::Load(obs_data_t *obj)
|
|||
{
|
||||
OBSDataAutoRelease data = obs_data_get_obj(obj, "segmentSettings");
|
||||
_collapsed = obs_data_get_bool(data, "collapsed");
|
||||
_varMappingExpanded = obs_data_get_bool(data, "varMappingExpanded");
|
||||
_useCustomLabel = obs_data_get_bool(data, "useCustomLabel");
|
||||
_customLabel = obs_data_get_string(data, "customLabel");
|
||||
obs_data_set_default_bool(data, "enabled", true);
|
||||
|
|
@ -50,6 +112,20 @@ bool MacroSegment::Load(obs_data_t *obj)
|
|||
_enabled = obs_data_get_bool(obj, "enabled");
|
||||
}
|
||||
|
||||
_varMappings.clear();
|
||||
OBSDataArrayAutoRelease mappingsArray =
|
||||
obs_data_get_array(data, "varMappings");
|
||||
const size_t count = obs_data_array_count(mappingsArray);
|
||||
_varMappings.reserve(count);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
OBSDataAutoRelease item = obs_data_array_item(mappingsArray, i);
|
||||
VarMapping mapping;
|
||||
mapping.variable = GetWeakVariableByName(
|
||||
obs_data_get_string(item, "variable"));
|
||||
_varMappings.push_back(std::move(mapping));
|
||||
_varMappings.back().tempVar.Load(item, GetMacro(), "tempVar");
|
||||
}
|
||||
|
||||
ClearAvailableTempvars();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -226,11 +302,38 @@ MacroSegmentEdit::MacroSegmentEdit(QWidget *parent)
|
|||
_headerInfo(new QLabel()),
|
||||
_frame(new QWidget),
|
||||
_contentLayout(new QVBoxLayout),
|
||||
_outputMappings(new TempVarOutputMappingsWidget(this)),
|
||||
_varMappingToggle(new QPushButton(this)),
|
||||
_noBorderframe(new QFrame),
|
||||
_borderFrame(new QFrame),
|
||||
_dropLineAbove(new QFrame),
|
||||
_dropLineBelow(new QFrame)
|
||||
{
|
||||
const auto iconPath = QString::fromStdString(GetDataFilePath(
|
||||
"res/images/" + GetThemeTypeName() + "Variable.svg"));
|
||||
_varMappingToggle->setIcon(QIcon(iconPath));
|
||||
_varMappingToggle->setMaximumWidth(22);
|
||||
_varMappingToggle->setFlat(true);
|
||||
_varMappingToggle->setCheckable(true);
|
||||
_varMappingToggle->setVisible(false);
|
||||
_varMappingToggle->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.outputMappings.toggle"));
|
||||
|
||||
QWidget::connect(_varMappingToggle, &QPushButton::toggled,
|
||||
_outputMappings,
|
||||
&TempVarOutputMappingsWidget::SetPanelExpanded);
|
||||
QWidget::connect(_varMappingToggle, &QPushButton::toggled, this,
|
||||
[this](bool checked) {
|
||||
if (Data()) {
|
||||
Data()->SetVarMappingExpanded(checked);
|
||||
}
|
||||
});
|
||||
QWidget::connect(_outputMappings,
|
||||
&TempVarOutputMappingsWidget::ExpandableChanged,
|
||||
_varMappingToggle, &QPushButton::setVisible);
|
||||
QWidget::connect(_section, &Section::Collapsed, _outputMappings,
|
||||
&TempVarOutputMappingsWidget::SetSectionCollapsed);
|
||||
|
||||
_dropLineAbove->setLineWidth(3);
|
||||
_dropLineAbove->setFixedHeight(11);
|
||||
_dropLineBelow->setLineWidth(3);
|
||||
|
|
@ -292,6 +395,21 @@ MacroSegmentEdit::MacroSegmentEdit(QWidget *parent)
|
|||
_headerInfo->installEventFilter(this);
|
||||
}
|
||||
|
||||
void MacroSegmentEdit::SetupVarMappings(MacroSegment *segment)
|
||||
{
|
||||
_outputMappings->SetSegment(segment);
|
||||
_varMappingToggle->setChecked(segment &&
|
||||
segment->GetVarMappingExpanded());
|
||||
}
|
||||
|
||||
void MacroSegmentEdit::ShowVariableMappings(bool show)
|
||||
{
|
||||
_varMappingToggle->setChecked(show);
|
||||
if (Data()) {
|
||||
Data()->SetVarMappingExpanded(show);
|
||||
}
|
||||
}
|
||||
|
||||
bool MacroSegmentEdit::eventFilter(QObject *obj, QEvent *ev)
|
||||
{
|
||||
if (obj == _headerInfo && ev->type() == QEvent::MouseMove) {
|
||||
|
|
|
|||
|
|
@ -9,15 +9,23 @@
|
|||
|
||||
#include <QWidget>
|
||||
#include <QFrame>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QTimer>
|
||||
#include <obs-data.h>
|
||||
#include <memory>
|
||||
|
||||
class QLabel;
|
||||
|
||||
namespace advss {
|
||||
|
||||
class Macro;
|
||||
class Variable;
|
||||
|
||||
struct VarMapping {
|
||||
TempVariableRef tempVar;
|
||||
std::weak_ptr<Variable> variable;
|
||||
};
|
||||
|
||||
class EXPORT MacroSegment : public Lockable {
|
||||
public:
|
||||
|
|
@ -28,6 +36,8 @@ public:
|
|||
int GetIndex() const { return _idx; }
|
||||
void SetCollapsed(bool collapsed) { _collapsed = collapsed; }
|
||||
bool GetCollapsed() const { return _collapsed; }
|
||||
void SetVarMappingExpanded(bool expanded);
|
||||
bool GetVarMappingExpanded() const { return _varMappingExpanded; }
|
||||
void SetUseCustomLabel(bool enable) { _useCustomLabel = enable; }
|
||||
bool GetUseCustomLabel() const { return _useCustomLabel; }
|
||||
void SetCustomLabel(const std::string &label) { _customLabel = label; }
|
||||
|
|
@ -43,6 +53,10 @@ public:
|
|||
void SetEnabled(bool);
|
||||
bool Enabled() const;
|
||||
virtual std::string GetVariableValue() const;
|
||||
void ApplyVarMappings();
|
||||
const std::vector<VarMapping> &GetVarMappings() const;
|
||||
void SetVarMappings(const std::vector<VarMapping> &mappings);
|
||||
std::vector<TempVariable> GetOwnTempVars() const;
|
||||
|
||||
protected:
|
||||
friend bool SupportsVariableValue(MacroSegment *);
|
||||
|
|
@ -87,6 +101,7 @@ private:
|
|||
// UI helper
|
||||
bool _highlight = false;
|
||||
bool _collapsed = false;
|
||||
bool _varMappingExpanded = false;
|
||||
bool _enabled = true;
|
||||
|
||||
// Custom header labels
|
||||
|
|
@ -99,6 +114,7 @@ private:
|
|||
int _variableRefs = 0;
|
||||
std::string _variableValue;
|
||||
std::vector<TempVariable> _tempVariables;
|
||||
std::vector<VarMapping> _varMappings;
|
||||
|
||||
friend class Macro;
|
||||
};
|
||||
|
|
@ -118,8 +134,11 @@ public:
|
|||
virtual std::shared_ptr<MacroSegment> Data() const = 0;
|
||||
virtual void SetupWidgets(bool basicSetup = false) = 0;
|
||||
|
||||
void SetupVarMappings(MacroSegment *segment);
|
||||
|
||||
public slots:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
void ShowVariableMappings(bool show);
|
||||
|
||||
protected slots:
|
||||
void Collapsed(bool) const;
|
||||
|
|
@ -134,6 +153,8 @@ protected:
|
|||
QLabel *_headerInfo;
|
||||
QWidget *_frame;
|
||||
QVBoxLayout *_contentLayout;
|
||||
TempVarOutputMappingsWidget *_outputMappings;
|
||||
QPushButton *_varMappingToggle;
|
||||
bool _allWidgetsAreSetup = false;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ static bool checkCondition(const std::shared_ptr<MacroCondition> &condition)
|
|||
condition->WithLock([&condition, &conditionMatched]() {
|
||||
conditionMatched = condition->EvaluateCondition();
|
||||
});
|
||||
condition->ApplyVarMappings();
|
||||
const auto endTime = std::chrono::high_resolution_clock::now();
|
||||
const auto timeSpent = endTime - startTime;
|
||||
|
||||
|
|
@ -432,6 +433,7 @@ bool Macro::RunActionsHelper(
|
|||
action->WithLock([&action, &actionResult]() {
|
||||
actionResult = action->PerformAction();
|
||||
});
|
||||
action->ApplyVarMappings();
|
||||
actionsExecutedSuccessfully =
|
||||
actionsExecutedSuccessfully && actionResult;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,20 @@
|
|||
#include "macro-edit.hpp"
|
||||
#include "macro-segment.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "sync-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "variable.hpp"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QAbstractItemView>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QPushButton>
|
||||
#include <QToolButton>
|
||||
#include <QVariant>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
Q_DECLARE_METATYPE(advss::TempVariableRef);
|
||||
|
|
@ -731,4 +740,293 @@ void NotifyUIAboutTempVarChange(MacroSegment *segment)
|
|||
segment);
|
||||
}
|
||||
|
||||
TempVarOutputMappingsWidget::TempVarOutputMappingsWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
_rowsLayout(new QVBoxLayout()),
|
||||
_addButton(new QPushButton(
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.outputMappings.add"),
|
||||
this)),
|
||||
_animation(new QPropertyAnimation(this, "maximumHeight", this))
|
||||
{
|
||||
_rowsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
_rowsLayout->setSpacing(2);
|
||||
auto rowsContainer = new QWidget(this);
|
||||
rowsContainer->setLayout(_rowsLayout);
|
||||
|
||||
auto label = new QLabel(
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.outputMappings"),
|
||||
this);
|
||||
|
||||
auto mainLayout = new QVBoxLayout();
|
||||
mainLayout->addWidget(label);
|
||||
mainLayout->addWidget(rowsContainer);
|
||||
mainLayout->addWidget(_addButton);
|
||||
setLayout(mainLayout);
|
||||
|
||||
_animation->setDuration(300);
|
||||
_animation->setEasingCurve(QEasingCurve::InOutQuad);
|
||||
connect(_animation, &QPropertyAnimation::finished, this,
|
||||
&TempVarOutputMappingsWidget::AnimationFinished);
|
||||
|
||||
hide();
|
||||
|
||||
connect(_addButton, &QPushButton::clicked, this,
|
||||
&TempVarOutputMappingsWidget::Add);
|
||||
connect(TempVarSignalManager::Instance(),
|
||||
SIGNAL(SegmentTempVarsChanged(MacroSegment *)), this,
|
||||
SLOT(SegmentTempVarsChanged(MacroSegment *)));
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::SetSegment(MacroSegment *segment)
|
||||
{
|
||||
_segment = segment;
|
||||
_panelExpanded = false;
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::Add()
|
||||
{
|
||||
if (!_segment) {
|
||||
return;
|
||||
}
|
||||
auto mappings = _segment->GetVarMappings();
|
||||
mappings.push_back(VarMapping{});
|
||||
{
|
||||
auto lock = LockContext();
|
||||
_segment->SetVarMappings(mappings);
|
||||
}
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::Remove(int rowIdx)
|
||||
{
|
||||
if (!_segment) {
|
||||
return;
|
||||
}
|
||||
auto mappings = _segment->GetVarMappings();
|
||||
if (rowIdx < 0 || rowIdx >= (int)mappings.size()) {
|
||||
return;
|
||||
}
|
||||
mappings.erase(mappings.begin() + rowIdx);
|
||||
{
|
||||
auto lock = LockContext();
|
||||
_segment->SetVarMappings(mappings);
|
||||
}
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::SegmentTempVarsChanged(MacroSegment *segment)
|
||||
{
|
||||
if (segment != _segment) {
|
||||
return;
|
||||
}
|
||||
// Re-populate each temp var combobox in case temp vars were added/removed
|
||||
_loading = true;
|
||||
const auto &mappings = _segment->GetVarMappings();
|
||||
for (int i = 0; i < (int)_rows.size(); i++) {
|
||||
auto combo = _rows[i].tempVarCombo;
|
||||
const QSignalBlocker blocker(combo);
|
||||
combo->clear();
|
||||
PopulateTempVarCombo(combo);
|
||||
if (i < (int)mappings.size() &&
|
||||
mappings[i].tempVar.HasValidID()) {
|
||||
QVariant v;
|
||||
v.setValue(mappings[i].tempVar);
|
||||
combo->setCurrentIndex(combo->findData(v));
|
||||
}
|
||||
}
|
||||
_loading = false;
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::WriteBackMappings()
|
||||
{
|
||||
if (_loading || !_segment) {
|
||||
return;
|
||||
}
|
||||
std::vector<VarMapping> mappings;
|
||||
for (const auto &row : _rows) {
|
||||
VarMapping m;
|
||||
const int idx = row.tempVarCombo->currentIndex();
|
||||
if (idx >= 0) {
|
||||
m.tempVar = row.tempVarCombo->itemData(idx)
|
||||
.value<TempVariableRef>();
|
||||
}
|
||||
|
||||
auto item = row.varSelection->GetCurrentItem();
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m.variable = GetWeakVariableByName(item->Name());
|
||||
mappings.push_back(std::move(m));
|
||||
}
|
||||
auto lock = LockContext();
|
||||
_segment->SetVarMappings(mappings);
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::Rebuild()
|
||||
{
|
||||
_loading = true;
|
||||
|
||||
// Remove all existing row widgets from layout and delete them
|
||||
for (auto &row : _rows) {
|
||||
_rowsLayout->removeWidget(row.container);
|
||||
delete row.container;
|
||||
}
|
||||
_rows.clear();
|
||||
|
||||
if (!_segment) {
|
||||
_loading = false;
|
||||
UpdateVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &mappings = _segment->GetVarMappings();
|
||||
for (int i = 0; i < (int)mappings.size(); i++) {
|
||||
const auto &mapping = mappings[i];
|
||||
|
||||
auto container = new QWidget(this);
|
||||
auto rowLayout = new QHBoxLayout();
|
||||
rowLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
auto tempVarCombo = new FilterComboBox(
|
||||
container,
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.select"));
|
||||
tempVarCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
tempVarCombo->setMaximumWidth(350);
|
||||
tempVarCombo->setDuplicatesEnabled(true);
|
||||
PopulateTempVarCombo(tempVarCombo);
|
||||
if (mapping.tempVar.HasValidID()) {
|
||||
QVariant v;
|
||||
v.setValue(mapping.tempVar);
|
||||
tempVarCombo->setCurrentIndex(
|
||||
tempVarCombo->findData(v));
|
||||
}
|
||||
|
||||
auto arrowLabel = new QLabel(container);
|
||||
{
|
||||
QIcon icon;
|
||||
const auto path = (GetThemeTypeName() == "Light")
|
||||
? "theme:Light/right.svg"
|
||||
: "theme:Dark/right.svg";
|
||||
icon.addFile(QString::fromUtf8(path), QSize(),
|
||||
QIcon::Normal, QIcon::Off);
|
||||
arrowLabel->setPixmap(icon.pixmap(16, 16));
|
||||
}
|
||||
|
||||
auto varSel = new VariableSelection(container);
|
||||
varSel->SetVariable(mapping.variable);
|
||||
|
||||
auto removeBtn = new QToolButton(container);
|
||||
removeBtn->setProperty("themeID", QVariant(QString::fromUtf8(
|
||||
"removeIconSmall")));
|
||||
removeBtn->setProperty(
|
||||
"class", QVariant(QString::fromUtf8("icon-trash")));
|
||||
removeBtn->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.outputMappings.remove"));
|
||||
|
||||
rowLayout->addWidget(tempVarCombo, 1);
|
||||
rowLayout->addWidget(arrowLabel);
|
||||
rowLayout->addWidget(varSel, 1);
|
||||
rowLayout->addWidget(removeBtn);
|
||||
container->setLayout(rowLayout);
|
||||
|
||||
_rowsLayout->addWidget(container);
|
||||
_rows.push_back({container, tempVarCombo, varSel});
|
||||
|
||||
const int capturedIdx = i;
|
||||
connect(removeBtn, &QPushButton::clicked, this,
|
||||
[this, capturedIdx]() { Remove(capturedIdx); });
|
||||
connect(tempVarCombo,
|
||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &TempVarOutputMappingsWidget::WriteBackMappings);
|
||||
connect(varSel, &VariableSelection::SelectionChanged, this,
|
||||
[this](const QString &) { WriteBackMappings(); });
|
||||
}
|
||||
|
||||
_loading = false;
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
bool TempVarOutputMappingsWidget::IsExpandable() const
|
||||
{
|
||||
return _segment && !_segment->GetOwnTempVars().empty();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::SetPanelExpanded(bool expanded)
|
||||
{
|
||||
_panelExpanded = expanded;
|
||||
UpdateHeight();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::SetSectionCollapsed(bool collapsed)
|
||||
{
|
||||
_sectionCollapsed = collapsed;
|
||||
UpdateHeight();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::AnimateTo(int targetHeight)
|
||||
{
|
||||
if (_animation->state() == QAbstractAnimation::Running) {
|
||||
_animation->stop();
|
||||
}
|
||||
|
||||
if (targetHeight > 0 && !isVisible()) {
|
||||
setMinimumHeight(0);
|
||||
setMaximumHeight(0);
|
||||
show();
|
||||
}
|
||||
|
||||
const int currentMax = maximumHeight();
|
||||
const int currentHeight = (currentMax >= QWIDGETSIZE_MAX) ? height()
|
||||
: currentMax;
|
||||
|
||||
_animationTargetHeight = targetHeight;
|
||||
_animation->setStartValue(currentHeight);
|
||||
_animation->setEndValue(targetHeight);
|
||||
_animation->start();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::AnimationFinished()
|
||||
{
|
||||
if (_animationTargetHeight > 0) {
|
||||
setMaximumHeight(QWIDGETSIZE_MAX);
|
||||
} else {
|
||||
hide();
|
||||
setMaximumHeight(QWIDGETSIZE_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::UpdateHeight()
|
||||
{
|
||||
const bool shouldShow = _panelExpanded && !_sectionCollapsed &&
|
||||
IsExpandable();
|
||||
if (shouldShow) {
|
||||
AnimateTo(sizeHint().height());
|
||||
} else {
|
||||
AnimateTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::UpdateVisibility()
|
||||
{
|
||||
const bool expandable = IsExpandable();
|
||||
emit ExpandableChanged(expandable);
|
||||
UpdateHeight();
|
||||
}
|
||||
|
||||
void TempVarOutputMappingsWidget::PopulateTempVarCombo(
|
||||
FilterComboBox *combo) const
|
||||
{
|
||||
if (!_segment) {
|
||||
return;
|
||||
}
|
||||
for (const auto &var : _segment->GetOwnTempVars()) {
|
||||
QVariant v;
|
||||
v.setValue(var.GetRef());
|
||||
combo->addItem(QString::fromStdString(var.Name()), v);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@
|
|||
#include <obs-data.h>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <QEnterEvent>
|
||||
#include <QEvent>
|
||||
#include <QStringList>
|
||||
#include <string>
|
||||
|
||||
class QPropertyAnimation;
|
||||
class QPushButton;
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace advss {
|
||||
|
||||
class Macro;
|
||||
|
|
@ -17,6 +18,9 @@ class MacroEdit;
|
|||
class MacroSegment;
|
||||
class TempVariableRef;
|
||||
class TempVariableSelection;
|
||||
class TempVarOutputMappingsWidget;
|
||||
class VariableSelection;
|
||||
struct VarMapping;
|
||||
|
||||
// TempVariables are variables that are local to a given macro.
|
||||
// They can be created and used by macro segments.
|
||||
|
|
@ -127,4 +131,48 @@ private:
|
|||
void NotifyUIAboutTempVarChange(MacroSegment *);
|
||||
EXPORT void IncrementTempVarInUseGeneration();
|
||||
|
||||
class ADVSS_EXPORT TempVarOutputMappingsWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TempVarOutputMappingsWidget(QWidget *parent);
|
||||
void SetSegment(MacroSegment *segment);
|
||||
void SetPanelExpanded(bool expanded);
|
||||
void SetSectionCollapsed(bool collapsed);
|
||||
bool IsExpandable() const;
|
||||
|
||||
signals:
|
||||
void ExpandableChanged(bool);
|
||||
|
||||
private slots:
|
||||
void Add();
|
||||
void Remove(int rowIdx);
|
||||
void SegmentTempVarsChanged(MacroSegment *segment);
|
||||
void WriteBackMappings();
|
||||
void AnimationFinished();
|
||||
|
||||
private:
|
||||
void Rebuild();
|
||||
void UpdateVisibility();
|
||||
void UpdateHeight();
|
||||
void AnimateTo(int targetHeight);
|
||||
void PopulateTempVarCombo(FilterComboBox *combo) const;
|
||||
|
||||
struct MappingRow {
|
||||
QWidget *container;
|
||||
FilterComboBox *tempVarCombo;
|
||||
VariableSelection *varSelection;
|
||||
};
|
||||
|
||||
MacroSegment *_segment = nullptr;
|
||||
QVBoxLayout *_rowsLayout;
|
||||
QPushButton *_addButton;
|
||||
std::vector<MappingRow> _rows;
|
||||
bool _loading = false;
|
||||
bool _panelExpanded = false;
|
||||
bool _sectionCollapsed = false;
|
||||
int _animationTargetHeight = 0;
|
||||
QPropertyAnimation *_animation;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@ const std::string MacroActionFilter::id = "filter";
|
|||
|
||||
std::vector<TempVariableRef> MacroActionFilter::GetTempVarRefs() const
|
||||
{
|
||||
if (!_tempVar.HasValidID()) {
|
||||
return {};
|
||||
auto refs = MacroSegment::GetTempVarRefs();
|
||||
if (_tempVar.HasValidID()) {
|
||||
refs.push_back(_tempVar);
|
||||
}
|
||||
return {_tempVar};
|
||||
return refs;
|
||||
}
|
||||
|
||||
bool MacroActionFilter::_registered = MacroActionFactory::Register(
|
||||
|
|
|
|||
|
|
@ -15,10 +15,11 @@ const std::string MacroActionSource::id = "source";
|
|||
|
||||
std::vector<TempVariableRef> MacroActionSource::GetTempVarRefs() const
|
||||
{
|
||||
if (!_tempVar.HasValidID()) {
|
||||
return {};
|
||||
auto refs = MacroSegment::GetTempVarRefs();
|
||||
if (_tempVar.HasValidID()) {
|
||||
refs.push_back(_tempVar);
|
||||
}
|
||||
return {_tempVar};
|
||||
return refs;
|
||||
}
|
||||
|
||||
bool MacroActionSource::_registered = MacroActionFactory::Register(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user