mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-08-29 20:55:28 -05:00
Compare commits
54 Commits
1.30.0-bet
...
1.30.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20488afdd1 | ||
|
|
d9d387ad47 | ||
|
|
0736d673e1 | ||
|
|
34151e4bc6 | ||
|
|
1346c19bec | ||
|
|
be6bc48231 | ||
|
|
79a8ad57af | ||
|
|
daeb9275a3 | ||
|
|
73b542a4db | ||
|
|
e3471066e9 | ||
|
|
ec41c06b4d | ||
|
|
201e45d058 | ||
|
|
b17aa30432 | ||
|
|
93703c80bc | ||
|
|
d7951a7179 | ||
|
|
d42a3b584a | ||
|
|
becd1bd02a | ||
|
|
30422aecf3 | ||
|
|
c567e6ef7f | ||
|
|
1ca61f3ed4 | ||
|
|
1affe9dce3 | ||
|
|
406e3c1855 | ||
|
|
c05dd40c4c | ||
|
|
9a86ecac42 | ||
|
|
721a786e79 | ||
|
|
32d29875ed | ||
|
|
0e5f56b562 | ||
|
|
5490fabf92 | ||
|
|
5e3ab19940 | ||
|
|
1c94a1ab44 | ||
|
|
34baa56134 | ||
|
|
5ce4171773 | ||
|
|
c281c6db83 | ||
|
|
c43439ee64 | ||
|
|
a84731b8fe | ||
|
|
61fbff5821 | ||
|
|
1381654fed | ||
|
|
9805601c07 | ||
|
|
fcf57ee031 | ||
|
|
ba3e87a761 | ||
|
|
3dd3f576c3 | ||
|
|
7403a18e96 | ||
|
|
56494480ba | ||
|
|
cdc5d16e95 | ||
|
|
27aed79305 | ||
|
|
7ec95e33eb | ||
|
|
98260b25a1 | ||
|
|
45b37de9f7 | ||
|
|
027a3e9074 | ||
|
|
cab50e0922 | ||
|
|
88514e209d | ||
|
|
4ed7f13b72 | ||
|
|
0fb11ac274 | ||
|
|
942933290a |
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@@ -2,7 +2,7 @@
|
||||
# https://github.com/obsproject/.github/tree/master/.github/ISSUE_TEMPLATE
|
||||
|
||||
name: Feature request
|
||||
description: Suggest an idea for this projectReport a bug or crash
|
||||
description: Suggest an idea for this project
|
||||
body:
|
||||
- type: markdown
|
||||
id: md_welcome
|
||||
|
||||
4
.github/scripts/.Aptfile
vendored
4
.github/scripts/.Aptfile
vendored
@@ -10,4 +10,6 @@ package 'libxss-dev'
|
||||
package 'libopencv-dev'
|
||||
package 'libtesseract-dev'
|
||||
package 'libproc2-dev'
|
||||
package 'libusb-1.0-0-dev'
|
||||
package 'libusb-1.0-0-dev'
|
||||
package 'libpaho-mqttpp-dev'
|
||||
package 'libpaho-mqtt-dev'
|
||||
27
.github/scripts/.build-deps.zsh
vendored
27
.github/scripts/.build-deps.zsh
vendored
@@ -478,6 +478,33 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
|
||||
unset MACOSX_DEPLOYMENT_TARGET
|
||||
|
||||
popd
|
||||
|
||||
local mqtt_dir="${project_root}/deps/paho.mqtt.cpp"
|
||||
local mqtt_build_dir="${mqtt_dir}/build_${target##*-}"
|
||||
|
||||
local -a mqtt_cmake_args=(
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=${DEPLOYMENT_TARGET:-10.15}
|
||||
-DCMAKE_PREFIX_PATH="${advss_dep_path};${_plugin_deps}"
|
||||
-DCMAKE_INSTALL_PREFIX="${advss_dep_path}"
|
||||
-DPAHO_BUILD_SHARED=OFF
|
||||
-DPAHO_BUILD_STATIC=ON
|
||||
-DPAHO_WITH_MQTT_C=ON
|
||||
-DOPENSSL_ROOT_DIR="${advss_dep_path}"
|
||||
-DPAHO_WITH_SSL=OFF # TODO: figure out linking issues with openssl
|
||||
)
|
||||
|
||||
pushd ${mqtt_dir}
|
||||
log_info "Configure paho.mqtt.cpp ..."
|
||||
cmake -S . -B ${mqtt_build_dir} ${mqtt_cmake_args}
|
||||
|
||||
log_info "Building paho.mqtt.cpp ..."
|
||||
cmake --build ${mqtt_build_dir} --config Release
|
||||
|
||||
log_info "Installing paho.mqtt.cpp ..."
|
||||
cmake --install ${mqtt_build_dir} --prefix "${advss_dep_path}" --config Release
|
||||
popd
|
||||
;;
|
||||
linux)
|
||||
# Nothing to do for now
|
||||
|
||||
31
.github/scripts/Build-Deps-Windows.ps1
vendored
31
.github/scripts/Build-Deps-Windows.ps1
vendored
@@ -219,6 +219,37 @@ function Build {
|
||||
} else {
|
||||
Log-Information "Failed to locate msbuild.exe - skipping libusb build"
|
||||
}
|
||||
|
||||
Push-Location -Stack BuildMqttTemp
|
||||
Ensure-Location $ProjectRoot
|
||||
|
||||
$MqttPath = "${ProjectRoot}/deps/paho.mqtt.cpp"
|
||||
$MqttBuildPath = "${MqttPath}/build"
|
||||
|
||||
# Explicitly disable PkgConfig and tiff as it will lead build errors
|
||||
$MqttCmakeArgs = @(
|
||||
"-DCMAKE_BUILD_TYPE=${Configuration}"
|
||||
"-DCMAKE_PREFIX_PATH:PATH=${OBSDepPath}"
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${ADVSSDepPath}"
|
||||
"-DPAHO_WITH_MQTT_C=ON"
|
||||
)
|
||||
|
||||
Log-Information "Configuring paho.mqtt.cpp..."
|
||||
Invoke-External cmake -S ${MqttPath} -B ${MqttBuildPath} @MqttCmakeArgs
|
||||
|
||||
$MqttCmakeArgs = @(
|
||||
'--config', "${Configuration}"
|
||||
)
|
||||
|
||||
if ( $VerbosePreference -eq 'Continue' ) {
|
||||
$MqttCmakeArgs += ('--verbose')
|
||||
}
|
||||
|
||||
Log-Information "Building paho.mqtt.cpp..."
|
||||
Invoke-External cmake --build "${MqttBuildPath}" @MqttCmakeArgs
|
||||
|
||||
Log-Information "Install paho.mqtt.cpp..."
|
||||
Invoke-External cmake --install "${MqttBuildPath}" --prefix "${ADVSSDepPath}" @MqttCmakeArgs
|
||||
}
|
||||
|
||||
Build
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -34,3 +34,6 @@
|
||||
[submodule "deps/jsoncons"]
|
||||
path = deps/jsoncons
|
||||
url = https://github.com/danielaparker/jsoncons.git
|
||||
[submodule "deps/paho.mqtt.cpp"]
|
||||
path = deps/paho.mqtt.cpp
|
||||
url = https://github.com/eclipse-paho/paho.mqtt.cpp.git
|
||||
|
||||
@@ -103,8 +103,6 @@ target_sources(
|
||||
lib/macro/macro-action-macro.hpp
|
||||
lib/macro/macro-action-queue.cpp
|
||||
lib/macro/macro-action-queue.hpp
|
||||
lib/macro/macro-action-script.cpp
|
||||
lib/macro/macro-action-script.hpp
|
||||
lib/macro/macro-action-variable.cpp
|
||||
lib/macro/macro-action-variable.hpp
|
||||
lib/macro/macro-action.cpp
|
||||
@@ -117,8 +115,6 @@ target_sources(
|
||||
lib/macro/macro-condition-macro.hpp
|
||||
lib/macro/macro-condition-queue.cpp
|
||||
lib/macro/macro-condition-queue.hpp
|
||||
lib/macro/macro-condition-script.cpp
|
||||
lib/macro/macro-condition-script.hpp
|
||||
lib/macro/macro-condition-tempvar.cpp
|
||||
lib/macro/macro-condition-tempvar.hpp
|
||||
lib/macro/macro-condition-variable.cpp
|
||||
@@ -139,14 +135,10 @@ target_sources(
|
||||
lib/macro/macro-ref.hpp
|
||||
lib/macro/macro-run-button.cpp
|
||||
lib/macro/macro-run-button.hpp
|
||||
lib/macro/macro-script-handler.cpp
|
||||
lib/macro/macro-script-handler.hpp
|
||||
lib/macro/macro-segment-copy-paste.cpp
|
||||
lib/macro/macro-segment-copy-paste.hpp
|
||||
lib/macro/macro-segment-list.cpp
|
||||
lib/macro/macro-segment-list.hpp
|
||||
lib/macro/macro-segment-script.cpp
|
||||
lib/macro/macro-segment-script.hpp
|
||||
lib/macro/macro-segment-selection.cpp
|
||||
lib/macro/macro-segment-selection.hpp
|
||||
lib/macro/macro-segment.cpp
|
||||
@@ -223,17 +215,12 @@ target_sources(
|
||||
lib/utils/plugin-state-helpers.hpp
|
||||
lib/utils/priority-helper.cpp
|
||||
lib/utils/priority-helper.hpp
|
||||
lib/utils/properties-view.cpp
|
||||
lib/utils/properties-view.hpp
|
||||
lib/utils/properties-view.moc.hpp
|
||||
lib/utils/regex-config.cpp
|
||||
lib/utils/regex-config.hpp
|
||||
lib/utils/resizing-text-edit.cpp
|
||||
lib/utils/resizing-text-edit.hpp
|
||||
lib/utils/resource-table.cpp
|
||||
lib/utils/resource-table.hpp
|
||||
lib/utils/resource-table-hotkey-handler.cpp
|
||||
lib/utils/resource-table-hotkey-handler.hpp
|
||||
lib/utils/scene-selection.cpp
|
||||
lib/utils/scene-selection.hpp
|
||||
lib/utils/scene-switch-helpers.cpp
|
||||
|
||||
@@ -40,7 +40,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Exportieren"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="Importieren"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Exportiere Erweiterter Automatischer Szenenwechsler Einstellungen zu Datei ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Exportiere Erweiterter Automatischer Szenenwechsler Einstellungen von Datei ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Text Dateien (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Text Dateien (*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="Importieren der Einstellungen ist fehlgeschlagen"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Einstellungen wurden erfolgreich importiert"
|
||||
AdvSceneSwitcher.generalTab.priority.fileContent="Datei Inhalt"
|
||||
@@ -194,12 +194,12 @@ AdvSceneSwitcher.condition.video.modelLoadFail="Modelldaten konnten nicht gelade
|
||||
AdvSceneSwitcher.condition.video.type.main="OBS's Haupt-Ausgabe"
|
||||
AdvSceneSwitcher.condition.video.type.source="Quelle"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Szene"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Modelldaten (Haar-Kaskaden-Klassifikator): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimale Anzahl von Nachbarn: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzieren Sie die CPU-Belastung, indem Sie die Prüfung nur alle {{throttleCount}} Millisekunden"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Kontrolle nur im Bereich durchführen"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Modelldaten (Haar-Kaskaden-Klassifikator): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Minimale Anzahl von Nachbarn: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzieren Sie die CPU-Belastung, indem Sie die Prüfung nur alle {{throttleCount}} Millisekunden"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Kontrolle nur im Bereich durchführen"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Minimale Größe:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Maximale Größe:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Bereich auswählen"
|
||||
@@ -752,9 +752,9 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Starte/Stoppe den Erweite
|
||||
AdvSceneSwitcher.hotkey.macro.pause="Pausiere Makro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.unpause="Makro %1 nicht mehr pausieren"
|
||||
AdvSceneSwitcher.hotkey.macro.togglePause="Pause von Makro %1 togglen"
|
||||
AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="Makro-Segmentauswahl nach oben verschieben"
|
||||
AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="Makro-Segmentauswahl nach unten verschieben"
|
||||
AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="Ausgewähltes Makro-Segment entfernen"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.up="Makro-Segmentauswahl nach oben verschieben"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.down="Makro-Segmentauswahl nach unten verschieben"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.remove="Ausgewähltes Makro-Segment entfernen"
|
||||
|
||||
AdvSceneSwitcher.askBackup="Neue Version des Erweiterten Automatischen Szenenwechslers wurde erkannt.\nSoll ein Backup der alten Einstellungen angelegt werden?"
|
||||
AdvSceneSwitcher.askForMacro="Makro auswählen {{macroSelection}}"
|
||||
|
||||
@@ -42,6 +42,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="Display warni
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="The plugin installation seems to be corrupted and might crash!\nPlease make sure the plugin was installed correctly!"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
|
||||
AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache="Disable macro widget caching"
|
||||
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
|
||||
AdvSceneSwitcher.generalTab.priority="Priority"
|
||||
AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)"
|
||||
@@ -52,7 +53,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Export"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="Import"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Export Advanced Scene Switcher settings to file ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Import Advanced Scene Switcher settings from file ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Text files (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Text files (*.txt);;JSON files (*.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="Advanced Scene Switcher failed to import settings"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Advanced Scene Switcher settings imported successfully"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportSensitiveDataWarning="Warning:\nThe exported data might contain sensitive information!"
|
||||
@@ -132,6 +133,18 @@ AdvSceneSwitcher.twitchConnectionTab.no="No"
|
||||
AdvSceneSwitcher.twitchConnectionTab.removeSingleConnectionPopup.text="Are you sure you want to remove \"%1\"?"
|
||||
AdvSceneSwitcher.twitchConnectionTab.removeMultipleConnectionsPopup.text="Are you sure you want to remove %1 Twitch connections?"
|
||||
|
||||
# MQTT Connections Tab
|
||||
AdvSceneSwitcher.mqttConnectionTab.title="MQTT Connections"
|
||||
AdvSceneSwitcher.mqttConnectionTab.help="MQTT connections can be used to communicate with other devices.\n\nClick on the highlighted plus symbol to add a new connection."
|
||||
AdvSceneSwitcher.mqttConnectionTab.mqttonnectionAddButton.tooltip="Add new MQTT connection"
|
||||
AdvSceneSwitcher.mqttConnectionTab.mqttConnectionRemoveButton.tooltip="Remove selected MQTT connections"
|
||||
AdvSceneSwitcher.mqttConnectionTab.name.header="Name"
|
||||
AdvSceneSwitcher.mqttConnectionTab.address.header="Address"
|
||||
AdvSceneSwitcher.mqttConnectionTab.topics.header="Topic subscription count"
|
||||
AdvSceneSwitcher.mqttConnectionTab.status.header="Status"
|
||||
AdvSceneSwitcher.mqttConnectionTab.removeSingleConnectionPopup.text="Are you sure you want to remove \"%1\"?"
|
||||
AdvSceneSwitcher.mqttConnectionTab.removeMultipleConnectionsPopup.text="Are you sure you want to remove %1 connections?"
|
||||
|
||||
# Macro Tab
|
||||
AdvSceneSwitcher.macroTab.title="Macro"
|
||||
AdvSceneSwitcher.macroTab.macros="Macros"
|
||||
@@ -203,7 +216,7 @@ AdvSceneSwitcher.macroTab.newMacroCheckInParallel="Evaluate conditions of new ma
|
||||
AdvSceneSwitcher.macroTab.checkInParallel.tooltip="If this option is not enabled, this macro's conditions will be evaluated after the preceeding macro's condition check has completed.\nSo, if there are three macros - Macro A, Macro B, and Macro C - in the macro list the order the conditions in are evaluated is:\n • Macro A's conditions\n • Macro B's conditions\n • Macro C's conditions\nIf this option is enabled, the order might differ.\nEnabling this option can be useful for scenarios in which you have multiple long running condition checks, which you don't want to result in \"blocking\" other macros."
|
||||
AdvSceneSwitcher.macroTab.saveSettingsOnMacroChange="Save settings when switching between macros"
|
||||
AdvSceneSwitcher.macroTab.saveSettingsOnMacroChange.tooltip="Saving the settings can be an expensive operation if you are working with a very large scene collection.\nIn this case, it might make sense to disable this option."
|
||||
AdvSceneSwitcher.macroTab.currentCheckInParallel="Evaluate conditions of selected macro in parallel to other macros"
|
||||
AdvSceneSwitcher.macroTab.currentCheckInParallel="Evaluate conditions of selected macro in parallel to other macros (Experimental)"
|
||||
AdvSceneSwitcher.macroTab.currentRegisterHotkeys="Register hotkeys to control the pause state of selected macro"
|
||||
AdvSceneSwitcher.macroTab.currentUseShortCircuitEvaluation="Enable short circuit evaluation of macro conditions for currently selected macro"
|
||||
AdvSceneSwitcher.macroTab.shortCircuit.tooltip="Enabling short circuit evaluation might improve the performance, as some condition checks are skipped, if the overall macro cannot be evaluated to \"true\" anymore.\nHowever, please note that condition checks, which are skipped over, will also not update their duration modifier checks."
|
||||
@@ -311,7 +324,7 @@ AdvSceneSwitcher.condition.scene.previousSceneTransitionBehaviour="During transi
|
||||
AdvSceneSwitcher.condition.scene.entry.line1="{{sceneType}}{{scenes}}{{pattern}}{{regex}}"
|
||||
AdvSceneSwitcher.condition.scene.entry.line2="{{useTransitionTargetScene}}"
|
||||
AdvSceneSwitcher.condition.window="Window"
|
||||
AdvSceneSwitcher.condition.window.entry.window="{{checkTitle}}Window title matches{{windowRegex}}{{windows}}"
|
||||
AdvSceneSwitcher.condition.window.entry.window="{{checkTitle}}Window title matches{{windows}}{{windowRegex}}"
|
||||
AdvSceneSwitcher.condition.window.entry.fullscreen="{{fullscreen}}Window is fullscreen"
|
||||
AdvSceneSwitcher.condition.window.entry.maximized="{{maximized}}Window is maximized"
|
||||
AdvSceneSwitcher.condition.window.entry.focused="{{focused}}Window is focused"
|
||||
@@ -380,6 +393,13 @@ AdvSceneSwitcher.condition.video.patternMatchSuccessFullImage="Full image matche
|
||||
AdvSceneSwitcher.condition.video.objectMatchFail="Object was not found!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red"
|
||||
AdvSceneSwitcher.condition.video.ocrMatchSuccess="Detected text:\n\n%1"
|
||||
AdvSceneSwitcher.condition.video.ocrMatchFail="Could not detect any text!"
|
||||
AdvSceneSwitcher.condition.video.ocrUseConfigFile="Use custom tesseract config file"
|
||||
AdvSceneSwitcher.condition.video.ocrOpenConfigFile="Open"
|
||||
AdvSceneSwitcher.condition.video.ocrOpenConfig.createFailed="Could not create the config file!"
|
||||
AdvSceneSwitcher.condition.video.ocrOpenConfig.openFailed="Could not open the config file!"
|
||||
AdvSceneSwitcher.condition.video.ocrConfigReload="Reload configuration file"
|
||||
AdvSceneSwitcher.condition.video.ocrConfigHint="Tesseract config files consist of lines with parameter-value pairs (space separated).\nFor example:\n\ntessedit_char_blacklist\t\t\t\t\"abc\"\nlanguage_model_penalty_non_dict_word\t0"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="Model data could not be loaded!"
|
||||
AdvSceneSwitcher.condition.video.selectColor="Select Color"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleColumn="Single column of text of variable sizes"
|
||||
@@ -399,16 +419,18 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="How similar
|
||||
AdvSceneSwitcher.condition.video.type.main="OBS's main output"
|
||||
AdvSceneSwitcher.condition.video.type.source="Source"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Scene"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Model data (haar cascade classifier):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum neighbors:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduce CPU load by performing check only every{{throttleCount}}milliseconds"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Perform check only in area"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="Check for text color:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="Check for text type:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="Check for language:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="Check for color:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Model data (haar cascade classifier):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Minimum neighbors:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduce CPU load by performing check only every{{throttleCount}}milliseconds"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Perform check only in area"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Check for text color:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Check for text type:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrBaseDir="Tesseract base directory:{{tesseractBaseDir}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Check for language:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrConfig="Config file:{{configFile}}{{openConfigFile}}{{reloadConfig}}{{configFileHint}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="Check for color:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Minimum size:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Maximum size:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Select area"
|
||||
@@ -708,6 +730,8 @@ AdvSceneSwitcher.condition.twitch.type.polling.channel.live="Stream is currently
|
||||
AdvSceneSwitcher.condition.twitch.type.polling.channel.title="Current title matches"
|
||||
AdvSceneSwitcher.condition.twitch.type.polling.channel.category="Current category is"
|
||||
AdvSceneSwitcher.condition.twitch.type.chat.message="Chat message received"
|
||||
AdvSceneSwitcher.condition.twitch.type.chat.messageRemoved="Single chat message removed"
|
||||
AdvSceneSwitcher.condition.twitch.type.chat.cleared="All messages of user or channel cleared"
|
||||
AdvSceneSwitcher.condition.twitch.type.chat.properties="Chat message properties:"
|
||||
AdvSceneSwitcher.condition.twitch.type.chat.properties.select="Select chat message property:"
|
||||
AdvSceneSwitcher.condition.twitch.type.chat.properties.firstMessage="Is first message"
|
||||
@@ -774,9 +798,12 @@ AdvSceneSwitcher.condition.streamDeck.stopListen="Stop listening"
|
||||
AdvSceneSwitcher.condition.streamDeck.pluginDownload="<html><head/><body><p>The Stream Deck plugin can be found <a href=\"https://github.com/WarmUpTill/advanced-scene-switcher-streamdeck-plugin/releases\"><span style=\" text-decoration: underline; color:#268bd2;\">here on GitHub</span></a>.</p></body></html>"
|
||||
AdvSceneSwitcher.condition.gameCapture="Game capture"
|
||||
AdvSceneSwitcher.condition.gameCapture.entry="{{sources}}hooked a game."
|
||||
|
||||
AdvSceneSwitcher.condition.screenshot="Screenshot"
|
||||
AdvSceneSwitcher.condition.screenshot.entry="A screenshot was taken"
|
||||
AdvSceneSwitcher.condition.mqtt="MQTT"
|
||||
AdvSceneSwitcher.condition.mqtt.layout.match="Message was received from{{connection}} which matches{{regex}}:"
|
||||
AdvSceneSwitcher.condition.mqtt.layout.listen="Set message selection to incoming message:{{listenButton}}"
|
||||
AdvSceneSwitcher.condition.script="Script"
|
||||
|
||||
# Macro Actions
|
||||
AdvSceneSwitcher.action.unknown="Unknown action"
|
||||
@@ -911,6 +938,7 @@ AdvSceneSwitcher.action.media.seek.percentage.label="Percentage of total duratio
|
||||
AdvSceneSwitcher.action.macro="Macro"
|
||||
AdvSceneSwitcher.action.macro.type.pause="Pause"
|
||||
AdvSceneSwitcher.action.macro.type.unpause="Unpause"
|
||||
AdvSceneSwitcher.action.macro.type.togglePause="Toggle pause"
|
||||
AdvSceneSwitcher.action.macro.type.resetCounter="Reset counter"
|
||||
AdvSceneSwitcher.action.macro.type.run="Run macro"
|
||||
AdvSceneSwitcher.action.macro.type.run.conditions.ignore="Do not consider condition state"
|
||||
@@ -1069,7 +1097,7 @@ AdvSceneSwitcher.action.http.type.post="POST"
|
||||
AdvSceneSwitcher.action.http.type.put="PUT"
|
||||
AdvSceneSwitcher.action.http.type.patch="PATCH"
|
||||
AdvSceneSwitcher.action.http.type.delete="DELETE"
|
||||
AdvSceneSwitcher.action.http.layout.method="Send{{method}}to URL{{url}}at path{{path}}"
|
||||
AdvSceneSwitcher.action.http.layout.method="Send{{method}}to URL{{url}}"
|
||||
AdvSceneSwitcher.action.http.layout.contentType="Content type:{{contentType}}"
|
||||
AdvSceneSwitcher.action.http.layout.timeout="Timeout:{{timeout}}seconds"
|
||||
AdvSceneSwitcher.action.http.entry.line1="Send{{method}}to{{url}}"
|
||||
@@ -1208,6 +1236,24 @@ AdvSceneSwitcher.action.window.entry="{{actions}}{{windows}}{{regex}}"
|
||||
AdvSceneSwitcher.action.log="Log"
|
||||
AdvSceneSwitcher.action.log.placeholder="My log message!"
|
||||
AdvSceneSwitcher.action.log.entry="Write to OBS log:{{logMessage}}"
|
||||
AdvSceneSwitcher.action.mqtt="MQTT"
|
||||
AdvSceneSwitcher.action.mqtt.topic="Topic:"
|
||||
AdvSceneSwitcher.action.mqtt.qos="QoS:"
|
||||
AdvSceneSwitcher.action.mqtt.retain="Retained message:"
|
||||
AdvSceneSwitcher.action.mqtt.layout="Send message to{{connection}}"
|
||||
AdvSceneSwitcher.action.obsSetting="OBS setting"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setFPSType="Set FPS selection type to"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setFPSCommonValue="Set FPS common selection to"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setFPSIntegerValue="Set FPS integer selection to"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setFPSFractionNumeratorValue="Set fractional FPS numerator selection to"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setFPSFractionDenominatorValue="Set fractional FPS denominator selection to"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setBaseCanvasX="Set base resolution X value"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setBaseCanvasY="Set base resolution Y value"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setOutputCanvasX="Set output resolution X value"
|
||||
AdvSceneSwitcher.action.obsSetting.action.setOutputCanvasY="Set output resolution Y value"
|
||||
AdvSceneSwitcher.action.obsSetting.getCurrentValue="Get current value"
|
||||
AdvSceneSwitcher.action.obsSettings.layout="{{actions}}{{fpsType}}{{fpsIntValue}}{{fpsStringValue}}{{canvasSizeValue}}{{getCurrentValue}}"
|
||||
AdvSceneSwitcher.action.script="Script"
|
||||
|
||||
# Hotkey
|
||||
AdvSceneSwitcher.hotkey.startSwitcherHotkey="Start the Advanced Scene Switcher"
|
||||
@@ -1216,9 +1262,10 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Toggle Start/Stop for the
|
||||
AdvSceneSwitcher.hotkey.macro.pause="Pause macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.unpause="Unpause macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.togglePause="Toggle pause of macro %1"
|
||||
AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="Move macro segment selection up"
|
||||
AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="Move macro segment selection down"
|
||||
AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="Remove selected macro segment"
|
||||
AdvSceneSwitcher.hotkey.macro.new="Add new macro"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.up="Move macro segment selection up"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.down="Move macro segment selection down"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.remove="Remove selected macro segment"
|
||||
|
||||
AdvSceneSwitcher.askBackup="Detected a new version of the Advanced Scene Switcher.\nShould a backup of the old settings be created?"
|
||||
AdvSceneSwitcher.askForMacro="Select macro{{macroSelection}}"
|
||||
@@ -1364,6 +1411,35 @@ AdvSceneSwitcher.osc.message.type.false="False"
|
||||
AdvSceneSwitcher.osc.message.type.infinity="Infinitum"
|
||||
AdvSceneSwitcher.osc.message.type.null="Nil"
|
||||
|
||||
AdvSceneSwitcher.mqttConnection.startListen="Start listening"
|
||||
AdvSceneSwitcher.mqttConnection.stopListen="Stop listening"
|
||||
AdvSceneSwitcher.mqttConnection.select="--select connection--"
|
||||
AdvSceneSwitcher.mqttConnection.add="Add new connection"
|
||||
AdvSceneSwitcher.mqttConnection.configure="Configure connection settings"
|
||||
AdvSceneSwitcher.mqttConnection.invalid="Invalid connection selection"
|
||||
AdvSceneSwitcher.mqttConnection.name="Name:"
|
||||
AdvSceneSwitcher.mqttConnection.address="Address:"
|
||||
AdvSceneSwitcher.mqttConnection.username="Username:"
|
||||
AdvSceneSwitcher.mqttConnection.password="Password:"
|
||||
AdvSceneSwitcher.mqttConnection.reconnect="Reconnect automatically:"
|
||||
AdvSceneSwitcher.mqttConnection.reconnectDelay="Automatically reconnect after:"
|
||||
AdvSceneSwitcher.mqttConnection.connectOnStart="Connect on startup:"
|
||||
AdvSceneSwitcher.mqttConnection.test="Test connection"
|
||||
AdvSceneSwitcher.mqttConnection.status.connected="Connected!"
|
||||
AdvSceneSwitcher.mqttConnection.status.connecting="Connecting ..."
|
||||
AdvSceneSwitcher.mqttConnection.status.disconnected="Could not connect!"
|
||||
AdvSceneSwitcher.mqttConnection.topic="Topic"
|
||||
AdvSceneSwitcher.mqttConnection.qos="QoS"
|
||||
AdvSceneSwitcher.mqttConnection.topics="Topic subscriptions:"
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.emptyTopic="Topic cannot be empty."
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.emptyTopic.title="Input Error"
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.duplicateTopic="This topic already exists."
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.duplicateTopic.title="Duplicate Topic"
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.qosRange="QoS must be 0, 1, or 2."
|
||||
AdvSceneSwitcher.mqttConnection.inputWarning.qosRange.title="Invalid QoS"
|
||||
AdvSceneSwitcher.mqttConnection.add.layout="Add topic subscription{{topic}}with QoS{{QoS}}"
|
||||
AdvSceneSwitcher.mqttConnection.add.title="Add MQTT Topic Subscription"
|
||||
|
||||
AdvSceneSwitcher.twitchToken.name="Account name:"
|
||||
AdvSceneSwitcher.twitchToken.nameNotAvailable="Account already in use"
|
||||
AdvSceneSwitcher.twitchToken.select="--select Twitch connection--"
|
||||
@@ -1442,6 +1518,17 @@ AdvSceneSwitcher.twitch.selection.points.reward.tooltip.noPermission="Can't sele
|
||||
AdvSceneSwitcher.twitch.selection.points.reward.tooltip.noChannel="Can't select points reward without entering a channel first!"
|
||||
AdvSceneSwitcher.twitch.selection.points.reward.tooltip.error="Can't select points reward because Twitch responded with an error! Check OBS logs for more details."
|
||||
|
||||
AdvSceneSwitcher.script.type.inline="Inline"
|
||||
AdvSceneSwitcher.script.type.file="File"
|
||||
AdvSceneSwitcher.script.type.layout="Script type:{{scriptType}}"
|
||||
AdvSceneSwitcher.script.language.python="Python"
|
||||
AdvSceneSwitcher.script.language.lua="LUA"
|
||||
AdvSceneSwitcher.script.language.select="--select language--"
|
||||
AdvSceneSwitcher.script.language.layout="Script language:{{language}}"
|
||||
AdvSceneSwitcher.script.file.open="Open"
|
||||
AdvSceneSwitcher.script.file.open.failed="Could not open script file!"
|
||||
AdvSceneSwitcher.script.file.layout="Script file:{{path}}{{open}}"
|
||||
|
||||
AdvSceneSwitcher.tempVar.select="--select value--"
|
||||
AdvSceneSwitcher.tempVar.selectionInfo.lastValues="Last values:"
|
||||
|
||||
@@ -1835,6 +1922,24 @@ AdvSceneSwitcher.tempVar.twitch.is_turbo.chatReceive.description="'true' if the
|
||||
AdvSceneSwitcher.tempVar.twitch.is_vip.chatReceive="Is chatter a VIP"
|
||||
AdvSceneSwitcher.tempVar.twitch.is_vip.chatReceive.description="'true' if the chatter is a VIP in the channel, 'false' otherwise."
|
||||
|
||||
AdvSceneSwitcher.tempVar.twitch.login.chatRemove="User login"
|
||||
AdvSceneSwitcher.tempVar.twitch.login.chatRemove.description="The name of the user who sent the message."
|
||||
AdvSceneSwitcher.tempVar.twitch.message.chatRemove="Chat message"
|
||||
AdvSceneSwitcher.tempVar.twitch.message_id.chatRemove.description="The chat message that was removed."
|
||||
AdvSceneSwitcher.tempVar.twitch.message_id.chatRemove="Chat message ID"
|
||||
AdvSceneSwitcher.tempVar.twitch.message_id.chatRemove.description="The ID of the message in UUID format."
|
||||
AdvSceneSwitcher.tempVar.twitch.timestamp.chatRemove="Chat message timestamp"
|
||||
AdvSceneSwitcher.tempVar.twitch.timestamp.chatRemove.description="The UNIX timestamp."
|
||||
|
||||
AdvSceneSwitcher.tempVar.twitch.login.chatClear="User login"
|
||||
AdvSceneSwitcher.tempVar.twitch.login.chatClear.description="The login name of the user whose messages were removed from the chat room because they were banned or put in a timeout."
|
||||
AdvSceneSwitcher.tempVar.twitch.user_id.chatClear="User ID"
|
||||
AdvSceneSwitcher.tempVar.twitch.user_id.chatClear.description="Optional.\nThe User ID of the user that was banned or put in a timeout.\nEmpty in case the complete chat was cleared."
|
||||
AdvSceneSwitcher.tempVar.twitch.ban_duration.chatClear="Ban duration"
|
||||
AdvSceneSwitcher.tempVar.twitch.ban_duration.chatClear.description="Set to zero if the complete chat was cleared or a user was banned indefinitely.\nIs set to non-zero value, if a user was put in a timeout.\nWill contain the duration of the timeout in seconds."
|
||||
AdvSceneSwitcher.tempVar.twitch.timestamp.chatClear="Timestamp"
|
||||
AdvSceneSwitcher.tempVar.twitch.timestamp.chatClear.description="The UNIX timestamp."
|
||||
|
||||
AdvSceneSwitcher.tempVar.twitch.user_login.chatJoin="User login"
|
||||
AdvSceneSwitcher.tempVar.twitch.user_login.chatJoin.description="The user login of the person who joined the chat room."
|
||||
|
||||
@@ -2066,6 +2171,11 @@ AdvSceneSwitcher.tempVar.http.body="Message body"
|
||||
AdvSceneSwitcher.tempVar.http.error="Error"
|
||||
AdvSceneSwitcher.tempVar.http.error.description="Empty when no error occurred.\nOther possible values:\n\n * Could not establish connection\n * Failed to bind IP address\n * Failed to read connection\n * Failed to write connection\n * Maximum redirect count exceeded\n * Connection handling canceled\n * SSL connection failed\n * SSL certificate loading failed\n * SSL server verification failed\n * Unsupported HTTP multipart boundary characters\n * Compression failed\n * Connection timed out\n * Proxy connection failed\n * Unknown"
|
||||
|
||||
AdvSceneSwitcher.tempVar.mqtt.message="Message"
|
||||
|
||||
AdvSceneSwitcher.tempVar.cursor.x="Cursor position (X)"
|
||||
AdvSceneSwitcher.tempVar.cursor.y="Cursor position (Y)"
|
||||
|
||||
AdvSceneSwitcher.selectScene="--select scene--"
|
||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||
@@ -2185,13 +2295,12 @@ AdvSceneSwitcher.script.timeout="Script timeout:{{timeout}}"
|
||||
|
||||
# This secion is copied from the OBS locale files
|
||||
|
||||
# commonly shared locale
|
||||
# OBS commonly shared locale
|
||||
Browse="Browse"
|
||||
Show="Show"
|
||||
Hide="Hide"
|
||||
|
||||
|
||||
# properties window
|
||||
# OBS properties window
|
||||
Basic.PropertiesWindow="Properties for '%1'"
|
||||
Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselect: %2)"
|
||||
Basic.PropertiesWindow.SelectColor="Select color"
|
||||
@@ -2208,7 +2317,7 @@ Basic.PropertiesWindow.AddEditableListFiles="Add files to '%1'"
|
||||
Basic.PropertiesWindow.AddEditableListEntry="Add entry to '%1'"
|
||||
Basic.PropertiesWindow.EditEditableListEntry="Edit entry from '%1'"
|
||||
|
||||
# properties view
|
||||
# OBS properties view
|
||||
Basic.PropertiesView.FPS.Simple="Simple FPS Values"
|
||||
Basic.PropertiesView.FPS.Rational="Rational FPS Values"
|
||||
Basic.PropertiesView.FPS.ValidFPSRanges="Valid FPS Ranges:"
|
||||
@@ -2216,6 +2325,11 @@ Basic.PropertiesView.UrlButton.Text="Open this link in your default web browser?
|
||||
Basic.PropertiesView.UrlButton.Text.Url="URL: %1"
|
||||
Basic.PropertiesView.UrlButton.OpenUrl="Open URL"
|
||||
|
||||
# OBS settings
|
||||
Basic.Settings.Video.FPSCommon="Common FPS Values"
|
||||
Basic.Settings.Video.FPSInteger="Integer FPS Value"
|
||||
Basic.Settings.Video.FPSFraction="Fractional FPS Value"
|
||||
|
||||
# Legacy tabs below - please don't waste your time adding translations for these :)
|
||||
# Transition Tab
|
||||
AdvSceneSwitcher.transitionTab.title="Transition"
|
||||
|
||||
@@ -38,7 +38,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Exportar"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="Importar"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Exportar los ajustes para Advanced Scene Switcher ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Importar los ajustes para Advanced Scene Switcher ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Archivos de texto (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Archivos de texto (*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="La importacion la configuracion de escenas fallo"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Configuración de escenas importada correctamente"
|
||||
AdvSceneSwitcher.generalTab.priority.fileContent="Contenido del archivo"
|
||||
@@ -154,12 +154,12 @@ AdvSceneSwitcher.condition.video.patternMatchSuccess="El patrón está resaltado
|
||||
AdvSceneSwitcher.condition.video.objectMatchFail="¡No se encontró el objeto!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="El objeto está resaltado en rojo"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="¡No se pudieron cargar los datos del modelo!"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Datos del modelo (haar cascade classifier): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Mínimo de vecinos: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzca la carga de la CPU realizando una comprobación solo cada {{throttleCount}} milisegundos"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Realizar comprobación solo en el área"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}Realizar comprobación solo en el área {{checkArea}} {{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Datos del modelo (haar cascade classifier): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Mínimo de vecinos: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzca la carga de la CPU realizando una comprobación solo cada {{throttleCount}} milisegundos"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Realizar comprobación solo en el área"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}Realizar comprobación solo en el área {{checkArea}} {{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Tamaño mínimo:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Tamaño máximo:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Seleccionar área"
|
||||
@@ -640,9 +640,9 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Alternar inicio / detenci
|
||||
AdvSceneSwitcher.hotkey.macro.pause="Pausar macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.unpause="Despausar macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.togglePause="Alternar pausa de macro %1"
|
||||
AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="Mover selección de segmento de macro hacia arriba"
|
||||
AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="Mover selección de segmento de macro hacia abajo"
|
||||
AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="Eliminar segmento de macro seleccionado"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.up="Mover selección de segmento de macro hacia arriba"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.down="Mover selección de segmento de macro hacia abajo"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.remove="Eliminar segmento de macro seleccionado"
|
||||
|
||||
AdvSceneSwitcher.askBackup="Se detectó una nueva versión de Advanced Scene Switcher.\n¿Crear una copia de seguridad de la configuración anterior?"
|
||||
AdvSceneSwitcher.askForMacro="Select macro {{macroSelection}}"
|
||||
|
||||
@@ -43,7 +43,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Exporter"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="Importer"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Exporter les paramètres d'Advanced Scene Switcher vers un fichier ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Importer les paramètres d'Advanced Scene Switcher depuis un fichier ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Fichiers texte (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Fichiers texte (*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="L'importation des paramètres d'Advanced Scene Switcher a échoué"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Les paramètres d'Advanced Scene Switcher ont été importés avec succès"
|
||||
AdvSceneSwitcher.generalTab.priority.fileContent="Contenu du fichier"
|
||||
@@ -257,14 +257,14 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="À quel poi
|
||||
AdvSceneSwitcher.condition.video.type.main="Sortie principale d'OBS"
|
||||
AdvSceneSwitcher.condition.video.type.source="Source"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Scène"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Données du modèle (classificateur de cascade de Haar) :{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Nombre minimum de voisins :{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Réduire la charge CPU en effectuant la vérification uniquement toutes les{{throttleCount}}millisecondes"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Effectuer la vérification uniquement dans la zone"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="Vérifier la couleur du texte :{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="Vérifier le type de texte :{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="Vérifier la langue :{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="Vérifier la couleur :{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Données du modèle (classificateur de cascade de Haar) :{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Nombre minimum de voisins :{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Réduire la charge CPU en effectuant la vérification uniquement toutes les{{throttleCount}}millisecondes"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Effectuer la vérification uniquement dans la zone"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Vérifier la couleur du texte :{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Vérifier le type de texte :{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Vérifier la langue :{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="Vérifier la couleur :{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Taille minimale :"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Taille maximale :"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Sélectionner la zone"
|
||||
@@ -920,9 +920,9 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Basculer le démarrage/ar
|
||||
AdvSceneSwitcher.hotkey.macro.pause="Mettre en pause la macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.unpause="Reprendre la macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.togglePause="Basculer la pause de la macro %1"
|
||||
AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="Déplacer la sélection du segment de macro vers le haut"
|
||||
AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="Déplacer la sélection du segment de macro vers le bas"
|
||||
AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="Supprimer le segment de macro sélectionné"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.up="Déplacer la sélection du segment de macro vers le haut"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.down="Déplacer la sélection du segment de macro vers le bas"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.remove="Supprimer le segment de macro sélectionné"
|
||||
|
||||
AdvSceneSwitcher.askBackup="Une nouvelle version du commutateur de scènes avancé a été détectée.\nSouhaitez-vous créer une sauvegarde des anciens paramètres ?"
|
||||
AdvSceneSwitcher.askForMacro="Sélectionnez la macro{{macroSelection}}"
|
||||
|
||||
@@ -48,7 +48,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="エクスポート"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="インポート"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="高機能シーンスイッチャーの設定をファイルにエクスポート..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="高機能シーンスイッチャーの設定をファイルからインポート..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="テキストファイル(*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="テキストファイル(*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="高機能シーンスイッチャーの設定インポートに失敗しました"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="高機能シーンスイッチャーの設定が正常にインポートされました"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportSensitiveDataWarning="警告:\nエクスポートされたデータにはセンシティブ情報が含まれている可能性があります!"
|
||||
@@ -379,16 +379,14 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="一致と
|
||||
AdvSceneSwitcher.condition.video.type.main="OBS's main output"
|
||||
AdvSceneSwitcher.condition.video.type.source="ソース"
|
||||
AdvSceneSwitcher.condition.video.type.scene="シーン"
|
||||
; AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="モデルデータ (そのカスケード分類子):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小近傍数:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}:{{throttleCount}}ミリ秒ごとにのみチェックを実行することでCPU負荷を軽減します"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="エリア内のみチェックを実施"
|
||||
; AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="テキストの色の確認:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="テキストタイプの確認:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="言語の確認:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="カラーを確認してください:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="モデルデータ (そのカスケード分類子):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="最小近傍数:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}:{{throttleCount}}ミリ秒ごとにのみチェックを実行することでCPU負荷を軽減します"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="エリア内のみチェックを実施"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="テキストの色の確認:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="テキストタイプの確認:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="言語の確認:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="カラーを確認してください:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="最小サイズ:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="最大サイズ:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="範囲指定"
|
||||
@@ -1130,9 +1128,9 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="高機能シーンスイ
|
||||
AdvSceneSwitcher.hotkey.macro.pause="マクロ %1 を一時停止します"
|
||||
AdvSceneSwitcher.hotkey.macro.unpause="マクロ %1 の一時停止を解除します"
|
||||
AdvSceneSwitcher.hotkey.macro.togglePause="マクロ %1 の一時停止を切り替えます"
|
||||
AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="マクロセグメント選択を上に移動"
|
||||
AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="マクロセグメント選択を下に移動"
|
||||
AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="選択したマクロセグメントを削除"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.up="マクロセグメント選択を上に移動"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.down="マクロセグメント選択を下に移動"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.remove="選択したマクロセグメントを削除"
|
||||
|
||||
AdvSceneSwitcher.askBackup="高機能シーンスイッチャーの新しいバージョンが検出されました。\n古い設定のバックアップを作成する必要がありますか?"
|
||||
AdvSceneSwitcher.askForMacro="マクロ選択{{macroSelection}}"
|
||||
|
||||
@@ -48,7 +48,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Exportar"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="Importar"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Exportar configurações do Advanced Scene Switcher para arquivo ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Importar configurações do Advanced Scene Switcher de arquivo ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Arquivos de texto (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Arquivos de texto (*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="O Advanced Scene Switcher falhou ao importar configurações"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Configurações do Advanced Scene Switcher importadas com sucesso"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportSensitiveDataWarning="Aviso:\nOs dados exportados podem conter informações sensíveis!"
|
||||
@@ -372,16 +372,16 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="Quão semel
|
||||
AdvSceneSwitcher.condition.video.type.main="Saída principal do OBS"
|
||||
AdvSceneSwitcher.condition.video.type.source="Fonte"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Cena"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Dados do modelo (classificador em cascata haar):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Vizinhos mínimos:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzir carga de CPU realizando a verificação apenas a cada {{throttleCount}} milissegundos"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Realizar verificação apenas na área"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="Verificar cor do texto:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="Verificar tipo de texto:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="Verificar idioma:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="Verificar cor:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Dados do modelo (classificador em cascata haar):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Vizinhos mínimos:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzir carga de CPU realizando a verificação apenas a cada {{throttleCount}} milissegundos"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Realizar verificação apenas na área"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Verificar cor do texto:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Verificar tipo de texto:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Verificar idioma:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="Verificar cor:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Tamanho mínimo:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Tamanho máximo:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Selecionar área"
|
||||
@@ -1111,9 +1111,9 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="Alternar Iniciar/Parar pa
|
||||
AdvSceneSwitcher.hotkey.macro.pause="Pausar macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.unpause="Retomar macro %1"
|
||||
AdvSceneSwitcher.hotkey.macro.togglePause="Alternar pausa da macro %1"
|
||||
AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="Mover seleção de segmento de macro para cima"
|
||||
AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="Mover seleção de segmento de macro para baixo"
|
||||
AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="Remover segmento de macro selecionado"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.up="Mover seleção de segmento de macro para cima"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.down="Mover seleção de segmento de macro para baixo"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.remove="Remover segmento de macro selecionado"
|
||||
|
||||
AdvSceneSwitcher.askBackup="Detectada uma nova versão do Advanced Scene Switcher.\nDeve ser criado um backup das configurações antigas?"
|
||||
AdvSceneSwitcher.askForMacro="Selecionar macro{{macroSelection}}"
|
||||
|
||||
@@ -36,7 +36,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Экспорт"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="Импорт"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Экспортировать настройки расширенного переключателя сцен в файл ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Импортировать настройки Advanced Scene Switcher из файла ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Текстовые файлы (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Текстовые файлы (*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="Advanced Scene Switcher не удалось импортировать настройки"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Настройки Advanced Scene Switcher импортированы успешно"
|
||||
AdvSceneSwitcher.generalTab.priority.fileContent="Содержание файла"
|
||||
|
||||
@@ -38,7 +38,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="Dışa Aktar"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="İçe Aktar"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="Gelişmiş Sahne Değiştirici ayarlarını dosyaya aktar ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="Gelişmiş Sahne Değiştirici ayarlarını dosyadan içe aktar ..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Text dosyası (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="Text dosyası (*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="Gelişmiş Sahne Değiştirici ayarları dosyadan içe aktarmakta başarısız oldu"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="Gelişmiş Sahne Değiştirici ayarları başarılı bir şekilde dosyadan içe aktarıldı"
|
||||
AdvSceneSwitcher.generalTab.priority.fileContent="Dosya İçeriği"
|
||||
@@ -139,10 +139,10 @@ AdvSceneSwitcher.condition.video.screenshotFail="Kaynağın ekran görüntüsü
|
||||
AdvSceneSwitcher.condition.video.patternMatchFail="Desen bulunamadı!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchFail="Nesne bulunamadı!"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="Model verileri yüklenemedi!"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Model verileri (haar kademeli sınıflandırıcı):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum komşular: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}} Yalnızca her seferinde kontrol gerçekleştirerek CPU yükünü azaltın {{throttleCount}} millisaniyeler"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Model verileri (haar kademeli sınıflandırıcı):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Minimum komşular: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}} Yalnızca her seferinde kontrol gerçekleştirerek CPU yükünü azaltın {{throttleCount}} millisaniyeler"
|
||||
AdvSceneSwitcher.condition.stream="Yayınlama"
|
||||
AdvSceneSwitcher.condition.stream.state.start="Yayın çalışıyor"
|
||||
AdvSceneSwitcher.condition.stream.state.stop="Yayın durdu"
|
||||
|
||||
@@ -51,7 +51,7 @@ AdvSceneSwitcher.generalTab.saveOrLoadsettings.export="导出设置"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.import="导入设置"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportWindowTitle="导出高级场景切换器到文件..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.importWindowTitle="导入高级场景切换器到文件..."
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="文本文件 (*.txt)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.textType="文本文件 (*.txt *.json)"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadFail="高级场景切换器导入设置失败"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.loadSuccess="高级场景切换器导入设置成功"
|
||||
AdvSceneSwitcher.generalTab.saveOrLoadsettings.exportSensitiveDataWarning="警告:\n导出的数据可能包含敏感信息!"
|
||||
@@ -395,16 +395,16 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="颜色与
|
||||
AdvSceneSwitcher.condition.video.type.main="OBS的主输出"
|
||||
AdvSceneSwitcher.condition.video.type.source="源"
|
||||
AdvSceneSwitcher.condition.video.type.scene="场景"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小区域: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}每隔{{throttleCount}} 毫秒,才执行一次检查,从而减少 CPU 负载."
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="仅在区域内执行检查"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="文本检查颜色:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="文本检查类型:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="语言检查:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="颜色检查:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="最小区域: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}每隔{{throttleCount}} 毫秒,才执行一次检查,从而减少 CPU 负载."
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="仅在区域内执行检查"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="文本检查颜色:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="文本检查类型:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="语言检查:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="颜色检查:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="最小尺寸:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="最大尺寸:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="选择区域"
|
||||
@@ -1189,9 +1189,9 @@ AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey="切换(启动/停止)高
|
||||
AdvSceneSwitcher.hotkey.macro.pause="停用宏 %1"
|
||||
AdvSceneSwitcher.hotkey.macro.unpause="启用宏 %1"
|
||||
AdvSceneSwitcher.hotkey.macro.togglePause="切换(停用/启用)宏 %1"
|
||||
AdvSceneSwitcher.hotkey.upMacroSegmentHotkey="上移选择宏"
|
||||
AdvSceneSwitcher.hotkey.downMacroSegmentHotkey="下移选择宏"
|
||||
AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey="删除选定的宏"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.up="上移选择宏"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.down="下移选择宏"
|
||||
AdvSceneSwitcher.hotkey.macro.segment.remove="删除选定的宏"
|
||||
|
||||
AdvSceneSwitcher.askBackup="检测到新版本的高级场景切换器。\n是否要创建旧版本的设置备份?"
|
||||
AdvSceneSwitcher.askForMacro="选择宏 {{macroSelection}}"
|
||||
|
||||
1
deps/paho.mqtt.cpp
vendored
Submodule
1
deps/paho.mqtt.cpp
vendored
Submodule
Submodule deps/paho.mqtt.cpp added at 165476b1dc
@@ -181,8 +181,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="logLevel">
|
||||
</widget>
|
||||
<widget class="QComboBox" name="logLevel"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_49">
|
||||
@@ -295,6 +294,17 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="disableMacroWidgetCache">
|
||||
<property name="text">
|
||||
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||
<item>
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace advss {
|
||||
|
||||
class MacroActionEdit;
|
||||
class MacroConditionEdit;
|
||||
class MacroSegment;
|
||||
class Duration;
|
||||
class SequenceWidget;
|
||||
struct SceneGroup;
|
||||
@@ -66,6 +67,7 @@ public slots:
|
||||
void on_showTrayNotifications_stateChanged(int state);
|
||||
void on_uiHintsDisable_stateChanged(int state);
|
||||
void on_disableComboBoxFilter_stateChanged(int state);
|
||||
void on_disableMacroWidgetCache_stateChanged(int state);
|
||||
void on_warnPluginLoadFailure_stateChanged(int state);
|
||||
void on_hideLegacyTabs_stateChanged(int state);
|
||||
void on_priorityUp_clicked();
|
||||
@@ -191,7 +193,7 @@ signals:
|
||||
void MacroRemoved(const QString &name);
|
||||
void MacroRenamed(const QString &oldName, const QString &newName);
|
||||
void MacroSegmentOrderChanged();
|
||||
void SegmentTempVarsChanged();
|
||||
void SegmentTempVarsChanged(MacroSegment *);
|
||||
void HighlightMacrosChanged(bool value);
|
||||
|
||||
void ConnectionAdded(const QString &);
|
||||
|
||||
@@ -205,6 +205,16 @@ void AdvSceneSwitcher::on_disableComboBoxFilter_stateChanged(int state)
|
||||
FilterComboBox::SetFilterBehaviourEnabled(!state);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_disableMacroWidgetCache_stateChanged(int state)
|
||||
{
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
switcher->disableMacroWidgetCache = state;
|
||||
MacroSegmentList::SetCachingEnabled(!state);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
|
||||
{
|
||||
if (loading) {
|
||||
@@ -275,12 +285,15 @@ static bool containsSensitiveData(obs_data_t *data)
|
||||
obs_data_get_array(data, "twitchConnections");
|
||||
OBSDataArrayAutoRelease websocketConnections =
|
||||
obs_data_get_array(data, "websocketConnections");
|
||||
OBSDataArrayAutoRelease mqttConnections =
|
||||
obs_data_get_array(data, "mqttConnections");
|
||||
|
||||
auto isNotEmpty = [](obs_data_array *array) {
|
||||
return obs_data_array_count(array) > 0;
|
||||
};
|
||||
|
||||
return isNotEmpty(twitchTokens) || isNotEmpty(websocketConnections);
|
||||
return isNotEmpty(twitchTokens) || isNotEmpty(websocketConnections) ||
|
||||
isNotEmpty(mqttConnections);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_exportSettings_clicked()
|
||||
@@ -537,6 +550,8 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
|
||||
obs_data_set_bool(obj, "disableHints", disableHints);
|
||||
obs_data_set_bool(obj, "disableFilterComboboxFilter",
|
||||
disableFilterComboboxFilter);
|
||||
obs_data_set_bool(obj, "disableMacroWidgetCache",
|
||||
disableMacroWidgetCache);
|
||||
obs_data_set_bool(obj, "warnPluginLoadFailure", warnPluginLoadFailure);
|
||||
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
|
||||
|
||||
@@ -594,6 +609,8 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
|
||||
disableHints = obs_data_get_bool(obj, "disableHints");
|
||||
disableFilterComboboxFilter =
|
||||
obs_data_get_bool(obj, "disableFilterComboboxFilter");
|
||||
disableMacroWidgetCache =
|
||||
obs_data_get_bool(obj, "disableMacroWidgetCache");
|
||||
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
|
||||
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
|
||||
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
|
||||
@@ -889,6 +906,9 @@ void AdvSceneSwitcher::SetupGeneralTab()
|
||||
switcher->disableFilterComboboxFilter);
|
||||
FilterComboBox::SetFilterBehaviourEnabled(
|
||||
!switcher->disableFilterComboboxFilter);
|
||||
ui->disableMacroWidgetCache->setChecked(
|
||||
switcher->disableMacroWidgetCache);
|
||||
MacroSegmentList::SetCachingEnabled(!switcher->disableMacroWidgetCache);
|
||||
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
|
||||
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
|
||||
|
||||
|
||||
@@ -259,7 +259,8 @@ void AudioSwitch::setVolumeLevel(void *data, const float *,
|
||||
}
|
||||
}
|
||||
|
||||
obs_volmeter_t *AddVolmeterToSource(AudioSwitch *entry, obs_weak_source *source)
|
||||
static obs_volmeter_t *addVolmeterToSource(AudioSwitch *entry,
|
||||
obs_weak_source *source)
|
||||
{
|
||||
obs_volmeter_t *volmeter = obs_volmeter_create(OBS_FADER_LOG);
|
||||
obs_volmeter_add_callback(volmeter, AudioSwitch::setVolumeLevel, entry);
|
||||
@@ -279,7 +280,7 @@ void AudioSwitch::resetVolmeter()
|
||||
obs_volmeter_remove_callback(volmeter, setVolumeLevel, this);
|
||||
obs_volmeter_destroy(volmeter);
|
||||
|
||||
volmeter = AddVolmeterToSource(this, audioSource);
|
||||
volmeter = addVolmeterToSource(this, audioSource);
|
||||
}
|
||||
|
||||
bool AudioSwitch::initialized()
|
||||
@@ -318,7 +319,7 @@ void AudioSwitch::load(obs_data_t *obj)
|
||||
duration.Load(obj, "duration");
|
||||
ignoreInactiveSource = obs_data_get_bool(obj, "ignoreInactiveSource");
|
||||
|
||||
volmeter = AddVolmeterToSource(this, audioSource);
|
||||
volmeter = addVolmeterToSource(this, audioSource);
|
||||
}
|
||||
|
||||
void AudioSwitchFallback::save(obs_data_t *obj)
|
||||
@@ -349,7 +350,7 @@ AudioSwitch::AudioSwitch(const AudioSwitch &other)
|
||||
condition(other.condition),
|
||||
duration(other.duration)
|
||||
{
|
||||
volmeter = AddVolmeterToSource(this, other.audioSource);
|
||||
volmeter = addVolmeterToSource(this, other.audioSource);
|
||||
}
|
||||
|
||||
AudioSwitch::AudioSwitch(AudioSwitch &&other) noexcept
|
||||
|
||||
@@ -35,12 +35,14 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
||||
_enable(new SwitchButton()),
|
||||
_entryData(entryData)
|
||||
{
|
||||
auto actionStateTimer = new QTimer(this);
|
||||
|
||||
QWidget::connect(_actionSelection,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(ActionSelectionChanged(const QString &)));
|
||||
QWidget::connect(_enable, SIGNAL(checked(bool)), this,
|
||||
SLOT(ActionEnableChanged(bool)));
|
||||
QWidget::connect(&_actionStateTimer, SIGNAL(timeout()), this,
|
||||
QWidget::connect(actionStateTimer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdateActionState()));
|
||||
|
||||
populateActionSelection(_actionSelection);
|
||||
@@ -63,7 +65,7 @@ MacroActionEdit::MacroActionEdit(QWidget *parent,
|
||||
_entryData = entryData;
|
||||
SetupWidgets(true);
|
||||
|
||||
_actionStateTimer.start(300);
|
||||
actionStateTimer->start(300);
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ private:
|
||||
SwitchButton *_enable;
|
||||
|
||||
std::shared_ptr<MacroAction> *_entryData;
|
||||
QTimer _actionStateTimer;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
MacroActionFactory() = delete;
|
||||
|
||||
EXPORT static bool Register(const std::string &id, MacroActionInfo);
|
||||
static bool Deregister(const std::string &id);
|
||||
EXPORT static bool Deregister(const std::string &id);
|
||||
static std::shared_ptr<MacroAction> Create(const std::string &id,
|
||||
Macro *m);
|
||||
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
||||
|
||||
@@ -12,25 +12,6 @@ bool MacroActionMacro::_registered = MacroActionFactory::Register(
|
||||
{MacroActionMacro::Create, MacroActionMacroEdit::Create,
|
||||
"AdvSceneSwitcher.action.macro"});
|
||||
|
||||
const static std::map<MacroActionMacro::Action, std::string> actionTypes = {
|
||||
{MacroActionMacro::Action::PAUSE,
|
||||
"AdvSceneSwitcher.action.macro.type.pause"},
|
||||
{MacroActionMacro::Action::UNPAUSE,
|
||||
"AdvSceneSwitcher.action.macro.type.unpause"},
|
||||
{MacroActionMacro::Action::RESET_COUNTER,
|
||||
"AdvSceneSwitcher.action.macro.type.resetCounter"},
|
||||
{MacroActionMacro::Action::RUN,
|
||||
"AdvSceneSwitcher.action.macro.type.run"},
|
||||
{MacroActionMacro::Action::STOP,
|
||||
"AdvSceneSwitcher.action.macro.type.stop"},
|
||||
{MacroActionMacro::Action::DISABLE_ACTION,
|
||||
"AdvSceneSwitcher.action.macro.type.disableAction"},
|
||||
{MacroActionMacro::Action::ENABLE_ACTION,
|
||||
"AdvSceneSwitcher.action.macro.type.enableAction"},
|
||||
{MacroActionMacro::Action::TOGGLE_ACTION,
|
||||
"AdvSceneSwitcher.action.macro.type.toggleAction"},
|
||||
};
|
||||
|
||||
bool MacroActionMacro::PerformAction()
|
||||
{
|
||||
auto macro = _macro.GetMacro();
|
||||
@@ -45,6 +26,9 @@ bool MacroActionMacro::PerformAction()
|
||||
case Action::UNPAUSE:
|
||||
macro->SetPaused(false);
|
||||
break;
|
||||
case Action::TOGGLE_PAUSE:
|
||||
macro->SetPaused(!macro->Paused());
|
||||
break;
|
||||
case Action::RESET_COUNTER:
|
||||
macro->ResetRunCount();
|
||||
break;
|
||||
@@ -210,8 +194,31 @@ void MacroActionMacro::RunActions(Macro *actionMacro) const
|
||||
|
||||
static void populateActionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[_, name] : actionTypes) {
|
||||
list->addItem(obs_module_text(name.c_str()));
|
||||
static const std::vector<std::pair<MacroActionMacro::Action, std::string>>
|
||||
actions = {
|
||||
{MacroActionMacro::Action::PAUSE,
|
||||
"AdvSceneSwitcher.action.macro.type.pause"},
|
||||
{MacroActionMacro::Action::UNPAUSE,
|
||||
"AdvSceneSwitcher.action.macro.type.unpause"},
|
||||
{MacroActionMacro::Action::TOGGLE_PAUSE,
|
||||
"AdvSceneSwitcher.action.macro.type.togglePause"},
|
||||
{MacroActionMacro::Action::RESET_COUNTER,
|
||||
"AdvSceneSwitcher.action.macro.type.resetCounter"},
|
||||
{MacroActionMacro::Action::RUN,
|
||||
"AdvSceneSwitcher.action.macro.type.run"},
|
||||
{MacroActionMacro::Action::STOP,
|
||||
"AdvSceneSwitcher.action.macro.type.stop"},
|
||||
{MacroActionMacro::Action::DISABLE_ACTION,
|
||||
"AdvSceneSwitcher.action.macro.type.disableAction"},
|
||||
{MacroActionMacro::Action::ENABLE_ACTION,
|
||||
"AdvSceneSwitcher.action.macro.type.enableAction"},
|
||||
{MacroActionMacro::Action::TOGGLE_ACTION,
|
||||
"AdvSceneSwitcher.action.macro.type.toggleAction"},
|
||||
};
|
||||
|
||||
for (const auto &[value, name] : actions) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,7 +328,8 @@ void MacroActionMacroEdit::UpdateEntryData()
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_actions->setCurrentIndex(
|
||||
_actions->findData(static_cast<int>(_entryData->_action)));
|
||||
_actionIndex->SetValue(_entryData->_actionIndex);
|
||||
_actionIndex->SetMacro(_entryData->_macro.GetMacro());
|
||||
_macros->SetCurrentMacro(_entryData->_macro);
|
||||
@@ -350,10 +358,11 @@ void MacroActionMacroEdit::MacroChanged(const QString &text)
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionMacroEdit::ActionChanged(int value)
|
||||
void MacroActionMacroEdit::ActionChanged(int idx)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_action = static_cast<MacroActionMacro::Action>(value);
|
||||
_entryData->_action = static_cast<MacroActionMacro::Action>(
|
||||
_actions->itemData(idx).toInt());
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
DISABLE_ACTION,
|
||||
ENABLE_ACTION,
|
||||
TOGGLE_ACTION,
|
||||
TOGGLE_PAUSE,
|
||||
};
|
||||
Action _action = Action::RUN;
|
||||
IntVariable _actionIndex = 1;
|
||||
|
||||
@@ -20,7 +20,7 @@ class MacroConditionFactory {
|
||||
public:
|
||||
MacroConditionFactory() = delete;
|
||||
EXPORT static bool Register(const std::string &, MacroConditionInfo);
|
||||
static bool Deregister(const std::string &);
|
||||
EXPORT static bool Deregister(const std::string &);
|
||||
static std::shared_ptr<MacroCondition> Create(const std::string &,
|
||||
Macro *m);
|
||||
static QWidget *CreateWidget(const std::string &id, QWidget *parent,
|
||||
|
||||
@@ -78,36 +78,36 @@ bool MacroSwitchedScene()
|
||||
return macroSceneSwitched;
|
||||
}
|
||||
|
||||
std::string GetMacroName(Macro *macro)
|
||||
std::string GetMacroName(const Macro *macro)
|
||||
{
|
||||
return macro ? macro->Name() : "";
|
||||
}
|
||||
|
||||
std::chrono::high_resolution_clock::time_point
|
||||
LastMacroConditionCheckTime(Macro *macro)
|
||||
LastMacroConditionCheckTime(const Macro *macro)
|
||||
{
|
||||
return macro ? macro->LastConditionCheckTime()
|
||||
: std::chrono::high_resolution_clock::time_point{};
|
||||
}
|
||||
|
||||
bool MacroIsStopped(Macro *macro)
|
||||
bool MacroIsStopped(const Macro *macro)
|
||||
{
|
||||
return macro ? macro->GetStop() : true;
|
||||
}
|
||||
|
||||
bool MacroIsPaused(Macro *macro)
|
||||
bool MacroIsPaused(const Macro *macro)
|
||||
{
|
||||
return macro ? macro->Paused() : true;
|
||||
}
|
||||
|
||||
bool MacroWasPausedSince(
|
||||
Macro *macro,
|
||||
const Macro *macro,
|
||||
const std::chrono::high_resolution_clock::time_point &time)
|
||||
{
|
||||
return macro ? macro->WasPausedSince(time) : false;
|
||||
}
|
||||
|
||||
bool MacroWasCheckedSinceLastStart(Macro *macro)
|
||||
bool MacroWasCheckedSinceLastStart(const Macro *macro)
|
||||
{
|
||||
if (!macro) {
|
||||
return false;
|
||||
@@ -144,7 +144,7 @@ void ResetMacroRunCount(Macro *macro)
|
||||
macro->ResetRunCount();
|
||||
}
|
||||
|
||||
bool IsValidMacroSegmentIndex(Macro *m, const int idx, bool isCondition)
|
||||
bool IsValidMacroSegmentIndex(const Macro *m, const int idx, bool isCondition)
|
||||
{
|
||||
if (!m || idx < 0) {
|
||||
return false;
|
||||
|
||||
@@ -41,17 +41,17 @@ EXPORT std::atomic_int &GetShutdownConditionCount();
|
||||
EXPORT void SetMacroSwitchedScene(bool value);
|
||||
EXPORT bool MacroSwitchedScene();
|
||||
|
||||
EXPORT std::string GetMacroName(Macro *);
|
||||
EXPORT std::string GetMacroName(const Macro *);
|
||||
|
||||
EXPORT std::chrono::high_resolution_clock::time_point
|
||||
LastMacroConditionCheckTime(Macro *);
|
||||
LastMacroConditionCheckTime(const Macro *);
|
||||
|
||||
EXPORT bool MacroIsStopped(Macro *);
|
||||
EXPORT bool MacroIsPaused(Macro *);
|
||||
EXPORT bool MacroIsStopped(const Macro *);
|
||||
EXPORT bool MacroIsPaused(const Macro *);
|
||||
EXPORT bool
|
||||
MacroWasPausedSince(Macro *,
|
||||
MacroWasPausedSince(const Macro *,
|
||||
const std::chrono::high_resolution_clock::time_point &);
|
||||
EXPORT bool MacroWasCheckedSinceLastStart(Macro *);
|
||||
EXPORT bool MacroWasCheckedSinceLastStart(const Macro *);
|
||||
|
||||
EXPORT void AddMacroHelperThread(Macro *, std::thread &&);
|
||||
|
||||
@@ -68,6 +68,6 @@ EXPORT void InvalidateMacroTempVarValues();
|
||||
EXPORT void ResetMacroConditionTimers(Macro *);
|
||||
EXPORT void ResetMacroRunCount(Macro *);
|
||||
|
||||
bool IsValidMacroSegmentIndex(Macro *m, const int idx, bool isCondition);
|
||||
bool IsValidMacroSegmentIndex(const Macro *m, const int idx, bool isCondition);
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
bool MacroSegmentList::_useCache = true;
|
||||
|
||||
MacroSegmentList::MacroSegmentList(QWidget *parent)
|
||||
: QScrollArea(parent),
|
||||
_layout(new QVBoxLayout),
|
||||
@@ -40,12 +42,21 @@ MacroSegmentList::MacroSegmentList(QWidget *parent)
|
||||
[this]() { SetupVisibleMacroSegmentWidgets(); });
|
||||
}
|
||||
|
||||
static void clearWidgetVector(const std::vector<QWidget *> &widgets)
|
||||
{
|
||||
for (auto widget : widgets) {
|
||||
widget->deleteLater();
|
||||
}
|
||||
};
|
||||
|
||||
MacroSegmentList::~MacroSegmentList()
|
||||
{
|
||||
if (_autoScrollThread.joinable()) {
|
||||
_autoScroll = false;
|
||||
_autoScrollThread.join();
|
||||
}
|
||||
|
||||
ClearWidgetCache();
|
||||
}
|
||||
|
||||
static bool posIsInScrollbar(const QScrollBar *scrollbar, const QPoint &pos)
|
||||
@@ -56,7 +67,7 @@ static bool posIsInScrollbar(const QScrollBar *scrollbar, const QPoint &pos)
|
||||
if (!scrollbar->isVisible()) {
|
||||
return false;
|
||||
}
|
||||
const auto geo = scrollbar->geometry();
|
||||
const auto &geo = scrollbar->geometry();
|
||||
const auto globalGeo = QRect(scrollbar->mapToGlobal(geo.topLeft()),
|
||||
scrollbar->mapToGlobal(geo.bottomRight()));
|
||||
return globalGeo.contains(pos);
|
||||
@@ -125,6 +136,61 @@ void MacroSegmentList::Clear(int idx) const
|
||||
ClearLayout(_contentLayout, idx);
|
||||
}
|
||||
|
||||
void MacroSegmentList::SetCachingEnabled(bool enable)
|
||||
{
|
||||
_useCache = enable;
|
||||
}
|
||||
|
||||
void MacroSegmentList::CacheCurrentWidgetsFor(const Macro *macro)
|
||||
{
|
||||
if (!_useCache) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<QWidget *> result;
|
||||
int idx = 0;
|
||||
QLayoutItem *item;
|
||||
while ((item = _contentLayout->takeAt(idx))) {
|
||||
if (!item || !item->widget()) {
|
||||
continue;
|
||||
}
|
||||
auto widget = item->widget();
|
||||
widget->hide();
|
||||
result.emplace_back(widget);
|
||||
}
|
||||
|
||||
_widgetCache[macro] = result;
|
||||
}
|
||||
|
||||
bool MacroSegmentList::PopulateWidgetsFromCache(const Macro *macro)
|
||||
{
|
||||
if (!_useCache) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = _widgetCache.find(macro);
|
||||
if (it == _widgetCache.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto widget : it->second) {
|
||||
_contentLayout->addWidget(widget);
|
||||
widget->show();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroSegmentList::ClearWidgetsFromCacheFor(const Macro *macro)
|
||||
{
|
||||
auto it = _widgetCache.find(macro);
|
||||
if (it == _widgetCache.end()) {
|
||||
return;
|
||||
}
|
||||
clearWidgetVector(it->second);
|
||||
_widgetCache.erase(it);
|
||||
}
|
||||
|
||||
void MacroSegmentList::Highlight(int idx, QColor color)
|
||||
{
|
||||
auto item = _contentLayout->itemAt(idx);
|
||||
@@ -270,6 +336,13 @@ void MacroSegmentList::HideLastDropLine()
|
||||
_dropLineIdx = -1;
|
||||
}
|
||||
|
||||
void MacroSegmentList::ClearWidgetCache()
|
||||
{
|
||||
for (const auto &[_, widgets] : _widgetCache) {
|
||||
clearWidgetVector(widgets);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isInUpperHalfOf(const QPoint &pos, const QRect &rect)
|
||||
{
|
||||
return QRect(rect.topLeft(),
|
||||
@@ -492,7 +565,7 @@ void MacroSegmentList::dropEvent(QDropEvent *event)
|
||||
|
||||
void MacroSegmentList::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
QScrollArea::resizeEvent(event);
|
||||
SetupVisibleMacroSegmentWidgets();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
class Macro;
|
||||
|
||||
class MacroSegmentList : public QScrollArea {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroSegmentList(QWidget *parent = nullptr);
|
||||
virtual ~MacroSegmentList();
|
||||
~MacroSegmentList();
|
||||
void SetHelpMsg(const QString &msg) const;
|
||||
void SetHelpMsgVisible(bool visible) const;
|
||||
MacroSegmentEdit *WidgetAt(int idx) const;
|
||||
@@ -24,6 +26,10 @@ public:
|
||||
void Add(QWidget *widget);
|
||||
void Remove(int idx) const;
|
||||
void Clear(int idx = 0) const; // Clear all elements >= idx
|
||||
static void SetCachingEnabled(bool enable);
|
||||
void CacheCurrentWidgetsFor(const Macro *);
|
||||
bool PopulateWidgetsFromCache(const Macro *);
|
||||
void ClearWidgetsFromCacheFor(const Macro *);
|
||||
void Highlight(int idx, QColor color = QColor(Qt::green));
|
||||
void SetCollapsed(bool) const;
|
||||
void SetSelection(int idx) const;
|
||||
@@ -55,6 +61,7 @@ private:
|
||||
bool IsInListArea(const QPoint &) const;
|
||||
QRect GetContentItemRectWithPadding(int idx) const;
|
||||
void HideLastDropLine();
|
||||
void ClearWidgetCache();
|
||||
|
||||
int _dragPosition = -1;
|
||||
int _dropLineIdx = -1;
|
||||
@@ -67,6 +74,9 @@ private:
|
||||
QLabel *_helpMsg;
|
||||
|
||||
bool _checkVisibility = true;
|
||||
|
||||
static bool _useCache;
|
||||
std::unordered_map<const Macro *, std::vector<QWidget *>> _widgetCache;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -107,7 +107,7 @@ void MacroSegment::SetupTempVars()
|
||||
void MacroSegment::ClearAvailableTempvars()
|
||||
{
|
||||
_tempVariables.clear();
|
||||
NotifyUIAboutTempVarChange();
|
||||
NotifyUIAboutTempVarChange(this);
|
||||
}
|
||||
|
||||
static std::shared_ptr<MacroSegment>
|
||||
@@ -149,7 +149,7 @@ void MacroSegment::AddTempvar(const std::string &id, const std::string &name,
|
||||
|
||||
TempVariable var(id, name, description, sharedSegment);
|
||||
_tempVariables.emplace_back(std::move(var));
|
||||
NotifyUIAboutTempVarChange();
|
||||
NotifyUIAboutTempVarChange(this);
|
||||
}
|
||||
|
||||
void MacroSegment::SetTempVarValue(const std::string &id,
|
||||
|
||||
@@ -76,12 +76,16 @@ void MacroSelection::ShowAllMacros()
|
||||
|
||||
void MacroSelection::MacroRemove(const QString &name)
|
||||
{
|
||||
const bool currentSelectionWasRemoved = name == currentText();
|
||||
|
||||
int idx = findText(name);
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
removeItem(idx);
|
||||
setCurrentIndex(-1);
|
||||
if (currentSelectionWasRemoved) {
|
||||
setCurrentIndex(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroSelection::MacroRename(const QString &oldName, const QString &newName)
|
||||
|
||||
@@ -100,6 +100,13 @@ bool AdvSceneSwitcher::AddNewMacro(std::shared_ptr<Macro> &res,
|
||||
|
||||
void AdvSceneSwitcher::on_macroAdd_clicked()
|
||||
{
|
||||
// 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
|
||||
// not focused we need to check this here.
|
||||
if (!MacroTabIsInFocus()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
std::shared_ptr<Macro> newMacro;
|
||||
if (!AddNewMacro(newMacro, name)) {
|
||||
@@ -133,6 +140,42 @@ void AdvSceneSwitcher::on_macroAdd_clicked()
|
||||
emit MacroAdded(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
static void addGroupSubitems(std::vector<std::shared_ptr<Macro>> ¯os,
|
||||
const std::shared_ptr<Macro> &group)
|
||||
{
|
||||
std::vector<std::shared_ptr<Macro>> subitems;
|
||||
subitems.reserve(group->GroupSize());
|
||||
|
||||
// Find all subitems
|
||||
auto allMacros = GetMacros();
|
||||
for (auto it = allMacros.begin(); it < allMacros.end(); it++) {
|
||||
if ((*it)->Name() != group->Name()) {
|
||||
continue;
|
||||
}
|
||||
for (uint32_t i = 1; i <= group->GroupSize(); i++) {
|
||||
subitems.emplace_back(*std::next(it, i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove subitems which were already selected to avoid duplicates
|
||||
for (const auto &subitem : subitems) {
|
||||
auto it = std::find(macros.begin(), macros.end(), subitem);
|
||||
if (it == macros.end()) {
|
||||
continue;
|
||||
}
|
||||
macros.erase(it);
|
||||
}
|
||||
|
||||
// Add group subitems
|
||||
auto it = std::find(macros.begin(), macros.end(), group);
|
||||
if (it == macros.end()) {
|
||||
return;
|
||||
}
|
||||
it = std::next(it);
|
||||
macros.insert(it, subitems.begin(), subitems.end());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::RemoveMacro(std::shared_ptr<Macro> ¯o)
|
||||
{
|
||||
if (!macro) {
|
||||
@@ -148,7 +191,27 @@ void AdvSceneSwitcher::RemoveMacro(std::shared_ptr<Macro> ¯o)
|
||||
}
|
||||
}
|
||||
|
||||
const auto clearWidgetCache = [this](Macro *macro) {
|
||||
ui->conditionsList->ClearWidgetsFromCacheFor(macro);
|
||||
ui->actionsList->ClearWidgetsFromCacheFor(macro);
|
||||
ui->elseActionsList->ClearWidgetsFromCacheFor(macro);
|
||||
};
|
||||
|
||||
if (macro->IsGroup()) {
|
||||
std::vector<std::shared_ptr<Macro>> macros = {macro};
|
||||
addGroupSubitems(macros, macro);
|
||||
for (auto macro : macros) {
|
||||
clearWidgetCache(macro.get());
|
||||
}
|
||||
} else {
|
||||
clearWidgetCache(macro.get());
|
||||
}
|
||||
|
||||
// Don't cache widgets for about to be deleted macros
|
||||
MacroSegmentList::SetCachingEnabled(false);
|
||||
ui->macros->Remove(macro);
|
||||
MacroSegmentList::SetCachingEnabled(!switcher->disableMacroWidgetCache);
|
||||
|
||||
emit MacroRemoved(name);
|
||||
}
|
||||
|
||||
@@ -247,41 +310,6 @@ void AdvSceneSwitcher::RenameSelectedMacro()
|
||||
ui->macroName->setText(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
static void addGroupSubitems(std::vector<std::shared_ptr<Macro>> ¯os,
|
||||
const std::shared_ptr<Macro> &group)
|
||||
{
|
||||
std::vector<std::shared_ptr<Macro>> subitems;
|
||||
subitems.reserve(group->GroupSize());
|
||||
|
||||
// Find all subitems
|
||||
auto allMacros = GetMacros();
|
||||
for (auto it = allMacros.begin(); it < allMacros.end(); it++) {
|
||||
if ((*it)->Name() == group->Name()) {
|
||||
for (uint32_t i = 1; i <= group->GroupSize(); i++) {
|
||||
subitems.emplace_back(*std::next(it, i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove subitems which were already selected to avoid duplicates
|
||||
for (const auto &subitem : subitems) {
|
||||
auto it = std::find(macros.begin(), macros.end(), subitem);
|
||||
if (it == macros.end()) {
|
||||
continue;
|
||||
}
|
||||
macros.erase(it);
|
||||
}
|
||||
|
||||
// Add group subitems
|
||||
auto it = std::find(macros.begin(), macros.end(), group);
|
||||
if (it == macros.end()) {
|
||||
return;
|
||||
}
|
||||
it = std::next(it);
|
||||
macros.insert(it, subitems.begin(), subitems.end());
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::ExportMacros() const
|
||||
{
|
||||
auto selectedMacros = GetSelectedMacros();
|
||||
@@ -537,6 +565,11 @@ void AdvSceneSwitcher::on_runMacroOnChange_stateChanged(int value) const
|
||||
void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx)
|
||||
{
|
||||
auto &actions = m.Actions();
|
||||
ui->actionsList->SetHelpMsgVisible(actions.size() == 0);
|
||||
|
||||
if (ui->actionsList->PopulateWidgetsFromCache(&m)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The layout system has not completed geometry propagation yet, so we
|
||||
// can skip those checks for now
|
||||
@@ -547,7 +580,6 @@ void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx)
|
||||
actions[afterIdx]->GetId());
|
||||
ui->actionsList->Add(newEntry);
|
||||
}
|
||||
ui->actionsList->SetHelpMsgVisible(actions.size() == 0);
|
||||
|
||||
// Give the layout system time before enabling the visibility checks and
|
||||
// fully constructing the visible macro segments
|
||||
@@ -559,6 +591,11 @@ void AdvSceneSwitcher::PopulateMacroActions(Macro &m, uint32_t afterIdx)
|
||||
void AdvSceneSwitcher::PopulateMacroElseActions(Macro &m, uint32_t afterIdx)
|
||||
{
|
||||
auto &actions = m.ElseActions();
|
||||
ui->elseActionsList->SetHelpMsgVisible(actions.size() == 0);
|
||||
|
||||
if (ui->elseActionsList->PopulateWidgetsFromCache(&m)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The layout system has not completed geometry propagation yet, so we
|
||||
// can skip those checks for now
|
||||
@@ -569,7 +606,6 @@ void AdvSceneSwitcher::PopulateMacroElseActions(Macro &m, uint32_t afterIdx)
|
||||
actions[afterIdx]->GetId());
|
||||
ui->elseActionsList->Add(newEntry);
|
||||
}
|
||||
ui->elseActionsList->SetHelpMsgVisible(actions.size() == 0);
|
||||
|
||||
// Give the layout system time before enabling the visibility checks and
|
||||
// fully constructing the visible macro segments
|
||||
@@ -582,6 +618,11 @@ void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
|
||||
{
|
||||
bool root = afterIdx == 0;
|
||||
auto &conditions = m.Conditions();
|
||||
ui->conditionsList->SetHelpMsgVisible(conditions.size() == 0);
|
||||
|
||||
if (ui->conditionsList->PopulateWidgetsFromCache(&m)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The layout system has not completed geometry propagation yet, so we
|
||||
// can skip those checks for now
|
||||
@@ -594,7 +635,6 @@ void AdvSceneSwitcher::PopulateMacroConditions(Macro &m, uint32_t afterIdx)
|
||||
ui->conditionsList->Add(newEntry);
|
||||
root = false;
|
||||
}
|
||||
ui->conditionsList->SetHelpMsgVisible(conditions.size() == 0);
|
||||
|
||||
// Give the layout system time before enabling the visibility checks and
|
||||
// fully constructing the visible macro segments
|
||||
@@ -779,6 +819,10 @@ void AdvSceneSwitcher::MacroSelectionAboutToChange() const
|
||||
}
|
||||
macro->SetElseActionSplitterPosition(
|
||||
ui->macroElseActionSplitter->sizes());
|
||||
|
||||
ui->conditionsList->CacheCurrentWidgetsFor(macro);
|
||||
ui->actionsList->CacheCurrentWidgetsFor(macro);
|
||||
ui->elseActionsList->CacheCurrentWidgetsFor(macro);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::MacroSelectionChanged()
|
||||
|
||||
@@ -1301,10 +1301,10 @@ QSize MacroTreeDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
QWidget *item = tree->indexWidget(index);
|
||||
|
||||
if (!item) {
|
||||
return (QSize(0, 0));
|
||||
return QStyledItemDelegate::sizeHint(option, index);
|
||||
}
|
||||
|
||||
return (QSize(option.widget->minimumWidth(), item->height()));
|
||||
return QSize(item->sizeHint());
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -724,16 +724,31 @@ std::deque<std::shared_ptr<MacroCondition>> &Macro::Conditions()
|
||||
return _conditions;
|
||||
}
|
||||
|
||||
const std::deque<std::shared_ptr<MacroCondition>> &Macro::Conditions() const
|
||||
{
|
||||
return _conditions;
|
||||
}
|
||||
|
||||
std::deque<std::shared_ptr<MacroAction>> &Macro::Actions()
|
||||
{
|
||||
return _actions;
|
||||
}
|
||||
|
||||
const std::deque<std::shared_ptr<MacroAction>> &Macro::Actions() const
|
||||
{
|
||||
return _actions;
|
||||
}
|
||||
|
||||
std::deque<std::shared_ptr<MacroAction>> &Macro::ElseActions()
|
||||
{
|
||||
return _elseActions;
|
||||
}
|
||||
|
||||
const std::deque<std::shared_ptr<MacroAction>> &Macro::ElseActions() const
|
||||
{
|
||||
return _elseActions;
|
||||
}
|
||||
|
||||
static void updateIndicesHelper(std::deque<std::shared_ptr<MacroSegment>> &list)
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
@@ -95,8 +95,11 @@ public:
|
||||
|
||||
// Macro segments
|
||||
std::deque<std::shared_ptr<MacroCondition>> &Conditions();
|
||||
const std::deque<std::shared_ptr<MacroCondition>> &Conditions() const;
|
||||
std::deque<std::shared_ptr<MacroAction>> &Actions();
|
||||
const std::deque<std::shared_ptr<MacroAction>> &Actions() const;
|
||||
std::deque<std::shared_ptr<MacroAction>> &ElseActions();
|
||||
const std::deque<std::shared_ptr<MacroAction>> &ElseActions() const;
|
||||
void UpdateActionIndices();
|
||||
void UpdateElseActionIndices();
|
||||
void UpdateConditionIndices();
|
||||
|
||||
@@ -255,6 +255,16 @@ static void removeMacroSegmentHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
}
|
||||
}
|
||||
|
||||
static void addNewMacroHotkeyFunc(void *, obs_hotkey_id, obs_hotkey_t *,
|
||||
bool pressed)
|
||||
{
|
||||
if (pressed && SettingsWindowIsOpened()) {
|
||||
QMetaObject::invokeMethod(GetSettingsWindow(),
|
||||
"on_macroAdd_clicked",
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
static void registerHotkeys()
|
||||
{
|
||||
switcher->startHotkey = obs_hotkey_register_frontend(
|
||||
@@ -270,19 +280,21 @@ static void registerHotkeys()
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.hotkey.startStopToggleSwitcherHotkey"),
|
||||
startStopToggleHotkeyFunc, NULL);
|
||||
switcher->newMacroHotkey = obs_hotkey_register_frontend(
|
||||
"newMacroSwitcherHotkey",
|
||||
obs_module_text("AdvSceneSwitcher.hotkey.macro.new"),
|
||||
addNewMacroHotkeyFunc, NULL);
|
||||
switcher->upMacroSegment = obs_hotkey_register_frontend(
|
||||
"upMacroSegmentSwitcherHotkey",
|
||||
obs_module_text("AdvSceneSwitcher.hotkey.upMacroSegmentHotkey"),
|
||||
obs_module_text("AdvSceneSwitcher.hotkey.macro.segment.up"),
|
||||
upMacroSegmentHotkeyFunc, NULL);
|
||||
switcher->downMacroSegment = obs_hotkey_register_frontend(
|
||||
"downMacroSegmentSwitcherHotkey",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.hotkey.downMacroSegmentHotkey"),
|
||||
obs_module_text("AdvSceneSwitcher.hotkey.macro.segment.down"),
|
||||
downMacroSegmentHotkeyFunc, NULL);
|
||||
switcher->removeMacroSegment = obs_hotkey_register_frontend(
|
||||
"removeMacroSegmentSwitcherHotkey",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.hotkey.removeMacroSegmentHotkey"),
|
||||
obs_module_text("AdvSceneSwitcher.hotkey.macro.segment.remove"),
|
||||
removeMacroSegmentHotkeyFunc, NULL);
|
||||
|
||||
switcher->hotkeysRegistered = true;
|
||||
@@ -300,6 +312,7 @@ void SwitcherData::SaveHotkeys(obs_data_t *obj)
|
||||
saveHotkey(obj, startHotkey, "startHotkey");
|
||||
saveHotkey(obj, stopHotkey, "stopHotkey");
|
||||
saveHotkey(obj, toggleHotkey, "toggleHotkey");
|
||||
saveHotkey(obj, newMacroHotkey, "newMacroHotkey");
|
||||
saveHotkey(obj, upMacroSegment, "upMacroSegmentHotkey");
|
||||
saveHotkey(obj, downMacroSegment, "downMacroSegmentHotkey");
|
||||
saveHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
||||
@@ -312,14 +325,31 @@ static void loadHotkey(obs_data_t *obj, obs_hotkey_id id, const char *name)
|
||||
obs_data_array_release(a);
|
||||
}
|
||||
|
||||
static void setDefaultHotkeyBinding(obs_data_t *data, const char *name,
|
||||
const char *value)
|
||||
{
|
||||
OBSDataAutoRelease hotkeyData = obs_data_create_from_json(value);
|
||||
OBSDataArrayAutoRelease hotkeyArray = obs_data_array_create();
|
||||
obs_data_array_push_back(hotkeyArray, hotkeyData);
|
||||
obs_data_set_default_array(data, name, hotkeyArray);
|
||||
}
|
||||
|
||||
void SwitcherData::LoadHotkeys(obs_data_t *obj)
|
||||
{
|
||||
if (!hotkeysRegistered) {
|
||||
registerHotkeys();
|
||||
}
|
||||
|
||||
setDefaultHotkeyBinding(obj, "newMacroHotkey",
|
||||
"{"
|
||||
"\"control\": true,"
|
||||
"\"key\": \"OBS_KEY_N\""
|
||||
"}");
|
||||
|
||||
loadHotkey(obj, startHotkey, "startHotkey");
|
||||
loadHotkey(obj, stopHotkey, "stopHotkey");
|
||||
loadHotkey(obj, toggleHotkey, "toggleHotkey");
|
||||
loadHotkey(obj, newMacroHotkey, "newMacroHotkey");
|
||||
loadHotkey(obj, upMacroSegment, "upMacroSegmentHotkey");
|
||||
loadHotkey(obj, downMacroSegment, "downMacroSegmentHotkey");
|
||||
loadHotkey(obj, removeMacroSegment, "removeMacroSegmentHotkey");
|
||||
|
||||
@@ -149,6 +149,7 @@ public:
|
||||
obs_hotkey_id startHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id stopHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id toggleHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id newMacroHotkey = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id upMacroSegment = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id downMacroSegment = OBS_INVALID_HOTKEY_ID;
|
||||
obs_hotkey_id removeMacroSegment = OBS_INVALID_HOTKEY_ID;
|
||||
@@ -163,6 +164,7 @@ public:
|
||||
bool warnPluginLoadFailure = true;
|
||||
bool disableHints = false;
|
||||
bool disableFilterComboboxFilter = false;
|
||||
bool disableMacroWidgetCache = false;
|
||||
bool hideLegacyTabs = true;
|
||||
bool saveWindowGeo = false;
|
||||
QPoint windowPos = {};
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
class SliderIgnoreScroll : public QSlider {
|
||||
class ADVSS_EXPORT SliderIgnoreScroll : public QSlider {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
@@ -9,15 +9,14 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
class DurationSelection : public QWidget {
|
||||
class ADVSS_EXPORT DurationSelection : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
EXPORT DurationSelection(QWidget *parent = nullptr,
|
||||
bool showUnitSelection = true,
|
||||
double minValue = 0.0);
|
||||
EXPORT void SetDuration(const Duration &);
|
||||
DurationSelection(QWidget *parent = nullptr,
|
||||
bool showUnitSelection = true, double minValue = 0.0);
|
||||
void SetDuration(const Duration &);
|
||||
Duration GetDuration() const { return _current; }
|
||||
EXPORT QDoubleSpinBox *SpinBox() { return _duration->SpinBox(); }
|
||||
QDoubleSpinBox *SpinBox() { return _duration->SpinBox(); }
|
||||
|
||||
private slots:
|
||||
void _DurationChanged(const NumberVariable<double> &value);
|
||||
|
||||
@@ -62,6 +62,11 @@ void FilterComboBox::SetFilterBehaviourEnabled(bool value)
|
||||
FilterComboBox::_filteringEnabled = value;
|
||||
}
|
||||
|
||||
void FilterComboBox::SetAllowUnmatchedSelection(bool allow)
|
||||
{
|
||||
_allowUnmatchedSelection = allow;
|
||||
}
|
||||
|
||||
void FilterComboBox::setCurrentText(const QString &text)
|
||||
{
|
||||
if (_filteringEnabled) {
|
||||
@@ -82,7 +87,7 @@ void FilterComboBox::setItemText(int index, const QString &text)
|
||||
void FilterComboBox::focusOutEvent(QFocusEvent *event)
|
||||
{
|
||||
// Reset on invalid selection
|
||||
if (findText(currentText()) == -1) {
|
||||
if (!_allowUnmatchedSelection && findText(currentText()) == -1) {
|
||||
setCurrentIndex(-1);
|
||||
Emit(-1, "");
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
FilterComboBox(QWidget *parent = nullptr,
|
||||
const QString &placehodler = "");
|
||||
static void SetFilterBehaviourEnabled(bool);
|
||||
void SetAllowUnmatchedSelection(bool allow);
|
||||
|
||||
void setCurrentText(const QString &text);
|
||||
void setItemText(int index, const QString &text);
|
||||
@@ -27,6 +28,7 @@ private slots:
|
||||
private:
|
||||
void Emit(int index, const QString &text);
|
||||
|
||||
bool _allowUnmatchedSelection = false;
|
||||
int _lastEmittedIndex = -1;
|
||||
QString _lastEmittedText;
|
||||
|
||||
|
||||
@@ -9,6 +9,27 @@ namespace advss {
|
||||
|
||||
template<class T> class MessageDispatcher {
|
||||
public:
|
||||
MessageDispatcher() = default;
|
||||
~MessageDispatcher() = default;
|
||||
MessageDispatcher(const MessageDispatcher &other)
|
||||
: _clients(other._clients)
|
||||
{
|
||||
}
|
||||
MessageDispatcher(MessageDispatcher &&other) noexcept
|
||||
: _clients(other._clients)
|
||||
{
|
||||
}
|
||||
MessageDispatcher<T> &operator=(const MessageDispatcher<T> &other)
|
||||
{
|
||||
_clients = other._clients;
|
||||
return *this;
|
||||
}
|
||||
MessageDispatcher<T> &operator=(MessageDispatcher<T> &&other) noexcept
|
||||
{
|
||||
std::swap(_clients, other._clients);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<MessageBuffer<T>> RegisterClient();
|
||||
void DispatchMessage(const T &message);
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ EXPORT void StopPlugin();
|
||||
EXPORT void StartPlugin();
|
||||
EXPORT bool PluginIsRunning();
|
||||
EXPORT int GetIntervalValue();
|
||||
void AddStartStep(std::function<void()>);
|
||||
void AddStopStep(std::function<void()>);
|
||||
EXPORT void AddStartStep(std::function<void()>);
|
||||
EXPORT void AddStopStep(std::function<void()>);
|
||||
void RunStartSteps();
|
||||
void RunStopSteps();
|
||||
void RunIntervalResetSteps();
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
class ResizingPlainTextEdit : public QPlainTextEdit {
|
||||
class ADVSS_EXPORT ResizingPlainTextEdit : public QPlainTextEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ResizingPlainTextEdit(QWidget *parent, const int scrollAt = 10,
|
||||
const int minLines = 3,
|
||||
const int paddingLines = 2);
|
||||
virtual ~ResizingPlainTextEdit(){};
|
||||
EXPORT int maxLength();
|
||||
EXPORT void setMaxLength(int maxLength);
|
||||
int maxLength();
|
||||
void setMaxLength(int maxLength);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#include "resource-table-hotkey-handler.hpp"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QWidget>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace advss {
|
||||
|
||||
void RegisterHotkeyFunction(QWidget *widget, Qt::Key key,
|
||||
std::function<void()> func)
|
||||
{
|
||||
ResourceTabHotkeyHandler::Instance()->RegisterHandler(widget, key,
|
||||
func);
|
||||
}
|
||||
|
||||
void DeregisterHotkeyFunctions(QWidget *widget)
|
||||
{
|
||||
ResourceTabHotkeyHandler::Instance()->Deregister(widget);
|
||||
}
|
||||
|
||||
ResourceTabHotkeyHandler *ResourceTabHotkeyHandler::Instance()
|
||||
{
|
||||
static ResourceTabHotkeyHandler handler;
|
||||
return &handler;
|
||||
}
|
||||
|
||||
void ResourceTabHotkeyHandler::RegisterHandler(QWidget *widget, Qt::Key key,
|
||||
std::function<void()> func)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
_callbacks.emplace(widget, CallbackData{key, func});
|
||||
widget->installEventFilter(this);
|
||||
}
|
||||
|
||||
void ResourceTabHotkeyHandler::Deregister(QWidget *widget)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
_callbacks.erase(widget);
|
||||
}
|
||||
|
||||
bool ResourceTabHotkeyHandler::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (event->type() != QEvent::KeyPress) {
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
auto pressedKey = keyEvent->key();
|
||||
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
auto it = _callbacks.find(obj);
|
||||
if (it == _callbacks.end()) {
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
auto current = it;
|
||||
while (current != _callbacks.end() && current->first == it->first) {
|
||||
auto &[_, cbData] = *current;
|
||||
if (pressedKey != cbData.key) {
|
||||
++current;
|
||||
continue;
|
||||
}
|
||||
cbData.func();
|
||||
++current;
|
||||
continue;
|
||||
}
|
||||
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#include "export-symbol-helper.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <QEvent>
|
||||
#include <QObject>
|
||||
|
||||
namespace advss {
|
||||
|
||||
EXPORT void RegisterHotkeyFunction(QWidget *, Qt::Key,
|
||||
std::function<void()> func);
|
||||
EXPORT void DeregisterHotkeyFunctions(QWidget *);
|
||||
|
||||
class ResourceTabHotkeyHandler : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static ResourceTabHotkeyHandler *Instance();
|
||||
void RegisterHandler(QWidget *, Qt::Key, std::function<void()> func);
|
||||
void Deregister(QWidget *);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
private:
|
||||
struct CallbackData {
|
||||
Qt::Key key;
|
||||
std::function<void()> func;
|
||||
};
|
||||
|
||||
ResourceTabHotkeyHandler() : QObject(){};
|
||||
|
||||
std::multimap<QObject *, CallbackData> _callbacks;
|
||||
std::mutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "resource-table.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "resource-table-hotkey-handler.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QShortcut>
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -64,13 +64,16 @@ ResourceTable::ResourceTable(QTabWidget *parent, const QString &help,
|
||||
QWidget::connect(_table, &QTableWidget::cellDoubleClicked,
|
||||
[openSettings]() { openSettings(); });
|
||||
|
||||
RegisterHotkeyFunction(this, Qt::Key_F2, openSettings);
|
||||
RegisterHotkeyFunction(this, Qt::Key_Delete, [this]() { Remove(); });
|
||||
}
|
||||
auto settingsShortcut = new QShortcut(QKeySequence("F2"), this);
|
||||
QWidget::connect(settingsShortcut, &QShortcut::activated, this,
|
||||
openSettings);
|
||||
auto removeShortcut = new QShortcut(QKeySequence("Del"), this);
|
||||
QWidget::connect(removeShortcut, &QShortcut::activated, this,
|
||||
[this]() { Remove(); });
|
||||
|
||||
ResourceTable::~ResourceTable()
|
||||
{
|
||||
DeregisterHotkeyFunctions(this);
|
||||
auto newShortcut = new QShortcut(QKeySequence("Ctrl+N"), this);
|
||||
QWidget::connect(newShortcut, &QShortcut::activated, this,
|
||||
[this]() { Add(); });
|
||||
}
|
||||
|
||||
void ResourceTable::SetHelpVisible(bool visible) const
|
||||
|
||||
@@ -18,7 +18,6 @@ public:
|
||||
const QString &addToolTip, const QString &removeToolTip,
|
||||
const QStringList &headers,
|
||||
const std::function<void()> &openSettings);
|
||||
virtual ~ResourceTable();
|
||||
|
||||
QTableWidget *Table() const { return _table; }
|
||||
void SetHelpVisible(bool) const;
|
||||
|
||||
@@ -409,6 +409,13 @@ void SceneSelectionWidget::SetScene(const SceneSelection &s)
|
||||
_currentSelection = s;
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const QSignalBlocker b(this);
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool SceneSelectionWidget::IsCurrentSceneSelected(const QString &name)
|
||||
{
|
||||
return name == QString::fromStdString((obs_module_text(
|
||||
@@ -435,9 +442,8 @@ void SceneSelectionWidget::SelectionChanged(int)
|
||||
|
||||
void SceneSelectionWidget::ItemAdd(const QString &)
|
||||
{
|
||||
blockSignals(true);
|
||||
const QSignalBlocker b(this);
|
||||
Reset();
|
||||
blockSignals(false);
|
||||
}
|
||||
|
||||
bool SceneSelectionWidget::NameUsed(const QString &name)
|
||||
@@ -462,9 +468,8 @@ void SceneSelectionWidget::ItemRemove(const QString &name)
|
||||
|
||||
void SceneSelectionWidget::ItemRename(const QString &, const QString &)
|
||||
{
|
||||
blockSignals(true);
|
||||
const QSignalBlocker b(this);
|
||||
Reset();
|
||||
blockSignals(false);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -45,6 +45,10 @@ public:
|
||||
bool previous = false, bool current = false,
|
||||
bool preview = false);
|
||||
EXPORT void SetScene(const SceneSelection &);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void SceneChanged(const SceneSelection &);
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ void SourceSelectionWidget::PopulateSelection()
|
||||
}
|
||||
_variablesEndIdx = count();
|
||||
|
||||
AddSelectionGroup(this, _sourceNames);
|
||||
AddSelectionGroup(this, _populateSourcesCallback());
|
||||
_sourcesEndIdx = count();
|
||||
|
||||
// Remove last separator
|
||||
@@ -172,13 +172,13 @@ void SourceSelectionWidget::PopulateSelection()
|
||||
setCurrentIndex(-1);
|
||||
}
|
||||
|
||||
SourceSelectionWidget::SourceSelectionWidget(QWidget *parent,
|
||||
const QStringList &sourceNames,
|
||||
bool addVariables)
|
||||
SourceSelectionWidget::SourceSelectionWidget(
|
||||
QWidget *parent, const std::function<QStringList()> &populate,
|
||||
bool addVariables)
|
||||
: FilterComboBox(parent,
|
||||
obs_module_text("AdvSceneSwitcher.selectSource")),
|
||||
_addVariables(addVariables),
|
||||
_sourceNames(sourceNames)
|
||||
_populateSourcesCallback(populate)
|
||||
{
|
||||
setDuplicatesEnabled(true);
|
||||
PopulateSelection();
|
||||
@@ -200,6 +200,11 @@ SourceSelectionWidget::SourceSelectionWidget(QWidget *parent,
|
||||
|
||||
void SourceSelectionWidget::SetSource(const SourceSelection &s)
|
||||
{
|
||||
{
|
||||
const QSignalBlocker b(this);
|
||||
PopulateSelection();
|
||||
}
|
||||
|
||||
int idx = -1;
|
||||
|
||||
switch (s.GetType()) {
|
||||
@@ -229,23 +234,23 @@ void SourceSelectionWidget::SetSource(const SourceSelection &s)
|
||||
_currentSelection = s;
|
||||
}
|
||||
|
||||
void SourceSelectionWidget::SetSourceNameList(const QStringList &list)
|
||||
{
|
||||
_sourceNames = list;
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SourceSelectionWidget::SelectionChanged(int)
|
||||
{
|
||||
_currentSelection = CurrentSelection();
|
||||
emit SourceChanged(_currentSelection);
|
||||
}
|
||||
|
||||
void SourceSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const QSignalBlocker b(this);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SourceSelectionWidget::ItemAdd(const QString &)
|
||||
{
|
||||
blockSignals(true);
|
||||
const QSignalBlocker b(this);
|
||||
Reset();
|
||||
blockSignals(false);
|
||||
}
|
||||
|
||||
bool SourceSelectionWidget::NameUsed(const QString &name)
|
||||
@@ -265,9 +270,8 @@ void SourceSelectionWidget::ItemRemove(const QString &name)
|
||||
|
||||
void SourceSelectionWidget::ItemRename(const QString &, const QString &)
|
||||
{
|
||||
blockSignals(true);
|
||||
const QSignalBlocker b(this);
|
||||
Reset();
|
||||
blockSignals(false);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -39,13 +39,16 @@ class ADVSS_EXPORT SourceSelectionWidget : public FilterComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SourceSelectionWidget(QWidget *parent, const QStringList &sourceNames,
|
||||
SourceSelectionWidget(QWidget *parent,
|
||||
const std::function<QStringList()> &populate,
|
||||
bool addVariables = true);
|
||||
void SetSource(const SourceSelection &);
|
||||
void SetSourceNameList(const QStringList &);
|
||||
signals:
|
||||
void SourceChanged(const SourceSelection &);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void SelectionChanged(int);
|
||||
void ItemAdd(const QString &name);
|
||||
@@ -59,7 +62,7 @@ private:
|
||||
bool NameUsed(const QString &name);
|
||||
|
||||
bool _addVariables;
|
||||
QStringList _sourceNames;
|
||||
std::function<QStringList()> _populateSourcesCallback;
|
||||
SourceSelection _currentSelection;
|
||||
|
||||
// Order of entries
|
||||
|
||||
@@ -274,8 +274,9 @@ TempVariableSelection::TempVariableSelection(QWidget *parent)
|
||||
SLOT(HighlightChanged(int)));
|
||||
QWidget::connect(window(), SIGNAL(MacroSegmentOrderChanged()), this,
|
||||
SLOT(MacroSegmentsChanged()));
|
||||
QWidget::connect(window(), SIGNAL(SegmentTempVarsChanged()), this,
|
||||
SLOT(SegmentTempVarsChanged()));
|
||||
QWidget::connect(window(),
|
||||
SIGNAL(SegmentTempVarsChanged(MacroSegment *)), this,
|
||||
SLOT(SegmentTempVarsChanged(MacroSegment *)));
|
||||
|
||||
auto layout = new QHBoxLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -314,9 +315,15 @@ void TempVariableSelection::MacroSegmentsChanged()
|
||||
SetVariable(currentSelection);
|
||||
}
|
||||
|
||||
void TempVariableSelection::SegmentTempVarsChanged()
|
||||
void TempVariableSelection::SegmentTempVarsChanged(MacroSegment *segment)
|
||||
{
|
||||
MacroSegmentsChanged();
|
||||
const auto currentSegment = GetSegment();
|
||||
const auto currentMacro = currentSegment ? currentSegment->GetMacro()
|
||||
: nullptr;
|
||||
const auto changeMacro = segment ? segment->GetMacro() : nullptr;
|
||||
if (currentMacro == changeMacro) {
|
||||
MacroSegmentsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void TempVariableSelection::HighlightChanged(int idx)
|
||||
@@ -427,13 +434,11 @@ QString TempVariableSelection::SetupInfoLabel()
|
||||
MacroSegment *TempVariableSelection::GetSegment() const
|
||||
{
|
||||
const QWidget *widget = this;
|
||||
{
|
||||
while (widget) {
|
||||
if (qobject_cast<const MacroSegmentEdit *>(widget)) {
|
||||
break;
|
||||
}
|
||||
widget = widget->parentWidget();
|
||||
while (widget) {
|
||||
if (qobject_cast<const MacroSegmentEdit *>(widget)) {
|
||||
break;
|
||||
}
|
||||
widget = widget->parentWidget();
|
||||
}
|
||||
if (!widget) {
|
||||
return nullptr;
|
||||
@@ -442,17 +447,18 @@ MacroSegment *TempVariableSelection::GetSegment() const
|
||||
return segmentWidget->Data().get();
|
||||
}
|
||||
|
||||
void NotifyUIAboutTempVarChange()
|
||||
void NotifyUIAboutTempVarChange(MacroSegment *segment)
|
||||
{
|
||||
obs_queue_task(
|
||||
OBS_TASK_UI,
|
||||
[](void *) {
|
||||
[](void *segment) {
|
||||
if (!SettingsWindowIsOpened()) {
|
||||
return;
|
||||
}
|
||||
AdvSceneSwitcher::window->SegmentTempVarsChanged();
|
||||
AdvSceneSwitcher::window->SegmentTempVarsChanged(
|
||||
(MacroSegment *)segment);
|
||||
},
|
||||
nullptr, false);
|
||||
segment, false);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
private slots:
|
||||
void SelectionIdxChanged(int);
|
||||
void MacroSegmentsChanged();
|
||||
void SegmentTempVarsChanged();
|
||||
void SegmentTempVarsChanged(MacroSegment *);
|
||||
void HighlightChanged(int);
|
||||
|
||||
signals:
|
||||
@@ -104,6 +104,6 @@ private:
|
||||
AutoUpdateTooltipLabel *_info;
|
||||
};
|
||||
|
||||
void NotifyUIAboutTempVarChange();
|
||||
void NotifyUIAboutTempVarChange(MacroSegment *);
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
|
||||
namespace advss {
|
||||
|
||||
class VariableTextEdit : public ResizingPlainTextEdit {
|
||||
class ADVSS_EXPORT VariableTextEdit : public ResizingPlainTextEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
EXPORT VariableTextEdit(QWidget *parent, const int scrollAt = 10,
|
||||
const int minLines = 3,
|
||||
const int paddingLines = 2);
|
||||
EXPORT void setPlainText(const QString &);
|
||||
EXPORT void setPlainText(const StringVariable &);
|
||||
EXPORT void setToolTip(const QString &string);
|
||||
VariableTextEdit(QWidget *parent, const int scrollAt = 10,
|
||||
const int minLines = 3, const int paddingLines = 2);
|
||||
virtual ~VariableTextEdit(){};
|
||||
void setPlainText(const QString &);
|
||||
void setPlainText(const StringVariable &);
|
||||
void setToolTip(const QString &string);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -30,7 +30,9 @@ install_advss_plugin_dependency(...)
|
||||
|
||||
add_plugin(http)
|
||||
add_plugin(midi)
|
||||
add_plugin(mqtt)
|
||||
add_plugin(openvr)
|
||||
add_plugin(scripting)
|
||||
add_plugin(stream-deck)
|
||||
add_plugin(twitch)
|
||||
add_plugin(usb)
|
||||
|
||||
@@ -21,6 +21,8 @@ target_sources(
|
||||
macro-action-log.hpp
|
||||
macro-action-media.cpp
|
||||
macro-action-media.hpp
|
||||
macro-action-obs-settings.cpp
|
||||
macro-action-obs-settings.hpp
|
||||
macro-action-osc.cpp
|
||||
macro-action-osc.hpp
|
||||
macro-action-plugin-state.cpp
|
||||
@@ -181,7 +183,9 @@ target_sources(
|
||||
utils/websocket-helpers.cpp
|
||||
utils/websocket-helpers.hpp
|
||||
utils/websocket-tab.cpp
|
||||
utils/websocket-tab.hpp)
|
||||
utils/websocket-tab.hpp
|
||||
utils/window-selection.cpp
|
||||
utils/window-selection.hpp)
|
||||
|
||||
if(OS_WINDOWS)
|
||||
target_sources(${PROJECT_NAME} PRIVATE utils/windows/windows.cpp)
|
||||
|
||||
@@ -421,10 +421,17 @@ static inline void populateFadeTypeSelection(QComboBox *list)
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getAudioSourcesList()
|
||||
{
|
||||
auto sources = GetAudioSourceNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionAudio> entryData)
|
||||
: QWidget(parent),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getAudioSourcesList, true)),
|
||||
_actions(new QComboBox),
|
||||
_fadeTypes(new QComboBox),
|
||||
_syncOffset(new VariableSpinBox),
|
||||
@@ -468,9 +475,6 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
_rate->setSuffix("%");
|
||||
|
||||
populateActionSelection(_actions);
|
||||
auto sources = GetAudioSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
populateFadeTypeSelection(_fadeTypes);
|
||||
PopulateMonitorTypeSelection(_monitorTypes);
|
||||
|
||||
@@ -518,7 +522,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
|
||||
QWidget::connect(_fadeTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(FadeTypeChanged(int)));
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{audioSources}}", _sources},
|
||||
{"{{actions}}", _actions},
|
||||
{"{{syncOffset}}", _syncOffset},
|
||||
|
||||
@@ -185,8 +185,8 @@ void MacroActionFilter::ResolveVariablesToFixedValues()
|
||||
|
||||
static inline void populateActionSelection(QComboBox *list)
|
||||
{
|
||||
for (auto entry : actionTypes) {
|
||||
list->addItem(obs_module_text(entry.second.c_str()));
|
||||
for (const auto &[_, name] : actionTypes) {
|
||||
list->addItem(obs_module_text(name.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,10 +199,17 @@ static inline void populateSettingsInputMethods(QComboBox *list)
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getFilterSourcesList()
|
||||
{
|
||||
auto sources = GetSourcesWithFilterNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroActionFilterEdit::MacroActionFilterEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionFilter> entryData)
|
||||
: QWidget(parent),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getFilterSourcesList, true)),
|
||||
_filters(new FilterSelectionWidget(this, _sources, true)),
|
||||
_actions(new QComboBox()),
|
||||
_getSettings(new QPushButton(obs_module_text(
|
||||
@@ -220,9 +227,6 @@ MacroActionFilterEdit::MacroActionFilterEdit(
|
||||
_filters->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
|
||||
populateActionSelection(_actions);
|
||||
auto sources = GetSourcesWithFilterNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
_refreshSettingSelection->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.action.filter.refresh.tooltip"));
|
||||
|
||||
|
||||
@@ -219,6 +219,13 @@ static inline void populateSelectionTypeSelection(QComboBox *list)
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getMediaSourcesList()
|
||||
{
|
||||
auto sources = GetMediaSourceNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroActionMediaEdit::MacroActionMediaEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionMedia> entryData)
|
||||
: QWidget(parent),
|
||||
@@ -229,15 +236,12 @@ MacroActionMediaEdit::MacroActionMediaEdit(
|
||||
0, 100,
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.action.media.seek.percentage.label"))),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getMediaSourcesList, true)),
|
||||
_sceneItems(new SceneItemSelectionWidget(parent, false)),
|
||||
_scenes(new SceneSelectionWidget(this, true, false, true, true, true))
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
populateSelectionTypeSelection(_selectionTypes);
|
||||
auto sources = GetMediaSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
|
||||
387
plugins/base/macro-action-obs-settings.cpp
Normal file
387
plugins/base/macro-action-obs-settings.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
#include "macro-action-obs-settings.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "profile-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
#include <util/config-file.h>
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroActionOBSSettings::id = "obs_settings";
|
||||
|
||||
bool MacroActionOBSSettings::_registered = MacroActionFactory::Register(
|
||||
MacroActionOBSSettings::id,
|
||||
{MacroActionOBSSettings::Create, MacroActionOBSSettingsEdit::Create,
|
||||
"AdvSceneSwitcher.action.obsSetting"});
|
||||
|
||||
const static std::map<MacroActionOBSSettings::Action, std::string> actionTypes = {
|
||||
{MacroActionOBSSettings::Action::FPS_TYPE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setFPSType"},
|
||||
{MacroActionOBSSettings::Action::FPS_COMMON_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setFPSCommonValue"},
|
||||
{MacroActionOBSSettings::Action::FPS_INT_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setFPSIntegerValue"},
|
||||
{MacroActionOBSSettings::Action::FPS_NUM_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setFPSFractionNumeratorValue"},
|
||||
{MacroActionOBSSettings::Action::FPS_DEN_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setFPSFractionDenominatorValue"},
|
||||
{MacroActionOBSSettings::Action::BASE_CANVAS_X_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setBaseCanvasX"},
|
||||
{MacroActionOBSSettings::Action::BASE_CANVAS_Y_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setBaseCanvasY"},
|
||||
{MacroActionOBSSettings::Action::OUTPUT_X_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setOutputCanvasX"},
|
||||
{MacroActionOBSSettings::Action::OUTPUT_Y_VALUE,
|
||||
"AdvSceneSwitcher.action.obsSetting.action.setOutputCanvasY"},
|
||||
};
|
||||
|
||||
template<typename Func, typename... Args>
|
||||
static void setConfigValueHelper(Func func, Args... args)
|
||||
{
|
||||
auto config = obs_frontend_get_profile_config();
|
||||
func(config, args...);
|
||||
if (config_save(config) != CONFIG_SUCCESS) {
|
||||
blog(LOG_WARNING, "failed to save config!");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Func, typename... Args>
|
||||
static auto getConfigValueHelper(Func func, Func defaultFunc, Args... args)
|
||||
-> std::optional<std::invoke_result_t<Func, config_t *, Args...>>
|
||||
{
|
||||
using Ret = std::invoke_result_t<Func, config_t *, Args...>;
|
||||
|
||||
auto config = obs_frontend_get_profile_config();
|
||||
if (config_has_user_value(config, args...)) {
|
||||
return func(config, args...);
|
||||
}
|
||||
if (config_has_default_value(config, args...)) {
|
||||
return defaultFunc(config, args...);
|
||||
}
|
||||
return std::optional<Ret>{};
|
||||
}
|
||||
|
||||
bool MacroActionOBSSettings::PerformAction()
|
||||
{
|
||||
switch (_action) {
|
||||
case Action::FPS_TYPE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "FPSType",
|
||||
static_cast<int>(_fpsType));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::FPS_COMMON_VALUE:
|
||||
setConfigValueHelper(config_set_string, "Video", "FPSCommon",
|
||||
_fpsStringValue.c_str());
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::FPS_INT_VALUE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "FPSInt",
|
||||
static_cast<int>(_fpsIntValue));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::FPS_NUM_VALUE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "FPSNum",
|
||||
static_cast<int>(_fpsIntValue));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::FPS_DEN_VALUE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "FPSDen",
|
||||
static_cast<int>(_fpsIntValue));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::BASE_CANVAS_X_VALUE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "BaseCX",
|
||||
static_cast<int>(_canvasSizeValue));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::BASE_CANVAS_Y_VALUE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "BaseCY",
|
||||
static_cast<int>(_canvasSizeValue));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::OUTPUT_X_VALUE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "OutputCX",
|
||||
static_cast<int>(_canvasSizeValue));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
case Action::OUTPUT_Y_VALUE:
|
||||
setConfigValueHelper(config_set_uint, "Video", "OutputCY",
|
||||
static_cast<int>(_canvasSizeValue));
|
||||
obs_frontend_reset_video();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroActionOBSSettings::LogAction() const
|
||||
{
|
||||
auto it = actionTypes.find(_action);
|
||||
if (it != actionTypes.end()) {
|
||||
ablog(LOG_INFO, "performed action \"%s\"", it->second.c_str());
|
||||
} else {
|
||||
blog(LOG_WARNING, "ignored unknown obs setting action %d",
|
||||
static_cast<int>(_action));
|
||||
}
|
||||
}
|
||||
|
||||
bool MacroActionOBSSettings::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroAction::Save(obj);
|
||||
obs_data_set_int(obj, "action", static_cast<int>(_action));
|
||||
_fpsIntValue.Save(obj, "fpsIntValue");
|
||||
_fpsStringValue.Save(obj, "fpsStringValue");
|
||||
_canvasSizeValue.Save(obj, "canvasSizeValue");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroActionOBSSettings::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroAction::Load(obj);
|
||||
_action = static_cast<Action>(obs_data_get_int(obj, "action"));
|
||||
_fpsIntValue.Load(obj, "fpsIntValue");
|
||||
_fpsStringValue.Load(obj, "fpsStringValue");
|
||||
_canvasSizeValue.Load(obj, "canvasSizeValue");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<MacroAction> MacroActionOBSSettings::Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroActionOBSSettings>(m);
|
||||
}
|
||||
|
||||
std::shared_ptr<MacroAction> MacroActionOBSSettings::Copy() const
|
||||
{
|
||||
return std::make_shared<MacroActionOBSSettings>(*this);
|
||||
}
|
||||
|
||||
void MacroActionOBSSettings::ResolveVariablesToFixedValues()
|
||||
{
|
||||
_fpsIntValue.ResolveVariables();
|
||||
_canvasSizeValue.ResolveVariables();
|
||||
}
|
||||
|
||||
static void populateActionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[value, name] : actionTypes) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(value));
|
||||
}
|
||||
}
|
||||
|
||||
static void populateFPSTypeSelection(QComboBox *list)
|
||||
{
|
||||
static const std::map<MacroActionOBSSettings::FPSType, std::string>
|
||||
types = {
|
||||
{MacroActionOBSSettings::FPSType::COMMON,
|
||||
"Basic.Settings.Video.FPSCommon"},
|
||||
{MacroActionOBSSettings::FPSType::INTEGER,
|
||||
"Basic.Settings.Video.FPSInteger"},
|
||||
{MacroActionOBSSettings::FPSType::FRACTION,
|
||||
"Basic.Settings.Video.FPSFraction"},
|
||||
};
|
||||
|
||||
for (const auto &[value, name] : types) {
|
||||
list->addItem(obs_module_text(name.c_str()),
|
||||
static_cast<int>(value));
|
||||
}
|
||||
}
|
||||
|
||||
MacroActionOBSSettingsEdit::MacroActionOBSSettingsEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionOBSSettings> entryData)
|
||||
: QWidget(parent),
|
||||
_actions(new QComboBox(this)),
|
||||
_fpsType(new QComboBox(this)),
|
||||
_fpsIntValue(new VariableSpinBox(this)),
|
||||
_fpsStringValue(new VariableLineEdit(this)),
|
||||
_canvasSizeValue(new VariableSpinBox(this)),
|
||||
_getCurrentValue(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.action.obsSetting.getCurrentValue")))
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
populateFPSTypeSelection(_fpsType);
|
||||
|
||||
_fpsIntValue->setMaximum(1000);
|
||||
_canvasSizeValue->setMaximum(100000);
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
QWidget::connect(_fpsType, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(FPSTypeChanged(int)));
|
||||
QWidget::connect(
|
||||
_fpsIntValue,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this, SLOT(FPSIntValueChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_fpsStringValue, SIGNAL(editingFinished()), this,
|
||||
SLOT(FPSStringValueChanged()));
|
||||
QWidget::connect(
|
||||
_canvasSizeValue,
|
||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
||||
this,
|
||||
SLOT(CanvasSizeValueChanged(const NumberVariable<int> &)));
|
||||
QWidget::connect(_getCurrentValue, SIGNAL(clicked()), this,
|
||||
SLOT(GetCurrentValueClicked()));
|
||||
|
||||
auto layout = new QHBoxLayout();
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.action.obsSettings.layout"),
|
||||
layout,
|
||||
{{"{{actions}}", _actions},
|
||||
{"{{fpsType}}", _fpsType},
|
||||
{"{{fpsIntValue}}", _fpsIntValue},
|
||||
{"{{fpsStringValue}}", _fpsStringValue},
|
||||
{"{{canvasSizeValue}}", _canvasSizeValue},
|
||||
{"{{getCurrentValue}}", _getCurrentValue}});
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_actions->setCurrentIndex(
|
||||
_actions->findData(static_cast<int>(_entryData->_action)));
|
||||
_fpsType->setCurrentIndex(
|
||||
_actions->findData(static_cast<int>(_entryData->_fpsType)));
|
||||
_fpsIntValue->SetValue(_entryData->_fpsIntValue);
|
||||
_fpsStringValue->setText(_entryData->_fpsStringValue);
|
||||
_canvasSizeValue->SetValue(_entryData->_canvasSizeValue);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::FPSTypeChanged(int idx)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_fpsType = static_cast<MacroActionOBSSettings::FPSType>(
|
||||
_fpsType->itemData(idx).toInt());
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::FPSIntValueChanged(
|
||||
const NumberVariable<int> &value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_fpsIntValue = value;
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::FPSStringValueChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_fpsStringValue = _fpsStringValue->text().toStdString();
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::CanvasSizeValueChanged(
|
||||
const NumberVariable<int> &value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_canvasSizeValue = value;
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::GetCurrentValueClicked()
|
||||
{
|
||||
const auto setSpinVideoValue = [this](VariableSpinBox *spin,
|
||||
const char *name) {
|
||||
auto value = getConfigValueHelper(config_get_uint,
|
||||
config_get_default_uint,
|
||||
"Video", name);
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
spin->SetFixedValue(static_cast<int>(*value));
|
||||
};
|
||||
const auto setFpsValue = [&](const char *name) {
|
||||
setSpinVideoValue(_fpsIntValue, name);
|
||||
};
|
||||
const auto setCanvasValue = [&](const char *name) {
|
||||
setSpinVideoValue(_canvasSizeValue, name);
|
||||
};
|
||||
|
||||
switch (_entryData->_action) {
|
||||
case MacroActionOBSSettings::Action::FPS_COMMON_VALUE: {
|
||||
auto value = getConfigValueHelper(config_get_string,
|
||||
config_get_default_string,
|
||||
"Video", "FPSCommon");
|
||||
if (!value) {
|
||||
break;
|
||||
}
|
||||
_fpsStringValue->setText(QString(*value));
|
||||
break;
|
||||
}
|
||||
case MacroActionOBSSettings::Action::FPS_INT_VALUE:
|
||||
setFpsValue("FPSInt");
|
||||
break;
|
||||
case MacroActionOBSSettings::Action::FPS_NUM_VALUE:
|
||||
setFpsValue("FPSNum");
|
||||
break;
|
||||
case MacroActionOBSSettings::Action::FPS_DEN_VALUE:
|
||||
setFpsValue("FPSDen");
|
||||
break;
|
||||
case MacroActionOBSSettings::Action::BASE_CANVAS_X_VALUE:
|
||||
setCanvasValue("BaseCX");
|
||||
break;
|
||||
case MacroActionOBSSettings::Action::BASE_CANVAS_Y_VALUE:
|
||||
setCanvasValue("BaseCY");
|
||||
break;
|
||||
case MacroActionOBSSettings::Action::OUTPUT_X_VALUE:
|
||||
setCanvasValue("OutputCX");
|
||||
break;
|
||||
case MacroActionOBSSettings::Action::OUTPUT_Y_VALUE:
|
||||
setCanvasValue("OutputCY");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::SetWidgetVisibility()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isFPSSelection =
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_TYPE ||
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_COMMON_VALUE ||
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_INT_VALUE ||
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_DEN_VALUE ||
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_NUM_VALUE;
|
||||
|
||||
_fpsType->setVisible(_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_TYPE);
|
||||
_fpsIntValue->setVisible(
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_INT_VALUE ||
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_NUM_VALUE ||
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_DEN_VALUE);
|
||||
_fpsStringValue->setVisible(
|
||||
_entryData->_action ==
|
||||
MacroActionOBSSettings::Action::FPS_COMMON_VALUE);
|
||||
_canvasSizeValue->setVisible(!isFPSSelection);
|
||||
_getCurrentValue->setVisible(_entryData->_action !=
|
||||
MacroActionOBSSettings::Action::FPS_TYPE);
|
||||
}
|
||||
|
||||
void MacroActionOBSSettingsEdit::ActionChanged(int idx)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_action = static_cast<MacroActionOBSSettings::Action>(
|
||||
_actions->itemData(idx).toInt());
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
90
plugins/base/macro-action-obs-settings.hpp
Normal file
90
plugins/base/macro-action-obs-settings.hpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <chrono>
|
||||
|
||||
namespace advss {
|
||||
|
||||
class MacroActionOBSSettings : public MacroAction {
|
||||
public:
|
||||
MacroActionOBSSettings(Macro *m) : MacroAction(m) {}
|
||||
bool PerformAction();
|
||||
void LogAction() const;
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroAction> Create(Macro *m);
|
||||
std::shared_ptr<MacroAction> Copy() const;
|
||||
void ResolveVariablesToFixedValues();
|
||||
|
||||
enum class Action {
|
||||
FPS_TYPE,
|
||||
FPS_COMMON_VALUE,
|
||||
FPS_INT_VALUE,
|
||||
FPS_NUM_VALUE,
|
||||
FPS_DEN_VALUE,
|
||||
BASE_CANVAS_X_VALUE,
|
||||
BASE_CANVAS_Y_VALUE,
|
||||
OUTPUT_X_VALUE,
|
||||
OUTPUT_Y_VALUE,
|
||||
};
|
||||
Action _action = Action::FPS_COMMON_VALUE;
|
||||
enum class FPSType {
|
||||
COMMON,
|
||||
INTEGER,
|
||||
FRACTION,
|
||||
};
|
||||
FPSType _fpsType = FPSType::INTEGER;
|
||||
IntVariable _fpsIntValue = 30;
|
||||
StringVariable _fpsStringValue = "24 NTSC";
|
||||
IntVariable _canvasSizeValue = 1920;
|
||||
|
||||
private:
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroActionOBSSettingsEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroActionOBSSettingsEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroActionOBSSettings> entryData = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroAction> action)
|
||||
{
|
||||
return new MacroActionOBSSettingsEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroActionOBSSettings>(
|
||||
action));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void ActionChanged(int);
|
||||
void FPSTypeChanged(int);
|
||||
void FPSIntValueChanged(const NumberVariable<int> &);
|
||||
void FPSStringValueChanged();
|
||||
void CanvasSizeValueChanged(const NumberVariable<int> &);
|
||||
void GetCurrentValueClicked();
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QComboBox *_actions;
|
||||
QComboBox *_fpsType;
|
||||
VariableSpinBox *_fpsIntValue;
|
||||
VariableLineEdit *_fpsStringValue;
|
||||
VariableSpinBox *_canvasSizeValue;
|
||||
QPushButton *_getCurrentValue;
|
||||
|
||||
std::shared_ptr<MacroActionOBSSettings> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "macro-action-profile.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "profile-helpers.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
@@ -55,20 +54,16 @@ std::shared_ptr<MacroAction> MacroActionProfile::Copy() const
|
||||
|
||||
MacroActionProfileEdit::MacroActionProfileEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionProfile> entryData)
|
||||
: QWidget(parent)
|
||||
: QWidget(parent),
|
||||
_profiles(new ProfileSelectionWidget(this))
|
||||
{
|
||||
_profiles = new QComboBox();
|
||||
PopulateProfileSelection(_profiles);
|
||||
QWidget::connect(_profiles, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(ProfileChanged(const QString &)));
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{profiles}}", _profiles},
|
||||
};
|
||||
auto layout = new QHBoxLayout;
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.profile.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
layout, {{"{{profiles}}", _profiles}});
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
@@ -86,11 +81,7 @@ void MacroActionProfileEdit::UpdateEntryData()
|
||||
|
||||
void MacroActionProfileEdit::ProfileChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_profile = text.toStdString();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include "profile-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -45,11 +44,10 @@ private slots:
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
protected:
|
||||
QComboBox *_profiles;
|
||||
std::shared_ptr<MacroActionProfile> _entryData;
|
||||
|
||||
private:
|
||||
ProfileSelectionWidget *_profiles;
|
||||
|
||||
std::shared_ptr<MacroActionProfile> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "macro-action-projector.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "monitor-helpers.hpp"
|
||||
#include "selection-helpers.hpp"
|
||||
#include "source-helpers.hpp"
|
||||
|
||||
@@ -230,6 +229,13 @@ static void populateWindowTypes(QComboBox *list)
|
||||
"AdvSceneSwitcher.action.projector.fullscreen"));
|
||||
}
|
||||
|
||||
static QStringList getSourcesList()
|
||||
{
|
||||
auto sources = GetSourceNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroActionProjectorEdit::MacroActionProjectorEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionProjector> entryData)
|
||||
: QWidget(parent),
|
||||
@@ -238,8 +244,8 @@ MacroActionProjectorEdit::MacroActionProjectorEdit(
|
||||
_windowTypes(new QComboBox()),
|
||||
_scenes(new SceneSelectionWidget(window(), true, false, true, true,
|
||||
true)),
|
||||
_sources(new SourceSelectionWidget(window(), QStringList(), true)),
|
||||
_monitors(new QComboBox()),
|
||||
_sources(new SourceSelectionWidget(window(), getSourcesList, true)),
|
||||
_monitors(new MonitorSelectionWidget(this)),
|
||||
_projectorWindowName(new VariableLineEdit(this)),
|
||||
_regex(new RegexConfigWidget(this)),
|
||||
_layout(new QHBoxLayout(this))
|
||||
@@ -247,12 +253,11 @@ MacroActionProjectorEdit::MacroActionProjectorEdit(
|
||||
populateActionSelection(_actions);
|
||||
populateWindowTypes(_windowTypes);
|
||||
populateSelectionTypes(_types);
|
||||
auto sources = GetSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
_monitors->addItems(GetMonitorNames());
|
||||
_monitors->setPlaceholderText(
|
||||
obs_module_text("AdvSceneSwitcher.selectDisplay"));
|
||||
_monitors->SetAllowUnmatchedSelection(false);
|
||||
|
||||
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ActionChanged(int)));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "monitor-helpers.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "scene-selection.hpp"
|
||||
#include "source-selection.hpp"
|
||||
@@ -88,7 +89,7 @@ private:
|
||||
QComboBox *_windowTypes;
|
||||
SceneSelectionWidget *_scenes;
|
||||
SourceSelectionWidget *_sources;
|
||||
QComboBox *_monitors;
|
||||
MonitorSelectionWidget *_monitors;
|
||||
VariableLineEdit *_projectorWindowName;
|
||||
RegexConfigWidget *_regex;
|
||||
QHBoxLayout *_layout;
|
||||
|
||||
@@ -193,12 +193,19 @@ static void populateTargetTypeSelection(QComboBox *list)
|
||||
list->addItem(obs_module_text("AdvSceneSwitcher.OBSVideoOutput"));
|
||||
}
|
||||
|
||||
static QStringList getVideoSourcesList()
|
||||
{
|
||||
auto sources = GetVideoSourceNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroActionScreenshotEdit::MacroActionScreenshotEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionScreenshot> entryData)
|
||||
: QWidget(parent),
|
||||
_scenes(new SceneSelectionWidget(this, true, false, true, true,
|
||||
true)),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getVideoSourcesList, true)),
|
||||
_saveType(new QComboBox()),
|
||||
_targetType(new QComboBox()),
|
||||
_savePath(new FileSelection(FileSelection::Type::WRITE, this)),
|
||||
@@ -206,9 +213,6 @@ MacroActionScreenshotEdit::MacroActionScreenshotEdit(
|
||||
{
|
||||
setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.action.screenshot.blackscreenNote"));
|
||||
auto sources = GetVideoSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
populateSaveTypeSelection(_saveType);
|
||||
populateTargetTypeSelection(_targetType);
|
||||
|
||||
@@ -274,10 +274,17 @@ static inline void populateModeSelection(QComboBox *list,
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getSourcesList()
|
||||
{
|
||||
auto sources = GetSourceNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroActionSourceEdit::MacroActionSourceEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionSource> entryData)
|
||||
: QWidget(parent),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getSourcesList, true)),
|
||||
_actions(new QComboBox()),
|
||||
_settingsButtons(new SourceSettingsButtonSelection(this)),
|
||||
_settingsLayout(new QHBoxLayout()),
|
||||
@@ -296,9 +303,7 @@ MacroActionSourceEdit::MacroActionSourceEdit(
|
||||
obs_module_text("AdvSceneSwitcher.action.source.refresh")))
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
auto sources = GetSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
populateModeSelection(_deinterlaceMode, deinterlaceModes);
|
||||
populateModeSelection(_deinterlaceOrder, deinterlaceFieldOrders);
|
||||
populateModeSelection(_settingsInputMethods, inputMethods);
|
||||
|
||||
@@ -163,15 +163,14 @@ MacroActionWindowEdit::MacroActionWindowEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroActionWindow> entryData)
|
||||
: QWidget(parent),
|
||||
_actions(new QComboBox()),
|
||||
_windows(new QComboBox()),
|
||||
_windows(new WindowSelectionWidget(this)),
|
||||
_regex(new RegexConfigWidget(this)),
|
||||
_infoLayout(new QHBoxLayout())
|
||||
{
|
||||
populateActionSelection(_actions);
|
||||
|
||||
_windows->setEditable(true);
|
||||
_windows->setMaxVisibleItems(20);
|
||||
PopulateWindowSelection(_windows);
|
||||
_windows->setToolTip(
|
||||
obs_module_text("AdvSceneSwitcher.tooltip.availableVariables"));
|
||||
|
||||
auto focusLimitation = new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.action.window.type.setFocusWindow.limitation"));
|
||||
@@ -211,19 +210,17 @@ void MacroActionWindowEdit::UpdateEntryData()
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
|
||||
_windows->setCurrentText(QString::fromStdString(_entryData->_window));
|
||||
_windows->setCurrentText(
|
||||
QString::fromStdString(_entryData->_window.UnresolvedValue()));
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroActionWindowEdit::WindowChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_window = text.toStdString();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
@@ -231,11 +228,7 @@ void MacroActionWindowEdit::WindowChanged(const QString &text)
|
||||
|
||||
void MacroActionWindowEdit::RegexChanged(const RegexConfig ®ex)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_regex = regex;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
@@ -252,11 +245,7 @@ void MacroActionWindowEdit::SetWidgetVisibility()
|
||||
|
||||
void MacroActionWindowEdit::ActionChanged(int value)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_action = static_cast<MacroActionWindow::Action>(value);
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "macro-action-edit.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "variable-string.hpp"
|
||||
#include "window-selection.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -62,7 +63,7 @@ private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QComboBox *_actions;
|
||||
QComboBox *_windows;
|
||||
WindowSelectionWidget *_windows;
|
||||
RegexConfigWidget *_regex;
|
||||
QHBoxLayout *_infoLayout;
|
||||
|
||||
|
||||
@@ -292,8 +292,8 @@ bool MacroConditionAudio::Save(obs_data_t *obj) const
|
||||
return true;
|
||||
}
|
||||
|
||||
obs_volmeter_t *AddVolmeterToSource(MacroConditionAudio *entry,
|
||||
obs_weak_source *source)
|
||||
static obs_volmeter_t *addVolmeterToSource(MacroConditionAudio *entry,
|
||||
obs_weak_source *source)
|
||||
{
|
||||
obs_volmeter_t *volmeter = obs_volmeter_create(OBS_FADER_LOG);
|
||||
obs_volmeter_add_callback(volmeter, MacroConditionAudio::SetVolumeLevel,
|
||||
@@ -328,7 +328,7 @@ bool MacroConditionAudio::Load(obs_data_t *obj)
|
||||
obs_data_get_int(obj, "outputCondition"));
|
||||
_volumeCondition = static_cast<VolumeCondition>(
|
||||
obs_data_get_int(obj, "volumeCondition"));
|
||||
_volmeter = AddVolmeterToSource(this, _audioSource.GetSource());
|
||||
_volmeter = addVolmeterToSource(this, _audioSource.GetSource());
|
||||
|
||||
if (obs_data_get_int(obj, "version") < 2) {
|
||||
// Set default values for dB handling
|
||||
@@ -379,7 +379,7 @@ void MacroConditionAudio::ResetVolmeter()
|
||||
obs_volmeter_remove_callback(_volmeter, SetVolumeLevel, this);
|
||||
obs_volmeter_destroy(_volmeter);
|
||||
|
||||
_volmeter = AddVolmeterToSource(this, _audioSource.GetSource());
|
||||
_volmeter = addVolmeterToSource(this, _audioSource.GetSource());
|
||||
}
|
||||
|
||||
void MacroConditionAudio::SetupTempVars()
|
||||
@@ -458,11 +458,18 @@ static inline void populateVolumeConditionSelection(QComboBox *list)
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getAudioSourcesList()
|
||||
{
|
||||
auto sources = GetAudioSourceNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionAudio> entryData)
|
||||
: QWidget(parent),
|
||||
_checkTypes(new QComboBox()),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getAudioSourcesList, true)),
|
||||
_condition(new QComboBox()),
|
||||
_volumePercent(new VariableDoubleSpinBox()),
|
||||
_volumeDB(new VariableDoubleSpinBox),
|
||||
@@ -484,10 +491,6 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||
_syncOffset->setMaximum(20000);
|
||||
_syncOffset->setSuffix("ms");
|
||||
|
||||
auto sources = GetAudioSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(CheckTypeChanged(int)));
|
||||
QWidget::connect(
|
||||
|
||||
@@ -52,24 +52,26 @@ bool MacroConditionCursor::CheckClick()
|
||||
bool MacroConditionCursor::CheckCondition()
|
||||
{
|
||||
bool ret = false;
|
||||
std::pair<int, int> cursorPos = GetCursorPos();
|
||||
const auto &[x, y] = GetCursorPos();
|
||||
SetTempVarValue("x", std::to_string(x));
|
||||
SetTempVarValue("y", std::to_string(y));
|
||||
|
||||
switch (_condition) {
|
||||
case Condition::REGION:
|
||||
ret = cursorPos.first >= _minX && cursorPos.second >= _minY &&
|
||||
cursorPos.first <= _maxX && cursorPos.second <= _maxY;
|
||||
SetVariableValue(std::to_string(cursorPos.first) + " " +
|
||||
std::to_string(cursorPos.second));
|
||||
ret = x >= _minX && y >= _minY && x <= _maxX && y <= _maxY;
|
||||
SetVariableValue(std::to_string(x) + " " + std::to_string(y));
|
||||
break;
|
||||
case Condition::MOVING:
|
||||
ret = cursorPos.first != _lastCursorPosition.first ||
|
||||
cursorPos.second != _lastCursorPosition.second;
|
||||
ret = x != _lastX || y != _lastY;
|
||||
break;
|
||||
case Condition::CLICK:
|
||||
ret = CheckClick();
|
||||
break;
|
||||
}
|
||||
|
||||
_lastCheckTime = std::chrono::high_resolution_clock::now();
|
||||
_lastCursorPosition = cursorPos;
|
||||
_lastX = x;
|
||||
_lastY = y;
|
||||
|
||||
if (GetVariableValue().empty()) {
|
||||
SetVariableValue(ret ? "true" : "false");
|
||||
@@ -109,6 +111,12 @@ bool MacroConditionCursor::Load(obs_data_t *obj)
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroConditionCursor::SetupTempVars()
|
||||
{
|
||||
AddTempvar("x", obs_module_text("AdvSceneSwitcher.tempVar.cursor.x"));
|
||||
AddTempvar("y", obs_module_text("AdvSceneSwitcher.tempVar.cursor.y"));
|
||||
}
|
||||
|
||||
static inline void populateConditionSelection(QComboBox *list)
|
||||
{
|
||||
for (const auto &[condition, name] : cursorConditionTypes) {
|
||||
|
||||
@@ -38,9 +38,12 @@ public:
|
||||
NumberVariable<int> _minX = 0, _minY = 0, _maxX = 0, _maxY = 0;
|
||||
|
||||
private:
|
||||
void SetupTempVars();
|
||||
|
||||
bool CheckClick();
|
||||
std::chrono::high_resolution_clock::time_point _lastCheckTime{};
|
||||
std::pair<int, int> _lastCursorPosition;
|
||||
int _lastX = 0;
|
||||
int _lastY = 0;
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "macro-condition-display.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "monitor-helpers.hpp"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
@@ -254,7 +253,7 @@ MacroConditionDisplayEdit::MacroConditionDisplayEdit(
|
||||
: QWidget(parent),
|
||||
_conditions(new QComboBox()),
|
||||
_compareModes(new QComboBox()),
|
||||
_displays(new QComboBox()),
|
||||
_displays(new MonitorSelectionWidget(this)),
|
||||
_regex(new RegexConfigWidget()),
|
||||
_displayCount(new VariableSpinBox(this)),
|
||||
_displayWidth(new VariableSpinBox(this)),
|
||||
@@ -264,8 +263,6 @@ MacroConditionDisplayEdit::MacroConditionDisplayEdit(
|
||||
{
|
||||
populateConditionSelection(_conditions);
|
||||
populateCompareModeselection(_compareModes);
|
||||
_displays->addItems(GetMonitorNames());
|
||||
_displays->setEditable(true);
|
||||
_displayWidth->setMaximum(99999);
|
||||
_displayHeight->setMaximum(99999);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "monitor-helpers.hpp"
|
||||
#include "variable-line-edit.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
#include "regex-config.hpp"
|
||||
@@ -80,7 +81,7 @@ private:
|
||||
|
||||
QComboBox *_conditions;
|
||||
QComboBox *_compareModes;
|
||||
QComboBox *_displays;
|
||||
MonitorSelectionWidget *_displays;
|
||||
RegexConfigWidget *_regex;
|
||||
VariableSpinBox *_displayCount;
|
||||
VariableSpinBox *_displayWidth;
|
||||
|
||||
@@ -185,10 +185,17 @@ static inline void populateConditionSelection(QComboBox *list)
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getFilterSourcesList()
|
||||
{
|
||||
auto sources = GetSourcesWithFilterNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroConditionFilterEdit::MacroConditionFilterEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionFilter> entryData)
|
||||
: QWidget(parent),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getFilterSourcesList, true)),
|
||||
_filters(new FilterSelectionWidget(this, _sources, true)),
|
||||
_conditions(new QComboBox()),
|
||||
_getSettings(new QPushButton(obs_module_text(
|
||||
@@ -200,9 +207,7 @@ MacroConditionFilterEdit::MacroConditionFilterEdit(
|
||||
obs_module_text("AdvSceneSwitcher.condition.filter.refresh")))
|
||||
{
|
||||
populateConditionSelection(_conditions);
|
||||
auto sources = GetSourcesWithFilterNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
_refreshSettingSelection->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.filter.refresh.tooltip"));
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ void MacroConditionGameCapture::SetupInitialState(obs_source_t *source)
|
||||
calldata_free(&cd);
|
||||
}
|
||||
|
||||
static QStringList getGameCaptureSourceNames()
|
||||
static QStringList getGameCaptureSourcesList()
|
||||
{
|
||||
auto sourceEnum = [](void *param, obs_source_t *source) -> bool /* -- */
|
||||
{
|
||||
@@ -156,18 +156,16 @@ static QStringList getGameCaptureSourceNames()
|
||||
|
||||
QStringList list;
|
||||
obs_enum_sources(sourceEnum, &list);
|
||||
list.sort();
|
||||
return list;
|
||||
}
|
||||
|
||||
MacroConditionGameCaptureEdit::MacroConditionGameCaptureEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionGameCapture> entryData)
|
||||
: QWidget(parent),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true))
|
||||
_sources(new SourceSelectionWidget(this, getGameCaptureSourcesList,
|
||||
true))
|
||||
{
|
||||
auto sources = getGameCaptureSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
QWidget::connect(_sources,
|
||||
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
||||
SLOT(SourceChanged(const SourceSelection &)));
|
||||
|
||||
@@ -256,7 +256,7 @@ void MacroConditionMedia::SetTempVarValues(
|
||||
const auto state = std::get<obs_media_state>(value);
|
||||
SetTempVarValue("state", std::to_string(state));
|
||||
} else {
|
||||
const auto timeInfo = std::get<MediaTimeInfo>(value);
|
||||
const auto &timeInfo = std::get<MediaTimeInfo>(value);
|
||||
SetTempVarValue("time", std::to_string(timeInfo.time));
|
||||
SetTempVarValue("duration", std::to_string(timeInfo.duration));
|
||||
}
|
||||
@@ -610,6 +610,13 @@ static void populateCheckTypes(QComboBox *list)
|
||||
static_cast<int>(MacroConditionMedia::CheckType::TIME));
|
||||
}
|
||||
|
||||
static QStringList getMediaSourcesList()
|
||||
{
|
||||
auto sources = GetMediaSourceNames();
|
||||
sources.sort();
|
||||
return sources;
|
||||
}
|
||||
|
||||
MacroConditionMediaEdit::MacroConditionMediaEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionMedia> entryData)
|
||||
: QWidget(parent),
|
||||
@@ -617,7 +624,7 @@ MacroConditionMediaEdit::MacroConditionMediaEdit(
|
||||
_checkTypes(new QComboBox()),
|
||||
_scenes(new SceneSelectionWidget(window(), true, true, true, true,
|
||||
true)),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getMediaSourcesList, true)),
|
||||
_states(new QComboBox()),
|
||||
_timeRestrictions(new QComboBox()),
|
||||
_time(new DurationSelection())
|
||||
@@ -625,10 +632,6 @@ MacroConditionMediaEdit::MacroConditionMediaEdit(
|
||||
_states->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.media.inconsistencyInfo"));
|
||||
|
||||
auto sources = GetMediaSourceNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
QWidget::connect(_sourceTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(SourceTypeChanged(int)));
|
||||
QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||
|
||||
@@ -60,7 +60,7 @@ bool MacroConditionProcess::CheckCondition()
|
||||
bool MacroConditionProcess::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
obs_data_set_string(obj, "process", _process.c_str());
|
||||
_process.Save(obj, "process");
|
||||
obs_data_set_bool(obj, "focus", _checkFocus);
|
||||
_regex.Save(obj);
|
||||
obs_data_set_int(obj, "version", 1);
|
||||
@@ -70,7 +70,7 @@ bool MacroConditionProcess::Save(obs_data_t *obj) const
|
||||
bool MacroConditionProcess::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_process = obs_data_get_string(obj, "process");
|
||||
_process.Load(obj, "process");
|
||||
_checkFocus = obs_data_get_bool(obj, "focus");
|
||||
// Fall back to partial match regex as default for old version
|
||||
if (!obs_data_has_user_value(obj, "version")) {
|
||||
@@ -104,6 +104,8 @@ MacroConditionProcessEdit::MacroConditionProcessEdit(
|
||||
{
|
||||
_processSelection->setEditable(true);
|
||||
_processSelection->setMaxVisibleItems(20);
|
||||
_processSelection->setToolTip(
|
||||
obs_module_text("AdvSceneSwitcher.tooltip.availableVariables"));
|
||||
|
||||
QWidget::connect(_processSelection,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
@@ -118,7 +120,7 @@ MacroConditionProcessEdit::MacroConditionProcessEdit(
|
||||
|
||||
PopulateProcessSelection(_processSelection);
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{processes}}", _processSelection},
|
||||
{"{{regex}}", _regex},
|
||||
{"{{focused}}", _focused},
|
||||
@@ -146,23 +148,24 @@ MacroConditionProcessEdit::MacroConditionProcessEdit(
|
||||
|
||||
void MacroConditionProcessEdit::ProcessChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_process = text.toStdString();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
}
|
||||
|
||||
void MacroConditionProcessEdit::showEvent(QShowEvent *event)
|
||||
{
|
||||
const QSignalBlocker b(_processSelection);
|
||||
const auto text = _processSelection->currentText();
|
||||
_processSelection->clear();
|
||||
PopulateProcessSelection(_processSelection);
|
||||
_processSelection->setCurrentText(text);
|
||||
}
|
||||
|
||||
void MacroConditionProcessEdit::RegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_regex = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
@@ -170,11 +173,7 @@ void MacroConditionProcessEdit::RegexChanged(const RegexConfig &conf)
|
||||
|
||||
void MacroConditionProcessEdit::FocusChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_checkFocus = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
@@ -193,6 +192,7 @@ void MacroConditionProcessEdit::SetWidgetVisibility()
|
||||
}
|
||||
SetLayoutVisible(_focusLayout, _entryData->_checkFocus);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MacroConditionProcessEdit::UpdateEntryData()
|
||||
@@ -201,7 +201,8 @@ void MacroConditionProcessEdit::UpdateEntryData()
|
||||
return;
|
||||
}
|
||||
|
||||
_processSelection->setCurrentText(_entryData->_process.c_str());
|
||||
_processSelection->setCurrentText(
|
||||
_entryData->_process.UnresolvedValue().c_str());
|
||||
_regex->SetRegexConfig(_entryData->_regex);
|
||||
_focused->setChecked(_entryData->_checkFocus);
|
||||
SetWidgetVisibility();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "variable-string.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
|
||||
namespace advss {
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
return std::make_shared<MacroConditionProcess>(m);
|
||||
}
|
||||
|
||||
std::string _process;
|
||||
StringVariable _process;
|
||||
bool _checkFocus = true;
|
||||
RegexConfig _regex = RegexConfig::PartialMatchRegexConfig();
|
||||
|
||||
@@ -47,6 +47,9 @@ public:
|
||||
std::dynamic_pointer_cast<MacroConditionProcess>(cond));
|
||||
}
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void ProcessChanged(const QString &text);
|
||||
void RegexChanged(const RegexConfig &);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "macro-condition-profile.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "profile-helpers.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
@@ -43,22 +42,16 @@ std::string MacroConditionProfile::GetShortDesc() const
|
||||
MacroConditionProfileEdit::MacroConditionProfileEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionProfile> entryData)
|
||||
: QWidget(parent),
|
||||
_profiles(new QComboBox())
|
||||
_profiles(new ProfileSelectionWidget(this))
|
||||
{
|
||||
PopulateProfileSelection(_profiles);
|
||||
QWidget::connect(_profiles, SIGNAL(currentTextChanged(const QString &)),
|
||||
this, SLOT(ProfileChanged(const QString &)));
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{profiles}}", _profiles},
|
||||
};
|
||||
|
||||
auto layout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.profile.entry"),
|
||||
mainLayout, widgetPlaceholders);
|
||||
setLayout(mainLayout);
|
||||
layout, {{"{{profiles}}", _profiles}});
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
@@ -67,11 +60,7 @@ MacroConditionProfileEdit::MacroConditionProfileEdit(
|
||||
|
||||
void MacroConditionProfileEdit::ProfileChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_profile = text.toStdString();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QComboBox>
|
||||
#include "profile-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
@@ -47,11 +45,10 @@ private slots:
|
||||
signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
protected:
|
||||
QComboBox *_profiles;
|
||||
std::shared_ptr<MacroConditionProfile> _entryData;
|
||||
|
||||
private:
|
||||
ProfileSelectionWidget *_profiles;
|
||||
|
||||
std::shared_ptr<MacroConditionProfile> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -235,6 +235,7 @@ static QStringList getSlideshowNames()
|
||||
|
||||
QStringList list;
|
||||
obs_enum_sources(sourceEnum, &list);
|
||||
list.sort();
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -244,7 +245,7 @@ MacroConditionSlideshowEdit::MacroConditionSlideshowEdit(
|
||||
_conditions(new QComboBox(this)),
|
||||
_index(new VariableSpinBox(this)),
|
||||
_path(new VariableLineEdit(this)),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getSlideshowNames, true)),
|
||||
_regex(new RegexConfigWidget(this)),
|
||||
_layout(new QHBoxLayout())
|
||||
{
|
||||
@@ -253,10 +254,6 @@ MacroConditionSlideshowEdit::MacroConditionSlideshowEdit(
|
||||
_index->setMinimum(1);
|
||||
populateConditionSelection(_conditions);
|
||||
|
||||
auto sources = getSlideshowNames();
|
||||
sources.sort();
|
||||
_sources->SetSourceNameList(sources);
|
||||
|
||||
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(ConditionChanged(int)));
|
||||
QWidget::connect(_sources,
|
||||
|
||||
@@ -229,10 +229,19 @@ static inline void populateSelection(QComboBox *list,
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList getSourcesList()
|
||||
{
|
||||
auto sources = GetSourceNames();
|
||||
sources.sort();
|
||||
auto scenes = GetSceneNames();
|
||||
scenes.sort();
|
||||
return sources + scenes;
|
||||
}
|
||||
|
||||
MacroConditionSourceEdit::MacroConditionSourceEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionSource> entryData)
|
||||
: QWidget(parent),
|
||||
_sources(new SourceSelectionWidget(this, QStringList(), true)),
|
||||
_sources(new SourceSelectionWidget(this, getSourcesList, true)),
|
||||
_conditions(new QComboBox()),
|
||||
_getSettings(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.getSettings"))),
|
||||
@@ -246,11 +255,7 @@ MacroConditionSourceEdit::MacroConditionSourceEdit(
|
||||
{
|
||||
populateSelection(_conditions, sourceConditionTypes);
|
||||
populateSelection(_sizeCompareMethods, compareMethods);
|
||||
auto sources = GetSourceNames();
|
||||
sources.sort();
|
||||
auto scenes = GetSceneNames();
|
||||
scenes.sort();
|
||||
_sources->SetSourceNameList(sources + scenes);
|
||||
|
||||
_refreshSettingSelection->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.source.refresh.tooltip"));
|
||||
_size->setMaximum(999999);
|
||||
|
||||
@@ -407,15 +407,16 @@ void MacroConditionTransitionEdit::SetWidgetVisibility()
|
||||
_entryData->_condition ==
|
||||
MacroConditionTransition::Condition::DURATION);
|
||||
|
||||
bool addCurrent = _entryData->_condition ==
|
||||
MacroConditionTransition::Condition::DURATION;
|
||||
bool addAny = _entryData->_condition ==
|
||||
MacroConditionTransition::Condition::STARTED ||
|
||||
_entryData->_condition ==
|
||||
MacroConditionTransition::Condition::ENDED ||
|
||||
_entryData->_condition ==
|
||||
MacroConditionTransition::Condition::VIDEO_ENDED;
|
||||
_transitions->Repopulate(addCurrent, addAny);
|
||||
_transitions->EnableCurrentEntry(
|
||||
_entryData->_condition ==
|
||||
MacroConditionTransition::Condition::DURATION);
|
||||
_transitions->EnableAnyEntry(
|
||||
_entryData->_condition ==
|
||||
MacroConditionTransition::Condition::STARTED ||
|
||||
_entryData->_condition ==
|
||||
MacroConditionTransition::Condition::ENDED ||
|
||||
_entryData->_condition ==
|
||||
MacroConditionTransition::Condition::VIDEO_ENDED);
|
||||
}
|
||||
|
||||
void MacroConditionTransitionEdit::UpdateEntryData()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "layout-helpers.hpp"
|
||||
#include "plugin-state-helpers.hpp"
|
||||
#include "platform-funcs.hpp"
|
||||
#include "selection-helpers.hpp"
|
||||
|
||||
#include <regex>
|
||||
|
||||
@@ -193,7 +192,7 @@ void MacroConditionWindow::SetupTempVars()
|
||||
MacroConditionWindowEdit::MacroConditionWindowEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionWindow> entryData)
|
||||
: QWidget(parent),
|
||||
_windowSelection(new QComboBox()),
|
||||
_windowSelection(new WindowSelectionWidget(this)),
|
||||
_windowRegex(new RegexConfigWidget(this)),
|
||||
_checkTitle(new QCheckBox()),
|
||||
_fullscreen(new QCheckBox()),
|
||||
@@ -206,14 +205,14 @@ MacroConditionWindowEdit::MacroConditionWindowEdit(
|
||||
_focusWindow(new QLabel()),
|
||||
_currentFocusLayout(new QHBoxLayout())
|
||||
{
|
||||
_windowSelection->setEditable(true);
|
||||
_windowSelection->setMaxVisibleItems(20);
|
||||
|
||||
_checkText->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.window.entry.text.note"));
|
||||
_text->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.window.entry.text.note"));
|
||||
|
||||
_windowSelection->setToolTip(
|
||||
obs_module_text("AdvSceneSwitcher.tooltip.availableVariables"));
|
||||
|
||||
QWidget::connect(_windowSelection,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(WindowChanged(const QString &)));
|
||||
@@ -240,9 +239,7 @@ MacroConditionWindowEdit::MacroConditionWindowEdit(
|
||||
QWidget::connect(&_timer, SIGNAL(timeout()), this,
|
||||
SLOT(UpdateFocusWindow()));
|
||||
|
||||
PopulateWindowSelection(_windowSelection);
|
||||
|
||||
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{windows}}", _windowSelection},
|
||||
{"{{windowRegex}}", _windowRegex},
|
||||
{"{{checkTitle}}", _checkTitle},
|
||||
@@ -320,11 +317,7 @@ MacroConditionWindowEdit::MacroConditionWindowEdit(
|
||||
|
||||
void MacroConditionWindowEdit::WindowChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_window = text.toStdString();
|
||||
emit HeaderInfoChanged(
|
||||
QString::fromStdString(_entryData->GetShortDesc()));
|
||||
@@ -332,11 +325,7 @@ void MacroConditionWindowEdit::WindowChanged(const QString &text)
|
||||
|
||||
void MacroConditionWindowEdit::WindowRegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_windowRegex = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
@@ -344,11 +333,7 @@ void MacroConditionWindowEdit::WindowRegexChanged(const RegexConfig &conf)
|
||||
|
||||
void MacroConditionWindowEdit::CheckTitleChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
const QSignalBlocker b1(_windowSelection);
|
||||
const QSignalBlocker b2(_windowRegex);
|
||||
if (!state) {
|
||||
@@ -363,22 +348,14 @@ void MacroConditionWindowEdit::CheckTitleChanged(int state)
|
||||
|
||||
void MacroConditionWindowEdit::CheckTextChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_checkText = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionWindowEdit::WindowTextChanged()
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_text = _text->toPlainText().toStdString();
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
@@ -386,11 +363,7 @@ void MacroConditionWindowEdit::WindowTextChanged()
|
||||
|
||||
void MacroConditionWindowEdit::TextRegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_textRegex = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
@@ -398,42 +371,26 @@ void MacroConditionWindowEdit::TextRegexChanged(const RegexConfig &conf)
|
||||
|
||||
void MacroConditionWindowEdit::FullscreenChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_fullscreen = state;
|
||||
}
|
||||
|
||||
void MacroConditionWindowEdit::MaximizedChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_maximized = state;
|
||||
}
|
||||
|
||||
void MacroConditionWindowEdit::FocusedChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_focus = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionWindowEdit::WindowFocusChanged(int state)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_windowFocusChanged = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "window-selection.hpp"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
@@ -77,7 +78,7 @@ signals:
|
||||
void HeaderInfoChanged(const QString &);
|
||||
|
||||
protected:
|
||||
QComboBox *_windowSelection;
|
||||
WindowSelectionWidget *_windowSelection;
|
||||
RegexConfigWidget *_windowRegex;
|
||||
QCheckBox *_checkTitle;
|
||||
QCheckBox *_fullscreen;
|
||||
|
||||
@@ -289,6 +289,13 @@ void FilterSelectionWidget::SetFilter(const SourceSelection &source,
|
||||
_currentSelection = filter;
|
||||
}
|
||||
|
||||
void FilterSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const QSignalBlocker b(this);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void FilterSelectionWidget::SourceChanged(const SourceSelection &source)
|
||||
{
|
||||
if (source == _source) {
|
||||
|
||||
@@ -45,6 +45,9 @@ public:
|
||||
bool addVariables = true);
|
||||
void SetFilter(const SourceSelection &, const FilterSelection &);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void FilterChanged(const FilterSelection &);
|
||||
|
||||
|
||||
@@ -47,4 +47,23 @@ QStringList GetMonitorNames()
|
||||
return monitorNames;
|
||||
}
|
||||
|
||||
MonitorSelectionWidget::MonitorSelectionWidget(QWidget *parent)
|
||||
: FilterComboBox(parent)
|
||||
{
|
||||
setEditable(true);
|
||||
SetAllowUnmatchedSelection(true);
|
||||
setMaxVisibleItems(20);
|
||||
addItems(GetMonitorNames());
|
||||
}
|
||||
|
||||
void MonitorSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const QSignalBlocker b(this);
|
||||
const auto text = currentText();
|
||||
clear();
|
||||
addItems(GetMonitorNames());
|
||||
setCurrentText(text);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
#pragma once
|
||||
#include <QStringList>
|
||||
#include "filter-combo-box.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
QStringList GetMonitorNames();
|
||||
|
||||
class MonitorSelectionWidget : public FilterComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MonitorSelectionWidget(QWidget *parent);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -30,4 +30,23 @@ std::string GetPathInProfileDir(const char *filePath)
|
||||
return result + "/" + filePath;
|
||||
}
|
||||
|
||||
ProfileSelectionWidget::ProfileSelectionWidget(QWidget *parent)
|
||||
: FilterComboBox(parent)
|
||||
{
|
||||
setEditable(true);
|
||||
SetAllowUnmatchedSelection(true);
|
||||
setMaxVisibleItems(20);
|
||||
PopulateProfileSelection(this);
|
||||
}
|
||||
|
||||
void ProfileSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const QSignalBlocker b(this);
|
||||
const auto text = currentText();
|
||||
clear();
|
||||
PopulateProfileSelection(this);
|
||||
setCurrentText(text);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <QComboBox>
|
||||
#include "filter-combo-box.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace advss {
|
||||
@@ -7,4 +8,14 @@ namespace advss {
|
||||
void PopulateProfileSelection(QComboBox *list);
|
||||
std::string GetPathInProfileDir(const char *filePath);
|
||||
|
||||
class ProfileSelectionWidget : public FilterComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ProfileSelectionWidget(QWidget *parent);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -558,7 +558,7 @@ static bool populateSceneItemSelectionHelper(obs_scene_t *,
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList GetSceneItemsList(SceneSelection &s)
|
||||
static QStringList getSceneItemsList(SceneSelection &s)
|
||||
{
|
||||
QStringList names;
|
||||
if (s.GetType() != SceneSelection::Type::SCENE) {
|
||||
@@ -589,8 +589,9 @@ QStringList GetSceneItemsList(SceneSelection &s)
|
||||
|
||||
void SceneItemSelectionWidget::PopulateItemSelection()
|
||||
{
|
||||
const QStringList sceneItmes = GetSceneItemsList(_scene);
|
||||
AddSelectionGroup(_sources, sceneItmes, false);
|
||||
_sources->clear();
|
||||
const QStringList sceneItems = getSceneItemsList(_scene);
|
||||
AddSelectionGroup(_sources, sceneItems, false);
|
||||
_sources->setCurrentIndex(-1);
|
||||
}
|
||||
|
||||
@@ -759,8 +760,8 @@ void SceneItemSelectionWidget::SetSceneItem(const SceneItemSelection &item)
|
||||
idx += 1;
|
||||
}
|
||||
_nameConflictIndex->setCurrentIndex(idx);
|
||||
_sources->setCurrentText(
|
||||
QString::fromStdString(GetWeakSourceName(item._source)));
|
||||
_sources->setCurrentIndex(_sources->findText(
|
||||
QString::fromStdString(GetWeakSourceName(item._source))));
|
||||
_sourceGroups->setCurrentText(
|
||||
QString::fromStdString(GetWeakSourceName(item._source)));
|
||||
_variables->SetVariable(item._variable);
|
||||
@@ -773,7 +774,10 @@ void SceneItemSelectionWidget::SetSceneItem(const SceneItemSelection &item)
|
||||
|
||||
_currentSelection = item;
|
||||
|
||||
SetNameConflictVisibility();
|
||||
{
|
||||
const QSignalBlocker b(_nameConflictIndex);
|
||||
SetNameConflictVisibility();
|
||||
}
|
||||
|
||||
switch (item._nameConflictSelectionType) {
|
||||
case SceneItemSelection::NameConflictSelection::ALL:
|
||||
@@ -795,10 +799,17 @@ void SceneItemSelectionWidget::SetSceneItem(const SceneItemSelection &item)
|
||||
|
||||
void SceneItemSelectionWidget::SetScene(const SceneSelection &s)
|
||||
{
|
||||
|
||||
_scene = s;
|
||||
_sources->clear();
|
||||
_nameConflictIndex->hide();
|
||||
if (_currentSelection._type != SceneItemSelection::Type::SOURCE_NAME) {
|
||||
PopulateItemSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
auto previous = _currentSelection;
|
||||
PopulateItemSelection();
|
||||
SetSceneItem(previous);
|
||||
}
|
||||
|
||||
void SceneItemSelectionWidget::ShowPlaceholder(bool value)
|
||||
@@ -819,6 +830,15 @@ void SceneItemSelectionWidget::SetPlaceholderType(Placeholder t,
|
||||
}
|
||||
}
|
||||
|
||||
void SceneItemSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
QWidget::showEvent(event);
|
||||
const QSignalBlocker b1(_sources);
|
||||
const QSignalBlocker b2(this);
|
||||
PopulateItemSelection();
|
||||
SetSceneItem(_currentSelection);
|
||||
}
|
||||
|
||||
void SceneItemSelectionWidget::SceneChanged(const SceneSelection &s)
|
||||
{
|
||||
SetScene(s);
|
||||
|
||||
@@ -97,6 +97,10 @@ public:
|
||||
void SetScene(const SceneSelection &);
|
||||
void ShowPlaceholder(bool);
|
||||
void SetPlaceholderType(Placeholder t, bool resetSelection = true);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void SceneItemChanged(const SceneItemSelection &);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "source-setting.hpp"
|
||||
#include "json-helpers.hpp"
|
||||
#include "log-helper.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "math-helpers.hpp"
|
||||
|
||||
@@ -151,10 +152,14 @@ void SetSourceSetting(obs_source_t *source, const SourceSetting &setting,
|
||||
{
|
||||
auto id = setting.GetID();
|
||||
OBSDataAutoRelease data = obs_source_get_settings(source);
|
||||
auto item = obs_data_item_byname(data, id.c_str());
|
||||
OBSDataAutoRelease dataWithDefaults = obs_data_get_defaults(data);
|
||||
obs_data_apply(dataWithDefaults, data);
|
||||
auto item = obs_data_item_byname(dataWithDefaults, id.c_str());
|
||||
auto type = obs_data_item_gettype(item);
|
||||
switch (type) {
|
||||
case OBS_DATA_NULL:
|
||||
vblog(LOG_WARNING,
|
||||
"could not set settings value, as the value does not (yet) exist!");
|
||||
break;
|
||||
case OBS_DATA_STRING:
|
||||
obs_data_set_string(data, id.c_str(), value.c_str());
|
||||
|
||||
@@ -72,7 +72,9 @@ std::string TransitionSelection::ToString() const
|
||||
TransitionSelectionWidget::TransitionSelectionWidget(QWidget *parent,
|
||||
bool current, bool any)
|
||||
: FilterComboBox(parent,
|
||||
obs_module_text("AdvSceneSwitcher.selectTransition"))
|
||||
obs_module_text("AdvSceneSwitcher.selectTransition")),
|
||||
_addCurrent(current),
|
||||
_addAny(any)
|
||||
{
|
||||
setDuplicatesEnabled(true);
|
||||
PopulateTransitionSelection(this, current, any, false);
|
||||
@@ -81,7 +83,7 @@ TransitionSelectionWidget::TransitionSelectionWidget(QWidget *parent,
|
||||
this, SLOT(SelectionChanged(const QString &)));
|
||||
}
|
||||
|
||||
void TransitionSelectionWidget::SetTransition(TransitionSelection &t)
|
||||
void TransitionSelectionWidget::SetTransition(const TransitionSelection &t)
|
||||
{
|
||||
// Order of entries
|
||||
// 1. Any transition
|
||||
@@ -106,19 +108,35 @@ void TransitionSelectionWidget::SetTransition(TransitionSelection &t)
|
||||
}
|
||||
}
|
||||
|
||||
void TransitionSelectionWidget::Repopulate(bool current, bool any)
|
||||
void TransitionSelectionWidget::EnableCurrentEntry(bool enable)
|
||||
{
|
||||
{
|
||||
const QSignalBlocker blocker(this);
|
||||
clear();
|
||||
PopulateTransitionSelection(this, current, any);
|
||||
setCurrentIndex(-1);
|
||||
}
|
||||
TransitionSelection t;
|
||||
emit TransitionChanged(t);
|
||||
_addCurrent = enable;
|
||||
Populate();
|
||||
}
|
||||
|
||||
static bool isFirstEntry(QComboBox *l, QString name, int idx)
|
||||
void TransitionSelectionWidget::EnableAnyEntry(bool enable)
|
||||
{
|
||||
_addAny = enable;
|
||||
Populate();
|
||||
}
|
||||
|
||||
void TransitionSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const auto selection = GetCurrentSelection();
|
||||
const QSignalBlocker b(this);
|
||||
Populate();
|
||||
SetTransition(selection);
|
||||
}
|
||||
|
||||
void TransitionSelectionWidget::Populate()
|
||||
{
|
||||
const QSignalBlocker blocker(this);
|
||||
clear();
|
||||
PopulateTransitionSelection(this, _addCurrent, _addAny);
|
||||
}
|
||||
|
||||
static bool isFirstEntry(const QComboBox *l, QString name, int idx)
|
||||
{
|
||||
for (auto i = l->count() - 1; i >= 0; i--) {
|
||||
if (l->itemText(i) == name) {
|
||||
@@ -130,7 +148,27 @@ static bool isFirstEntry(QComboBox *l, QString name, int idx)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TransitionSelectionWidget::IsCurrentTransitionSelected(const QString &name)
|
||||
TransitionSelection TransitionSelectionWidget::GetCurrentSelection() const
|
||||
{
|
||||
TransitionSelection result;
|
||||
const auto text = currentText();
|
||||
auto transition = GetWeakTransitionByQString(text);
|
||||
if (transition) {
|
||||
result._type = TransitionSelection::Type::TRANSITION;
|
||||
result._transition = transition;
|
||||
} else {
|
||||
if (IsCurrentTransitionSelected(text)) {
|
||||
result._type = TransitionSelection::Type::CURRENT;
|
||||
}
|
||||
if (IsAnyTransitionSelected(text)) {
|
||||
result._type = TransitionSelection::Type::ANY;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TransitionSelectionWidget::IsCurrentTransitionSelected(
|
||||
const QString &name) const
|
||||
{
|
||||
if (name == QString::fromStdString((obs_module_text(
|
||||
"AdvSceneSwitcher.currentTransition")))) {
|
||||
@@ -139,7 +177,8 @@ bool TransitionSelectionWidget::IsCurrentTransitionSelected(const QString &name)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TransitionSelectionWidget::IsAnyTransitionSelected(const QString &name)
|
||||
bool TransitionSelectionWidget::IsAnyTransitionSelected(
|
||||
const QString &name) const
|
||||
{
|
||||
if (name == QString::fromStdString((obs_module_text(
|
||||
"AdvSceneSwitcher.anyTransition")))) {
|
||||
@@ -148,25 +187,9 @@ bool TransitionSelectionWidget::IsAnyTransitionSelected(const QString &name)
|
||||
return false;
|
||||
}
|
||||
|
||||
void TransitionSelectionWidget::SelectionChanged(const QString &name)
|
||||
void TransitionSelectionWidget::SelectionChanged(const QString &)
|
||||
{
|
||||
TransitionSelection t;
|
||||
auto transition = GetWeakTransitionByQString(name);
|
||||
if (transition) {
|
||||
t._type = TransitionSelection::Type::TRANSITION;
|
||||
t._transition = transition;
|
||||
}
|
||||
|
||||
if (!transition) {
|
||||
if (IsCurrentTransitionSelected(name)) {
|
||||
t._type = TransitionSelection::Type::CURRENT;
|
||||
}
|
||||
if (IsAnyTransitionSelected(name)) {
|
||||
t._type = TransitionSelection::Type::ANY;
|
||||
}
|
||||
}
|
||||
|
||||
emit TransitionChanged(t);
|
||||
emit TransitionChanged(GetCurrentSelection());
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
||||
@@ -34,8 +34,13 @@ class TransitionSelectionWidget : public FilterComboBox {
|
||||
public:
|
||||
TransitionSelectionWidget(QWidget *parent, bool current = true,
|
||||
bool any = false);
|
||||
void SetTransition(TransitionSelection &);
|
||||
void Repopulate(bool current, bool any);
|
||||
void SetTransition(const TransitionSelection &);
|
||||
void EnableCurrentEntry(bool enable);
|
||||
void EnableAnyEntry(bool enable);
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void TransitionChanged(const TransitionSelection &);
|
||||
|
||||
@@ -43,8 +48,13 @@ private slots:
|
||||
void SelectionChanged(const QString &name);
|
||||
|
||||
private:
|
||||
bool IsCurrentTransitionSelected(const QString &name);
|
||||
bool IsAnyTransitionSelected(const QString &name);
|
||||
void Populate();
|
||||
TransitionSelection GetCurrentSelection() const;
|
||||
bool IsCurrentTransitionSelected(const QString &name) const;
|
||||
bool IsAnyTransitionSelected(const QString &name) const;
|
||||
|
||||
bool _addCurrent;
|
||||
bool _addAny;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
||||
25
plugins/base/utils/window-selection.cpp
Normal file
25
plugins/base/utils/window-selection.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "window-selection.hpp"
|
||||
#include "selection-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
WindowSelectionWidget::WindowSelectionWidget(QWidget *parent)
|
||||
: FilterComboBox(parent)
|
||||
{
|
||||
setEditable(true);
|
||||
SetAllowUnmatchedSelection(true);
|
||||
setMaxVisibleItems(20);
|
||||
PopulateWindowSelection(this);
|
||||
}
|
||||
|
||||
void WindowSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const QSignalBlocker b(this);
|
||||
const auto text = currentText();
|
||||
clear();
|
||||
PopulateWindowSelection(this);
|
||||
setCurrentText(text);
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user