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.hpp
lib/queue/action-queue-tab.cpp lib/queue/action-queue-tab.cpp
lib/queue/action-queue-tab.hpp 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.cpp
lib/utils/backup.hpp lib/utils/backup.hpp
lib/utils/condition-logic.cpp 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.stop="Stream gestoppt"
AdvSceneSwitcher.condition.stream.state.starting="Stream wird gestartet" AdvSceneSwitcher.condition.stream.state.starting="Stream wird gestartet"
AdvSceneSwitcher.condition.stream.state.stopping="Stream wird gestoppt" AdvSceneSwitcher.condition.stream.state.stopping="Stream wird gestoppt"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Aufnahme" AdvSceneSwitcher.condition.record="Aufnahme"
AdvSceneSwitcher.condition.record.state.start="Aufnahme läuft" AdvSceneSwitcher.condition.record.state.start="Aufnahme läuft"
AdvSceneSwitcher.condition.record.state.pause="Aufnahme pausiert" 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.moveTop="An erste Stelle verschieben"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="An letzte Stelle verschieben" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="An letzte Stelle verschieben"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="An Position 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="Szenenelement transformieren"
AdvSceneSwitcher.action.sceneTransform.getTransform="Transformation erhalten" AdvSceneSwitcher.action.sceneTransform.getTransform="Transformation erhalten"
AdvSceneSwitcher.action.sceneTransform.entry="Auf{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}" 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.queueRemoveButton.tooltip="Remove selected action queues"
AdvSceneSwitcher.actionQueueTab.name.header="Name" AdvSceneSwitcher.actionQueueTab.name.header="Name"
AdvSceneSwitcher.actionQueueTab.size.header="Size" AdvSceneSwitcher.actionQueueTab.size.header="Size"
AdvSceneSwitcher.actionQueueTab.lastEmpty.header="Last empty"
AdvSceneSwitcher.actionQueueTab.isRunning.header="Is running" AdvSceneSwitcher.actionQueueTab.isRunning.header="Is running"
AdvSceneSwitcher.actionQueueTab.runOnStartup.header="Run on startup" AdvSceneSwitcher.actionQueueTab.runOnStartup.header="Run on startup"
AdvSceneSwitcher.actionQueueTab.yes="Yes" 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.starting="Stream starting"
AdvSceneSwitcher.condition.stream.state.stopping="Stream stopping" AdvSceneSwitcher.condition.stream.state.stopping="Stream stopping"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="Keyframe interval equals" 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="Recording"
AdvSceneSwitcher.condition.record.state.start="Recording running" AdvSceneSwitcher.condition.record.state.start="Recording running"
AdvSceneSwitcher.condition.record.state.pause="Recording paused" 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.moveTop="Move to top"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position" 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="Scene item transform"
AdvSceneSwitcher.action.sceneTransform.type.manual="Set transform string" AdvSceneSwitcher.action.sceneTransform.type.manual="Set transform string"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="Set transform setting" 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="Stream keyframe interval"
AdvSceneSwitcher.tempVar.streaming.keyframeInterval.description="Stream keyframe interval configured in the OBS settings." 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="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.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="Clipboard text"
AdvSceneSwitcher.tempVar.clipboard.text.description="The text contained in the clipboard.\nWill be empty if the clipboard does not contain 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="Data"
AdvSceneSwitcher.tempVar.streamDeck.data.description="The value of the \"Data\" field configured in the action on the Stream Deck side." 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.selectScene="--select scene--"
AdvSceneSwitcher.selectPreviousScene="Previous Scene" AdvSceneSwitcher.selectPreviousScene="Previous Scene"
AdvSceneSwitcher.selectCurrentScene="Current 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.stop="Transmisión detenida"
AdvSceneSwitcher.condition.stream.state.starting="Inicio de transmisión" AdvSceneSwitcher.condition.stream.state.starting="Inicio de transmisión"
AdvSceneSwitcher.condition.stream.state.stopping="Detener transmisión" AdvSceneSwitcher.condition.stream.state.stopping="Detener transmisión"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Grabación" AdvSceneSwitcher.condition.record="Grabación"
AdvSceneSwitcher.condition.record.state.start="Grabación en ejecución" AdvSceneSwitcher.condition.record.state.start="Grabación en ejecución"
AdvSceneSwitcher.condition.record.state.pause="Grabación en pausa" 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.moveTop="Mover al principio"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Mover al final" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Mover al final"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Mover a la posición" 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="Transformar elemento de escena"
AdvSceneSwitcher.action.sceneTransform.getTransform="Obtener transformación" AdvSceneSwitcher.action.sceneTransform.getTransform="Obtener transformación"
AdvSceneSwitcher.action.sceneTransform.entry="En{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}" 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.moveTop="Déplacer en haut"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Déplacer en bas" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Déplacer en bas"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Déplacer à la position" 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="Transformation de l'élément de la scène"
AdvSceneSwitcher.action.sceneTransform.type.manual="Transform" AdvSceneSwitcher.action.sceneTransform.type.manual="Transform"
AdvSceneSwitcher.action.sceneTransform.type.reset="Réinitialiser la transformation" 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.moveTop="トップへ移動"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="一番下へ移動" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="一番下へ移動"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="ポジションへの移動" 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="シーンアイテムの変形"
AdvSceneSwitcher.action.sceneTransform.type.manual="変形" AdvSceneSwitcher.action.sceneTransform.type.manual="変形"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="トランスフォーム設定を行う" 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.starting="Iniciando o streaming"
AdvSceneSwitcher.condition.stream.state.stopping="Parando o streaming" AdvSceneSwitcher.condition.stream.state.stopping="Parando o streaming"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="Intervalo de keyframe igual a" AdvSceneSwitcher.condition.stream.state.keyFrameInterval="Intervalo de keyframe igual a"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Gravação" AdvSceneSwitcher.condition.record="Gravação"
AdvSceneSwitcher.condition.record.state.start="Gravação em execução" AdvSceneSwitcher.condition.record.state.start="Gravação em execução"
AdvSceneSwitcher.condition.record.state.pause="Gravação pausada" 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.moveTop="Mover para o topo"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Mover para o fundo" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Mover para o fundo"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Mover para posição" 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="Transformação de item de cena"
AdvSceneSwitcher.action.sceneTransform.type.manual="Definir string de transformação" AdvSceneSwitcher.action.sceneTransform.type.manual="Definir string de transformação"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="Definir configuração 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.stop="Yayın durdu"
AdvSceneSwitcher.condition.stream.state.starting="Yayın başlıyor" AdvSceneSwitcher.condition.stream.state.starting="Yayın başlıyor"
AdvSceneSwitcher.condition.stream.state.stopping="Yayın duruyor" AdvSceneSwitcher.condition.stream.state.stopping="Yayın duruyor"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Kayıt" AdvSceneSwitcher.condition.record="Kayıt"
AdvSceneSwitcher.condition.record.state.start="Kayıt Çalışıyor" AdvSceneSwitcher.condition.record.state.start="Kayıt Çalışıyor"
AdvSceneSwitcher.condition.record.state.pause="Kayıt durakladı" 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.moveTop="En üste taşı"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Aşağıya taşı" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Aşağıya taşı"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Konuma 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="Sahne öğesi dönüşümü"
AdvSceneSwitcher.action.sceneTransform.getTransform="Dönüşümü al" AdvSceneSwitcher.action.sceneTransform.getTransform="Dönüşümü al"
AdvSceneSwitcher.action.sceneTransform.entry="Açık{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}" 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.starting="推流启动中"
AdvSceneSwitcher.condition.stream.state.stopping="推流停止中" AdvSceneSwitcher.condition.stream.state.stopping="推流停止中"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="关键帧间隔等于" AdvSceneSwitcher.condition.stream.state.keyFrameInterval="关键帧间隔等于"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="录制" AdvSceneSwitcher.condition.record="录制"
AdvSceneSwitcher.condition.record.state.start="录制运行中" AdvSceneSwitcher.condition.record.state.start="录制运行中"
AdvSceneSwitcher.condition.record.state.pause="录制暂停" AdvSceneSwitcher.condition.record.state.pause="录制暂停"
@@ -547,7 +546,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="顶部" AdvSceneSwitcher.action.sceneOrder.type.moveTop="顶部"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="底部" AdvSceneSwitcher.action.sceneOrder.type.moveBottom="底部"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="移动到数值位置" 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="场景项目转换"
AdvSceneSwitcher.action.sceneTransform.getTransform="获得转换" AdvSceneSwitcher.action.sceneTransform.getTransform="获得转换"
AdvSceneSwitcher.action.sceneTransform.entry="在{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}" AdvSceneSwitcher.action.sceneTransform.entry="在{{scenes}}{{action}}{{rotation}}{{sources}}{{settingSelection}}{{singleSettingValue}}"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -51,8 +51,17 @@ protected:
virtual void SetupTempVars(); virtual void SetupTempVars();
void AddTempvar(const std::string &id, const std::string &name, void AddTempvar(const std::string &id, const std::string &name,
const std::string &description = ""); const std::string &description = "");
void SetTempVarValue(const std::string &id, const std::string &value); 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: private:
void ClearAvailableTempvars(); void ClearAvailableTempvars();
std::optional<const TempVariable> std::optional<const TempVariable>

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#include "auto-update-tooltip-label.hpp"
#include "filter-combo-box.hpp" #include "filter-combo-box.hpp"
#include <obs-data.h> #include <obs-data.h>
@@ -6,8 +7,6 @@
#include <optional> #include <optional>
#include <QEnterEvent> #include <QEnterEvent>
#include <QEvent> #include <QEvent>
#include <QLabel>
#include <QTimer>
#include <QStringList> #include <QStringList>
#include <string> #include <string>
@@ -79,29 +78,6 @@ private:
friend TempVariableSelection; 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 { class ADVSS_EXPORT TempVariableSelection : public QWidget {
Q_OBJECT Q_OBJECT

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,17 +10,21 @@ bool MacroActionSceneOrder::_registered = MacroActionFactory::Register(
{MacroActionSceneOrder::Create, MacroActionSceneOrderEdit::Create, {MacroActionSceneOrder::Create, MacroActionSceneOrderEdit::Create,
"AdvSceneSwitcher.action.sceneOrder"}); "AdvSceneSwitcher.action.sceneOrder"});
const static std::map<SceneOrderAction, std::string> actionTypes = { const static std::map<MacroActionSceneOrder::Action, std::string> actionTypes = {
{SceneOrderAction::MOVE_UP, {MacroActionSceneOrder::Action::MOVE_UP,
"AdvSceneSwitcher.action.sceneOrder.type.moveUp"}, "AdvSceneSwitcher.action.sceneOrder.type.moveUp"},
{SceneOrderAction::MOVE_DOWN, {MacroActionSceneOrder::Action::MOVE_DOWN,
"AdvSceneSwitcher.action.sceneOrder.type.moveDown"}, "AdvSceneSwitcher.action.sceneOrder.type.moveDown"},
{SceneOrderAction::MOVE_TOP, {MacroActionSceneOrder::Action::MOVE_TOP,
"AdvSceneSwitcher.action.sceneOrder.type.moveTop"}, "AdvSceneSwitcher.action.sceneOrder.type.moveTop"},
{SceneOrderAction::MOVE_BOTTOM, {MacroActionSceneOrder::Action::MOVE_BOTTOM,
"AdvSceneSwitcher.action.sceneOrder.type.moveBottom"}, "AdvSceneSwitcher.action.sceneOrder.type.moveBottom"},
{SceneOrderAction::POSITION, {MacroActionSceneOrder::Action::POSITION,
"AdvSceneSwitcher.action.sceneOrder.type.movePosition"}, "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) 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() bool MacroActionSceneOrder::PerformAction()
{ {
auto items = _source.GetSceneItems(_scene); auto items = _source.GetSceneItems(_scene);
switch (_action) { switch (_action) {
case SceneOrderAction::MOVE_UP: case Action::MOVE_UP:
moveSceneItemsUp(items); moveSceneItemsUp(items);
break; break;
case SceneOrderAction::MOVE_DOWN: case Action::MOVE_DOWN:
moveSceneItemsDown(items); moveSceneItemsDown(items);
break; break;
case SceneOrderAction::MOVE_TOP: case Action::MOVE_TOP:
moveSceneItemsTop(items); moveSceneItemsTop(items);
break; break;
case SceneOrderAction::MOVE_BOTTOM: case Action::MOVE_BOTTOM:
moveSceneItemsBottom(items); moveSceneItemsBottom(items);
break; break;
case SceneOrderAction::POSITION: case Action::POSITION:
moveSceneItemsPos(items, _position); moveSceneItemsPos(items, _position);
break; break;
case Action::ABOVE:
case Action::BELOW: {
moveItemToItemHelper(_action, items, _source2, _scene);
break;
}
default: default:
break; break;
} }
@@ -111,6 +217,7 @@ bool MacroActionSceneOrder::Save(obs_data_t *obj) const
MacroAction::Save(obj); MacroAction::Save(obj);
_scene.Save(obj); _scene.Save(obj);
_source.Save(obj); _source.Save(obj);
_source2.Save(obj, "sceneItemSelection2");
obs_data_set_int(obj, "action", static_cast<int>(_action)); obs_data_set_int(obj, "action", static_cast<int>(_action));
obs_data_set_int(obj, "position", _position); obs_data_set_int(obj, "position", _position);
return true; return true;
@@ -128,8 +235,8 @@ bool MacroActionSceneOrder::Load(obs_data_t *obj)
MacroAction::Load(obj); MacroAction::Load(obj);
_scene.Load(obj); _scene.Load(obj);
_source.Load(obj); _source.Load(obj);
_action = _source2.Load(obj, "sceneItemSelection2");
static_cast<SceneOrderAction>(obs_data_get_int(obj, "action")); _action = static_cast<Action>(obs_data_get_int(obj, "action"));
_position = obs_data_get_int(obj, "position"); _position = obs_data_get_int(obj, "position");
return true; return true;
} }
@@ -167,13 +274,13 @@ static inline void populateActionSelection(QComboBox *list)
MacroActionSceneOrderEdit::MacroActionSceneOrderEdit( MacroActionSceneOrderEdit::MacroActionSceneOrderEdit(
QWidget *parent, std::shared_ptr<MacroActionSceneOrder> entryData) 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); populateActionSelection(_actions);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
@@ -182,23 +289,28 @@ MacroActionSceneOrderEdit::MacroActionSceneOrderEdit(
this, SLOT(SceneChanged(const SceneSelection &))); this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &))); _sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources2, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources, QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)), SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(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, QWidget::connect(_position, SIGNAL(valueChanged(int)), this,
SLOT(PositionChanged(int))); SLOT(PositionChanged(int)));
QHBoxLayout *mainLayout = new QHBoxLayout; auto layout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{scenes}}", _scenes},
{"{{sources}}", _sources},
{"{{actions}}", _actions},
{"{{position}}", _position},
};
PlaceWidgets( PlaceWidgets(
obs_module_text("AdvSceneSwitcher.action.sceneOrder.entry"), obs_module_text("AdvSceneSwitcher.action.sceneOrder.entry"),
mainLayout, widgetPlaceholders); layout,
setLayout(mainLayout); {{"{{scenes}}", _scenes},
{"{{sources}}", _sources},
{"{{sources2}}", _sources2},
{"{{actions}}", _actions},
{"{{position}}", _position}});
setLayout(layout);
_entryData = entryData; _entryData = entryData;
UpdateEntryData(); UpdateEntryData();
@@ -214,28 +326,20 @@ void MacroActionSceneOrderEdit::UpdateEntryData()
_actions->setCurrentIndex(static_cast<int>(_entryData->_action)); _actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_scenes->SetScene(_entryData->_scene); _scenes->SetScene(_entryData->_scene);
_sources->SetSceneItem(_entryData->_source); _sources->SetSceneItem(_entryData->_source);
_sources2->SetSceneItem(_entryData->_source2);
_position->setValue(_entryData->_position); _position->setValue(_entryData->_position);
_position->setVisible(_entryData->_action == SetWidgetVisibility();
SceneOrderAction::POSITION);
} }
void MacroActionSceneOrderEdit::SceneChanged(const SceneSelection &s) void MacroActionSceneOrderEdit::SceneChanged(const SceneSelection &s)
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return;
}
auto lock = LockContext();
_entryData->_scene = s; _entryData->_scene = s;
} }
void MacroActionSceneOrderEdit::SourceChanged(const SceneItemSelection &item) void MacroActionSceneOrderEdit::SourceChanged(const SceneItemSelection &item)
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return;
}
auto lock = LockContext();
_entryData->_source = item; _entryData->_source = item;
emit HeaderInfoChanged( emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
@@ -243,26 +347,36 @@ void MacroActionSceneOrderEdit::SourceChanged(const SceneItemSelection &item)
updateGeometry(); updateGeometry();
} }
void MacroActionSceneOrderEdit::Source2Changed(const SceneItemSelection &item)
{
GUARD_LOADING_AND_LOCK();
_entryData->_source2 = item;
adjustSize();
updateGeometry();
}
void MacroActionSceneOrderEdit::ActionChanged(int value) void MacroActionSceneOrderEdit::ActionChanged(int value)
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return; _entryData->_action = static_cast<MacroActionSceneOrder::Action>(value);
} SetWidgetVisibility();
auto lock = LockContext();
_entryData->_action = static_cast<SceneOrderAction>(value);
_position->setVisible(_entryData->_action ==
SceneOrderAction::POSITION);
} }
void MacroActionSceneOrderEdit::PositionChanged(int value) void MacroActionSceneOrderEdit::PositionChanged(int value)
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return;
}
auto lock = LockContext();
_entryData->_position = value; _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 } // namespace advss

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,8 +1,10 @@
#include "macro-condition-streaming.hpp" #include "macro-condition-streaming.hpp"
#include "profile-helpers.hpp" #include "profile-helpers.hpp"
#include "layout-helpers.hpp" #include "layout-helpers.hpp"
#include "ui-helpers.hpp"
#include <obs-frontend-api.h> #include <obs-frontend-api.h>
#include <obs.hpp>
namespace advss { namespace advss {
@@ -13,8 +15,8 @@ bool MacroConditionStream::_registered = MacroConditionFactory::Register(
{MacroConditionStream::Create, MacroConditionStreamEdit::Create, {MacroConditionStream::Create, MacroConditionStreamEdit::Create,
"AdvSceneSwitcher.condition.stream"}); "AdvSceneSwitcher.condition.stream"});
const static std::map<MacroConditionStream::Condition, std::string> const static std::map<MacroConditionStream::Condition, std::string> conditions =
streamStates = { {
{MacroConditionStream::Condition::STOP, {MacroConditionStream::Condition::STOP,
"AdvSceneSwitcher.condition.stream.state.stop"}, "AdvSceneSwitcher.condition.stream.state.stop"},
{MacroConditionStream::Condition::START, {MacroConditionStream::Condition::START,
@@ -25,6 +27,10 @@ const static std::map<MacroConditionStream::Condition, std::string>
"AdvSceneSwitcher.condition.stream.state.stopping"}, "AdvSceneSwitcher.condition.stream.state.stopping"},
{MacroConditionStream::Condition::KEYFRAME_INTERVAL, {MacroConditionStream::Condition::KEYFRAME_INTERVAL,
"AdvSceneSwitcher.condition.stream.state.keyFrameInterval"}, "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(); 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 streamStartTime{};
static std::chrono::high_resolution_clock::time_point streamStopTime{}; static std::chrono::high_resolution_clock::time_point streamStopTime{};
bool setupStreamingEventHandler() static bool setupStreamingEventHandler()
{ {
static auto handleStreamingEvents = [](enum obs_frontend_event event, static auto handleStreamingEvents = [](enum obs_frontend_event event,
void *) { void *) {
@@ -53,26 +59,67 @@ bool setupStreamingEventHandler()
return true; 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"); const auto configPath = GetPathInProfileDir("streamEncoder.json");
obs_data_t *settings = OBSDataAutoRelease settings =
obs_data_create_from_json_file_safe(configPath.c_str(), "bak"); obs_data_create_from_json_file_safe(configPath.c_str(), "bak");
if (!settings) { if (!settings) {
return -1; return {};
} }
int ret = obs_data_get_int(settings, "keyint_sec"); int ret = obs_data_get_int(settings, "keyint_sec");
obs_data_release(settings);
return ret; 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 MacroConditionStream::CheckCondition()
{ {
bool match = false; bool match = false;
bool streamStarting = streamStartTime != _lastStreamStartingTime; bool streamStarting = streamStartTime != _lastStreamStartingTime;
bool streamStopping = streamStopTime != _lastStreamStoppingTime; bool streamStopping = streamStopTime != _lastStreamStoppingTime;
const int keyFrameInterval = GetKeyFrameInterval(); auto keyFrameInterval = getKeyFrameInterval();
auto streamKey = getStreamKey();
auto serviceName = getCurrentServiceName();
switch (_condition) { switch (_condition) {
case Condition::STOP: case Condition::STOP:
@@ -88,7 +135,21 @@ bool MacroConditionStream::CheckCondition()
match = streamStopping; match = streamStopping;
break; break;
case Condition::KEYFRAME_INTERVAL: 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; break;
default: default:
break; break;
@@ -107,7 +168,14 @@ bool MacroConditionStream::CheckCondition()
obs_frontend_streaming_active() ? seconds.count() : 0; obs_frontend_streaming_active() ? seconds.count() : 0;
SetTempVarValue("durationSeconds", SetTempVarValue("durationSeconds",
std::to_string(streamDurationSeconds)); 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; return match;
} }
@@ -117,6 +185,9 @@ bool MacroConditionStream::Save(obs_data_t *obj) const
MacroCondition::Save(obj); MacroCondition::Save(obj);
obs_data_set_int(obj, "state", static_cast<int>(_condition)); obs_data_set_int(obj, "state", static_cast<int>(_condition));
_keyFrameInterval.Save(obj, "keyFrameInterval"); _keyFrameInterval.Save(obj, "keyFrameInterval");
_streamKey.Save(obj, "streamKey");
_serviceName.Save(obj, "serviceName");
_regex.Save(obj);
return true; return true;
} }
@@ -125,6 +196,9 @@ bool MacroConditionStream::Load(obs_data_t *obj)
MacroCondition::Load(obj); MacroCondition::Load(obj);
_condition = static_cast<Condition>(obs_data_get_int(obj, "state")); _condition = static_cast<Condition>(obs_data_get_int(obj, "state"));
_keyFrameInterval.Load(obj, "keyFrameInterval"); _keyFrameInterval.Load(obj, "keyFrameInterval");
_streamKey.Load(obj, "streamKey");
_serviceName.Load(obj, "serviceName");
_regex.Load(obj);
return true; return true;
} }
@@ -137,87 +211,140 @@ void MacroConditionStream::SetupTempVars()
"AdvSceneSwitcher.tempVar.streaming.keyframeInterval"), "AdvSceneSwitcher.tempVar.streaming.keyframeInterval"),
obs_module_text( obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.keyframeInterval.description")); "AdvSceneSwitcher.tempVar.streaming.keyframeInterval.description"));
AddTempvar("streamKey",
obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.streamKey"));
AddTempvar( AddTempvar(
"durationSeconds", "durationSeconds",
obs_module_text( obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.durationSeconds"), "AdvSceneSwitcher.tempVar.streaming.durationSeconds"),
obs_module_text( obs_module_text(
"AdvSceneSwitcher.tempVar.streaming.durationSeconds.description")); "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) { for (const auto &[_, name] : conditions) {
list->addItem(obs_module_text(entry.second.c_str())); list->addItem(obs_module_text(name.c_str()));
} }
} }
MacroConditionStreamEdit::MacroConditionStreamEdit( MacroConditionStreamEdit::MacroConditionStreamEdit(
QWidget *parent, std::shared_ptr<MacroConditionStream> entryData) QWidget *parent, std::shared_ptr<MacroConditionStream> entryData)
: QWidget(parent), : QWidget(parent),
_streamState(new QComboBox()), _conditions(new QComboBox()),
_keyFrameInterval(new VariableSpinBox()) _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->setMinimum(0);
_keyFrameInterval->setMaximum(25); _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, _streamKey->setEchoMode(QLineEdit::PasswordEchoOnEdit);
SLOT(StateChanged(int)));
populateConditionSelection(_conditions);
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
QWidget::connect( QWidget::connect(
_keyFrameInterval, _keyFrameInterval,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)), SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, this,
SLOT(KeyFrameIntervalChanged(const NumberVariable<int> &))); 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"), PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.stream.entry"),
mainLayout, layout,
{{"{{streamState}}", _streamState}, {{"{{streamState}}", _conditions},
{"{{keyFrameInterval}}", _keyFrameInterval}}); {"{{keyFrameInterval}}", _keyFrameInterval},
setLayout(mainLayout); {"{{streamKey}}", _streamKey},
{"{{serviceName}}", _serviceName},
{"{{regex}}", _regex},
{"{{currentService}}", _currentService}});
setLayout(layout);
_entryData = entryData; _entryData = entryData;
UpdateEntryData(); UpdateEntryData();
_loading = false; _loading = false;
} }
void MacroConditionStreamEdit::StateChanged(int value) void MacroConditionStreamEdit::ConditionChanged(int value)
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return;
}
auto lock = LockContext();
_entryData->_condition = _entryData->_condition =
static_cast<MacroConditionStream::Condition>(value); static_cast<MacroConditionStream::Condition>(value);
SetWidgetVisiblity(); SetWidgetVisibility();
} }
void MacroConditionStreamEdit::KeyFrameIntervalChanged( void MacroConditionStreamEdit::KeyFrameIntervalChanged(
const NumberVariable<int> &value) const NumberVariable<int> &value)
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return;
}
auto lock = LockContext();
_entryData->_keyFrameInterval = value; _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() void MacroConditionStreamEdit::UpdateEntryData()
{ {
if (!_entryData) { if (!_entryData) {
return; 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); _keyFrameInterval->SetValue(_entryData->_keyFrameInterval);
SetWidgetVisiblity(); SetWidgetVisibility();
} }
void MacroConditionStreamEdit::SetWidgetVisiblity() void MacroConditionStreamEdit::SetWidgetVisibility()
{ {
if (!_entryData) { if (!_entryData) {
return; return;
@@ -225,6 +352,14 @@ void MacroConditionStreamEdit::SetWidgetVisiblity()
_keyFrameInterval->setVisible( _keyFrameInterval->setVisible(
_entryData->_condition == _entryData->_condition ==
MacroConditionStream::Condition::KEYFRAME_INTERVAL); 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 } // namespace advss

View File

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

View File

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

View File

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

View File

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