Compare commits

...

14 Commits

Author SHA1 Message Date
WarmUpTill
0ee6feb529 Add option to check the current stream key
Some checks failed
debian-build / build (push) Has been cancelled
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-10-26 23:42:59 +02:00
WarmUpTill
3b82b55090 Fix Queue condition not displaying the correct size selection 2024-10-26 23:42:59 +02:00
WarmUpTill
071c3309c2 Add option to check current streaming service
Some checks are pending
debian-build / build (push) Waiting to run
Check locale / ubuntu64 (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
2024-10-26 11:09:06 +02:00
WarmUpTill
ee7ee7a846 Move AutoUpdateTooltipLabel definition 2024-10-26 11:09:06 +02:00
WarmUpTill
d10300bd4b Fix typo 2024-10-26 11:09:06 +02:00
WarmUpTill
e262672876 Add "Last empty" row to Queue tab 2024-10-26 11:08:51 +02:00
WarmUpTill
392e775c7b Add temp var support for size and running state 2024-10-26 11:08:51 +02:00
WarmUpTill
f641c20564 Add SetTempVarValue() overload to support boolean values 2024-10-26 11:08:51 +02:00
WarmUpTill
39327be88e Add option to move scene item above / below specified scene item
Some checks failed
debian-build / build (push) Has been cancelled
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-10-21 20:46:27 +02:00
WarmUpTill
ed0963799c Fix "Screenshot" action variable selection not being loaded
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-10-18 18:30:49 +02:00
WarmUpTill
f9e73a2b8f Fix crash when clearing Twitch chat buffer 2024-10-18 18:29:46 +02:00
Przemek Pawlas
dfaa704b71 Remove some unused includes 2024-10-12 17:09:33 +02:00
Przemek Pawlas
d54edddde4 Enable use of variables as input for "Variable" action 2024-10-12 17:09:33 +02:00
Przemek Pawlas
37cc289204 Rename function 2024-10-12 17:09:33 +02:00
51 changed files with 647 additions and 287 deletions

View File

@@ -157,6 +157,8 @@ target_sources(
lib/queue/action-queue.hpp
lib/queue/action-queue-tab.cpp
lib/queue/action-queue-tab.hpp
lib/utils/auto-update-tooltip-label.cpp
lib/utils/auto-update-tooltip-label.hpp
lib/utils/backup.cpp
lib/utils/backup.hpp
lib/utils/condition-logic.cpp

View File

@@ -212,7 +212,6 @@ AdvSceneSwitcher.condition.stream.state.start="Stream läuft"
AdvSceneSwitcher.condition.stream.state.stop="Stream gestoppt"
AdvSceneSwitcher.condition.stream.state.starting="Stream wird gestartet"
AdvSceneSwitcher.condition.stream.state.stopping="Stream wird gestoppt"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Aufnahme"
AdvSceneSwitcher.condition.record.state.start="Aufnahme läuft"
AdvSceneSwitcher.condition.record.state.pause="Aufnahme pausiert"
@@ -490,7 +489,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Nach unten verschieben"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="An erste Stelle verschieben"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="An letzte Stelle verschieben"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="An Position verschieben"
AdvSceneSwitcher.action.sceneOrder.entry="Auf{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="Auf{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="Szenenelement transformieren"
AdvSceneSwitcher.action.sceneTransform.getTransform="Transformation erhalten"
AdvSceneSwitcher.action.sceneTransform.entry="Auf{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"

View File

@@ -97,6 +97,7 @@ AdvSceneSwitcher.actionQueueTab.queueAddButton.tooltip="Add new action queue"
AdvSceneSwitcher.actionQueueTab.queueRemoveButton.tooltip="Remove selected action queues"
AdvSceneSwitcher.actionQueueTab.name.header="Name"
AdvSceneSwitcher.actionQueueTab.size.header="Size"
AdvSceneSwitcher.actionQueueTab.lastEmpty.header="Last empty"
AdvSceneSwitcher.actionQueueTab.isRunning.header="Is running"
AdvSceneSwitcher.actionQueueTab.runOnStartup.header="Run on startup"
AdvSceneSwitcher.actionQueueTab.yes="Yes"
@@ -418,7 +419,10 @@ AdvSceneSwitcher.condition.stream.state.stop="Stream stopped"
AdvSceneSwitcher.condition.stream.state.starting="Stream starting"
AdvSceneSwitcher.condition.stream.state.stopping="Stream stopping"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="Keyframe interval equals"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.stream.state.streamKey="Stream key is"
AdvSceneSwitcher.condition.stream.state.service="Service name matches"
AdvSceneSwitcher.condition.stream.service.tooltip="Current service name: %1"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}{{streamKey}}{{serviceName}}{{regex}}{{currentService}}"
AdvSceneSwitcher.condition.record="Recording"
AdvSceneSwitcher.condition.record.state.start="Recording running"
AdvSceneSwitcher.condition.record.state.pause="Recording paused"
@@ -956,7 +960,9 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Move to top"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position"
AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.type.above="Move above"
AdvSceneSwitcher.action.sceneOrder.type.below="Move below"
AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}{{sources2}}"
AdvSceneSwitcher.action.sceneTransform="Scene item transform"
AdvSceneSwitcher.action.sceneTransform.type.manual="Set transform string"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="Set transform setting"
@@ -1877,8 +1883,11 @@ AdvSceneSwitcher.tempVar.display.height.description="The height of the display w
AdvSceneSwitcher.tempVar.streaming.keyframeInterval="Stream keyframe interval"
AdvSceneSwitcher.tempVar.streaming.keyframeInterval.description="Stream keyframe interval configured in the OBS settings."
AdvSceneSwitcher.tempVar.streaming.streamKey="Stream key"
AdvSceneSwitcher.tempVar.streaming.durationSeconds="Stream duration"
AdvSceneSwitcher.tempVar.streaming.durationSeconds.description="Seconds passed since the stream was started.\nThis value will be zero if the stream is stopped."
AdvSceneSwitcher.tempVar.streaming.serviceName="Service"
AdvSceneSwitcher.tempVar.streaming.serviceName.description="The name of the streaming service being streamed to (e.g. Twitch)"
AdvSceneSwitcher.tempVar.clipboard.text="Clipboard text"
AdvSceneSwitcher.tempVar.clipboard.text.description="The text contained in the clipboard.\nWill be empty if the clipboard does not contain text."
@@ -1958,6 +1967,10 @@ AdvSceneSwitcher.tempVar.streamDeck.column="Key column"
AdvSceneSwitcher.tempVar.streamDeck.data="Data"
AdvSceneSwitcher.tempVar.streamDeck.data.description="The value of the \"Data\" field configured in the action on the Stream Deck side."
AdvSceneSwitcher.tempVar.queue.size="Size"
AdvSceneSwitcher.tempVar.queue.running="Is running"
AdvSceneSwitcher.tempVar.queue.running.description="Returns \"true\" if the queue is started and \"false\" if it is stopped."
AdvSceneSwitcher.selectScene="--select scene--"
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
AdvSceneSwitcher.selectCurrentScene="Current Scene"

View File

@@ -172,7 +172,6 @@ AdvSceneSwitcher.condition.stream.state.start="Transmisión en ejecución"
AdvSceneSwitcher.condition.stream.state.stop="Transmisión detenida"
AdvSceneSwitcher.condition.stream.state.starting="Inicio de transmisión"
AdvSceneSwitcher.condition.stream.state.stopping="Detener transmisión"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Grabación"
AdvSceneSwitcher.condition.record.state.start="Grabación en ejecución"
AdvSceneSwitcher.condition.record.state.pause="Grabación en pausa"
@@ -407,7 +406,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover hacia abajo"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Mover al principio"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Mover al final"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Mover a la posición"
AdvSceneSwitcher.action.sceneOrder.entry="En{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="En{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="Transformar elemento de escena"
AdvSceneSwitcher.action.sceneTransform.getTransform="Obtener transformación"
AdvSceneSwitcher.action.sceneTransform.entry="En{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"

View File

@@ -597,7 +597,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Déplacer vers le bas"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Déplacer en haut"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Déplacer en bas"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Déplacer à la position"
AdvSceneSwitcher.action.sceneOrder.entry="Sur{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="Sur{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="Transformation de l'élément de la scène"
AdvSceneSwitcher.action.sceneTransform.type.manual="Transform"
AdvSceneSwitcher.action.sceneTransform.type.reset="Réinitialiser la transformation"

View File

@@ -925,7 +925,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="下へ移動"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="トップへ移動"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="一番下へ移動"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="ポジションへの移動"
AdvSceneSwitcher.action.sceneOrder.entry="オン{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="オン{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="シーンアイテムの変形"
AdvSceneSwitcher.action.sceneTransform.type.manual="変形"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="トランスフォーム設定を行う"

View File

@@ -395,7 +395,6 @@ AdvSceneSwitcher.condition.stream.state.stop="Streaming parado"
AdvSceneSwitcher.condition.stream.state.starting="Iniciando o streaming"
AdvSceneSwitcher.condition.stream.state.stopping="Parando o streaming"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="Intervalo de keyframe igual a"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Gravação"
AdvSceneSwitcher.condition.record.state.start="Gravação em execução"
AdvSceneSwitcher.condition.record.state.pause="Gravação pausada"
@@ -907,7 +906,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover para baixo"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Mover para o topo"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Mover para o fundo"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Mover para posição"
AdvSceneSwitcher.action.sceneOrder.entry="Em{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="Em{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="Transformação de item de cena"
AdvSceneSwitcher.action.sceneTransform.type.manual="Definir string de transformação"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="Definir configuração de transformação"

View File

@@ -149,7 +149,6 @@ AdvSceneSwitcher.condition.stream.state.start="Yayın çalışıyor"
AdvSceneSwitcher.condition.stream.state.stop="Yayın durdu"
AdvSceneSwitcher.condition.stream.state.starting="Yayın başlıyor"
AdvSceneSwitcher.condition.stream.state.stopping="Yayın duruyor"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Kayıt"
AdvSceneSwitcher.condition.record.state.start="Kayıt Çalışıyor"
AdvSceneSwitcher.condition.record.state.pause="Kayıt durakladı"
@@ -336,7 +335,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Aşağı indir"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="En üste taşı"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Aşağıya taşı"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Konuma taşı"
AdvSceneSwitcher.action.sceneOrder.entry="Açık{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="Açık{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="Sahne öğesi dönüşümü"
AdvSceneSwitcher.action.sceneTransform.getTransform="Dönüşümü al"
AdvSceneSwitcher.action.sceneTransform.entry="Açık{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"

View File

@@ -257,7 +257,6 @@ AdvSceneSwitcher.condition.stream.state.stop="推流停止"
AdvSceneSwitcher.condition.stream.state.starting="推流启动中"
AdvSceneSwitcher.condition.stream.state.stopping="推流停止中"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="关键帧间隔等于"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="录制"
AdvSceneSwitcher.condition.record.state.start="录制运行中"
AdvSceneSwitcher.condition.record.state.pause="录制暂停"
@@ -547,7 +546,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="顶部"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="底部"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="移动到数值位置"
AdvSceneSwitcher.action.sceneOrder.entry="在 {{scenes}} {{actions}} {{sources}} {{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="在{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="场景项目转换"
AdvSceneSwitcher.action.sceneTransform.getTransform="获得转换"
AdvSceneSwitcher.action.sceneTransform.entry="在{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"

View File

@@ -105,16 +105,20 @@ MacroActionVariable::~MacroActionVariable()
void MacroActionVariable::HandleIndexSubString(Variable *var)
{
const auto curValue = var->Value();
const auto subStringSize = _subStringSize.GetValue();
const auto subStringStart = _subStringStart.GetValue() - 1;
try {
if (_subStringSize == 0) {
var->SetValue(curValue.substr(_subStringStart));
if (subStringSize == 0) {
var->SetValue(curValue.substr(subStringStart));
return;
}
var->SetValue(curValue.substr(_subStringStart, _subStringSize));
var->SetValue(curValue.substr(subStringStart, subStringSize));
} catch (const std::out_of_range &) {
vblog(LOG_WARNING,
"invalid start index \"%d\" selected for substring of \"%s\" of variable \"%s\"",
_subStringStart, curValue.c_str(), var->Name().c_str());
subStringStart, curValue.c_str(), var->Name().c_str());
}
}
@@ -127,7 +131,8 @@ void MacroActionVariable::HandleRegexSubString(Variable *var)
}
auto it = regex.globalMatch(QString::fromStdString(curValue));
for (int idx = 0; idx < _regexMatchIdx; idx++) {
const auto regexMatchIndex = _regexMatchIdx.GetValue() - 1;
for (int idx = 0; idx < regexMatchIndex; idx++) {
if (!it.hasNext()) {
return;
}
@@ -324,10 +329,10 @@ bool MacroActionVariable::PerformAction()
break;
}
case Type::INCREMENT:
modifyNumValue(*var, _numValue, true);
modifyNumValue(*var, _numValue.GetValue(), true);
break;
case Type::DECREMENT:
modifyNumValue(*var, _numValue, false);
modifyNumValue(*var, _numValue.GetValue(), false);
break;
case Type::SET_CONDITION_VALUE:
case Type::SET_ACTION_VALUE: {
@@ -473,13 +478,13 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
obs_data_set_string(obj, "variable2Name",
GetWeakVariableName(_variable2).c_str());
_strValue.Save(obj, "strValue");
obs_data_set_double(obj, "numValue", _numValue);
_numValue.Save(obj, "numValue");
obs_data_set_int(obj, "condition", static_cast<int>(_type));
obs_data_set_int(obj, "segmentIdx", GetSegmentIndexValue());
obs_data_set_int(obj, "subStringStart", _subStringStart);
obs_data_set_int(obj, "subStringSize", _subStringSize);
_subStringStart.Save(obj, "subStringStart");
_subStringSize.Save(obj, "subStringSize");
obs_data_set_string(obj, "regexPattern", _regexPattern.c_str());
obs_data_set_int(obj, "regexMatchIdx", _regexMatchIdx);
_regexMatchIdx.Save(obj, "regexMatchIdx");
_findRegex.Save(obj, "findRegex");
_findStr.Save(obj, "findStr");
_replaceStr.Save(obj, "replaceStr");
@@ -498,6 +503,8 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
obs_data_set_int(obj, "paddingChar", _paddingChar);
obs_data_set_int(obj, "caseType", static_cast<int>(_caseType));
obs_data_set_int(obj, "version", 1);
return true;
}
@@ -509,14 +516,10 @@ bool MacroActionVariable::Load(obs_data_t *obj)
_variable2 = GetWeakVariableByName(
obs_data_get_string(obj, "variable2Name"));
_strValue.Load(obj, "strValue");
_numValue = obs_data_get_double(obj, "numValue");
_type = static_cast<Type>(obs_data_get_int(obj, "condition"));
_segmentIdxLoadValue = obs_data_get_int(obj, "segmentIdx");
_subStringStart = obs_data_get_int(obj, "subStringStart");
_subStringSize = obs_data_get_int(obj, "subStringSize");
_subStringRegex.Load(obj);
_regexPattern = obs_data_get_string(obj, "regexPattern");
_regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx");
_findRegex.Load(obj, "findRegex");
_findStr.Load(obj, "findStr");
_replaceStr.Load(obj, "replaceStr");
@@ -538,6 +541,20 @@ bool MacroActionVariable::Load(obs_data_t *obj)
}
_caseType = static_cast<CaseType>(obs_data_get_int(obj, "caseType"));
// Convert old data format
// TODO: Remove in future version
if (!obs_data_has_user_value(obj, "version")) {
_numValue = obs_data_get_double(obj, "numValue");
_subStringStart = obs_data_get_int(obj, "subStringStart") + 1;
_subStringSize = obs_data_get_int(obj, "subStringSize");
_regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx") + 1;
} else {
_numValue.Load(obj, "numValue");
_subStringStart.Load(obj, "subStringStart");
_subStringSize.Load(obj, "subStringSize");
_regexMatchIdx.Load(obj, "regexMatchIdx");
}
return true;
}
@@ -681,7 +698,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
_variables2(new VariableSelection(this)),
_actions(new FilterComboBox(this)),
_strValue(new VariableTextEdit(this, 5, 1, 1)),
_numValue(new QDoubleSpinBox()),
_numValue(new VariableDoubleSpinBox(this)),
_segmentIdx(new MacroSegmentSelection(
this, MacroSegmentSelection::Type::CONDITION, false)),
_segmentValueStatus(new QLabel()),
@@ -689,11 +706,11 @@ MacroActionVariableEdit::MacroActionVariableEdit(
_substringLayout(new QVBoxLayout()),
_subStringIndexEntryLayout(new QHBoxLayout()),
_subStringRegexEntryLayout(new QHBoxLayout()),
_subStringStart(new QSpinBox()),
_subStringSize(new QSpinBox()),
_subStringStart(new VariableSpinBox(this)),
_subStringSize(new VariableSpinBox(this)),
_substringRegex(new RegexConfigWidget(parent)),
_regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)),
_regexMatchIdx(new QSpinBox()),
_regexMatchIdx(new VariableSpinBox(this)),
_findReplaceLayout(new QHBoxLayout()),
_findRegex(new RegexConfigWidget()),
_findStr(new VariableTextEdit(this, 10, 1, 1)),
@@ -712,9 +729,9 @@ MacroActionVariableEdit::MacroActionVariableEdit(
_tempVars(new TempVariableSelection(this)),
_tempVarsHelp(new HelpIcon(obs_module_text(
"AdvSceneSwitcher.action.variable.type.setToTempvar.help"))),
_sceneItemIndex(new VariableSpinBox()),
_sceneItemIndex(new VariableSpinBox(this)),
_direction(new QComboBox()),
_stringLength(new VariableSpinBox()),
_stringLength(new VariableSpinBox(this)),
_paddingCharSelection(new SingleCharSelection()),
_caseType(new FilterComboBox(this)),
_entryLayout(new QHBoxLayout())
@@ -751,24 +768,32 @@ MacroActionVariableEdit::MacroActionVariableEdit(
SLOT(ActionChanged(int)));
QWidget::connect(_strValue, SIGNAL(textChanged()), this,
SLOT(StrValueChanged()));
QWidget::connect(_numValue, SIGNAL(valueChanged(double)), this,
SLOT(NumValueChanged(double)));
QWidget::connect(
_numValue,
SIGNAL(NumberVariableChanged(const NumberVariable<double> &)),
this, SLOT(NumValueChanged(const NumberVariable<double> &)));
QWidget::connect(_segmentIdx,
SIGNAL(SelectionChanged(const IntVariable &)), this,
SLOT(SegmentIndexChanged(const IntVariable &)));
QWidget::connect(window(), SIGNAL(MacroSegmentOrderChanged()), this,
SLOT(MacroSegmentOrderChanged()));
QWidget::connect(_subStringStart, SIGNAL(valueChanged(int)), this,
SLOT(SubStringStartChanged(int)));
QWidget::connect(_subStringSize, SIGNAL(valueChanged(int)), this,
SLOT(SubStringSizeChanged(int)));
QWidget::connect(
_subStringStart,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(SubStringStartChanged(const NumberVariable<int> &)));
QWidget::connect(
_subStringSize,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(SubStringSizeChanged(const NumberVariable<int> &)));
QWidget::connect(_substringRegex,
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
SLOT(SubStringRegexChanged(const RegexConfig &)));
QWidget::connect(_regexPattern, SIGNAL(textChanged()), this,
SLOT(RegexPatternChanged()));
QWidget::connect(_regexMatchIdx, SIGNAL(valueChanged(int)), this,
SLOT(RegexMatchIdxChanged(int)));
QWidget::connect(
_regexMatchIdx,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(RegexMatchIdxChanged(const NumberVariable<int> &)));
QWidget::connect(_findRegex,
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
SLOT(FindRegexChanged(const RegexConfig &)));
@@ -906,7 +931,7 @@ void MacroActionVariableEdit::UpdateEntryData()
_actions->setCurrentIndex(
_actions->findData(static_cast<int>(_entryData->_type)));
_strValue->setPlainText(_entryData->_strValue);
_numValue->setValue(_entryData->_numValue);
_numValue->SetValue(_entryData->_numValue);
_segmentIdx->SetValue(_entryData->GetSegmentIndexValue() + 1);
_segmentIdx->SetMacro(_entryData->GetMacro());
_segmentIdx->SetType(
@@ -914,13 +939,13 @@ void MacroActionVariableEdit::UpdateEntryData()
MacroActionVariable::Type::SET_CONDITION_VALUE
? MacroSegmentSelection::Type::CONDITION
: MacroSegmentSelection::Type::ACTION);
_subStringStart->setValue(_entryData->_subStringStart + 1);
_subStringSize->setValue(_entryData->_subStringSize);
_subStringStart->SetValue(_entryData->_subStringStart);
_subStringSize->SetValue(_entryData->_subStringSize);
_substringRegex->SetRegexConfig(_entryData->_subStringRegex);
_findRegex->SetRegexConfig(_entryData->_findRegex);
_regexPattern->setPlainText(
QString::fromStdString(_entryData->_regexPattern));
_regexMatchIdx->setValue(_entryData->_regexMatchIdx + 1);
_regexMatchIdx->SetValue(_entryData->_regexMatchIdx);
_findStr->setPlainText(_entryData->_findStr);
_replaceStr->setPlainText(_entryData->_replaceStr);
_mathExpression->setText(_entryData->_mathExpression);
@@ -995,14 +1020,15 @@ void MacroActionVariableEdit::StrValueChanged()
updateGeometry();
}
void MacroActionVariableEdit::NumValueChanged(double val)
void MacroActionVariableEdit::NumValueChanged(
const NumberVariable<double> &value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_numValue = val;
_entryData->_numValue = value;
}
void MacroActionVariableEdit::SegmentIndexChanged(const IntVariable &val)
@@ -1113,24 +1139,26 @@ void MacroActionVariableEdit::MacroSegmentOrderChanged()
_segmentIdx->SetValue(_entryData->GetSegmentIndexValue() + 1);
}
void MacroActionVariableEdit::SubStringStartChanged(int val)
void MacroActionVariableEdit::SubStringStartChanged(
const NumberVariable<int> &start)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_subStringStart = val - 1;
_entryData->_subStringStart = start;
}
void MacroActionVariableEdit::SubStringSizeChanged(int val)
void MacroActionVariableEdit::SubStringSizeChanged(
const NumberVariable<int> &size)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_subStringSize = val;
_entryData->_subStringSize = size;
}
void MacroActionVariableEdit::SubStringRegexChanged(const RegexConfig &conf)
@@ -1157,14 +1185,15 @@ void MacroActionVariableEdit::RegexPatternChanged()
updateGeometry();
}
void MacroActionVariableEdit::RegexMatchIdxChanged(int val)
void MacroActionVariableEdit::RegexMatchIdxChanged(
const NumberVariable<int> &index)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_regexMatchIdx = val - 1;
_entryData->_regexMatchIdx = index;
}
void MacroActionVariableEdit::FindStrValueChanged()

View File

@@ -58,12 +58,12 @@ public:
std::weak_ptr<Variable> _variable;
std::weak_ptr<Variable> _variable2;
StringVariable _strValue = "";
double _numValue = 0;
int _subStringStart = 0;
int _subStringSize = 0;
DoubleVariable _numValue = 0;
IntVariable _subStringStart = 0;
IntVariable _subStringSize = 0;
RegexConfig _subStringRegex = RegexConfig::PartialMatchRegexConfig();
std::string _regexPattern = ".*";
int _regexMatchIdx = 0;
IntVariable _regexMatchIdx = 0;
RegexConfig _findRegex;
StringVariable _findStr = obs_module_text(
"AdvSceneSwitcher.action.variable.findAndReplace.find");
@@ -136,15 +136,15 @@ private slots:
void Variable2Changed(const QString &);
void ActionChanged(int);
void StrValueChanged();
void NumValueChanged(double);
void NumValueChanged(const NumberVariable<double> &value);
void SegmentIndexChanged(const IntVariable &);
void UpdateSegmentVariableValue();
void MacroSegmentOrderChanged();
void SubStringStartChanged(int val);
void SubStringSizeChanged(int val);
void SubStringStartChanged(const NumberVariable<int> &start);
void SubStringSizeChanged(const NumberVariable<int> &size);
void SubStringRegexChanged(const RegexConfig &conf);
void RegexPatternChanged();
void RegexMatchIdxChanged(int val);
void RegexMatchIdxChanged(const NumberVariable<int> &index);
void FindStrValueChanged();
void FindRegexChanged(const RegexConfig &conf);
void ReplaceStrValueChanged();
@@ -173,18 +173,18 @@ private:
VariableSelection *_variables2;
FilterComboBox *_actions;
VariableTextEdit *_strValue;
QDoubleSpinBox *_numValue;
VariableDoubleSpinBox *_numValue;
MacroSegmentSelection *_segmentIdx;
QLabel *_segmentValueStatus;
ResizingPlainTextEdit *_segmentValue;
QVBoxLayout *_substringLayout;
QHBoxLayout *_subStringIndexEntryLayout;
QHBoxLayout *_subStringRegexEntryLayout;
QSpinBox *_subStringStart;
QSpinBox *_subStringSize;
VariableSpinBox *_subStringStart;
VariableSpinBox *_subStringSize;
RegexConfigWidget *_substringRegex;
ResizingPlainTextEdit *_regexPattern;
QSpinBox *_regexMatchIdx;
VariableSpinBox *_regexMatchIdx;
QHBoxLayout *_findReplaceLayout;
RegexConfigWidget *_findRegex;
VariableTextEdit *_findStr;

View File

@@ -27,6 +27,9 @@ bool MacroConditionQueue::CheckCondition()
return false;
}
SetTempVarValue("size", std::to_string(queue->Size()));
SetTempVarValue("running", queue->IsRunning());
switch (_condition) {
case Condition::STARTED:
return queue->IsRunning();
@@ -63,6 +66,18 @@ std::string MacroConditionQueue::GetShortDesc() const
return GetActionQueueName(_queue);
}
void MacroConditionQueue::SetupTempVars()
{
MacroCondition::SetupTempVars();
AddTempvar("size",
obs_module_text("AdvSceneSwitcher.tempVar.queue.size"));
AddTempvar(
"running",
obs_module_text("AdvSceneSwitcher.tempVar.queue.running"),
obs_module_text(
"AdvSceneSwitcher.tempVar.queue.running.description"));
}
static inline void populateQueueTypeSelection(QComboBox *list)
{
for (const auto &[_, name] : conditionTypes) {
@@ -141,6 +156,7 @@ void MacroConditionQueueEdit::UpdateEntryData()
}
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
_queues->SetActionQueue(_entryData->_queue);
_size->SetValue(_entryData->_size);
SetWidgetVisibility();
}

View File

@@ -32,6 +32,8 @@ public:
IntVariable _size = 1;
private:
void SetupTempVars();
static bool _registered;
static const std::string id;
};

View File

@@ -21,7 +21,7 @@ MacroSegmentSelection::MacroSegmentSelection(QWidget *parent, Type type,
{
_index->setMinimum(0);
_index->setMaximum(99);
_index->specialValueText("-");
_index->setSpecialValueText("-");
if (!allowVariables) {
_index->DisableVariableSelection();
}

View File

@@ -51,8 +51,17 @@ protected:
virtual void SetupTempVars();
void AddTempvar(const std::string &id, const std::string &name,
const std::string &description = "");
void SetTempVarValue(const std::string &id, const std::string &value);
template<typename T, typename = std::enable_if_t<
std::is_same<std::decay_t<T>, bool>::value>>
void SetTempVarValue(const std::string &id, T value)
{
SetTempVarValue(id, value ? std::string("true")
: std::string("false"));
}
private:
void ClearAvailableTempvars();
std::optional<const TempVariable>

View File

@@ -5,6 +5,7 @@
#include "plugin-state-helpers.hpp"
#include "sync-helpers.hpp"
#include "tab-helpers.hpp"
#include "time-helpers.hpp"
#include "ui-helpers.hpp"
#include <QTimer>
@@ -55,6 +56,13 @@ void ActionQueueTable::Add()
QString::fromStdString(newQueue->Name()));
}
static double getSecondsSinceLastEmpty(ActionQueue *queue)
{
const auto time = std::chrono::high_resolution_clock::now() -
queue->GetLastEmptyTime();
return std::chrono::duration_cast<std::chrono::seconds>(time).count();
}
static QStringList getCellLabels(ActionQueue *queue, bool addName = true)
{
assert(queue);
@@ -64,6 +72,7 @@ static QStringList getCellLabels(ActionQueue *queue, bool addName = true)
result << QString::fromStdString(queue->Name());
}
result << QString::number(queue->Size())
<< FormatRelativeTime(getSecondsSinceLastEmpty(queue))
<< QString::fromStdString(obs_module_text(
queue->IsRunning()
? "AdvSceneSwitcher.actionQueueTab.yes"
@@ -199,6 +208,8 @@ ActionQueueTable::ActionQueueTable(QTabWidget *parent)
"AdvSceneSwitcher.actionQueueTab.name.header")
<< obs_module_text(
"AdvSceneSwitcher.actionQueueTab.size.header")
<< obs_module_text(
"AdvSceneSwitcher.actionQueueTab.lastEmpty.header")
<< obs_module_text(
"AdvSceneSwitcher.actionQueueTab.isRunning.header")
<< obs_module_text(

View File

@@ -26,7 +26,10 @@ void SetupActionQueues()
done = true;
}
ActionQueue::ActionQueue() : Item() {}
ActionQueue::ActionQueue() : Item()
{
_lastEmpty = std::chrono::high_resolution_clock::now();
}
ActionQueue::~ActionQueue()
{
@@ -124,6 +127,14 @@ bool ActionQueue::IsEmpty()
return _actions.empty();
}
ActionQueue::TimePoint ActionQueue::GetLastEmptyTime()
{
if (IsEmpty()) {
_lastEmpty = std::chrono::high_resolution_clock::now();
}
return _lastEmpty;
}
size_t ActionQueue::Size()
{
std::lock_guard<std::mutex> lock(_mutex);
@@ -137,6 +148,8 @@ void ActionQueue::RunActions()
{ // Grab next action to run
std::unique_lock<std::mutex> lock(_mutex);
while (_actions.empty() && !_stop) {
_lastEmpty =
std::chrono::high_resolution_clock::now();
_cv.wait(lock);
}

View File

@@ -2,11 +2,12 @@
#include "item-selection-helpers.hpp"
#include "macro-action.hpp"
#include <chrono>
#include <condition_variable>
#include <deque>
#include <obs-data.h>
#include <QCheckBox>
#include <thread>
#include <condition_variable>
namespace advss {
@@ -14,6 +15,8 @@ class ActionQueueSelection;
class ActionQueueSettingsDialog;
class ActionQueue : public Item {
using TimePoint = std::chrono::high_resolution_clock::time_point;
public:
ActionQueue();
~ActionQueue();
@@ -30,6 +33,7 @@ public:
void Clear();
bool IsEmpty();
TimePoint GetLastEmptyTime();
void Add(const std::shared_ptr<MacroAction> &);
size_t Size();
@@ -44,6 +48,7 @@ private:
std::condition_variable _cv;
std::thread _thread;
std::deque<std::shared_ptr<MacroAction>> _actions;
TimePoint _lastEmpty;
friend ActionQueueSelection;
friend ActionQueueSettingsDialog;

View File

@@ -0,0 +1,38 @@
#include "auto-update-tooltip-label.hpp"
namespace advss {
AutoUpdateTooltipLabel::AutoUpdateTooltipLabel(
QWidget *parent, const std::function<QString()> &updateTooltipCallback,
int updateIntervalMs)
: QLabel(parent),
_callback(updateTooltipCallback),
_timer(new QTimer(this)),
_updateIntervalMs(updateIntervalMs)
{
connect(_timer, &QTimer::timeout, this,
&AutoUpdateTooltipLabel::UpdateTooltip);
}
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
void AutoUpdateTooltipLabel::enterEvent(QEnterEvent *event)
#else
void AutoUpdateTooltipLabel::enterEvent(QEvent *event)
#endif
{
_timer->start(_updateIntervalMs);
QLabel::enterEvent(event);
}
void AutoUpdateTooltipLabel::leaveEvent(QEvent *event)
{
_timer->stop();
QLabel::leaveEvent(event);
}
void AutoUpdateTooltipLabel::UpdateTooltip()
{
setToolTip(_callback());
}
} // namespace advss

View File

@@ -0,0 +1,36 @@
#pragma once
#include "export-symbol-helper.hpp"
#include <functional>
#include <QLabel>
#include <QTimer>
namespace advss {
class ADVSS_EXPORT AutoUpdateTooltipLabel : public QLabel {
Q_OBJECT
public:
AutoUpdateTooltipLabel(
QWidget *parent,
const std::function<QString()> &updateTooltipCallback,
int updateIntervalMs = 300);
protected:
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
void enterEvent(QEnterEvent *event) override;
#else
void enterEvent(QEvent *event) override;
#endif
void leaveEvent(QEvent *event) override;
private slots:
void UpdateTooltip();
private:
const std::function<QString()> _callback;
QTimer *_timer;
const int _updateIntervalMs;
};
} // namespace advss

View File

@@ -455,35 +455,4 @@ void NotifyUIAboutTempVarChange()
nullptr, false);
}
AutoUpdateTooltipLabel::AutoUpdateTooltipLabel(
QWidget *parent, std::function<QString()> updateFunc)
: QLabel(parent),
_updateFunc(updateFunc),
_timer(new QTimer(this))
{
connect(_timer, &QTimer::timeout, this,
&AutoUpdateTooltipLabel::UpdateTooltip);
}
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
void AutoUpdateTooltipLabel::enterEvent(QEnterEvent *event)
#else
void AutoUpdateTooltipLabel::enterEvent(QEvent *event)
#endif
{
_timer->start(300);
QLabel::enterEvent(event);
}
void AutoUpdateTooltipLabel::leaveEvent(QEvent *event)
{
_timer->stop();
QLabel::leaveEvent(event);
}
void AutoUpdateTooltipLabel::UpdateTooltip()
{
setToolTip(_updateFunc());
}
} // namespace advss

View File

@@ -1,4 +1,5 @@
#pragma once
#include "auto-update-tooltip-label.hpp"
#include "filter-combo-box.hpp"
#include <obs-data.h>
@@ -6,8 +7,6 @@
#include <optional>
#include <QEnterEvent>
#include <QEvent>
#include <QLabel>
#include <QTimer>
#include <QStringList>
#include <string>
@@ -79,29 +78,6 @@ private:
friend TempVariableSelection;
};
class AutoUpdateTooltipLabel : public QLabel {
Q_OBJECT
public:
AutoUpdateTooltipLabel(QWidget *parent,
std::function<QString()> updateFunc);
protected:
#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
void enterEvent(QEnterEvent *event) override;
#else
void enterEvent(QEvent *event) override;
#endif
void leaveEvent(QEvent *event) override;
private slots:
void UpdateTooltip();
private:
std::function<QString()> _updateFunc;
QTimer *_timer;
};
class ADVSS_EXPORT TempVariableSelection : public QWidget {
Q_OBJECT

View File

@@ -82,9 +82,10 @@ template<typename T> bool NumberVariable<T>::HasValidValue() const
auto value = var->IntValue();
return value.has_value();
} else if constexpr (std::is_same<T, double>::value) {
auto value = var->IntValue();
auto value = var->DoubleValue();
return value.has_value();
}
assert(false);
return false;
}

View File

@@ -101,7 +101,7 @@ void GenericVaraiableSpinbox::setSuffix(const QString &suffix)
_fixedValueDouble->setSuffix(suffix);
}
void GenericVaraiableSpinbox::specialValueText(const QString &text)
void GenericVaraiableSpinbox::setSpecialValueText(const QString &text)
{
_fixedValueInt->setSpecialValueText(text);
_fixedValueDouble->setSpecialValueText(text);

View File

@@ -23,7 +23,7 @@ public:
void setPrefix(const QString &prefix);
void setSuffix(const QString &suffix);
void specialValueText(const QString &text);
void setSpecialValueText(const QString &text);
public slots:
void SetFixedValue(int);

View File

@@ -461,7 +461,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
_volumeDB->setMinimum(-100);
_volumeDB->setMaximum(0);
_volumeDB->setSuffix("dB");
_volumeDB->specialValueText("-inf");
_volumeDB->setSpecialValueText("-inf");
_rate->setMinimum(0.01);
_rate->setMaximum(999.);

View File

@@ -4,8 +4,6 @@
#include "slider-spinbox.hpp"
#include "source-selection.hpp"
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QCheckBox>
#include <QHBoxLayout>

View File

@@ -3,8 +3,6 @@
#include "file-selection.hpp"
#include "variable-text-edit.hpp"
#include <QSpinBox>
namespace advss {
class MacroActionFile : public MacroAction {

View File

@@ -7,7 +7,6 @@
#include "source-setting.hpp"
#include <QComboBox>
#include <QSpinBox>
#include <QPushButton>
namespace advss {

View File

@@ -5,7 +5,6 @@
#include <QComboBox>
#include <QCheckBox>
#include <QSpinBox>
#include <QHBoxLayout>
namespace advss {

View File

@@ -3,7 +3,6 @@
#include "file-selection.hpp"
#include <obs.hpp>
#include <QDoubleSpinBox>
#include <QLabel>
namespace advss {

View File

@@ -142,10 +142,10 @@ void MacroActionReplayBufferEdit::UpdateEntryData()
}
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_duration->SetDuration(_entryData->_duration);
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroActionReplayBufferEdit::SetWidgetVisiblity()
void MacroActionReplayBufferEdit::SetWidgetVisibility()
{
_warning->setVisible(_entryData->_action ==
MacroActionReplayBuffer::Action::SAVE);
@@ -169,7 +169,7 @@ void MacroActionReplayBufferEdit::ActionChanged(int value)
_entryData->_action =
static_cast<MacroActionReplayBuffer::Action>(value);
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroActionReplayBufferEdit::DurationChanged(const Duration &duration)

View File

@@ -53,7 +53,7 @@ private slots:
void DurationChanged(const Duration &);
private:
void SetWidgetVisiblity();
void SetWidgetVisibility();
QComboBox *_actions;
QLabel *_warning;

View File

@@ -10,17 +10,21 @@ bool MacroActionSceneOrder::_registered = MacroActionFactory::Register(
{MacroActionSceneOrder::Create, MacroActionSceneOrderEdit::Create,
"AdvSceneSwitcher.action.sceneOrder"});
const static std::map<SceneOrderAction, std::string> actionTypes = {
{SceneOrderAction::MOVE_UP,
const static std::map<MacroActionSceneOrder::Action, std::string> actionTypes = {
{MacroActionSceneOrder::Action::MOVE_UP,
"AdvSceneSwitcher.action.sceneOrder.type.moveUp"},
{SceneOrderAction::MOVE_DOWN,
{MacroActionSceneOrder::Action::MOVE_DOWN,
"AdvSceneSwitcher.action.sceneOrder.type.moveDown"},
{SceneOrderAction::MOVE_TOP,
{MacroActionSceneOrder::Action::MOVE_TOP,
"AdvSceneSwitcher.action.sceneOrder.type.moveTop"},
{SceneOrderAction::MOVE_BOTTOM,
{MacroActionSceneOrder::Action::MOVE_BOTTOM,
"AdvSceneSwitcher.action.sceneOrder.type.moveBottom"},
{SceneOrderAction::POSITION,
{MacroActionSceneOrder::Action::POSITION,
"AdvSceneSwitcher.action.sceneOrder.type.movePosition"},
{MacroActionSceneOrder::Action::ABOVE,
"AdvSceneSwitcher.action.sceneOrder.type.above"},
{MacroActionSceneOrder::Action::BELOW,
"AdvSceneSwitcher.action.sceneOrder.type.below"},
};
static void moveSceneItemsUp(std::vector<OBSSceneItem> &items)
@@ -66,26 +70,128 @@ static void moveSceneItemsPos(std::vector<OBSSceneItem> &items, int pos)
}
}
namespace {
struct PositionData {
obs_scene_item *item = nullptr;
bool found = false;
int position = 0;
};
} // namespace
static bool getSceneItemPositionHelper(obs_scene_t *, obs_sceneitem_t *item,
void *data)
{
auto positionData = reinterpret_cast<PositionData *>(data);
if (obs_sceneitem_is_group(item)) {
obs_scene_t *scene = obs_sceneitem_group_get_scene(item);
obs_scene_enum_items(scene, getSceneItemPositionHelper, data);
}
if (positionData->item == item) {
positionData->found = true;
return false;
}
positionData->position += 1;
return true;
}
static std::optional<int> getSceneItemPosition(const OBSSceneItem &item,
const SceneSelection &scene)
{
auto sceneSource = OBSGetStrongRef(scene.GetScene());
auto obsScene = obs_scene_from_source(sceneSource);
PositionData data{item};
obs_scene_enum_items(obsScene, getSceneItemPositionHelper, &data);
if (!data.found) {
return {};
}
return data.position;
}
static void moveItemFromToHelper(MacroActionSceneOrder::Action action,
const OBSSceneItem &itemToMove,
int currentPosition, int targetPosition)
{
if (action == MacroActionSceneOrder::Action::ABOVE) {
if (currentPosition > targetPosition) {
obs_sceneitem_set_order_position(itemToMove,
targetPosition + 1);
} else {
obs_sceneitem_set_order_position(itemToMove,
targetPosition);
}
} else if (action == MacroActionSceneOrder::Action::BELOW) {
if (currentPosition > targetPosition) {
obs_sceneitem_set_order_position(itemToMove,
targetPosition);
} else {
obs_sceneitem_set_order_position(itemToMove,
targetPosition - 1);
}
}
}
static void moveItemToItemHelper(MacroActionSceneOrder::Action action,
const std::vector<OBSSceneItem> &itemsToMove,
const SceneItemSelection &target,
const SceneSelection &scene)
{
auto targetItems = target.GetSceneItems(scene);
if (targetItems.empty()) {
return;
}
auto targetItem = targetItems.at(0);
for (const auto &item : itemsToMove) {
if (item == targetItem) {
continue;
}
auto targetPosition = getSceneItemPosition(targetItem, scene);
if (!targetPosition) {
continue;
}
auto currentPosition = getSceneItemPosition(item, scene);
if (!currentPosition) {
continue;
}
moveItemFromToHelper(action, item, *currentPosition,
*targetPosition);
}
}
bool MacroActionSceneOrder::PerformAction()
{
auto items = _source.GetSceneItems(_scene);
switch (_action) {
case SceneOrderAction::MOVE_UP:
case Action::MOVE_UP:
moveSceneItemsUp(items);
break;
case SceneOrderAction::MOVE_DOWN:
case Action::MOVE_DOWN:
moveSceneItemsDown(items);
break;
case SceneOrderAction::MOVE_TOP:
case Action::MOVE_TOP:
moveSceneItemsTop(items);
break;
case SceneOrderAction::MOVE_BOTTOM:
case Action::MOVE_BOTTOM:
moveSceneItemsBottom(items);
break;
case SceneOrderAction::POSITION:
case Action::POSITION:
moveSceneItemsPos(items, _position);
break;
case Action::ABOVE:
case Action::BELOW: {
moveItemToItemHelper(_action, items, _source2, _scene);
break;
}
default:
break;
}
@@ -111,6 +217,7 @@ bool MacroActionSceneOrder::Save(obs_data_t *obj) const
MacroAction::Save(obj);
_scene.Save(obj);
_source.Save(obj);
_source2.Save(obj, "sceneItemSelection2");
obs_data_set_int(obj, "action", static_cast<int>(_action));
obs_data_set_int(obj, "position", _position);
return true;
@@ -128,8 +235,8 @@ bool MacroActionSceneOrder::Load(obs_data_t *obj)
MacroAction::Load(obj);
_scene.Load(obj);
_source.Load(obj);
_action =
static_cast<SceneOrderAction>(obs_data_get_int(obj, "action"));
_source2.Load(obj, "sceneItemSelection2");
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
_position = obs_data_get_int(obj, "position");
return true;
}
@@ -167,13 +274,13 @@ static inline void populateActionSelection(QComboBox *list)
MacroActionSceneOrderEdit::MacroActionSceneOrderEdit(
QWidget *parent, std::shared_ptr<MacroActionSceneOrder> entryData)
: QWidget(parent)
: QWidget(parent),
_scenes(new SceneSelectionWidget(this, true, false, false, true)),
_sources(new SceneItemSelectionWidget(this)),
_sources2(new SceneItemSelectionWidget(this)),
_actions(new QComboBox(this)),
_position(new QSpinBox(this))
{
_scenes = new SceneSelectionWidget(window(), true, false, false, true);
_sources = new SceneItemSelectionWidget(parent);
_actions = new QComboBox();
_position = new QSpinBox();
populateActionSelection(_actions);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
@@ -182,23 +289,28 @@ MacroActionSceneOrderEdit::MacroActionSceneOrderEdit(
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources2, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(const SceneItemSelection &)));
QWidget::connect(_sources2,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this,
SLOT(Source2Changed(const SceneItemSelection &)));
QWidget::connect(_position, SIGNAL(valueChanged(int)), this,
SLOT(PositionChanged(int)));
QHBoxLayout *mainLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{scenes}}", _scenes},
{"{{sources}}", _sources},
{"{{actions}}", _actions},
{"{{position}}", _position},
};
auto layout = new QHBoxLayout;
PlaceWidgets(
obs_module_text("AdvSceneSwitcher.action.sceneOrder.entry"),
mainLayout, widgetPlaceholders);
setLayout(mainLayout);
layout,
{{"{{scenes}}", _scenes},
{"{{sources}}", _sources},
{"{{sources2}}", _sources2},
{"{{actions}}", _actions},
{"{{position}}", _position}});
setLayout(layout);
_entryData = entryData;
UpdateEntryData();
@@ -214,28 +326,20 @@ void MacroActionSceneOrderEdit::UpdateEntryData()
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_scenes->SetScene(_entryData->_scene);
_sources->SetSceneItem(_entryData->_source);
_sources2->SetSceneItem(_entryData->_source2);
_position->setValue(_entryData->_position);
_position->setVisible(_entryData->_action ==
SceneOrderAction::POSITION);
SetWidgetVisibility();
}
void MacroActionSceneOrderEdit::SceneChanged(const SceneSelection &s)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_scene = s;
}
void MacroActionSceneOrderEdit::SourceChanged(const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_source = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
@@ -243,26 +347,36 @@ void MacroActionSceneOrderEdit::SourceChanged(const SceneItemSelection &item)
updateGeometry();
}
void MacroActionSceneOrderEdit::Source2Changed(const SceneItemSelection &item)
{
GUARD_LOADING_AND_LOCK();
_entryData->_source2 = item;
adjustSize();
updateGeometry();
}
void MacroActionSceneOrderEdit::ActionChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_action = static_cast<SceneOrderAction>(value);
_position->setVisible(_entryData->_action ==
SceneOrderAction::POSITION);
GUARD_LOADING_AND_LOCK();
_entryData->_action = static_cast<MacroActionSceneOrder::Action>(value);
SetWidgetVisibility();
}
void MacroActionSceneOrderEdit::PositionChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_position = value;
}
void MacroActionSceneOrderEdit::SetWidgetVisibility()
{
_position->setVisible(_entryData->_action ==
MacroActionSceneOrder::Action::POSITION);
_sources2->setVisible(
_entryData->_action == MacroActionSceneOrder::Action::ABOVE ||
_entryData->_action == MacroActionSceneOrder::Action::BELOW);
adjustSize();
updateGeometry();
}
} // namespace advss

View File

@@ -7,14 +7,6 @@
namespace advss {
enum class SceneOrderAction {
MOVE_UP,
MOVE_DOWN,
MOVE_TOP,
MOVE_BOTTOM,
POSITION,
};
class MacroActionSceneOrder : public MacroAction {
public:
MacroActionSceneOrder(Macro *m) : MacroAction(m) {}
@@ -30,7 +22,17 @@ public:
SceneSelection _scene;
SceneItemSelection _source;
SceneOrderAction _action = SceneOrderAction::MOVE_UP;
SceneItemSelection _source2;
enum class Action {
MOVE_UP,
MOVE_DOWN,
MOVE_TOP,
MOVE_BOTTOM,
POSITION,
ABOVE,
BELOW,
};
Action _action = Action::MOVE_UP;
int _position = 0;
private:
@@ -58,20 +60,22 @@ public:
private slots:
void SceneChanged(const SceneSelection &);
void SourceChanged(const SceneItemSelection &);
void Source2Changed(const SceneItemSelection &);
void ActionChanged(int value);
void PositionChanged(int value);
signals:
void HeaderInfoChanged(const QString &);
protected:
private:
void SetWidgetVisibility();
SceneSelectionWidget *_scenes;
SceneItemSelectionWidget *_sources;
SceneItemSelectionWidget *_sources2;
QComboBox *_actions;
QSpinBox *_position;
std::shared_ptr<MacroActionSceneOrder> _entryData;
private:
QHBoxLayout *_mainLayout;
std::shared_ptr<MacroActionSceneOrder> _entryData;
bool _loading = true;
};

View File

@@ -6,8 +6,6 @@
#include "variable-text-edit.hpp"
#include "variable-spinbox.hpp"
#include <QSpinBox>
namespace advss {
class MacroActionSceneTransform : public MacroAction {

View File

@@ -3,8 +3,6 @@
#include "scene-selection.hpp"
#include "scene-item-selection.hpp"
#include <QSpinBox>
namespace advss {
class MacroActionSceneVisibility : public MacroAction {

View File

@@ -131,8 +131,7 @@ bool MacroActionScreenshot::Load(obs_data_t *obj)
_targetType =
static_cast<TargetType>(obs_data_get_int(obj, "targetType"));
_path.Load(obj, "savePath");
_variable =
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
_variable = GetWeakVariableByName(obs_data_get_string(obj, "variable"));
// TODO: Remove fallback for older versions
if (!obs_data_has_user_value(obj, "version")) {

View File

@@ -5,7 +5,6 @@
#include "source-selection.hpp"
#include "source-setting.hpp"
#include <QSpinBox>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>

View File

@@ -230,7 +230,7 @@ void MacroActionStreamEdit::UpdateEntryData()
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_keyFrameInterval->SetValue(_entryData->_keyFrameInterval);
_stringValue->setText(_entryData->_stringValue);
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroActionStreamEdit::KeyFrameIntervalChanged(
@@ -252,7 +252,7 @@ void MacroActionStreamEdit::StringValueChanged()
auto lock = LockContext();
_entryData->_stringValue = _stringValue->text().toStdString();
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroActionStreamEdit::ShowPassword()
@@ -267,7 +267,7 @@ void MacroActionStreamEdit::HidePassword()
_stringValue->setEchoMode(QLineEdit::PasswordEchoOnEdit);
}
void MacroActionStreamEdit::SetWidgetVisiblity()
void MacroActionStreamEdit::SetWidgetVisibility()
{
if (!_entryData) {
return;
@@ -310,7 +310,7 @@ void MacroActionStreamEdit::ActionChanged(int value)
static_cast<MacroActionStream::Action>(value);
}
_stringValue->setText(QString(""));
SetWidgetVisiblity();
SetWidgetVisibility();
}
} // namespace advss

View File

@@ -3,7 +3,6 @@
#include "variable-spinbox.hpp"
#include "variable-line-edit.hpp"
#include <QDoubleSpinBox>
#include <QComboBox>
#include <QHBoxLayout>
#include <chrono>
@@ -77,7 +76,7 @@ protected:
std::shared_ptr<MacroActionStream> _entryData;
private:
void SetWidgetVisiblity();
void SetWidgetVisibility();
QHBoxLayout *_layout;
bool _loading = true;

View File

@@ -3,7 +3,6 @@
#include "duration-control.hpp"
#include "macro-selection.hpp"
#include <QDoubleSpinBox>
#include <QHBoxLayout>
namespace advss {

View File

@@ -2,7 +2,6 @@
#include "macro-action-edit.hpp"
#include "duration-control.hpp"
#include <QDoubleSpinBox>
#include <QHBoxLayout>
namespace advss {

View File

@@ -478,7 +478,7 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
_volumeDB->setMinimum(-100);
_volumeDB->setMaximum(0);
_volumeDB->setSuffix("dB");
_volumeDB->specialValueText("-inf");
_volumeDB->setSpecialValueText("-inf");
_syncOffset->setMinimum(-950);
_syncOffset->setMaximum(20000);

View File

@@ -3,7 +3,6 @@
#include "striped-frame.hpp"
#include "variable-spinbox.hpp"
#include <QSpinBox>
#include <QComboBox>
#include <QPushButton>
#include <QTimer>

View File

@@ -6,7 +6,6 @@
#include "transform-setting.hpp"
#include "variable-text-edit.hpp"
#include <QSpinBox>
#include <QCheckBox>
namespace advss {

View File

@@ -1,8 +1,10 @@
#include "macro-condition-streaming.hpp"
#include "profile-helpers.hpp"
#include "layout-helpers.hpp"
#include "ui-helpers.hpp"
#include <obs-frontend-api.h>
#include <obs.hpp>
namespace advss {
@@ -13,8 +15,8 @@ bool MacroConditionStream::_registered = MacroConditionFactory::Register(
{MacroConditionStream::Create, MacroConditionStreamEdit::Create,
"AdvSceneSwitcher.condition.stream"});
const static std::map<MacroConditionStream::Condition, std::string>
streamStates = {
const static std::map<MacroConditionStream::Condition, std::string> conditions =
{
{MacroConditionStream::Condition::STOP,
"AdvSceneSwitcher.condition.stream.state.stop"},
{MacroConditionStream::Condition::START,
@@ -25,6 +27,10 @@ const static std::map<MacroConditionStream::Condition, std::string>
"AdvSceneSwitcher.condition.stream.state.stopping"},
{MacroConditionStream::Condition::KEYFRAME_INTERVAL,
"AdvSceneSwitcher.condition.stream.state.keyFrameInterval"},
{MacroConditionStream::Condition::STREAM_KEY,
"AdvSceneSwitcher.condition.stream.state.streamKey"},
{MacroConditionStream::Condition::SERVICE,
"AdvSceneSwitcher.condition.stream.state.service"},
};
static bool setupStreamingEventHandler();
@@ -32,7 +38,7 @@ static bool steamingEventHandlerIsSetup = setupStreamingEventHandler();
static std::chrono::high_resolution_clock::time_point streamStartTime{};
static std::chrono::high_resolution_clock::time_point streamStopTime{};
bool setupStreamingEventHandler()
static bool setupStreamingEventHandler()
{
static auto handleStreamingEvents = [](enum obs_frontend_event event,
void *) {
@@ -53,26 +59,67 @@ bool setupStreamingEventHandler()
return true;
}
int MacroConditionStream::GetKeyFrameInterval() const
static std::optional<std::string> getStreamKey()
{
const auto configPath = GetPathInProfileDir("service.json");
OBSDataAutoRelease data =
obs_data_create_from_json_file_safe(configPath.c_str(), "bak");
if (!data) {
return {};
}
OBSDataAutoRelease settings = obs_data_get_obj(data, "settings");
if (!settings) {
return {};
}
return obs_data_get_string(settings, "key");
}
std::optional<int> getKeyFrameInterval()
{
const auto configPath = GetPathInProfileDir("streamEncoder.json");
obs_data_t *settings =
OBSDataAutoRelease settings =
obs_data_create_from_json_file_safe(configPath.c_str(), "bak");
if (!settings) {
return -1;
return {};
}
int ret = obs_data_get_int(settings, "keyint_sec");
obs_data_release(settings);
return ret;
}
static std::string getCurrentServiceName()
{
auto service = obs_frontend_get_streaming_service();
if (!service) {
return "None";
}
auto id = obs_service_get_id(service);
if (strcmp(id, "rtmp_common") != 0) {
return obs_service_get_display_name(id);
}
const auto configPath = GetPathInProfileDir("service.json");
OBSDataAutoRelease serviceSettings =
obs_data_create_from_json_file_safe(configPath.c_str(), "bak");
OBSDataAutoRelease settings =
obs_data_get_obj(serviceSettings, "settings");
auto serviceName = obs_data_get_string(settings, "service");
if (serviceName) {
return serviceName;
}
return "None";
}
bool MacroConditionStream::CheckCondition()
{
bool match = false;
bool streamStarting = streamStartTime != _lastStreamStartingTime;
bool streamStopping = streamStopTime != _lastStreamStoppingTime;
const int keyFrameInterval = GetKeyFrameInterval();
auto keyFrameInterval = getKeyFrameInterval();
auto streamKey = getStreamKey();
auto serviceName = getCurrentServiceName();
switch (_condition) {
case Condition::STOP:
@@ -88,7 +135,21 @@ bool MacroConditionStream::CheckCondition()
match = streamStopping;
break;
case Condition::KEYFRAME_INTERVAL:
match = keyFrameInterval == _keyFrameInterval;
if (keyFrameInterval) {
match = *keyFrameInterval == _keyFrameInterval;
}
break;
case Condition::STREAM_KEY:
if (streamKey) {
match = streamKey == std::string(_streamKey);
}
break;
case Condition::SERVICE:
if (_regex.Enabled()) {
match = _regex.Matches(serviceName, _serviceName);
} else {
match = std::string(_serviceName) == serviceName;
}
break;
default:
break;
@@ -107,7 +168,14 @@ bool MacroConditionStream::CheckCondition()
obs_frontend_streaming_active() ? seconds.count() : 0;
SetTempVarValue("durationSeconds",
std::to_string(streamDurationSeconds));
SetTempVarValue("keyframeInterval", std::to_string(keyFrameInterval));
SetTempVarValue("serviceName", serviceName);
if (keyFrameInterval) {
SetTempVarValue("keyframeInterval",
std::to_string(*keyFrameInterval));
}
if (streamKey) {
SetTempVarValue("streamKey", *streamKey);
}
return match;
}
@@ -117,6 +185,9 @@ bool MacroConditionStream::Save(obs_data_t *obj) const
MacroCondition::Save(obj);
obs_data_set_int(obj, "state", static_cast<int>(_condition));
_keyFrameInterval.Save(obj, "keyFrameInterval");
_streamKey.Save(obj, "streamKey");
_serviceName.Save(obj, "serviceName");
_regex.Save(obj);
return true;
}
@@ -125,6 +196,9 @@ bool MacroConditionStream::Load(obs_data_t *obj)
MacroCondition::Load(obj);
_condition = static_cast<Condition>(obs_data_get_int(obj, "state"));
_keyFrameInterval.Load(obj, "keyFrameInterval");
_streamKey.Load(obj, "streamKey");
_serviceName.Load(obj, "serviceName");
_regex.Load(obj);
return true;
}
@@ -137,87 +211,140 @@ void MacroConditionStream::SetupTempVars()
"AdvSceneSwitcher.tempVar.streaming.keyframeInterval"),
obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.keyframeInterval.description"));
AddTempvar("streamKey",
obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.streamKey"));
AddTempvar(
"durationSeconds",
obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.durationSeconds"),
obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.durationSeconds.description"));
AddTempvar(
"serviceName",
obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.serviceName"),
obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.serviceName.description"));
}
static inline void populateStateSelection(QComboBox *list)
static void populateConditionSelection(QComboBox *list)
{
for (auto entry : streamStates) {
list->addItem(obs_module_text(entry.second.c_str()));
for (const auto &[_, name] : conditions) {
list->addItem(obs_module_text(name.c_str()));
}
}
MacroConditionStreamEdit::MacroConditionStreamEdit(
QWidget *parent, std::shared_ptr<MacroConditionStream> entryData)
: QWidget(parent),
_streamState(new QComboBox()),
_keyFrameInterval(new VariableSpinBox())
_conditions(new QComboBox()),
_keyFrameInterval(new VariableSpinBox()),
_streamKey(new VariableLineEdit(this)),
_serviceName(new VariableLineEdit(this)),
_currentService(new AutoUpdateTooltipLabel(
this,
[]() {
QString formatString = obs_module_text(
"AdvSceneSwitcher.condition.stream.service.tooltip");
return formatString.arg(QString::fromStdString(
getCurrentServiceName()));
})),
_regex(new RegexConfigWidget(this))
{
_keyFrameInterval->setMinimum(0);
_keyFrameInterval->setMaximum(25);
populateStateSelection(_streamState);
QString path = GetThemeTypeName() == "Light"
? ":/res/images/help.svg"
: ":/res/images/help_light.svg";
QIcon icon(path);
QPixmap pixmap = icon.pixmap(QSize(16, 16));
_currentService->setPixmap(pixmap);
QWidget::connect(_streamState, SIGNAL(currentIndexChanged(int)), this,
SLOT(StateChanged(int)));
_streamKey->setEchoMode(QLineEdit::PasswordEchoOnEdit);
populateConditionSelection(_conditions);
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
QWidget::connect(
_keyFrameInterval,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this,
SLOT(KeyFrameIntervalChanged(const NumberVariable<int> &)));
QWidget::connect(_serviceName, SIGNAL(editingFinished()), this,
SLOT(ServiceNameChanged()));
QWidget::connect(_regex,
SIGNAL(RegexConfigChanged(const RegexConfig &)), this,
SLOT(RegexChanged(const RegexConfig &)));
QWidget::connect(_streamKey, SIGNAL(editingFinished()), this,
SLOT(StreamKeyChanged()));
QHBoxLayout *mainLayout = new QHBoxLayout;
auto layout = new QHBoxLayout;
PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.stream.entry"),
mainLayout,
{{"{{streamState}}", _streamState},
{"{{keyFrameInterval}}", _keyFrameInterval}});
setLayout(mainLayout);
layout,
{{"{{streamState}}", _conditions},
{"{{keyFrameInterval}}", _keyFrameInterval},
{"{{streamKey}}", _streamKey},
{"{{serviceName}}", _serviceName},
{"{{regex}}", _regex},
{"{{currentService}}", _currentService}});
setLayout(layout);
_entryData = entryData;
UpdateEntryData();
_loading = false;
}
void MacroConditionStreamEdit::StateChanged(int value)
void MacroConditionStreamEdit::ConditionChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_condition =
static_cast<MacroConditionStream::Condition>(value);
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroConditionStreamEdit::KeyFrameIntervalChanged(
const NumberVariable<int> &value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_keyFrameInterval = value;
}
void MacroConditionStreamEdit::ServiceNameChanged()
{
GUARD_LOADING_AND_LOCK();
_entryData->_serviceName = _serviceName->text().toStdString();
}
void MacroConditionStreamEdit::RegexChanged(const RegexConfig &regex)
{
GUARD_LOADING_AND_LOCK();
_entryData->_regex = regex;
}
void MacroConditionStreamEdit::StreamKeyChanged()
{
GUARD_LOADING_AND_LOCK();
_entryData->_streamKey = _streamKey->text().toStdString();
}
void MacroConditionStreamEdit::UpdateEntryData()
{
if (!_entryData) {
return;
}
_streamState->setCurrentIndex(static_cast<int>(_entryData->_condition));
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
_streamKey->setText(_entryData->_streamKey);
_serviceName->setText(_entryData->_serviceName);
_regex->SetRegexConfig(_entryData->_regex);
_keyFrameInterval->SetValue(_entryData->_keyFrameInterval);
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroConditionStreamEdit::SetWidgetVisiblity()
void MacroConditionStreamEdit::SetWidgetVisibility()
{
if (!_entryData) {
return;
@@ -225,6 +352,14 @@ void MacroConditionStreamEdit::SetWidgetVisiblity()
_keyFrameInterval->setVisible(
_entryData->_condition ==
MacroConditionStream::Condition::KEYFRAME_INTERVAL);
_streamKey->setVisible(_entryData->_condition ==
MacroConditionStream::Condition::STREAM_KEY);
const bool isCheckingStreamingService =
_entryData->_condition ==
MacroConditionStream::Condition::SERVICE;
_serviceName->setVisible(isCheckingStreamingService);
_regex->setVisible(isCheckingStreamingService);
_currentService->setVisible(isCheckingStreamingService);
}
} // namespace advss

View File

@@ -1,6 +1,9 @@
#pragma once
#include "macro-condition-edit.hpp"
#include "variable-spinbox.hpp"
#include "regex-config.hpp"
#include "variable-string.hpp"
#include "variable-line-edit.hpp"
#include <QWidget>
#include <QComboBox>
@@ -25,13 +28,17 @@ public:
STARTING,
STOPPING,
KEYFRAME_INTERVAL,
STREAM_KEY,
SERVICE,
};
Condition _condition = Condition::STOP;
NumberVariable<int> _keyFrameInterval = 0;
StringVariable _streamKey;
StringVariable _serviceName = "";
RegexConfig _regex;
private:
void SetupTempVars();
int GetKeyFrameInterval() const;
std::chrono::high_resolution_clock::time_point _lastStreamStartingTime{};
std::chrono::high_resolution_clock::time_point _lastStreamStoppingTime{};
@@ -57,17 +64,23 @@ public:
}
private slots:
void StateChanged(int value);
void ConditionChanged(int value);
void KeyFrameIntervalChanged(const NumberVariable<int> &);
protected:
QComboBox *_streamState;
VariableSpinBox *_keyFrameInterval;
std::shared_ptr<MacroConditionStream> _entryData;
void StreamKeyChanged();
void ServiceNameChanged();
void RegexChanged(const RegexConfig &);
private:
void SetWidgetVisiblity();
void SetWidgetVisibility();
QComboBox *_conditions;
VariableSpinBox *_keyFrameInterval;
VariableLineEdit *_streamKey;
VariableLineEdit *_serviceName;
QLabel *_currentService;
RegexConfigWidget *_regex;
std::shared_ptr<MacroConditionStream> _entryData;
bool _loading = true;
};

View File

@@ -782,11 +782,11 @@ MidiMessageSelection::MidiMessageSelection(QWidget *parent)
"Note.svg");
SetButtonIcon(_noteValueStringToggle, path.c_str());
_channel->specialValueText(
_channel->setSpecialValueText(
obs_module_text("AdvSceneSwitcher.midi.message.placeholder"));
_noteValue->specialValueText(
_noteValue->setSpecialValueText(
obs_module_text("AdvSceneSwitcher.midi.message.placeholder"));
_value->specialValueText(
_value->setSpecialValueText(
obs_module_text("AdvSceneSwitcher.midi.message.placeholder"));
_channel->setMinimum(MidiMessage::optionalChannelIndicator);

View File

@@ -304,11 +304,10 @@ bool MacroConditionTwitch::CheckChannelGenericEvents()
continue;
}
SetVariableValue(event->ToString());
setTempVarsHelper(
event->data,
std::bind(&MacroConditionTwitch::SetTempVarValue, this,
std::placeholders::_1,
std::placeholders::_2));
setTempVarsHelper(event->data,
[this](const char *id, const char *value) {
SetTempVarValue(id, value);
});
if (_clearBufferOnMatch) {
_eventBuffer->Clear();
@@ -346,11 +345,10 @@ bool MacroConditionTwitch::CheckChannelLiveEvents()
}
SetVariableValue(event->ToString());
setTempVarsHelper(
event->data,
std::bind(&MacroConditionTwitch::SetTempVarValue, this,
std::placeholders::_1,
std::placeholders::_2));
setTempVarsHelper(event->data,
[this](const char *id, const char *value) {
SetTempVarValue(id, value);
});
if (_clearBufferOnMatch) {
_eventBuffer->Clear();
@@ -446,7 +444,7 @@ bool MacroConditionTwitch::CheckChatMessages(TwitchToken &token)
message->properties.isVIP ? "true" : "false");
if (_clearBufferOnMatch) {
_eventBuffer->Clear();
_chatBuffer->Clear();
}
return true;
}
@@ -481,7 +479,7 @@ bool MacroConditionTwitch::CheckChatUserJoinOrLeave(TwitchToken &token)
SetTempVarValue("user_login", message->source.nick);
if (_clearBufferOnMatch) {
_eventBuffer->Clear();
_chatBuffer->Clear();
}
return true;
}

View File

@@ -2,7 +2,6 @@
#include <variable-spinbox.hpp>
#include <QWidget>
#include <QSpinBox>
#include <obs-data.h>
#include <opencv2/opencv.hpp>