Compare commits

...

19 Commits

Author SHA1 Message Date
WarmUpTill
db50822b05 Prepare to fix deprecation warning when using OBS 31
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
The following log message will be present in OBS 31 when
CheckIfTrayIsDisabled() is called:

DEPRECATION: obs_frontend_get_global_config is deprecated. Read from
global or user configuration explicitly instead.

It will be resolved when the minimum OBS version is bumped to OBS 31.
2024-11-02 08:28:52 +01:00
WarmUpTill
63a545b293 Fix "Date" condition returning true unexpectedly
This could happen if the plugin was stopped on the General tab and
restarted or the first time the plugin was started.
2024-11-02 08:28:52 +01:00
WarmUpTill
bc0497d2c9 Add MacroWasCheckedSinceLastStart() 2024-11-02 08:28:52 +01:00
WarmUpTill
37226a3a4c Fix macro group icon not being displayed correctly in OBS 31
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-31 19:39:38 +01:00
WarmUpTill
9f15fbe47c Recursively search for source button in property groups
Some checks are pending
debian-build / build (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-30 18:29:23 +01:00
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
57 changed files with 697 additions and 308 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

@@ -109,6 +109,14 @@ bool MacroWasPausedSince(
return macro ? macro->WasPausedSince(time) : false; return macro ? macro->WasPausedSince(time) : false;
} }
bool MacroWasCheckedSinceLastStart(Macro *macro)
{
if (!macro) {
return false;
}
return macro->LastConditionCheckTime().time_since_epoch().count() != 0;
}
void AddMacroHelperThread(Macro *macro, std::thread &&newThread) void AddMacroHelperThread(Macro *macro, std::thread &&newThread)
{ {
if (!macro) { if (!macro) {

View File

@@ -51,6 +51,7 @@ EXPORT bool MacroIsPaused(Macro *);
EXPORT bool EXPORT bool
MacroWasPausedSince(Macro *, MacroWasPausedSince(Macro *,
const std::chrono::high_resolution_clock::time_point &); const std::chrono::high_resolution_clock::time_point &);
EXPORT bool MacroWasCheckedSinceLastStart(Macro *);
EXPORT void AddMacroHelperThread(Macro *, std::thread &&); EXPORT void AddMacroHelperThread(Macro *, std::thread &&);

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

@@ -178,6 +178,7 @@ void MacroTreeItem::Update(bool force)
QSizePolicy::Maximum); QSizePolicy::Maximum);
_expand->setMaximumSize(10, 16); _expand->setMaximumSize(10, 16);
_expand->setMinimumSize(10, 0); _expand->setMinimumSize(10, 0);
_expand->setProperty("class", "checkbox-icon indicator-expand");
#ifdef __APPLE__ #ifdef __APPLE__
_expand->setAttribute(Qt::WA_LayoutUsesWidgetRect); _expand->setAttribute(Qt::WA_LayoutUsesWidgetRect);
#endif #endif

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

@@ -123,27 +123,23 @@ MacroActionSystrayEdit::MacroActionSystrayEdit(
void MacroActionSystrayEdit::TitleChanged() void MacroActionSystrayEdit::TitleChanged()
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return;
}
auto lock = LockContext();
_entryData->_title = _title->text().toStdString(); _entryData->_title = _title->text().toStdString();
} }
void MacroActionSystrayEdit::IconPathChanged(const QString &text) void MacroActionSystrayEdit::IconPathChanged(const QString &text)
{ {
if (_loading || !_entryData) { GUARD_LOADING_AND_LOCK();
return;
}
auto lock = LockContext();
_entryData->_iconPath = text.toStdString(); _entryData->_iconPath = text.toStdString();
} }
void MacroActionSystrayEdit::CheckIfTrayIsDisabled() void MacroActionSystrayEdit::CheckIfTrayIsDisabled()
{ {
#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(31, 0, 0)
auto config = obs_frontend_get_user_config();
#else
auto config = obs_frontend_get_global_config(); auto config = obs_frontend_get_global_config();
#endif
if (!config) { if (!config) {
return; return;
} }

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

@@ -176,15 +176,21 @@ bool MacroConditionDate::CheckRegularDate(int64_t msSinceLastCheck)
bool MacroConditionDate::CheckCondition() bool MacroConditionDate::CheckCondition()
{ {
auto m = GetMacro(); auto macro = GetMacro();
if (!m) { if (!macro) {
return false; return false;
} }
const auto timePassed = std::chrono::high_resolution_clock::now() -
LastMacroConditionCheckTime(m); const auto now = std::chrono::high_resolution_clock::now();
const auto lastCheck = LastMacroConditionCheckTime(macro);
const auto timePassed = now - lastCheck;
const auto msSinceLastCheck = const auto msSinceLastCheck =
std::chrono::duration_cast<std::chrono::milliseconds>( MacroWasCheckedSinceLastStart(macro)
timePassed); ? std::chrono::duration_cast<std::chrono::milliseconds>(
timePassed)
: std::chrono::milliseconds(0);
if (_dayOfWeekCheck) { if (_dayOfWeekCheck) {
return CheckDayOfWeek(msSinceLastCheck.count()); return CheckDayOfWeek(msSinceLastCheck.count());

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

@@ -29,20 +29,37 @@ std::string SourceSettingButton::ToString() const
return "[" + id + "] " + description; return "[" + id + "] " + description;
} }
std::vector<SourceSettingButton> GetSourceButtons(OBSWeakSource source) static void getSourceButtonsHelper(obs_properties_t *sourceProperties,
std::vector<SourceSettingButton> &buttons)
{ {
OBSSourceAutoRelease s = obs_weak_source_get_source(source);
std::vector<SourceSettingButton> buttons;
obs_properties_t *sourceProperties = obs_source_properties(s);
auto it = obs_properties_first(sourceProperties); auto it = obs_properties_first(sourceProperties);
do { do {
if (!it || obs_property_get_type(it) != OBS_PROPERTY_BUTTON) { if (!it) {
continue;
}
auto type = obs_property_get_type(it);
if (type == OBS_PROPERTY_GROUP) {
auto group = obs_property_group_content(it);
getSourceButtonsHelper(group, buttons);
continue;
}
if (obs_property_get_type(it) != OBS_PROPERTY_BUTTON) {
continue; continue;
} }
SourceSettingButton button = {obs_property_name(it), SourceSettingButton button = {obs_property_name(it),
obs_property_description(it)}; obs_property_description(it)};
buttons.emplace_back(button); buttons.emplace_back(button);
} while (obs_property_next(&it)); } while (obs_property_next(&it));
}
std::vector<SourceSettingButton> GetSourceButtons(OBSWeakSource source)
{
OBSSourceAutoRelease s = obs_weak_source_get_source(source);
std::vector<SourceSettingButton> buttons;
auto sourceProperties = obs_source_properties(s);
getSourceButtonsHelper(sourceProperties, buttons);
obs_properties_destroy(sourceProperties); obs_properties_destroy(sourceProperties);
return buttons; return buttons;
} }

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>