mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-29 12:45:28 -05:00
Compare commits
3 Commits
1.32.8
...
lind-clean
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
189fa5c314 | ||
|
|
393d70be33 | ||
|
|
422c1a39cb |
@@ -166,7 +166,6 @@ target_sources(
|
||||
lib/macro/macro-tab.cpp
|
||||
lib/macro/macro-tree.cpp
|
||||
lib/macro/macro-tree.hpp
|
||||
lib/macro/macro-websocket-trigger.cpp
|
||||
lib/macro/macro.cpp
|
||||
lib/macro/macro.hpp)
|
||||
|
||||
|
||||
@@ -291,14 +291,14 @@ AdvSceneSwitcher.condition.replay.state.started="Replay Buffer gestartet"
|
||||
AdvSceneSwitcher.condition.replay.state.saved="Replay Buffer gespeichert"
|
||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||
AdvSceneSwitcher.condition.date="Datum"
|
||||
AdvSceneSwitcher.day.any="Beliebiger Tag"
|
||||
AdvSceneSwitcher.day.monday="Montag"
|
||||
AdvSceneSwitcher.day.tuesday="Dienstag"
|
||||
AdvSceneSwitcher.day.wednesday="Mittwoch"
|
||||
AdvSceneSwitcher.day.thursday="Donnerstag"
|
||||
AdvSceneSwitcher.day.friday="Freitag"
|
||||
AdvSceneSwitcher.day.saturday="Samstag"
|
||||
AdvSceneSwitcher.day.sunday="Sonntag"
|
||||
AdvSceneSwitcher.condition.date.anyDay="Beliebiger Tag"
|
||||
AdvSceneSwitcher.condition.date.monday="Montag"
|
||||
AdvSceneSwitcher.condition.date.tuesday="Dienstag"
|
||||
AdvSceneSwitcher.condition.date.wednesday="Mittwoch"
|
||||
AdvSceneSwitcher.condition.date.thursday="Donnerstag"
|
||||
AdvSceneSwitcher.condition.date.friday="Freitag"
|
||||
AdvSceneSwitcher.condition.date.saturday="Samstag"
|
||||
AdvSceneSwitcher.condition.date.sunday="Sonntag"
|
||||
AdvSceneSwitcher.condition.date.state.at="Am"
|
||||
AdvSceneSwitcher.condition.date.state.after="Nach"
|
||||
AdvSceneSwitcher.condition.date.state.before="Vor"
|
||||
@@ -309,13 +309,12 @@ AdvSceneSwitcher.condition.date.ignoreDate="Wenn diese Option nicht aktiviert is
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="Wenn diese Option nicht aktiviert ist, wird die Zeitkomponente ignoriert"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Erweiterte Einstellungen anzeigen"
|
||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Einfache Einstellungen anzeigen"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.day="Am{{dayOfWeek}}"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}} Wiederholen alle {{duration}} bei Datumsübereinstimmung"
|
||||
AdvSceneSwitcher.condition.date.layout.pattern="Aktuelles Datum \"{{currentDate}}\" entspricht dem Muster {{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Nächster Treffer bei: %1"
|
||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}} Bei Wiederholung ausgewähltes Datum auf Wiederholungsdatum aktualisieren"
|
||||
AdvSceneSwitcher.condition.date.entry.simple="Am {{dayOfWeek}} {{weekCondition}} {{ignoreWeekTime}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} Wiederholen alle {{duration}} bei Datumsübereinstimmung"
|
||||
AdvSceneSwitcher.condition.date.entry.pattern="Aktuelles Datum \"{{currentDate}}\" entspricht dem Muster {{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Nächster Treffer bei: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Bei Wiederholung ausgewähltes Datum auf Wiederholungsdatum aktualisieren"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Szenenelement transformieren"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Transformation erhalten"
|
||||
AdvSceneSwitcher.condition.sceneTransform.condition.match="entspricht Transformation"
|
||||
@@ -430,7 +429,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="Verstecken"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Umschalten"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Quelle"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Beliebig"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout="Auf{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Auf{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="Filter"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Aktivieren"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Deaktivieren"
|
||||
|
||||
@@ -157,15 +157,11 @@ AdvSceneSwitcher.mqttConnectionTab.removeMultipleConnectionsPopup.text="Are you
|
||||
|
||||
# Macro Tab
|
||||
AdvSceneSwitcher.macroTab.title="Macro"
|
||||
AdvSceneSwitcher.macroTab.macros="Macros"
|
||||
AdvSceneSwitcher.macroTab.priorityWarning="Note: It is recommended to configure macros to be the highest priority functionality.\nThis setting can be changed on the General tab."
|
||||
AdvSceneSwitcher.macroTab.help="Macros allow you to execute a string of actions depending on multiple conditions.\n\nClick on the highlighted plus symbol to add a new Macro."
|
||||
AdvSceneSwitcher.macroTab.macroLastExecutedTooltip="Was last executed %1 seconds ago."
|
||||
AdvSceneSwitcher.macroTab.macroNotYetExecutedTooltip="Was not yet executed."
|
||||
AdvSceneSwitcher.macroTab.editConditionHelp="This section allows you to define macro conditions.\n\nSelect an existing or add a new macro on the left.\nThen click the plus button below to add a new condition."
|
||||
AdvSceneSwitcher.macroTab.editActionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are met.\n\nSelect an existing or add a new macro on the left.\nThen click the plus button below to add a new action."
|
||||
AdvSceneSwitcher.macroTab.editElseActionHelp="This section allows you to define macro actions.\nThe actions in this section will be performed when the conditions are *not* met.\n\nSelect an existing or add a new macro on the left.\nThen click the plus button below to add a new action."
|
||||
AdvSceneSwitcher.macroTab.edit="Edit macro"
|
||||
AdvSceneSwitcher.macroTab.edit.logic="Logic type:"
|
||||
AdvSceneSwitcher.macroTab.edit.condition="Condition type:"
|
||||
AdvSceneSwitcher.macroTab.edit.action="Action type:"
|
||||
@@ -589,6 +585,14 @@ AdvSceneSwitcher.condition.replay.state.started="Replay buffer started"
|
||||
AdvSceneSwitcher.condition.replay.state.saved="Replay buffer saved"
|
||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||
AdvSceneSwitcher.condition.date="Date"
|
||||
AdvSceneSwitcher.condition.date.anyDay="Any day"
|
||||
AdvSceneSwitcher.condition.date.monday="Monday"
|
||||
AdvSceneSwitcher.condition.date.tuesday="Tuesday"
|
||||
AdvSceneSwitcher.condition.date.wednesday="Wednesday"
|
||||
AdvSceneSwitcher.condition.date.thursday="Thursday"
|
||||
AdvSceneSwitcher.condition.date.friday="Friday"
|
||||
AdvSceneSwitcher.condition.date.saturday="Saturday"
|
||||
AdvSceneSwitcher.condition.date.sunday="Sunday"
|
||||
AdvSceneSwitcher.condition.date.state.at="At"
|
||||
AdvSceneSwitcher.condition.date.state.after="After"
|
||||
AdvSceneSwitcher.condition.date.state.before="Before"
|
||||
@@ -599,13 +603,12 @@ AdvSceneSwitcher.condition.date.ignoreDate="If unchecked the date component will
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="If unchecked the time component will be ignored"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Show advanced settings"
|
||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Show simple settings"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.day="On{{dayOfWeek}}"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}}Repeat every{{duration}}on date match"
|
||||
AdvSceneSwitcher.condition.date.layout.pattern="Current date \"{{currentDate}}\" matches pattern{{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Next match at: %1"
|
||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}}On repeat update selected date to repeat date"
|
||||
AdvSceneSwitcher.condition.date.entry.simple="On{{dayOfWeek}}{{weekCondition}}{{ignoreWeekTime}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}}Repeat every{{duration}}on date match"
|
||||
AdvSceneSwitcher.condition.date.entry.pattern="Current date \"{{currentDate}}\" matches pattern{{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Next match at: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}On repeat update selected date to repeat date"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Scene item transform"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getCurrentValue="Get current value"
|
||||
@@ -911,9 +914,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Toggle"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Source"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Any"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout="On{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout.transition="{{updateTransition}}Set transition to{{transitions}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout.duration="{{updateDuration}}Set transition duration to{{duration}}seconds"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="On{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="Filter"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Enable"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Disable"
|
||||
@@ -1189,8 +1190,6 @@ AdvSceneSwitcher.action.variable.type.swapValues="Swap variable values"
|
||||
AdvSceneSwitcher.action.variable.type.trim="Trim whitespace"
|
||||
AdvSceneSwitcher.action.variable.type.changeCase="Change case"
|
||||
AdvSceneSwitcher.action.variable.type.randomNumber="Generate random number"
|
||||
AdvSceneSwitcher.action.variable.type.randomListValue="Select random value"
|
||||
AdvSceneSwitcher.action.variable.type.allowRepeat="Allow repeat values"
|
||||
AdvSceneSwitcher.action.variable.case.type.lowerCase="lowercase"
|
||||
AdvSceneSwitcher.action.variable.case.type.upperCase="UPPERCASE"
|
||||
AdvSceneSwitcher.action.variable.case.type.capitalized="Capitalized"
|
||||
@@ -2467,16 +2466,6 @@ AdvSceneSwitcher.clearBufferOnMatch="Clear message buffer when matching message
|
||||
AdvSceneSwitcher.script.settings="Settings"
|
||||
AdvSceneSwitcher.script.timeout="Script timeout:{{timeout}}"
|
||||
|
||||
AdvSceneSwitcher.day.monday="Monday"
|
||||
AdvSceneSwitcher.day.tuesday="Tuesday"
|
||||
AdvSceneSwitcher.day.wednesday="Wednesday"
|
||||
AdvSceneSwitcher.day.thursday="Thursday"
|
||||
AdvSceneSwitcher.day.friday="Friday"
|
||||
AdvSceneSwitcher.day.saturday="Saturday"
|
||||
AdvSceneSwitcher.day.sunday="Sunday"
|
||||
AdvSceneSwitcher.day.none="No day"
|
||||
AdvSceneSwitcher.day.any="Any day"
|
||||
|
||||
# This secion is copied from the OBS locale files
|
||||
|
||||
# OBS commonly shared locale
|
||||
|
||||
@@ -241,14 +241,14 @@ AdvSceneSwitcher.condition.replay.state.started="Búfer de reproducción iniciad
|
||||
AdvSceneSwitcher.condition.replay.state.saved="Búfer de reproducción guardado"
|
||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||
AdvSceneSwitcher.condition.date="Fecha"
|
||||
AdvSceneSwitcher.day.any="Cualquier día"
|
||||
AdvSceneSwitcher.day.monday="Lunes"
|
||||
AdvSceneSwitcher.day.tuesday="Martes"
|
||||
AdvSceneSwitcher.day.wednesday="Miércoles"
|
||||
AdvSceneSwitcher.day.thursday="Jueves"
|
||||
AdvSceneSwitcher.day.friday="Viernes"
|
||||
AdvSceneSwitcher.day.saturday="Sábado"
|
||||
AdvSceneSwitcher.day.sunday="Domingo"
|
||||
AdvSceneSwitcher.condition.date.anyDay="Cualquier día"
|
||||
AdvSceneSwitcher.condition.date.monday="Lunes"
|
||||
AdvSceneSwitcher.condition.date.tuesday="Martes"
|
||||
AdvSceneSwitcher.condition.date.wednesday="Miércoles"
|
||||
AdvSceneSwitcher.condition.date.thursday="Jueves"
|
||||
AdvSceneSwitcher.condition.date.friday="Viernes"
|
||||
AdvSceneSwitcher.condition.date.saturday="Sábado"
|
||||
AdvSceneSwitcher.condition.date.sunday="Domingo"
|
||||
AdvSceneSwitcher.condition.date.state.at="A las"
|
||||
AdvSceneSwitcher.condition.date.state.after="Después"
|
||||
AdvSceneSwitcher.condition.date.state.before="Antes"
|
||||
@@ -258,12 +258,11 @@ AdvSceneSwitcher.condition.date.ignoreDate="Si no se marca, se ignorará el comp
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="Si no se marca, se ignorará el componente de tiempo"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Mostrar configuración avanzada"
|
||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Mostrar configuración simple"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.day="El{{dayOfWeek}}"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}} Repetir cada {{duration}} en la coincidencia de fechas"
|
||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Próxima coincidencia en: %1"
|
||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha"
|
||||
AdvSceneSwitcher.condition.date.entry.simple="El {{dayOfWeek}} {{weekCondition}} {{ignoreWeekTime}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}} {{ignoreDate}}{{date}} {{ignoreTime}}{{time}} {{separator}} {{date2}} {{time2}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} Repetir cada {{duration}} en la coincidencia de fechas"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Próxima coincidencia en: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} Al repetir actualizar la fecha seleccionada para repetir la fecha"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Transformar elemento de escena"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtener transformación"
|
||||
AdvSceneSwitcher.condition.sceneTransform.condition.match="coincide con la transformación"
|
||||
@@ -351,7 +350,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.show="Mostrar"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Fuente"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Cualquiera"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout="En{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="En{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="Filtro"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Deshabilitar"
|
||||
|
||||
@@ -356,14 +356,14 @@ AdvSceneSwitcher.condition.replay.state.stopped="Tampon de répétition arrêté
|
||||
AdvSceneSwitcher.condition.replay.state.started="Tampon de répétition démarré"
|
||||
AdvSceneSwitcher.condition.replay.state.saved="Tampon de répétition enregistré"
|
||||
AdvSceneSwitcher.condition.date="Date"
|
||||
AdvSceneSwitcher.day.any="N'importe quel jour"
|
||||
AdvSceneSwitcher.day.monday="Lundi"
|
||||
AdvSceneSwitcher.day.tuesday="Mardi"
|
||||
AdvSceneSwitcher.day.wednesday="Mercredi"
|
||||
AdvSceneSwitcher.day.thursday="Jeudi"
|
||||
AdvSceneSwitcher.day.friday="Vendredi"
|
||||
AdvSceneSwitcher.day.saturday="Samedi"
|
||||
AdvSceneSwitcher.day.sunday="Dimanche"
|
||||
AdvSceneSwitcher.condition.date.anyDay="N'importe quel jour"
|
||||
AdvSceneSwitcher.condition.date.monday="Lundi"
|
||||
AdvSceneSwitcher.condition.date.tuesday="Mardi"
|
||||
AdvSceneSwitcher.condition.date.wednesday="Mercredi"
|
||||
AdvSceneSwitcher.condition.date.thursday="Jeudi"
|
||||
AdvSceneSwitcher.condition.date.friday="Vendredi"
|
||||
AdvSceneSwitcher.condition.date.saturday="Samedi"
|
||||
AdvSceneSwitcher.condition.date.sunday="Dimanche"
|
||||
AdvSceneSwitcher.condition.date.state.at="À"
|
||||
AdvSceneSwitcher.condition.date.state.after="Après"
|
||||
AdvSceneSwitcher.condition.date.state.before="Avant"
|
||||
@@ -374,12 +374,11 @@ AdvSceneSwitcher.condition.date.ignoreDate="Si non cochée, la composante date s
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="Si non cochée, la composante heure sera ignorée"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Afficher les paramètres avancés"
|
||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Afficher les paramètres simples"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.day="Le{{dayOfWeek}}"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}}Répéter toutes les{{duration}}lorsque la date correspond"
|
||||
AdvSceneSwitcher.condition.date.layout.pattern="La date actuelle \"{{currentDate}}\" correspond au motif{{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Prochaine correspondance à : %1"
|
||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}}À la répétition, mettre à jour la date sélectionnée pour la date de répétition"
|
||||
AdvSceneSwitcher.condition.date.entry.simple="Le{{dayOfWeek}}{{weekCondition}}{{ignoreWeekTime}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}}Répéter toutes les{{duration}}lorsque la date correspond"
|
||||
AdvSceneSwitcher.condition.date.entry.pattern="La date actuelle \"{{currentDate}}\" correspond au motif{{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Prochaine correspondance à : %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}À la répétition, mettre à jour la date sélectionnée pour la date de répétition"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Transformation de l'élément de la scène"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obtenir la transformation"
|
||||
AdvSceneSwitcher.condition.sceneTransform.condition.match="correspond à la transformation"
|
||||
@@ -511,7 +510,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="Masquer"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Basculer"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Source"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="N'importe"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout="Sur{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Sur{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="Filtre"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Activer"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Désactiver"
|
||||
|
||||
@@ -555,14 +555,14 @@ AdvSceneSwitcher.condition.replay.state.started="リプレイバッファを開
|
||||
AdvSceneSwitcher.condition.replay.state.saved="リプレイバッファを保存"
|
||||
; AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||
AdvSceneSwitcher.condition.date="日付条件"
|
||||
AdvSceneSwitcher.day.any="いつでも"
|
||||
AdvSceneSwitcher.day.monday="月曜日"
|
||||
AdvSceneSwitcher.day.tuesday="火曜日"
|
||||
AdvSceneSwitcher.day.wednesday="水曜日"
|
||||
AdvSceneSwitcher.day.thursday="木曜日"
|
||||
AdvSceneSwitcher.day.friday="金曜日"
|
||||
AdvSceneSwitcher.day.saturday="土曜日"
|
||||
AdvSceneSwitcher.day.sunday="日曜日"
|
||||
AdvSceneSwitcher.condition.date.anyDay="いつでも"
|
||||
AdvSceneSwitcher.condition.date.monday="月曜日"
|
||||
AdvSceneSwitcher.condition.date.tuesday="火曜日"
|
||||
AdvSceneSwitcher.condition.date.wednesday="水曜日"
|
||||
AdvSceneSwitcher.condition.date.thursday="木曜日"
|
||||
AdvSceneSwitcher.condition.date.friday="金曜日"
|
||||
AdvSceneSwitcher.condition.date.saturday="土曜日"
|
||||
AdvSceneSwitcher.condition.date.sunday="日曜日"
|
||||
; AdvSceneSwitcher.condition.date.state.at="At"
|
||||
AdvSceneSwitcher.condition.date.state.after="アフター"
|
||||
AdvSceneSwitcher.condition.date.state.before="前"
|
||||
@@ -573,9 +573,12 @@ AdvSceneSwitcher.condition.date.ignoreDate="チェックを外すと日付部分
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="チェックを外すと時間要素は無視されます"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="詳細設定を表示"
|
||||
AdvSceneSwitcher.condition.date.showSimpleSettings="簡単設定を表示"
|
||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}}日付の一致ごとに{{duration}}繰り返します"
|
||||
AdvSceneSwitcher.condition.date.layout.pattern="現在の日付「{{currentDate}}」はパターン{{pattern}}と一致します"
|
||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}}繰り返しの場合、選択した日付を繰り返しの日付に更新します"
|
||||
; AdvSceneSwitcher.condition.date.entry.simple="On{{dayOfWeek}}{{weekCondition}}{{ignoreWeekTime}}{{weekTime}}"
|
||||
; AdvSceneSwitcher.condition.date.entry.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}}日付の一致ごとに{{duration}}繰り返します"
|
||||
AdvSceneSwitcher.condition.date.entry.pattern="現在の日付「{{currentDate}}」はパターン{{pattern}}と一致します"
|
||||
; AdvSceneSwitcher.condition.date.entry.nextMatchDate="Next match at: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}繰り返しの場合、選択した日付を繰り返しの日付に更新します"
|
||||
; AdvSceneSwitcher.condition.sceneTransform="Scene item transform"
|
||||
; AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getCurrentValue="現在の値を取得"
|
||||
@@ -867,6 +870,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="非表示"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="切り替え"
|
||||
; AdvSceneSwitcher.action.sceneVisibility.type.source="Source"
|
||||
; AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Any"
|
||||
; AdvSceneSwitcher.action.sceneVisibility.entry="On{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="フィルタ"
|
||||
AdvSceneSwitcher.action.filter.type.enable="有効にする"
|
||||
AdvSceneSwitcher.action.filter.type.disable="無効化"
|
||||
|
||||
@@ -502,14 +502,14 @@ AdvSceneSwitcher.condition.replay.state.started="Buffer de replay iniciado"
|
||||
AdvSceneSwitcher.condition.replay.state.saved="Buffer de replay salvo"
|
||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||
AdvSceneSwitcher.condition.date="Data"
|
||||
AdvSceneSwitcher.day.any="Qualquer dia"
|
||||
AdvSceneSwitcher.day.monday="Segunda-feira"
|
||||
AdvSceneSwitcher.day.tuesday="Terça-feira"
|
||||
AdvSceneSwitcher.day.wednesday="Quarta-feira"
|
||||
AdvSceneSwitcher.day.thursday="Quinta-feira"
|
||||
AdvSceneSwitcher.day.friday="Sexta-feira"
|
||||
AdvSceneSwitcher.day.saturday="Sábado"
|
||||
AdvSceneSwitcher.day.sunday="Domingo"
|
||||
AdvSceneSwitcher.condition.date.anyDay="Qualquer dia"
|
||||
AdvSceneSwitcher.condition.date.monday="Segunda-feira"
|
||||
AdvSceneSwitcher.condition.date.tuesday="Terça-feira"
|
||||
AdvSceneSwitcher.condition.date.wednesday="Quarta-feira"
|
||||
AdvSceneSwitcher.condition.date.thursday="Quinta-feira"
|
||||
AdvSceneSwitcher.condition.date.friday="Sexta-feira"
|
||||
AdvSceneSwitcher.condition.date.saturday="Sábado"
|
||||
AdvSceneSwitcher.condition.date.sunday="Domingo"
|
||||
AdvSceneSwitcher.condition.date.state.at="Às"
|
||||
AdvSceneSwitcher.condition.date.state.after="Após"
|
||||
AdvSceneSwitcher.condition.date.state.before="Antes"
|
||||
@@ -520,13 +520,12 @@ AdvSceneSwitcher.condition.date.ignoreDate="Se desmarcado, o componente de data
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="Se desmarcado, o componente de tempo será ignorado"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="Mostrar configurações avançadas"
|
||||
AdvSceneSwitcher.condition.date.showSimpleSettings="Mostrar configurações simples"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.day="Em{{dayOfWeek}}"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}}Repetir a cada{{duration}}em correspondência de data"
|
||||
AdvSceneSwitcher.condition.date.layout.pattern="Data atual \"{{currentDate}}\" corresponde ao padrão{{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="Próxima correspondência em: %1"
|
||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}}Ao repetir, atualize a data selecionada para a data de repetição"
|
||||
AdvSceneSwitcher.condition.date.entry.simple="Em{{dayOfWeek}}{{weekCondition}}{{ignoreWeekTime}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}}Repetir a cada{{duration}}em correspondência de data"
|
||||
AdvSceneSwitcher.condition.date.entry.pattern="Data atual \"{{currentDate}}\" corresponde ao padrão{{pattern}}"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="Próxima correspondência em: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}}Ao repetir, atualize a data selecionada para a data de repetição"
|
||||
AdvSceneSwitcher.condition.sceneTransform="Transformação do item de cena"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="Obter transformação"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getCurrentValue="Obter valor atual"
|
||||
@@ -782,7 +781,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="Ocultar"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="Alternar"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Fonte"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Qualquer"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout="Em{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Em{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="Filtro"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Habilitar"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Desabilitar"
|
||||
|
||||
@@ -281,7 +281,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.show="Göster"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.hide="Gizle"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="Kayıt"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Herhangi"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout="Açık{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="Açık{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="Filtrele"
|
||||
AdvSceneSwitcher.action.filter.type.enable="Etkin"
|
||||
AdvSceneSwitcher.action.filter.type.disable="Etkisiz"
|
||||
|
||||
@@ -530,14 +530,14 @@ AdvSceneSwitcher.condition.replay.state.started="回放缓存已启动"
|
||||
AdvSceneSwitcher.condition.replay.state.saved="已保存回放缓存"
|
||||
AdvSceneSwitcher.condition.replay.entry="{{state}}"
|
||||
AdvSceneSwitcher.condition.date="日期"
|
||||
AdvSceneSwitcher.day.any="每一天"
|
||||
AdvSceneSwitcher.day.monday="周一"
|
||||
AdvSceneSwitcher.day.tuesday="周二"
|
||||
AdvSceneSwitcher.day.wednesday="周三"
|
||||
AdvSceneSwitcher.day.thursday="周四"
|
||||
AdvSceneSwitcher.day.friday="周五"
|
||||
AdvSceneSwitcher.day.saturday="周六"
|
||||
AdvSceneSwitcher.day.sunday="周日"
|
||||
AdvSceneSwitcher.condition.date.anyDay="每一天"
|
||||
AdvSceneSwitcher.condition.date.monday="周一"
|
||||
AdvSceneSwitcher.condition.date.tuesday="周二"
|
||||
AdvSceneSwitcher.condition.date.wednesday="周三"
|
||||
AdvSceneSwitcher.condition.date.thursday="周四"
|
||||
AdvSceneSwitcher.condition.date.friday="周五"
|
||||
AdvSceneSwitcher.condition.date.saturday="周六"
|
||||
AdvSceneSwitcher.condition.date.sunday="周日"
|
||||
AdvSceneSwitcher.condition.date.state.at="现在"
|
||||
AdvSceneSwitcher.condition.date.state.after="之后"
|
||||
AdvSceneSwitcher.condition.date.state.before="之前"
|
||||
@@ -548,13 +548,12 @@ AdvSceneSwitcher.condition.date.ignoreDate="如果未选中,日期组件将被
|
||||
AdvSceneSwitcher.condition.date.ignoreTime="如果未选中,时间组件将被忽略"
|
||||
AdvSceneSwitcher.condition.date.showAdvancedSettings="显示高级设置"
|
||||
AdvSceneSwitcher.condition.date.showSimpleSettings="显示简单设置"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.day="{{dayOfWeek}}"
|
||||
AdvSceneSwitcher.condition.date.layout.simple.time="{{ignoreWeekTime}}{{weekCondition}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.layout.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||
AdvSceneSwitcher.condition.date.layout.repeat="{{repeat}} 每 {{duration}} 重复一次时间/日期匹配"
|
||||
AdvSceneSwitcher.condition.date.layout.pattern="当前日期 \"{{currentDate}}\" 与 {{pattern}} 模式匹配 , 例子:2025 03 18 24 00 00 = .... .. .. .. .. .. ,难崩,我测试了一段时间才明白"
|
||||
AdvSceneSwitcher.condition.date.layout.nextMatchDate="下一次匹配 在: %1"
|
||||
AdvSceneSwitcher.condition.date.layout.updateOnRepeat="{{updateOnRepeat}} 在重复时将选定日期更新为重复日期"
|
||||
AdvSceneSwitcher.condition.date.entry.simple="{{dayOfWeek}}{{weekCondition}}{{ignoreWeekTime}}{{weekTime}}"
|
||||
AdvSceneSwitcher.condition.date.entry.advanced="{{condition}}{{ignoreDate}}{{date}}{{ignoreTime}}{{time}}{{separator}}{{date2}}{{time2}}"
|
||||
AdvSceneSwitcher.condition.date.entry.repeat="{{repeat}} 每 {{duration}} 重复一次时间/日期匹配"
|
||||
AdvSceneSwitcher.condition.date.entry.pattern="当前日期 \"{{currentDate}}\" 与 {{pattern}} 模式匹配 , 例子:2025 03 18 24 00 00 = .... .. .. .. .. .. ,难崩,我测试了一段时间才明白"
|
||||
AdvSceneSwitcher.condition.date.entry.nextMatchDate="下一次匹配 在: %1"
|
||||
AdvSceneSwitcher.condition.date.entry.updateOnRepeat="{{updateOnRepeat}} 在重复时将选定日期更新为重复日期"
|
||||
AdvSceneSwitcher.condition.sceneTransform="场景项目变换"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getTransform="获取变换"
|
||||
AdvSceneSwitcher.condition.sceneTransform.getCurrentValue="获取当前值"
|
||||
@@ -841,7 +840,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.hide="隐藏"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.toggle="切换可见性"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.source="源"
|
||||
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="任何"
|
||||
AdvSceneSwitcher.action.sceneVisibility.layout="{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.sceneVisibility.entry="{{scenes}}{{actions}}{{sources}}"
|
||||
AdvSceneSwitcher.action.filter="滤镜"
|
||||
AdvSceneSwitcher.action.filter.type.enable="开启"
|
||||
AdvSceneSwitcher.action.filter.type.disable="关闭"
|
||||
|
||||
@@ -68,10 +68,22 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>962</width>
|
||||
<height>1160</height>
|
||||
<height>1142</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="statusBox">
|
||||
<property name="title">
|
||||
@@ -590,11 +602,8 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>AdvSceneSwitcher.macroTab.macros</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_36">
|
||||
<widget class="QWidget" name="wrapper">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="macroPriorityWarning">
|
||||
<property name="text">
|
||||
@@ -677,66 +686,34 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="macroControlLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="macroAdd">
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroAddButton</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-plus</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="macroRemove">
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroRemoveButton</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">removeIconSmall</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-trash</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="macroUp">
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroUpButton</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">upArrowIconSmall</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="macroDown">
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroDownButton</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">downArrowIconSmall</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QToolBar" name="macrosToolbar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="floatable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<addaction name="macroAdd"/>
|
||||
<addaction name="macroRemove"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="macroUp"/>
|
||||
<addaction name="macroDown"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="macroEditGroup">
|
||||
<property name="title">
|
||||
<string>AdvSceneSwitcher.macroTab.edit</string>
|
||||
<string>AdvSceneSwitcher.macroTab.title</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_38">
|
||||
<item>
|
||||
@@ -4045,6 +4022,78 @@
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="macroAdd">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/res/images/plus.svg</normaloff>:/res/images/plus.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroAddButton</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-plus</string>
|
||||
</property>
|
||||
<property name="themeID" stdset="0">
|
||||
<string notr="true">addIconSmall</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="macroRemove">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/res/images/minus.svg</normaloff>:/res/images/minus.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroRemoveButton</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Del</string>
|
||||
</property>
|
||||
<property name="shortcutContext">
|
||||
<enum>Qt::WidgetWithChildrenShortcut</enum>
|
||||
</property>
|
||||
<property name="iconVisibleInMenu">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-trash</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="macroUp">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/res/images/up.svg</normaloff>:/res/images/up.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>MoveUp</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroUpButton</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-up</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="macroDown">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/res/images/down.svg</normaloff>:/res/images/down.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>MoveDown</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>AdvSceneSwitcher.macroTab.tooltip.macroDownButton</string>
|
||||
</property>
|
||||
<property name="class" stdset="0">
|
||||
<string notr="true">icon-down</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
@@ -4110,11 +4159,6 @@
|
||||
<tabstop>priorityUp</tabstop>
|
||||
<tabstop>priorityDown</tabstop>
|
||||
<tabstop>threadPriority</tabstop>
|
||||
<tabstop>macros</tabstop>
|
||||
<tabstop>macroAdd</tabstop>
|
||||
<tabstop>macroRemove</tabstop>
|
||||
<tabstop>macroUp</tabstop>
|
||||
<tabstop>macroDown</tabstop>
|
||||
<tabstop>macroName</tabstop>
|
||||
<tabstop>runMacro</tabstop>
|
||||
<tabstop>runMacroInParallel</tabstop>
|
||||
|
||||
@@ -192,7 +192,17 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
|
||||
|
||||
switcher->m.lock();
|
||||
if (switcher->VersionChanged(data, g_GIT_SHA1)) {
|
||||
AskForBackup(data);
|
||||
auto json = obs_data_get_json(data);
|
||||
static QString jsonQString = json ? json : "";
|
||||
std::thread t([]() {
|
||||
obs_queue_task(
|
||||
OBS_TASK_UI,
|
||||
[](void *) {
|
||||
AskForBackup(jsonQString);
|
||||
},
|
||||
nullptr, false);
|
||||
});
|
||||
t.detach();
|
||||
}
|
||||
|
||||
switcher->LoadSettings(data);
|
||||
|
||||
@@ -101,10 +101,10 @@ public:
|
||||
void HighlightMacroSettingsButton(bool enable = true);
|
||||
|
||||
public slots:
|
||||
void on_macroAdd_clicked();
|
||||
void on_macroRemove_clicked();
|
||||
void on_macroUp_clicked() const;
|
||||
void on_macroDown_clicked() const;
|
||||
void on_macroAdd_triggered();
|
||||
void on_macroRemove_triggered();
|
||||
void on_macroUp_triggered() const;
|
||||
void on_macroDown_triggered() const;
|
||||
void on_macroName_editingFinished();
|
||||
void on_runMacroInParallel_stateChanged(int value) const;
|
||||
void on_runMacroOnChange_stateChanged(int value) const;
|
||||
|
||||
@@ -219,43 +219,6 @@ void MacroActionVariable::GenerateRandomNumber(Variable *var)
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionVariable::PickRandomValue(Variable *var)
|
||||
{
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static const uint8_t maxIter = 255;
|
||||
|
||||
if (_randomValues.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_randomValues.size() == 1) {
|
||||
const auto &value = _randomValues.at(0);
|
||||
var->SetValue(value);
|
||||
_lastRandomValue = value;
|
||||
}
|
||||
|
||||
std::uniform_int_distribution<int> dis(0, _randomValues.size() - 1);
|
||||
StringVariable value = _randomValues.at(dis(gen));
|
||||
|
||||
uint8_t iter = 0;
|
||||
for (; !_allowRepeatValues && iter < maxIter &&
|
||||
_lastRandomValue.has_value() &&
|
||||
std::string(value) == _lastRandomValue.value();
|
||||
iter++) {
|
||||
value = _randomValues.at(dis(gen));
|
||||
}
|
||||
|
||||
if (iter == maxIter) {
|
||||
blog(LOG_INFO,
|
||||
"giving up picking non-repeat random value after %d tries",
|
||||
maxIter);
|
||||
}
|
||||
|
||||
var->SetValue(value);
|
||||
_lastRandomValue = value;
|
||||
}
|
||||
|
||||
struct AskForInputParams {
|
||||
AskForInputParams(const QString &prompt_, const QString &placeholder_)
|
||||
: prompt(prompt_),
|
||||
@@ -495,9 +458,6 @@ bool MacroActionVariable::PerformAction()
|
||||
case Action::RANDOM_NUMBER:
|
||||
GenerateRandomNumber(var.get());
|
||||
return true;
|
||||
case Action::RANDOM_LIST_VALUE:
|
||||
PickRandomValue(var.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -538,8 +498,6 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
|
||||
_randomNumberStart.Save(obj, "randomNumberStart");
|
||||
_randomNumberEnd.Save(obj, "randomNumberEnd");
|
||||
obs_data_set_bool(obj, "generateInteger", _generateInteger);
|
||||
_randomValues.Save(obj, "randomValues", "value");
|
||||
obs_data_set_bool(obj, "allowRepeatValues", _allowRepeatValues);
|
||||
_jsonQuery.Save(obj, "jsonQuery");
|
||||
_jsonIndex.Save(obj, "jsonIndex");
|
||||
|
||||
@@ -598,8 +556,6 @@ bool MacroActionVariable::Load(obs_data_t *obj)
|
||||
_randomNumberStart.Load(obj, "randomNumberStart");
|
||||
_randomNumberEnd.Load(obj, "randomNumberEnd");
|
||||
_generateInteger = obs_data_get_bool(obj, "generateInteger");
|
||||
_randomValues.Load(obj, "randomValues", "value");
|
||||
_allowRepeatValues = obs_data_get_bool(obj, "allowRepeatValues");
|
||||
_jsonQuery.Load(obj, "jsonQuery");
|
||||
_jsonIndex.Load(obj, "jsonIndex");
|
||||
|
||||
@@ -768,8 +724,6 @@ static inline void populateActionSelection(QComboBox *list)
|
||||
"AdvSceneSwitcher.action.variable.type.roundToInt"},
|
||||
{MacroActionVariable::Action::RANDOM_NUMBER,
|
||||
"AdvSceneSwitcher.action.variable.type.randomNumber"},
|
||||
{MacroActionVariable::Action::RANDOM_LIST_VALUE,
|
||||
"AdvSceneSwitcher.action.variable.type.randomListValue"},
|
||||
{true, ""}, // Separator
|
||||
|
||||
{MacroActionVariable::Action::USER_INPUT,
|
||||
@@ -882,13 +836,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.generateInteger"),
|
||||
this)),
|
||||
_randomNumberLayout(new QVBoxLayout()),
|
||||
_randomValues(new StringListEdit(this)),
|
||||
_allowRepeatValues(new QCheckBox(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.type.allowRepeat"),
|
||||
this)),
|
||||
_randomValueLayout(new QVBoxLayout()),
|
||||
_randomLayout(new QVBoxLayout()),
|
||||
_jsonQuery(new VariableLineEdit(this)),
|
||||
_jsonQueryHelp(new HelpIcon(
|
||||
obs_module_text(
|
||||
@@ -924,7 +872,6 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
_randomNumberStart->setMaximum(9999999999);
|
||||
_randomNumberEnd->setMinimum(-9999999999);
|
||||
_randomNumberEnd->setMaximum(9999999999);
|
||||
_randomValues->SetMaxStringSize(99999999);
|
||||
_jsonIndex->setMaximum(999);
|
||||
|
||||
QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)),
|
||||
@@ -1013,11 +960,6 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
SLOT(RandomNumberEndChanged(const NumberVariable<double> &)));
|
||||
QWidget::connect(_generateInteger, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(GenerateIntegerChanged(int)));
|
||||
QWidget::connect(_randomValues,
|
||||
SIGNAL(StringListChanged(const StringList &)), this,
|
||||
SLOT(RandomValueListChanged(const StringList &)));
|
||||
QWidget::connect(_allowRepeatValues, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(AllowRepeatValuesChanged(int)));
|
||||
QWidget::connect(_jsonQuery, SIGNAL(editingFinished()), this,
|
||||
SLOT(JsonQueryChanged()));
|
||||
QWidget::connect(
|
||||
@@ -1084,11 +1026,8 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.variable.layout.randomNumber"),
|
||||
randomLayout, widgetPlaceholders);
|
||||
_randomNumberLayout->addLayout(randomLayout);
|
||||
_randomNumberLayout->addWidget(_generateInteger);
|
||||
|
||||
_randomValueLayout->addWidget(_randomValues);
|
||||
_randomValueLayout->addWidget(_allowRepeatValues);
|
||||
_randomLayout->addLayout(randomLayout);
|
||||
_randomLayout->addWidget(_generateInteger);
|
||||
|
||||
auto regexConfigLayout = new QHBoxLayout;
|
||||
regexConfigLayout->addWidget(_subStringRegex);
|
||||
@@ -1107,8 +1046,7 @@ MacroActionVariableEdit::MacroActionVariableEdit(
|
||||
layout->addWidget(_mathExpressionResult);
|
||||
layout->addLayout(_promptLayout);
|
||||
layout->addLayout(_placeholderLayout);
|
||||
layout->addLayout(_randomNumberLayout);
|
||||
layout->addLayout(_randomValueLayout);
|
||||
layout->addLayout(_randomLayout);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
@@ -1167,8 +1105,6 @@ void MacroActionVariableEdit::UpdateEntryData()
|
||||
_randomNumberStart->SetValue(_entryData->_randomNumberStart);
|
||||
_randomNumberEnd->SetValue(_entryData->_randomNumberEnd);
|
||||
_generateInteger->setChecked(_entryData->_generateInteger);
|
||||
_allowRepeatValues->setChecked(_entryData->_allowRepeatValues);
|
||||
_randomValues->SetStringList(_entryData->_randomValues);
|
||||
_jsonQuery->setText(_entryData->_jsonQuery);
|
||||
_jsonIndex->SetValue(_entryData->_jsonIndex);
|
||||
|
||||
@@ -1511,18 +1447,6 @@ void MacroActionVariableEdit::GenerateIntegerChanged(int value)
|
||||
_entryData->_generateInteger = value;
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::RandomValueListChanged(const StringList &values)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_randomValues = values;
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::AllowRepeatValuesChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_allowRepeatValues = value;
|
||||
}
|
||||
|
||||
void MacroActionVariableEdit::JsonQueryChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
@@ -1717,13 +1641,9 @@ void MacroActionVariableEdit::SetWidgetVisibility()
|
||||
MacroActionVariable::Action::PAD);
|
||||
_caseType->setVisible(_entryData->_action ==
|
||||
MacroActionVariable::Action::CHANGE_CASE);
|
||||
SetLayoutVisible(_randomNumberLayout,
|
||||
SetLayoutVisible(_randomLayout,
|
||||
_entryData->_action ==
|
||||
MacroActionVariable::Action::RANDOM_NUMBER);
|
||||
SetLayoutVisible(
|
||||
_randomValueLayout,
|
||||
_entryData->_action ==
|
||||
MacroActionVariable::Action::RANDOM_LIST_VALUE);
|
||||
_jsonQuery->setVisible(_entryData->_action ==
|
||||
MacroActionVariable::Action::QUERY_JSON);
|
||||
_jsonQueryHelp->setVisible(_entryData->_action ==
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "resizing-text-edit.hpp"
|
||||
#include "scene-selection.hpp"
|
||||
#include "single-char-selection.hpp"
|
||||
#include "string-list.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
@@ -57,7 +56,6 @@ public:
|
||||
QUERY_JSON,
|
||||
ARRAY_JSON,
|
||||
COPY_VAR,
|
||||
RANDOM_LIST_VALUE,
|
||||
};
|
||||
|
||||
Action _action = Action::SET_VALUE;
|
||||
@@ -109,10 +107,6 @@ public:
|
||||
DoubleVariable _randomNumberEnd = 100;
|
||||
bool _generateInteger = true;
|
||||
|
||||
StringList _randomValues = {"value1", "value2", "value3"};
|
||||
bool _allowRepeatValues = true;
|
||||
std::optional<std::string> _lastRandomValue;
|
||||
|
||||
StringVariable _jsonQuery = "$.some.nested.value";
|
||||
IntVariable _jsonIndex = 0;
|
||||
|
||||
@@ -125,7 +119,6 @@ private:
|
||||
void HandleCaseChange(Variable *);
|
||||
void SetToSceneItemName(Variable *);
|
||||
void GenerateRandomNumber(Variable *);
|
||||
void PickRandomValue(Variable *);
|
||||
|
||||
std::weak_ptr<MacroSegment> _macroSegment;
|
||||
int _segmentIdxLoadValue = -1;
|
||||
@@ -182,8 +175,6 @@ private slots:
|
||||
void RandomNumberStartChanged(const NumberVariable<double> &);
|
||||
void RandomNumberEndChanged(const NumberVariable<double> &);
|
||||
void GenerateIntegerChanged(int);
|
||||
void RandomValueListChanged(const StringList &);
|
||||
void AllowRepeatValuesChanged(int);
|
||||
void JsonQueryChanged();
|
||||
void JsonIndexChanged(const NumberVariable<int> &);
|
||||
|
||||
@@ -233,10 +224,7 @@ private:
|
||||
VariableDoubleSpinBox *_randomNumberStart;
|
||||
VariableDoubleSpinBox *_randomNumberEnd;
|
||||
QCheckBox *_generateInteger;
|
||||
QVBoxLayout *_randomNumberLayout;
|
||||
StringListEdit *_randomValues;
|
||||
QCheckBox *_allowRepeatValues;
|
||||
QVBoxLayout *_randomValueLayout;
|
||||
QVBoxLayout *_randomLayout;
|
||||
VariableLineEdit *_jsonQuery;
|
||||
QLabel *_jsonQueryHelp;
|
||||
VariableSpinBox *_jsonIndex;
|
||||
|
||||
@@ -242,11 +242,6 @@ bool RunMacroActions(Macro *macro)
|
||||
return macro && macro->PerformActions(true);
|
||||
}
|
||||
|
||||
bool RunMacroElseActions(Macro *macro)
|
||||
{
|
||||
return macro && macro->PerformActions(false);
|
||||
}
|
||||
|
||||
void ResetMacroConditionTimers(Macro *macro)
|
||||
{
|
||||
if (!macro) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
|
||||
struct obs_data;
|
||||
@@ -68,7 +69,6 @@ EXPORT void AddMacroHelperThread(Macro *, std::thread &&);
|
||||
EXPORT bool CheckMacros();
|
||||
|
||||
EXPORT bool RunMacroActions(Macro *);
|
||||
bool RunMacroElseActions(Macro *);
|
||||
EXPORT bool RunMacros();
|
||||
void StopAllMacros();
|
||||
|
||||
|
||||
@@ -25,8 +25,6 @@ namespace advss {
|
||||
|
||||
static QObject *addPulse = nullptr;
|
||||
static QTimer onChangeHighlightTimer;
|
||||
static std::chrono::high_resolution_clock::time_point
|
||||
lastOnChangeHighlightCheckTime{};
|
||||
|
||||
static void disableAddButtonHighlight()
|
||||
{
|
||||
@@ -99,7 +97,7 @@ bool AdvSceneSwitcher::AddNewMacro(std::shared_ptr<Macro> &res,
|
||||
return true;
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroAdd_clicked()
|
||||
void AdvSceneSwitcher::on_macroAdd_triggered()
|
||||
{
|
||||
// Hotkey to add new macro will also use this function.
|
||||
// Since we don't want the hotkey to have an effect if the macro tab is
|
||||
@@ -249,12 +247,12 @@ void AdvSceneSwitcher::RenameMacro(std::shared_ptr<Macro> ¯o,
|
||||
MacroSignalManager::Instance()->Rename(oldName, name);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroRemove_clicked()
|
||||
void AdvSceneSwitcher::on_macroRemove_triggered()
|
||||
{
|
||||
RemoveSelectedMacros();
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroUp_clicked() const
|
||||
void AdvSceneSwitcher::on_macroUp_triggered() const
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
@@ -263,7 +261,7 @@ void AdvSceneSwitcher::on_macroUp_clicked() const
|
||||
ui->macros->Up(macro);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroDown_clicked() const
|
||||
void AdvSceneSwitcher::on_macroDown_triggered() const
|
||||
{
|
||||
auto macro = GetSelectedMacro();
|
||||
if (!macro) {
|
||||
@@ -552,14 +550,10 @@ void AdvSceneSwitcher::HighlightOnChange() const
|
||||
return;
|
||||
}
|
||||
|
||||
if (macro->OnChangePreventedActionsSince(
|
||||
lastOnChangeHighlightCheckTime)) {
|
||||
if (macro->OnChangePreventedActionsRecently()) {
|
||||
HighlightWidget(ui->runMacroOnChange, Qt::yellow,
|
||||
Qt::transparent, true);
|
||||
}
|
||||
|
||||
lastOnChangeHighlightCheckTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_macroSettings_clicked()
|
||||
@@ -638,13 +632,11 @@ void AdvSceneSwitcher::SetupMacroTab()
|
||||
auto ¯os = GetTopLevelMacros();
|
||||
|
||||
if (macros.size() == 0 && !switcher->disableHints) {
|
||||
addPulse = HighlightWidget(ui->macroAdd, QColor(Qt::green));
|
||||
addPulse = HighlightWidget(
|
||||
ui->macrosToolbar->widgetForAction(ui->macroAdd),
|
||||
QColor(Qt::green));
|
||||
}
|
||||
|
||||
auto macroControls = setupToolBar({{ui->macroAdd, ui->macroRemove},
|
||||
{ui->macroUp, ui->macroDown}});
|
||||
ui->macroControlLayout->addWidget(macroControls);
|
||||
|
||||
ui->macros->Reset(macros, GetGlobalMacroSettings()._highlightExecuted);
|
||||
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
|
||||
SLOT(MacroSelectionChanged()));
|
||||
@@ -658,8 +650,6 @@ void AdvSceneSwitcher::SetupMacroTab()
|
||||
ui->macroPriorityWarning->setVisible(
|
||||
switcher->functionNamesByPriority[0] != macro_func);
|
||||
|
||||
lastOnChangeHighlightCheckTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
onChangeHighlightTimer.setInterval(1500);
|
||||
connect(&onChangeHighlightTimer, SIGNAL(timeout()), this,
|
||||
SLOT(HighlightOnChange()));
|
||||
@@ -691,7 +681,7 @@ void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos)
|
||||
|
||||
menu.addAction(
|
||||
obs_module_text("AdvSceneSwitcher.macroTab.contextMenuAdd"),
|
||||
this, &AdvSceneSwitcher::on_macroAdd_clicked);
|
||||
this, &AdvSceneSwitcher::on_macroAdd_triggered);
|
||||
|
||||
auto copy = menu.addAction(
|
||||
obs_module_text("AdvSceneSwitcher.macroTab.copy"), this,
|
||||
@@ -707,7 +697,7 @@ void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos)
|
||||
|
||||
auto remove = menu.addAction(
|
||||
obs_module_text("AdvSceneSwitcher.macroTab.remove"), this,
|
||||
&AdvSceneSwitcher::on_macroRemove_clicked);
|
||||
&AdvSceneSwitcher::on_macroRemove_triggered);
|
||||
remove->setDisabled(ui->macros->SelectionEmpty());
|
||||
menu.addSeparator();
|
||||
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
#include "path-helpers.hpp"
|
||||
#include "sync-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <obs.h>
|
||||
#include <string>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QSpacerItem>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QStylePainter>
|
||||
#include <QToolTip>
|
||||
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<advss::Macro>);
|
||||
|
||||
@@ -89,35 +90,6 @@ MacroTreeItem::MacroTreeItem(MacroTree *tree, std::shared_ptr<Macro> macroItem,
|
||||
_timer.start(1500);
|
||||
}
|
||||
|
||||
bool MacroTreeItem::event(QEvent *event)
|
||||
{
|
||||
if (event->type() != QEvent::ToolTip) {
|
||||
return QFrame::event(event);
|
||||
}
|
||||
|
||||
if (_macro->IsGroup()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString text;
|
||||
if (!_macro->WasExecutedSince({})) {
|
||||
text = obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.macroNotYetExecutedTooltip");
|
||||
} else {
|
||||
const QString formatStr = obs_module_text(
|
||||
"AdvSceneSwitcher.macroTab.macroLastExecutedTooltip");
|
||||
const auto secondsSinceLastRun =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::high_resolution_clock::now() -
|
||||
_macro->GetLastExecutionTime());
|
||||
text = formatStr.arg(secondsSinceLastRun.count());
|
||||
}
|
||||
|
||||
auto helpEvent = static_cast<QHelpEvent *>(event);
|
||||
QToolTip::showText(helpEvent->globalPos(), text, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroTreeItem::EnableHighlight(bool enable)
|
||||
{
|
||||
_highlight = enable;
|
||||
@@ -215,19 +187,10 @@ void MacroTreeItem::HighlightIfExecuted()
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasHighlighted = false;
|
||||
if (_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
||||
_macro->WasExecutedSince(_lastHighlightCheckTime)) {
|
||||
HighlightWidget(this, Qt::green, QColor(0, 0, 0, 0), true);
|
||||
wasHighlighted = true;
|
||||
}
|
||||
|
||||
if (!wasHighlighted &&
|
||||
_lastHighlightCheckTime.time_since_epoch().count() != 0 &&
|
||||
_macro->OnChangePreventedActionsSince(_lastHighlightCheckTime)) {
|
||||
HighlightWidget(this, Qt::yellow, QColor(0, 0, 0, 0), true);
|
||||
}
|
||||
|
||||
_lastHighlightCheckTime = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
@@ -304,7 +267,7 @@ void MacroTreeItem::Update(bool force)
|
||||
_expand->blockSignals(true);
|
||||
_expand->setChecked(_macro->IsCollapsed());
|
||||
_expand->blockSignals(false);
|
||||
connect(_expand, &QCheckBox::toggled, this,
|
||||
connect(_expand, &QPushButton::toggled, this,
|
||||
&MacroTreeItem::ExpandClicked);
|
||||
} else {
|
||||
_spacer = new QSpacerItem(3, 1);
|
||||
|
||||
@@ -34,9 +34,6 @@ public:
|
||||
explicit MacroTreeItem(MacroTree *tree, std::shared_ptr<Macro> macro,
|
||||
bool highlight);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *) override;
|
||||
|
||||
private slots:
|
||||
void ExpandClicked(bool checked);
|
||||
void EnableHighlight(bool enable);
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#include "websocket-api.hpp"
|
||||
#include "log-helper.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "variable.hpp"
|
||||
#include "macro-helpers.hpp"
|
||||
|
||||
#include <obs.hpp>
|
||||
|
||||
namespace advss {
|
||||
|
||||
static bool setup();
|
||||
static bool setupDone = setup();
|
||||
static void receiveRunMacroMessage(obs_data_t *data, obs_data_t *);
|
||||
static void receiveSetVariablesMessage(obs_data_t *data, obs_data_t *);
|
||||
|
||||
static const char *runMacroMessage = "AdvancedSceneSwitcherRunMacro";
|
||||
static const char *setVariablesMessage = "AdvancedSceneSwitcherSetVariables";
|
||||
|
||||
static bool setup()
|
||||
{
|
||||
AddPluginInitStep([]() {
|
||||
RegisterWebsocketRequest(runMacroMessage,
|
||||
receiveRunMacroMessage);
|
||||
RegisterWebsocketRequest(setVariablesMessage,
|
||||
receiveSetVariablesMessage);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
static void setVariables(obs_data_t *data)
|
||||
{
|
||||
OBSDataArrayAutoRelease variables =
|
||||
obs_data_get_array(data, "variables");
|
||||
size_t count = obs_data_array_count(variables);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
OBSDataAutoRelease item = obs_data_array_item(variables, i);
|
||||
if (!obs_data_has_user_value(item, "name")) {
|
||||
blog(LOG_INFO,
|
||||
"ignoring invalid variable entry in \"%s\" websocket message (missing \"name\")",
|
||||
runMacroMessage);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!obs_data_has_user_value(item, "value")) {
|
||||
blog(LOG_INFO,
|
||||
"ignoring invalid variable entry in \"%s\" websocket message (missing \"value\")",
|
||||
runMacroMessage);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto varName = obs_data_get_string(item, "name");
|
||||
auto value = obs_data_get_string(item, "value");
|
||||
|
||||
auto weakVar = GetWeakVariableByName(varName);
|
||||
auto var = weakVar.lock();
|
||||
if (!var) {
|
||||
blog(LOG_INFO,
|
||||
"ignoring invalid variable name \"%s\" in \"%s\" websocket message",
|
||||
varName, runMacroMessage);
|
||||
continue;
|
||||
}
|
||||
|
||||
var->SetValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
static void receiveRunMacroMessage(obs_data_t *data, obs_data_t *)
|
||||
{
|
||||
if (!obs_data_has_user_value(data, "name")) {
|
||||
blog(LOG_INFO,
|
||||
"ignoring invalid \"%s\" websocket message (missing \"name\")",
|
||||
runMacroMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
auto name = obs_data_get_string(data, "name");
|
||||
const auto weakMacro =
|
||||
GetWeakMacroByName(obs_data_get_string(data, "name"));
|
||||
const auto macro = weakMacro.lock();
|
||||
if (!macro) {
|
||||
blog(LOG_INFO,
|
||||
"ignoring invalid \"%s\" websocket message (macro \"%s\") not found",
|
||||
runMacroMessage, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obs_data_has_user_value(data, "variables")) {
|
||||
setVariables(data);
|
||||
}
|
||||
|
||||
const bool runElse = obs_data_get_bool(data, "runElseActions");
|
||||
if (runElse) {
|
||||
RunMacroElseActions(macro.get());
|
||||
} else {
|
||||
RunMacroActions(macro.get());
|
||||
}
|
||||
}
|
||||
|
||||
static void receiveSetVariablesMessage(obs_data_t *data, obs_data_t *)
|
||||
{
|
||||
if (!obs_data_has_user_value(data, "variables")) {
|
||||
blog(LOG_INFO,
|
||||
"ignoring invalid \"%s\" websocket message (missing \"variables\")",
|
||||
setVariablesMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
setVariables(data);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
@@ -242,12 +242,8 @@ bool Macro::CheckConditions(bool ignorePause)
|
||||
vblog(LOG_INFO, "Macro %s returned %d", _name.c_str(), _matched);
|
||||
|
||||
_conditionSateChanged = _lastMatched != _matched;
|
||||
const bool hasActionsToExecute = _matched ? (_actions.size() > 0)
|
||||
: (_elseActions.size() > 0);
|
||||
if (!_conditionSateChanged && _performActionsOnChange &&
|
||||
hasActionsToExecute) {
|
||||
_lastOnChangeActionsPreventedTime =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
if (!_conditionSateChanged && _performActionsOnChange) {
|
||||
_onPreventedActionExecution = true;
|
||||
}
|
||||
|
||||
_lastMatched = _matched;
|
||||
@@ -306,16 +302,6 @@ bool Macro::WasExecutedSince(const TimePoint &time) const
|
||||
return _lastExecutionTime > time;
|
||||
}
|
||||
|
||||
bool Macro::OnChangePreventedActionsSince(const TimePoint &time) const
|
||||
{
|
||||
return _lastOnChangeActionsPreventedTime > time;
|
||||
}
|
||||
|
||||
Macro::TimePoint Macro::GetLastExecutionTime() const
|
||||
{
|
||||
return _lastExecutionTime;
|
||||
}
|
||||
|
||||
bool Macro::ConditionsShouldBeChecked() const
|
||||
{
|
||||
if (!_useCustomConditionCheckInterval) {
|
||||
@@ -1000,8 +986,18 @@ bool Macro::HasValidSplitterPositions() const
|
||||
!_elseActionSplitterPosition.empty();
|
||||
}
|
||||
|
||||
bool Macro::OnChangePreventedActionsRecently()
|
||||
{
|
||||
if (_onPreventedActionExecution) {
|
||||
_onPreventedActionExecution = false;
|
||||
return _matched ? _actions.size() > 0 : _elseActions.size() > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Macro::ResetUIHelpers()
|
||||
{
|
||||
_onPreventedActionExecution = false;
|
||||
for (auto c : _conditions) {
|
||||
c->GetHighlightAndReset();
|
||||
}
|
||||
|
||||
@@ -137,8 +137,7 @@ public:
|
||||
const QList<int> &GetElseActionSplitterPosition() const;
|
||||
bool HasValidSplitterPositions() const;
|
||||
bool WasExecutedSince(const TimePoint &) const;
|
||||
bool OnChangePreventedActionsSince(const TimePoint &) const;
|
||||
TimePoint GetLastExecutionTime() const;
|
||||
bool OnChangePreventedActionsRecently();
|
||||
void ResetUIHelpers();
|
||||
|
||||
// Hotkeys
|
||||
@@ -169,7 +168,6 @@ private:
|
||||
TimePoint _lastCheckTime{};
|
||||
TimePoint _lastUnpauseTime{};
|
||||
TimePoint _lastExecutionTime{};
|
||||
TimePoint _lastOnChangeActionsPreventedTime{};
|
||||
std::vector<std::thread> _helperThreads;
|
||||
|
||||
std::deque<std::shared_ptr<MacroCondition>> _conditions;
|
||||
@@ -206,6 +204,9 @@ private:
|
||||
|
||||
MacroInputVariables _inputVariables;
|
||||
|
||||
// UI helpers
|
||||
bool _onPreventedActionExecution = false;
|
||||
|
||||
QList<int> _actionConditionSplitterPosition;
|
||||
QList<int> _elseActionSplitterPosition;
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "auto-update-tooltip-label.hpp"
|
||||
|
||||
#include <QToolTip>
|
||||
|
||||
namespace advss {
|
||||
|
||||
AutoUpdateHelpIcon::AutoUpdateHelpIcon(
|
||||
@@ -18,7 +16,6 @@ AutoUpdateHelpIcon::AutoUpdateHelpIcon(
|
||||
|
||||
void AutoUpdateHelpIcon::enterEvent(QEnterEvent *event)
|
||||
{
|
||||
UpdateTooltip();
|
||||
_timer->start(_updateIntervalMs);
|
||||
QLabel::enterEvent(event);
|
||||
}
|
||||
@@ -31,12 +28,7 @@ void AutoUpdateHelpIcon::leaveEvent(QEvent *event)
|
||||
|
||||
void AutoUpdateHelpIcon::UpdateTooltip()
|
||||
{
|
||||
if (!underMouse()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString text = _callback();
|
||||
QToolTip::showText(QCursor::pos(), text, this);
|
||||
setToolTip(_callback());
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -8,18 +8,13 @@
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
#include <obs-module.h>
|
||||
#include <util/config-file.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMainWindow>
|
||||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
|
||||
#include <thread>
|
||||
#include <util/config-file.h>
|
||||
|
||||
namespace advss {
|
||||
|
||||
static void showBackupDialogs(const QString &json)
|
||||
void AskForBackup(const QString &json)
|
||||
{
|
||||
const bool backupWasConfirmed = DisplayMessage(
|
||||
obs_module_text("AdvSceneSwitcher.askBackup"), true, false);
|
||||
@@ -47,40 +42,6 @@ static void showBackupDialogs(const QString &json)
|
||||
out << json;
|
||||
}
|
||||
|
||||
void AskForBackup(obs_data_t *settings)
|
||||
{
|
||||
// This function is called while the plugin settings are being loaded.
|
||||
// Blocking at this stage can cause issues such as OBS failing to start
|
||||
// or crashing.
|
||||
// Therefore, we ask the user whether they want to back up the settings
|
||||
// asynchronously.
|
||||
//
|
||||
// On macOS, an additional QTimer::singleShot wrapper is required for
|
||||
// this to work correctly.
|
||||
|
||||
auto json = obs_data_get_json(settings);
|
||||
static QString jsonQString = json ? json : "";
|
||||
|
||||
static const auto askForBackupWrapper = [](void *) {
|
||||
#ifdef __APPLE__
|
||||
QTimer::singleShot(0,
|
||||
static_cast<QMainWindow *>(
|
||||
obs_frontend_get_main_window()),
|
||||
[]() {
|
||||
#endif
|
||||
showBackupDialogs(jsonQString);
|
||||
#ifdef __APPLE__
|
||||
});
|
||||
#endif
|
||||
};
|
||||
|
||||
std::thread t([]() {
|
||||
obs_queue_task(OBS_TASK_UI, askForBackupWrapper, nullptr,
|
||||
false);
|
||||
});
|
||||
t.detach();
|
||||
}
|
||||
|
||||
void BackupSettingsOfCurrentVersion()
|
||||
{
|
||||
auto sceneCollectionName = obs_frontend_get_current_scene_collection();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
#include <obs-data.h>
|
||||
#include <QString>
|
||||
|
||||
namespace advss {
|
||||
|
||||
void AskForBackup(obs_data_t *settings);
|
||||
void AskForBackup(const QString &json);
|
||||
void BackupSettingsOfCurrentVersion();
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
|
||||
#include <thread>
|
||||
|
||||
@@ -106,13 +104,10 @@ static bool wasUncleanShutdown()
|
||||
return true;
|
||||
}
|
||||
|
||||
static void askForStartupSkip()
|
||||
static bool askForStartupSkip()
|
||||
{
|
||||
bool skipStart = DisplayMessage(
|
||||
obs_module_text("AdvSceneSwitcher.crashDetected"), true, false);
|
||||
if (!skipStart) {
|
||||
StartPlugin();
|
||||
}
|
||||
return DisplayMessage(obs_module_text("AdvSceneSwitcher.crashDetected"),
|
||||
true, false);
|
||||
}
|
||||
|
||||
bool ShouldSkipPluginStartOnUncleanShutdown()
|
||||
@@ -121,29 +116,16 @@ bool ShouldSkipPluginStartOnUncleanShutdown()
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function is called while the plugin settings are being loaded.
|
||||
// Blocking at this stage can cause issues such as OBS failing to start
|
||||
// or crashing.
|
||||
// Therefore, we ask the user whether they want to start the plugin
|
||||
// asynchronously.
|
||||
//
|
||||
// On macOS, an additional QTimer::singleShot wrapper is required for
|
||||
// this to work correctly.
|
||||
static const auto showDialogWrapper = [](void *) {
|
||||
#ifdef __APPLE__
|
||||
QTimer::singleShot(0,
|
||||
static_cast<QMainWindow *>(
|
||||
obs_frontend_get_main_window()),
|
||||
[]() {
|
||||
#endif
|
||||
askForStartupSkip();
|
||||
#ifdef __APPLE__
|
||||
});
|
||||
#endif
|
||||
};
|
||||
|
||||
std::thread t([]() {
|
||||
obs_queue_task(OBS_TASK_UI, showDialogWrapper, nullptr, false);
|
||||
obs_queue_task(
|
||||
OBS_TASK_UI,
|
||||
[](void *) {
|
||||
const bool skipStart = askForStartupSkip();
|
||||
if (!skipStart) {
|
||||
StartPlugin();
|
||||
}
|
||||
},
|
||||
nullptr, false);
|
||||
});
|
||||
t.detach();
|
||||
|
||||
|
||||
@@ -4,11 +4,9 @@
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QAction>
|
||||
#include <QLayout>
|
||||
#include <QMenu>
|
||||
#include <QTimer>
|
||||
#include <QLayout>
|
||||
|
||||
Q_DECLARE_METATYPE(advss::Item *);
|
||||
|
||||
@@ -332,13 +330,6 @@ void ItemSettingsDialog::NameChanged(const QString &text)
|
||||
SetNameWarning("");
|
||||
}
|
||||
|
||||
void ItemSettingsDialog::showEvent(QShowEvent *)
|
||||
{
|
||||
if (_showNameEmptyWarning && _name->text().isEmpty()) {
|
||||
_name->setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
}
|
||||
|
||||
void ItemSettingsDialog::SetNameWarning(const QString warn)
|
||||
{
|
||||
if (warn.isEmpty()) {
|
||||
|
||||
@@ -52,7 +52,6 @@ private slots:
|
||||
void NameChanged(const QString &);
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent *) override;
|
||||
void SetNameWarning(const QString);
|
||||
|
||||
QLineEdit *_name;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include "non-modal-dialog.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <obs-frontend-api.h>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QMainWindow>
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace advss {
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ void AddPluginInitStep(std::function<void()> step)
|
||||
|
||||
void AddPluginPostLoadStep(std::function<void()> step)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::lock_guard<std::mutex> lock(initMutex);
|
||||
getPluginPostLoadSteps().emplace_back(step);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ ResourceTable::ResourceTable(QWidget *parent, const QString &help,
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addLayout(helpAndTableLayout);
|
||||
layout->addLayout(controlLayout);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
setLayout(layout);
|
||||
|
||||
QWidget::connect(_add, SIGNAL(clicked()), this, SLOT(Add()));
|
||||
|
||||
@@ -58,9 +58,6 @@ StringListEdit::StringListEdit(
|
||||
_filterCallback(filter),
|
||||
_preprocessCallback(preprocess)
|
||||
{
|
||||
if (_addString.isEmpty()) {
|
||||
_addString = obs_module_text("AdvSceneSwitcher.windowTitle");
|
||||
}
|
||||
}
|
||||
|
||||
void StringListEdit::SetStringList(const StringList &list)
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace advss {
|
||||
|
||||
class StringList : public QList<StringVariable> {
|
||||
public:
|
||||
using QList<StringVariable>::QList;
|
||||
|
||||
EXPORT bool Save(obs_data_t *obj, const char *name,
|
||||
const char *elementName = "string") const;
|
||||
EXPORT bool Load(obs_data_t *obj, const char *name,
|
||||
|
||||
@@ -150,8 +150,6 @@ target_sources(
|
||||
utils/connection-manager.hpp
|
||||
utils/cursor-helpers.cpp
|
||||
utils/cursor-helpers.hpp
|
||||
utils/day-of-week-selector.cpp
|
||||
utils/day-of-week-selector.hpp
|
||||
utils/filter-selection.cpp
|
||||
utils/filter-selection.hpp
|
||||
utils/hotkey-helpers.cpp
|
||||
@@ -168,8 +166,6 @@ target_sources(
|
||||
utils/scene-item-selection.hpp
|
||||
utils/scene-item-transform-helpers.cpp
|
||||
utils/scene-item-transform-helpers.hpp
|
||||
utils/transition-helpers.cpp
|
||||
utils/transition-helpers.hpp
|
||||
utils/source-properties-button.cpp
|
||||
utils/source-properties-button.hpp
|
||||
utils/source-settings-helpers.cpp
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "scene-switch-helpers.hpp"
|
||||
#include "source-helpers.hpp"
|
||||
#include "transition-helpers.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
@@ -69,6 +68,14 @@ static int getTransitionOverrideDuration(OBSWeakSource &scene)
|
||||
return duration;
|
||||
}
|
||||
|
||||
static bool isUsingFixedLengthTransition(const OBSWeakSource &transition)
|
||||
{
|
||||
obs_source_t *source = obs_weak_source_get_source(transition);
|
||||
bool ret = obs_transition_fixed(source);
|
||||
obs_source_release(source);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OBSWeakSource getOverrideTransition(OBSWeakSource &scene)
|
||||
{
|
||||
OBSWeakSource transition;
|
||||
@@ -94,13 +101,13 @@ static int getExpectedTransitionDuration(OBSWeakSource &scene,
|
||||
auto overrideTransition = getOverrideTransition(scene);
|
||||
if (overrideTransition) {
|
||||
transition = overrideTransition;
|
||||
if (!IsFixedLengthTransition(transition)) {
|
||||
if (!isUsingFixedLengthTransition(transition)) {
|
||||
return getTransitionOverrideDuration(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsFixedLengthTransition(transition)) {
|
||||
if (isUsingFixedLengthTransition(transition)) {
|
||||
return -1; // no API is available to access the fixed duration
|
||||
}
|
||||
if (duration != 0) {
|
||||
@@ -496,7 +503,7 @@ shouldShowDurationInTransitionLayout(MacroActionSwitchScene::SceneType type,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsFixedLengthTransition(transition.GetTransition())) {
|
||||
if (isUsingFixedLengthTransition(transition.GetTransition())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
#include "macro-action-scene-visibility.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "transition-helpers.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -25,168 +21,9 @@ const static std::map<MacroActionSceneVisibility::Action, std::string>
|
||||
"AdvSceneSwitcher.action.sceneVisibility.type.toggle"},
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
struct TransitionRestoreContext;
|
||||
static std::unordered_map<obs_sceneitem_t *, TransitionRestoreContext *>
|
||||
restoreContexts;
|
||||
static std::mutex restoreMutex;
|
||||
|
||||
struct TransitionRestoreContext {
|
||||
public:
|
||||
obs_sceneitem_t *item;
|
||||
bool wasVisible;
|
||||
|
||||
OBSSource originalTransition = nullptr;
|
||||
uint32_t originalDuration;
|
||||
|
||||
obs_source_t *transition = nullptr;
|
||||
signal_handler_t *sh = nullptr;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
static void handleShutdown(enum obs_frontend_event event, void *private_data)
|
||||
{
|
||||
if (event != OBS_FRONTEND_EVENT_EXIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(restoreMutex);
|
||||
for (const auto &[_, ctx] : restoreContexts) {
|
||||
obs_source_release(ctx->transition);
|
||||
}
|
||||
restoreContexts.clear();
|
||||
}
|
||||
|
||||
static bool setup()
|
||||
{
|
||||
obs_frontend_add_event_callback(handleShutdown, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setupDone = setup();
|
||||
|
||||
static void handleSourceDestroyed(void *param, calldata_t *)
|
||||
{
|
||||
if (OBSIsShuttingDown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto ctx = static_cast<TransitionRestoreContext *>(param);
|
||||
ctx->sh = nullptr;
|
||||
ctx->originalTransition = nullptr;
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
static void resetSceneItemTransition(void *param, calldata_t *)
|
||||
{
|
||||
if (OBSIsShuttingDown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto ctx = static_cast<TransitionRestoreContext *>(param);
|
||||
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetSceneItemTransition(ctx->item, ctx->originalTransition,
|
||||
!ctx->wasVisible);
|
||||
|
||||
obs_sceneitem_set_transition_duration(ctx->item, !ctx->wasVisible,
|
||||
ctx->originalDuration);
|
||||
|
||||
signal_handler_disconnect(ctx->sh, "transition_stop",
|
||||
resetSceneItemTransition, ctx);
|
||||
signal_handler_disconnect(ctx->sh, "destroy", handleSourceDestroyed,
|
||||
ctx);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(restoreMutex);
|
||||
restoreContexts.erase(ctx->item);
|
||||
}
|
||||
|
||||
obs_source_release(ctx->transition);
|
||||
delete ctx;
|
||||
}
|
||||
|
||||
static void attachRestoreContext(obs_sceneitem_t *item,
|
||||
obs_source_t *transition, bool itemWasVisible,
|
||||
OBSSource originalTransition,
|
||||
uint32_t originalDuration)
|
||||
{
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(transition);
|
||||
if (!sh) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(restoreMutex);
|
||||
|
||||
auto ctx = new TransitionRestoreContext{
|
||||
item,
|
||||
itemWasVisible,
|
||||
originalTransition,
|
||||
originalDuration,
|
||||
obs_source_get_ref(transition),
|
||||
sh,
|
||||
};
|
||||
|
||||
auto it = restoreContexts.find(item);
|
||||
if (it != restoreContexts.end()) {
|
||||
auto *oldCtx = it->second;
|
||||
|
||||
signal_handler_disconnect(oldCtx->sh, "transition_stop",
|
||||
resetSceneItemTransition, oldCtx);
|
||||
|
||||
signal_handler_disconnect(oldCtx->sh, "destroy",
|
||||
handleSourceDestroyed, oldCtx);
|
||||
|
||||
ctx->originalTransition = oldCtx->originalTransition;
|
||||
ctx->originalDuration = oldCtx->originalDuration;
|
||||
|
||||
obs_source_release(oldCtx->transition);
|
||||
delete oldCtx;
|
||||
|
||||
restoreContexts.erase(it);
|
||||
}
|
||||
|
||||
restoreContexts[item] = ctx;
|
||||
|
||||
signal_handler_connect(sh, "transition_stop", resetSceneItemTransition,
|
||||
ctx);
|
||||
signal_handler_connect(sh, "destroy", handleSourceDestroyed, ctx);
|
||||
}
|
||||
|
||||
static void setSceneItemVisibility(obs_sceneitem_t *item,
|
||||
const bool setTransition,
|
||||
const OBSWeakSource &transitionWeak,
|
||||
const bool setDuration,
|
||||
const Duration &duration,
|
||||
MacroActionSceneVisibility::Action action)
|
||||
{
|
||||
const OBSSourceAutoRelease transition = OBSGetStrongRef(transitionWeak);
|
||||
const bool itemIsVisible = obs_sceneitem_visible(item);
|
||||
|
||||
const OBSSource currentTransition =
|
||||
obs_sceneitem_get_transition(item, !itemIsVisible);
|
||||
const uint32_t currentTransitionDuration =
|
||||
obs_sceneitem_get_transition_duration(item, !itemIsVisible);
|
||||
|
||||
OBSSource privateTransitionSource = nullptr;
|
||||
if (setTransition) {
|
||||
privateTransitionSource = SetSceneItemTransition(
|
||||
item, transition, !itemIsVisible);
|
||||
} else {
|
||||
privateTransitionSource =
|
||||
obs_sceneitem_get_transition(item, !itemIsVisible);
|
||||
}
|
||||
|
||||
if (setDuration) {
|
||||
obs_sceneitem_set_transition_duration(item, !itemIsVisible,
|
||||
duration.Milliseconds());
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case MacroActionSceneVisibility::Action::SHOW:
|
||||
obs_sceneitem_set_visible(item, true);
|
||||
@@ -195,43 +32,16 @@ static void setSceneItemVisibility(obs_sceneitem_t *item,
|
||||
obs_sceneitem_set_visible(item, false);
|
||||
break;
|
||||
case MacroActionSceneVisibility::Action::TOGGLE:
|
||||
obs_sceneitem_set_visible(item, !itemIsVisible);
|
||||
obs_sceneitem_set_visible(item, !obs_sceneitem_visible(item));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!setTransition && !setDuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!privateTransitionSource) {
|
||||
if (setTransition) {
|
||||
SetSceneItemTransition(item, currentTransition,
|
||||
!itemIsVisible);
|
||||
}
|
||||
if (setDuration) {
|
||||
obs_sceneitem_set_transition_duration(
|
||||
item, !itemIsVisible,
|
||||
currentTransitionDuration);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto sh = obs_source_get_signal_handler(privateTransitionSource);
|
||||
if (!sh) {
|
||||
return;
|
||||
}
|
||||
|
||||
attachRestoreContext(item, privateTransitionSource, itemIsVisible,
|
||||
currentTransition, currentTransitionDuration);
|
||||
}
|
||||
|
||||
bool MacroActionSceneVisibility::PerformAction()
|
||||
{
|
||||
auto items = _source.GetSceneItems(_scene);
|
||||
for (const auto &item : items) {
|
||||
setSceneItemVisibility(item, _updateTransition,
|
||||
_transition.GetTransition(),
|
||||
_updateDuration, _duration, _action);
|
||||
setSceneItemVisibility(item, _action);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -256,10 +66,6 @@ bool MacroActionSceneVisibility::Save(obs_data_t *obj) const
|
||||
MacroAction::Save(obj);
|
||||
_scene.Save(obj);
|
||||
_source.Save(obj);
|
||||
obs_data_set_bool(obj, "updateTransition", _updateTransition);
|
||||
_transition.Save(obj);
|
||||
obs_data_set_bool(obj, "updateDuration", _updateDuration);
|
||||
_duration.Save(obj);
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
return true;
|
||||
}
|
||||
@@ -276,10 +82,6 @@ bool MacroActionSceneVisibility::Load(obs_data_t *obj)
|
||||
MacroAction::Load(obj);
|
||||
_scene.Load(obj);
|
||||
_source.Load(obj);
|
||||
_updateTransition = obs_data_get_bool(obj, "updateTransition");
|
||||
_transition.Load(obj);
|
||||
_updateDuration = obs_data_get_bool(obj, "updateDuration");
|
||||
_duration.Load(obj);
|
||||
_action = static_cast<MacroActionSceneVisibility::Action>(
|
||||
obs_data_get_int(obj, "action"));
|
||||
|
||||
@@ -339,17 +141,10 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
|
||||
SceneItemSelection::Type::ALL,
|
||||
},
|
||||
SceneItemSelectionWidget::NameClashMode::ALL)),
|
||||
_updateTransition(new QCheckBox(this)),
|
||||
_transitions(new TransitionSelectionWidget(this, false, false)),
|
||||
_updateDuration(new QCheckBox(this)),
|
||||
_duration(new DurationSelection(this, false)),
|
||||
_durationLayout(new QHBoxLayout),
|
||||
_actions(new QComboBox())
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
|
||||
_duration->SpinBox()->setSpecialValueText("-");
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
|
||||
@@ -359,49 +154,18 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
|
||||
this, SLOT(SourceChanged(const SceneItemSelection &)));
|
||||
QWidget::connect(_updateTransition, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(UpdateTransitionChanged(int)));
|
||||
QWidget::connect(_transitions,
|
||||
SIGNAL(TransitionChanged(const TransitionSelection &)),
|
||||
this,
|
||||
SLOT(TransitionChanged(const TransitionSelection &)));
|
||||
QWidget::connect(_updateDuration, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(UpdateDurationChanged(int)));
|
||||
QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
|
||||
this, SLOT(DurationChanged(const Duration &)));
|
||||
|
||||
auto sceneItemLayout = new QHBoxLayout;
|
||||
auto layout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.action.sceneVisibility.layout"),
|
||||
sceneItemLayout,
|
||||
"AdvSceneSwitcher.action.sceneVisibility.entry"),
|
||||
layout,
|
||||
{{"{{scenes}}", _scenes},
|
||||
{"{{sources}}", _sources},
|
||||
{"{{actions}}", _actions}});
|
||||
|
||||
auto transitionLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.sceneVisibility.layout.transition"),
|
||||
transitionLayout,
|
||||
{{"{{updateTransition}}", _updateTransition},
|
||||
{"{{transitions}}", _transitions}});
|
||||
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.sceneVisibility.layout.duration"),
|
||||
_durationLayout,
|
||||
{{"{{updateDuration}}", _updateDuration},
|
||||
{"{{duration}}", _duration}});
|
||||
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->addLayout(sceneItemLayout);
|
||||
layout->addLayout(transitionLayout);
|
||||
layout->addLayout(_durationLayout);
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
SetWidgetVisibility();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
@@ -413,11 +177,7 @@ void MacroActionSceneVisibilityEdit::UpdateEntryData()
|
||||
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_scenes->SetScene(_entryData->_scene);
|
||||
_sources->SetSceneItem(_entryData->_source);
|
||||
_updateTransition->setChecked(_entryData->_updateTransition);
|
||||
_transitions->SetTransition(_entryData->_transition);
|
||||
_updateDuration->setChecked(_entryData->_updateDuration);
|
||||
_duration->SetDuration(_entryData->_duration);
|
||||
_sources->SetSceneItem((_entryData->_source));
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::SceneChanged(const SceneSelection &s)
|
||||
@@ -437,34 +197,6 @@ void MacroActionSceneVisibilityEdit::SourceChanged(
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::UpdateTransitionChanged(int state)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_updateTransition = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::TransitionChanged(
|
||||
const TransitionSelection &t)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_transition = t;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::UpdateDurationChanged(int state)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_updateDuration = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::DurationChanged(const Duration &dur)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_duration = dur;
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::ActionChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
@@ -472,20 +204,4 @@ void MacroActionSceneVisibilityEdit::ActionChanged(int value)
|
||||
static_cast<MacroActionSceneVisibility::Action>(value);
|
||||
}
|
||||
|
||||
void MacroActionSceneVisibilityEdit::SetWidgetVisibility()
|
||||
{
|
||||
const bool hideDurationSelection =
|
||||
_entryData->_updateTransition &&
|
||||
IsFixedLengthTransition(
|
||||
_entryData->_transition.GetTransition());
|
||||
|
||||
SetLayoutVisible(_durationLayout, !hideDurationSelection);
|
||||
|
||||
_transitions->setEnabled(_entryData->_updateTransition);
|
||||
_duration->setEnabled(_entryData->_updateDuration);
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#pragma once
|
||||
#include "duration-control.hpp"
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "scene-selection.hpp"
|
||||
#include "scene-item-selection.hpp"
|
||||
#include "transition-selection.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -22,10 +20,6 @@ public:
|
||||
|
||||
SceneSelection _scene;
|
||||
SceneItemSelection _source;
|
||||
bool _updateTransition = false;
|
||||
TransitionSelection _transition;
|
||||
bool _updateDuration = false;
|
||||
Duration _duration;
|
||||
|
||||
enum class Action {
|
||||
SHOW,
|
||||
@@ -59,27 +53,17 @@ public:
|
||||
private slots:
|
||||
void SceneChanged(const SceneSelection &);
|
||||
void SourceChanged(const SceneItemSelection &);
|
||||
void UpdateTransitionChanged(int);
|
||||
void TransitionChanged(const TransitionSelection &);
|
||||
void UpdateDurationChanged(int);
|
||||
void DurationChanged(const Duration &seconds);
|
||||
void ActionChanged(int value);
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
protected:
|
||||
SceneSelectionWidget *_scenes;
|
||||
SceneItemSelectionWidget *_sources;
|
||||
QCheckBox *_updateTransition;
|
||||
TransitionSelectionWidget *_transitions;
|
||||
QCheckBox *_updateDuration;
|
||||
DurationSelection *_duration;
|
||||
QHBoxLayout *_durationLayout;
|
||||
QComboBox *_actions;
|
||||
|
||||
std::shared_ptr<MacroActionSceneVisibility> _entryData;
|
||||
|
||||
private:
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "macro-action-transition.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "transition-helpers.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
@@ -76,6 +75,26 @@ static void obs_sceneitem_set_transition_duration(obs_sceneitem_t *item,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void setSceneItemTransition(const OBSSceneItem &item,
|
||||
const OBSSourceAutoRelease &transition,
|
||||
bool show)
|
||||
{
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(transition);
|
||||
if (!transition || !settings) {
|
||||
// Set transition to "None"
|
||||
obs_sceneitem_set_transition(item, show, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// We cannot share the transition source between
|
||||
// scene items without introducing strange graphical
|
||||
// artifacts so we have to create new ones here
|
||||
OBSSourceAutoRelease transitionSource = obs_source_create_private(
|
||||
obs_source_get_id(transition), obs_source_get_name(transition),
|
||||
settings);
|
||||
obs_sceneitem_set_transition(item, show, transitionSource);
|
||||
}
|
||||
|
||||
void MacroActionTransition::SetSourceTransition(bool show)
|
||||
{
|
||||
#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(27, 0, 0)
|
||||
@@ -84,7 +103,7 @@ void MacroActionTransition::SetSourceTransition(bool show)
|
||||
const auto items = _source.GetSceneItems(_scene);
|
||||
for (const auto &item : items) {
|
||||
if (_setTransitionType) {
|
||||
SetSceneItemTransition(item, transition, show);
|
||||
setSceneItemTransition(item, transition, show);
|
||||
}
|
||||
if (_setDuration) {
|
||||
obs_sceneitem_set_transition_duration(
|
||||
|
||||
@@ -38,13 +38,32 @@ const static std::map<MacroConditionDate::Condition, std::string>
|
||||
"AdvSceneSwitcher.condition.date.state.before"},
|
||||
};
|
||||
|
||||
const static std::map<MacroConditionDate::Day, std::string> dayOfWeekNames = {
|
||||
{MacroConditionDate::Day::ANY,
|
||||
"AdvSceneSwitcher.condition.date.anyDay"},
|
||||
{MacroConditionDate::Day::MONDAY,
|
||||
"AdvSceneSwitcher.condition.date.monday"},
|
||||
{MacroConditionDate::Day::TUESDAY,
|
||||
"AdvSceneSwitcher.condition.date.tuesday"},
|
||||
{MacroConditionDate::Day::WEDNESDAY,
|
||||
"AdvSceneSwitcher.condition.date.wednesday"},
|
||||
{MacroConditionDate::Day::THURSDAY,
|
||||
"AdvSceneSwitcher.condition.date.thursday"},
|
||||
{MacroConditionDate::Day::FRIDAY,
|
||||
"AdvSceneSwitcher.condition.date.friday"},
|
||||
{MacroConditionDate::Day::SATURDAY,
|
||||
"AdvSceneSwitcher.condition.date.saturday"},
|
||||
{MacroConditionDate::Day::SUNDAY,
|
||||
"AdvSceneSwitcher.condition.date.sunday"},
|
||||
};
|
||||
|
||||
bool MacroConditionDate::CheckDayOfWeek(int64_t msSinceLastCheck)
|
||||
{
|
||||
QDateTime cur = QDateTime::currentDateTime();
|
||||
SetVariables(cur);
|
||||
|
||||
if (!_days.contains(static_cast<DayOfWeekSelector::Day>(
|
||||
cur.date().dayOfWeek()))) {
|
||||
if (_dayOfWeek != Day::ANY &&
|
||||
cur.date().dayOfWeek() != static_cast<int>(_dayOfWeek)) {
|
||||
return false;
|
||||
}
|
||||
if (_ignoreTime) {
|
||||
@@ -182,7 +201,7 @@ bool MacroConditionDate::CheckCondition()
|
||||
bool MacroConditionDate::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
SaveSelectedDays(obj, _days);
|
||||
obs_data_set_int(obj, "dayOfWeek", static_cast<int>(_dayOfWeek));
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
const auto &dateToSave = _updateOnRepeat ? _dateTime : _origDateTime;
|
||||
const auto &dateToSave2 = _updateOnRepeat ? _dateTime2 : _origDateTime2;
|
||||
@@ -197,14 +216,13 @@ bool MacroConditionDate::Save(obs_data_t *obj) const
|
||||
_duration.Save(obj);
|
||||
obs_data_set_bool(obj, "dayOfWeekCheck", _dayOfWeekCheck);
|
||||
obs_data_set_string(obj, "pattern", _pattern.c_str());
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionDate::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_days = LoadSelectedDays(obj);
|
||||
_dayOfWeek = static_cast<Day>(obs_data_get_int(obj, "dayOfWeek"));
|
||||
_condition = static_cast<MacroConditionDate::Condition>(
|
||||
obs_data_get_int(obj, "condition"));
|
||||
_dateTime = QDateTime::fromString(
|
||||
@@ -227,64 +245,17 @@ bool MacroConditionDate::Load(obs_data_t *obj)
|
||||
_condition == MacroConditionDate::Condition::BETWEEN) {
|
||||
_condition = MacroConditionDate::Condition::AT;
|
||||
}
|
||||
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
enum class Day {
|
||||
ANY = 0,
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY,
|
||||
SUNDAY,
|
||||
};
|
||||
auto oldDay =
|
||||
static_cast<Day>(obs_data_get_int(obj, "dayOfWeek"));
|
||||
switch (oldDay) {
|
||||
case Day::ANY:
|
||||
_days = {DayOfWeekSelector::Monday,
|
||||
DayOfWeekSelector::Tuesday,
|
||||
DayOfWeekSelector::Wednesday,
|
||||
DayOfWeekSelector::Thursday,
|
||||
DayOfWeekSelector::Friday,
|
||||
DayOfWeekSelector::Saturday,
|
||||
DayOfWeekSelector::Sunday};
|
||||
break;
|
||||
case Day::MONDAY:
|
||||
_days = {DayOfWeekSelector::Monday};
|
||||
break;
|
||||
case Day::TUESDAY:
|
||||
_days = {DayOfWeekSelector::Tuesday};
|
||||
break;
|
||||
case Day::WEDNESDAY:
|
||||
_days = {DayOfWeekSelector::Wednesday};
|
||||
break;
|
||||
case Day::THURSDAY:
|
||||
_days = {DayOfWeekSelector::Thursday};
|
||||
break;
|
||||
case Day::FRIDAY:
|
||||
_days = {DayOfWeekSelector::Friday};
|
||||
break;
|
||||
case Day::SATURDAY:
|
||||
_days = {DayOfWeekSelector::Saturday};
|
||||
break;
|
||||
case Day::SUNDAY:
|
||||
_days = {DayOfWeekSelector::Sunday};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacroConditionDate::GetShortDesc() const
|
||||
{
|
||||
if (_dayOfWeekCheck) {
|
||||
const auto dayName =
|
||||
DayOfWeekSelector::ToString(_days).toStdString();
|
||||
auto it = dayOfWeekNames.find(_dayOfWeek);
|
||||
if (it == dayOfWeekNames.end()) {
|
||||
return "";
|
||||
}
|
||||
std::string dayName = obs_module_text(it->second.c_str());
|
||||
if (_ignoreTime) {
|
||||
return dayName;
|
||||
}
|
||||
@@ -376,6 +347,13 @@ void MacroConditionDate::SetupTempVars()
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.date.dayOfWeek"));
|
||||
}
|
||||
|
||||
static inline void populateDaySelection(QComboBox *list)
|
||||
{
|
||||
for (auto entry : dayOfWeekNames) {
|
||||
list->addItem(obs_module_text(entry.second.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void populateConditionSelection(QComboBox *list)
|
||||
{
|
||||
for (auto entry : dateConditionTypes) {
|
||||
@@ -394,7 +372,7 @@ MacroConditionDateEdit::MacroConditionDateEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionDate> entryData)
|
||||
: QWidget(parent),
|
||||
_weekCondition(new QComboBox()),
|
||||
_days(new DayOfWeekSelector(this)),
|
||||
_dayOfWeek(new QComboBox()),
|
||||
_ignoreWeekTime(new QCheckBox()),
|
||||
_weekTime(new QTimeEdit()),
|
||||
_condition(new QComboBox()),
|
||||
@@ -414,7 +392,7 @@ MacroConditionDateEdit::MacroConditionDateEdit(
|
||||
_currentDate(new QLabel()),
|
||||
_advancedSettingsTooggle(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.showAdvancedSettings"))),
|
||||
_simpleLayout(new QVBoxLayout()),
|
||||
_simpleLayout(new QHBoxLayout()),
|
||||
_advancedLayout(new QHBoxLayout()),
|
||||
_repeatLayout(new QVBoxLayout()),
|
||||
_repeatUpdateLayout(new QHBoxLayout()),
|
||||
@@ -440,8 +418,8 @@ MacroConditionDateEdit::MacroConditionDateEdit(
|
||||
|
||||
QWidget::connect(_weekCondition, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_days, &DayOfWeekSelector::SelectionChanged, this,
|
||||
&MacroConditionDateEdit::DaysChanged);
|
||||
QWidget::connect(_dayOfWeek, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(DayOfWeekChanged(int)));
|
||||
QWidget::connect(_ignoreWeekTime, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(IgnoreTimeChanged(int)));
|
||||
QWidget::connect(_weekTime, SIGNAL(timeChanged(const QTime &)), this,
|
||||
@@ -471,12 +449,13 @@ MacroConditionDateEdit::MacroConditionDateEdit(
|
||||
QWidget::connect(_pattern, SIGNAL(editingFinished()), this,
|
||||
SLOT(PatternChanged()));
|
||||
|
||||
populateDaySelection(_dayOfWeek);
|
||||
populateConditionSelection(_condition);
|
||||
populateWeekConditionSelection(_weekCondition);
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{weekCondition}}", _weekCondition},
|
||||
{"{{dayOfWeek}}", _days},
|
||||
{"{{dayOfWeek}}", _dayOfWeek},
|
||||
{"{{ignoreWeekTime}}", _ignoreWeekTime},
|
||||
{"{{weekTime}}", _weekTime},
|
||||
{"{{condition}}", _condition},
|
||||
@@ -493,39 +472,28 @@ MacroConditionDateEdit::MacroConditionDateEdit(
|
||||
{"{{pattern}}", _pattern},
|
||||
{"{{currentDate}}", _currentDate},
|
||||
};
|
||||
|
||||
auto dayLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.layout.simple.day"),
|
||||
dayLayout, widgetPlaceholders);
|
||||
auto timeLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.layout.simple.time"),
|
||||
timeLayout, widgetPlaceholders);
|
||||
_simpleLayout->addLayout(dayLayout);
|
||||
_simpleLayout->addLayout(timeLayout);
|
||||
|
||||
obs_module_text("AdvSceneSwitcher.condition.date.entry.simple"),
|
||||
_simpleLayout, widgetPlaceholders);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.layout.advanced"),
|
||||
"AdvSceneSwitcher.condition.date.entry.advanced"),
|
||||
_advancedLayout, widgetPlaceholders);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.layout.updateOnRepeat"),
|
||||
"AdvSceneSwitcher.condition.date.entry.updateOnRepeat"),
|
||||
_repeatUpdateLayout, widgetPlaceholders);
|
||||
auto repeatLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.date.entry.repeat"),
|
||||
repeatLayout, widgetPlaceholders);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.layout.repeat"),
|
||||
repeatLayout, widgetPlaceholders);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.layout.pattern"),
|
||||
"AdvSceneSwitcher.condition.date.entry.pattern"),
|
||||
_patternLayout, widgetPlaceholders);
|
||||
_repeatLayout->addLayout(repeatLayout);
|
||||
_repeatLayout->addWidget(_nextMatchDate);
|
||||
_repeatLayout->addLayout(_repeatUpdateLayout);
|
||||
|
||||
auto mainLayout = new QVBoxLayout;
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(_simpleLayout);
|
||||
mainLayout->addLayout(_advancedLayout);
|
||||
mainLayout->addLayout(_patternLayout);
|
||||
@@ -547,11 +515,10 @@ MacroConditionDateEdit::MacroConditionDateEdit(
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionDateEdit::DaysChanged(
|
||||
const QSet<DayOfWeekSelector::Day> &days)
|
||||
void MacroConditionDateEdit::DayOfWeekChanged(int day)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_days = days;
|
||||
_entryData->_dayOfWeek = static_cast<MacroConditionDate::Day>(day);
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
@@ -665,7 +632,7 @@ void MacroConditionDateEdit::ShowNextMatch()
|
||||
return;
|
||||
}
|
||||
QString format(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.date.layout.nextMatchDate"));
|
||||
"AdvSceneSwitcher.condition.date.entry.nextMatchDate"));
|
||||
_nextMatchDate->setText(
|
||||
format.arg(_entryData->GetNextMatchDateTime().toString()));
|
||||
}
|
||||
@@ -691,7 +658,8 @@ void MacroConditionDateEdit::UpdateEntryData()
|
||||
}
|
||||
_weekCondition->setCurrentIndex(
|
||||
static_cast<int>(_entryData->_condition));
|
||||
_days->SetSelectedDays(_entryData->_days);
|
||||
_dayOfWeek->setCurrentIndex(
|
||||
static_cast<int>(static_cast<int>(_entryData->_dayOfWeek)));
|
||||
_ignoreWeekTime->setChecked(!_entryData->_ignoreTime);
|
||||
_weekTime->setTime(_entryData->GetDateTime1().time());
|
||||
_condition->setCurrentIndex(static_cast<int>(_entryData->_condition));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "day-of-week-selector.hpp"
|
||||
#include "duration-control.hpp"
|
||||
|
||||
#include <QCheckBox>
|
||||
@@ -31,6 +30,17 @@ public:
|
||||
QDateTime GetDateTime2() const;
|
||||
QDateTime GetNextMatchDateTime() const;
|
||||
|
||||
enum class Day {
|
||||
ANY = 0,
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY,
|
||||
SUNDAY,
|
||||
};
|
||||
|
||||
enum class Condition {
|
||||
AT,
|
||||
AFTER,
|
||||
@@ -39,11 +49,7 @@ public:
|
||||
PATTERN,
|
||||
};
|
||||
|
||||
QSet<DayOfWeekSelector::Day> _days = {
|
||||
DayOfWeekSelector::Day::Monday,
|
||||
DayOfWeekSelector::Day::Tuesday,
|
||||
DayOfWeekSelector::Day::Wednesday,
|
||||
};
|
||||
Day _dayOfWeek = Day::ANY;
|
||||
bool _ignoreDate = false;
|
||||
bool _ignoreTime = false;
|
||||
bool _repeat = false;
|
||||
@@ -88,7 +94,7 @@ public:
|
||||
}
|
||||
|
||||
private slots:
|
||||
void DaysChanged(const QSet<DayOfWeekSelector::Day> &);
|
||||
void DayOfWeekChanged(int day);
|
||||
void ConditionChanged(int cond);
|
||||
void DateChanged(const QDate &date);
|
||||
void TimeChanged(const QTime &time);
|
||||
@@ -108,7 +114,7 @@ signals:
|
||||
|
||||
protected:
|
||||
QComboBox *_weekCondition;
|
||||
DayOfWeekSelector *_days;
|
||||
QComboBox *_dayOfWeek;
|
||||
QCheckBox *_ignoreWeekTime;
|
||||
QTimeEdit *_weekTime;
|
||||
|
||||
@@ -128,7 +134,7 @@ protected:
|
||||
QLabel *_currentDate;
|
||||
|
||||
QPushButton *_advancedSettingsTooggle;
|
||||
QVBoxLayout *_simpleLayout;
|
||||
QHBoxLayout *_simpleLayout;
|
||||
QHBoxLayout *_advancedLayout;
|
||||
QVBoxLayout *_repeatLayout;
|
||||
QHBoxLayout *_repeatUpdateLayout;
|
||||
|
||||
@@ -55,17 +55,17 @@ void MacroConditionGameCapture::GetCalldataInfo(calldata_t *cd)
|
||||
if (!calldata_get_string(cd, "title", &title)) {
|
||||
blog(LOG_WARNING, "%s failed to get title", __func__);
|
||||
}
|
||||
_title = title ? title : "";
|
||||
_title = title;
|
||||
const char *className = "";
|
||||
if (!calldata_get_string(cd, "class", &className)) {
|
||||
blog(LOG_WARNING, "%s failed to get class", __func__);
|
||||
}
|
||||
_class = className ? className : "";
|
||||
_class = className;
|
||||
const char *executable = "";
|
||||
if (!calldata_get_string(cd, "executable", &executable)) {
|
||||
blog(LOG_WARNING, "%s failed to get executable", __func__);
|
||||
}
|
||||
_executable = executable ? executable : "";
|
||||
_executable = executable;
|
||||
}
|
||||
|
||||
void MacroConditionGameCapture::HookedSignalReceived(void *data, calldata_t *cd)
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
#include "day-of-week-selector.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
namespace advss {
|
||||
|
||||
DayOfWeekSelector::DayOfWeekSelector(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
auto layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(4);
|
||||
|
||||
const QVector<QPair<Day, QString>> days = {
|
||||
{Monday, obs_module_text("AdvSceneSwitcher.day.monday")},
|
||||
{Tuesday, obs_module_text("AdvSceneSwitcher.day.tuesday")},
|
||||
{Wednesday, obs_module_text("AdvSceneSwitcher.day.wednesday")},
|
||||
{Thursday, obs_module_text("AdvSceneSwitcher.day.thursday")},
|
||||
{Friday, obs_module_text("AdvSceneSwitcher.day.friday")},
|
||||
{Saturday, obs_module_text("AdvSceneSwitcher.day.saturday")},
|
||||
{Sunday, obs_module_text("AdvSceneSwitcher.day.sunday")}};
|
||||
|
||||
for (const auto &[day, name] : days) {
|
||||
auto btn = new QPushButton(this);
|
||||
btn->setText(name);
|
||||
btn->setCheckable(true);
|
||||
|
||||
connect(btn, &QPushButton::toggled, this,
|
||||
&DayOfWeekSelector::OnButtonToggled);
|
||||
|
||||
layout->addWidget(btn);
|
||||
m_buttons.insert(day, btn);
|
||||
}
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void DayOfWeekSelector::OnButtonToggled(bool)
|
||||
{
|
||||
emit SelectionChanged(SelectedDays());
|
||||
}
|
||||
|
||||
QSet<DayOfWeekSelector::Day> DayOfWeekSelector::SelectedDays() const
|
||||
{
|
||||
QSet<Day> result;
|
||||
for (auto it = m_buttons.begin(); it != m_buttons.end(); ++it) {
|
||||
if (it.value()->isChecked()) {
|
||||
result.insert(it.key());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void DayOfWeekSelector::SetSelectedDays(const QSet<Day> &days)
|
||||
{
|
||||
for (auto it = m_buttons.begin(); it != m_buttons.end(); ++it) {
|
||||
it.value()->setChecked(days.contains(it.key()));
|
||||
}
|
||||
}
|
||||
|
||||
QString DayOfWeekSelector::ToString(const QSet<Day> &days)
|
||||
{
|
||||
const QVector<QPair<Day, QString>> dayNames = {
|
||||
{Monday, obs_module_text("AdvSceneSwitcher.day.monday")},
|
||||
{Tuesday, obs_module_text("AdvSceneSwitcher.day.tuesday")},
|
||||
{Wednesday, obs_module_text("AdvSceneSwitcher.day.wednesday")},
|
||||
{Thursday, obs_module_text("AdvSceneSwitcher.day.thursday")},
|
||||
{Friday, obs_module_text("AdvSceneSwitcher.day.friday")},
|
||||
{Saturday, obs_module_text("AdvSceneSwitcher.day.saturday")},
|
||||
{Sunday, obs_module_text("AdvSceneSwitcher.day.sunday")}};
|
||||
|
||||
if (days.isEmpty()) {
|
||||
return obs_module_text("AdvSceneSwitcher.day.none");
|
||||
}
|
||||
|
||||
if (days.size() == 7) {
|
||||
return obs_module_text("AdvSceneSwitcher.day.any");
|
||||
}
|
||||
|
||||
QStringList parts;
|
||||
for (const auto &[day, name] : dayNames) {
|
||||
if (days.contains(day)) {
|
||||
parts << name;
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join(", ");
|
||||
}
|
||||
|
||||
void SaveSelectedDays(obs_data_t *settings,
|
||||
const QSet<DayOfWeekSelector::Day> &days)
|
||||
{
|
||||
uint64_t mask = 0;
|
||||
|
||||
for (DayOfWeekSelector::Day day : days) {
|
||||
mask |= (1ULL << static_cast<int>(day));
|
||||
}
|
||||
|
||||
obs_data_set_int(settings, "selectedDays",
|
||||
static_cast<long long>(mask));
|
||||
}
|
||||
|
||||
QSet<DayOfWeekSelector::Day> LoadSelectedDays(obs_data_t *settings)
|
||||
{
|
||||
QSet<DayOfWeekSelector::Day> result;
|
||||
|
||||
uint64_t mask = static_cast<uint64_t>(
|
||||
obs_data_get_int(settings, "selectedDays"));
|
||||
|
||||
for (int i = DayOfWeekSelector::Monday; i <= DayOfWeekSelector::Sunday;
|
||||
++i) {
|
||||
if (mask & (1ULL << i)) {
|
||||
result.insert(static_cast<DayOfWeekSelector::Day>(i));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <QSet>
|
||||
|
||||
#include <obs-data.h>
|
||||
|
||||
class QPushButton;
|
||||
|
||||
namespace advss {
|
||||
|
||||
class DayOfWeekSelector : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Day {
|
||||
Monday = 1,
|
||||
Tuesday,
|
||||
Wednesday,
|
||||
Thursday,
|
||||
Friday,
|
||||
Saturday,
|
||||
Sunday
|
||||
};
|
||||
Q_ENUM(Day)
|
||||
|
||||
explicit DayOfWeekSelector(QWidget *parent = nullptr);
|
||||
|
||||
QSet<Day> SelectedDays() const;
|
||||
void SetSelectedDays(const QSet<Day> &days);
|
||||
static QString ToString(const QSet<Day> &days);
|
||||
|
||||
signals:
|
||||
void SelectionChanged(const QSet<Day> &days);
|
||||
|
||||
private:
|
||||
void OnButtonToggled(bool checked);
|
||||
|
||||
QMap<Day, QPushButton *> m_buttons;
|
||||
};
|
||||
|
||||
void SaveSelectedDays(obs_data_t *settings,
|
||||
const QSet<DayOfWeekSelector::Day> &days);
|
||||
QSet<DayOfWeekSelector::Day> LoadSelectedDays(obs_data_t *settings);
|
||||
|
||||
} // namespace advss
|
||||
@@ -335,12 +335,6 @@ void SetSourceSetting(obs_source_t *source, const SourceSetting &setting,
|
||||
case OBS_DATA_OBJECT: {
|
||||
OBSDataAutoRelease json =
|
||||
obs_data_create_from_json(value.c_str());
|
||||
if (!json) {
|
||||
blog(LOG_WARNING,
|
||||
"not setting invalid data object settings value! (%s)",
|
||||
value.c_str());
|
||||
break;
|
||||
}
|
||||
obs_data_set_obj(data, id.c_str(), json);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#include "transition-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
bool IsFixedLengthTransition(const OBSWeakSource &transition)
|
||||
{
|
||||
OBSSourceAutoRelease source = obs_weak_source_get_source(transition);
|
||||
return obs_transition_fixed(source);
|
||||
}
|
||||
|
||||
obs_source_t *SetSceneItemTransition(const OBSSceneItem &item,
|
||||
const OBSSourceAutoRelease &transition,
|
||||
bool show)
|
||||
{
|
||||
OBSDataAutoRelease settings = obs_source_get_settings(transition);
|
||||
if (!transition || !settings) {
|
||||
// Set transition to "None"
|
||||
obs_sceneitem_set_transition(item, show, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We cannot share the transition source between
|
||||
// scene items without introducing strange graphical
|
||||
// artifacts so we have to create new ones here
|
||||
OBSSourceAutoRelease transitionSource = obs_source_create_private(
|
||||
obs_source_get_id(transition), obs_source_get_name(transition),
|
||||
settings);
|
||||
obs_sceneitem_set_transition(item, show, transitionSource);
|
||||
return transitionSource.Get();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
#include <obs.hpp>
|
||||
|
||||
namespace advss {
|
||||
|
||||
bool IsFixedLengthTransition(const OBSWeakSource &transition);
|
||||
obs_source_t *SetSceneItemTransition(const OBSSceneItem &item,
|
||||
const OBSSourceAutoRelease &transition,
|
||||
bool show);
|
||||
|
||||
} // namespace advss
|
||||
@@ -70,7 +70,7 @@ struct URLInfo {
|
||||
std::string path;
|
||||
};
|
||||
|
||||
static URLInfo getURLInfo(const std::string &input, bool keepParams)
|
||||
static URLInfo getURLInfo(const std::string &input)
|
||||
{
|
||||
if (input.empty()) {
|
||||
return {};
|
||||
@@ -84,35 +84,21 @@ static URLInfo getURLInfo(const std::string &input, bool keepParams)
|
||||
const QUrl url(urlInput);
|
||||
auto host =
|
||||
url.scheme().toStdString() + "://" + url.host().toStdString();
|
||||
|
||||
const int port = url.port();
|
||||
int port = url.port();
|
||||
if (port != -1) {
|
||||
host += ":" + std::to_string(port);
|
||||
}
|
||||
|
||||
auto path = url.path().toStdString();
|
||||
if (path.empty()) {
|
||||
path = "/";
|
||||
}
|
||||
|
||||
const auto query = url.query().toStdString();
|
||||
if (!query.empty()) {
|
||||
if (keepParams) {
|
||||
path += "?" + query;
|
||||
} else {
|
||||
blog(LOG_WARNING,
|
||||
"ignoring query parameters \"%s\" in URL field. "
|
||||
"Using parameter field values instead.",
|
||||
query.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return {host, path};
|
||||
}
|
||||
|
||||
bool MacroActionHttp::PerformAction()
|
||||
{
|
||||
const auto [host, path] = getURLInfo(_url, !_setParams);
|
||||
const auto [host, path] = getURLInfo(_url);
|
||||
|
||||
httplib::Client cli(host);
|
||||
setTimeout(cli, _timeout);
|
||||
|
||||
@@ -93,7 +93,7 @@ bool MacroConditionStreamdeck::MessageMatches(const StreamDeckMessage &message)
|
||||
{
|
||||
const bool keyStateMatches = !_pattern.checkKeyState ||
|
||||
((message.keyDown && _pattern.keyDown) ||
|
||||
(!message.keyDown && !_pattern.keyDown));
|
||||
(!message.keyDown && !message.keyDown));
|
||||
const bool positionMatches = !_pattern.checkPosition ||
|
||||
(message.row == _pattern.row &&
|
||||
message.column == _pattern.column);
|
||||
|
||||
@@ -89,24 +89,12 @@ void EventSub::ConnectThread()
|
||||
|
||||
void EventSub::WaitAndReconnect()
|
||||
{
|
||||
if (_reconnecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
_reconnecting = true;
|
||||
|
||||
auto thread = std::thread([this]() {
|
||||
std::unique_lock<std::mutex> lock(_waitMtx);
|
||||
blog(LOG_INFO,
|
||||
"Twitch EventSub trying to reconnect to in %d seconds.",
|
||||
reconnectDelay);
|
||||
_cv.wait_for(lock, std::chrono::seconds(reconnectDelay));
|
||||
_reconnecting = false;
|
||||
|
||||
if (_disconnect) {
|
||||
return;
|
||||
}
|
||||
|
||||
Connect();
|
||||
});
|
||||
thread.detach();
|
||||
@@ -114,10 +102,6 @@ void EventSub::WaitAndReconnect()
|
||||
|
||||
void EventSub::Connect()
|
||||
{
|
||||
if (_reconnecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(_connectMtx);
|
||||
if (_connected) {
|
||||
vblog(LOG_INFO, "Twitch EventSub connect already in progress");
|
||||
@@ -481,8 +465,8 @@ void EventSub::StartServerMigrationClient(const std::string &url)
|
||||
const auto &data = msg->payload;
|
||||
|
||||
if (type == "session_welcome") {
|
||||
blog(LOG_INFO,
|
||||
"Twitch EventSub migration successful - switching to new connection");
|
||||
vblog(LOG_INFO,
|
||||
"Twitch EventSub migration successful - switching to new connection");
|
||||
OBSDataAutoRelease session =
|
||||
obs_data_get_obj(data, "session");
|
||||
_migrationSessionID =
|
||||
@@ -581,7 +565,7 @@ void EventSub::OnClose(connection_hdl hdl)
|
||||
blog(LOG_INFO, "Twitch EventSub connection closed: %s / %s (%d)",
|
||||
msg.c_str(), reason.c_str(), code);
|
||||
|
||||
if (!_migrating) {
|
||||
if (_migrating) {
|
||||
ClearActiveSubscriptions();
|
||||
}
|
||||
_connected = false;
|
||||
|
||||
@@ -110,7 +110,6 @@ private:
|
||||
std::condition_variable _cv;
|
||||
std::atomic_bool _connected{false};
|
||||
std::atomic_bool _disconnect{false};
|
||||
std::atomic_bool _reconnecting{false};
|
||||
|
||||
std::string _url;
|
||||
std::string _sessionID;
|
||||
|
||||
@@ -7,11 +7,7 @@
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMainWindow>
|
||||
#include <QTabWidget>
|
||||
#include <QTimer>
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -42,29 +38,8 @@ static bool setup()
|
||||
}
|
||||
};
|
||||
|
||||
// This function is called while the plugin settings are being loaded.
|
||||
// Blocking at this stage can cause issues such as OBS failing to start
|
||||
// or crashing.
|
||||
// Therefore, we ask the user whether they want to update their Twitch
|
||||
// connections asynchronously.
|
||||
//
|
||||
// On macOS, an additional QTimer::singleShot wrapper is required for
|
||||
// this to work correctly.
|
||||
AddLoadStep([](obs_data_t *) {
|
||||
AddPostLoadStep([]() {
|
||||
#ifdef __APPLE__
|
||||
QTimer::singleShot(
|
||||
0,
|
||||
static_cast<QMainWindow *>(
|
||||
obs_frontend_get_main_window()),
|
||||
[]() {
|
||||
#endif
|
||||
showInvalidWarnings();
|
||||
|
||||
#ifdef __APPLE__
|
||||
});
|
||||
#endif
|
||||
});
|
||||
AddPostLoadStep([]() { showInvalidWarnings(); });
|
||||
});
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user