Compare commits

...

67 Commits

Author SHA1 Message Date
WarmUpTill
17d9b73b9a Fix thread flood when Twitch event sub connection is lost
Some checks failed
debian-build / build (push) Has been cancelled
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-03-15 12:31:13 +01:00
WarmUpTill
d6185a6099 Add handling for Twitch API throttling 2025-03-15 12:31:13 +01:00
WarmUpTill
41c06b9edb Refactor Twitch condition event handling 2025-03-15 12:31:13 +01:00
WarmUpTill
d8807077da Add option to query reward information 2025-03-15 12:31:13 +01:00
WarmUpTill
34e125f82d Rework chache handling
* No longer provide multiple HTTP helper functions with the same name
* Default to cache not being used
* Explicitly use the cache for certain Twitch actions and conditions
* Clear caches on shutdown to avoid leaks being reported
2025-03-15 12:31:13 +01:00
WarmUpTill
d670b6d07e Move JSON temp var heper functions 2025-03-15 12:31:13 +01:00
WarmUpTill
7b0f985f18 Add macro properties for 'reward' object in redemption events 2025-03-15 12:31:13 +01:00
WarmUpTill
212be923f6 Add option to query user information 2025-03-15 12:31:13 +01:00
WarmUpTill
88fcb57e9f Cleanup 2025-03-15 12:31:13 +01:00
WarmUpTill
9b609c118f Fix disabling chat emote only mode attempting to send chat messages 2025-03-15 12:31:13 +01:00
WarmUpTill
37c398d37a Indicate that "Set to condition/action value" should be avoided 2025-03-15 12:31:13 +01:00
WarmUpTill
a51b7f6b13 Fix UI theming issues
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-03-11 22:12:05 +01:00
WarmUpTill
808fd84b83 Remove Qt5 support 2025-03-11 22:12:05 +01:00
WarmUpTill
57bcea15f5 cmake: Replace find_qt with find_package 2025-03-10 19:48:01 +01:00
WarmUpTill
4e51b56b9b Add game capture condition 2025-03-10 18:49:07 +01:00
WarmUpTill
ef5cf41d34 Add OBS 31 support 2025-03-10 18:49:07 +01:00
WarmUpTill
911e79ea6a Fix OCR controls showing in place of color controls
This happened when OCR support was disabled at build time
2025-03-10 18:33:13 +01:00
WarmUpTill
d586177de0 Add screenshot condition
Some checks are pending
debian-build / build (push) Waiting to run
Check locale / ubuntu64 (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
2025-03-09 20:57:51 +01:00
WarmUpTill
202c36646c Fix UI issues when opening ItemSettingsDialogs
Some widgets were displayed incorrectly if the parent of the dialog
window is not the main settings window
2025-03-09 20:05:07 +01:00
WarmUpTill
ab5102f5ca Fix typo 2025-03-09 20:05:07 +01:00
WarmUpTill
e612fb99f6 Cleanup
Some checks failed
debian-build / build (push) Has been cancelled
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
* Reorder action type selection
* Refactor
2025-03-06 21:30:03 +01:00
WarmUpTill
691e77a69a Add option to generate random number 2025-03-06 21:30:03 +01:00
Kaito Udagawa
930118c61f Call Setup() after Load()
Some checks are pending
debian-build / build (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
Tesseract API depends on the languageCode and this must be reinitialized after Load
2025-03-06 08:43:54 +01:00
Kaito Udagawa
1e05f2f2ce Fix languageCode
LanguageCode is not respected by OCRParameters and settings properly.
2025-03-06 08:43:54 +01:00
WarmUpTill
ae25b4d023 Improve setting selection handling
Some checks are pending
debian-build / build (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
Will now try to keep the current selection if possible.
This can be useful when switching between source of the same time.
2025-03-05 14:16:04 +01:00
WarmUpTill
af055a12a1 Cleanup 2025-03-05 14:16:04 +01:00
WarmUpTill
7de28eedd3 Improve settings button selection handling
Will now try to keep the current button selection if possible.
This can be useful when switching between source of the same time.
2025-03-05 14:16:04 +01:00
WarmUpTill
8dfe81f522 Display failure if Twitch token account name cannot be fetched
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-02-27 19:52:41 +01:00
WarmUpTill
a1d8ae291d Add option to hide empty name warning in ItemSettingsDialog 2025-02-27 19:52:41 +01:00
WarmUpTill
eb6989527d Add support for libproc2 version 4.0.5
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-02-10 18:12:08 +01:00
WarmUpTill
2986a5dd96 Fix crash when actions were copied into a action queue
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
The steps added via AddPostLoadStep() from the copy were never executed.
Thus they might be invalid when RunPostLoadSteps() is next called.

This could result in a crash when a new action or condition is added
after e.g. a "Filter" action's TempVariableRef was copied, which adds a
PostLoadStep to resolve the macro segment reference.
2025-02-04 08:26:04 +01:00
WarmUpTill
816ee9b244 Fix crash when changing Twitch condition type 2025-02-04 08:26:04 +01:00
WarmUpTill
51b53bf948 Fix script actions / conditions not working after stopping macro
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-01-30 09:39:50 +01:00
WarmUpTill
2c5121ee94 Prevent crash when macro contains invalid action or condition 2025-01-30 09:39:50 +01:00
WarmUpTill
6a58684854 Fix import of incomplete settings not resetting duration to zero
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-01-23 19:00:51 +01:00
WarmUpTill
0b622fdbed Fix crash when importing settings 2025-01-23 19:00:51 +01:00
WarmUpTill
3bce8e075f CI: Switch to and adapt to Ubuntu 24 runner
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2025-01-15 21:36:54 +01:00
WarmUpTill
f598d84ea1 Fix freeze due to ResizingPlainTextEdit constantly resizing incorrectly 2025-01-15 21:36:35 +01:00
WarmUpTill
d7a244e80e Fix transition condition not considering transition overrides
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-12-31 12:47:20 +01:00
WarmUpTill
408002e96a Add support for OBS 31 in-tree builds
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-12-12 21:41:21 +01:00
WarmUpTill
50da3d3210 Fix "Media" condition showing the incorrect macro property selection
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-11-30 12:11:14 +01:00
WarmUpTill
9e13067769 Fix typo
Some checks failed
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-11-23 17:11:05 +01:00
WarmUpTill
821e768e76 Reduce screenshot selection area to area to be checked
Some checks failed
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
debian-build / build (push) Has been cancelled
2024-11-22 20:52:15 +01:00
WarmUpTill
4d2179448b Rename files 2024-11-22 20:52:15 +01:00
WarmUpTill
40d9002470 Update scripting examples
* Add more comments
* Add example showcasing how to register and set temp vars
2024-11-22 20:36:36 +01:00
WarmUpTill
7f1e310ca6 Add support to register, deregister, and set temp vars from scripts 2024-11-22 20:36:36 +01:00
WarmUpTill
66d02f4683 Fix typos 2024-11-22 20:36:36 +01:00
Arash Partow
0aae1b9978 Update ExprTk to 0.0.3
Some checks are pending
debian-build / build (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
2024-11-22 19:56:02 +01:00
WarmUpTill
db50822b05 Prepare to fix deprecation warning when using OBS 31
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
The following log message will be present in OBS 31 when
CheckIfTrayIsDisabled() is called:

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

It will be resolved when the minimum OBS version is bumped to OBS 31.
2024-11-02 08:28:52 +01:00
WarmUpTill
63a545b293 Fix "Date" condition returning true unexpectedly
This could happen if the plugin was stopped on the General tab and
restarted or the first time the plugin was started.
2024-11-02 08:28:52 +01:00
WarmUpTill
bc0497d2c9 Add MacroWasCheckedSinceLastStart() 2024-11-02 08:28:52 +01:00
WarmUpTill
37226a3a4c Fix macro group icon not being displayed correctly in OBS 31
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-10-31 19:39:38 +01:00
WarmUpTill
9f15fbe47c Recursively search for source button in property groups
Some checks are pending
debian-build / build (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
2024-10-30 18:29:23 +01:00
WarmUpTill
0ee6feb529 Add option to check the current stream key
Some checks failed
debian-build / build (push) Has been cancelled
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-10-26 23:42:59 +02:00
WarmUpTill
3b82b55090 Fix Queue condition not displaying the correct size selection 2024-10-26 23:42:59 +02:00
WarmUpTill
071c3309c2 Add option to check current streaming service
Some checks are pending
debian-build / build (push) Waiting to run
Check locale / ubuntu64 (push) Waiting to run
Push to master / Check Formatting 🔍 (push) Waiting to run
Push to master / Build Project 🧱 (push) Waiting to run
Push to master / Create Release 🛫 (push) Blocked by required conditions
2024-10-26 11:09:06 +02:00
WarmUpTill
ee7ee7a846 Move AutoUpdateTooltipLabel definition 2024-10-26 11:09:06 +02:00
WarmUpTill
d10300bd4b Fix typo 2024-10-26 11:09:06 +02:00
WarmUpTill
e262672876 Add "Last empty" row to Queue tab 2024-10-26 11:08:51 +02:00
WarmUpTill
392e775c7b Add temp var support for size and running state 2024-10-26 11:08:51 +02:00
WarmUpTill
f641c20564 Add SetTempVarValue() overload to support boolean values 2024-10-26 11:08:51 +02:00
WarmUpTill
39327be88e Add option to move scene item above / below specified scene item
Some checks failed
debian-build / build (push) Has been cancelled
Check locale / ubuntu64 (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-10-21 20:46:27 +02:00
WarmUpTill
ed0963799c Fix "Screenshot" action variable selection not being loaded
Some checks failed
debian-build / build (push) Has been cancelled
Push to master / Check Formatting 🔍 (push) Has been cancelled
Push to master / Build Project 🧱 (push) Has been cancelled
Push to master / Create Release 🛫 (push) Has been cancelled
2024-10-18 18:30:49 +02:00
WarmUpTill
f9e73a2b8f Fix crash when clearing Twitch chat buffer 2024-10-18 18:29:46 +02:00
Przemek Pawlas
dfaa704b71 Remove some unused includes 2024-10-12 17:09:33 +02:00
Przemek Pawlas
d54edddde4 Enable use of variables as input for "Variable" action 2024-10-12 17:09:33 +02:00
Przemek Pawlas
37cc289204 Rename function 2024-10-12 17:09:33 +02:00
140 changed files with 12652 additions and 5451 deletions

View File

@@ -6,15 +6,6 @@
"autosort": true
},
"additional_commands": {
"find_qt": {
"flags": [],
"kwargs": {
"COMPONENTS": "+",
"COMPONENTS_WIN": "+",
"COMPONENTS_MACOS": "+",
"COMPONENTS_LINUX": "+"
}
},
"set_target_properties_obs": {
"pargs": 1,
"flags": [],

View File

@@ -20,6 +20,7 @@ body:
- macOS 13
- macOS 12
- macOS 11
- Ubuntu 24.04
- Ubuntu 23.10
- Ubuntu 22.04
- Other

View File

@@ -9,5 +9,5 @@ package 'libxtst-dev'
package 'libxss-dev'
package 'libopencv-dev'
package 'libtesseract-dev'
package 'libprocps-dev'
package 'libproc2-dev'
package 'libusb-1.0-0-dev'

View File

@@ -480,12 +480,7 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
popd
;;
linux)
# Hacky workaround to support libproc2 with Ubuntu 22 build environment
local lsb_version=$(lsb_release -r | cut -f 2 || true)
if [[ "${lsb_version}" == '22.04' ]] {
sudo apt install ${project_root}/build-aux/CI/linux/ubuntu22/libproc2-0_4.0.2-3_amd64.deb
sudo apt install ${project_root}/build-aux/CI/linux/ubuntu22/libproc2-dev_4.0.2-3_amd64.deb
}
# Nothing to do for now
;;
}
}

0
.github/test vendored
View File

View File

@@ -43,7 +43,7 @@ jobs:
# devscripts and libobs-dev are needed but they were already installed
# from check_libobs_revision and install_frontend_header sections.
sudo apt update
sudo apt install cmake debhelper libcurl4-openssl-dev libxss-dev libxtst-dev qtbase5-dev libopencv-dev libprocps-dev
sudo apt install build-essential cmake debhelper libcurl4-openssl-dev libxss-dev libxtst-dev qt6-base-dev libopencv-dev libproc2-dev
- name: build
run: |
debuild --no-lintian --no-sign

View File

@@ -10,7 +10,7 @@ env:
jobs:
check-event:
name: Check GitHub Event Data 🔎
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
defaults:
run:
shell: bash
@@ -177,7 +177,7 @@ jobs:
ubuntu-build:
name: Build for Ubuntu 🐧
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
needs: check-event
defaults:
run:
@@ -241,14 +241,14 @@ jobs:
- name: Upload Artifacts 📡
uses: actions/upload-artifact@v4
with:
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-22.04-x86_64-${{ needs.check-event.outputs.commitHash }}
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-24.04-x86_64-${{ needs.check-event.outputs.commitHash }}
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*.*
- name: Upload debug symbol artifacts 🪲
uses: actions/upload-artifact@v4
if: ${{ fromJSON(needs.check-event.outputs.package) }}
with:
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-22.04-x86_64-${{ needs.check-event.outputs.commitHash }}-dbgsym
name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-24.04-x86_64-${{ needs.check-event.outputs.commitHash }}-dbgsym
path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-*-x86_64*-dbgsym.ddeb
windows-build:

View File

@@ -3,7 +3,7 @@ on:
workflow_call:
jobs:
clang-format:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
@@ -15,7 +15,7 @@ jobs:
failCondition: error
cmake-format:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:

View File

@@ -31,7 +31,7 @@ jobs:
create-release:
name: Create Release 🛫
if: github.ref_type == 'tag'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
needs: build-project
defaults:
run:
@@ -77,7 +77,7 @@ jobs:
variants=(
'windows-x64;zip|exe'
'macos-universal;tar.xz|pkg'
'ubuntu-22.04-x86_64;tar.xz|deb|ddeb'
'ubuntu-24.04-x86_64;tar.xz|deb|ddeb'
'sources;tar.xz'
)

View File

@@ -20,6 +20,12 @@ if(BUILD_OUT_OF_TREE)
include(helpers)
endif()
# OBS 31 no longer defines find_qt so check if we need to include it for in-tree
# builds
if(NOT COMMAND find_qt)
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/helpers_common.cmake")
endif()
set(LIB_NAME "${PROJECT_NAME}-lib")
add_library(${PROJECT_NAME} MODULE)
add_library(${LIB_NAME} SHARED)
@@ -157,6 +163,8 @@ target_sources(
lib/queue/action-queue.hpp
lib/queue/action-queue-tab.cpp
lib/queue/action-queue-tab.hpp
lib/utils/auto-update-tooltip-label.cpp
lib/utils/auto-update-tooltip-label.hpp
lib/utils/backup.cpp
lib/utils/backup.hpp
lib/utils/condition-logic.cpp
@@ -287,9 +295,9 @@ include(cmake/common/advss_helpers.cmake)
setup_obs_lib_dependency(${LIB_NAME})
setup_obs_lib_dependency(${PROJECT_NAME})
find_qt(COMPONENTS Widgets Core)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Core Qt::Widgets)
target_link_libraries(${LIB_NAME} PRIVATE Qt::Core Qt::Widgets)
find_package(Qt6 REQUIRED COMPONENTS Widgets Core)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Widgets)
target_link_libraries(${LIB_NAME} PRIVATE Qt6::Core Qt6::Widgets)
target_compile_options(
${PROJECT_NAME}
PRIVATE
@@ -405,7 +413,12 @@ else()
set(PROCESS_CONDITION_SUPPORTED 1)
endif()
if(PROCPS2_INCLUDE_DIR)
message(STATUS "${PROJECT_NAME} using libproc2")
find_package(PkgConfig REQUIRED)
pkg_check_modules(libproc2 IMPORTED_TARGET libproc2<4.0.5 QUIET)
if(libproc2_FOUND)
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS2_USE_INFO)
endif()
pkg_check_modules(libproc2 REQUIRED IMPORTED_TARGET libproc2)
set(PROC_INCLUDE_DIR "${PROCPS2_INCLUDE_DIR}")
target_compile_definitions(${LIB_NAME} PRIVATE PROCPS2_AVAILABLE)
set(PROCESS_CONDITION_SUPPORTED 1)

View File

@@ -7,7 +7,7 @@ Build-Depends: cmake,
libcurl4-openssl-dev,
libobs-dev,
libxtst-dev,
qtbase5-dev,
qt6-base-dev,
libxss-dev,
libopencv-dev
Standards-Version: 4.6.0

View File

@@ -3,7 +3,7 @@
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
export QT_SELECT = qt5
export QT_SELECT = qt6
%:
dh $@

View File

@@ -283,8 +283,8 @@ endfunction()
function(setup_advss_plugin target)
setup_obs_lib_dependency(${target})
find_qt(COMPONENTS Widgets Core)
target_link_libraries(${target} PRIVATE Qt::Core Qt::Widgets)
find_package(Qt6 REQUIRED COMPONENTS Widgets Core)
target_link_libraries(${target} PRIVATE Qt6::Core Qt6::Widgets)
set_target_properties(
${target}

View File

@@ -17,85 +17,6 @@ if(NOT QT_VERSION)
set_property(CACHE QT_VERSION PROPERTY STRINGS AUTO 5 6)
endif()
# find_qt: Macro to find best possible Qt version for use with the project:
macro(find_qt)
set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX)
cmake_parse_arguments(find_qt "" "${oneValueArgs}" "${multiValueArgs}"
${ARGN})
# Do not use versionless targets in the first step to avoid Qt::Core being
# clobbered by later opportunistic find_package runs
set(QT_NO_CREATE_VERSIONLESS_TARGETS TRUE)
message(DEBUG "Start Qt version discovery...")
# Loop until _QT_VERSION is set or FATAL_ERROR aborts script execution early
while(NOT _QT_VERSION)
message(DEBUG "QT_VERSION set to ${QT_VERSION}")
if(QT_VERSION STREQUAL AUTO AND NOT qt_test_version)
set(qt_test_version 6)
elseif(NOT QT_VERSION STREQUAL AUTO)
set(qt_test_version ${QT_VERSION})
endif()
message(DEBUG "Attempting to find Qt${qt_test_version}")
find_package(
Qt${qt_test_version}
COMPONENTS Core
QUIET)
if(TARGET Qt${qt_test_version}::Core)
set(_QT_VERSION
${qt_test_version}
CACHE INTERNAL "")
message(STATUS "Qt version found: ${_QT_VERSION}")
unset(qt_test_version)
break()
elseif(QT_VERSION STREQUAL AUTO)
if(qt_test_version EQUAL 6)
message(WARNING "Qt6 was not found, falling back to Qt5")
set(qt_test_version 5)
continue()
endif()
endif()
message(FATAL_ERROR "Neither Qt6 nor Qt5 found.")
endwhile()
# Enable versionless targets for the remaining Qt components
set(QT_NO_CREATE_VERSIONLESS_TARGETS FALSE)
set(qt_components ${find_qt_COMPONENTS})
if(OS_WINDOWS)
list(APPEND qt_components ${find_qt_COMPONENTS_WIN})
elseif(OS_MACOS)
list(APPEND qt_components ${find_qt_COMPONENTS_MAC})
else()
list(APPEND qt_components ${find_qt_COMPONENTS_LINUX})
endif()
message(DEBUG "Trying to find Qt components ${qt_components}...")
find_package(Qt${_QT_VERSION} REQUIRED ${qt_components})
list(APPEND qt_components Core)
if("Gui" IN_LIST find_qt_COMPONENTS_LINUX)
list(APPEND qt_components "GuiPrivate")
endif()
# Check for versionless targets of each requested component and create if
# necessary
foreach(component IN LISTS qt_components)
message(DEBUG "Checking for target Qt::${component}")
if(NOT TARGET Qt::${component} AND TARGET Qt${_QT_VERSION}::${component})
add_library(Qt::${component} INTERFACE IMPORTED)
set_target_properties(
Qt::${component} PROPERTIES INTERFACE_LINK_LIBRARIES
Qt${_QT_VERSION}::${component})
endif()
set_property(TARGET Qt::${component} PROPERTY INTERFACE_COMPILE_FEATURES "")
endforeach()
endmacro()
# check_uuid: Helper function to check for valid UUID
function(check_uuid uuid_string return_value)
set(valid_uuid TRUE)

View File

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

View File

@@ -97,6 +97,7 @@ AdvSceneSwitcher.actionQueueTab.queueAddButton.tooltip="Add new action queue"
AdvSceneSwitcher.actionQueueTab.queueRemoveButton.tooltip="Remove selected action queues"
AdvSceneSwitcher.actionQueueTab.name.header="Name"
AdvSceneSwitcher.actionQueueTab.size.header="Size"
AdvSceneSwitcher.actionQueueTab.lastEmpty.header="Last empty"
AdvSceneSwitcher.actionQueueTab.isRunning.header="Is running"
AdvSceneSwitcher.actionQueueTab.runOnStartup.header="Run on startup"
AdvSceneSwitcher.actionQueueTab.yes="Yes"
@@ -418,7 +419,10 @@ AdvSceneSwitcher.condition.stream.state.stop="Stream stopped"
AdvSceneSwitcher.condition.stream.state.starting="Stream starting"
AdvSceneSwitcher.condition.stream.state.stopping="Stream stopping"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="Keyframe interval equals"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.stream.state.streamKey="Stream key is"
AdvSceneSwitcher.condition.stream.state.service="Service name matches"
AdvSceneSwitcher.condition.stream.service.tooltip="Current service name: %1"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}{{streamKey}}{{serviceName}}{{regex}}{{currentService}}"
AdvSceneSwitcher.condition.record="Recording"
AdvSceneSwitcher.condition.record.state.start="Recording running"
AdvSceneSwitcher.condition.record.state.pause="Recording paused"
@@ -765,6 +769,11 @@ AdvSceneSwitcher.condition.streamDeck.checkData="Check data field"
AdvSceneSwitcher.condition.streamDeck.startListen="Start listening"
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"
# Macro Actions
AdvSceneSwitcher.action.unknown="Unknown action"
@@ -956,7 +965,9 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Move to top"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position"
AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.type.above="Move above"
AdvSceneSwitcher.action.sceneOrder.type.below="Move below"
AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}{{sources2}}"
AdvSceneSwitcher.action.sceneTransform="Scene item transform"
AdvSceneSwitcher.action.sceneTransform.type.manual="Set transform string"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="Set transform setting"
@@ -1048,13 +1059,13 @@ AdvSceneSwitcher.action.http.type.post="POST"
AdvSceneSwitcher.action.http.entry.line1="Send{{method}}to{{url}}"
AdvSceneSwitcher.action.http.entry.line2="Timeout:{{timeout}}seconds"
AdvSceneSwitcher.action.variable="Variable"
AdvSceneSwitcher.action.variable.type.set="Set to fixed value"
AdvSceneSwitcher.action.variable.type.set="Set to value"
AdvSceneSwitcher.action.variable.type.append="Append"
AdvSceneSwitcher.action.variable.type.appendVar="Append variable"
AdvSceneSwitcher.action.variable.type.increment="Increment"
AdvSceneSwitcher.action.variable.type.decrement="Decrement"
AdvSceneSwitcher.action.variable.type.setActionValue="Set to action value"
AdvSceneSwitcher.action.variable.type.setConditionValue="Set to condition value"
AdvSceneSwitcher.action.variable.type.setActionValue="Set to action value (legacy)"
AdvSceneSwitcher.action.variable.type.setConditionValue="Set to condition value (legacy)"
AdvSceneSwitcher.action.variable.type.roundToInt="Round to nearest integer"
AdvSceneSwitcher.action.variable.type.subString="Set to substring of current value"
AdvSceneSwitcher.action.variable.type.findAndReplace="Find and replace in current value"
@@ -1072,6 +1083,7 @@ AdvSceneSwitcher.action.variable.type.truncateValue="Truncate current value"
AdvSceneSwitcher.action.variable.type.swapValues="Swap variable values"
AdvSceneSwitcher.action.variable.type.trim="Trim whitespace"
AdvSceneSwitcher.action.variable.type.changeCase="Change case"
AdvSceneSwitcher.action.variable.type.randomNumber="Generate random number"
AdvSceneSwitcher.action.variable.case.type.lowerCase="lowercase"
AdvSceneSwitcher.action.variable.case.type.upperCase="UPPERCASE"
AdvSceneSwitcher.action.variable.case.type.capitalized="Capitalized"
@@ -1086,6 +1098,7 @@ AdvSceneSwitcher.action.variable.findAndReplace.replace="Text to replace with"
AdvSceneSwitcher.action.variable.findAndReplace.replace.tooltip="Using \1, \2, etc. to represent first, second, etc. capture groups is supported."
AdvSceneSwitcher.action.variable.subString.begin="Beginning"
AdvSceneSwitcher.action.variable.subString.all="All"
AdvSceneSwitcher.action.variable.generateInteger="Only generate integers"
AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!"
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!"
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!"
@@ -1098,6 +1111,7 @@ AdvSceneSwitcher.action.variable.entry.substringRegex="Assign value of{{regexMat
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{findRegex}}{{replaceStr}}"
AdvSceneSwitcher.action.variable.entry.userInput.customPrompt="{{useCustomPrompt}}Use custom prompt{{inputPrompt}}"
AdvSceneSwitcher.action.variable.entry.userInput.placeholder="{{useInputPlaceholder}}Fill with placeholder{{inputPlaceholder}}"
AdvSceneSwitcher.action.variable.entry.randomNumber="Generate random number in range from{{randomNumberStart}}to{{randomNumberEnd}}"
AdvSceneSwitcher.action.projector="Projector"
AdvSceneSwitcher.action.projector.type.source="Source"
AdvSceneSwitcher.action.projector.type.scene="Scene"
@@ -1128,10 +1142,15 @@ AdvSceneSwitcher.action.twitch.type.clip.create="Create stream clip"
AdvSceneSwitcher.action.twitch.type.chat.announcement.send="Send chat announcement"
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.enable="Enable chat's emote-only mode"
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable="Disable chat's emote-only mode"
AdvSceneSwitcher.action.twitch.type.sendChatMessage="Send chat message"
AdvSceneSwitcher.action.twitch.type.chat.sendMessage="Send chat message"
AdvSceneSwitcher.action.twitch.type.user.getInfo="Get user information"
AdvSceneSwitcher.action.twitch.type.reward.getInfo="Get channel points reward information"
AdvSceneSwitcher.action.twitch.reward.toggleControl="Toggle reward name / variable selection control"
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Cannot select category without selecting a Twitch account first!"
AdvSceneSwitcher.action.twitch.entry.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}"
AdvSceneSwitcher.action.twitch.entry.chat="Using account{{account}}{{actions}}on{{channel}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}"
AdvSceneSwitcher.action.twitch.entry.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
AdvSceneSwitcher.action.twitch.entry.chat="Using account{{account}}{{actions}}on{{channel}}"
AdvSceneSwitcher.action.twitch.entry.user.getInfo="Using account{{account}}{{actions}}for{{userInfoQueryType}}{{userLogin}}{{userId}}"
AdvSceneSwitcher.action.twitch.entry.reward.getInfo="Using account{{account}}{{actions}}for channel{{channel}}{{pointsReward}}{{rewardVariable}}{{toggleRewardSelection}}"
AdvSceneSwitcher.action.twitch.title.title="Enter title"
AdvSceneSwitcher.action.twitch.marker.description="Describe marker"
AdvSceneSwitcher.action.twitch.clip.hasDelay="Add a slight delay before capturing the clip"
@@ -1141,6 +1160,8 @@ AdvSceneSwitcher.action.twitch.announcement.blue="Blue"
AdvSceneSwitcher.action.twitch.announcement.green="Green"
AdvSceneSwitcher.action.twitch.announcement.orange="Orange"
AdvSceneSwitcher.action.twitch.announcement.purple="Purple"
AdvSceneSwitcher.action.twitch.user.getInfo.queryType.id="User Id"
AdvSceneSwitcher.action.twitch.user.getInfo.queryType.login="User login"
AdvSceneSwitcher.action.clipboard="Clipboard"
AdvSceneSwitcher.action.clipboard.type.copy.text="Copy text"
AdvSceneSwitcher.action.clipboard.type.copy.image="Copy image"
@@ -1205,7 +1226,7 @@ AdvSceneSwitcher.validation.text.maxLength="Only %1 characters are allowed in th
AdvSceneSwitcher.variable.select="--select variable--"
AdvSceneSwitcher.variable.add="Add new variable"
AdvSceneSwitcher.variable.configure="Configure variable settings"
AdvSceneSwitcher.variable.invalid="Invalid varialbe selection"
AdvSceneSwitcher.variable.invalid="Invalid variable selection"
AdvSceneSwitcher.variable.name="Name:"
AdvSceneSwitcher.variable.value="Current value:"
AdvSceneSwitcher.variable.save="Save / load behavior"
@@ -1584,12 +1605,21 @@ AdvSceneSwitcher.tempVar.twitch.started_at.shoutoutReceived="Shoutout time"
AdvSceneSwitcher.tempVar.twitch.started_at.shoutoutReceived.description="The UTC timestamp (in RFC3339 format) of when the moderator sent the Shoutout."
AdvSceneSwitcher.tempVar.twitch.id.reward="Reward ID"
AdvSceneSwitcher.tempVar.twitch.id.redemption="Redemption ID"
AdvSceneSwitcher.tempVar.twitch.user_id.reward="User ID redeeming the reward"
AdvSceneSwitcher.tempVar.twitch.user_login.reward="User login redeeming the reward"
AdvSceneSwitcher.tempVar.twitch.user_name.reward="User name redeeming the reward"
AdvSceneSwitcher.tempVar.twitch.user_input.reward="User input for reward"
AdvSceneSwitcher.tempVar.twitch.reward.reward="Reward Information"
AdvSceneSwitcher.tempVar.twitch.reward.reward.description="Basic information about the reward that was redeemed, at the time it was redeemed."
AdvSceneSwitcher.tempVar.twitch.reward.reward="Reward Information (JSON)"
AdvSceneSwitcher.tempVar.twitch.reward.reward.description="Basic information about the reward that was redeemed in JSON form, at the time it was redeemed."
AdvSceneSwitcher.tempVar.twitch.reward.id.reward="Reward ID"
AdvSceneSwitcher.tempVar.twitch.reward.id.reward.description="The ID that uniquely identifies the reward."
AdvSceneSwitcher.tempVar.twitch.reward.title.reward="Reward title"
AdvSceneSwitcher.tempVar.twitch.reward.title.reward.description="The rewards title."
AdvSceneSwitcher.tempVar.twitch.reward.prompt.reward="Reward prompt"
AdvSceneSwitcher.tempVar.twitch.reward.prompt.reward.description="The prompt displayed to the viewer if user input is required."
AdvSceneSwitcher.tempVar.twitch.reward.cost.reward="Reward cost"
AdvSceneSwitcher.tempVar.twitch.reward.cost.reward.description="The rewards cost, in Channel Points."
AdvSceneSwitcher.tempVar.twitch.status.reward="Reward status"
AdvSceneSwitcher.tempVar.twitch.status.reward.description="Defaults to unfulfilled. Possible values are unknown, unfulfilled, fulfilled, and canceled."
AdvSceneSwitcher.tempVar.twitch.redeemed_at.reward="Redemption time"
@@ -1604,22 +1634,37 @@ AdvSceneSwitcher.tempVar.twitch.title.reward="Reward title"
AdvSceneSwitcher.tempVar.twitch.cost.reward="Reward cost"
AdvSceneSwitcher.tempVar.twitch.prompt.reward="Reward description"
AdvSceneSwitcher.tempVar.twitch.is_user_input_required.reward="Reward requires user input"
AdvSceneSwitcher.tempVar.twitch.should_redemptions_skip_request_queue.reward="Redemptions skip request queue"
AdvSceneSwitcher.tempVar.twitch.should_redemptions_skip_request_queue.reward.description="Should redemptions be set to fulfilled status immediately when redeemed and skip the request queue instead of the normal unfulfilled status."
AdvSceneSwitcher.tempVar.twitch.max_per_stream.reward="Reward maximum per stream"
AdvSceneSwitcher.tempVar.twitch.max_per_user_per_stream.reward="Reward maximum per user per stream"
AdvSceneSwitcher.tempVar.twitch.background_color.reward="Reward background color"
AdvSceneSwitcher.tempVar.twitch.image.reward="Reward image"
AdvSceneSwitcher.tempVar.twitch.image.reward="Reward image (JSON)"
AdvSceneSwitcher.tempVar.twitch.image.reward.description="Set of custom images of 1x, 2x and 4x sizes for the reward. Can be null if no images have been uploaded."
AdvSceneSwitcher.tempVar.twitch.default_image.reward="Reward default image"
AdvSceneSwitcher.tempVar.twitch.image.url_4x.reward="Reward image URL"
AdvSceneSwitcher.tempVar.twitch.image.url_4x.reward.description="The URL to the custom image for the reward. This field is null if the broadcaster didnt upload images."
AdvSceneSwitcher.tempVar.twitch.default_image.reward="Reward default image (JSON)"
AdvSceneSwitcher.tempVar.twitch.default_image.reward.description="Set of default images of 1x, 2x and 4x sizes for the reward."
AdvSceneSwitcher.tempVar.twitch.global_cooldown.reward="Reward cooldown"
AdvSceneSwitcher.tempVar.twitch.global_cooldown.reward.description="Whether a cooldown is enabled and what the cooldown is in seconds."
AdvSceneSwitcher.tempVar.twitch.cooldown_expires_at.reward="Reward cooldown expiration"
AdvSceneSwitcher.tempVar.twitch.cooldown_expires_at.reward.description="Timestamp of the cooldown expiration. null if the reward isnt on cooldown."
AdvSceneSwitcher.tempVar.twitch.default_image.url_4x.reward="Reward default image URL"
AdvSceneSwitcher.tempVar.twitch.default_image.url_4x.reward.description="The URL to the default image for the reward."
AdvSceneSwitcher.tempVar.twitch.redemptions_redeemed_current_stream.reward="Redemption count"
AdvSceneSwitcher.tempVar.twitch.redemptions_redeemed_current_stream.reward.description="The number of redemptions redeemed during the current live stream. Counts against the max_per_stream limit. null if the broadcasters stream isnt live or max_per_stream isnt enabled."
AdvSceneSwitcher.tempVar.twitch.redemptions_redeemed_current_stream.reward.description="The number of redemptions redeemed during the current live stream. Counts against the max_per_stream limit. null if the broadcasters stream isnt live or max_per_stream isnt enabled."
AdvSceneSwitcher.tempVar.twitch.should_redemptions_skip_request_queue.reward="Redemptions skip request queue"
AdvSceneSwitcher.tempVar.twitch.should_redemptions_skip_request_queue.reward.description="Should redemptions be set to fulfilled status immediately when redeemed and skip the request queue instead of the normal unfulfilled status."
AdvSceneSwitcher.tempVar.twitch.max_per_stream.reward="Maximum redemptions per stream (JSON)"
AdvSceneSwitcher.tempVar.twitch.max_per_stream.is_enabled.reward="Maximum redemptions per stream enabled"
AdvSceneSwitcher.tempVar.twitch.max_per_stream.is_enabled.reward.description="A Boolean value that determines whether the reward applies a limit on the number of redemptions allowed per live stream. Is true if the reward applies a limit."
AdvSceneSwitcher.tempVar.twitch.max_per_stream.max_per_stream.reward="Maximum redemptions per stream"
AdvSceneSwitcher.tempVar.twitch.max_per_stream.max_per_stream.reward.description="The maximum number of redemptions allowed per live stream."
AdvSceneSwitcher.tempVar.twitch.max_per_user_per_stream.reward="Reward maximum per user per stream (JSON)"
AdvSceneSwitcher.tempVar.twitch.max_per_user_per_stream.is_enabled.reward="Maximum redemptions per user per stream enabled"
AdvSceneSwitcher.tempVar.twitch.max_per_user_per_stream.is_enabled.reward.description="A Boolean value that determines whether the reward applies a limit on the number of redemptions allowed per user per live stream. Is true if the reward applies a limit."
AdvSceneSwitcher.tempVar.twitch.max_per_user_per_stream.max_per_user_per_stream.reward="Maximum redemptions per user per stream"
AdvSceneSwitcher.tempVar.twitch.max_per_user_per_stream.max_per_user_per_stream.reward.description="The settings used to determine whether to apply a maximum to the number of redemptions allowed per user per live stream."
AdvSceneSwitcher.tempVar.twitch.global_cooldown.reward="Global cooldown (JSON)"
AdvSceneSwitcher.tempVar.twitch.global_cooldown.reward.description="Whether a cooldown is enabled and what the cooldown is in seconds."
AdvSceneSwitcher.tempVar.twitch.global_cooldown.is_enabled.reward="Global cooldown enabled"
AdvSceneSwitcher.tempVar.twitch.global_cooldown.is_enabled.reward.description="A Boolean value that determines whether to apply a cooldown period. Is true if a cooldown period is enabled."
AdvSceneSwitcher.tempVar.twitch.global_cooldown.global_cooldown_seconds.reward="Global cooldown"
AdvSceneSwitcher.tempVar.twitch.global_cooldown.global_cooldown_seconds.reward.description="The cooldown period, in seconds."
AdvSceneSwitcher.tempVar.twitch.cooldown_expires_at.reward="Reward cooldown expiration"
AdvSceneSwitcher.tempVar.twitch.cooldown_expires_at.reward.description="Timestamp of the cooldown expiration. null if the reward isnt on cooldown."
AdvSceneSwitcher.tempVar.twitch.charity_name="Charity name"
AdvSceneSwitcher.tempVar.twitch.charity_description="Charity description"
@@ -1788,6 +1833,24 @@ AdvSceneSwitcher.tempVar.twitch.to_broadcaster_user_name.raid.description="The b
AdvSceneSwitcher.tempVar.twitch.viewers.raid="Raid participants"
AdvSceneSwitcher.tempVar.twitch.viewers.raid.description="The number of viewers in the raid."
AdvSceneSwitcher.tempVar.twitch.id.user.getInfo="User ID"
AdvSceneSwitcher.tempVar.twitch.id.user.getInfo.description="The user ID of the queried account."
AdvSceneSwitcher.tempVar.twitch.login.user.getInfo="User login"
AdvSceneSwitcher.tempVar.twitch.login.user.getInfo.description="The user login of the queried account."
AdvSceneSwitcher.tempVar.twitch.display_name.user.getInfo="User name"
AdvSceneSwitcher.tempVar.twitch.display_name.user.getInfo.description="The display name of the queried account."
AdvSceneSwitcher.tempVar.twitch.type.user.getInfo="User type"
AdvSceneSwitcher.tempVar.twitch.type.user.getInfo.description="The type of user. Possible values are:\n admin — Twitch administrator\n global_mod\n staff — Twitch staff\n \"\" — Normal user"
AdvSceneSwitcher.tempVar.twitch.broadcaster_type.user.getInfo="Broadcaster type"
AdvSceneSwitcher.tempVar.twitch.broadcaster_type.user.getInfo.description="The type of broadcaster. Possible values are:\n affiliate — An affiliate broadcaster\n partner — A partner broadcaster\n \"\" — A normal broadcaster"
AdvSceneSwitcher.tempVar.twitch.description.user.getInfo="Description"
AdvSceneSwitcher.tempVar.twitch.description.user.getInfo.description="The user's description of their channel."
AdvSceneSwitcher.tempVar.twitch.profile_image_url.user.getInfo="Profile image URL"
AdvSceneSwitcher.tempVar.twitch.offline_image_url.user.getInfo="Offline image URL"
AdvSceneSwitcher.tempVar.twitch.created_at.user.getInfo="Account creation date"
AdvSceneSwitcher.tempVar.twitch.created_at.user.getInfo.description="The UTC date and time that the user's account was created. The timestamp is in RFC3339 format."
AdvSceneSwitcher.tempVar.audio.output_volume="Output volume"
AdvSceneSwitcher.tempVar.audio.output_volume.description="The volume the audio source is outputting."
AdvSceneSwitcher.tempVar.audio.configured_volume="Configured volume"
@@ -1877,8 +1940,11 @@ AdvSceneSwitcher.tempVar.display.height.description="The height of the display w
AdvSceneSwitcher.tempVar.streaming.keyframeInterval="Stream keyframe interval"
AdvSceneSwitcher.tempVar.streaming.keyframeInterval.description="Stream keyframe interval configured in the OBS settings."
AdvSceneSwitcher.tempVar.streaming.streamKey="Stream key"
AdvSceneSwitcher.tempVar.streaming.durationSeconds="Stream duration"
AdvSceneSwitcher.tempVar.streaming.durationSeconds.description="Seconds passed since the stream was started.\nThis value will be zero if the stream is stopped."
AdvSceneSwitcher.tempVar.streaming.serviceName="Service"
AdvSceneSwitcher.tempVar.streaming.serviceName.description="The name of the streaming service being streamed to (e.g. Twitch)"
AdvSceneSwitcher.tempVar.clipboard.text="Clipboard text"
AdvSceneSwitcher.tempVar.clipboard.text.description="The text contained in the clipboard.\nWill be empty if the clipboard does not contain text."
@@ -1958,6 +2024,20 @@ AdvSceneSwitcher.tempVar.streamDeck.column="Key column"
AdvSceneSwitcher.tempVar.streamDeck.data="Data"
AdvSceneSwitcher.tempVar.streamDeck.data.description="The value of the \"Data\" field configured in the action on the Stream Deck side."
AdvSceneSwitcher.tempVar.queue.size="Size"
AdvSceneSwitcher.tempVar.queue.running="Is running"
AdvSceneSwitcher.tempVar.queue.running.description="Returns \"true\" if the queue is started and \"false\" if it is stopped."
AdvSceneSwitcher.tempVar.screenshot.lastScreenshotPath="Last screenshot path"
AdvSceneSwitcher.tempVar.screenshot.lastScreenshotPath.description="The filesystem path to the last screenshot taken."
AdvSceneSwitcher.tempVar.gameCapture.title="Title"
AdvSceneSwitcher.tempVar.gameCapture.title.description="Window title of the application captured by the source."
AdvSceneSwitcher.tempVar.gameCapture.class="Class"
AdvSceneSwitcher.tempVar.gameCapture.class.description="Window class of the application captured by the source."
AdvSceneSwitcher.tempVar.gameCapture.executable="Executable"
AdvSceneSwitcher.tempVar.gameCapture.executable.description="Executable name of the application captured by the source."
AdvSceneSwitcher.selectScene="--select scene--"
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
AdvSceneSwitcher.selectCurrentScene="Current Scene"

View File

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

View File

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

View File

@@ -925,7 +925,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="下へ移動"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="トップへ移動"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="一番下へ移動"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="ポジションへの移動"
AdvSceneSwitcher.action.sceneOrder.entry="オン{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="オン{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="シーンアイテムの変形"
AdvSceneSwitcher.action.sceneTransform.type.manual="変形"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="トランスフォーム設定を行う"
@@ -1089,10 +1089,10 @@ AdvSceneSwitcher.action.twitch.type.clip.create="ストリームクリップの
AdvSceneSwitcher.action.twitch.type.chat.announcement.send="チャット通知の送信"
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.enable="チャットのエモート専用モードを有効にする"
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable="チャットのエモート専用モードを無効にする"
AdvSceneSwitcher.action.twitch.type.sendChatMessage="チャットメッセージを送る"
AdvSceneSwitcher.action.twitch.type.chat.sendMessage="チャットメッセージを送る"
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Twitchアカウントを選択しないとカテゴリを選択できません"
; AdvSceneSwitcher.action.twitch.entry.default="On{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}"
AdvSceneSwitcher.action.twitch.entry.chat="{{channel}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}} でアカウント{{account}}{{actions}}を使用しています"
AdvSceneSwitcher.action.twitch.entry.chat="{{channel}}でアカウント{{account}}{{actions}}を使用しています"
AdvSceneSwitcher.action.twitch.title.title="タイトルを入力してください"
AdvSceneSwitcher.action.twitch.marker.description="マーカーの説明"
AdvSceneSwitcher.action.twitch.clip.hasDelay="クリップをキャプチャする前にわずかな遅延を追加します"

View File

@@ -395,7 +395,6 @@ AdvSceneSwitcher.condition.stream.state.stop="Streaming parado"
AdvSceneSwitcher.condition.stream.state.starting="Iniciando o streaming"
AdvSceneSwitcher.condition.stream.state.stopping="Parando o streaming"
AdvSceneSwitcher.condition.stream.state.keyFrameInterval="Intervalo de keyframe igual a"
AdvSceneSwitcher.condition.stream.entry="{{streamState}}{{keyFrameInterval}}"
AdvSceneSwitcher.condition.record="Gravação"
AdvSceneSwitcher.condition.record.state.start="Gravação em execução"
AdvSceneSwitcher.condition.record.state.pause="Gravação pausada"
@@ -907,7 +906,7 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover para baixo"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Mover para o topo"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Mover para o fundo"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Mover para posição"
AdvSceneSwitcher.action.sceneOrder.entry="Em{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="Em{{scenes}}{{actions}}{{sources}}{{sources2}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="Transformação de item de cena"
AdvSceneSwitcher.action.sceneTransform.type.manual="Definir string de transformação"
AdvSceneSwitcher.action.sceneTransform.type.setSingleSetting="Definir configuração de transformação"
@@ -1071,10 +1070,10 @@ AdvSceneSwitcher.action.twitch.type.clip.create="Criar clipe da transmissão"
AdvSceneSwitcher.action.twitch.type.chat.announcement.send="Enviar anúncio de chat"
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.enable="Habilitar modo apenas emotes no chat"
AdvSceneSwitcher.action.twitch.type.chat.emoteOnly.disable="Desabilitar modo apenas emotes no chat"
AdvSceneSwitcher.action.twitch.type.sendChatMessage="Enviar mensagem de chat"
AdvSceneSwitcher.action.twitch.type.chat.sendMessage="Enviar mensagem de chat"
AdvSceneSwitcher.action.twitch.categorySelectionDisabled="Não é possível selecionar categoria sem selecionar uma conta Twitch primeiro!"
AdvSceneSwitcher.action.twitch.entry.default="Em{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}"
AdvSceneSwitcher.action.twitch.entry.chat="Usando conta{{account}}{{actions}}em{{channel}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}"
AdvSceneSwitcher.action.twitch.entry.default="Em{{account}}{{actions}}{{streamTitle}}{{category}}{{markerDescription}}{{clipHasDelay}}{{duration}}{{announcementColor}}{{channel}}{{pointsReward}}"
AdvSceneSwitcher.action.twitch.entry.chat="Usando conta{{account}}{{actions}}em{{channel}}"
AdvSceneSwitcher.action.twitch.title.title="Digite o título"
AdvSceneSwitcher.action.twitch.marker.description="Descreva o marcador"
AdvSceneSwitcher.action.twitch.clip.hasDelay="Adicionar um leve atraso antes de capturar o clipe"

View File

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

View File

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

13156
deps/exprtk/exprtk.hpp vendored

File diff suppressed because it is too large Load Diff

View File

@@ -735,7 +735,7 @@ void OpenSettingsWindow()
}
}
void AdvSceneSwitcher::HighligthMacroSettingsButton(bool enable)
void AdvSceneSwitcher::HighlightMacroSettingsButton(bool enable)
{
static QObject *highlight = nullptr;
if ((highlight && enable) || (!highlight && !enable)) {
@@ -755,13 +755,13 @@ void AdvSceneSwitcher::HighligthMacroSettingsButton(bool enable)
highlight = HighlightWidget(ui->macroSettings, Qt::green);
}
void HighligthMacroSettingsButton(bool enable)
void HighlightMacroSettingsButton(bool enable)
{
auto window = GetSettingsWindow();
if (!window) {
return;
}
static_cast<AdvSceneSwitcher *>(window)->HighligthMacroSettingsButton(
static_cast<AdvSceneSwitcher *>(window)->HighlightMacroSettingsButton(
enable);
}

View File

@@ -97,7 +97,7 @@ public:
void SetConditionData(Macro &m);
void SwapActions(Macro *m, int pos1, int pos2);
void SwapConditions(Macro *m, int pos1, int pos2);
void HighligthMacroSettingsButton(bool enable = true);
void HighlightMacroSettingsButton(bool enable = true);
public slots:
void on_macroAdd_clicked();
@@ -386,6 +386,6 @@ private:
};
void OpenSettingsWindow();
void HighligthMacroSettingsButton(bool enable);
void HighlightMacroSettingsButton(bool enable);
} // namespace advss

View File

@@ -344,6 +344,10 @@ void AdvSceneSwitcher::on_importSettings_clicked()
return;
}
// We have to make sure to that no macro is currently being edited while
// the new settings are loaded
ui->macros->clearSelection();
std::lock_guard<std::mutex> lock(switcher->m);
switcher->LoadSettings(obj);
switcher->lastImportPath = path.toStdString();

View File

@@ -122,11 +122,7 @@ void SwitcherData::writeToStatusFile(const QString &msg)
QFile file(QString::fromStdString(fileIO.writePath));
if (file.open(QIODevice::ReadWrite)) {
QTextStream stream(&file);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
stream << msg << "\n";
#else
stream << msg << Qt::endl;
#endif
}
file.close();
}

View File

@@ -384,7 +384,11 @@ static void getProcessListProcps2(QStringList &processes)
return;
}
while ((stack = procps_pids_get_(info, PIDS_FETCH_TASKS_ONLY))) {
#ifdef PROCPS2_USE_INFO
auto cmd = PIDS_VAL(0, str, stack, info);
#else
auto cmd = PIDS_VAL(0, str, stack);
#endif
QString procName(cmd);
if (!procName.isEmpty() && !processes.contains(procName)) {
processes << procName;

View File

@@ -309,11 +309,11 @@ MacroActionMacroEdit::MacroActionMacroEdit(
_loading = false;
}
void HighligthMacroSettingsButton(bool enable);
void HighlightMacroSettingsButton(bool enable);
MacroActionMacroEdit::~MacroActionMacroEdit()
{
HighligthMacroSettingsButton(false);
HighlightMacroSettingsButton(false);
}
void MacroActionMacroEdit::UpdateEntryData()
@@ -480,7 +480,7 @@ void MacroActionMacroEdit::SetWidgetVisibility()
_inputs->setVisible(_entryData->_action ==
MacroActionMacro::Action::RUN &&
_entryData->_runOptions.setInputs);
HighligthMacroSettingsButton(_entryData->_action ==
HighlightMacroSettingsButton(_entryData->_action ==
MacroActionMacro::Action::RUN &&
_entryData->_runOptions.setInputs &&
!_inputs->HasInputsToSet());

View File

@@ -6,14 +6,17 @@
namespace advss {
MacroActionScript::MacroActionScript(Macro *m, const std::string &id,
const OBSData &defaultSettings,
const std::string &propertiesSignalName,
const std::string &triggerSignal,
const std::string &completionSignal)
MacroActionScript::MacroActionScript(
Macro *m, const std::string &id, const OBSData &defaultSettings,
const std::string &propertiesSignalName,
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName)
: MacroAction(m),
MacroSegmentScript(defaultSettings, propertiesSignalName,
triggerSignal, completionSignal),
triggerSignalName, completionSignalName,
newInstanceSignalName, deletedInstanceSignalName),
_id(id)
{
}
@@ -89,4 +92,29 @@ void MacroActionScript::WaitForCompletion() const
}
}
void MacroActionScript::RegisterTempVarHelper(const std::string &variableId,
const std::string &name,
const std::string &helpText)
{
AddTempvar(variableId, name, helpText);
}
void MacroActionScript::DeregisterAllTempVarsHelper()
{
MacroSegment::SetupTempVars();
}
void MacroActionScript::SetTempVarValueHelper(const std::string &variableId,
const std::string &value)
{
MacroAction::SetTempVarValue(variableId, value);
}
void MacroActionScript::SetupTempVars()
{
// This just exists so MacroSegment::SetupTempVars() is not called.
// We want the ScriptHandler to handle the registration and clearing of
// the temp vars.
}
} // namespace advss

View File

@@ -10,8 +10,10 @@ public:
MacroActionScript(Macro *m, const std::string &id,
const OBSData &defaultSettings,
const std::string &propertiesSignalName,
const std::string &triggerSignal,
const std::string &signalComplete);
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName);
MacroActionScript(const advss::MacroActionScript &);
bool PerformAction();
void LogAction() const;
@@ -22,6 +24,13 @@ public:
private:
void WaitForCompletion() const;
void RegisterTempVarHelper(const std::string &variableId,
const std::string &name,
const std::string &helpText);
void DeregisterAllTempVarsHelper();
void SetTempVarValueHelper(const std::string &variableId,
const std::string &value);
void SetupTempVars();
std::string _id = "";
};

File diff suppressed because it is too large Load Diff

View File

@@ -28,8 +28,8 @@ public:
int GetSegmentIndexValue() const;
void ResolveVariablesToFixedValues();
enum class Type {
SET_FIXED_VALUE,
enum class Action {
SET_VALUE,
APPEND,
APPEND_VAR,
INCREMENT,
@@ -52,18 +52,19 @@ public:
SWAP_VALUES,
TRIM,
CHANGE_CASE,
RANDOM_NUMBER,
};
Type _type = Type::SET_FIXED_VALUE;
Action _action = Action::SET_VALUE;
std::weak_ptr<Variable> _variable;
std::weak_ptr<Variable> _variable2;
StringVariable _strValue = "";
double _numValue = 0;
int _subStringStart = 0;
int _subStringSize = 0;
DoubleVariable _numValue = 0;
IntVariable _subStringStart = 0;
IntVariable _subStringSize = 0;
RegexConfig _subStringRegex = RegexConfig::PartialMatchRegexConfig();
std::string _regexPattern = ".*";
int _regexMatchIdx = 0;
IntVariable _regexMatchIdx = 0;
RegexConfig _findRegex;
StringVariable _findStr = obs_module_text(
"AdvSceneSwitcher.action.variable.findAndReplace.find");
@@ -99,6 +100,9 @@ public:
};
CaseType _caseType = CaseType::LOWER_CASE;
DoubleVariable _randomNumberStart = 0;
DoubleVariable _randomNumberEnd = 100;
bool _generateInteger = true;
private:
void DecrementCurrentSegmentVariableRef();
@@ -108,6 +112,7 @@ private:
void HandleMathExpression(Variable *);
void HandleCaseChange(Variable *);
void SetToSceneItemName(Variable *);
void GenerateRandomNumber(Variable *);
std::weak_ptr<MacroSegment> _macroSegment;
int _segmentIdxLoadValue = -1;
@@ -136,15 +141,15 @@ private slots:
void Variable2Changed(const QString &);
void ActionChanged(int);
void StrValueChanged();
void NumValueChanged(double);
void NumValueChanged(const NumberVariable<double> &value);
void SegmentIndexChanged(const IntVariable &);
void UpdateSegmentVariableValue();
void MacroSegmentOrderChanged();
void SubStringStartChanged(int val);
void SubStringSizeChanged(int val);
void SubStringStartChanged(const NumberVariable<int> &start);
void SubStringSizeChanged(const NumberVariable<int> &size);
void SubStringRegexChanged(const RegexConfig &conf);
void RegexPatternChanged();
void RegexMatchIdxChanged(int val);
void RegexMatchIdxChanged(const NumberVariable<int> &index);
void FindStrValueChanged();
void FindRegexChanged(const RegexConfig &conf);
void ReplaceStrValueChanged();
@@ -161,6 +166,9 @@ private slots:
void StringLengthChanged(const NumberVariable<int> &);
void CharSelectionChanged(const QString &);
void CaseTypeChanged(int index);
void RandomNumberStartChanged(const NumberVariable<double> &);
void RandomNumberEndChanged(const NumberVariable<double> &);
void GenerateIntegerChanged(int);
signals:
void HeaderInfoChanged(const QString &);
@@ -173,18 +181,18 @@ private:
VariableSelection *_variables2;
FilterComboBox *_actions;
VariableTextEdit *_strValue;
QDoubleSpinBox *_numValue;
VariableDoubleSpinBox *_numValue;
MacroSegmentSelection *_segmentIdx;
QLabel *_segmentValueStatus;
ResizingPlainTextEdit *_segmentValue;
QVBoxLayout *_substringLayout;
QHBoxLayout *_subStringIndexEntryLayout;
QHBoxLayout *_subStringRegexEntryLayout;
QSpinBox *_subStringStart;
QSpinBox *_subStringSize;
VariableSpinBox *_subStringStart;
VariableSpinBox *_subStringSize;
RegexConfigWidget *_substringRegex;
ResizingPlainTextEdit *_regexPattern;
QSpinBox *_regexMatchIdx;
VariableSpinBox *_regexMatchIdx;
QHBoxLayout *_findReplaceLayout;
RegexConfigWidget *_findRegex;
VariableTextEdit *_findStr;
@@ -206,6 +214,10 @@ private:
VariableSpinBox *_stringLength;
SingleCharSelection *_paddingCharSelection;
FilterComboBox *_caseType;
VariableDoubleSpinBox *_randomNumberStart;
VariableDoubleSpinBox *_randomNumberEnd;
QCheckBox *_generateInteger;
QVBoxLayout *_randomLayout;
QHBoxLayout *_entryLayout;
std::shared_ptr<MacroActionVariable> _entryData;

View File

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

View File

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

View File

@@ -8,10 +8,14 @@ namespace advss {
MacroConditionScript::MacroConditionScript(
Macro *m, const std::string &id, const OBSData &defaultSettings,
const std::string &propertiesSignalName,
const std::string &triggerSignal, const std::string &completionSignal)
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName)
: MacroCondition(m),
MacroSegmentScript(defaultSettings, propertiesSignalName,
triggerSignal, completionSignal),
triggerSignalName, completionSignalName,
newInstanceSignalName, deletedInstanceSignalName),
_id(id)
{
}
@@ -76,4 +80,29 @@ void MacroConditionScript::WaitForCompletion() const
}
}
void MacroConditionScript::RegisterTempVarHelper(const std::string &variableId,
const std::string &name,
const std::string &helpText)
{
AddTempvar(variableId, name, helpText);
}
void MacroConditionScript::DeregisterAllTempVarsHelper()
{
MacroSegment::SetupTempVars();
}
void MacroConditionScript::SetTempVarValueHelper(const std::string &variableId,
const std::string &value)
{
MacroCondition::SetTempVarValue(variableId, value);
}
void MacroConditionScript::SetupTempVars()
{
// This just exists so MacroSegment::SetupTempVars() is not called.
// We want the ScriptHandler to handle the registration and clearing of
// the temp vars.
}
} // namespace advss

View File

@@ -10,8 +10,10 @@ public:
MacroConditionScript(Macro *m, const std::string &id,
const OBSData &defaultSettings,
const std::string &propertiesSignalName,
const std::string &triggerSignal,
const std::string &signalComplete);
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName);
MacroConditionScript(const advss::MacroConditionScript &);
bool CheckCondition();
bool Save(obs_data_t *obj) const;
@@ -20,6 +22,13 @@ public:
private:
void WaitForCompletion() const;
void RegisterTempVarHelper(const std::string &variableId,
const std::string &name,
const std::string &helpText);
void DeregisterAllTempVarsHelper();
void SetTempVarValueHelper(const std::string &variableId,
const std::string &value);
void SetupTempVars();
std::string _id = "";
};

View File

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

View File

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

View File

@@ -181,15 +181,7 @@ void MacroInputEdit::SetInputVariablesAndValues(
_variables = inputs;
_values = values;
if ((size_t)_values.size() < _variables._inputVariables.size()) {
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
for (int i = 0;
_variables._inputVariables.size() - (size_t)_values.size();
i++) {
_values.push_back({});
}
#else
_values.resize(_variables._inputVariables.size());
#endif
}
SetupWidgets();
}
@@ -199,7 +191,7 @@ bool MacroInputEdit::HasInputsToSet() const
return !_variables._inputVariables.empty();
}
void HighligthMacroSettingsButton(bool enable);
void HighlightMacroSettingsButton(bool enable);
void MacroInputEdit::SetupWidgets()
{

View File

@@ -29,6 +29,10 @@ static constexpr std::string_view defaultSettingsParam = "default_settings";
static constexpr std::string_view propertiesSignalParam =
"properties_signal_name";
static constexpr std::string_view triggerSignalParam = "trigger_signal_name";
static constexpr std::string_view newInstanceSignalNameParam =
"new_instance_signal_name";
static constexpr std::string_view deletedInstanceSignalNameParam =
"deleted_instance_signal_name";
static std::string getRegisterScriptSegmentDeclString(const char *funcName)
{
@@ -72,16 +76,37 @@ static const std::string deregisterScriptConditionDeclString =
/* Script variables */
static constexpr std::string_view valueParam = "value";
static constexpr std::string_view tempVarIdParam = "temp_var_id";
static constexpr std::string_view tempVarNameParam = "temp_var_name";
static constexpr std::string_view tempVarHelpParam = "temp_var_help";
static constexpr std::string_view getVariableValueFuncName =
"advss_get_variable_value";
static constexpr std::string_view setVariableValueFuncName =
"advss_set_variable_value";
static constexpr std::string_view registerTempVarFuncName =
"advss_register_temp_var";
static constexpr std::string_view deregisterAllTempVarsFuncName =
"advss_deregister_temp_vars";
static constexpr std::string_view setTempVarValueFuncName =
"advss_set_temp_var_value";
static const std::string getVariableValueDeclString =
std::string("bool ") + getVariableValueFuncName.data() + "(in string " +
nameParam.data() + ", out string " + valueParam.data() + ")";
static const std::string setVariableValueDeclString =
std::string("bool ") + setVariableValueFuncName.data() + "(in string " +
nameParam.data() + ", in string " + valueParam.data() + ")";
static const std::string registerTempVarDeclString =
std::string("bool ") + registerTempVarFuncName.data() + "(in string " +
tempVarIdParam.data() + ", in string " + tempVarNameParam.data() +
", in string " + tempVarHelpParam.data() + ", in int " +
GetInstanceIdParamName().data() + ")";
static const std::string deregisterAllTempVarsDeclString =
std::string("bool ") + deregisterAllTempVarsFuncName.data() +
"(in int " + GetInstanceIdParamName().data() + ")";
static const std::string setTempVarValueDeclString =
std::string("bool ") + setTempVarValueFuncName.data() + "(in string " +
tempVarIdParam.data() + ", in string " + valueParam.data() +
", in int " + GetInstanceIdParamName().data() + ")";
static bool setup();
static bool setupDone = setup();
@@ -103,13 +128,23 @@ static bool setup()
&ScriptHandler::GetVariableValue, nullptr);
proc_handler_add(ph, setVariableValueDeclString.c_str(),
&ScriptHandler::SetVariableValue, nullptr);
proc_handler_add(ph, registerTempVarDeclString.c_str(),
&ScriptHandler::RegisterTempVar, nullptr);
proc_handler_add(ph, deregisterAllTempVarsDeclString.c_str(),
&ScriptHandler::DeregisterAllTempVars, nullptr);
proc_handler_add(ph, setTempVarValueDeclString.c_str(),
&ScriptHandler::SetTempVarValue, nullptr);
return true;
}
static void replaceWhitespace(std::string &string)
static void replaceProblematicChars(std::string &string)
{
std::transform(string.begin(), string.end(), string.begin(), [](char c) {
return std::isspace(static_cast<unsigned char>(c)) ? '_' : c;
if (std::isspace(static_cast<unsigned char>(c)) || c == '(' ||
c == ')' || c == '[' || c == ']' || c == '{' || c == '}') {
return '_';
}
return c;
});
}
@@ -122,7 +157,7 @@ static std::string getTriggerSignal(const std::string &name,
const bool isAction)
{
std::string signal = name;
replaceWhitespace(signal);
replaceProblematicChars(signal);
signal += "_run";
signal += isAction ? "_action" : "_condition";
return signal;
@@ -140,12 +175,32 @@ static std::string getPropertiesSignal(const std::string &name,
const bool isAction)
{
std::string signal = name;
replaceWhitespace(signal);
replaceProblematicChars(signal);
signal += isAction ? "_action" : "_condition";
signal += "_get_properties";
return signal;
}
static std::string getNewInstanceSignal(const std::string &name,
const bool isAction)
{
std::string signal = name;
replaceProblematicChars(signal);
signal += isAction ? "_action" : "_condition";
signal += "_new_instance";
return signal;
}
static std::string getDeletedInstanceSignal(const std::string &name,
const bool isAction)
{
std::string signal = name;
replaceProblematicChars(signal);
signal += isAction ? "_action" : "_condition";
signal += "_deleted_instance";
return signal;
}
void ScriptHandler::RegisterScriptAction(void *, calldata_t *data)
{
const char *actionName;
@@ -177,14 +232,19 @@ void ScriptHandler::RegisterScriptAction(void *, calldata_t *data)
auto triggerSignalName = getTriggerSignal(actionName, true);
auto completionSignalName = getCompletionSignal(actionName, true);
auto propertiesSignalName = getPropertiesSignal(actionName, true);
auto newInstanceSignalName = getNewInstanceSignal(actionName, true);
auto deletedInstanceSignalName =
getDeletedInstanceSignal(actionName, true);
const auto createScriptAction =
[id, defaultSettings, propertiesSignalName, triggerSignalName,
completionSignalName](
completionSignalName, newInstanceSignalName,
deletedInstanceSignalName](
Macro *m) -> std::shared_ptr<MacroAction> {
return std::make_shared<MacroActionScript>(
m, id, defaultSettings, propertiesSignalName,
triggerSignalName, completionSignalName);
triggerSignalName, completionSignalName,
newInstanceSignalName, deletedInstanceSignalName);
};
if (!MacroActionFactory::Register(id, {createScriptAction,
MacroSegmentScriptEdit::Create,
@@ -202,9 +262,15 @@ void ScriptHandler::RegisterScriptAction(void *, calldata_t *data)
triggerSignalName.c_str());
calldata_set_string(data, propertiesSignalParam.data(),
propertiesSignalName.c_str());
calldata_set_string(data, newInstanceSignalNameParam.data(),
newInstanceSignalName.c_str());
calldata_set_string(data, deletedInstanceSignalNameParam.data(),
deletedInstanceSignalName.c_str());
_actions.emplace(id, ScriptSegmentType(id, propertiesSignalName,
triggerSignalName,
completionSignalName));
completionSignalName,
newInstanceSignalName,
deletedInstanceSignalName));
RETURN_SUCCESS();
}
@@ -279,14 +345,19 @@ void ScriptHandler::RegisterScriptCondition(void *, calldata_t *data)
auto triggerSignalName = getTriggerSignal(conditionName, false);
auto completionSignalName = getCompletionSignal(conditionName, false);
auto propertiesSignalName = getPropertiesSignal(conditionName, false);
auto newInstanceSignalName = getNewInstanceSignal(conditionName, false);
auto deletedInstanceSignalName =
getDeletedInstanceSignal(conditionName, false);
const auto createScriptCondition =
[id, defaultSettings, propertiesSignalName, triggerSignalName,
completionSignalName](
completionSignalName, newInstanceSignalName,
deletedInstanceSignalName](
Macro *m) -> std::shared_ptr<MacroCondition> {
return std::make_shared<MacroConditionScript>(
m, id, defaultSettings, propertiesSignalName,
triggerSignalName, completionSignalName);
triggerSignalName, completionSignalName,
newInstanceSignalName, deletedInstanceSignalName);
};
if (!MacroConditionFactory::Register(
id, {createScriptCondition, MacroSegmentScriptEdit::Create,
@@ -304,9 +375,15 @@ void ScriptHandler::RegisterScriptCondition(void *, calldata_t *data)
triggerSignalName.c_str());
calldata_set_string(data, propertiesSignalParam.data(),
propertiesSignalName.c_str());
calldata_set_string(data, newInstanceSignalNameParam.data(),
newInstanceSignalName.c_str());
calldata_set_string(data, deletedInstanceSignalNameParam.data(),
deletedInstanceSignalName.c_str());
_conditions.emplace(id, ScriptSegmentType(id, propertiesSignalName,
triggerSignalName,
completionSignalName));
completionSignalName,
newInstanceSignalName,
deletedInstanceSignalName));
RETURN_SUCCESS();
}
@@ -399,6 +476,92 @@ void ScriptHandler::SetVariableValue(void *, calldata_t *data)
RETURN_SUCCESS();
}
void ScriptHandler::RegisterTempVar(void *, calldata_t *data)
{
const char *variableId;
if (!calldata_get_string(data, tempVarIdParam.data(), &variableId) ||
strlen(variableId) == 0) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
registerTempVarFuncName.data(), tempVarIdParam.data());
RETURN_FAILURE();
}
const char *name;
if (!calldata_get_string(data, tempVarNameParam.data(), &name) ||
strlen(name) == 0) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
registerTempVarFuncName.data(), tempVarNameParam.data());
RETURN_FAILURE();
}
const char *helpText;
if (!calldata_get_string(data, tempVarHelpParam.data(), &helpText)) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
registerTempVarFuncName.data(), tempVarHelpParam.data());
RETURN_FAILURE();
}
long long instanceId;
if (!calldata_get_int(data, GetInstanceIdParamName().data(),
&instanceId)) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
registerTempVarFuncName.data(),
GetInstanceIdParamName().data());
RETURN_FAILURE();
}
std::lock_guard<std::mutex> lock(_mutex);
MacroSegmentScript::RegisterTempVar(variableId, name, helpText,
instanceId);
RETURN_SUCCESS();
}
void ScriptHandler::DeregisterAllTempVars(void *, calldata_t *data)
{
long long instanceId;
if (!calldata_get_int(data, GetInstanceIdParamName().data(),
&instanceId)) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
deregisterAllTempVarsFuncName.data(),
GetInstanceIdParamName().data());
RETURN_FAILURE();
}
std::lock_guard<std::mutex> lock(_mutex);
MacroSegmentScript::DeregisterAllTempVars(instanceId);
RETURN_SUCCESS();
}
void ScriptHandler::SetTempVarValue(void *, calldata_t *data)
{
const char *variableId;
if (!calldata_get_string(data, tempVarIdParam.data(), &variableId) ||
strlen(variableId) == 0) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
setTempVarValueFuncName.data(), tempVarIdParam.data());
RETURN_FAILURE();
}
const char *variableValue;
if (!calldata_get_string(data, valueParam.data(), &variableValue) ||
strlen(variableValue) == 0) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
setTempVarValueFuncName.data(), valueParam.data());
RETURN_FAILURE();
}
long long instanceId;
if (!calldata_get_int(data, GetInstanceIdParamName().data(),
&instanceId)) {
blog(LOG_WARNING, "[%s] failed! \"%s\" parameter missing!",
setTempVarValueFuncName.data(),
GetInstanceIdParamName().data());
RETURN_FAILURE();
}
std::lock_guard<std::mutex> lock(_mutex);
MacroSegmentScript::SetTempVarValue(variableId, variableValue,
instanceId);
RETURN_SUCCESS();
}
bool ScriptHandler::ActionIdIsValid(const std::string &id)
{
std::lock_guard<std::mutex> lock(_mutex);
@@ -424,24 +587,39 @@ static std::string signalNameToPropertiesSignalDecl(const std::string &name)
static std::string signalNameToCompletionSignalDecl(const std::string &name)
{
return std::string("bool ") + name + "(in int " +
GeCompletionIdParamName().data() + ")";
GetCompletionIdParamName().data() + ")";
}
ScriptSegmentType::ScriptSegmentType(const std::string &id,
const std::string &propertiesSignal,
const std::string &triggerSignal,
const std::string &completionSignal)
static std::string signalNameToInstanceSignalDecl(const std::string &name)
{
return std::string("void ") + name + "(out int " +
GetInstanceIdParamName().data() + ")";
}
ScriptSegmentType::ScriptSegmentType(
const std::string &id, const std::string &propertiesSignalName,
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName)
: _id(id)
{
auto sh = obs_get_signal_handler();
signal_handler_add(
obs_get_signal_handler(),
signalNameToPropertiesSignalDecl(propertiesSignal).c_str());
sh,
signalNameToPropertiesSignalDecl(propertiesSignalName).c_str());
signal_handler_add(
obs_get_signal_handler(),
signalNameToTriggerSignalDecl(triggerSignal).c_str());
sh, signalNameToTriggerSignalDecl(triggerSignalName).c_str());
signal_handler_add(
obs_get_signal_handler(),
signalNameToCompletionSignalDecl(completionSignal).c_str());
sh,
signalNameToCompletionSignalDecl(completionSignalName).c_str());
signal_handler_add(
sh,
signalNameToInstanceSignalDecl(newInstanceSignalName).c_str());
signal_handler_add(
sh, signalNameToInstanceSignalDecl(deletedInstanceSignalName)
.c_str());
}
} // namespace advss

View File

@@ -10,9 +10,11 @@ class ScriptSegmentType {
public:
ScriptSegmentType() = delete;
ScriptSegmentType(const std::string &id,
const std::string &propertiesSignal,
const std::string &triggerSignal,
const std::string &completionSignal);
const std::string &propertiesSignalName,
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName);
private:
std::string _id;
@@ -26,6 +28,9 @@ public:
static void RegisterScriptCondition(void *ctx, calldata_t *data);
static void DeregisterScriptCondition(void *ctx, calldata_t *data);
static void GetVariableValue(void *ctx, calldata_t *data);
static void RegisterTempVar(void *ctx, calldata_t *data);
static void DeregisterAllTempVars(void *ctx, calldata_t *data);
static void SetTempVarValue(void *ctx, calldata_t *data);
static void SetVariableValue(void *ctx, calldata_t *data);
static bool ActionIdIsValid(const std::string &id);
static bool ConditionIdIsValid(const std::string &id);
@@ -46,14 +51,19 @@ static constexpr std::string_view GetActionCompletionSignalParamName()
return "completion_signal_name";
}
static constexpr std::string_view GeCompletionIdParamName()
static constexpr std::string_view GetCompletionIdParamName()
{
return "completion_id";
}
static constexpr std::string_view GeResultSignalParamName()
static constexpr std::string_view GetResultSignalParamName()
{
return "result";
}
static constexpr std::string_view GetInstanceIdParamName()
{
return "instance_id";
}
} // namespace advss

View File

@@ -178,11 +178,7 @@ void MacroSegmentList::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton ||
event->button() == Qt::RightButton) {
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
_dragPosition = GetDragIndex(event->globalPos());
#else
_dragPosition = GetDragIndex(event->globalPosition().toPoint());
#endif
emit SelectionChanged(_dragPosition);
} else {
_dragPosition = -1;
@@ -300,11 +296,7 @@ void MacroSegmentList::dragMoveEvent(QDragMoveEvent *event)
return;
}
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
_dragCursorPos = (mapToGlobal(event->pos()));
#else
_dragCursorPos = (mapToGlobal(event->position().toPoint()));
#endif
CheckDropLine(_dragCursorPos);
}
@@ -450,16 +442,6 @@ void MacroSegmentList::dropEvent(QDropEvent *event)
{
HideLastDropLine();
auto widget = qobject_cast<QWidget *>(event->source());
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
if (widget && !widget->geometry().contains(event->pos()) &&
widgetIsInLayout(widget, _contentLayout)) {
int dropPosition = GetDropIndex(mapToGlobal(event->pos()));
if (dropPosition == -1) {
return;
}
emit Reorder(dropPosition, _dragPosition);
}
#else
if (widget &&
!widget->geometry().contains(event->position().toPoint()) &&
widgetIsInLayout(widget, _contentLayout)) {
@@ -470,7 +452,6 @@ void MacroSegmentList::dropEvent(QDropEvent *event)
}
emit Reorder(dropPosition, _dragPosition);
}
#endif
_dragPosition = -1;
}

View File

@@ -11,33 +11,106 @@
namespace advss {
static std::atomic_int completionIdCounter = 0;
static std::atomic_int instanceIdCounter = 0;
static std::mutex instanceMtx;
static std::vector<MacroSegmentScript *> instances{};
MacroSegmentScript::MacroSegmentScript(obs_data_t *defaultSettings,
const std::string &propertiesSignalName,
const std::string &triggerSignal,
const std::string &completionSignal)
MacroSegmentScript::MacroSegmentScript(
obs_data_t *defaultSettings, const std::string &propertiesSignalName,
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName)
: _settings(obs_data_get_defaults(defaultSettings)),
_propertiesSignal(propertiesSignalName),
_triggerSignal(triggerSignal),
_completionSignal(completionSignal)
_triggerSignal(triggerSignalName),
_completionSignal(completionSignalName),
_newInstanceSignal(newInstanceSignalName),
_deletedInstanceSignal(deletedInstanceSignalName),
_instanceId(++instanceIdCounter)
{
signal_handler_connect(obs_get_signal_handler(),
completionSignal.c_str(),
completionSignalName.c_str(),
&MacroSegmentScript::CompletionSignalReceived,
this);
std::lock_guard<std::mutex> lock(instanceMtx);
instances.emplace_back(this);
SignalNewInstance();
}
MacroSegmentScript::MacroSegmentScript(const MacroSegmentScript &other)
: _settings(obs_data_create()),
_propertiesSignal(other._propertiesSignal),
_triggerSignal(other._triggerSignal),
_completionSignal(other._completionSignal)
_completionSignal(other._completionSignal),
_newInstanceSignal(other._newInstanceSignal),
_deletedInstanceSignal(other._deletedInstanceSignal),
_instanceId(++instanceIdCounter)
{
signal_handler_connect(obs_get_signal_handler(),
_completionSignal.c_str(),
&MacroSegmentScript::CompletionSignalReceived,
this);
obs_data_apply(_settings.Get(), other._settings.Get());
std::lock_guard<std::mutex> lock(instanceMtx);
instances.emplace_back(this);
SignalNewInstance();
}
MacroSegmentScript::~MacroSegmentScript()
{
auto data = calldata_create();
calldata_set_int(data, GetInstanceIdParamName().data(), _instanceId);
signal_handler_signal(obs_get_signal_handler(),
_deletedInstanceSignal.c_str(), data);
calldata_destroy(data);
std::lock_guard<std::mutex> lock(instanceMtx);
instances.erase(std::remove(instances.begin(), instances.end(), this),
instances.end());
}
void MacroSegmentScript::RegisterTempVar(const std::string &variableId,
const std::string &name,
const std::string &helpText,
int instanceId)
{
std::lock_guard<std::mutex> lock(instanceMtx);
for (auto instance : instances) {
if (instance->_instanceId != instanceId) {
continue;
}
instance->RegisterTempVarHelper(variableId, name, helpText);
break;
}
}
void MacroSegmentScript::DeregisterAllTempVars(int instanceId)
{
std::lock_guard<std::mutex> lock(instanceMtx);
for (auto instance : instances) {
if (instance->_instanceId != instanceId) {
continue;
}
instance->DeregisterAllTempVarsHelper();
}
}
void MacroSegmentScript::SetTempVarValue(const std::string &variableId,
const std::string &value,
int instanceId)
{
std::lock_guard<std::mutex> lock(instanceMtx);
for (auto instance : instances) {
if (instance->_instanceId != instanceId) {
continue;
}
instance->SetTempVarValueHelper(variableId, value);
}
}
bool MacroSegmentScript::Save(obs_data_t *obj) const
@@ -85,8 +158,10 @@ bool MacroSegmentScript::SendTriggerSignal()
auto data = calldata_create();
calldata_set_string(data, GetActionCompletionSignalParamName().data(),
_completionSignal.c_str());
calldata_set_int(data, GeCompletionIdParamName().data(), _completionId);
calldata_set_int(data, GetCompletionIdParamName().data(),
_completionId);
calldata_set_string(data, "settings", obs_data_get_json(GetSettings()));
calldata_set_int(data, GetInstanceIdParamName().data(), _instanceId);
signal_handler_signal(obs_get_signal_handler(), _triggerSignal.c_str(),
data);
calldata_destroy(data);
@@ -101,18 +176,18 @@ void MacroSegmentScript::CompletionSignalReceived(void *param, calldata_t *data)
{
auto segment = static_cast<MacroSegmentScript *>(param);
long long int id;
if (!calldata_get_int(data, GeCompletionIdParamName().data(), &id)) {
if (!calldata_get_int(data, GetCompletionIdParamName().data(), &id)) {
blog(LOG_WARNING,
"received completion signal without \"%s\" parameter",
GeCompletionIdParamName().data());
GetCompletionIdParamName().data());
return;
}
bool result;
if (!calldata_get_bool(data, GeResultSignalParamName().data(),
if (!calldata_get_bool(data, GetResultSignalParamName().data(),
&result)) {
blog(LOG_WARNING,
"received completion signal without \"%s\" parameter",
GeResultSignalParamName().data());
GetResultSignalParamName().data());
return;
}
if (id != segment->_completionId) {
@@ -122,6 +197,19 @@ void MacroSegmentScript::CompletionSignalReceived(void *param, calldata_t *data)
segment->_triggerResult = result;
}
void MacroSegmentScript::SignalNewInstance() const
{
std::thread signalNewInstanceThread([this]() {
auto data = calldata_create();
calldata_set_int(data, GetInstanceIdParamName().data(),
_instanceId);
signal_handler_signal(obs_get_signal_handler(),
_newInstanceSignal.c_str(), data);
calldata_destroy(data);
});
signalNewInstanceThread.detach();
}
obs_properties_t *MacroSegmentScriptEdit::GetProperties(void *obj)
{
auto segmentEdit = reinterpret_cast<MacroSegmentScriptEdit *>(obj);

View File

@@ -15,9 +15,20 @@ class MacroSegmentScript {
public:
MacroSegmentScript(obs_data_t *defaultSettings,
const std::string &propertiesSignalName,
const std::string &triggerSignal,
const std::string &completionSignal);
const std::string &triggerSignalName,
const std::string &completionSignalName,
const std::string &newInstanceSignalName,
const std::string &deletedInstanceSignalName);
MacroSegmentScript(const advss::MacroSegmentScript &);
virtual ~MacroSegmentScript();
static void RegisterTempVar(const std::string &variableId,
const std::string &name,
const std::string &helpText,
int instanceId);
static void DeregisterAllTempVars(int instanceId);
static void SetTempVarValue(const std::string &variableId,
const std::string &value, int instanceId);
protected:
bool Save(obs_data_t *obj) const;
@@ -31,15 +42,27 @@ protected:
double GetTimeoutSeconds() const { return _timeout.Seconds(); };
bool TriggerIsCompleted() const { return _triggerIsComplete; }
virtual void RegisterTempVarHelper(const std::string &variableId,
const std::string &name,
const std::string &helpText) = 0;
virtual void DeregisterAllTempVarsHelper() = 0;
virtual void SetTempVarValueHelper(const std::string &variableId,
const std::string &value) = 0;
const int64_t _instanceId;
private:
virtual void WaitForCompletion() const = 0;
static void CompletionSignalReceived(void *param, calldata_t *data);
void SignalNewInstance() const;
OBSDataAutoRelease _settings;
std::string _propertiesSignal = "";
std::string _triggerSignal = "";
std::string _completionSignal = "";
std::string _newInstanceSignal = "";
std::string _deletedInstanceSignal = "";
std::atomic_bool _triggerIsComplete = {false};
bool _triggerResult = false;
int64_t _completionId = 0;

View File

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

View File

@@ -294,13 +294,8 @@ bool MacroSegmentEdit::eventFilter(QObject *obj, QEvent *ev)
QMouseEvent *newEvent = new QMouseEvent(
mouseEvent->type(),
_headerInfo->mapTo(this, mouseEvent->pos()),
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
mouseEvent->globalPos(),
#else
mouseEvent->globalPosition(),
#endif
mouseEvent->button(), mouseEvent->buttons(),
mouseEvent->modifiers());
mouseEvent->globalPosition(), mouseEvent->button(),
mouseEvent->buttons(), mouseEvent->modifiers());
QApplication::sendEvent(parentWidget(), newEvent);
}
return QWidget::eventFilter(obj, ev);

View File

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

View File

@@ -178,6 +178,7 @@ void MacroTreeItem::Update(bool force)
QSizePolicy::Maximum);
_expand->setMaximumSize(10, 16);
_expand->setMinimumSize(10, 0);
_expand->setProperty("class", "checkbox-icon indicator-expand");
#ifdef __APPLE__
_expand->setAttribute(Qt::WA_LayoutUsesWidgetRect);
#endif
@@ -888,14 +889,7 @@ void MacroTree::dropEvent(QDropEvent *event)
QModelIndexList indices = selectedIndexes();
DropIndicatorPosition indicator = dropIndicatorPosition();
int row = indexAt(
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
event->position().toPoint()
#else
event->pos()
#endif
)
.row();
int row = indexAt(event->position().toPoint()).row();
bool emptyDrop = row == -1;
if (emptyDrop) {

View File

@@ -244,8 +244,13 @@ bool Macro::CheckConditions(bool ignorePause)
return false;
}
_stop = false;
_matched = false;
for (auto &condition : _conditions) {
if (!condition) {
continue;
}
if (_paused && !ignorePause) {
vblog(LOG_INFO, "Macro %s is paused", _name.c_str());
return false;
@@ -383,6 +388,9 @@ bool Macro::RunActionsHelper(
bool actionsExecutedSuccessfully = true;
for (auto &action : actions) {
if (!action) {
continue;
}
if (action->Enabled()) {
action->LogAction();
actionsExecutedSuccessfully =

View File

@@ -5,6 +5,7 @@
#include "plugin-state-helpers.hpp"
#include "sync-helpers.hpp"
#include "tab-helpers.hpp"
#include "time-helpers.hpp"
#include "ui-helpers.hpp"
#include <QTimer>
@@ -39,8 +40,8 @@ ActionQueueTable *ActionQueueTable::Create()
void ActionQueueTable::Add()
{
auto newQueue = std::make_shared<ActionQueue>();
auto accepted =
ActionQueueSettingsDialog::AskForSettings(this, *newQueue);
auto accepted = ActionQueueSettingsDialog::AskForSettings(
GetSettingsWindow(), *newQueue);
if (!accepted) {
return;
}
@@ -55,6 +56,13 @@ void ActionQueueTable::Add()
QString::fromStdString(newQueue->Name()));
}
static double getSecondsSinceLastEmpty(ActionQueue *queue)
{
const auto time = std::chrono::high_resolution_clock::now() -
queue->GetLastEmptyTime();
return std::chrono::duration_cast<std::chrono::seconds>(time).count();
}
static QStringList getCellLabels(ActionQueue *queue, bool addName = true)
{
assert(queue);
@@ -64,6 +72,7 @@ static QStringList getCellLabels(ActionQueue *queue, bool addName = true)
result << QString::fromStdString(queue->Name());
}
result << QString::number(queue->Size())
<< FormatRelativeTime(getSecondsSinceLastEmpty(queue))
<< QString::fromStdString(obs_module_text(
queue->IsRunning()
? "AdvSceneSwitcher.actionQueueTab.yes"
@@ -115,7 +124,7 @@ static void openSettingsDialog()
auto oldName = queue->Name();
bool accepted = ActionQueueSettingsDialog::AskForSettings(
tabWidget->Table(), *queue.get());
GetSettingsWindow(), *queue.get());
if (accepted && oldName != queue->Name()) {
ActionQueueSignalManager::Instance()->Rename(
QString::fromStdString(oldName),
@@ -199,6 +208,8 @@ ActionQueueTable::ActionQueueTable(QTabWidget *parent)
"AdvSceneSwitcher.actionQueueTab.name.header")
<< obs_module_text(
"AdvSceneSwitcher.actionQueueTab.size.header")
<< obs_module_text(
"AdvSceneSwitcher.actionQueueTab.lastEmpty.header")
<< obs_module_text(
"AdvSceneSwitcher.actionQueueTab.isRunning.header")
<< obs_module_text(

View File

@@ -26,7 +26,10 @@ void SetupActionQueues()
done = true;
}
ActionQueue::ActionQueue() : Item() {}
ActionQueue::ActionQueue() : Item()
{
_lastEmpty = std::chrono::high_resolution_clock::now();
}
ActionQueue::~ActionQueue()
{
@@ -110,6 +113,7 @@ void ActionQueue::Add(const std::shared_ptr<MacroAction> &action)
action->Save(data);
copy->Load(data);
copy->PostLoad();
RunPostLoadSteps();
copy->ResolveVariablesToFixedValues();
_actions.emplace_back(copy);
} else {
@@ -124,6 +128,14 @@ bool ActionQueue::IsEmpty()
return _actions.empty();
}
ActionQueue::TimePoint ActionQueue::GetLastEmptyTime()
{
if (IsEmpty()) {
_lastEmpty = std::chrono::high_resolution_clock::now();
}
return _lastEmpty;
}
size_t ActionQueue::Size()
{
std::lock_guard<std::mutex> lock(_mutex);
@@ -137,6 +149,8 @@ void ActionQueue::RunActions()
{ // Grab next action to run
std::unique_lock<std::mutex> lock(_mutex);
while (_actions.empty() && !_stop) {
_lastEmpty =
std::chrono::high_resolution_clock::now();
_cv.wait(lock);
}
@@ -166,7 +180,7 @@ ActionQueueSettingsDialog::ActionQueueSettingsDialog(QWidget *parent,
"AdvSceneSwitcher.actionQueues.select",
"AdvSceneSwitcher.actionQueues.add",
"AdvSceneSwitcher.actionQueues.nameNotAvailable",
parent),
true, parent),
_queueRunStatus(new QLabel()),
_startStopToggle(new QPushButton()),
_queueSize(new QLabel()),

View File

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

View File

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

View File

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

View File

@@ -29,6 +29,7 @@ void Duration::Load(obs_data_t *obj, const char *name)
// TODO: remove this fallback
if (!data || !obs_data_has_user_value(data, "version") ||
obs_data_get_int(data, "version") != 1) {
_value = 0.;
bool usingDefaultArgs = strcmp("duration", name) == 0;
if (usingDefaultArgs) {
_value = obs_data_get_double(obj, "seconds");

View File

@@ -59,7 +59,10 @@ ItemSelection::ItemSelection(std::deque<std::shared_ptr<Item>> &items,
_conflictStr(conflict)
{
_modify->setMaximumWidth(22);
SetButtonIcon(_modify, ":/settings/images/settings/general.svg");
SetButtonIcon(_modify,
GetThemeTypeName() == "Light"
? ":/settings/images/settings/general.svg"
: "theme:Dark/settings/general.svg");
_modify->setFlat(true);
if (!configureTooltip.empty()) {
_modify->setToolTip(obs_module_text(configureTooltip.data()));
@@ -265,6 +268,7 @@ ItemSettingsDialog::ItemSettingsDialog(const Item &settings,
std::string_view select,
std::string_view add,
std::string_view nameConflict,
bool showNameEmptyWarning,
QWidget *parent)
: QDialog(parent),
_name(new QLineEdit()),
@@ -274,7 +278,8 @@ ItemSettingsDialog::ItemSettingsDialog(const Item &settings,
_items(items),
_selectStr(select),
_addStr(add),
_conflictStr(nameConflict)
_conflictStr(nameConflict),
_showNameEmptyWarning(showNameEmptyWarning)
{
setModal(true);
setWindowModality(Qt::WindowModality::WindowModal);

View File

@@ -45,7 +45,7 @@ public:
std::string_view addString = "AdvSceneSwitcher.item.add",
std::string_view conflictString =
"AdvSceneSwitcher.item.nameNotAvailable",
QWidget *parent = 0);
bool showEmptyNameWarning = true, QWidget *parent = 0);
virtual ~ItemSettingsDialog() = default;
private slots:

View File

@@ -92,7 +92,10 @@ RegexConfigWidget::RegexConfigWidget(QWidget *parent, bool showEnable)
_openSettings(new QToolButton()),
_enable(new QPushButton())
{
SetButtonIcon(_openSettings, ":/settings/images/settings/general.svg");
SetButtonIcon(_openSettings,
GetThemeTypeName() == "Light"
? ":/settings/images/settings/general.svg"
: "theme:Dark/settings/general.svg");
_openSettings->setToolTip(
obs_module_text("AdvSceneSwitcher.regex.configure"));

View File

@@ -94,7 +94,7 @@ void ResizingPlainTextEdit::AddHeightForScrollBar(bool addHeight)
return;
}
_hScrollBarAddedHeight = verticalScrollBar()->height();
_hScrollBarAddedHeight = horizontalScrollBar()->height();
setFixedHeight(height() + _hScrollBarAddedHeight);
}

View File

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

View File

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

View File

@@ -29,7 +29,7 @@ private:
T _value = {};
std::weak_ptr<Variable> _variable;
friend class GenericVaraiableSpinbox;
friend class GenericVariableSpinbox;
friend class VariableSpinBox;
friend class VariableDoubleSpinBox;
};

View File

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

View File

@@ -5,8 +5,8 @@
namespace advss {
GenericVaraiableSpinbox::GenericVaraiableSpinbox(QWidget *parent,
bool wholeNumber)
GenericVariableSpinbox::GenericVariableSpinbox(QWidget *parent,
bool wholeNumber)
: QWidget(parent),
_fixedValueInt(new QSpinBox()),
_fixedValueDouble(new QDoubleSpinBox()),
@@ -16,7 +16,9 @@ GenericVaraiableSpinbox::GenericVaraiableSpinbox(QWidget *parent,
{
_toggleType->setCheckable(true);
_toggleType->setMaximumWidth(11);
SetButtonIcon(_toggleType, ":/res/images/dots-vert.svg");
SetButtonIcon(_toggleType, GetThemeTypeName() == "Light"
? ":/res/images/dots-vert.svg"
: "theme:Dark/dots-vert.svg");
QWidget::connect(_fixedValueInt, SIGNAL(valueChanged(int)), this,
SLOT(SetFixedValue(int)));
@@ -48,7 +50,7 @@ GenericVaraiableSpinbox::GenericVaraiableSpinbox(QWidget *parent,
SetVisibility();
}
void GenericVaraiableSpinbox::SetValue(const NumberVariable<int> &number)
void GenericVariableSpinbox::SetValue(const NumberVariable<int> &number)
{
_numberInt = number;
const QSignalBlocker b1(_toggleType);
@@ -59,7 +61,7 @@ void GenericVaraiableSpinbox::SetValue(const NumberVariable<int> &number)
SetVisibility();
}
void GenericVaraiableSpinbox::SetValue(const NumberVariable<double> &number)
void GenericVariableSpinbox::SetValue(const NumberVariable<double> &number)
{
_numberDouble = number;
const QSignalBlocker b1(_toggleType);
@@ -70,44 +72,44 @@ void GenericVaraiableSpinbox::SetValue(const NumberVariable<double> &number)
SetVisibility();
}
void GenericVaraiableSpinbox::DisableVariableSelection()
void GenericVariableSpinbox::DisableVariableSelection()
{
_hideTypeToggle = true;
_toggleType->hide();
ToggleTypeClicked(false);
}
void GenericVaraiableSpinbox::setMinimum(double value)
void GenericVariableSpinbox::setMinimum(double value)
{
_fixedValueInt->setMinimum(value);
_fixedValueDouble->setMinimum(value);
}
void GenericVaraiableSpinbox::setMaximum(double value)
void GenericVariableSpinbox::setMaximum(double value)
{
_fixedValueInt->setMaximum(value);
_fixedValueDouble->setMaximum(value);
}
void GenericVaraiableSpinbox::setPrefix(const QString &prefix)
void GenericVariableSpinbox::setPrefix(const QString &prefix)
{
_fixedValueInt->setPrefix(prefix);
_fixedValueDouble->setPrefix(prefix);
}
void GenericVaraiableSpinbox::setSuffix(const QString &suffix)
void GenericVariableSpinbox::setSuffix(const QString &suffix)
{
_fixedValueInt->setSuffix(suffix);
_fixedValueDouble->setSuffix(suffix);
}
void GenericVaraiableSpinbox::specialValueText(const QString &text)
void GenericVariableSpinbox::setSpecialValueText(const QString &text)
{
_fixedValueInt->setSpecialValueText(text);
_fixedValueDouble->setSpecialValueText(text);
}
void GenericVaraiableSpinbox::SetFixedValue(int value)
void GenericVariableSpinbox::SetFixedValue(int value)
{
_numberInt._value = value;
const QSignalBlocker b(_fixedValueInt);
@@ -115,7 +117,7 @@ void GenericVaraiableSpinbox::SetFixedValue(int value)
EmitSignals();
}
void GenericVaraiableSpinbox::SetFixedValue(double value)
void GenericVariableSpinbox::SetFixedValue(double value)
{
_numberDouble._value = value;
const QSignalBlocker b(_fixedValueDouble);
@@ -123,14 +125,14 @@ void GenericVaraiableSpinbox::SetFixedValue(double value)
EmitSignals();
}
void GenericVaraiableSpinbox::VariableChanged(const QString &name)
void GenericVariableSpinbox::VariableChanged(const QString &name)
{
_numberInt._variable = GetWeakVariableByQString(name);
_numberDouble._variable = GetWeakVariableByQString(name);
EmitSignals();
}
void GenericVaraiableSpinbox::ToggleTypeClicked(bool useVariable)
void GenericVariableSpinbox::ToggleTypeClicked(bool useVariable)
{
_numberInt._type = useVariable ? NumberVariable<int>::Type::VARIABLE
: NumberVariable<int>::Type::FIXED_VALUE;
@@ -142,7 +144,7 @@ void GenericVaraiableSpinbox::ToggleTypeClicked(bool useVariable)
EmitSignals();
}
void GenericVaraiableSpinbox::EmitSignals()
void GenericVariableSpinbox::EmitSignals()
{
if (_wholeNumber) {
emit FixedValueChanged(_numberInt);
@@ -153,7 +155,7 @@ void GenericVaraiableSpinbox::EmitSignals()
}
}
void GenericVaraiableSpinbox::SetVisibility()
void GenericVariableSpinbox::SetVisibility()
{
if (_wholeNumber) {
_fixedValueDouble->hide();
@@ -164,7 +166,7 @@ void GenericVaraiableSpinbox::SetVisibility()
}
}
void GenericVaraiableSpinbox::SetVisibilityInt()
void GenericVariableSpinbox::SetVisibilityInt()
{
if (_numberInt.IsFixedType()) {
_fixedValueInt->show();
@@ -180,7 +182,7 @@ void GenericVaraiableSpinbox::SetVisibilityInt()
updateGeometry();
}
void GenericVaraiableSpinbox::SetVisibilityDouble()
void GenericVariableSpinbox::SetVisibilityDouble()
{
if (_numberDouble.IsFixedType()) {
_fixedValueDouble->show();
@@ -197,12 +199,12 @@ void GenericVaraiableSpinbox::SetVisibilityDouble()
}
VariableSpinBox::VariableSpinBox(QWidget *parent)
: GenericVaraiableSpinbox(parent, true)
: GenericVariableSpinbox(parent, true)
{
}
VariableDoubleSpinBox::VariableDoubleSpinBox(QWidget *parent)
: GenericVaraiableSpinbox(parent, false)
: GenericVariableSpinbox(parent, false)
{
}

View File

@@ -9,10 +9,10 @@
namespace advss {
class ADVSS_EXPORT GenericVaraiableSpinbox : public QWidget {
class ADVSS_EXPORT GenericVariableSpinbox : public QWidget {
Q_OBJECT
public:
GenericVaraiableSpinbox(QWidget *parent, bool wholeNumber);
GenericVariableSpinbox(QWidget *parent, bool wholeNumber);
void SetValue(const NumberVariable<int> &);
void SetValue(const NumberVariable<double> &);
void DisableVariableSelection();
@@ -23,7 +23,7 @@ public:
void setPrefix(const QString &prefix);
void setSuffix(const QString &suffix);
void specialValueText(const QString &text);
void setSpecialValueText(const QString &text);
public slots:
void SetFixedValue(int);
@@ -59,7 +59,7 @@ private:
bool _hideTypeToggle = false;
};
class ADVSS_EXPORT VariableSpinBox : public GenericVaraiableSpinbox {
class ADVSS_EXPORT VariableSpinBox : public GenericVariableSpinbox {
Q_OBJECT
public:
@@ -68,7 +68,7 @@ public:
QSpinBox *SpinBox() { return _fixedValueInt; }
};
class ADVSS_EXPORT VariableDoubleSpinBox : public GenericVaraiableSpinbox {
class ADVSS_EXPORT VariableDoubleSpinBox : public GenericVariableSpinbox {
Q_OBJECT
public:

View File

@@ -43,8 +43,8 @@ VariableTable *VariableTable::Create()
void VariableTable::Add()
{
auto newVariable = std::make_shared<Variable>();
auto accepted =
VariableSettingsDialog::AskForSettings(this, *newVariable);
auto accepted = VariableSettingsDialog::AskForSettings(
GetSettingsWindow(), *newVariable);
if (!accepted) {
return;
}
@@ -184,7 +184,7 @@ static void openSettingsDialog()
auto oldName = variable->Name();
bool accepted = VariableSettingsDialog::AskForSettings(
tabWidget->Table(), *variable.get());
GetSettingsWindow(), *variable.get());
if (accepted && oldName != variable->Name()) {
VariableSignalManager::Instance()->Rename(
QString::fromStdString(oldName),

View File

@@ -137,7 +137,8 @@ VariableSettingsDialog::VariableSettingsDialog(QWidget *parent,
: ItemSettingsDialog(settings, variables,
"AdvSceneSwitcher.variable.select",
"AdvSceneSwitcher.variable.add",
"AdvSceneSwitcher.item.nameNotAvailable", parent),
"AdvSceneSwitcher.item.nameNotAvailable", true,
parent),
_value(new ResizingPlainTextEdit(this)),
_defaultValue(new ResizingPlainTextEdit(this)),
_save(new QComboBox())

View File

@@ -89,6 +89,8 @@ target_sources(
macro-condition-filter.hpp
macro-condition-folder.cpp
macro-condition-folder.hpp
macro-condition-game-capture.cpp
macro-condition-game-capture.hpp
macro-condition-hotkey.cpp
macro-condition-hotkey.hpp
macro-condition-idle.cpp
@@ -117,6 +119,8 @@ target_sources(
macro-condition-scene-visibility.hpp
macro-condition-scene.cpp
macro-condition-scene.hpp
macro-condition-screenshot.cpp
macro-condition-screenshot.hpp
macro-condition-slideshow.cpp
macro-condition-slideshow.hpp
macro-condition-source.cpp

View File

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

View File

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

View File

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

View File

@@ -215,7 +215,7 @@ MacroActionFilterEdit::MacroActionFilterEdit(
_settingsString(new VariableTextEdit(this)),
_refreshSettingSelection(new QPushButton(
obs_module_text("AdvSceneSwitcher.action.filter.refresh"))),
_settingsButtons(new QComboBox())
_settingsButtons(new SourceSettingsButtonSelection(this))
{
_filters->setSizeAdjustPolicy(QComboBox::AdjustToContents);
@@ -253,8 +253,10 @@ MacroActionFilterEdit::MacroActionFilterEdit(
SLOT(SelectionChanged(const SourceSetting &)));
QWidget::connect(_refreshSettingSelection, SIGNAL(clicked()), this,
SLOT(RefreshVariableSourceSelectionValue()));
QWidget::connect(_settingsButtons, SIGNAL(currentIndexChanged(int)),
this, SLOT(ButtonChanged(int)));
QWidget::connect(_settingsButtons,
SIGNAL(SelectionChanged(const SourceSettingButton &)),
this,
SLOT(ButtonChanged(const SourceSettingButton &)));
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{sources}}", _sources},
@@ -305,25 +307,18 @@ void MacroActionFilterEdit::UpdateEntryData()
const auto filters =
_entryData->_filter.GetFilters(_entryData->_source);
OBSWeakSource firstFilter = filters.empty() ? nullptr : filters.at(0);
_filterSettings->SetSource(firstFilter);
_filterSettings->SetSetting(_entryData->_setting);
_filterSettings->SetSelection(firstFilter, _entryData->_setting);
_settingsInputMethods->setCurrentIndex(_settingsInputMethods->findData(
static_cast<int>(_entryData->_settingsInputMethod)));
_tempVars->SetVariable(_entryData->_tempVar);
_manualSettingValue->setPlainText(_entryData->_manualSettingValue);
PopulateSourceButtonSelection(_settingsButtons, firstFilter);
_settingsButtons->setCurrentText(
QString::fromStdString(_entryData->_button.ToString()));
_settingsButtons->SetSelection(firstFilter, _entryData->_button);
SetWidgetVisibility();
}
void MacroActionFilterEdit::SourceChanged(const SourceSelection &source)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_source = source;
}
@@ -337,11 +332,13 @@ void MacroActionFilterEdit::FilterChanged(const FilterSelection &filter)
auto lock = LockContext();
_entryData->_filter = filter;
}
const auto filters =
_entryData->_filter.GetFilters(_entryData->_source);
OBSWeakSource firstFilter = filters.empty() ? nullptr : filters.at(0);
_filterSettings->SetSource(firstFilter);
PopulateSourceButtonSelection(_settingsButtons, firstFilter);
_settingsButtons->SetSource(firstFilter);
SetWidgetVisibility();
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
@@ -349,11 +346,7 @@ void MacroActionFilterEdit::FilterChanged(const FilterSelection &filter)
void MacroActionFilterEdit::ActionChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_action = static_cast<MacroActionFilter::Action>(value);
SetWidgetVisibility();
}
@@ -391,11 +384,7 @@ void MacroActionFilterEdit::GetSettingsClicked()
void MacroActionFilterEdit::SettingsStringChanged()
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_settingsString =
_settingsString->toPlainText().toStdString();
@@ -405,11 +394,7 @@ void MacroActionFilterEdit::SettingsStringChanged()
void MacroActionFilterEdit::SettingsInputMethodChanged(int idx)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_settingsInputMethod =
static_cast<MacroActionFilter::SettingsInputMethod>(
_settingsInputMethods->itemData(idx).toInt());
@@ -418,31 +403,19 @@ void MacroActionFilterEdit::SettingsInputMethodChanged(int idx)
void MacroActionFilterEdit::SelectionChanged(const TempVariableRef &var)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_tempVar = var;
}
void MacroActionFilterEdit::SelectionChanged(const SourceSetting &setting)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_setting = setting;
}
void MacroActionFilterEdit::ManualSettingsValueChanged()
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_manualSettingValue =
_manualSettingValue->toPlainText().toStdString();
@@ -457,15 +430,10 @@ void MacroActionFilterEdit::RefreshVariableSourceSelectionValue()
_filterSettings->SetSource(filters.empty() ? nullptr : filters.at(0));
}
void MacroActionFilterEdit::ButtonChanged(int idx)
void MacroActionFilterEdit::ButtonChanged(const SourceSettingButton &button)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_button = qvariant_cast<SourceSettingButton>(
_settingsButtons->itemData(idx));
GUARD_LOADING_AND_LOCK();
_entryData->_button = button;
}
void MacroActionFilterEdit::SetWidgetVisibility()

View File

@@ -7,7 +7,6 @@
#include "source-setting.hpp"
#include <QComboBox>
#include <QSpinBox>
#include <QPushButton>
namespace advss {
@@ -82,7 +81,7 @@ private slots:
void SelectionChanged(const SourceSetting &);
void ManualSettingsValueChanged();
void RefreshVariableSourceSelectionValue();
void ButtonChanged(int idx);
void ButtonChanged(const SourceSettingButton &);
signals:
void HeaderInfoChanged(const QString &);
@@ -101,7 +100,7 @@ private:
SourceSettingSelection *_filterSettings;
VariableTextEdit *_settingsString;
QPushButton *_refreshSettingSelection;
QComboBox *_settingsButtons;
SourceSettingsButtonSelection *_settingsButtons;
std::shared_ptr<MacroActionFilter> _entryData;
bool _loading = true;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -263,28 +263,12 @@ static inline void populateActionSelection(QComboBox *list)
}
}
static inline void populateDeinterlaceModeSelection(QComboBox *list)
template<class T>
static inline void populateModeSelection(QComboBox *list,
const std::map<T, std::string> &modes)
{
list->clear();
for (const auto &[value, name] : deinterlaceModes) {
list->addItem(obs_module_text(name.c_str()),
static_cast<int>(value));
}
}
static inline void populateDeinterlaceFieldOrderSelection(QComboBox *list)
{
list->clear();
for (const auto &[value, name] : deinterlaceFieldOrders) {
list->addItem(obs_module_text(name.c_str()),
static_cast<int>(value));
}
}
static inline void populateSettingsInputMethods(QComboBox *list)
{
list->clear();
for (const auto &[value, name] : inputMethods) {
for (const auto &[value, name] : modes) {
list->addItem(obs_module_text(name.c_str()),
static_cast<int>(value));
}
@@ -295,7 +279,7 @@ MacroActionSourceEdit::MacroActionSourceEdit(
: QWidget(parent),
_sources(new SourceSelectionWidget(this, QStringList(), true)),
_actions(new QComboBox()),
_settingsButtons(new QComboBox()),
_settingsButtons(new SourceSettingsButtonSelection(this)),
_settingsLayout(new QHBoxLayout()),
_settingsInputMethods(new QComboBox(this)),
_manualSettingValue(new VariableTextEdit(this, 5, 1, 1)),
@@ -315,16 +299,18 @@ MacroActionSourceEdit::MacroActionSourceEdit(
auto sources = GetSourceNames();
sources.sort();
_sources->SetSourceNameList(sources);
populateDeinterlaceModeSelection(_deinterlaceMode);
populateDeinterlaceFieldOrderSelection(_deinterlaceOrder);
populateSettingsInputMethods(_settingsInputMethods);
populateModeSelection(_deinterlaceMode, deinterlaceModes);
populateModeSelection(_deinterlaceOrder, deinterlaceFieldOrders);
populateModeSelection(_settingsInputMethods, inputMethods);
_refreshSettingSelection->setToolTip(obs_module_text(
"AdvSceneSwitcher.action.source.refresh.tooltip"));
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));
QWidget::connect(_settingsButtons, SIGNAL(currentIndexChanged(int)),
this, SLOT(ButtonChanged(int)));
QWidget::connect(_settingsButtons,
SIGNAL(SelectionChanged(const SourceSettingButton &)),
this,
SLOT(ButtonChanged(const SourceSettingButton &)));
QWidget::connect(_sources,
SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &)));
@@ -394,14 +380,11 @@ void MacroActionSourceEdit::UpdateEntryData()
return;
}
PopulateSourceButtonSelection(_settingsButtons,
_entryData->_source.GetSource());
const auto weakSource = _entryData->_source.GetSource();
_settingsButtons->SetSelection(weakSource, _entryData->_button);
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_sources->SetSource(_entryData->_source);
_sourceSettings->SetSource(_entryData->_source.GetSource());
_sourceSettings->SetSetting(_entryData->_setting);
_settingsButtons->setCurrentText(
QString::fromStdString(_entryData->_button.ToString()));
_sourceSettings->SetSelection(weakSource, _entryData->_setting);
_settingsString->setPlainText(_entryData->_settingsString);
_deinterlaceMode->setCurrentIndex(_deinterlaceMode->findData(
static_cast<int>(_entryData->_deinterlaceMode)));
@@ -425,9 +408,10 @@ void MacroActionSourceEdit::SourceChanged(const SourceSelection &source)
auto lock = LockContext();
_entryData->_source = source;
}
PopulateSourceButtonSelection(_settingsButtons,
_entryData->_source.GetSource());
_sourceSettings->SetSource(_entryData->_source.GetSource());
const auto weakSource = _entryData->_source.GetSource();
_sourceSettings->SetSource(weakSource);
_settingsButtons->SetSource(weakSource);
SetWidgetVisibility();
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
@@ -435,24 +419,15 @@ void MacroActionSourceEdit::SourceChanged(const SourceSelection &source)
void MacroActionSourceEdit::ActionChanged(int value)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_action = static_cast<MacroActionSource::Action>(value);
SetWidgetVisibility();
}
void MacroActionSourceEdit::ButtonChanged(int idx)
void MacroActionSourceEdit::ButtonChanged(const SourceSettingButton &button)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
_entryData->_button = qvariant_cast<SourceSettingButton>(
_settingsButtons->itemData(idx));
GUARD_LOADING_AND_LOCK();
_entryData->_button = button;
}
void MacroActionSourceEdit::GetSettingsClicked()
@@ -479,11 +454,7 @@ void MacroActionSourceEdit::GetSettingsClicked()
void MacroActionSourceEdit::SettingsStringChanged()
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_settingsString =
_settingsString->toPlainText().toStdString();
@@ -493,22 +464,14 @@ void MacroActionSourceEdit::SettingsStringChanged()
void MacroActionSourceEdit::DeinterlaceModeChanged(int idx)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_deinterlaceMode = static_cast<obs_deinterlace_mode>(
_deinterlaceMode->itemData(idx).toInt());
}
void MacroActionSourceEdit::DeinterlaceOrderChanged(int idx)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_deinterlaceOrder =
static_cast<obs_deinterlace_field_order>(
_deinterlaceOrder->itemData(idx).toInt());
@@ -516,21 +479,13 @@ void MacroActionSourceEdit::DeinterlaceOrderChanged(int idx)
void MacroActionSourceEdit::SelectionChanged(const TempVariableRef &var)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_tempVar = var;
}
void MacroActionSourceEdit::SettingsInputMethodChanged(int idx)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_settingsInputMethod =
static_cast<MacroActionSource::SettingsInputMethod>(
_settingsInputMethods->itemData(idx).toInt());
@@ -539,21 +494,13 @@ void MacroActionSourceEdit::SettingsInputMethodChanged(int idx)
void MacroActionSourceEdit::SelectionChanged(const SourceSetting &setting)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_setting = setting;
}
void MacroActionSourceEdit::ManualSettingsValueChanged()
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_manualSettingValue =
_manualSettingValue->toPlainText().toStdString();

View File

@@ -5,7 +5,6 @@
#include "source-selection.hpp"
#include "source-setting.hpp"
#include <QSpinBox>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
@@ -81,7 +80,7 @@ public:
private slots:
void SourceChanged(const SourceSelection &);
void ActionChanged(int value);
void ButtonChanged(int idx);
void ButtonChanged(const SourceSettingButton &);
void GetSettingsClicked();
void SettingsStringChanged();
void DeinterlaceModeChanged(int);
@@ -100,7 +99,7 @@ private:
SourceSelectionWidget *_sources;
QComboBox *_actions;
QComboBox *_settingsButtons;
SourceSettingsButtonSelection *_settingsButtons;
QHBoxLayout *_settingsLayout;
QComboBox *_settingsInputMethods;
VariableTextEdit *_manualSettingValue;

View File

@@ -230,7 +230,7 @@ void MacroActionStreamEdit::UpdateEntryData()
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_keyFrameInterval->SetValue(_entryData->_keyFrameInterval);
_stringValue->setText(_entryData->_stringValue);
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroActionStreamEdit::KeyFrameIntervalChanged(
@@ -252,12 +252,14 @@ void MacroActionStreamEdit::StringValueChanged()
auto lock = LockContext();
_entryData->_stringValue = _stringValue->text().toStdString();
SetWidgetVisiblity();
SetWidgetVisibility();
}
void MacroActionStreamEdit::ShowPassword()
{
SetButtonIcon(_showPassword, ":res/images/visible.svg");
SetButtonIcon(_showPassword, GetThemeTypeName() == "Light"
? ":res/images/visible.svg"
: "theme:Dark/visible.svg");
_stringValue->setEchoMode(QLineEdit::Normal);
}
@@ -267,7 +269,7 @@ void MacroActionStreamEdit::HidePassword()
_stringValue->setEchoMode(QLineEdit::PasswordEchoOnEdit);
}
void MacroActionStreamEdit::SetWidgetVisiblity()
void MacroActionStreamEdit::SetWidgetVisibility()
{
if (!_entryData) {
return;
@@ -310,7 +312,7 @@ void MacroActionStreamEdit::ActionChanged(int value)
static_cast<MacroActionStream::Action>(value);
}
_stringValue->setText(QString(""));
SetWidgetVisiblity();
SetWidgetVisibility();
}
} // namespace advss

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -420,8 +420,9 @@ void MacroConditionFilterEdit::UpdateEntryData()
_regex->SetRegexConfig(_entryData->_regex);
const auto filters =
_entryData->_filter.GetFilters(_entryData->_source);
_settingSelection->SetSource(filters.empty() ? nullptr : filters.at(0));
_settingSelection->SetSetting(_entryData->_setting);
_settingSelection->SetSelection(filters.empty() ? nullptr
: filters.at(0),
_entryData->_setting);
SetWidgetVisibility();
adjustSize();

View File

@@ -0,0 +1,197 @@
#include "macro-condition-game-capture.hpp"
#include "layout-helpers.hpp"
namespace advss {
const std::string MacroConditionGameCapture::id = "game_capture";
#ifdef _WIN32
bool MacroConditionGameCapture::_registered = MacroConditionFactory::Register(
MacroConditionGameCapture::id,
{MacroConditionGameCapture::Create,
MacroConditionGameCaptureEdit::Create,
"AdvSceneSwitcher.condition.gameCapture"});
#else
bool MacroConditionGameCapture::_registered =
false; // For now the 'game_capture' source only exists on Windows
#endif
bool MacroConditionGameCapture::CheckCondition()
{
auto source = OBSGetStrongRef(_source.GetSource());
if (source != _lastSource) {
SetupSignalHandler(source);
return false;
}
std::lock_guard<std::mutex> lock(_mtx);
if (_hooked) {
SetTempVarValue("title", _title);
SetTempVarValue("class", _class);
SetTempVarValue("executable", _executable);
}
return _hooked;
}
bool MacroConditionGameCapture::Save(obs_data_t *obj) const
{
MacroCondition::Save(obj);
_source.Save(obj);
return true;
}
bool MacroConditionGameCapture::Load(obs_data_t *obj)
{
MacroCondition::Load(obj);
_source.Load(obj);
SetupSignalHandler(OBSGetStrongRef(_source.GetSource()));
return true;
}
void MacroConditionGameCapture::GetCalldataInfo(calldata_t *cd)
{
const char *title = "";
if (!calldata_get_string(cd, "title", &title)) {
blog(LOG_WARNING, "%s failed to get title", __func__);
}
_title = title;
const char *className = "";
if (!calldata_get_string(cd, "class", &className)) {
blog(LOG_WARNING, "%s failed to get class", __func__);
}
_class = className;
const char *executable = "";
if (!calldata_get_string(cd, "executable", &executable)) {
blog(LOG_WARNING, "%s failed to get executable", __func__);
}
_executable = executable;
}
void MacroConditionGameCapture::HookedSignalReceived(void *data, calldata_t *cd)
{
auto condition = static_cast<MacroConditionGameCapture *>(data);
std::lock_guard<std::mutex> lock(condition->_mtx);
condition->GetCalldataInfo(cd);
condition->_hooked = true;
}
void MacroConditionGameCapture::UnhookedSignalReceived(void *data, calldata_t *)
{
auto condition = static_cast<MacroConditionGameCapture *>(data);
std::lock_guard<std::mutex> lock(condition->_mtx);
condition->_hooked = false;
}
void MacroConditionGameCapture::SetupTempVars()
{
MacroCondition::SetupTempVars();
AddTempvar(
"title",
obs_module_text("AdvSceneSwitcher.tempVar.gameCapture.title"),
obs_module_text(
"AdvSceneSwitcher.tempVar.gameCapture.title.description"));
AddTempvar(
"class",
obs_module_text("AdvSceneSwitcher.tempVar.gameCapture.class"),
obs_module_text(
"AdvSceneSwitcher.tempVar.gameCapture.class.description"));
AddTempvar(
"executable",
obs_module_text(
"AdvSceneSwitcher.tempVar.gameCapture.executable"),
obs_module_text(
"AdvSceneSwitcher.tempVar.gameCapture.executable.description"));
}
void MacroConditionGameCapture::SetupSignalHandler(obs_source_t *source)
{
signal_handler_t *sh = obs_source_get_signal_handler(source);
_hookSignal = OBSSignal(sh, "hooked", HookedSignalReceived, this);
_unhookSignal = OBSSignal(sh, "unhooked", UnhookedSignalReceived, this);
_lastSource = source;
SetupInitialState(source);
}
void MacroConditionGameCapture::SetupInitialState(obs_source_t *source)
{
std::lock_guard<std::mutex> lock(_mtx);
_hooked = false;
if (!source) {
return;
}
calldata_t cd;
calldata_init(&cd);
auto ph = obs_source_get_proc_handler(source);
if (!proc_handler_call(ph, "get_hooked", &cd)) {
blog(LOG_WARNING,
"%s failed to call proc_handler for 'get_hooked'",
__func__);
return;
}
if (!calldata_get_bool(&cd, "hooked", &_hooked)) {
blog(LOG_WARNING, "%s failed to get hooked state", __func__);
}
GetCalldataInfo(&cd);
calldata_free(&cd);
}
static QStringList getGameCaptureSourceNames()
{
auto sourceEnum = [](void *param, obs_source_t *source) -> bool /* -- */
{
QStringList *list = reinterpret_cast<QStringList *>(param);
if (strcmp(obs_source_get_unversioned_id(source),
"game_capture") == 0) {
*list << obs_source_get_name(source);
}
return true;
};
QStringList list;
obs_enum_sources(sourceEnum, &list);
return list;
}
MacroConditionGameCaptureEdit::MacroConditionGameCaptureEdit(
QWidget *parent, std::shared_ptr<MacroConditionGameCapture> entryData)
: QWidget(parent),
_sources(new SourceSelectionWidget(this, QStringList(), true))
{
auto sources = getGameCaptureSourceNames();
sources.sort();
_sources->SetSourceNameList(sources);
QWidget::connect(_sources,
SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &)));
auto layout = new QHBoxLayout;
PlaceWidgets(
obs_module_text("AdvSceneSwitcher.condition.gameCapture.entry"),
layout, {{"{{sources}}", _sources}});
setLayout(layout);
_entryData = entryData;
UpdateEntryData();
_loading = false;
}
void MacroConditionGameCaptureEdit::SourceChanged(const SourceSelection &source)
{
GUARD_LOADING_AND_LOCK();
_entryData->_source = source;
}
void MacroConditionGameCaptureEdit::UpdateEntryData()
{
_sources->SetSource(_entryData->_source);
}
} // namespace advss

View File

@@ -0,0 +1,74 @@
#pragma once
#include "macro-condition-edit.hpp"
#include "source-selection.hpp"
#include <QWidget>
#include <QComboBox>
namespace advss {
class MacroConditionGameCapture : public MacroCondition {
public:
MacroConditionGameCapture(Macro *m) : MacroCondition(m) {}
bool CheckCondition();
bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj);
std::string GetId() const { return id; };
static std::shared_ptr<MacroCondition> Create(Macro *m)
{
return std::make_shared<MacroConditionGameCapture>(m);
}
SourceSelection _source;
private:
static void HookedSignalReceived(void *data, calldata_t *);
static void UnhookedSignalReceived(void *data, calldata_t *);
void SetupTempVars();
void SetupSignalHandler(obs_source_t *source);
void SetupInitialState(obs_source_t *source);
void GetCalldataInfo(calldata_t *cd);
obs_source_t *_lastSource = nullptr;
OBSSignal _hookSignal;
OBSSignal _unhookSignal;
bool _hooked = false;
std::string _title = "";
std::string _class = "";
std::string _executable = "";
std::mutex _mtx;
static bool _registered;
static const std::string id;
};
class MacroConditionGameCaptureEdit : public QWidget {
Q_OBJECT
public:
MacroConditionGameCaptureEdit(
QWidget *parent,
std::shared_ptr<MacroConditionGameCapture> cond = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroCondition> cond)
{
return new MacroConditionGameCaptureEdit(
parent,
std::dynamic_pointer_cast<MacroConditionGameCapture>(
cond));
}
private slots:
void SourceChanged(const SourceSelection &);
private:
SourceSelectionWidget *_sources;
std::shared_ptr<MacroConditionGameCapture> _entryData;
bool _loading = true;
};
} // namespace advss

View File

@@ -548,14 +548,14 @@ void MacroConditionMedia::MediaNext(void *data, calldata_t *)
void MacroConditionMedia::SetSourceType(SourceType t)
{
SetupTempVars();
_sourceType = t;
SetupTempVars();
}
void MacroConditionMedia::SetCheckType(CheckType t)
{
SetupTempVars();
_checkType = t;
SetupTempVars();
}
static void populateSateSelection(QComboBox *list, bool addLegacyEntries)

View File

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

Some files were not shown because too many files have changed in this diff Show More