Compare commits

...

60 Commits
osx ... 1.21.0

Author SHA1 Message Date
WarmUpTill
2fdd39fba5 Use exprtk lib to evaluate mathematical expressions 2023-04-01 05:37:40 -07:00
WarmUpTill
fe1ddc3a94 Fix connection selection being lost after renaming connection 2023-04-01 05:37:40 -07:00
WarmUpTill
cff2d805db Fix variable selection being lost after renaming variable 2023-04-01 05:37:40 -07:00
WarmUpTill
34425d3e47 CI: minor improvements
* Print checksums in log
* Log if tests were skipped
* Switch to gh-release action version 1
2023-03-27 12:37:08 -07:00
WarmUpTill
4ac4f00620 Fix icons not loading on Linux and MacOS 2023-03-25 16:15:55 -07:00
WarmUpTill
e30a4623c5 Fix HideSelectedMacro() hiding the incorrect index 2023-03-25 15:17:19 -07:00
WarmUpTill
e2f4dcaaee Fix warnings 2023-03-25 15:17:19 -07:00
WarmUpTill
ebbf64ddae Add simple tests 2023-03-25 15:17:19 -07:00
WarmUpTill
8b105ad22b Add support for abs, sin, cos, tan, sqrt function in math expression 2023-03-25 15:17:19 -07:00
WarmUpTill
f3416c5b1d Add option to remove Run or Pause button from macro dock 2023-03-25 12:50:49 -07:00
WarmUpTill
e194fc5ee4 Fix crash when deleting multiple macros in combination with a group 2023-03-25 12:50:49 -07:00
WarmUpTill
e465c81bf1 Fix rename via contenxt menu not updating macro name line edit 2023-03-25 12:50:49 -07:00
WarmUpTill
9dce6a99fd Prevent crashes in case obs_module_text() is called during shutdown 2023-03-25 12:50:49 -07:00
WarmUpTill
6f2c53d14e Add option to create docks of macros
These docks allow to control the pause state and manual execution of the
macro actions
2023-03-25 12:50:49 -07:00
WarmUpTill
9044ae4ade Move OBSDock definition 2023-03-25 12:50:49 -07:00
WarmUpTill
0a422174bc Remove unnecessary cast 2023-03-25 12:50:49 -07:00
WarmUpTill
c2020fe77c Fix crash when selecting new audio source in audio condition 2023-03-24 14:39:41 -07:00
WarmUpTill
8beca6fcc7 Do not allow duplication of groups
Functionality has to be implemented first.
Otherwise visual issues might occur when expanding or collapsing the
new copy of the group entry.
2023-03-24 14:39:41 -07:00
WarmUpTill
18769df2ca Fix duplication of macro not copying references to macros or segments 2023-03-22 11:09:41 -07:00
WarmUpTill
2806fd6cdb Add support for variables in various path selections 2023-03-19 03:52:21 -07:00
WarmUpTill
b607940c8c Add variable support to OpenVR condition 2023-03-19 03:52:21 -07:00
WarmUpTill
dff599df4c Add variable support for scene item order condition
Also cleaned up condition type being defined globally
2023-03-19 03:52:21 -07:00
WarmUpTill
b3cd38e019 Add variable support for OBS stats condition
Also move definition of stat type and condition type into
MacroConditionStats
2023-03-19 03:52:21 -07:00
WarmUpTill
61975e1992 Fix macro list layout margins 2023-03-19 03:52:21 -07:00
WarmUpTill
1a8ad69f23 Add variable support for macro condition spinbox controls 2023-03-19 03:52:21 -07:00
WarmUpTill
f21e40151b Add variable support for cursor condition spinbox controls 2023-03-19 03:52:21 -07:00
WarmUpTill
4e58769648 Fix hotkey action not "holding" down keys for the specified duration 2023-03-19 03:52:21 -07:00
WarmUpTill
f9d6001025 Enable use of variables for hotkey action duration selection 2023-03-19 03:52:21 -07:00
WarmUpTill
ae5f5f90ff Add variable support for audio condition spinbox controls 2023-03-19 03:52:21 -07:00
WarmUpTill
89db21d734 Add variable support for video condition spinbox controls 2023-03-19 03:52:21 -07:00
WarmUpTill
0e4b072650 Add varaible support for audio action spinbox controls 2023-03-19 03:52:21 -07:00
WarmUpTill
13b0e00b27 Add variable support to SliderSpinbox 2023-03-19 03:52:21 -07:00
WarmUpTill
bf5d8ca19e Add option to assign value of math expressions to variable 2023-03-19 03:52:21 -07:00
WarmUpTill
4a3339c09c Add math helpers 2023-03-19 03:52:21 -07:00
WarmUpTill
b28c2b28b2 Adjust to Duration rework 2023-03-19 03:52:21 -07:00
WarmUpTill
fcb3e648d2 Enable use of variables in duration selections 2023-03-19 03:52:21 -07:00
WarmUpTill
5d6f08e38f Adjust to refactor of variable string 2023-03-19 03:52:21 -07:00
WarmUpTill
b932af1c97 Move string and number variables to separate files 2023-03-19 03:52:21 -07:00
WarmUpTill
8874eb2b1c Add widgets that allows using both fixed number values or variables 2023-03-19 03:52:21 -07:00
WarmUpTill
dcf9816a72 Add header support to http action 2023-03-19 03:52:21 -07:00
WarmUpTill
c8722c9f62 Add support for using variables in URL field of http action 2023-03-19 03:52:21 -07:00
WarmUpTill
a82a2ccffe Add option to find and replace strings in current value 2023-03-19 03:52:21 -07:00
WarmUpTill
0bf70e443e Move replaceAll() to utility 2023-03-19 03:52:21 -07:00
WarmUpTill
3d6d690583 Add variable support for custom screenshot path 2023-03-19 03:52:21 -07:00
WarmUpTill
783f76d55d Add support for variables in file FileSelection widget 2023-03-19 03:52:21 -07:00
WarmUpTill
1dd46fb777 Add VariableLineEdit helper 2023-03-19 03:52:21 -07:00
WarmUpTill
22bbd3a4ca Extract argument list to generic string list class and widget
* To be used for http header support
* Add variable support
2023-03-19 03:52:21 -07:00
WarmUpTill
3cd4b2251f CI: Remove zip file from windows installer 2023-03-19 03:51:28 -07:00
WarmUpTill
9e4b003608 Use theme based icons for status dock, group, and duration icon 2023-03-19 03:51:28 -07:00
WarmUpTill
e66d0bc6b8 Rework MacroRef
This should resolve issues of macro names / selections not properly
updating after renaming / grouping / un-grouping macros
2023-03-13 11:30:29 -07:00
WarmUpTill
9a4abd78ed Fix warnings 2023-03-13 11:30:29 -07:00
WarmUpTill
826bee8b1e Enable assigning value of scene item transform to variables 2023-03-11 06:06:18 -08:00
WarmUpTill
143020dc27 Prevent accidental duration changes while scrolling through settings
This was especially problematic with the "cooldown" option of the "Match
behavior" settings on the General tab as accidental changes here could
lead to macros not being executed unexpectedly, which is very hard to
diagnose without inspecting logs.
2023-03-10 13:52:32 -08:00
WarmUpTill
be23065988 Move MouseWheelWidgetAdjustmentGuard 2023-03-10 13:52:32 -08:00
WarmUpTill
2cb62eae96 Enable shrinking the status dock to smaller sizes 2023-03-10 13:52:32 -08:00
WarmUpTill
76c411d1e2 Extract argument list to generic string list class and widget
To be used for http header support.
2023-03-04 13:45:32 -08:00
WarmUpTill
16fa91c2a1 Add "Run" condition
Allows to use external programs as conditions
2023-03-04 13:45:32 -08:00
WarmUpTill
b77f8717fe Move process configuration to separate class and widget 2023-03-04 13:45:32 -08:00
WarmUpTill
59ecf43c5f Enable setting a minimum and initial duration 2023-03-04 13:45:32 -08:00
WarmUpTill
1fd8546354 Improve preview frame visibilty of cursor condition
* Add transparent diagonal stripes to frame
* Do not show frame if invalid selection was made
2023-03-04 13:40:14 -08:00
163 changed files with 65752 additions and 1772 deletions

37
.github/actions/run-tests/action.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: 'Package plugin'
description: 'Packages the plugin for specified architecture and build config.'
inputs:
target:
description: 'Build target'
required: true
workingDirectory:
description: 'Working directory'
required: false
default: ${{ github.workspace }}
runs:
using: 'composite'
steps:
- name: Run macOS tests
if: ${{ runner.os == 'macOS' }}
shell: zsh {0}
run: |
if [[ '${{ inputs.target }}' != 'x86_64' ]]; then
echo tests skipped!
exit 0
fi
${{ inputs.workingDirectory }}/build_x86_64/tests/advanced-scene-switcher-tests
- name: Run Linux packaging
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
if [[ '${{ inputs.target }}' != 'x86_64' ]]; then
exit 0
fi
${{ inputs.workingDirectory }}/build_x86_64/tests/advanced-scene-switcher-tests
- name: Run Windows packaging
if: ${{ runner.os == 'Windows' }}
shell: pwsh
run: |
${{ inputs.workingDirectory }}/build_x64/tests/RelWithDebInfo/advanced-scene-switcher-tests.exe

View File

@@ -155,6 +155,12 @@ jobs:
codesign: 'true' codesign: 'true'
codesignIdent: ${{ env.CODESIGN_IDENT }} codesignIdent: ${{ env.CODESIGN_IDENT }}
- name: Run tests
uses: ./plugin/.github/actions/run-tests
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
- name: Package Plugin - name: Package Plugin
uses: ./plugin/.github/actions/package-plugin uses: ./plugin/.github/actions/package-plugin
with: with:
@@ -250,6 +256,12 @@ jobs:
config: RelWithDebInfo config: RelWithDebInfo
portable: ${{ matrix.portable }} portable: ${{ matrix.portable }}
- name: Run tests
uses: ./plugin/.github/actions/run-tests
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
- name: Package Plugin - name: Package Plugin
uses: ./plugin/.github/actions/package-plugin uses: ./plugin/.github/actions/package-plugin
with: with:
@@ -353,6 +365,12 @@ jobs:
config: RelWithDebInfo config: RelWithDebInfo
visualStudio: 'Visual Studio 17 2022' visualStudio: 'Visual Studio 17 2022'
- name: Run tests
uses: ./plugin/.github/actions/run-tests
with:
workingDirectory: ${{ github.workspace }}/plugin
target: ${{ matrix.arch }}
- name: Package Plugin - name: Package Plugin
uses: ./plugin/.github/actions/package-plugin uses: ./plugin/.github/actions/package-plugin
with: with:
@@ -407,10 +425,11 @@ jobs:
for file in ${{ github.workspace }}/**/@(*.pkg|*.exe|*.deb|*.zip); do for file in ${{ github.workspace }}/**/@(*.pkg|*.exe|*.deb|*.zip); do
echo " ${file##*/}: $(sha256sum "${file}" | cut -d " " -f 1)" >> ${{ github.workspace }}/CHECKSUMS.txt echo " ${file##*/}: $(sha256sum "${file}" | cut -d " " -f 1)" >> ${{ github.workspace }}/CHECKSUMS.txt
done done
cat ${{ github.workspace }}/CHECKSUMS.txt
- name: Create Release - name: Create Release
id: create_release id: create_release
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5 uses: softprops/action-gh-release@v1
with: with:
draft: true draft: true
prerelease: true prerelease: true

View File

@@ -191,6 +191,8 @@ target_sources(
src/macro-core/macro-condition-recording.hpp src/macro-core/macro-condition-recording.hpp
src/macro-core/macro-condition-replay-buffer.cpp src/macro-core/macro-condition-replay-buffer.cpp
src/macro-core/macro-condition-replay-buffer.hpp src/macro-core/macro-condition-replay-buffer.hpp
src/macro-core/macro-condition-run.cpp
src/macro-core/macro-condition-run.hpp
src/macro-core/macro-condition-scene-order.cpp src/macro-core/macro-condition-scene-order.cpp
src/macro-core/macro-condition-scene-order.hpp src/macro-core/macro-condition-scene-order.hpp
src/macro-core/macro-condition-scene-transform.cpp src/macro-core/macro-condition-scene-transform.cpp
@@ -219,6 +221,8 @@ target_sources(
src/macro-core/macro-condition-window.hpp src/macro-core/macro-condition-window.hpp
src/macro-core/macro-condition.cpp src/macro-core/macro-condition.cpp
src/macro-core/macro-condition.hpp src/macro-core/macro-condition.hpp
src/macro-core/macro-dock.cpp
src/macro-core/macro-dock.hpp
src/macro-core/macro-properties.cpp src/macro-core/macro-properties.cpp
src/macro-core/macro-properties.hpp src/macro-core/macro-properties.hpp
src/macro-core/macro-ref.cpp src/macro-core/macro-ref.cpp
@@ -250,8 +254,15 @@ target_sources(
src/utils/file-selection.hpp src/utils/file-selection.hpp
src/utils/macro-list.cpp src/utils/macro-list.cpp
src/utils/macro-list.hpp src/utils/macro-list.hpp
src/utils/math-helpers.cpp
src/utils/math-helpers.hpp
src/utils/mouse-wheel-guard.cpp
src/utils/mouse-wheel-guard.hpp
src/utils/name-dialog.cpp src/utils/name-dialog.cpp
src/utils/name-dialog.hpp src/utils/name-dialog.hpp
src/utils/obs-dock.hpp
src/utils/process-config.cpp
src/utils/process-config.hpp
src/utils/regex-config.cpp src/utils/regex-config.cpp
src/utils/regex-config.hpp src/utils/regex-config.hpp
src/utils/resizing-text-edit.cpp src/utils/resizing-text-edit.cpp
@@ -268,12 +279,24 @@ target_sources(
src/utils/slider-spinbox.hpp src/utils/slider-spinbox.hpp
src/utils/source-selection.cpp src/utils/source-selection.cpp
src/utils/source-selection.hpp src/utils/source-selection.hpp
src/utils/string-list.cpp
src/utils/string-list.hpp
src/utils/striped-frame.cpp
src/utils/striped-frame.hpp
src/utils/transition-selection.cpp src/utils/transition-selection.cpp
src/utils/transition-selection.hpp src/utils/transition-selection.hpp
src/utils/utility.cpp src/utils/utility.cpp
src/utils/utility.hpp src/utils/utility.hpp
src/utils/variable.cpp src/utils/variable.cpp
src/utils/variable.hpp src/utils/variable.hpp
src/utils/variable-line-edit.cpp
src/utils/variable-line-edit.hpp
src/utils/variable-number.tpp
src/utils/variable-number.hpp
src/utils/variable-spinbox.cpp
src/utils/variable-spinbox.hpp
src/utils/variable-string.cpp
src/utils/variable-string.hpp
src/utils/variable-text-edit.cpp src/utils/variable-text-edit.cpp
src/utils/variable-text-edit.hpp src/utils/variable-text-edit.hpp
src/utils/volume-control.cpp src/utils/volume-control.cpp
@@ -320,7 +343,8 @@ target_include_directories(
${LIB_NAME} ${LIB_NAME}
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include" PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/deps/asio/asio/include"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp" "${CMAKE_CURRENT_SOURCE_DIR}/deps/websocketpp"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib") "${CMAKE_CURRENT_SOURCE_DIR}/deps/obs-websocket/lib"
"${CMAKE_CURRENT_SOURCE_DIR}/deps/exprtk")
# --- End of section --- # --- End of section ---
@@ -331,7 +355,8 @@ if(OS_WINDOWS)
target_compile_definitions(${LIB_NAME} PRIVATE UNICODE _UNICODE) target_compile_definitions(${LIB_NAME} PRIVATE UNICODE _UNICODE)
if(MSVC) if(MSVC)
target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267) target_compile_options(${LIB_NAME} PUBLIC /MP /d2FH4- /wd4267 /wd4267
/bigobj)
endif() endif()
target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp) target_sources(${LIB_NAME} PRIVATE src/win/advanced-scene-switcher-win.cpp)
add_definitions(-D_WEBSOCKETPP_CPP11_STL_) add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
@@ -448,3 +473,4 @@ endif()
# --- End of section --- # --- End of section ---
add_subdirectory(src/macro-external) add_subdirectory(src/macro-external)
add_subdirectory(tests)

View File

@@ -25,7 +25,7 @@ DirExistsWarning=no
Name: "english"; MessagesFile: "compiler:Default.isl" Name: "english"; MessagesFile: "compiler:Default.isl"
[Files] [Files]
Source: "..\release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs Source: "..\release\*"; Excludes: "*.zip"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\LICENSE"; Flags: dontcopy Source: "..\LICENSE"; Flags: dontcopy
; NOTE: Don't use "Flags: ignoreversion" on any shared system files ; NOTE: Don't use "Flags: ignoreversion" on any shared system files

View File

@@ -506,7 +506,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Linke Meta-Taste"
AdvSceneSwitcher.action.hotkey.rightMeta="Rechte Meta-Taste" AdvSceneSwitcher.action.hotkey.rightMeta="Rechte Meta-Taste"
AdvSceneSwitcher.action.hotkey.onlyOBS="Tastendruck nur an OBS senden" AdvSceneSwitcher.action.hotkey.onlyOBS="Tastendruck nur an OBS senden"
AdvSceneSwitcher.action.hotkey.disabled="Globale Tastendrücke können nicht simuliert werden - die Funktionalität beschränkt sich auf das Senden von Tastendrücken an OBS!" AdvSceneSwitcher.action.hotkey.disabled="Globale Tastendrücke können nicht simuliert werden - die Funktionalität beschränkt sich auf das Senden von Tastendrücken an OBS!"
AdvSceneSwitcher.action.hotkey.entry="Drücke {{keys}} für {{duration}} Millisekunden" AdvSceneSwitcher.action.hotkey.entry="Drücke {{keys}} für {{duration}}"
AdvSceneSwitcher.action.sceneOrder="Reihenfolge der Szenenelemente" AdvSceneSwitcher.action.sceneOrder="Reihenfolge der Szenenelemente"
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Nach oben verschieben" AdvSceneSwitcher.action.sceneOrder.type.moveUp="Nach oben verschieben"
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Nach unten verschieben" AdvSceneSwitcher.action.sceneOrder.type.moveDown="Nach unten verschieben"
@@ -587,7 +587,7 @@ AdvSceneSwitcher.action.variable.invalidSelection="Ungültige Auswahl!"
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Das Abrufen von Variablenwerten aus %1 Aktionen wird nicht unterstützt!" AdvSceneSwitcher.action.variable.actionNoVariableSupport="Das Abrufen von Variablenwerten aus %1 Aktionen wird nicht unterstützt!"
AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Das Abrufen von Variablenwerten aus %1 Bedingungen wird nicht unterstützt!" AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Das Abrufen von Variablenwerten aus %1 Bedingungen wird nicht unterstützt!"
AdvSceneSwitcher.action.variable.currentSegmentValue="Aktueller Wert:" AdvSceneSwitcher.action.variable.currentSegmentValue="Aktueller Wert:"
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}" AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
; Transition Tab ; Transition Tab

View File

@@ -95,11 +95,19 @@ AdvSceneSwitcher.macroTab.maximize="Maximize"
AdvSceneSwitcher.macroTab.minimize="Minimize" AdvSceneSwitcher.macroTab.minimize="Minimize"
AdvSceneSwitcher.macroTab.highlightSettings="Visual settings" AdvSceneSwitcher.macroTab.highlightSettings="Visual settings"
AdvSceneSwitcher.macroTab.hotkeySettings="Hotkey settings" AdvSceneSwitcher.macroTab.hotkeySettings="Hotkey settings"
AdvSceneSwitcher.macroTab.dockSettings="Dock settings"
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros" AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros"
AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently" AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently"
AdvSceneSwitcher.macroTab.highlightPerformedActions="Highlight recently performed actions of currently selected macro" AdvSceneSwitcher.macroTab.highlightPerformedActions="Highlight recently performed actions of currently selected macro"
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="Register hotkeys to control the pause state of new macros" AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="Register hotkeys to control the pause state of new macros"
AdvSceneSwitcher.macroTab.currentDisableHotkeys="Register hotkeys to control the pause state of selected macro" AdvSceneSwitcher.macroTab.currentDisableHotkeys="Register hotkeys to control the pause state of selected macro"
AdvSceneSwitcher.macroTab.currentRegisterDock="Register dock widget to control the pause state of selected macro or run it manually"
AdvSceneSwitcher.macroTab.currentDockAddRunButton="Add button to run the macro"
AdvSceneSwitcher.macroTab.currentDockAddPauseButton="Add button to pause or unpause the macro"
AdvSceneSwitcher.macroDock.pause="Pause"
AdvSceneSwitcher.macroDock.unpause="Unpause"
AdvSceneSwitcher.macroDock.run="Run"
; Macro List ; Macro List
AdvSceneSwitcher.macroList.deleted="deleted" AdvSceneSwitcher.macroList.deleted="deleted"
@@ -416,6 +424,9 @@ AdvSceneSwitcher.condition.variable.type.equalsVariable="equals variable"
AdvSceneSwitcher.condition.variable.type.lessThanVariable="is less than variable" AdvSceneSwitcher.condition.variable.type.lessThanVariable="is less than variable"
AdvSceneSwitcher.condition.variable.type.greaterThanVariable="is greater than variable" AdvSceneSwitcher.condition.variable.type.greaterThanVariable="is greater than variable"
AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}" AdvSceneSwitcher.condition.variable.entry="{{variables}}{{conditions}}{{strValue}}{{numValue}}{{variables2}}"
AdvSceneSwitcher.condition.run="Run"
AdvSceneSwitcher.condition.run.entry="Process exits before timeout of{{timeout}} seconds"
AdvSceneSwitcher.condition.run.entry.exit="{{checkExitCode}}Check for exit code{{exitCode}}"
; Macro Actions ; Macro Actions
AdvSceneSwitcher.action.switchScene="Switch scene" AdvSceneSwitcher.action.switchScene="Switch scene"
@@ -463,11 +474,6 @@ AdvSceneSwitcher.action.streaming.type.stop="Stop streaming"
AdvSceneSwitcher.action.streaming.type.start="Start streaming" AdvSceneSwitcher.action.streaming.type.start="Start streaming"
AdvSceneSwitcher.action.streaming.entry="{{actions}}" AdvSceneSwitcher.action.streaming.entry="{{actions}}"
AdvSceneSwitcher.action.run="Run" AdvSceneSwitcher.action.run="Run"
AdvSceneSwitcher.action.run.arguments="Arguments:"
AdvSceneSwitcher.action.run.addArgument="Add argument"
AdvSceneSwitcher.action.run.addArgumentDescription="Add new argument:"
AdvSceneSwitcher.action.run.entry="Run {{filePath}}"
AdvSceneSwitcher.action.run.entry.workingDirectory="Working directory:{{workingDirectory}}"
AdvSceneSwitcher.action.sceneVisibility="Scene item visibility" AdvSceneSwitcher.action.sceneVisibility="Scene item visibility"
AdvSceneSwitcher.action.sceneVisibility.type.show="Show" AdvSceneSwitcher.action.sceneVisibility.type.show="Show"
AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide" AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
@@ -529,7 +535,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Left Meta"
AdvSceneSwitcher.action.hotkey.rightMeta="Right Meta" AdvSceneSwitcher.action.hotkey.rightMeta="Right Meta"
AdvSceneSwitcher.action.hotkey.onlyOBS="Send keypress only to OBS" AdvSceneSwitcher.action.hotkey.onlyOBS="Send keypress only to OBS"
AdvSceneSwitcher.action.hotkey.disabled="Cannot simulate global key presses - functionality limited to sending key press to OBS!" AdvSceneSwitcher.action.hotkey.disabled="Cannot simulate global key presses - functionality limited to sending key press to OBS!"
AdvSceneSwitcher.action.hotkey.entry="Press {{keys}} for {{duration}} milliseconds" AdvSceneSwitcher.action.hotkey.entry="Press {{keys}} for {{duration}}"
AdvSceneSwitcher.action.sceneOrder="Scene item order" AdvSceneSwitcher.action.sceneOrder="Scene item order"
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Move up" AdvSceneSwitcher.action.sceneOrder.type.moveUp="Move up"
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down" AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down"
@@ -594,6 +600,9 @@ AdvSceneSwitcher.action.websocket.type.event="Event"
AdvSceneSwitcher.action.websocket.entry.request="Send scene switcher {{type}} via {{connection}}" AdvSceneSwitcher.action.websocket.entry.request="Send scene switcher {{type}} via {{connection}}"
AdvSceneSwitcher.action.websocket.entry.event="Send scene switcher {{type}} to connected clients" AdvSceneSwitcher.action.websocket.entry.event="Send scene switcher {{type}} to connected clients"
AdvSceneSwitcher.action.http="Http" AdvSceneSwitcher.action.http="Http"
AdvSceneSwitcher.action.http.setHeaders="Set headers"
AdvSceneSwitcher.action.http.headers="Headers:"
AdvSceneSwitcher.action.http.addHeader="Add header"
AdvSceneSwitcher.action.http.type.get="GET" AdvSceneSwitcher.action.http.type.get="GET"
AdvSceneSwitcher.action.http.type.post="POST" AdvSceneSwitcher.action.http.type.post="POST"
AdvSceneSwitcher.action.http.entry.line1="Send {{method}} to {{url}}" AdvSceneSwitcher.action.http.entry.line1="Send {{method}} to {{url}}"
@@ -608,15 +617,21 @@ AdvSceneSwitcher.action.variable.type.setActionValue="Set to action value"
AdvSceneSwitcher.action.variable.type.setConditionValue="Set to condition value" AdvSceneSwitcher.action.variable.type.setConditionValue="Set to condition value"
AdvSceneSwitcher.action.variable.type.roundToInt="Round to nearest integer" AdvSceneSwitcher.action.variable.type.roundToInt="Round to nearest integer"
AdvSceneSwitcher.action.variable.type.subString="Set to substring of current value" AdvSceneSwitcher.action.variable.type.subString="Set to substring of current value"
AdvSceneSwitcher.action.variable.type.findAndReplace="Find and replace in current value"
AdvSceneSwitcher.action.variable.type.mathExpression="Mathematical expression"
AdvSceneSwitcher.action.variable.mathExpression.example="( 1 + 2 * 3 ) / 4"
AdvSceneSwitcher.action.variable.findAndReplace.find="Text to find"
AdvSceneSwitcher.action.variable.findAndReplace.replace="Text to replace with"
AdvSceneSwitcher.action.variable.subString.begin="Beginning" AdvSceneSwitcher.action.variable.subString.begin="Beginning"
AdvSceneSwitcher.action.variable.subString.all="All" AdvSceneSwitcher.action.variable.subString.all="All"
AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!" AdvSceneSwitcher.action.variable.invalidSelection="Invalid selection!"
AdvSceneSwitcher.action.variable.actionNoVariableSupport="Getting variable values from %1 actions is not supported!" 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!" AdvSceneSwitcher.action.variable.conditionNoVariableSupport="Getting variable values from %1 conditions is not supported!"
AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:" AdvSceneSwitcher.action.variable.currentSegmentValue="Current value:"
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}" AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}} Substring size:{{subStringSize}}" AdvSceneSwitcher.action.variable.entry.substringIndex="Substring start:{{subStringStart}} Substring size:{{subStringSize}}"
AdvSceneSwitcher.action.variable.entry.substringRegex="Assign value of{{regexMatchIdx}}match using regular expression:" AdvSceneSwitcher.action.variable.entry.substringRegex="Assign value of{{regexMatchIdx}}match using regular expression:"
AdvSceneSwitcher.action.variable.entry.findAndReplace="{{findStr}}{{replaceStr}}"
AdvSceneSwitcher.action.projector="Projector" AdvSceneSwitcher.action.projector="Projector"
AdvSceneSwitcher.action.projector.type.source="Source" AdvSceneSwitcher.action.projector.type.source="Source"
AdvSceneSwitcher.action.projector.type.scene="Scene" AdvSceneSwitcher.action.projector.type.scene="Scene"
@@ -921,6 +936,15 @@ AdvSceneSwitcher.regex.dotMatchNewline=". matches newlines"
AdvSceneSwitcher.regex.multiLine="^ and $ match start/end of line" AdvSceneSwitcher.regex.multiLine="^ and $ match start/end of line"
AdvSceneSwitcher.regex.extendedPattern="Enable Qt's ExtendedPatternSyntax" AdvSceneSwitcher.regex.extendedPattern="Enable Qt's ExtendedPatternSyntax"
AdvSceneSwitcher.process.showAdvanced="Show advanced settings"
AdvSceneSwitcher.process.arguments="Arguments:"
AdvSceneSwitcher.process.addArgument="Add argument"
AdvSceneSwitcher.process.addArgumentDescription="Add new argument:"
AdvSceneSwitcher.process.entry="Run{{filePath}}{{advancedSettings}}"
AdvSceneSwitcher.process.entry.workingDirectory="Working directory:{{workingDirectory}}"
AdvSceneSwitcher.math.expressionFail="Failed evaluate expression"
AdvSceneSwitcher.selectScene="--select scene--" AdvSceneSwitcher.selectScene="--select scene--"
AdvSceneSwitcher.selectPreviousScene="Previous Scene" AdvSceneSwitcher.selectPreviousScene="Previous Scene"
AdvSceneSwitcher.selectCurrentScene="Current Scene" AdvSceneSwitcher.selectCurrentScene="Current Scene"

View File

@@ -422,7 +422,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Meta izquierda"
AdvSceneSwitcher.action.hotkey.rightMeta="Meta derecho" AdvSceneSwitcher.action.hotkey.rightMeta="Meta derecho"
AdvSceneSwitcher.action.hotkey.onlyOBS="Enviar pulsación de tecla solo a OBS" AdvSceneSwitcher.action.hotkey.onlyOBS="Enviar pulsación de tecla solo a OBS"
AdvSceneSwitcher.action.hotkey.disabled="No se puede simular la pulsación de teclas: ¡funcionalidad desactivada!" AdvSceneSwitcher.action.hotkey.disabled="No se puede simular la pulsación de teclas: ¡funcionalidad desactivada!"
AdvSceneSwitcher.action.hotkey.entry="Presione {{keys}} durante {{duration}} milisegundos" AdvSceneSwitcher.action.hotkey.entry="Presione {{keys}} durante {{duration}}"
AdvSceneSwitcher.action.sceneOrder="Orden de elementos de escena" AdvSceneSwitcher.action.sceneOrder="Orden de elementos de escena"
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Mover hacia arriba" AdvSceneSwitcher.action.sceneOrder.type.moveUp="Mover hacia arriba"
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover hacia abajo" AdvSceneSwitcher.action.sceneOrder.type.moveDown="Mover hacia abajo"

View File

@@ -350,7 +350,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="Sol Meta"
AdvSceneSwitcher.action.hotkey.rightMeta="Sağ Meta" AdvSceneSwitcher.action.hotkey.rightMeta="Sağ Meta"
AdvSceneSwitcher.action.hotkey.onlyOBS="Tuşa basımı yalnızca OBS'ye gönder" AdvSceneSwitcher.action.hotkey.onlyOBS="Tuşa basımı yalnızca OBS'ye gönder"
AdvSceneSwitcher.action.hotkey.disabled="Tuşa basma simülasyonu yapılamıyor - işlevsellik devre dışı!" AdvSceneSwitcher.action.hotkey.disabled="Tuşa basma simülasyonu yapılamıyor - işlevsellik devre dışı!"
AdvSceneSwitcher.action.hotkey.entry="Bas {{keys}} uygun {{duration}} millisaniye" AdvSceneSwitcher.action.hotkey.entry="Bas {{keys}} uygun {{duration}}"
AdvSceneSwitcher.action.sceneOrder="Sahne öğesi sırası" AdvSceneSwitcher.action.sceneOrder="Sahne öğesi sırası"
AdvSceneSwitcher.action.sceneOrder.type.moveUp="Yukarı taşı" AdvSceneSwitcher.action.sceneOrder.type.moveUp="Yukarı taşı"
AdvSceneSwitcher.action.sceneOrder.type.moveDown="Aşağı indir" AdvSceneSwitcher.action.sceneOrder.type.moveDown="Aşağı indir"

View File

@@ -467,7 +467,7 @@ AdvSceneSwitcher.action.hotkey.leftMeta="左 Meta"
AdvSceneSwitcher.action.hotkey.rightMeta="右 Meta" AdvSceneSwitcher.action.hotkey.rightMeta="右 Meta"
AdvSceneSwitcher.action.hotkey.onlyOBS="仅向OBS发送按键" AdvSceneSwitcher.action.hotkey.onlyOBS="仅向OBS发送按键"
AdvSceneSwitcher.action.hotkey.disabled="无法模拟按键-功能已禁用!" AdvSceneSwitcher.action.hotkey.disabled="无法模拟按键-功能已禁用!"
AdvSceneSwitcher.action.hotkey.entry="按下 {{keys}} for {{duration}} 毫秒" AdvSceneSwitcher.action.hotkey.entry="按下 {{keys}} for {{duration}}"
AdvSceneSwitcher.action.sceneOrder="场景项目顺序" AdvSceneSwitcher.action.sceneOrder="场景项目顺序"
AdvSceneSwitcher.action.sceneOrder.type.moveUp="上移" AdvSceneSwitcher.action.sceneOrder.type.moveUp="上移"
AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移" AdvSceneSwitcher.action.sceneOrder.type.moveDown="下移"
@@ -541,7 +541,7 @@ AdvSceneSwitcher.action.variable.type.append="追加"
AdvSceneSwitcher.action.variable.type.appendVar="追加变量" AdvSceneSwitcher.action.variable.type.appendVar="追加变量"
AdvSceneSwitcher.action.variable.type.increment="增加" AdvSceneSwitcher.action.variable.type.increment="增加"
AdvSceneSwitcher.action.variable.type.decrement="减少" AdvSceneSwitcher.action.variable.type.decrement="减少"
AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}" AdvSceneSwitcher.action.variable.entry="{{actions}}{{variables}}{{variables2}}{{strValue}}{{numValue}}{{segmentIndex}}{{mathExpression}}"
; Transition Tab ; Transition Tab

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 13.855469 0 l -1.539063 1.4375 c -0.453125 0.421875 -0.53125 1.148438 -0.269531 1.707031 l -5.886719 5.996094 c -0.011718 0 -0.019531 0 -0.03125 0 c -0.257812 -0.128906 -0.550781 -0.183594 -0.839844 -0.148437 c -0.328124 0.046874 -0.632812 0.199218 -0.867187 0.441406 l -3.945313 3.996094 c -0.3906245 0.375 -0.5468745 0.933593 -0.4062495 1.457031 c 0.1406255 0.523437 0.5546875 0.929687 1.0820315 1.058593 c 0.527344 0.132813 1.082031 -0.03125 1.453125 -0.425781 l 3.945312 -3.996093 c 0.472657 -0.453126 0.59375 -1.15625 0.296875 -1.738282 l 5.890625 -5.964844 c 0.558594 0.25 1.273438 0.148438 1.707031 -0.289062 l 1.414063 -1.5625 z m -10.308594 0.0898438 c -0.398437 0 -0.785156 0.0937502 -1.140625 0.2187502 l 1.882812 1.878906 c 0.390626 0.382812 0.390626 1 0 1.386719 l -0.710937 0.707031 c -0.386719 0.386719 -1 0.386719 -1.390625 0 l -1.882812 -1.878906 c -0.125 0.355468 -0.2187505 0.742187 -0.2187505 1.140625 c 0 1.90625 1.5507815 3.453125 3.4609375 3.453125 c 0.402344 0 0.789063 -0.09375 1.144531 -0.21875 l 1.175782 1.171875 h 0.058593 l 2.070313 -2.0625 l -1.203125 -1.203125 c 0.125 -0.359375 0.214843 -0.742188 0.214843 -1.140625 c 0 -1.90625 -1.546874 -3.4531252 -3.460937 -3.4531252 z m 6.550781 7.8906252 l -2.070312 2.066406 c 0.011718 0.027344 0.023437 0.058594 0.03125 0.089844 l 1.144531 1.140625 c -0.125 0.355468 -0.21875 0.742187 -0.21875 1.140625 c 0 1.902343 1.550781 3.449219 3.460937 3.449219 c 0.433594 0 0.855469 -0.101563 1.238282 -0.246094 l -2.007813 -2 c -0.386719 -0.386719 -0.386719 -1.035156 0 -1.417969 l 0.679688 -0.679687 c 0.195312 -0.191407 0.457031 -0.308594 0.710937 -0.308594 s 0.515625 0.117187 0.710938 0.308594 l 1.945312 1.941406 c 0.105469 -0.328125 0.183594 -0.683594 0.183594 -1.046875 c 0 -1.90625 -1.546875 -3.453125 -3.460938 -3.453125 c -0.398437 0 -0.785156 0.09375 -1.140624 0.21875 z m 0 0" fill="#fefefe"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#fefefe">
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8.882812 c 0.832032 0 1.578126 -0.402344 2.054688 -0.9375 c 0.472656 -0.53125 0.738281 -1.167969 0.910156 -1.800781 l 0.972656 -2.609375 c 0.390626 -1.449219 -0.09375 -2.652344 -0.820312 -3.167969 c -0.484375 -0.34375 -0.714844 -0.292969 -1 -0.324219 v -1.160156 c 0 -0.855469 -0.558594 -1.589844 -1.09375 -1.828125 c -0.53125 -0.238281 -1.011719 -0.167969 -1.011719 -0.167969 l 0.105469 -0.003906 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 2.585938 l 1.707031 1.707031 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 h 4 c 0.035156 0 0.070312 -0.003906 0.105469 -0.007812 c 0 0 0.019531 0.019531 -0.011719 0.003906 c -0.035156 -0.011719 -0.09375 -0.25 -0.09375 0.003906 v 2 c 0 0.550781 0.449219 1 1 1 c 1 0 1.046875 0.703125 0.886719 1.128906 l -0.972657 2.609375 c -0.117187 0.4375 -0.296874 0.800781 -0.472656 0.996094 c -0.175781 0.199219 -0.285156 0.265625 -0.558594 0.265625 h -8.882812 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.46875 -0.792969 1 -1 z m 0 0"/>
<path d="m 7 6 l 0.042969 0.003906 c -0.914063 -0.042968 -1.75 0.390625 -2.195313 0.96875 c -0.710937 1.222656 -1.15625 2.277344 -1.800781 3.71875 c -0.171875 0.523438 0.117187 1.089844 0.640625 1.261719 c 0.527344 0.171875 1.09375 -0.117187 1.261719 -0.640625 c 0.488281 -1.011719 0.921875 -1.816406 1.339843 -2.808594 c 0.210938 -0.503906 0.703126 -0.492187 0.898438 -0.503906 h 5.8125 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,3 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#fefefe" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#fefefe" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#fefefe" fill-opacity="1"></use></g></g></g></svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#d2d2d2" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#d2d2d2" fill-opacity="1"></use></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<path d="m 13.855469 0 l -1.539063 1.4375 c -0.453125 0.421875 -0.53125 1.148438 -0.269531 1.707031 l -5.886719 5.996094 c -0.011718 0 -0.019531 0 -0.03125 0 c -0.257812 -0.128906 -0.550781 -0.183594 -0.839844 -0.148437 c -0.328124 0.046874 -0.632812 0.199218 -0.867187 0.441406 l -3.945313 3.996094 c -0.3906245 0.375 -0.5468745 0.933593 -0.4062495 1.457031 c 0.1406255 0.523437 0.5546875 0.929687 1.0820315 1.058593 c 0.527344 0.132813 1.082031 -0.03125 1.453125 -0.425781 l 3.945312 -3.996093 c 0.472657 -0.453126 0.59375 -1.15625 0.296875 -1.738282 l 5.890625 -5.964844 c 0.558594 0.25 1.273438 0.148438 1.707031 -0.289062 l 1.414063 -1.5625 z m -10.308594 0.0898438 c -0.398437 0 -0.785156 0.0937502 -1.140625 0.2187502 l 1.882812 1.878906 c 0.390626 0.382812 0.390626 1 0 1.386719 l -0.710937 0.707031 c -0.386719 0.386719 -1 0.386719 -1.390625 0 l -1.882812 -1.878906 c -0.125 0.355468 -0.2187505 0.742187 -0.2187505 1.140625 c 0 1.90625 1.5507815 3.453125 3.4609375 3.453125 c 0.402344 0 0.789063 -0.09375 1.144531 -0.21875 l 1.175782 1.171875 h 0.058593 l 2.070313 -2.0625 l -1.203125 -1.203125 c 0.125 -0.359375 0.214843 -0.742188 0.214843 -1.140625 c 0 -1.90625 -1.546874 -3.4531252 -3.460937 -3.4531252 z m 6.550781 7.8906252 l -2.070312 2.066406 c 0.011718 0.027344 0.023437 0.058594 0.03125 0.089844 l 1.144531 1.140625 c -0.125 0.355468 -0.21875 0.742187 -0.21875 1.140625 c 0 1.902343 1.550781 3.449219 3.460937 3.449219 c 0.433594 0 0.855469 -0.101563 1.238282 -0.246094 l -2.007813 -2 c -0.386719 -0.386719 -0.386719 -1.035156 0 -1.417969 l 0.679688 -0.679687 c 0.195312 -0.191407 0.457031 -0.308594 0.710937 -0.308594 s 0.515625 0.117187 0.710938 0.308594 l 1.945312 1.941406 c 0.105469 -0.328125 0.183594 -0.683594 0.183594 -1.046875 c 0 -1.90625 -1.546875 -3.453125 -3.460938 -3.453125 c -0.398437 0 -0.785156 0.09375 -1.140624 0.21875 z m 0 0" fill="#202020"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg height="16px" viewBox="0 0 16 16" width="16px" xmlns="http://www.w3.org/2000/svg">
<g fill="#202020">
<path d="m 3 1 c -1.644531 0 -3 1.355469 -3 3 v 8 c 0 1.644531 1.355469 3 3 3 h 8.882812 c 0.832032 0 1.578126 -0.402344 2.054688 -0.9375 c 0.472656 -0.53125 0.738281 -1.167969 0.910156 -1.800781 l 0.972656 -2.609375 c 0.390626 -1.449219 -0.09375 -2.652344 -0.820312 -3.167969 c -0.484375 -0.34375 -0.714844 -0.292969 -1 -0.324219 v -1.160156 c 0 -0.855469 -0.558594 -1.589844 -1.09375 -1.828125 c -0.53125 -0.238281 -1.011719 -0.167969 -1.011719 -0.167969 l 0.105469 -0.003906 h -3.585938 l -1.707031 -1.707031 c -0.1875 -0.1875 -0.441406 -0.292969 -0.707031 -0.292969 z m 0 2 h 2.585938 l 1.707031 1.707031 c 0.1875 0.1875 0.441406 0.292969 0.707031 0.292969 h 4 c 0.035156 0 0.070312 -0.003906 0.105469 -0.007812 c 0 0 0.019531 0.019531 -0.011719 0.003906 c -0.035156 -0.011719 -0.09375 -0.25 -0.09375 0.003906 v 2 c 0 0.550781 0.449219 1 1 1 c 1 0 1.046875 0.703125 0.886719 1.128906 l -0.972657 2.609375 c -0.117187 0.4375 -0.296874 0.800781 -0.472656 0.996094 c -0.175781 0.199219 -0.285156 0.265625 -0.558594 0.265625 h -8.882812 c -0.570312 0 -1 -0.429688 -1 -1 v -8 c 0 -0.570312 0.46875 -0.792969 1 -1 z m 0 0"/>
<path d="m 7 6 l 0.042969 0.003906 c -0.914063 -0.042968 -1.75 0.390625 -2.195313 0.96875 c -0.710937 1.222656 -1.15625 2.277344 -1.800781 3.71875 c -0.171875 0.523438 0.117187 1.089844 0.640625 1.261719 c 0.527344 0.171875 1.09375 -0.117187 1.261719 -0.640625 c 0.488281 -1.011719 0.921875 -1.816406 1.339843 -2.808594 c 0.210938 -0.503906 0.703126 -0.492187 0.898438 -0.503906 h 5.8125 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" height="640"><defs><path d="M599.62 325.49C599.62 477.26 476.41 600.47 324.64 600.47C172.88 600.47 49.67 477.26 49.67 325.49C49.67 173.73 172.88 50.52 324.64 50.52C476.41 50.52 599.62 173.73 599.62 325.49Z" id="c3Wyq0kfYS"></path><mask id="maskanTyyngos" x="-20.33" y="-19.48" width="689.95" height="689.95" maskUnits="userSpaceOnUse"><rect x="-20.33" y="-19.48" width="689.95" height="689.95" fill="white"></rect><use xlink:href="#c3Wyq0kfYS" opacity="1" fill="black"></use></mask><path d="M334.97 96.07C339.51 96.07 343.2 99.75 343.2 104.3C343.2 151.24 343.2 283.84 343.2 330.78C343.2 335.32 339.51 339 334.97 339C329.2 339 320.09 339 314.31 339C309.77 339 306.09 335.32 306.09 330.78C306.09 283.84 306.09 151.24 306.09 104.3C306.09 99.75 309.77 96.07 314.31 96.07C320.09 96.07 329.2 96.07 334.97 96.07Z" id="fxMeu932c"></path><path d="M471.96 338.21C471.97 341.31 469.46 343.83 466.37 343.84C434.35 343.93 343.92 344.21 311.91 344.31C308.81 344.32 306.3 341.82 306.29 338.72C306.27 332.42 306.23 319.13 306.21 312.83C306.2 309.73 308.7 307.21 311.8 307.2C343.81 307.11 434.24 306.83 466.25 306.73C469.35 306.72 471.87 309.23 471.88 312.32C471.9 318.62 471.94 331.91 471.96 338.21Z" id="h65nGmP2BL"></path></defs><g><g><g><g mask="url(#maskanTyyngos)"><use xlink:href="#c3Wyq0kfYS" opacity="1" fill-opacity="0" stroke="#202020" stroke-width="70" stroke-opacity="1"></use></g></g><g><use xlink:href="#fxMeu932c" opacity="1" fill="#202020" fill-opacity="1"></use></g><g><use xlink:href="#h65nGmP2BL" opacity="1" fill="#202020" fill-opacity="1"></use></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

41032
deps/exprtk/exprtk.hpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,9 @@
const char *obs_module_text(const char *text) const char *obs_module_text(const char *text)
{ {
if (!switcher) {
return "";
}
return switcher->translate(text); return switcher->translate(text);
} }

View File

@@ -112,10 +112,8 @@ public slots:
void on_noMatchDontSwitch_clicked(); void on_noMatchDontSwitch_clicked();
void on_noMatchSwitch_clicked(); void on_noMatchSwitch_clicked();
void on_noMatchRandomSwitch_clicked(); void on_noMatchRandomSwitch_clicked();
void NoMatchDelayDurationChanged(double); void NoMatchDelayDurationChanged(const Duration &);
void NoMatchDelayUnitChanged(DurationUnit); void CooldownDurationChanged(const Duration &);
void CooldownDurationChanged(double);
void CooldownUnitChanged(DurationUnit);
void on_startupBehavior_currentIndexChanged(int index); void on_startupBehavior_currentIndexChanged(int index);
void on_autoStartEvent_currentIndexChanged(int index); void on_autoStartEvent_currentIndexChanged(int index);
void on_noMatchSwitchScene_currentTextChanged(const QString &text); void on_noMatchSwitchScene_currentTextChanged(const QString &text);

View File

@@ -60,44 +60,24 @@ void AdvSceneSwitcher::on_noMatchRandomSwitch_clicked()
ui->randomDisabledWarning->setVisible(false); ui->randomDisabledWarning->setVisible(false);
} }
void AdvSceneSwitcher::NoMatchDelayDurationChanged(double sec) void AdvSceneSwitcher::NoMatchDelayDurationChanged(const Duration &dur)
{ {
if (loading) { if (loading) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
switcher->noMatchDelay.seconds = sec; switcher->noMatchDelay = dur;
} }
void AdvSceneSwitcher::NoMatchDelayUnitChanged(DurationUnit unit) void AdvSceneSwitcher::CooldownDurationChanged(const Duration &dur)
{ {
if (loading) { if (loading) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
switcher->noMatchDelay.displayUnit = unit; switcher->cooldown = dur;
}
void AdvSceneSwitcher::CooldownDurationChanged(double sec)
{
if (loading) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
switcher->cooldown.seconds = sec;
}
void AdvSceneSwitcher::CooldownUnitChanged(DurationUnit unit)
{
if (loading) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
switcher->cooldown.displayUnit = unit;
} }
void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index) void AdvSceneSwitcher::on_startupBehavior_currentIndexChanged(int index)
@@ -558,8 +538,8 @@ void SwitcherData::loadSettings(obs_data_t *obj)
// selections to be available. // selections to be available.
loadSceneGroups(obj); loadSceneGroups(obj);
loadVariables(obj); loadVariables(obj);
loadMacros(obj);
loadConnections(obj); loadConnections(obj);
loadMacros(obj);
loadWindowTitleSwitches(obj); loadWindowTitleSwitches(obj);
loadScreenRegionSwitches(obj); loadScreenRegionSwitches(obj);
loadPauseSwitches(obj); loadPauseSwitches(obj);
@@ -622,9 +602,9 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
obs_data_set_string(obj, "non_matching_scene", obs_data_set_string(obj, "non_matching_scene",
nonMatchingSceneName.c_str()); nonMatchingSceneName.c_str());
obs_data_set_int(obj, "switch_if_not_matching", switchIfNotMatching); obs_data_set_int(obj, "switch_if_not_matching", switchIfNotMatching);
noMatchDelay.Save(obj, "noMatchDelay", "noMatchDelayUnit"); noMatchDelay.Save(obj, "noMatchDelay");
cooldown.Save(obj, "cooldown", "cooldownUnit"); cooldown.Save(obj, "cooldown");
obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop); obs_data_set_bool(obj, "active", sceneColletionStop ? true : !stop);
sceneColletionStop = false; sceneColletionStop = false;
@@ -672,9 +652,9 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
std::string nonMatchingSceneName = std::string nonMatchingSceneName =
obs_data_get_string(obj, "non_matching_scene"); obs_data_get_string(obj, "non_matching_scene");
nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str()); nonMatchingScene = GetWeakSourceByName(nonMatchingSceneName.c_str());
noMatchDelay.Load(obj, "noMatchDelay", "noMatchDelayUnit"); noMatchDelay.Load(obj, "noMatchDelay");
cooldown.Load(obj, "cooldown", "cooldownUnit"); cooldown.Load(obj, "cooldown");
stop = !obs_data_get_bool(obj, "active"); stop = !obs_data_get_bool(obj, "active");
startupBehavior = startupBehavior =
@@ -970,10 +950,9 @@ void AdvSceneSwitcher::setupGeneralTab()
noMatchDelay->setToolTip(obs_module_text( noMatchDelay->setToolTip(obs_module_text(
"AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip")); "AdvSceneSwitcher.generalTab.generalBehavior.onNoMetDelayTooltip"));
ui->noMatchLayout->addWidget(noMatchDelay); ui->noMatchLayout->addWidget(noMatchDelay);
QWidget::connect(noMatchDelay, SIGNAL(DurationChanged(double)), this, QWidget::connect(noMatchDelay,
SLOT(NoMatchDelayDurationChanged(double))); SIGNAL(DurationChanged(const Duration &)), this,
QWidget::connect(noMatchDelay, SIGNAL(UnitChanged(DurationUnit)), this, SLOT(NoMatchDelayDurationChanged(const Duration &)));
SLOT(NoMatchDelayUnitChanged(DurationUnit)));
ui->checkInterval->setValue(switcher->interval); ui->checkInterval->setValue(switcher->interval);
@@ -983,10 +962,9 @@ void AdvSceneSwitcher::setupGeneralTab()
"AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint")); "AdvSceneSwitcher.generalTab.generalBehavior.cooldownHint"));
ui->cooldownLayout->addWidget(cooldownTime); ui->cooldownLayout->addWidget(cooldownTime);
ui->cooldownLayout->addStretch(); ui->cooldownLayout->addStretch();
QWidget::connect(cooldownTime, SIGNAL(DurationChanged(double)), this, QWidget::connect(cooldownTime,
SLOT(CooldownDurationChanged(double))); SIGNAL(DurationChanged(const Duration &)), this,
QWidget::connect(cooldownTime, SIGNAL(UnitChanged(DurationUnit)), this, SLOT(CooldownDurationChanged(const Duration &)));
SLOT(CooldownUnitChanged(DurationUnit)));
ui->verboseLogging->setChecked(switcher->verbose); ui->verboseLogging->setChecked(switcher->verbose);
ui->saveWindowGeo->setChecked(switcher->saveWindowGeo); ui->saveWindowGeo->setChecked(switcher->saveWindowGeo);

View File

@@ -156,7 +156,7 @@ void SceneTrigger::logMatch()
blog(LOG_INFO, blog(LOG_INFO,
"scene '%s' in status '%s' triggering action '%s' after %f seconds", "scene '%s' in status '%s' triggering action '%s' after %f seconds",
GetWeakSourceName(scene).c_str(), statusName.c_str(), GetWeakSourceName(scene).c_str(), statusName.c_str(),
actionName.c_str(), duration.seconds); actionName.c_str(), duration.Seconds());
} }
void frontEndActionThread(sceneTriggerAction action, double delay) void frontEndActionThread(sceneTriggerAction action, double delay)
@@ -266,14 +266,14 @@ void SceneTrigger::performAction()
if (isFrontendAction(triggerAction)) { if (isFrontendAction(triggerAction)) {
t = std::thread(frontEndActionThread, triggerAction, t = std::thread(frontEndActionThread, triggerAction,
duration.seconds); duration.Seconds());
} else if (isAudioAction(triggerAction)) { } else if (isAudioAction(triggerAction)) {
bool mute = triggerAction == sceneTriggerAction::MUTE_SOURCE; bool mute = triggerAction == sceneTriggerAction::MUTE_SOURCE;
t = std::thread(muteThread, audioSource, duration.seconds, t = std::thread(muteThread, audioSource, duration.Seconds(),
mute); mute);
} else if (isSwitcherStatusAction(triggerAction)) { } else if (isSwitcherStatusAction(triggerAction)) {
bool stop = triggerAction == sceneTriggerAction::STOP_SWITCHER; bool stop = triggerAction == sceneTriggerAction::STOP_SWITCHER;
t = std::thread(statusThread, duration.seconds, stop); t = std::thread(statusThread, duration.Seconds(), stop);
} else { } else {
blog(LOG_WARNING, "ignoring unknown action '%d'", blog(LOG_WARNING, "ignoring unknown action '%d'",
static_cast<int>(triggerAction)); static_cast<int>(triggerAction));
@@ -460,10 +460,8 @@ SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
SLOT(TriggerTypeChanged(int))); SLOT(TriggerTypeChanged(int)));
QWidget::connect(actions, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(TriggerActionChanged(int))); SLOT(TriggerActionChanged(int)));
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(duration, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DurationUnitChanged(DurationUnit)));
QWidget::connect(audioSources, QWidget::connect(audioSources,
SIGNAL(currentTextChanged(const QString &)), this, SIGNAL(currentTextChanged(const QString &)), this,
SLOT(AudioSourceChanged(const QString &))); SLOT(AudioSourceChanged(const QString &)));
@@ -552,24 +550,14 @@ void SceneTriggerWidget::TriggerActionChanged(int index)
} }
} }
void SceneTriggerWidget::DurationChanged(double seconds) void SceneTriggerWidget::DurationChanged(const Duration &duration)
{ {
if (loading || !switchData) { if (loading || !switchData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
switchData->duration.seconds = seconds; switchData->duration = duration;
}
void SceneTriggerWidget::DurationUnitChanged(DurationUnit unit)
{
if (loading || !switchData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
switchData->duration.displayUnit = unit;
} }
void SceneTriggerWidget::AudioSourceChanged(const QString &text) void SceneTriggerWidget::AudioSourceChanged(const QString &text)

View File

@@ -71,8 +71,7 @@ public:
private slots: private slots:
void TriggerTypeChanged(int index); void TriggerTypeChanged(int index);
void TriggerActionChanged(int index); void TriggerActionChanged(int index);
void DurationChanged(double seconds); void DurationChanged(const Duration &);
void DurationUnitChanged(DurationUnit unit);
void AudioSourceChanged(const QString &text); void AudioSourceChanged(const QString &text);
private: private:

View File

@@ -438,8 +438,8 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
SLOT(VolumeThresholdChanged(int))); SLOT(VolumeThresholdChanged(int)));
QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(condition, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int))); SLOT(ConditionChanged(int)));
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(audioSources, QWidget::connect(audioSources,
SIGNAL(currentTextChanged(const QString &)), this, SIGNAL(currentTextChanged(const QString &)), this,
SLOT(SourceChanged(const QString &))); SLOT(SourceChanged(const QString &)));
@@ -554,14 +554,14 @@ void AudioSwitchWidget::ConditionChanged(int cond)
switchData->condition = (audioCondition)cond; switchData->condition = (audioCondition)cond;
} }
void AudioSwitchWidget::DurationChanged(double sec) void AudioSwitchWidget::DurationChanged(const Duration &dur)
{ {
if (loading || !switchData) { if (loading || !switchData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
switchData->duration.seconds = sec; switchData->duration = dur;
} }
void AudioSwitchWidget::IgnoreInactiveChanged(int state) void AudioSwitchWidget::IgnoreInactiveChanged(int state)
@@ -580,8 +580,8 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
{ {
duration = new DurationSelection(this, false); duration = new DurationSelection(this, false);
QWidget::connect(duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
if (s) { if (s) {
duration->SetDuration(s->duration); duration->SetDuration(s->duration);
@@ -602,12 +602,12 @@ AudioSwitchFallbackWidget::AudioSwitchFallbackWidget(QWidget *parent,
loading = false; loading = false;
} }
void AudioSwitchFallbackWidget::DurationChanged(double sec) void AudioSwitchFallbackWidget::DurationChanged(const Duration &dur)
{ {
if (loading || !switchData) { if (loading || !switchData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
switchData->duration.seconds = sec; switchData->duration = dur;
} }

View File

@@ -75,7 +75,7 @@ private slots:
void SourceChanged(const QString &text); void SourceChanged(const QString &text);
void VolumeThresholdChanged(int vol); void VolumeThresholdChanged(int vol);
void ConditionChanged(int cond); void ConditionChanged(int cond);
void DurationChanged(double dur); void DurationChanged(const Duration &);
void IgnoreInactiveChanged(int state); void IgnoreInactiveChanged(int state);
private: private:
@@ -96,7 +96,7 @@ public:
AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s); AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s);
private slots: private slots:
void DurationChanged(double dur); void DurationChanged(const Duration &dur);
private: private:
DurationSelection *duration; DurationSelection *duration;

View File

@@ -455,7 +455,7 @@ bool SceneSequenceSwitch::checkDurationMatchInterruptible()
void SceneSequenceSwitch::prepareUninterruptibleMatch(int &linger) void SceneSequenceSwitch::prepareUninterruptibleMatch(int &linger)
{ {
int dur = delay.seconds * 1000; int dur = delay.Milliseconds();
if (dur > 0) { if (dur > 0) {
linger = dur; linger = dur;
} }
@@ -588,10 +588,8 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)), QWidget::connect(scenes, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SceneChanged(const QString &))); this, SLOT(SceneChanged(const QString &)));
QWidget::connect(delay, SIGNAL(DurationChanged(double)), this, QWidget::connect(delay, SIGNAL(DurationChanged(const Duration &)), this,
SLOT(DelayChanged(double))); SLOT(DelayChanged(const Duration &)));
QWidget::connect(delay, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DelayUnitsChanged(DurationUnit)));
QWidget::connect(startScenes, QWidget::connect(startScenes,
SIGNAL(currentTextChanged(const QString &)), this, SIGNAL(currentTextChanged(const QString &)), this,
SLOT(StartSceneChanged(const QString &))); SLOT(StartSceneChanged(const QString &)));
@@ -689,24 +687,14 @@ void SequenceWidget::swapSwitchData(SequenceWidget *s1, SequenceWidget *s2)
s2->setSwitchData(t); s2->setSwitchData(t);
} }
void SequenceWidget::DelayChanged(double sec) void SequenceWidget::DelayChanged(const Duration &delay)
{ {
if (loading || !switchData) { if (loading || !switchData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
switchData->delay.seconds = sec; switchData->delay = delay;
}
void SequenceWidget::DelayUnitsChanged(DurationUnit unit)
{
if (loading || !switchData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
switchData->delay.displayUnit = unit;
} }
void SequenceWidget::setExtendedSequenceStartScene() void SequenceWidget::setExtendedSequenceStartScene()

View File

@@ -59,8 +59,7 @@ public:
private slots: private slots:
void SceneChanged(const QString &text); void SceneChanged(const QString &text);
void DelayChanged(double delay); void DelayChanged(const Duration &delay);
void DelayUnitsChanged(DurationUnit);
void StartSceneChanged(const QString &text); void StartSceneChanged(const QString &text);
void InterruptibleChanged(int state); void InterruptibleChanged(int state);
void ExtendClicked(); void ExtendClicked();

View File

@@ -114,7 +114,7 @@ void MacroActionAudio::FadeVolume()
int nrSteps = 0; int nrSteps = 0;
float volStep = 0.; float volStep = 0.;
if (_fadeType == FadeType::DURATION) { if (_fadeType == FadeType::DURATION) {
nrSteps = _duration.seconds * 1000 / fadeInterval.count(); nrSteps = _duration.Milliseconds() / fadeInterval.count();
volStep = volDiff / nrSteps; volStep = volDiff / nrSteps;
} else { } else {
volStep = _rate / 1000.0f; volStep = _rate / 1000.0f;
@@ -212,7 +212,7 @@ void MacroActionAudio::LogAction() const
vblog(LOG_INFO, vblog(LOG_INFO,
"performed action \"%s\" for source \"%s\" with volume %d with fade %d %f", "performed action \"%s\" for source \"%s\" with volume %d with fade %d %f",
it->second.c_str(), _audioSource.ToString(true).c_str(), it->second.c_str(), _audioSource.ToString(true).c_str(),
_volume, _fade, _duration.seconds); _volume.GetValue(), _fade, _duration.Seconds());
} else { } else {
blog(LOG_WARNING, "ignored unknown audio action %d", blog(LOG_WARNING, "ignored unknown audio action %d",
static_cast<int>(_action)); static_cast<int>(_action));
@@ -225,15 +225,16 @@ bool MacroActionAudio::Save(obs_data_t *obj) const
_duration.Save(obj); _duration.Save(obj);
_audioSource.Save(obj, "audioSource"); _audioSource.Save(obj, "audioSource");
obs_data_set_int(obj, "action", static_cast<int>(_action)); obs_data_set_int(obj, "action", static_cast<int>(_action));
obs_data_set_int(obj, "syncOffset", _syncOffset);
obs_data_set_int(obj, "monitor", _monitorType); obs_data_set_int(obj, "monitor", _monitorType);
obs_data_set_double(obj, "balance", _balance); _syncOffset.Save(obj, "syncOffset");
obs_data_set_int(obj, "volume", _volume); _balance.Save(obj, "balance");
obs_data_set_double(obj, "rate", _rate); _volume.Save(obj, "volume");
_rate.Save(obj, "rate");
obs_data_set_bool(obj, "fade", _fade); obs_data_set_bool(obj, "fade", _fade);
obs_data_set_int(obj, "fadeType", static_cast<int>(_fadeType)); obs_data_set_int(obj, "fadeType", static_cast<int>(_fadeType));
obs_data_set_bool(obj, "wait", _wait); obs_data_set_bool(obj, "wait", _wait);
obs_data_set_bool(obj, "abortActiveFade", _abortActiveFade); obs_data_set_bool(obj, "abortActiveFade", _abortActiveFade);
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -243,12 +244,19 @@ bool MacroActionAudio::Load(obs_data_t *obj)
_duration.Load(obj); _duration.Load(obj);
_audioSource.Load(obj, "audioSource"); _audioSource.Load(obj, "audioSource");
_action = static_cast<Action>(obs_data_get_int(obj, "action")); _action = static_cast<Action>(obs_data_get_int(obj, "action"));
_syncOffset = obs_data_get_int(obj, "syncOffset");
_monitorType = static_cast<obs_monitoring_type>( _monitorType = static_cast<obs_monitoring_type>(
obs_data_get_int(obj, "monitor")); obs_data_get_int(obj, "monitor"));
_balance = obs_data_get_double(obj, "balance"); if (!obs_data_has_user_value(obj, "version")) {
_volume = obs_data_get_int(obj, "volume"); _syncOffset = obs_data_get_int(obj, "syncOffset");
_rate = obs_data_get_double(obj, "rate"); _balance = obs_data_get_double(obj, "balance");
_volume = obs_data_get_int(obj, "volume");
_rate = obs_data_get_double(obj, "rate");
} else {
_syncOffset.Load(obj, "syncOffset");
_balance.Load(obj, "balance");
_volume.Load(obj, "volume");
_rate.Load(obj, "rate");
}
_fade = obs_data_get_bool(obj, "fade"); _fade = obs_data_get_bool(obj, "fade");
if (obs_data_has_user_value(obj, "wait")) { if (obs_data_has_user_value(obj, "wait")) {
_wait = obs_data_get_bool(obj, "wait"); _wait = obs_data_get_bool(obj, "wait");
@@ -302,16 +310,16 @@ MacroActionAudioEdit::MacroActionAudioEdit(
_sources(new SourceSelectionWidget(this, QStringList(), true)), _sources(new SourceSelectionWidget(this, QStringList(), true)),
_actions(new QComboBox), _actions(new QComboBox),
_fadeTypes(new QComboBox), _fadeTypes(new QComboBox),
_syncOffset(new QSpinBox), _syncOffset(new VariableSpinBox),
_monitorTypes(new QComboBox), _monitorTypes(new QComboBox),
_balance(new SliderSpinBox( _balance(new SliderSpinBox(
0., 1., "", 0., 1., "",
obs_module_text( obs_module_text(
"AdvSceneSwitcher.action.audio.balance.description"))), "AdvSceneSwitcher.action.audio.balance.description"))),
_volumePercent(new QSpinBox), _volumePercent(new VariableSpinBox),
_fade(new QCheckBox), _fade(new QCheckBox),
_duration(new DurationSelection(parent, false)), _duration(new DurationSelection(parent, false)),
_rate(new QDoubleSpinBox), _rate(new VariableDoubleSpinBox),
_wait(new QCheckBox( _wait(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.audio.fade.wait"))), obs_module_text("AdvSceneSwitcher.action.audio.fade.wait"))),
_abortActiveFade(new QCheckBox( _abortActiveFade(new QCheckBox(
@@ -343,20 +351,28 @@ MacroActionAudioEdit::MacroActionAudioEdit(
QWidget::connect(_sources, QWidget::connect(_sources,
SIGNAL(SourceChanged(const SourceSelection &)), this, SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &))); SLOT(SourceChanged(const SourceSelection &)));
QWidget::connect(_syncOffset, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(SyncOffsetChanged(int))); _syncOffset,
QWidget::connect(_balance, SIGNAL(DoubleValueChanged(double)), this, SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
SLOT(BalanceChanged(double))); this, SLOT(SyncOffsetChanged(const NumberVariable<int> &)));
QWidget::connect(
_balance,
SIGNAL(DoubleValueChanged(const NumberVariable<double> &)),
this, SLOT(BalanceChanged(const NumberVariable<double> &)));
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(MonitorTypeChanged(int))); SLOT(MonitorTypeChanged(int)));
QWidget::connect(_volumePercent, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(VolumeChanged(int))); _volumePercent,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(VolumeChanged(const NumberVariable<int> &)));
QWidget::connect(_fade, SIGNAL(stateChanged(int)), this, QWidget::connect(_fade, SIGNAL(stateChanged(int)), this,
SLOT(FadeChanged(int))); SLOT(FadeChanged(int)));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_rate, SIGNAL(valueChanged(double)), this, QWidget::connect(
SLOT(RateChanged(double))); _rate,
SIGNAL(NumberVariableChanged(const NumberVariable<double> &)),
this, SLOT(RateChanged(const NumberVariable<double> &)));
QWidget::connect(_wait, SIGNAL(stateChanged(int)), this, QWidget::connect(_wait, SIGNAL(stateChanged(int)), this,
SLOT(WaitChanged(int))); SLOT(WaitChanged(int)));
QWidget::connect(_abortActiveFade, SIGNAL(stateChanged(int)), this, QWidget::connect(_abortActiveFade, SIGNAL(stateChanged(int)), this,
@@ -468,13 +484,13 @@ void MacroActionAudioEdit::UpdateEntryData()
_sources->SetSource(_entryData->_audioSource); _sources->SetSource(_entryData->_audioSource);
_actions->setCurrentIndex( _actions->setCurrentIndex(
_actions->findData(static_cast<int>(_entryData->_action))); _actions->findData(static_cast<int>(_entryData->_action)));
_syncOffset->setValue(_entryData->_syncOffset); _syncOffset->SetValue(_entryData->_syncOffset);
_monitorTypes->setCurrentIndex(_entryData->_monitorType); _monitorTypes->setCurrentIndex(_entryData->_monitorType);
_balance->SetDoubleValue(_entryData->_balance); _balance->SetDoubleValue(_entryData->_balance);
_volumePercent->setValue(_entryData->_volume); _volumePercent->SetValue(_entryData->_volume);
_fade->setChecked(_entryData->_fade); _fade->setChecked(_entryData->_fade);
_duration->SetDuration(_entryData->_duration); _duration->SetDuration(_entryData->_duration);
_rate->setValue(_entryData->_rate); _rate->SetValue(_entryData->_rate);
_wait->setChecked(_entryData->_wait); _wait->setChecked(_entryData->_wait);
_abortActiveFade->setChecked(_entryData->_abortActiveFade); _abortActiveFade->setChecked(_entryData->_abortActiveFade);
_fadeTypes->setCurrentIndex(static_cast<int>(_entryData->_fadeType)); _fadeTypes->setCurrentIndex(static_cast<int>(_entryData->_fadeType));
@@ -505,7 +521,7 @@ void MacroActionAudioEdit::ActionChanged(int idx)
SetWidgetVisibility(); SetWidgetVisibility();
} }
void MacroActionAudioEdit::SyncOffsetChanged(int value) void MacroActionAudioEdit::SyncOffsetChanged(const NumberVariable<int> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -525,7 +541,7 @@ void MacroActionAudioEdit::MonitorTypeChanged(int value)
_entryData->_monitorType = static_cast<obs_monitoring_type>(value); _entryData->_monitorType = static_cast<obs_monitoring_type>(value);
} }
void MacroActionAudioEdit::BalanceChanged(double value) void MacroActionAudioEdit::BalanceChanged(const NumberVariable<double> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -535,7 +551,7 @@ void MacroActionAudioEdit::BalanceChanged(double value)
_entryData->_balance = value; _entryData->_balance = value;
} }
void MacroActionAudioEdit::VolumeChanged(int value) void MacroActionAudioEdit::VolumeChanged(const NumberVariable<int> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -556,17 +572,17 @@ void MacroActionAudioEdit::FadeChanged(int value)
SetWidgetVisibility(); SetWidgetVisibility();
} }
void MacroActionAudioEdit::DurationChanged(double seconds) void MacroActionAudioEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
} }
void MacroActionAudioEdit::RateChanged(double value) void MacroActionAudioEdit::RateChanged(const NumberVariable<double> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;

View File

@@ -42,13 +42,13 @@ public:
Action _action = Action::MUTE; Action _action = Action::MUTE;
FadeType _fadeType = FadeType::DURATION; FadeType _fadeType = FadeType::DURATION;
int64_t _syncOffset = 0; NumberVariable<int> _syncOffset = 0;
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE; obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
double _balance = 0.5; NumberVariable<double> _balance = 0.5;
int _volume = 0; NumberVariable<int> _volume = 0;
bool _fade = false; bool _fade = false;
Duration _duration; Duration _duration;
double _rate = 100.; NumberVariable<double> _rate = 100.;
bool _wait = false; bool _wait = false;
bool _abortActiveFade = false; bool _abortActiveFade = false;
@@ -84,13 +84,13 @@ public:
private slots: private slots:
void SourceChanged(const SourceSelection &); void SourceChanged(const SourceSelection &);
void ActionChanged(int value); void ActionChanged(int value);
void SyncOffsetChanged(int value); void SyncOffsetChanged(const NumberVariable<int> &value);
void MonitorTypeChanged(int value); void MonitorTypeChanged(int value);
void BalanceChanged(double value); void BalanceChanged(const NumberVariable<double> &value);
void VolumeChanged(int value); void VolumeChanged(const NumberVariable<int> &value);
void FadeChanged(int value); void FadeChanged(int value);
void DurationChanged(double seconds); void DurationChanged(const Duration &seconds);
void RateChanged(double value); void RateChanged(const NumberVariable<double> &value);
void WaitChanged(int value); void WaitChanged(int value);
void AbortActiveFadeChanged(int value); void AbortActiveFadeChanged(int value);
void FadeTypeChanged(int value); void FadeTypeChanged(int value);
@@ -101,13 +101,13 @@ protected:
SourceSelectionWidget *_sources; SourceSelectionWidget *_sources;
QComboBox *_actions; QComboBox *_actions;
QComboBox *_fadeTypes; QComboBox *_fadeTypes;
QSpinBox *_syncOffset; VariableSpinBox *_syncOffset;
QComboBox *_monitorTypes; QComboBox *_monitorTypes;
SliderSpinBox *_balance; SliderSpinBox *_balance;
QSpinBox *_volumePercent; VariableSpinBox *_volumePercent;
QCheckBox *_fade; QCheckBox *_fade;
DurationSelection *_duration; DurationSelection *_duration;
QDoubleSpinBox *_rate; VariableDoubleSpinBox *_rate;
QCheckBox *_wait; QCheckBox *_wait;
QCheckBox *_abortActiveFade; QCheckBox *_abortActiveFade;
QHBoxLayout *_fadeTypeLayout; QHBoxLayout *_fadeTypeLayout;

View File

@@ -55,7 +55,7 @@ void MacroActionFile::LogAction() const
bool MacroActionFile::Save(obs_data_t *obj) const bool MacroActionFile::Save(obs_data_t *obj) const
{ {
MacroAction::Save(obj); MacroAction::Save(obj);
obs_data_set_string(obj, "file", _file.c_str()); _file.Save(obj, "file");
_text.Save(obj, "text"); _text.Save(obj, "text");
obs_data_set_int(obj, "action", static_cast<int>(_action)); obs_data_set_int(obj, "action", static_cast<int>(_action));
return true; return true;
@@ -64,7 +64,7 @@ bool MacroActionFile::Save(obs_data_t *obj) const
bool MacroActionFile::Load(obs_data_t *obj) bool MacroActionFile::Load(obs_data_t *obj)
{ {
MacroAction::Load(obj); MacroAction::Load(obj);
_file = obs_data_get_string(obj, "file"); _file.Load(obj, "file");
_text.Load(obj, "text"); _text.Load(obj, "text");
_action = static_cast<FileAction>(obs_data_get_int(obj, "action")); _action = static_cast<FileAction>(obs_data_get_int(obj, "action"));
return true; return true;
@@ -72,7 +72,7 @@ bool MacroActionFile::Load(obs_data_t *obj)
std::string MacroActionFile::GetShortDesc() const std::string MacroActionFile::GetShortDesc() const
{ {
return _file; return _file.UnresolvedValue();
} }
static inline void populateActionSelection(QComboBox *list) static inline void populateActionSelection(QComboBox *list)

View File

@@ -24,9 +24,8 @@ public:
return std::make_shared<MacroActionFile>(m); return std::make_shared<MacroActionFile>(m);
} }
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath"); StringVariable _file = obs_module_text("AdvSceneSwitcher.enterPath");
VariableResolvingString _text = StringVariable _text = obs_module_text("AdvSceneSwitcher.enterText");
obs_module_text("AdvSceneSwitcher.enterText");
FileAction _action = FileAction::WRITE; FileAction _action = FileAction::WRITE;
private: private:

View File

@@ -30,7 +30,7 @@ public:
SourceSelection _source; SourceSelection _source;
OBSWeakSource _filter; OBSWeakSource _filter;
Action _action = Action::ENABLE; Action _action = Action::ENABLE;
VariableResolvingString _settings = ""; StringVariable _settings = "";
private: private:
void ResolveVariables(); void ResolveVariables();

View File

@@ -224,7 +224,7 @@ bool MacroActionHotkey::PerformAction()
} }
if (!keys.empty()) { if (!keys.empty()) {
int dur = _duration; int dur = _duration.Milliseconds();
if (_onlySendToObs || !canSimulateKeyPresses) { if (_onlySendToObs || !canSimulateKeyPresses) {
std::thread t([keys, dur]() { InjectKeys(keys, dur); }); std::thread t([keys, dur]() { InjectKeys(keys, dur); });
t.detach(); t.detach();
@@ -254,8 +254,9 @@ bool MacroActionHotkey::Save(obs_data_t *obj) const
obs_data_set_bool(obj, "right_alt", _rightAlt); obs_data_set_bool(obj, "right_alt", _rightAlt);
obs_data_set_bool(obj, "left_meta", _leftMeta); obs_data_set_bool(obj, "left_meta", _leftMeta);
obs_data_set_bool(obj, "right_meta", _rightMeta); obs_data_set_bool(obj, "right_meta", _rightMeta);
obs_data_set_int(obj, "duration", _duration); _duration.Save(obj);
obs_data_set_bool(obj, "onlyOBS", _onlySendToObs); obs_data_set_bool(obj, "onlyOBS", _onlySendToObs);
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -271,7 +272,11 @@ bool MacroActionHotkey::Load(obs_data_t *obj)
_rightAlt = obs_data_get_bool(obj, "right_alt"); _rightAlt = obs_data_get_bool(obj, "right_alt");
_leftMeta = obs_data_get_bool(obj, "left_meta"); _leftMeta = obs_data_get_bool(obj, "left_meta");
_rightMeta = obs_data_get_bool(obj, "right_meta"); _rightMeta = obs_data_get_bool(obj, "right_meta");
_duration = obs_data_get_int(obj, "duration"); if (!obs_data_has_user_value(obj, "version")) {
_duration = obs_data_get_int(obj, "duration") / 1000.0;
} else {
_duration.Load(obj);
}
_onlySendToObs = obs_data_get_bool(obj, "onlyOBS"); _onlySendToObs = obs_data_get_bool(obj, "onlyOBS");
return true; return true;
} }
@@ -388,32 +393,30 @@ static inline void populateKeySelection(QComboBox *list)
MacroActionHotkeyEdit::MacroActionHotkeyEdit( MacroActionHotkeyEdit::MacroActionHotkeyEdit(
QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData) QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData)
: QWidget(parent) : QWidget(parent),
_keys(new QComboBox()),
_leftShift(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"))),
_rightShift(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.action.hotkey.rightShift"))),
_leftCtrl(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftCtrl"))),
_rightCtrl(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.rightCtrl"))),
_leftAlt(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftAlt"))),
_rightAlt(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.rightAlt"))),
_leftMeta(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftMeta"))),
_rightMeta(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.rightMeta"))),
_duration(new DurationSelection(this, false)),
_onlySendToOBS(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.onlyOBS"))),
_noKeyPressSimulationWarning(new QLabel(
obs_module_text("AdvSceneSwitcher.action.hotkey.disabled")))
{ {
_keys = new QComboBox();
_leftShift = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"));
_rightShift = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.rightShift"));
_leftCtrl = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftCtrl"));
_rightCtrl = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.rightCtrl"));
_leftAlt = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftAlt"));
_rightAlt = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.rightAlt"));
_leftMeta = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftMeta"));
_rightMeta = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.rightMeta"));
_duration = new QSpinBox();
_duration->setMaximum(5000);
_onlySendToOBS = new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.onlyOBS"));
_noKeyPressSimulationWarning = new QLabel(
obs_module_text("AdvSceneSwitcher.action.hotkey.disabled"));
populateKeySelection(_keys); populateKeySelection(_keys);
QWidget::connect(_keys, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_keys, SIGNAL(currentIndexChanged(int)), this,
@@ -434,8 +437,8 @@ MacroActionHotkeyEdit::MacroActionHotkeyEdit(
SLOT(LMetaChanged(int))); SLOT(LMetaChanged(int)));
QWidget::connect(_rightMeta, SIGNAL(stateChanged(int)), this, QWidget::connect(_rightMeta, SIGNAL(stateChanged(int)), this,
SLOT(RMetaChanged(int))); SLOT(RMetaChanged(int)));
QWidget::connect(_duration, SIGNAL(valueChanged(int)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(int))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_onlySendToOBS, SIGNAL(stateChanged(int)), this, QWidget::connect(_onlySendToOBS, SIGNAL(stateChanged(int)), this,
SLOT(OnlySendToOBSChanged(int))); SLOT(OnlySendToOBSChanged(int)));
@@ -493,7 +496,7 @@ void MacroActionHotkeyEdit::UpdateEntryData()
_rightAlt->setChecked(_entryData->_rightAlt); _rightAlt->setChecked(_entryData->_rightAlt);
_leftMeta->setChecked(_entryData->_leftMeta); _leftMeta->setChecked(_entryData->_leftMeta);
_rightMeta->setChecked(_entryData->_rightMeta); _rightMeta->setChecked(_entryData->_rightMeta);
_duration->setValue(_entryData->_duration); _duration->SetDuration(_entryData->_duration);
_onlySendToOBS->setChecked(_entryData->_onlySendToObs || _onlySendToOBS->setChecked(_entryData->_onlySendToObs ||
!canSimulateKeyPresses); !canSimulateKeyPresses);
SetWarningVisibility(); SetWarningVisibility();
@@ -579,14 +582,14 @@ void MacroActionHotkeyEdit::RMetaChanged(int state)
_entryData->_rightMeta = state; _entryData->_rightMeta = state;
} }
void MacroActionHotkeyEdit::DurationChanged(int ms) void MacroActionHotkeyEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration = ms; _entryData->_duration = dur;
} }
void MacroActionHotkeyEdit::OnlySendToOBSChanged(int state) void MacroActionHotkeyEdit::OnlySendToOBSChanged(int state)

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "macro-action-edit.hpp" #include "macro-action-edit.hpp"
#include "hotkey.hpp" #include "hotkey.hpp"
#include "duration-control.hpp"
#include <QComboBox> #include <QComboBox>
#include <QCheckBox> #include <QCheckBox>
@@ -30,7 +31,7 @@ public:
bool _rightAlt = false; bool _rightAlt = false;
bool _leftMeta = false; bool _leftMeta = false;
bool _rightMeta = false; bool _rightMeta = false;
int _duration = 300; // in ms Duration _duration = 0.3;
#ifdef __APPLE__ #ifdef __APPLE__
bool _onlySendToObs = true; bool _onlySendToObs = true;
#else #else
@@ -68,7 +69,7 @@ private slots:
void RAltChanged(int state); void RAltChanged(int state);
void LMetaChanged(int state); void LMetaChanged(int state);
void RMetaChanged(int state); void RMetaChanged(int state);
void DurationChanged(int ms); void DurationChanged(const Duration &);
void OnlySendToOBSChanged(int state); void OnlySendToOBSChanged(int state);
protected: protected:
@@ -81,7 +82,7 @@ protected:
QCheckBox *_rightAlt; QCheckBox *_rightAlt;
QCheckBox *_leftMeta; QCheckBox *_leftMeta;
QCheckBox *_rightMeta; QCheckBox *_rightMeta;
QSpinBox *_duration; DurationSelection *_duration;
QCheckBox *_onlySendToOBS; QCheckBox *_onlySendToOBS;
QLabel *_noKeyPressSimulationWarning; QLabel *_noKeyPressSimulationWarning;

View File

@@ -27,11 +27,26 @@ size_t WriteCB(void *ptr, size_t size, size_t nmemb, std::string *buffer)
return size * nmemb; return size * nmemb;
} }
void MacroActionHttp::SetupHeaders()
{
if (!_setHeaders) {
return;
}
struct curl_slist *headers = nullptr;
for (auto &header : _headers) {
headers = switcher->curl.SlistAppend(headers, header.c_str());
}
if (!_headers.empty()) {
switcher->curl.SetOpt(CURLOPT_HTTPHEADER, headers);
}
}
void MacroActionHttp::Get() void MacroActionHttp::Get()
{ {
switcher->curl.SetOpt(CURLOPT_URL, _url.c_str()); switcher->curl.SetOpt(CURLOPT_URL, _url.c_str());
switcher->curl.SetOpt(CURLOPT_HTTPGET, 1L); switcher->curl.SetOpt(CURLOPT_HTTPGET, 1L);
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.seconds * 1000); switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds());
SetupHeaders();
std::string response; std::string response;
if (IsReferencedInVars()) { if (IsReferencedInVars()) {
@@ -49,7 +64,8 @@ void MacroActionHttp::Post()
{ {
switcher->curl.SetOpt(CURLOPT_URL, _url.c_str()); switcher->curl.SetOpt(CURLOPT_URL, _url.c_str());
switcher->curl.SetOpt(CURLOPT_POSTFIELDS, _data.c_str()); switcher->curl.SetOpt(CURLOPT_POSTFIELDS, _data.c_str());
switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.seconds * 1000); switcher->curl.SetOpt(CURLOPT_TIMEOUT_MS, _timeout.Milliseconds());
SetupHeaders();
switcher->curl.Perform(); switcher->curl.Perform();
} }
@@ -90,8 +106,10 @@ void MacroActionHttp::LogAction() const
bool MacroActionHttp::Save(obs_data_t *obj) const bool MacroActionHttp::Save(obs_data_t *obj) const
{ {
MacroAction::Save(obj); MacroAction::Save(obj);
obs_data_set_string(obj, "url", _url.c_str()); _url.Save(obj, "url");
_data.Save(obj, "data"); _data.Save(obj, "data");
obs_data_set_bool(obj, "setHeaders", _setHeaders);
_headers.Save(obj, "headers", "header");
obs_data_set_int(obj, "method", static_cast<int>(_method)); obs_data_set_int(obj, "method", static_cast<int>(_method));
_timeout.Save(obj); _timeout.Save(obj);
return true; return true;
@@ -100,8 +118,10 @@ bool MacroActionHttp::Save(obs_data_t *obj) const
bool MacroActionHttp::Load(obs_data_t *obj) bool MacroActionHttp::Load(obs_data_t *obj)
{ {
MacroAction::Load(obj); MacroAction::Load(obj);
_url = obs_data_get_string(obj, "url"); _url.Load(obj, "url");
_data.Load(obj, "data"); _data.Load(obj, "data");
_setHeaders = obs_data_get_bool(obj, "setHeaders");
_headers.Load(obj, "headers", "header");
_method = static_cast<Method>(obs_data_get_int(obj, "method")); _method = static_cast<Method>(obs_data_get_int(obj, "method"));
_timeout.Load(obj); _timeout.Load(obj);
return true; return true;
@@ -109,7 +129,7 @@ bool MacroActionHttp::Load(obs_data_t *obj)
std::string MacroActionHttp::GetShortDesc() const std::string MacroActionHttp::GetShortDesc() const
{ {
return _url; return _url.UnresolvedValue();
} }
static inline void populateMethodSelection(QComboBox *list) static inline void populateMethodSelection(QComboBox *list)
@@ -122,9 +142,15 @@ static inline void populateMethodSelection(QComboBox *list)
MacroActionHttpEdit::MacroActionHttpEdit( MacroActionHttpEdit::MacroActionHttpEdit(
QWidget *parent, std::shared_ptr<MacroActionHttp> entryData) QWidget *parent, std::shared_ptr<MacroActionHttp> entryData)
: QWidget(parent), : QWidget(parent),
_url(new QLineEdit()), _url(new VariableLineEdit(this)),
_methods(new QComboBox()), _methods(new QComboBox()),
_data(new VariableTextEdit(this)), _data(new VariableTextEdit(this)),
_setHeaders(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.http.setHeaders"))),
_headerListLayout(new QVBoxLayout()),
_headerList(new StringListEdit(
this, obs_module_text("AdvSceneSwitcher.action.http.headers"),
obs_module_text("AdvSceneSwitcher.action.http.addHeader"))),
_timeout(new DurationSelection(this, false)) _timeout(new DurationSelection(this, false))
{ {
populateMethodSelection(_methods); populateMethodSelection(_methods);
@@ -135,8 +161,13 @@ MacroActionHttpEdit::MacroActionHttpEdit(
SLOT(DataChanged())); SLOT(DataChanged()));
QWidget::connect(_methods, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_methods, SIGNAL(currentIndexChanged(int)), this,
SLOT(MethodChanged(int))); SLOT(MethodChanged(int)));
QWidget::connect(_timeout, SIGNAL(DurationChanged(double)), this, QWidget::connect(_setHeaders, SIGNAL(stateChanged(int)), this,
SLOT(TimeoutChanged(double))); SLOT(SetHeadersChanged(int)));
QWidget::connect(_headerList,
SIGNAL(StringListChanged(const StringList &)), this,
SLOT(HeadersChanged(const StringList &)));
QWidget::connect(_timeout, SIGNAL(DurationChanged(const Duration &)),
this, SLOT(TimeoutChanged(const Duration &)));
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{url}}", _url}, {"{{url}}", _url},
@@ -153,8 +184,14 @@ MacroActionHttpEdit::MacroActionHttpEdit(
obs_module_text("AdvSceneSwitcher.action.http.entry.line2"), obs_module_text("AdvSceneSwitcher.action.http.entry.line2"),
timeoutLayout, widgetPlaceholders); timeoutLayout, widgetPlaceholders);
_headerListLayout->addWidget(new QLabel(
obs_module_text("AdvSceneSwitcher.action.http.headers")));
_headerListLayout->addWidget(_headerList);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(actionLayout); mainLayout->addLayout(actionLayout);
mainLayout->addWidget(_setHeaders);
mainLayout->addLayout(_headerListLayout);
mainLayout->addWidget(_data); mainLayout->addWidget(_data);
mainLayout->addLayout(timeoutLayout); mainLayout->addLayout(timeoutLayout);
setLayout(mainLayout); setLayout(mainLayout);
@@ -170,8 +207,10 @@ void MacroActionHttpEdit::UpdateEntryData()
return; return;
} }
_url->setText(QString::fromStdString(_entryData->_url)); _url->setText(_entryData->_url);
_data->setPlainText(_entryData->_data); _data->setPlainText(_entryData->_data);
_setHeaders->setChecked(_entryData->_setHeaders);
_headerList->SetStringList(_entryData->_headers);
_methods->setCurrentIndex(static_cast<int>(_entryData->_method)); _methods->setCurrentIndex(static_cast<int>(_entryData->_method));
_timeout->SetDuration(_entryData->_timeout); _timeout->SetDuration(_entryData->_timeout);
SetWidgetVisibility(); SetWidgetVisibility();
@@ -199,28 +238,43 @@ void MacroActionHttpEdit::MethodChanged(int value)
SetWidgetVisibility(); SetWidgetVisibility();
} }
void MacroActionHttpEdit::TimeoutChanged(double seconds) void MacroActionHttpEdit::TimeoutChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_timeout.seconds = seconds; _entryData->_timeout = dur;
}
void MacroActionHttpEdit::SetHeadersChanged(int value)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_setHeaders = value;
SetWidgetVisibility();
}
void MacroActionHttpEdit::HeadersChanged(const StringList &headers)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_headers = headers;
adjustSize();
updateGeometry();
} }
void MacroActionHttpEdit::SetWidgetVisibility() void MacroActionHttpEdit::SetWidgetVisibility()
{ {
switch (_entryData->_method) { _data->setVisible(_entryData->_method == MacroActionHttp::Method::POST);
case MacroActionHttp::Method::GET: setLayoutVisible(_headerListLayout, _entryData->_setHeaders);
_data->hide();
break;
case MacroActionHttp::Method::POST:
_data->show();
break;
default:
break;
}
adjustSize(); adjustSize();
updateGeometry(); updateGeometry();

View File

@@ -1,10 +1,13 @@
#pragma once #pragma once
#include "macro-action-edit.hpp" #include "macro-action-edit.hpp"
#include "variable-text-edit.hpp" #include "variable-text-edit.hpp"
#include "variable-line-edit.hpp"
#include "duration-control.hpp" #include "duration-control.hpp"
#include "string-list.hpp"
#include <QLineEdit> #include <QLineEdit>
#include <QComboBox> #include <QComboBox>
#include <QCheckBox>
class MacroActionHttp : public MacroAction { class MacroActionHttp : public MacroAction {
public: public:
@@ -25,13 +28,15 @@ public:
POST, POST,
}; };
std::string _url = obs_module_text("AdvSceneSwitcher.enterURL"); StringVariable _url = obs_module_text("AdvSceneSwitcher.enterURL");
VariableResolvingString _data = StringVariable _data = obs_module_text("AdvSceneSwitcher.enterText");
obs_module_text("AdvSceneSwitcher.enterText"); bool _setHeaders = false;
StringList _headers;
Method _method = Method::GET; Method _method = Method::GET;
Duration _timeout; Duration _timeout = Duration(1.0);
private: private:
void SetupHeaders();
void Get(); void Get();
void Post(); void Post();
@@ -59,7 +64,9 @@ private slots:
void DataChanged(); void DataChanged();
void URLChanged(); void URLChanged();
void MethodChanged(int); void MethodChanged(int);
void TimeoutChanged(double seconds); void TimeoutChanged(const Duration &seconds);
void SetHeadersChanged(int);
void HeadersChanged(const StringList &);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);
@@ -69,9 +76,12 @@ protected:
private: private:
void SetWidgetVisibility(); void SetWidgetVisibility();
QLineEdit *_url; VariableLineEdit *_url;
QComboBox *_methods; QComboBox *_methods;
VariableTextEdit *_data; VariableTextEdit *_data;
QCheckBox *_setHeaders;
QVBoxLayout *_headerListLayout;
StringListEdit *_headerList;
DurationSelection *_timeout; DurationSelection *_timeout;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -21,27 +21,28 @@ const static std::map<PerformMacroAction, std::string> actionTypes = {
bool MacroActionMacro::PerformAction() bool MacroActionMacro::PerformAction()
{ {
if (!_macro.get()) { auto macro = _macro.GetMacro();
if (!macro) {
return true; return true;
} }
switch (_action) { switch (_action) {
case PerformMacroAction::PAUSE: case PerformMacroAction::PAUSE:
_macro->SetPaused(); macro->SetPaused();
break; break;
case PerformMacroAction::UNPAUSE: case PerformMacroAction::UNPAUSE:
_macro->SetPaused(false); macro->SetPaused(false);
break; break;
case PerformMacroAction::RESET_COUNTER: case PerformMacroAction::RESET_COUNTER:
_macro->ResetRunCount(); macro->ResetRunCount();
break; break;
case PerformMacroAction::RUN: case PerformMacroAction::RUN:
if (!_macro->Paused()) { if (!macro->Paused()) {
_macro->PerformActions(); macro->PerformActions();
} }
break; break;
case PerformMacroAction::STOP: case PerformMacroAction::STOP:
_macro->Stop(); macro->Stop();
break; break;
default: default:
break; break;
@@ -51,26 +52,27 @@ bool MacroActionMacro::PerformAction()
void MacroActionMacro::LogAction() const void MacroActionMacro::LogAction() const
{ {
if (!_macro.get()) { auto macro = _macro.GetMacro();
if (!macro) {
return; return;
} }
switch (_action) { switch (_action) {
case PerformMacroAction::PAUSE: case PerformMacroAction::PAUSE:
vblog(LOG_INFO, "paused \"%s\"", _macro->Name().c_str()); vblog(LOG_INFO, "paused \"%s\"", macro->Name().c_str());
break; break;
case PerformMacroAction::UNPAUSE: case PerformMacroAction::UNPAUSE:
vblog(LOG_INFO, "unpaused \"%s\"", _macro->Name().c_str()); vblog(LOG_INFO, "unpaused \"%s\"", macro->Name().c_str());
break; break;
case PerformMacroAction::RESET_COUNTER: case PerformMacroAction::RESET_COUNTER:
vblog(LOG_INFO, "reset counter for \"%s\"", vblog(LOG_INFO, "reset counter for \"%s\"",
_macro->Name().c_str()); macro->Name().c_str());
break; break;
case PerformMacroAction::RUN: case PerformMacroAction::RUN:
vblog(LOG_INFO, "run nested macro \"%s\"", vblog(LOG_INFO, "run nested macro \"%s\"",
_macro->Name().c_str()); macro->Name().c_str());
break; break;
case PerformMacroAction::STOP: case PerformMacroAction::STOP:
vblog(LOG_INFO, "stopped macro \"%s\"", _macro->Name().c_str()); vblog(LOG_INFO, "stopped macro \"%s\"", macro->Name().c_str());
break; break;
default: default:
break; break;
@@ -96,10 +98,7 @@ bool MacroActionMacro::Load(obs_data_t *obj)
std::string MacroActionMacro::GetShortDesc() const std::string MacroActionMacro::GetShortDesc() const
{ {
if (_macro.get()) { return _macro.Name();
return _macro->Name();
}
return "";
} }
static inline void populateActionSelection(QComboBox *list) static inline void populateActionSelection(QComboBox *list)
@@ -120,8 +119,6 @@ MacroActionMacroEdit::MacroActionMacroEdit(
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)), QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(MacroChanged(const QString &))); this, SLOT(MacroChanged(const QString &)));
QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this,
SLOT(MacroRemove(const QString &)));
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int))); SLOT(ActionChanged(int)));
@@ -145,7 +142,7 @@ void MacroActionMacroEdit::UpdateEntryData()
return; return;
} }
_actions->setCurrentIndex(static_cast<int>(_entryData->_action)); _actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_macros->SetCurrentMacro(_entryData->_macro.get()); _macros->SetCurrentMacro(_entryData->_macro);
if (_entryData->_action == PerformMacroAction::RUN || if (_entryData->_action == PerformMacroAction::RUN ||
_entryData->_action == PerformMacroAction::STOP) { _entryData->_action == PerformMacroAction::STOP) {
_macros->HideSelectedMacro(); _macros->HideSelectedMacro();
@@ -159,7 +156,7 @@ void MacroActionMacroEdit::MacroChanged(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_macro.UpdateRef(text); _entryData->_macro = text;
emit HeaderInfoChanged( emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
@@ -180,10 +177,3 @@ void MacroActionMacroEdit::ActionChanged(int value)
_macros->ShowAllMacros(); _macros->ShowAllMacros();
} }
} }
void MacroActionMacroEdit::MacroRemove(const QString &)
{
if (_entryData) {
_entryData->_macro.UpdateRef();
}
}

View File

@@ -51,7 +51,6 @@ public:
private slots: private slots:
void MacroChanged(const QString &text); void MacroChanged(const QString &text);
void MacroRemove(const QString &name);
void ActionChanged(int value); void ActionChanged(int value);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);

View File

@@ -48,7 +48,7 @@ bool MacroActionMedia::PerformAction()
obs_source_media_previous(source); obs_source_media_previous(source);
break; break;
case MediaAction::SEEK: case MediaAction::SEEK:
obs_source_media_set_time(source, _seek.seconds * 1000); obs_source_media_set_time(source, _seek.Milliseconds());
break; break;
default: default:
break; break;
@@ -116,10 +116,8 @@ MacroActionMediaEdit::MacroActionMediaEdit(
QWidget::connect(_sources, QWidget::connect(_sources,
SIGNAL(SourceChanged(const SourceSelection &)), this, SIGNAL(SourceChanged(const SourceSelection &)), this,
SLOT(SourceChanged(const SourceSelection &))); SLOT(SourceChanged(const SourceSelection &)));
QWidget::connect(_seek, SIGNAL(DurationChanged(double)), this, QWidget::connect(_seek, SIGNAL(DurationChanged(const Duration &)), this,
SLOT(DurationChanged(double))); SLOT(DurationChanged(const Duration &)));
QWidget::connect(_seek, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DurationUnitChanged(DurationUnit)));
QHBoxLayout *mainLayout = new QHBoxLayout; QHBoxLayout *mainLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@@ -171,24 +169,14 @@ void MacroActionMediaEdit::ActionChanged(int value)
SetWidgetVisibility(); SetWidgetVisibility();
} }
void MacroActionMediaEdit::DurationChanged(double seconds) void MacroActionMediaEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_seek.seconds = seconds; _entryData->_seek = dur;
}
void MacroActionMediaEdit::DurationUnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_seek.displayUnit = unit;
} }
void MacroActionMediaEdit::SetWidgetVisibility() void MacroActionMediaEdit::SetWidgetVisibility()

View File

@@ -58,8 +58,7 @@ public:
private slots: private slots:
void SourceChanged(const SourceSelection &); void SourceChanged(const SourceSelection &);
void ActionChanged(int value); void ActionChanged(int value);
void DurationChanged(double value); void DurationChanged(const Duration &value);
void DurationUnitChanged(DurationUnit unit);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);

View File

@@ -102,7 +102,7 @@ bool MacroActionPluginState::Save(obs_data_t *obj) const
obs_data_set_int(obj, "action", static_cast<int>(_action)); obs_data_set_int(obj, "action", static_cast<int>(_action));
obs_data_set_int(obj, "value", _value); obs_data_set_int(obj, "value", _value);
obs_data_set_string(obj, "scene", GetWeakSourceName(_scene).c_str()); obs_data_set_string(obj, "scene", GetWeakSourceName(_scene).c_str());
obs_data_set_string(obj, "settingsPath", _settingsPath.c_str()); _settingsPath.Save(obj, "settingsPath");
return true; return true;
} }
@@ -114,7 +114,7 @@ bool MacroActionPluginState::Load(obs_data_t *obj)
_value = obs_data_get_int(obj, "value"); _value = obs_data_get_int(obj, "value");
const char *sceneName = obs_data_get_string(obj, "scene"); const char *sceneName = obs_data_get_string(obj, "scene");
_scene = GetWeakSourceByName(sceneName); _scene = GetWeakSourceByName(sceneName);
_settingsPath = obs_data_get_string(obj, "settingsPath"); _settingsPath.Load(obj, "settingsPath");
return true; return true;
} }
@@ -185,7 +185,7 @@ void MacroActionPluginStateEdit::UpdateEntryData()
populateValueSelection(_values, _entryData->_action); populateValueSelection(_values, _entryData->_action);
_values->setCurrentIndex(_entryData->_value); _values->setCurrentIndex(_entryData->_value);
_scenes->setCurrentText(GetWeakSourceName(_entryData->_scene).c_str()); _scenes->setCurrentText(GetWeakSourceName(_entryData->_scene).c_str());
_settings->SetPath(QString::fromStdString(_entryData->_settingsPath)); _settings->SetPath(_entryData->_settingsPath);
SetWidgetVisibility(); SetWidgetVisibility();
} }

View File

@@ -26,7 +26,7 @@ public:
PluginStateAction _action = PluginStateAction::STOP; PluginStateAction _action = PluginStateAction::STOP;
int _value = 0; int _value = 0;
std::string _settingsPath; StringVariable _settingsPath;
OBSWeakSource _scene; OBSWeakSource _scene;
private: private:

View File

@@ -249,7 +249,7 @@ void MacroActionProjectorEdit::MonitorChanged(int value)
_entryData->_monitor = value; _entryData->_monitor = value;
} }
void MacroActionProjectorEdit::WindowTypeChanged(int value) void MacroActionProjectorEdit::WindowTypeChanged(int)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;

View File

@@ -11,22 +11,30 @@ bool MacroActionRandom::_registered = MacroActionFactory::Register(
{MacroActionRandom::Create, MacroActionRandomEdit::Create, {MacroActionRandom::Create, MacroActionRandomEdit::Create,
"AdvSceneSwitcher.action.random"}); "AdvSceneSwitcher.action.random"});
std::vector<MacroRef> getNextMacros(std::vector<MacroRef> &macros, static bool validNextMacro(const std::shared_ptr<Macro> &macro)
MacroRef &lastRandomMacro, bool allowRepeat)
{ {
std::vector<MacroRef> res; return macro && !macro->Paused();
}
static std::vector<std::shared_ptr<Macro>>
getNextMacros(std::vector<MacroRef> &macros, MacroRef &lastRandomMacroRef,
bool allowRepeat)
{
std::vector<std::shared_ptr<Macro>> res;
if (macros.size() == 1) { if (macros.size() == 1) {
if (!macros[0].get() || macros[0]->Paused()) { auto macro = macros[0].GetMacro();
return res; if (validNextMacro(macro)) {
} else { res.push_back(macro);
return macros;
} }
return res;
} }
auto lastRandomMacro = lastRandomMacroRef.GetMacro();
for (auto &m : macros) { for (auto &m : macros) {
if (m.get() && !m->Paused() && auto macro = m.GetMacro();
(allowRepeat || (lastRandomMacro.get() != m.get()))) { if (validNextMacro(macro) &&
res.push_back(m); (allowRepeat || (lastRandomMacro != macro))) {
res.push_back(macro);
} }
} }
return res; return res;
@@ -42,7 +50,7 @@ bool MacroActionRandom::PerformAction()
if (macros.size() == 0) { if (macros.size() == 0) {
return true; return true;
} }
if (macros.size() == 1 && macros[0].get()) { if (macros.size() == 1) {
lastRandomMacro = macros[0]; lastRandomMacro = macros[0];
return macros[0]->PerformActions(); return macros[0]->PerformActions();
} }
@@ -126,8 +134,7 @@ void MacroActionRandomEdit::MacroRemove(const QString &)
auto it = _entryData->_macros.begin(); auto it = _entryData->_macros.begin();
while (it != _entryData->_macros.end()) { while (it != _entryData->_macros.end()) {
it->UpdateRef(); if (!it->GetMacro()) {
if (it->get() == nullptr) {
it = _entryData->_macros.erase(it); it = _entryData->_macros.erase(it);
} else { } else {
++it; ++it;
@@ -188,9 +195,9 @@ bool MacroActionRandomEdit::ShouldShowAllowRepeat()
if (_entryData->_macros.size() <= 1) { if (_entryData->_macros.size() <= 1) {
return false; return false;
} }
const auto macro = _entryData->_macros[0]; const auto macro = _entryData->_macros[0].GetMacro();
for (const auto &m : _entryData->_macros) { for (const auto &m : _entryData->_macros) {
if (macro.get() != m.get()) { if (macro != m.GetMacro()) {
return true; return true;
} }
} }

View File

@@ -1,10 +1,8 @@
#include "macro-action-run.hpp" #include "macro-action-run.hpp"
#include "advanced-scene-switcher.hpp" #include "advanced-scene-switcher.hpp"
#include "name-dialog.hpp"
#include "utility.hpp" #include "utility.hpp"
#include <QProcess> #include <QProcess>
#include <QFileDialog>
#include <QDesktopServices> #include <QDesktopServices>
const std::string MacroActionRun::id = "run"; const std::string MacroActionRun::id = "run";
@@ -15,137 +13,53 @@ bool MacroActionRun::_registered = MacroActionFactory::Register(
bool MacroActionRun::PerformAction() bool MacroActionRun::PerformAction()
{ {
if (!QProcess::startDetached( bool procStarted = QProcess::startDetached(
QString::fromStdString(_path), _args, QString::fromStdString(_procConfig.Path()), _procConfig.Args(),
QString::fromStdString(_workingDirectory)) && QString::fromStdString(_procConfig.WorkingDir()));
_args.empty()) { if (!procStarted && _procConfig.Args().empty()) {
vblog(LOG_INFO, "run \"%s\" using QDesktopServices", vblog(LOG_INFO, "run \"%s\" using QDesktopServices",
_path.c_str()); _procConfig.Path().c_str());
QDesktopServices::openUrl( QDesktopServices::openUrl(QUrl::fromLocalFile(
QUrl::fromLocalFile(QString::fromStdString(_path))); QString::fromStdString(_procConfig.Path())));
} }
return true; return true;
} }
void MacroActionRun::LogAction() const void MacroActionRun::LogAction() const
{ {
vblog(LOG_INFO, "run \"%s\"", _path.c_str()); vblog(LOG_INFO, "run \"%s\"", _procConfig.UnresolvedPath().c_str());
} }
bool MacroActionRun::Save(obs_data_t *obj) const bool MacroActionRun::Save(obs_data_t *obj) const
{ {
MacroAction::Save(obj); MacroAction::Save(obj);
obs_data_set_string(obj, "path", _path.c_str()); _procConfig.Save(obj);
obs_data_set_string(obj, "workingDirectory", _workingDirectory.c_str());
obs_data_array_t *args = obs_data_array_create();
for (auto &arg : _args) {
obs_data_t *array_obj = obs_data_create();
obs_data_set_string(array_obj, "arg",
arg.toStdString().c_str());
obs_data_array_push_back(args, array_obj);
obs_data_release(array_obj);
}
obs_data_set_array(obj, "args", args);
obs_data_array_release(args);
return true; return true;
} }
bool MacroActionRun::Load(obs_data_t *obj) bool MacroActionRun::Load(obs_data_t *obj)
{ {
MacroAction::Load(obj); MacroAction::Load(obj);
_path = obs_data_get_string(obj, "path"); _procConfig.Load(obj);
_workingDirectory = obs_data_get_string(obj, "workingDirectory");
obs_data_array_t *args = obs_data_get_array(obj, "args");
size_t count = obs_data_array_count(args);
for (size_t i = 0; i < count; i++) {
obs_data_t *array_obj = obs_data_array_item(args, i);
_args << QString::fromStdString(
obs_data_get_string(array_obj, "arg"));
obs_data_release(array_obj);
}
obs_data_array_release(args);
return true; return true;
} }
std::string MacroActionRun::GetShortDesc() const std::string MacroActionRun::GetShortDesc() const
{ {
return _path; return _procConfig.UnresolvedPath();
} }
MacroActionRunEdit::MacroActionRunEdit( MacroActionRunEdit::MacroActionRunEdit(
QWidget *parent, std::shared_ptr<MacroActionRun> entryData) QWidget *parent, std::shared_ptr<MacroActionRun> entryData)
: QWidget(parent), : QWidget(parent), _procConfig(new ProcessConfigEdit(this))
_filePath(new FileSelection()),
_argList(new QListWidget()),
_addArg(new QPushButton()),
_removeArg(new QPushButton()),
_argUp(new QPushButton()),
_argDown(new QPushButton()),
_workingDirectory(new FileSelection(FileSelection::Type::FOLDER))
{ {
_addArg->setMaximumWidth(22); QWidget::connect(_procConfig,
_addArg->setProperty("themeID", SIGNAL(ConfigChanged(const ProcessConfig &)), this,
QVariant(QString::fromUtf8("addIconSmall"))); SLOT(ProcessConfigChanged(const ProcessConfig &)));
_addArg->setFlat(true);
_removeArg->setMaximumWidth(22);
_removeArg->setProperty("themeID",
QVariant(QString::fromUtf8("removeIconSmall")));
_removeArg->setFlat(true);
_argUp->setMaximumWidth(22);
_argUp->setProperty("themeID",
QVariant(QString::fromUtf8("upArrowIconSmall")));
_argUp->setFlat(true);
_argDown->setMaximumWidth(22);
_argDown->setProperty(
"themeID", QVariant(QString::fromUtf8("downArrowIconSmall")));
_argDown->setFlat(true);
QWidget::connect(_filePath, SIGNAL(PathChanged(const QString &)), this, auto *layout = new QVBoxLayout;
SLOT(PathChanged(const QString &))); layout->addWidget(_procConfig);
QWidget::connect(_addArg, SIGNAL(clicked()), this, SLOT(AddArg())); setLayout(layout);
QWidget::connect(_removeArg, SIGNAL(clicked()), this,
SLOT(RemoveArg()));
QWidget::connect(_argUp, SIGNAL(clicked()), this, SLOT(ArgUp()));
QWidget::connect(_argDown, SIGNAL(clicked()), this, SLOT(ArgDown()));
QWidget::connect(_argList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
this, SLOT(ArgItemClicked(QListWidgetItem *)));
QWidget::connect(_workingDirectory,
SIGNAL(PathChanged(const QString &)), this,
SLOT(WorkingDirectoryChanged(const QString &)));
auto *entryLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{filePath}}", _filePath},
{"{{workingDirectory}}", _workingDirectory},
};
placeWidgets(obs_module_text("AdvSceneSwitcher.action.run.entry"),
entryLayout, widgetPlaceholders, false);
auto argButtonLayout = new QHBoxLayout;
argButtonLayout->addWidget(_addArg);
argButtonLayout->addWidget(_removeArg);
QFrame *line = new QFrame();
line->setFrameShape(QFrame::VLine);
line->setFrameShadow(QFrame::Sunken);
argButtonLayout->addWidget(line);
argButtonLayout->addWidget(_argUp);
argButtonLayout->addWidget(_argDown);
argButtonLayout->addStretch();
auto workingDirectoryLayout = new QHBoxLayout;
placeWidgets(
obs_module_text(
"AdvSceneSwitcher.action.run.entry.workingDirectory"),
workingDirectoryLayout, widgetPlaceholders, false);
auto *mainLayout = new QVBoxLayout;
mainLayout->addLayout(entryLayout);
mainLayout->addWidget(new QLabel(
obs_module_text("AdvSceneSwitcher.action.run.arguments")));
mainLayout->addWidget(_argList);
mainLayout->addLayout(argButtonLayout);
mainLayout->addLayout(workingDirectoryLayout);
setLayout(mainLayout);
_entryData = entryData; _entryData = entryData;
UpdateEntryData(); UpdateEntryData();
@@ -157,142 +71,19 @@ void MacroActionRunEdit::UpdateEntryData()
if (!_entryData) { if (!_entryData) {
return; return;
} }
_filePath->SetPath(QString::fromStdString(_entryData->_path)); _procConfig->SetProcessConfig(_entryData->_procConfig);
for (auto &arg : _entryData->_args) {
QListWidgetItem *item = new QListWidgetItem(arg, _argList);
item->setData(Qt::UserRole, arg);
}
_workingDirectory->SetPath(
QString::fromStdString(_entryData->_workingDirectory));
SetArgListSize();
} }
void MacroActionRunEdit::PathChanged(const QString &text) void MacroActionRunEdit::ProcessConfigChanged(const ProcessConfig &conf)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_path = text.toUtf8().constData(); _entryData->_procConfig = conf;
adjustSize();
updateGeometry();
emit HeaderInfoChanged( emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
void MacroActionRunEdit::AddArg()
{
if (_loading || !_entryData) {
return;
}
std::string name;
bool accepted = AdvSSNameDialog::AskForName(
this,
obs_module_text("AdvSceneSwitcher.action.run.addArgument"),
obs_module_text(
"AdvSceneSwitcher.action.run.addArgumentDescription"),
name, "", 170, false);
if (!accepted || name.empty()) {
return;
}
auto arg = QString::fromStdString(name);
QVariant v = QVariant::fromValue(arg);
QListWidgetItem *item = new QListWidgetItem(arg, _argList);
item->setData(Qt::UserRole, arg);
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_args << arg;
SetArgListSize();
}
void MacroActionRunEdit::RemoveArg()
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
int idx = _argList->currentRow();
if (idx == -1) {
return;
}
_entryData->_args.removeAt(idx);
QListWidgetItem *item = _argList->currentItem();
if (!item) {
return;
}
delete item;
SetArgListSize();
}
void MacroActionRunEdit::ArgUp()
{
if (_loading || !_entryData) {
return;
}
int idx = _argList->currentRow();
if (idx != -1 && idx != 0) {
_argList->insertItem(idx - 1, _argList->takeItem(idx));
_argList->setCurrentRow(idx - 1);
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_args.move(idx, idx - 1);
}
}
void MacroActionRunEdit::ArgDown()
{
int idx = _argList->currentRow();
if (idx != -1 && idx != _argList->count() - 1) {
_argList->insertItem(idx + 1, _argList->takeItem(idx));
_argList->setCurrentRow(idx + 1);
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_args.move(idx, idx + 1);
}
}
void MacroActionRunEdit::ArgItemClicked(QListWidgetItem *item)
{
if (_loading || !_entryData) {
return;
}
std::string name;
bool accepted = AdvSSNameDialog::AskForName(
this,
obs_module_text("AdvSceneSwitcher.action.run.addArgument"),
obs_module_text(
"AdvSceneSwitcher.action.run.addArgumentDescription"),
name, item->text(), 170, false);
if (!accepted || name.empty()) {
return;
}
auto arg = QString::fromStdString(name);
QVariant v = QVariant::fromValue(arg);
item->setText(arg);
item->setData(Qt::UserRole, arg);
int idx = _argList->currentRow();
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_args[idx] = arg;
}
void MacroActionRunEdit::WorkingDirectoryChanged(const QString &path)
{
if (_loading || !_entryData) {
return;
}
_entryData->_workingDirectory = path.toStdString();
}
void MacroActionRunEdit::SetArgListSize()
{
setHeightToContentHeight(_argList);
adjustSize();
}

View File

@@ -1,11 +1,6 @@
#pragma once #pragma once
#include "macro-action-edit.hpp" #include "macro-action-edit.hpp"
#include "file-selection.hpp" #include "process-config.hpp"
#include <QLineEdit>
#include <QPushButton>
#include <QListWidget>
#include <QStringList>
class MacroActionRun : public MacroAction { class MacroActionRun : public MacroAction {
public: public:
@@ -21,9 +16,7 @@ public:
return std::make_shared<MacroActionRun>(m); return std::make_shared<MacroActionRun>(m);
} }
std::string _path = obs_module_text("AdvSceneSwitcher.enterPath"); ProcessConfig _procConfig;
std::string _workingDirectory = "";
QStringList _args;
private: private:
static bool _registered; static bool _registered;
@@ -46,13 +39,7 @@ public:
} }
private slots: private slots:
void PathChanged(const QString &text); void ProcessConfigChanged(const ProcessConfig &);
void AddArg();
void RemoveArg();
void ArgUp();
void ArgDown();
void ArgItemClicked(QListWidgetItem *);
void WorkingDirectoryChanged(const QString &text);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);
@@ -60,14 +47,6 @@ protected:
std::shared_ptr<MacroActionRun> _entryData; std::shared_ptr<MacroActionRun> _entryData;
private: private:
void SetArgListSize(); ProcessConfigEdit *_procConfig;
FileSelection *_filePath;
QListWidget *_argList;
QPushButton *_addArg;
QPushButton *_removeArg;
QPushButton *_argUp;
QPushButton *_argDown;
FileSelection *_workingDirectory;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -103,7 +103,7 @@ bool MacroActionSwitchScene::WaitForTransition(OBSWeakSource &scene,
OBSWeakSource &transition) OBSWeakSource &transition)
{ {
const int expectedTransitionDuration = getExpectedTransitionDuration( const int expectedTransitionDuration = getExpectedTransitionDuration(
scene, transition, _duration.seconds); scene, transition, _duration.Seconds());
switcher->abortMacroWait = false; switcher->abortMacroWait = false;
std::unique_lock<std::mutex> lock(switcher->m); std::unique_lock<std::mutex> lock(switcher->m);
@@ -121,7 +121,7 @@ bool MacroActionSwitchScene::PerformAction()
{ {
auto scene = _scene.GetScene(); auto scene = _scene.GetScene();
auto transition = _transition.GetTransition(); auto transition = _transition.GetTransition();
switchScene({scene, transition, (int)(_duration.seconds * 1000)}, switchScene({scene, transition, (int)(_duration.Milliseconds())},
obs_frontend_preview_program_mode_active()); obs_frontend_preview_program_mode_active());
if (_blockUntilTransitionDone && scene) { if (_blockUntilTransitionDone && scene) {
return WaitForTransition(scene, transition); return WaitForTransition(scene, transition);
@@ -196,8 +196,8 @@ MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
SIGNAL(TransitionChanged(const TransitionSelection &)), SIGNAL(TransitionChanged(const TransitionSelection &)),
this, this,
SLOT(TransitionChanged(const TransitionSelection &))); SLOT(TransitionChanged(const TransitionSelection &)));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_blockUntilTransitionDone, SIGNAL(stateChanged(int)), QWidget::connect(_blockUntilTransitionDone, SIGNAL(stateChanged(int)),
this, SLOT(BlockUntilTransitionDoneChanged(int))); this, SLOT(BlockUntilTransitionDoneChanged(int)));
@@ -225,14 +225,14 @@ MacroActionSwitchSceneEdit::MacroActionSwitchSceneEdit(
_loading = false; _loading = false;
} }
void MacroActionSwitchSceneEdit::DurationChanged(double seconds) void MacroActionSwitchSceneEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
} }
void MacroActionSwitchSceneEdit::BlockUntilTransitionDoneChanged(int state) void MacroActionSwitchSceneEdit::BlockUntilTransitionDoneChanged(int state)

View File

@@ -51,7 +51,7 @@ public:
private slots: private slots:
void SceneChanged(const SceneSelection &); void SceneChanged(const SceneSelection &);
void TransitionChanged(const TransitionSelection &); void TransitionChanged(const TransitionSelection &);
void DurationChanged(double seconds); void DurationChanged(const Duration &seconds);
void BlockUntilTransitionDoneChanged(int state); void BlockUntilTransitionDoneChanged(int state);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);

View File

@@ -22,7 +22,7 @@ public:
SceneSelection _scene; SceneSelection _scene;
SceneItemSelection _source; SceneItemSelection _source;
VariableResolvingString _settings = ""; StringVariable _settings = "";
private: private:
void ApplySettings(const std::string &); void ApplySettings(const std::string &);

View File

@@ -87,7 +87,7 @@ bool MacroActionScreenshot::Save(obs_data_t *obj) const
_source.Save(obj); _source.Save(obj);
obs_data_set_int(obj, "saveType", static_cast<int>(_saveType)); obs_data_set_int(obj, "saveType", static_cast<int>(_saveType));
obs_data_set_int(obj, "targetType", static_cast<int>(_targetType)); obs_data_set_int(obj, "targetType", static_cast<int>(_targetType));
obs_data_set_string(obj, "savePath", _path.c_str()); _path.Save(obj, "savePath");
obs_data_set_int(obj, "version", _version); obs_data_set_int(obj, "version", _version);
return true; return true;
} }
@@ -100,7 +100,7 @@ bool MacroActionScreenshot::Load(obs_data_t *obj)
_saveType = static_cast<SaveType>(obs_data_get_int(obj, "saveType")); _saveType = static_cast<SaveType>(obs_data_get_int(obj, "saveType"));
_targetType = _targetType =
static_cast<TargetType>(obs_data_get_int(obj, "targetType")); static_cast<TargetType>(obs_data_get_int(obj, "targetType"));
_path = obs_data_get_string(obj, "savePath"); _path.Load(obj, "savePath");
// TODO: Remove fallback for older versions // TODO: Remove fallback for older versions
if (!obs_data_has_user_value(obj, "version")) { if (!obs_data_has_user_value(obj, "version")) {
@@ -200,7 +200,7 @@ void MacroActionScreenshotEdit::UpdateEntryData()
_scenes->SetScene(_entryData->_scene); _scenes->SetScene(_entryData->_scene);
_saveType->setCurrentIndex(static_cast<int>(_entryData->_saveType)); _saveType->setCurrentIndex(static_cast<int>(_entryData->_saveType));
_targetType->setCurrentIndex(static_cast<int>(_entryData->_targetType)); _targetType->setCurrentIndex(static_cast<int>(_entryData->_targetType));
_savePath->SetPath(QString::fromStdString(_entryData->_path)); _savePath->SetPath(_entryData->_path);
SetWidgetVisibility(); SetWidgetVisibility();
} }
@@ -243,7 +243,7 @@ void MacroActionScreenshotEdit::PathChanged(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_path = text.toUtf8().constData(); _entryData->_path = text.toStdString();
} }
void MacroActionScreenshotEdit::SourceChanged(const SourceSelection &source) void MacroActionScreenshotEdit::SourceChanged(const SourceSelection &source)

View File

@@ -33,7 +33,7 @@ public:
TargetType _targetType = TargetType::SOURCE; TargetType _targetType = TargetType::SOURCE;
SceneSelection _scene; SceneSelection _scene;
SourceSelection _source; SourceSelection _source;
std::string _path = obs_module_text("AdvSceneSwitcher.enterPath"); StringVariable _path = obs_module_text("AdvSceneSwitcher.enterPath");
private: private:
void FrontendScreenshot(OBSWeakSource &); void FrontendScreenshot(OBSWeakSource &);

View File

@@ -12,7 +12,8 @@ bool MacroActionSequence::_registered = MacroActionFactory::Register(
int getNextUnpausedMacroIdx(std::vector<MacroRef> &macros, int startIdx) int getNextUnpausedMacroIdx(std::vector<MacroRef> &macros, int startIdx)
{ {
for (; (int)macros.size() > startIdx; ++startIdx) { for (; (int)macros.size() > startIdx; ++startIdx) {
if (macros[startIdx].get() && !macros[startIdx]->Paused()) { auto macro = macros[startIdx].GetMacro();
if (macro && !macro->Paused()) {
return startIdx; return startIdx;
} }
} }
@@ -58,7 +59,7 @@ bool MacroActionSequence::PerformAction()
return true; return true;
} }
auto macro = GetNextMacro(); auto macro = GetNextMacro().GetMacro();
if (!macro.get()) { if (!macro.get()) {
return true; return true;
} }
@@ -158,8 +159,8 @@ void MacroActionSequenceEdit::MacroRemove(const QString &)
auto it = _entryData->_macros.begin(); auto it = _entryData->_macros.begin();
while (it != _entryData->_macros.end()) { while (it != _entryData->_macros.end()) {
it->UpdateRef();
if (it->get() == nullptr) { if (!it->GetMacro()) {
it = _entryData->_macros.erase(it); it = _entryData->_macros.erase(it);
} else { } else {
++it; ++it;
@@ -250,12 +251,11 @@ void MacroActionSequenceEdit::UpdateStatusLine()
QString nextMacroName = QString nextMacroName =
obs_module_text("AdvSceneSwitcher.action.sequence.status.none"); obs_module_text("AdvSceneSwitcher.action.sequence.status.none");
if (_entryData) { if (_entryData) {
if (_entryData->_lastSequenceMacro.get()) { if (auto macro = _entryData->_lastSequenceMacro.GetMacro()) {
lastMacroName = QString::fromStdString( lastMacroName = QString::fromStdString(macro->Name());
_entryData->_lastSequenceMacro->Name());
} }
auto next = _entryData->GetNextMacro(false); auto next = _entryData->GetNextMacro(false).GetMacro();
if (next.get()) { if (next) {
nextMacroName = QString::fromStdString(next->Name()); nextMacroName = QString::fromStdString(next->Name());
} }
} }

View File

@@ -41,7 +41,7 @@ public:
SourceSelection _source; SourceSelection _source;
SourceSettingButton _button; SourceSettingButton _button;
VariableResolvingString _settings = ""; StringVariable _settings = "";
SourceAction _action = SourceAction::ENABLE; SourceAction _action = SourceAction::ENABLE;
private: private:

View File

@@ -22,10 +22,11 @@ static std::map<TimerAction, std::string> timerActions = {
bool MacroActionTimer::PerformAction() bool MacroActionTimer::PerformAction()
{ {
if (!_macro.get()) { auto macro = _macro.GetMacro();
if (!macro) {
return true; return true;
} }
for (auto c : _macro->Conditions()) { for (auto c : macro->Conditions()) {
if (c->GetId() != "timer") { if (c->GetId() != "timer") {
continue; continue;
} }
@@ -47,7 +48,7 @@ bool MacroActionTimer::PerformAction()
break; break;
case TimerAction::SET_TIME_REMAINING: case TimerAction::SET_TIME_REMAINING:
timerCondition->_duration.SetTimeRemaining( timerCondition->_duration.SetTimeRemaining(
_duration.seconds); _duration.Seconds());
break; break;
default: default:
break; break;
@@ -58,26 +59,27 @@ bool MacroActionTimer::PerformAction()
void MacroActionTimer::LogAction() const void MacroActionTimer::LogAction() const
{ {
if (!_macro.get()) { auto macro = _macro.GetMacro();
if (!macro) {
return; return;
} }
switch (_actionType) { switch (_actionType) {
case TimerAction::PAUSE: case TimerAction::PAUSE:
vblog(LOG_INFO, "paused timers on \"%s\"", vblog(LOG_INFO, "paused timers on \"%s\"",
_macro->Name().c_str()); macro->Name().c_str());
break; break;
case TimerAction::CONTINUE: case TimerAction::CONTINUE:
vblog(LOG_INFO, "continued timers on \"%s\"", vblog(LOG_INFO, "continued timers on \"%s\"",
_macro->Name().c_str()); macro->Name().c_str());
break; break;
case TimerAction::RESET: case TimerAction::RESET:
vblog(LOG_INFO, "reset timers on \"%s\"", vblog(LOG_INFO, "reset timers on \"%s\"",
_macro->Name().c_str()); macro->Name().c_str());
break; break;
case TimerAction::SET_TIME_REMAINING: case TimerAction::SET_TIME_REMAINING:
vblog(LOG_INFO, vblog(LOG_INFO,
"set time remaining of timers on \"%s\" to \"%s\"", "set time remaining of timers on \"%s\" to \"%s\"",
_macro->Name().c_str(), _duration.ToString().c_str()); macro->Name().c_str(), _duration.ToString().c_str());
break; break;
default: default:
break; break;
@@ -105,10 +107,7 @@ bool MacroActionTimer::Load(obs_data_t *obj)
std::string MacroActionTimer::GetShortDesc() const std::string MacroActionTimer::GetShortDesc() const
{ {
if (_macro.get()) { return _macro.Name();
return _macro->Name();
}
return "";
} }
static inline void populateTypeSelection(QComboBox *list) static inline void populateTypeSelection(QComboBox *list)
@@ -130,12 +129,8 @@ MacroActionTimerEdit::MacroActionTimerEdit(
QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)), QWidget::connect(_macros, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(MacroChanged(const QString &))); this, SLOT(MacroChanged(const QString &)));
QWidget::connect(parent, SIGNAL(MacroRemoved(const QString &)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(MacroRemove(const QString &))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this,
SLOT(DurationChanged(double)));
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DurationUnitChanged(DurationUnit)));
QWidget::connect(_timerAction, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_timerAction, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionTypeChanged(int))); SLOT(ActionTypeChanged(int)));
@@ -160,7 +155,7 @@ void MacroActionTimerEdit::UpdateEntryData()
return; return;
} }
_macros->SetCurrentMacro(_entryData->_macro.get()); _macros->SetCurrentMacro(_entryData->_macro);
_duration->SetDuration(_entryData->_duration); _duration->SetDuration(_entryData->_duration);
_timerAction->setCurrentIndex( _timerAction->setCurrentIndex(
static_cast<int>(_entryData->_actionType)); static_cast<int>(_entryData->_actionType));
@@ -188,24 +183,14 @@ void MacroActionTimerEdit::SetWidgetVisibility()
adjustSize(); adjustSize();
} }
void MacroActionTimerEdit::DurationChanged(double seconds) void MacroActionTimerEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
}
void MacroActionTimerEdit::DurationUnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.displayUnit = unit;
} }
void MacroActionTimerEdit::MacroChanged(const QString &text) void MacroActionTimerEdit::MacroChanged(const QString &text)
@@ -215,14 +200,7 @@ void MacroActionTimerEdit::MacroChanged(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_macro.UpdateRef(text); _entryData->_macro = text;
emit HeaderInfoChanged( emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
void MacroActionTimerEdit::MacroRemove(const QString &)
{
if (_entryData) {
_entryData->_macro.UpdateRef();
}
}

View File

@@ -52,9 +52,7 @@ public:
private slots: private slots:
void MacroChanged(const QString &text); void MacroChanged(const QString &text);
void MacroRemove(const QString &name); void DurationChanged(const Duration &value);
void DurationChanged(double value);
void DurationUnitChanged(DurationUnit unit);
void ActionTypeChanged(int value); void ActionTypeChanged(int value);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);

View File

@@ -29,7 +29,8 @@ void MacroActionTransition::SetSceneTransition()
obs_source_release(t); obs_source_release(t);
} }
if (_setDuration) { if (_setDuration) {
obs_frontend_set_transition_duration(_duration.seconds * 1000); obs_frontend_set_transition_duration(_duration.Seconds() *
1000);
} }
} }
@@ -43,7 +44,7 @@ void MacroActionTransition::SetTransitionOverride()
} }
if (_setDuration) { if (_setDuration) {
obs_data_set_int(data, "transition_duration", obs_data_set_int(data, "transition_duration",
_duration.seconds * 1000); _duration.Milliseconds());
} }
obs_data_release(data); obs_data_release(data);
obs_source_release(scene); obs_source_release(scene);
@@ -91,7 +92,7 @@ void MacroActionTransition::SetSourceTransition(bool show)
} }
if (_setDuration) { if (_setDuration) {
obs_sceneitem_set_transition_duration( obs_sceneitem_set_transition_duration(
item, show, _duration.seconds * 1000); item, show, _duration.Milliseconds());
} }
obs_sceneitem_release(item); obs_sceneitem_release(item);
} }
@@ -230,8 +231,8 @@ MacroActionTransitionEdit::MacroActionTransitionEdit(
SIGNAL(TransitionChanged(const TransitionSelection &)), SIGNAL(TransitionChanged(const TransitionSelection &)),
this, this,
SLOT(TransitionChanged(const TransitionSelection &))); SLOT(TransitionChanged(const TransitionSelection &)));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_setTransition, SIGNAL(stateChanged(int)), this, QWidget::connect(_setTransition, SIGNAL(stateChanged(int)), this,
SLOT(SetTransitionChanged(int))); SLOT(SetTransitionChanged(int)));
QWidget::connect(_setDuration, SIGNAL(stateChanged(int)), this, QWidget::connect(_setDuration, SIGNAL(stateChanged(int)), this,
@@ -334,14 +335,14 @@ void MacroActionTransitionEdit::TransitionChanged(const TransitionSelection &t)
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
void MacroActionTransitionEdit::DurationChanged(double seconds) void MacroActionTransitionEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
} }
void MacroActionTransitionEdit::SetWidgetVisibility() void MacroActionTransitionEdit::SetWidgetVisibility()

View File

@@ -70,7 +70,7 @@ private slots:
void SetTransitionChanged(int state); void SetTransitionChanged(int state);
void SetDurationChanged(int state); void SetDurationChanged(int state);
void TransitionChanged(const TransitionSelection &); void TransitionChanged(const TransitionSelection &);
void DurationChanged(double seconds); void DurationChanged(const Duration &seconds);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);

View File

@@ -1,6 +1,7 @@
#include "macro-action-variable.hpp" #include "macro-action-variable.hpp"
#include "advanced-scene-switcher.hpp" #include "advanced-scene-switcher.hpp"
#include "macro-condition-edit.hpp" #include "macro-condition-edit.hpp"
#include "math-helpers.hpp"
#include "utility.hpp" #include "utility.hpp"
const std::string MacroActionVariable::id = "variable"; const std::string MacroActionVariable::id = "variable";
@@ -29,6 +30,10 @@ static std::map<MacroActionVariable::Type, std::string> actionTypes = {
"AdvSceneSwitcher.action.variable.type.roundToInt"}, "AdvSceneSwitcher.action.variable.type.roundToInt"},
{MacroActionVariable::Type::SUBSTRING, {MacroActionVariable::Type::SUBSTRING,
"AdvSceneSwitcher.action.variable.type.subString"}, "AdvSceneSwitcher.action.variable.type.subString"},
{MacroActionVariable::Type::FIND_AND_REPLACE,
"AdvSceneSwitcher.action.variable.type.findAndReplace"},
{MacroActionVariable::Type::MATH_EXPRESSION,
"AdvSceneSwitcher.action.variable.type.mathExpression"},
}; };
static void apppend(Variable &var, const std::string &value) static void apppend(Variable &var, const std::string &value)
@@ -39,14 +44,14 @@ static void apppend(Variable &var, const std::string &value)
static void modifyNumValue(Variable &var, double val, const bool increment) static void modifyNumValue(Variable &var, double val, const bool increment)
{ {
double current; auto current = var.DoubleValue();
if (!var.DoubleValue(current)) { if (!current.has_value()) {
return; return;
} }
if (increment) { if (increment) {
var.SetValue(current + val); var.SetValue(*current + val);
} else { } else {
var.SetValue(current - val); var.SetValue(*current - val);
} }
} }
@@ -95,9 +100,26 @@ void MacroActionVariable::HandleRegexSubString(Variable *var)
var->SetValue(match.captured(0).toStdString()); var->SetValue(match.captured(0).toStdString());
} }
void MacroActionVariable::HandleFindAndReplace(Variable *var)
{
auto value = var->Value();
replaceAll(value, _findStr, _replaceStr);
var->SetValue(value);
}
void MacroActionVariable::HandleMathExpression(Variable *var)
{
auto result = EvalMathExpression(_mathExpression);
if (std::holds_alternative<std::string>(result)) {
blog(LOG_WARNING, "%s", std::get<std::string>(result).c_str());
return;
}
var->SetValue(std::get<double>(result));
}
bool MacroActionVariable::PerformAction() bool MacroActionVariable::PerformAction()
{ {
auto var = GetVariableByName(_variableName); auto var = _variable.lock();
if (!var) { if (!var) {
return true; return true;
} }
@@ -110,7 +132,7 @@ bool MacroActionVariable::PerformAction()
apppend(*var, _strValue); apppend(*var, _strValue);
break; break;
case Type::APPEND_VAR: { case Type::APPEND_VAR: {
auto var2 = GetVariableByName(_variable2Name); auto var2 = _variable2.lock();
if (!var2) { if (!var2) {
return true; return true;
} }
@@ -140,19 +162,27 @@ bool MacroActionVariable::PerformAction()
break; break;
} }
case Type::ROUND_TO_INT: { case Type::ROUND_TO_INT: {
double curValue; auto curValue = var->DoubleValue();
if (!var->DoubleValue(curValue)) { if (!curValue.has_value()) {
return true; return true;
} }
var->SetValue(std::to_string(int(std::round(curValue)))); var->SetValue(std::to_string(int(std::round(*curValue))));
return true; return true;
} }
case Type::SUBSTRING: { case Type::SUBSTRING: {
if (_regex.Enabled()) { if (_regex.Enabled()) {
HandleRegexSubString(var); HandleRegexSubString(var.get());
return true; return true;
} }
HandleIndexSubString(var); HandleIndexSubString(var.get());
return true;
}
case Type::FIND_AND_REPLACE: {
HandleFindAndReplace(var.get());
return true;
}
case Type::MATH_EXPRESSION: {
HandleMathExpression(var.get());
return true; return true;
} }
} }
@@ -163,8 +193,10 @@ bool MacroActionVariable::PerformAction()
bool MacroActionVariable::Save(obs_data_t *obj) const bool MacroActionVariable::Save(obs_data_t *obj) const
{ {
MacroAction::Save(obj); MacroAction::Save(obj);
obs_data_set_string(obj, "variableName", _variableName.c_str()); obs_data_set_string(obj, "variableName",
obs_data_set_string(obj, "variable2Name", _variable2Name.c_str()); GetWeakVariableName(_variable).c_str());
obs_data_set_string(obj, "variable2Name",
GetWeakVariableName(_variable2).c_str());
obs_data_set_string(obj, "strValue", _strValue.c_str()); obs_data_set_string(obj, "strValue", _strValue.c_str());
obs_data_set_double(obj, "numValue", _numValue); obs_data_set_double(obj, "numValue", _numValue);
obs_data_set_int(obj, "condition", static_cast<int>(_type)); obs_data_set_int(obj, "condition", static_cast<int>(_type));
@@ -173,15 +205,20 @@ bool MacroActionVariable::Save(obs_data_t *obj) const
obs_data_set_int(obj, "subStringSize", _subStringSize); obs_data_set_int(obj, "subStringSize", _subStringSize);
obs_data_set_string(obj, "regexPattern", _regexPattern.c_str()); obs_data_set_string(obj, "regexPattern", _regexPattern.c_str());
obs_data_set_int(obj, "regexMatchIdx", _regexMatchIdx); obs_data_set_int(obj, "regexMatchIdx", _regexMatchIdx);
obs_data_set_string(obj, "findStr", _findStr.c_str());
obs_data_set_string(obj, "replaceStr", _replaceStr.c_str());
_regex.Save(obj); _regex.Save(obj);
_mathExpression.Save(obj, "mathExpression");
return true; return true;
} }
bool MacroActionVariable::Load(obs_data_t *obj) bool MacroActionVariable::Load(obs_data_t *obj)
{ {
MacroAction::Load(obj); MacroAction::Load(obj);
_variableName = obs_data_get_string(obj, "variableName"); _variable =
_variable2Name = obs_data_get_string(obj, "variable2Name"); GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
_variable2 = GetWeakVariableByName(
obs_data_get_string(obj, "variable2Name"));
_strValue = obs_data_get_string(obj, "strValue"); _strValue = obs_data_get_string(obj, "strValue");
_numValue = obs_data_get_double(obj, "numValue"); _numValue = obs_data_get_double(obj, "numValue");
_type = static_cast<Type>(obs_data_get_int(obj, "condition")); _type = static_cast<Type>(obs_data_get_int(obj, "condition"));
@@ -191,6 +228,9 @@ bool MacroActionVariable::Load(obs_data_t *obj)
_regex.Load(obj); _regex.Load(obj);
_regexPattern = obs_data_get_string(obj, "regexPattern"); _regexPattern = obs_data_get_string(obj, "regexPattern");
_regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx"); _regexMatchIdx = obs_data_get_int(obj, "regexMatchIdx");
_findStr = obs_data_get_string(obj, "findStr");
_replaceStr = obs_data_get_string(obj, "replaceStr");
_mathExpression.Load(obj, "mathExpression");
return true; return true;
} }
@@ -202,7 +242,7 @@ bool MacroActionVariable::PostLoad()
std::string MacroActionVariable::GetShortDesc() const std::string MacroActionVariable::GetShortDesc() const
{ {
return _variableName; return GetWeakVariableName(_variable);
} }
void MacroActionVariable::SetSegmentIndexValue(int value) void MacroActionVariable::SetSegmentIndexValue(int value)
@@ -303,7 +343,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
_subStringSize(new QSpinBox()), _subStringSize(new QSpinBox()),
_regex(new RegexConfigWidget(parent)), _regex(new RegexConfigWidget(parent)),
_regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)), _regexPattern(new ResizingPlainTextEdit(this, 10, 1, 1)),
_regexMatchIdx(new QSpinBox()) _regexMatchIdx(new QSpinBox()),
_findReplaceLayout(new QHBoxLayout()),
_findStr(new ResizingPlainTextEdit(this, 10, 1, 1)),
_replaceStr(new ResizingPlainTextEdit(this, 10, 1, 1)),
_mathExpression(new VariableLineEdit(this)),
_mathExpressionResult(new QLabel())
{ {
_numValue->setMinimum(-9999999999); _numValue->setMinimum(-9999999999);
_numValue->setMaximum(9999999999); _numValue->setMaximum(9999999999);
@@ -348,6 +393,12 @@ MacroActionVariableEdit::MacroActionVariableEdit(
SLOT(RegexPatternChanged())); SLOT(RegexPatternChanged()));
QWidget::connect(_regexMatchIdx, SIGNAL(valueChanged(int)), this, QWidget::connect(_regexMatchIdx, SIGNAL(valueChanged(int)), this,
SLOT(RegexMatchIdxChanged(int))); SLOT(RegexMatchIdxChanged(int)));
QWidget::connect(_findStr, SIGNAL(textChanged()), this,
SLOT(FindStrValueChanged()));
QWidget::connect(_replaceStr, SIGNAL(textChanged()), this,
SLOT(ReplaceStrValueChanged()));
QWidget::connect(_mathExpression, SIGNAL(editingFinished()), this,
SLOT(MathExpressionChanged()));
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{variables}}", _variables}, {"{{variables}}", _variables},
@@ -359,6 +410,9 @@ MacroActionVariableEdit::MacroActionVariableEdit(
{"{{subStringStart}}", _subStringStart}, {"{{subStringStart}}", _subStringStart},
{"{{subStringSize}}", _subStringSize}, {"{{subStringSize}}", _subStringSize},
{"{{regexMatchIdx}}", _regexMatchIdx}, {"{{regexMatchIdx}}", _regexMatchIdx},
{"{{findStr}}", _findStr},
{"{{replaceStr}}", _replaceStr},
{"{{mathExpression}}", _mathExpression},
}; };
auto entryLayout = new QHBoxLayout; auto entryLayout = new QHBoxLayout;
placeWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"), placeWidgets(obs_module_text("AdvSceneSwitcher.action.variable.entry"),
@@ -374,6 +428,11 @@ MacroActionVariableEdit::MacroActionVariableEdit(
"AdvSceneSwitcher.action.variable.entry.substringRegex"), "AdvSceneSwitcher.action.variable.entry.substringRegex"),
_subStringRegexEntryLayout, widgetPlaceholders); _subStringRegexEntryLayout, widgetPlaceholders);
placeWidgets(
obs_module_text(
"AdvSceneSwitcher.action.variable.entry.findAndReplace"),
_findReplaceLayout, widgetPlaceholders, false);
auto regexConfigLayout = new QHBoxLayout; auto regexConfigLayout = new QHBoxLayout;
regexConfigLayout->addWidget(_regex); regexConfigLayout->addWidget(_regex);
regexConfigLayout->addStretch(); regexConfigLayout->addStretch();
@@ -388,6 +447,8 @@ MacroActionVariableEdit::MacroActionVariableEdit(
layout->addLayout(_substringLayout); layout->addLayout(_substringLayout);
layout->addWidget(_segmentValueStatus); layout->addWidget(_segmentValueStatus);
layout->addWidget(_segmentValue); layout->addWidget(_segmentValue);
layout->addLayout(_findReplaceLayout);
layout->addWidget(_mathExpressionResult);
setLayout(layout); setLayout(layout);
_entryData = entryData; _entryData = entryData;
@@ -406,8 +467,8 @@ void MacroActionVariableEdit::UpdateEntryData()
return; return;
} }
_variables->SetVariable(_entryData->_variableName); _variables->SetVariable(_entryData->_variable);
_variables2->SetVariable(_entryData->_variable2Name); _variables2->SetVariable(_entryData->_variable2);
_actions->setCurrentIndex(static_cast<int>(_entryData->_type)); _actions->setCurrentIndex(static_cast<int>(_entryData->_type));
_strValue->setPlainText(QString::fromStdString(_entryData->_strValue)); _strValue->setPlainText(QString::fromStdString(_entryData->_strValue));
_numValue->setValue(_entryData->_numValue); _numValue->setValue(_entryData->_numValue);
@@ -418,6 +479,10 @@ void MacroActionVariableEdit::UpdateEntryData()
_regexPattern->setPlainText( _regexPattern->setPlainText(
QString::fromStdString(_entryData->_regexPattern)); QString::fromStdString(_entryData->_regexPattern));
_regexMatchIdx->setValue(_entryData->_regexMatchIdx + 1); _regexMatchIdx->setValue(_entryData->_regexMatchIdx + 1);
_findStr->setPlainText(QString::fromStdString(_entryData->_findStr));
_replaceStr->setPlainText(
QString::fromStdString(_entryData->_replaceStr));
_mathExpression->setText(_entryData->_mathExpression);
SetWidgetVisibility(); SetWidgetVisibility();
} }
@@ -428,7 +493,7 @@ void MacroActionVariableEdit::VariableChanged(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_variableName = text.toStdString(); _entryData->_variable = GetWeakVariableByQString(text);
} }
void MacroActionVariableEdit::Variable2Changed(const QString &text) void MacroActionVariableEdit::Variable2Changed(const QString &text)
@@ -438,7 +503,7 @@ void MacroActionVariableEdit::Variable2Changed(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_variable2Name = text.toStdString(); _entryData->_variable2 = GetWeakVariableByQString(text);
} }
void MacroActionVariableEdit::ActionChanged(int value) void MacroActionVariableEdit::ActionChanged(int value)
@@ -467,6 +532,7 @@ void MacroActionVariableEdit::StrValueChanged()
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_strValue = _strValue->toPlainText().toStdString(); _entryData->_strValue = _strValue->toPlainText().toStdString();
adjustSize(); adjustSize();
updateGeometry();
} }
void MacroActionVariableEdit::NumValueChanged(double val) void MacroActionVariableEdit::NumValueChanged(double val)
@@ -623,6 +689,7 @@ void MacroActionVariableEdit::RegexPatternChanged()
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_regexPattern = _regexPattern->toPlainText().toStdString(); _entryData->_regexPattern = _regexPattern->toPlainText().toStdString();
adjustSize(); adjustSize();
updateGeometry();
} }
void MacroActionVariableEdit::RegexMatchIdxChanged(int val) void MacroActionVariableEdit::RegexMatchIdxChanged(int val)
@@ -635,6 +702,52 @@ void MacroActionVariableEdit::RegexMatchIdxChanged(int val)
_entryData->_regexMatchIdx = val - 1; _entryData->_regexMatchIdx = val - 1;
} }
void MacroActionVariableEdit::FindStrValueChanged()
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_findStr = _findStr->toPlainText().toStdString();
adjustSize();
updateGeometry();
}
void MacroActionVariableEdit::ReplaceStrValueChanged()
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_replaceStr = _replaceStr->toPlainText().toStdString();
adjustSize();
updateGeometry();
}
void MacroActionVariableEdit::MathExpressionChanged()
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_mathExpression = _mathExpression->text().toStdString();
// In case of invalid expression display an error
auto result = EvalMathExpression(_entryData->_mathExpression);
auto hasError = std::holds_alternative<std::string>(result);
if (hasError) {
_mathExpressionResult->setText(
QString::fromStdString(std::get<std::string>(result)));
}
_mathExpressionResult->setVisible(hasError);
adjustSize();
updateGeometry();
}
void MacroActionVariableEdit::MarkSelectedSegment() void MacroActionVariableEdit::MarkSelectedSegment()
{ {
if (switcher->disableHints) { if (switcher->disableHints) {
@@ -710,6 +823,12 @@ void MacroActionVariableEdit::SetWidgetVisibility()
setLayoutVisible(_subStringRegexEntryLayout, showRegex); setLayoutVisible(_subStringRegexEntryLayout, showRegex);
_regexPattern->setVisible(showRegex); _regexPattern->setVisible(showRegex);
} }
setLayoutVisible(_findReplaceLayout,
_entryData->_type ==
MacroActionVariable::Type::FIND_AND_REPLACE);
_mathExpression->setVisible(_entryData->_type ==
MacroActionVariable::Type::MATH_EXPRESSION);
_mathExpressionResult->hide();
adjustSize(); adjustSize();
updateGeometry(); updateGeometry();

View File

@@ -1,8 +1,8 @@
#pragma once #pragma once
#include "macro-action-edit.hpp" #include "macro-action-edit.hpp"
#include "resizing-text-edit.hpp"
#include "regex-config.hpp" #include "regex-config.hpp"
#include "variable.hpp" #include "resizing-text-edit.hpp"
#include "variable-line-edit.hpp"
class MacroActionVariable : public MacroAction { class MacroActionVariable : public MacroAction {
public: public:
@@ -31,11 +31,13 @@ public:
SET_ACTION_VALUE, SET_ACTION_VALUE,
ROUND_TO_INT, ROUND_TO_INT,
SUBSTRING, SUBSTRING,
FIND_AND_REPLACE,
MATH_EXPRESSION,
}; };
Type _type = Type::SET_FIXED_VALUE; Type _type = Type::SET_FIXED_VALUE;
std::string _variableName = ""; std::weak_ptr<Variable> _variable;
std::string _variable2Name = ""; std::weak_ptr<Variable> _variable2;
std::string _strValue = ""; std::string _strValue = "";
double _numValue = 0; double _numValue = 0;
int _subStringStart = 0; int _subStringStart = 0;
@@ -43,11 +45,19 @@ public:
RegexConfig _regex = RegexConfig::PartialMatchRegexConfig(); RegexConfig _regex = RegexConfig::PartialMatchRegexConfig();
std::string _regexPattern = ".*"; std::string _regexPattern = ".*";
int _regexMatchIdx = 0; int _regexMatchIdx = 0;
std::string _findStr = obs_module_text(
"AdvSceneSwitcher.action.variable.findAndReplace.find");
std::string _replaceStr = obs_module_text(
"AdvSceneSwitcher.action.variable.findAndReplace.replace");
StringVariable _mathExpression = obs_module_text(
"AdvSceneSwitcher.action.variable.mathExpression.example");
private: private:
void DecrementCurrentSegmentVariableRef(); void DecrementCurrentSegmentVariableRef();
void HandleIndexSubString(Variable *); void HandleIndexSubString(Variable *);
void HandleRegexSubString(Variable *); void HandleRegexSubString(Variable *);
void HandleFindAndReplace(Variable *);
void HandleMathExpression(Variable *);
std::weak_ptr<MacroSegment> _macroSegment; std::weak_ptr<MacroSegment> _macroSegment;
int _segmentIdxLoadValue = -1; int _segmentIdxLoadValue = -1;
@@ -85,6 +95,9 @@ private slots:
void RegexChanged(RegexConfig conf); void RegexChanged(RegexConfig conf);
void RegexPatternChanged(); void RegexPatternChanged();
void RegexMatchIdxChanged(int val); void RegexMatchIdxChanged(int val);
void FindStrValueChanged();
void ReplaceStrValueChanged();
void MathExpressionChanged();
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);
@@ -106,6 +119,11 @@ protected:
RegexConfigWidget *_regex; RegexConfigWidget *_regex;
ResizingPlainTextEdit *_regexPattern; ResizingPlainTextEdit *_regexPattern;
QSpinBox *_regexMatchIdx; QSpinBox *_regexMatchIdx;
QHBoxLayout *_findReplaceLayout;
ResizingPlainTextEdit *_findStr;
ResizingPlainTextEdit *_replaceStr;
VariableLineEdit *_mathExpression;
QLabel *_mathExpressionResult;
std::shared_ptr<MacroActionVariable> _entryData; std::shared_ptr<MacroActionVariable> _entryData;
private: private:

View File

@@ -34,14 +34,14 @@ bool MacroActionWait::PerformAction()
{ {
double sleepDuration; double sleepDuration;
if (_waitType == WaitType::FIXED) { if (_waitType == WaitType::FIXED) {
sleepDuration = _duration.seconds; sleepDuration = _duration.Seconds();
} else { } else {
double min = (_duration.seconds < _duration2.seconds) double min = (_duration.Seconds() < _duration2.Seconds())
? _duration.seconds ? _duration.Seconds()
: _duration2.seconds; : _duration2.Seconds();
double max = (_duration.seconds < _duration2.seconds) double max = (_duration.Seconds() < _duration2.Seconds())
? _duration2.seconds ? _duration2.Seconds()
: _duration.seconds; : _duration.Seconds();
std::uniform_real_distribution<double> unif(min, max); std::uniform_real_distribution<double> unif(min, max);
sleepDuration = unif(re); sleepDuration = unif(re);
} }
@@ -62,8 +62,9 @@ bool MacroActionWait::Save(obs_data_t *obj) const
{ {
MacroAction::Save(obj); MacroAction::Save(obj);
_duration.Save(obj); _duration.Save(obj);
_duration2.Save(obj, "seconds2", "displayUnit2"); _duration2.Save(obj, "duration2");
obs_data_set_int(obj, "waitType", static_cast<int>(_waitType)); obs_data_set_int(obj, "waitType", static_cast<int>(_waitType));
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -71,7 +72,14 @@ bool MacroActionWait::Load(obs_data_t *obj)
{ {
MacroAction::Load(obj); MacroAction::Load(obj);
_duration.Load(obj); _duration.Load(obj);
_duration2.Load(obj, "seconds2", "displayUnit2"); // TODO: remove this fallback
if (obs_data_get_int(obj, "version") == 1) {
_duration2.Load(obj, "duration2");
} else {
_duration2.Load(obj, "seconds2");
_duration2.SetUnit(static_cast<Duration::Unit>(
obs_data_get_int(obj, "displayUnit2")));
}
_waitType = static_cast<WaitType>(obs_data_get_int(obj, "waitType")); _waitType = static_cast<WaitType>(obs_data_get_int(obj, "waitType"));
return true; return true;
} }
@@ -93,14 +101,10 @@ MacroActionWaitEdit::MacroActionWaitEdit(
populateTypeSelection(_waitType); populateTypeSelection(_waitType);
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this, QWidget::connect(_duration2, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationUnitChanged(DurationUnit))); this, SLOT(Duration2Changed(const Duration &)));
QWidget::connect(_duration2, SIGNAL(DurationChanged(double)), this,
SLOT(Duration2Changed(double)));
QWidget::connect(_duration2, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(Duration2UnitChanged(DurationUnit)));
QWidget::connect(_waitType, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_waitType, SIGNAL(currentIndexChanged(int)), this,
SLOT(TypeChanged(int))); SLOT(TypeChanged(int)));
@@ -180,42 +184,22 @@ void MacroActionWaitEdit::TypeChanged(int value)
_entryData->_waitType = type; _entryData->_waitType = type;
} }
void MacroActionWaitEdit::DurationChanged(double seconds) void MacroActionWaitEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
} }
void MacroActionWaitEdit::DurationUnitChanged(DurationUnit unit) void MacroActionWaitEdit::Duration2Changed(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.displayUnit = unit; _entryData->_duration2 = dur;
}
void MacroActionWaitEdit::Duration2Changed(double seconds)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration2.seconds = seconds;
}
void MacroActionWaitEdit::Duration2UnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration2.displayUnit = unit;
} }

View File

@@ -49,10 +49,8 @@ public:
} }
private slots: private slots:
void DurationChanged(double value); void DurationChanged(const Duration &value);
void DurationUnitChanged(DurationUnit unit); void Duration2Changed(const Duration &value);
void Duration2Changed(double value);
void Duration2UnitChanged(DurationUnit unit);
void TypeChanged(int value); void TypeChanged(int value);
protected: protected:

View File

@@ -18,7 +18,7 @@ static std::map<MacroActionWebsocket::Type, std::string> actionTypes = {
void MacroActionWebsocket::SendRequest() void MacroActionWebsocket::SendRequest()
{ {
auto connection = GetConnectionByName(_connection); auto connection = _connection.lock();
if (!connection) { if (!connection) {
return; return;
} }
@@ -46,7 +46,7 @@ void MacroActionWebsocket::LogAction() const
switch (_type) { switch (_type) {
case MacroActionWebsocket::Type::REQUEST: case MacroActionWebsocket::Type::REQUEST:
vblog(LOG_INFO, "sent msg \"%s\" via \"%s\"", _message.c_str(), vblog(LOG_INFO, "sent msg \"%s\" via \"%s\"", _message.c_str(),
_connection.c_str()); GetWeakConnectionName(_connection).c_str());
break; break;
case MacroActionWebsocket::Type::EVENT: case MacroActionWebsocket::Type::EVENT:
vblog(LOG_INFO, "sent event \"%s\" to connected clients", vblog(LOG_INFO, "sent event \"%s\" to connected clients",
@@ -62,7 +62,8 @@ bool MacroActionWebsocket::Save(obs_data_t *obj) const
MacroAction::Save(obj); MacroAction::Save(obj);
obs_data_set_int(obj, "type", static_cast<int>(_type)); obs_data_set_int(obj, "type", static_cast<int>(_type));
_message.Save(obj, "message"); _message.Save(obj, "message");
obs_data_set_string(obj, "connection", _connection.c_str()); obs_data_set_string(obj, "connection",
GetWeakConnectionName(_connection).c_str());
return true; return true;
} }
@@ -71,14 +72,15 @@ bool MacroActionWebsocket::Load(obs_data_t *obj)
MacroAction::Load(obj); MacroAction::Load(obj);
_type = static_cast<Type>(obs_data_get_int(obj, "type")); _type = static_cast<Type>(obs_data_get_int(obj, "type"));
_message.Load(obj, "message"); _message.Load(obj, "message");
_connection = obs_data_get_string(obj, "connection"); _connection =
GetWeakConnectionByName(obs_data_get_string(obj, "connection"));
return true; return true;
} }
std::string MacroActionWebsocket::GetShortDesc() const std::string MacroActionWebsocket::GetShortDesc() const
{ {
if (_type == Type::REQUEST) { if (_type == Type::REQUEST) {
return _connection; return GetWeakConnectionName(_connection);
} }
return ""; return "";
} }
@@ -206,6 +208,6 @@ void MacroActionWebsocketEdit::ConnectionSelectionChanged(
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_connection = connection.toStdString(); _entryData->_connection = GetWeakConnectionByQString(connection);
emit(HeaderInfoChanged(connection)); emit(HeaderInfoChanged(connection));
} }

View File

@@ -28,9 +28,8 @@ public:
}; };
Type _type = Type::REQUEST; Type _type = Type::REQUEST;
VariableResolvingString _message = StringVariable _message = obs_module_text("AdvSceneSwitcher.enterText");
obs_module_text("AdvSceneSwitcher.enterText"); std::weak_ptr<Connection> _connection;
std::string _connection;
private: private:
void SendRequest(); void SendRequest();

View File

@@ -29,9 +29,10 @@ MacroRefAction::MacroRefAction(Macro *m, bool supportsVariableValue)
{ {
} }
void MacroRefAction::ResolveMacroRef() bool MacroRefAction::PostLoad()
{ {
_macro.UpdateRef(); _macro.PostLoad();
return true;
} }
MultiMacroRefAction::MultiMacroRefAction(Macro *m, bool supportsVariableValue) MultiMacroRefAction::MultiMacroRefAction(Macro *m, bool supportsVariableValue)
@@ -39,9 +40,10 @@ MultiMacroRefAction::MultiMacroRefAction(Macro *m, bool supportsVariableValue)
{ {
} }
void MultiMacroRefAction::ResolveMacroRef() bool MultiMacroRefAction::PostLoad()
{ {
for (auto &m : _macros) { for (auto &macro : _macros) {
m.UpdateRef(); macro.PostLoad();
} }
return true;
} }

View File

@@ -15,13 +15,15 @@ public:
class MacroRefAction : virtual public MacroAction { class MacroRefAction : virtual public MacroAction {
public: public:
MacroRefAction(Macro *m, bool supportsVariableValue = false); MacroRefAction(Macro *m, bool supportsVariableValue = false);
void ResolveMacroRef(); bool PostLoad() override;
MacroRef _macro; MacroRef _macro;
}; };
class MultiMacroRefAction : virtual public MacroAction { class MultiMacroRefAction : virtual public MacroAction {
public: public:
MultiMacroRefAction(Macro *m, bool supportsVariableValue = false); MultiMacroRefAction(Macro *m, bool supportsVariableValue = false);
void ResolveMacroRef(); bool PostLoad() override;
std::vector<MacroRef> _macros; std::vector<MacroRef> _macros;
}; };

View File

@@ -205,15 +205,16 @@ bool MacroConditionAudio::Save(obs_data_t *obj) const
{ {
MacroCondition::Save(obj); MacroCondition::Save(obj);
_audioSource.Save(obj, "audioSource"); _audioSource.Save(obj, "audioSource");
obs_data_set_int(obj, "volume", _volume);
obs_data_set_int(obj, "syncOffset", _syncOffset);
obs_data_set_int(obj, "monitor", _monitorType); obs_data_set_int(obj, "monitor", _monitorType);
obs_data_set_double(obj, "balance", _balance); _volume.Save(obj, "volume");
_syncOffset.Save(obj, "syncOffset");
_balance.Save(obj, "balance");
obs_data_set_int(obj, "checkType", static_cast<int>(_checkType)); obs_data_set_int(obj, "checkType", static_cast<int>(_checkType));
obs_data_set_int(obj, "outputCondition", obs_data_set_int(obj, "outputCondition",
static_cast<int>(_outputCondition)); static_cast<int>(_outputCondition));
obs_data_set_int(obj, "volumeCondition", obs_data_set_int(obj, "volumeCondition",
static_cast<int>(_volumeCondition)); static_cast<int>(_volumeCondition));
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -238,11 +239,17 @@ bool MacroConditionAudio::Load(obs_data_t *obj)
{ {
MacroCondition::Load(obj); MacroCondition::Load(obj);
_audioSource.Load(obj, "audioSource"); _audioSource.Load(obj, "audioSource");
_volume = obs_data_get_int(obj, "volume");
_syncOffset = obs_data_get_int(obj, "syncOffset");
_monitorType = static_cast<obs_monitoring_type>( _monitorType = static_cast<obs_monitoring_type>(
obs_data_get_int(obj, "monitor")); obs_data_get_int(obj, "monitor"));
_balance = obs_data_get_double(obj, "balance"); if (!obs_data_has_user_value(obj, "version")) {
_volume = obs_data_get_int(obj, "volume");
_syncOffset = obs_data_get_int(obj, "syncOffset");
_balance = obs_data_get_double(obj, "balance");
} else {
_volume.Load(obj, "volume");
_syncOffset.Load(obj, "syncOffset");
_balance.Load(obj, "balance");
}
_checkType = static_cast<Type>(obs_data_get_int(obj, "checkType")); _checkType = static_cast<Type>(obs_data_get_int(obj, "checkType"));
_outputCondition = static_cast<OutputCondition>( _outputCondition = static_cast<OutputCondition>(
obs_data_get_int(obj, "outputCondition")); obs_data_get_int(obj, "outputCondition"));
@@ -320,8 +327,8 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
_checkTypes(new QComboBox()), _checkTypes(new QComboBox()),
_sources(new SourceSelectionWidget(this, QStringList(), true)), _sources(new SourceSelectionWidget(this, QStringList(), true)),
_condition(new QComboBox()), _condition(new QComboBox()),
_volume(new QSpinBox()), _volume(new VariableSpinBox()),
_syncOffset(new QSpinBox()), _syncOffset(new VariableSpinBox()),
_monitorTypes(new QComboBox), _monitorTypes(new QComboBox),
_balance(new SliderSpinBox(0., 1., "")) _balance(new SliderSpinBox(0., 1., ""))
{ {
@@ -339,14 +346,21 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(CheckTypeChanged(int))); SLOT(CheckTypeChanged(int)));
QWidget::connect(_volume, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(VolumeThresholdChanged(int))); _volume,
QWidget::connect(_syncOffset, SIGNAL(valueChanged(int)), this, SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
SLOT(SyncOffsetChanged(int))); this,
SLOT(VolumeThresholdChanged(const NumberVariable<int> &)));
QWidget::connect(
_syncOffset,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(SyncOffsetChanged(const NumberVariable<int> &)));
QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_monitorTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(MonitorTypeChanged(int))); SLOT(MonitorTypeChanged(int)));
QWidget::connect(_balance, SIGNAL(DoubleValueChanged(double)), this, QWidget::connect(
SLOT(BalanceChanged(double))); _balance,
SIGNAL(DoubleValueChanged(const NumberVariable<double> &)),
this, SLOT(BalanceChanged(const NumberVariable<double> &)));
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int))); SLOT(ConditionChanged(int)));
QWidget::connect(_sources, QWidget::connect(_sources,
@@ -391,8 +405,8 @@ void MacroConditionAudioEdit::UpdateVolmeterSource()
layout->addWidget(_volMeter); layout->addWidget(_volMeter);
QWidget::connect(_volMeter->GetSlider(), SIGNAL(valueChanged(int)), QWidget::connect(_volMeter->GetSlider(), SIGNAL(valueChanged(int)),
_volume, SLOT(setValue(int))); _volume, SLOT(SetFixedValue(int)));
QWidget::connect(_volume, SIGNAL(valueChanged(int)), QWidget::connect(_volume, SIGNAL(FixedValueChanged(int)),
_volMeter->GetSlider(), SLOT(setValue(int))); _volMeter->GetSlider(), SLOT(setValue(int)));
// Slider will default to 0 so set it manually once // Slider will default to 0 so set it manually once
@@ -405,16 +419,19 @@ void MacroConditionAudioEdit::SourceChanged(const SourceSelection &source)
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); {
_entryData->_audioSource = source; std::lock_guard<std::mutex> lock(switcher->m);
_entryData->ResetVolmeter(); _entryData->_audioSource = source;
_entryData->ResetVolmeter();
}
UpdateVolmeterSource(); UpdateVolmeterSource();
SetWidgetVisibility(); SetWidgetVisibility();
emit HeaderInfoChanged( emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
void MacroConditionAudioEdit::VolumeThresholdChanged(int vol) void MacroConditionAudioEdit::VolumeThresholdChanged(
const NumberVariable<int> &vol)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -424,7 +441,7 @@ void MacroConditionAudioEdit::VolumeThresholdChanged(int vol)
_entryData->_volume = vol; _entryData->_volume = vol;
} }
void MacroConditionAudioEdit::SyncOffsetChanged(int value) void MacroConditionAudioEdit::SyncOffsetChanged(const NumberVariable<int> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -444,7 +461,7 @@ void MacroConditionAudioEdit::MonitorTypeChanged(int value)
_entryData->_monitorType = static_cast<obs_monitoring_type>(value); _entryData->_monitorType = static_cast<obs_monitoring_type>(value);
} }
void MacroConditionAudioEdit::BalanceChanged(double value) void MacroConditionAudioEdit::BalanceChanged(const NumberVariable<double> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -504,8 +521,8 @@ void MacroConditionAudioEdit::UpdateEntryData()
} }
_sources->SetSource(_entryData->_audioSource); _sources->SetSource(_entryData->_audioSource);
_volume->setValue(_entryData->_volume); _volume->SetValue(_entryData->_volume);
_syncOffset->setValue(_entryData->_syncOffset); _syncOffset->SetValue(_entryData->_syncOffset);
_monitorTypes->setCurrentIndex(_entryData->_monitorType); _monitorTypes->setCurrentIndex(_entryData->_monitorType);
_balance->SetDoubleValue(_entryData->_balance); _balance->SetDoubleValue(_entryData->_balance);
_checkTypes->setCurrentIndex(_checkTypes->findData( _checkTypes->setCurrentIndex(_checkTypes->findData(

View File

@@ -50,10 +50,10 @@ public:
}; };
SourceSelection _audioSource; SourceSelection _audioSource;
int _volume = 0; NumberVariable<int> _volume = 0;
int64_t _syncOffset = 0; NumberVariable<int> _syncOffset = 0;
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE; obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
double _balance = 0.5; NumberVariable<double> _balance = 0.5;
Type _checkType = Type::OUTPUT_VOLUME; Type _checkType = Type::OUTPUT_VOLUME;
OutputCondition _outputCondition = OutputCondition::ABOVE; OutputCondition _outputCondition = OutputCondition::ABOVE;
VolumeCondition _volumeCondition = VolumeCondition::ABOVE; VolumeCondition _volumeCondition = VolumeCondition::ABOVE;
@@ -90,12 +90,12 @@ public:
private slots: private slots:
void SourceChanged(const SourceSelection &); void SourceChanged(const SourceSelection &);
void VolumeThresholdChanged(int vol); void VolumeThresholdChanged(const NumberVariable<int> &vol);
void ConditionChanged(int cond); void ConditionChanged(int cond);
void CheckTypeChanged(int cond); void CheckTypeChanged(int cond);
void SyncOffsetChanged(int value); void SyncOffsetChanged(const NumberVariable<int> &value);
void MonitorTypeChanged(int value); void MonitorTypeChanged(int value);
void BalanceChanged(double value); void BalanceChanged(const NumberVariable<double> &value);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);
@@ -104,8 +104,8 @@ protected:
QComboBox *_checkTypes; QComboBox *_checkTypes;
SourceSelectionWidget *_sources; SourceSelectionWidget *_sources;
QComboBox *_condition; QComboBox *_condition;
QSpinBox *_volume; VariableSpinBox *_volume;
QSpinBox *_syncOffset; VariableSpinBox *_syncOffset;
QComboBox *_monitorTypes; QComboBox *_monitorTypes;
SliderSpinBox *_balance; SliderSpinBox *_balance;
VolControl *_volMeter = nullptr; VolControl *_volMeter = nullptr;

View File

@@ -77,10 +77,11 @@ bool MacroConditionCursor::Save(obs_data_t *obj) const
MacroCondition::Save(obj); MacroCondition::Save(obj);
obs_data_set_int(obj, "condition", static_cast<int>(_condition)); obs_data_set_int(obj, "condition", static_cast<int>(_condition));
obs_data_set_int(obj, "button", static_cast<int>(_button)); obs_data_set_int(obj, "button", static_cast<int>(_button));
obs_data_set_int(obj, "minX", _minX); _minX.Save(obj, "minX");
obs_data_set_int(obj, "minY", _minY); _minY.Save(obj, "minY");
obs_data_set_int(obj, "maxX", _maxX); _maxX.Save(obj, "maxX");
obs_data_set_int(obj, "maxY", _maxY); _maxY.Save(obj, "maxY");
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -89,10 +90,17 @@ bool MacroConditionCursor::Load(obs_data_t *obj)
MacroCondition::Load(obj); MacroCondition::Load(obj);
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition")); _condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
_button = static_cast<Button>(obs_data_get_int(obj, "button")); _button = static_cast<Button>(obs_data_get_int(obj, "button"));
_minX = obs_data_get_int(obj, "minX"); if (!obs_data_has_user_value(obj, "version")) {
_minY = obs_data_get_int(obj, "minY"); _minX = obs_data_get_int(obj, "minX");
_maxX = obs_data_get_int(obj, "maxX"); _minY = obs_data_get_int(obj, "minY");
_maxY = obs_data_get_int(obj, "maxY"); _maxX = obs_data_get_int(obj, "maxX");
_maxY = obs_data_get_int(obj, "maxY");
} else {
_minX.Load(obj, "minX");
_minY.Load(obj, "minY");
_maxX.Load(obj, "maxX");
_maxY.Load(obj, "maxY");
}
return true; return true;
} }
@@ -115,10 +123,10 @@ static inline void populateButtonSelection(QComboBox *list)
MacroConditionCursorEdit::MacroConditionCursorEdit( MacroConditionCursorEdit::MacroConditionCursorEdit(
QWidget *parent, std::shared_ptr<MacroConditionCursor> entryData) QWidget *parent, std::shared_ptr<MacroConditionCursor> entryData)
: QWidget(parent), : QWidget(parent),
_minX(new QSpinBox()), _minX(new VariableSpinBox()),
_minY(new QSpinBox()), _minY(new VariableSpinBox()),
_maxX(new QSpinBox()), _maxX(new VariableSpinBox()),
_maxY(new QSpinBox()), _maxY(new VariableSpinBox()),
_conditions(new QComboBox()), _conditions(new QComboBox()),
_buttons(new QComboBox()), _buttons(new QComboBox()),
_frameToggle(new QPushButton(obs_module_text( _frameToggle(new QPushButton(obs_module_text(
@@ -151,14 +159,22 @@ MacroConditionCursorEdit::MacroConditionCursorEdit(
SLOT(ConditionChanged(int))); SLOT(ConditionChanged(int)));
QWidget::connect(_buttons, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_buttons, SIGNAL(currentIndexChanged(int)), this,
SLOT(ButtonChanged(int))); SLOT(ButtonChanged(int)));
QWidget::connect(_minX, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(MinXChanged(int))); _minX,
QWidget::connect(_minY, SIGNAL(valueChanged(int)), this, SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
SLOT(MinYChanged(int))); this, SLOT(MinXChanged(const NumberVariable<int> &)));
QWidget::connect(_maxX, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(MaxXChanged(int))); _minY,
QWidget::connect(_maxY, SIGNAL(valueChanged(int)), this, SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
SLOT(MaxYChanged(int))); this, SLOT(MinYChanged(const NumberVariable<int> &)));
QWidget::connect(
_maxX,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(MaxXChanged(const NumberVariable<int> &)));
QWidget::connect(
_maxY,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(MaxYChanged(const NumberVariable<int> &)));
QWidget::connect(_frameToggle, SIGNAL(clicked()), this, QWidget::connect(_frameToggle, SIGNAL(clicked()), this,
SLOT(ToggleFrame())); SLOT(ToggleFrame()));
@@ -217,7 +233,7 @@ void MacroConditionCursorEdit::ButtonChanged(int index)
_buttons->itemData(index).toInt()); _buttons->itemData(index).toInt());
} }
void MacroConditionCursorEdit::MinXChanged(int pos) void MacroConditionCursorEdit::MinXChanged(const NumberVariable<int> &pos)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -228,7 +244,7 @@ void MacroConditionCursorEdit::MinXChanged(int pos)
SetupFrame(); SetupFrame();
} }
void MacroConditionCursorEdit::MinYChanged(int pos) void MacroConditionCursorEdit::MinYChanged(const NumberVariable<int> &pos)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -239,7 +255,7 @@ void MacroConditionCursorEdit::MinYChanged(int pos)
SetupFrame(); SetupFrame();
} }
void MacroConditionCursorEdit::MaxXChanged(int pos) void MacroConditionCursorEdit::MaxXChanged(const NumberVariable<int> &pos)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -250,7 +266,7 @@ void MacroConditionCursorEdit::MaxXChanged(int pos)
SetupFrame(); SetupFrame();
} }
void MacroConditionCursorEdit::MaxYChanged(int pos) void MacroConditionCursorEdit::MaxYChanged(const NumberVariable<int> &pos)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -334,18 +350,20 @@ void MacroConditionCursorEdit::SetupFrame()
Qt::WindowStaysOnTopHint); Qt::WindowStaysOnTopHint);
_frame.setAttribute(Qt::WA_TranslucentBackground, true); _frame.setAttribute(Qt::WA_TranslucentBackground, true);
if (_entryData) { if (!_entryData) {
QRect rect(_entryData->_minX, _entryData->_minY, return;
_entryData->_maxX - _entryData->_minX,
_entryData->_maxY - _entryData->_minY);
if (rect.size().height() == 0 || rect.size().width() == 0) {
_frame.setGeometry(0, 0, 1, 1);
return;
}
_frame.setGeometry(getScreenUnionRect().intersected(rect));
} }
QRect rect(_entryData->_minX, _entryData->_minY,
_entryData->_maxX - _entryData->_minX,
_entryData->_maxY - _entryData->_minY);
if (rect.size().height() <= 0 || rect.size().width() <= 0) {
_frame.setGeometry(0, 0, 1, 1);
return;
}
_frame.setGeometry(getScreenUnionRect().intersected(rect));
} }
void MacroConditionCursorEdit::UpdateEntryData() void MacroConditionCursorEdit::UpdateEntryData()
@@ -356,9 +374,9 @@ void MacroConditionCursorEdit::UpdateEntryData()
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition)); _conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
_buttons->setCurrentIndex(static_cast<int>(_entryData->_button)); _buttons->setCurrentIndex(static_cast<int>(_entryData->_button));
_minX->setValue(_entryData->_minX); _minX->SetValue(_entryData->_minX);
_minY->setValue(_entryData->_minY); _minY->SetValue(_entryData->_minY);
_maxX->setValue(_entryData->_maxX); _maxX->SetValue(_entryData->_maxX);
_maxY->setValue(_entryData->_maxY); _maxY->SetValue(_entryData->_maxY);
SetWidgetVisibility(); SetWidgetVisibility();
} }

View File

@@ -1,11 +1,12 @@
#pragma once #pragma once
#include "macro.hpp" #include "macro.hpp"
#include "striped-frame.hpp"
#include "variable-spinbox.hpp"
#include <QSpinBox> #include <QSpinBox>
#include <QComboBox> #include <QComboBox>
#include <QPushButton> #include <QPushButton>
#include <QTimer> #include <QTimer>
#include <QFrame>
class MacroConditionCursor : public MacroCondition { class MacroConditionCursor : public MacroCondition {
public: public:
@@ -33,7 +34,7 @@ public:
Condition _condition = Condition::REGION; Condition _condition = Condition::REGION;
Button _button = Button::LEFT; Button _button = Button::LEFT;
int _minX = 0, _minY = 0, _maxX = 0, _maxY = 0; NumberVariable<int> _minX = 0, _minY = 0, _maxX = 0, _maxY = 0;
private: private:
bool CheckClick(); bool CheckClick();
@@ -62,18 +63,18 @@ public:
private slots: private slots:
void ConditionChanged(int idx); void ConditionChanged(int idx);
void ButtonChanged(int idx); void ButtonChanged(int idx);
void MinXChanged(int pos); void MinXChanged(const NumberVariable<int> &pos);
void MinYChanged(int pos); void MinYChanged(const NumberVariable<int> &pos);
void MaxXChanged(int pos); void MaxXChanged(const NumberVariable<int> &pos);
void MaxYChanged(int pos); void MaxYChanged(const NumberVariable<int> &pos);
void UpdateCursorPos(); void UpdateCursorPos();
void ToggleFrame(); void ToggleFrame();
protected: protected:
QSpinBox *_minX; VariableSpinBox *_minX;
QSpinBox *_minY; VariableSpinBox *_minY;
QSpinBox *_maxX; VariableSpinBox *_maxX;
QSpinBox *_maxY; VariableSpinBox *_maxY;
QComboBox *_conditions; QComboBox *_conditions;
QComboBox *_buttons; QComboBox *_buttons;
QPushButton *_frameToggle; QPushButton *_frameToggle;
@@ -86,6 +87,6 @@ private:
void SetWidgetVisibility(); void SetWidgetVisibility();
void SetupFrame(); void SetupFrame();
QTimer _timer; QTimer _timer;
QFrame _frame; StripedFrame _frame;
bool _loading = true; bool _loading = true;
}; };

View File

@@ -165,8 +165,8 @@ bool MacroConditionDate::CheckRegularDate(int64_t msSinceLastCheck)
} }
if (match && _repeat) { if (match && _repeat) {
_dateTime = _dateTime.addSecs(_duration.seconds); _dateTime = _dateTime.addSecs(_duration.Seconds());
_dateTime2 = _dateTime2.addSecs(_duration.seconds); _dateTime2 = _dateTime2.addSecs(_duration.Seconds());
} }
return match; return match;
@@ -398,10 +398,8 @@ MacroConditionDateEdit::MacroConditionDateEdit(
SLOT(RepeatChanged(int))); SLOT(RepeatChanged(int)));
QWidget::connect(_updateOnRepeat, SIGNAL(stateChanged(int)), this, QWidget::connect(_updateOnRepeat, SIGNAL(stateChanged(int)), this,
SLOT(UpdateOnRepeatChanged(int))); SLOT(UpdateOnRepeatChanged(int)));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DurationUnitChanged(DurationUnit)));
QWidget::connect(_advancedSettingsTooggle, SIGNAL(clicked()), this, QWidget::connect(_advancedSettingsTooggle, SIGNAL(clicked()), this,
SLOT(AdvancedSettingsToggleClicked())); SLOT(AdvancedSettingsToggleClicked()));
QWidget::connect(_pattern, SIGNAL(editingFinished()), this, QWidget::connect(_pattern, SIGNAL(editingFinished()), this,
@@ -589,24 +587,14 @@ void MacroConditionDateEdit::UpdateOnRepeatChanged(int state)
_entryData->_updateOnRepeat = state; _entryData->_updateOnRepeat = state;
} }
void MacroConditionDateEdit::DurationChanged(double seconds) void MacroConditionDateEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
}
void MacroConditionDateEdit::DurationUnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.displayUnit = unit;
} }
void MacroConditionDateEdit::AdvancedSettingsToggleClicked() void MacroConditionDateEdit::AdvancedSettingsToggleClicked()

View File

@@ -100,8 +100,7 @@ private slots:
void IgnoreTimeChanged(int state); void IgnoreTimeChanged(int state);
void RepeatChanged(int state); void RepeatChanged(int state);
void UpdateOnRepeatChanged(int state); void UpdateOnRepeatChanged(int state);
void DurationChanged(double seconds); void DurationChanged(const Duration &seconds);
void DurationUnitChanged(DurationUnit unit);
void AdvancedSettingsToggleClicked(); void AdvancedSettingsToggleClicked();
void ShowNextMatch(); void ShowNextMatch();
void UpdateCurrentTime(); void UpdateCurrentTime();

View File

@@ -121,15 +121,14 @@ DurationModifierEdit::DurationModifierEdit(QWidget *parent)
_duration = new DurationSelection(parent); _duration = new DurationSelection(parent);
_toggle = new QPushButton(parent); _toggle = new QPushButton(parent);
_toggle->setMaximumWidth(22); _toggle->setMaximumWidth(22);
_toggle->setIcon( const auto path = QString::fromStdString(getDataFilePath(
QIcon(QString::fromStdString(getDataFilePath("res/time.svg")))); "res/images/" + GetThemeTypeName() + "Time.svg"));
_toggle->setIcon(QIcon(path));
populateDurationModifierTypes(_condition); populateDurationModifierTypes(_condition);
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
SLOT(_ModifierChanged(int))); SLOT(_ModifierChanged(int)));
QObject::connect(_duration, &DurationSelection::DurationChanged, this, QObject::connect(_duration, &DurationSelection::DurationChanged, this,
&DurationModifierEdit::DurationChanged); &DurationModifierEdit::DurationChanged);
QObject::connect(_duration, &DurationSelection::UnitChanged, this,
&DurationModifierEdit::UnitChanged);
QWidget::connect(_toggle, SIGNAL(clicked()), this, QWidget::connect(_toggle, SIGNAL(clicked()), this,
SLOT(ToggleClicked())); SLOT(ToggleClicked()));
@@ -150,11 +149,6 @@ void DurationModifierEdit::SetValue(DurationModifier &value)
_duration->setVisible(value.GetType() != DurationModifier::Type::NONE); _duration->setVisible(value.GetType() != DurationModifier::Type::NONE);
} }
void DurationModifierEdit::SetUnit(DurationUnit u)
{
_duration->SetUnit(u);
}
void DurationModifierEdit::SetDuration(const Duration &d) void DurationModifierEdit::SetDuration(const Duration &d)
{ {
_duration->SetDuration(d); _duration->SetDuration(d);
@@ -195,10 +189,8 @@ MacroConditionEdit::MacroConditionEdit(
QWidget::connect(_conditionSelection, QWidget::connect(_conditionSelection,
SIGNAL(currentTextChanged(const QString &)), this, SIGNAL(currentTextChanged(const QString &)), this,
SLOT(ConditionSelectionChanged(const QString &))); SLOT(ConditionSelectionChanged(const QString &)));
QWidget::connect(_dur, SIGNAL(DurationChanged(double)), this, QWidget::connect(_dur, SIGNAL(DurationChanged(const Duration &)), this,
SLOT(DurationChanged(double))); SLOT(DurationChanged(const Duration &)));
QWidget::connect(_dur, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DurationUnitChanged(DurationUnit)));
QWidget::connect(_dur, SIGNAL(ModifierChanged(DurationModifier::Type)), QWidget::connect(_dur, SIGNAL(ModifierChanged(DurationModifier::Type)),
this, this,
SLOT(DurationModifierChanged(DurationModifier::Type))); SLOT(DurationModifierChanged(DurationModifier::Type)));
@@ -324,7 +316,7 @@ void MacroConditionEdit::ConditionSelectionChanged(const QString &text)
SetFocusPolicyOfWidgets(); SetFocusPolicyOfWidgets();
} }
void MacroConditionEdit::DurationChanged(double seconds) void MacroConditionEdit::DurationChanged(const Duration &seconds)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -344,16 +336,6 @@ void MacroConditionEdit::DurationModifierChanged(DurationModifier::Type m)
(*_entryData)->SetDurationModifier(m); (*_entryData)->SetDurationModifier(m);
} }
void MacroConditionEdit::DurationUnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
(*_entryData)->SetDurationUnit(unit);
}
std::shared_ptr<MacroSegment> MacroConditionEdit::Data() std::shared_ptr<MacroSegment> MacroConditionEdit::Data()
{ {
return *_entryData; return *_entryData;

View File

@@ -35,15 +35,13 @@ class DurationModifierEdit : public QWidget {
public: public:
DurationModifierEdit(QWidget *parent = nullptr); DurationModifierEdit(QWidget *parent = nullptr);
void SetValue(DurationModifier &value); void SetValue(DurationModifier &value);
void SetUnit(DurationUnit u);
void SetDuration(const Duration &d); void SetDuration(const Duration &d);
private slots: private slots:
void _ModifierChanged(int value); void _ModifierChanged(int value);
void ToggleClicked(); void ToggleClicked();
signals: signals:
void DurationChanged(double value); void DurationChanged(const Duration &value);
void UnitChanged(DurationUnit u);
void ModifierChanged(DurationModifier::Type value); void ModifierChanged(DurationModifier::Type value);
private: private:
@@ -69,9 +67,8 @@ public:
private slots: private slots:
void LogicSelectionChanged(int idx); void LogicSelectionChanged(int idx);
void ConditionSelectionChanged(const QString &text); void ConditionSelectionChanged(const QString &text);
void DurationChanged(double seconds); void DurationChanged(const Duration &value);
void DurationModifierChanged(DurationModifier::Type m); void DurationModifierChanged(DurationModifier::Type m);
void DurationUnitChanged(DurationUnit unit);
private: private:
void SetLogicSelection(); void SetLogicSelection();

View File

@@ -65,7 +65,8 @@ bool MacroConditionFile::MatchFileContent(QString &filedata)
bool MacroConditionFile::CheckRemoteFileContent() bool MacroConditionFile::CheckRemoteFileContent()
{ {
std::string data = getRemoteData(_file); std::string path = _file;
std::string data = getRemoteData(path);
SetVariableValue(data); SetVariableValue(data);
QString qdata = QString::fromStdString(data); QString qdata = QString::fromStdString(data);
return MatchFileContent(qdata); return MatchFileContent(qdata);
@@ -99,7 +100,8 @@ bool MacroConditionFile::CheckChangeContent()
QString filedata; QString filedata;
switch (_fileType) { switch (_fileType) {
case FileType::LOCAL: { case FileType::LOCAL: {
QFile file(QString::fromStdString(_file)); std::string path = _file;
QFile file(QString::fromStdString(path));
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false; return false;
} }
@@ -107,7 +109,8 @@ bool MacroConditionFile::CheckChangeContent()
file.close(); file.close();
} break; } break;
case FileType::REMOTE: { case FileType::REMOTE: {
std::string data = getRemoteData(_file); std::string path = _file;
std::string data = getRemoteData(path);
QString filedata = QString::fromStdString(data); QString filedata = QString::fromStdString(data);
} break; } break;
default: default:
@@ -166,7 +169,7 @@ bool MacroConditionFile::Save(obs_data_t *obj) const
{ {
MacroCondition::Save(obj); MacroCondition::Save(obj);
_regex.Save(obj); _regex.Save(obj);
obs_data_set_string(obj, "file", _file.c_str()); _file.Save(obj, "file");
_text.Save(obj, "text"); _text.Save(obj, "text");
obs_data_set_int(obj, "fileType", static_cast<int>(_fileType)); obs_data_set_int(obj, "fileType", static_cast<int>(_fileType));
obs_data_set_int(obj, "condition", static_cast<int>(_condition)); obs_data_set_int(obj, "condition", static_cast<int>(_condition));
@@ -184,7 +187,7 @@ bool MacroConditionFile::Load(obs_data_t *obj)
_regex.CreateBackwardsCompatibleRegex( _regex.CreateBackwardsCompatibleRegex(
obs_data_get_bool(obj, "useRegex")); obs_data_get_bool(obj, "useRegex"));
} }
_file = obs_data_get_string(obj, "file"); _file.Load(obj, "file");
_text.Load(obj, "text"); _text.Load(obj, "text");
_fileType = static_cast<FileType>(obs_data_get_int(obj, "fileType")); _fileType = static_cast<FileType>(obs_data_get_int(obj, "fileType"));
_condition = _condition =
@@ -196,7 +199,7 @@ bool MacroConditionFile::Load(obs_data_t *obj)
std::string MacroConditionFile::GetShortDesc() const std::string MacroConditionFile::GetShortDesc() const
{ {
return _file; return _file.UnresolvedValue();
} }
static void populateFileTypes(QComboBox *list) static void populateFileTypes(QComboBox *list)
@@ -292,7 +295,7 @@ void MacroConditionFileEdit::UpdateEntryData()
_fileTypes->setCurrentIndex(static_cast<int>(_entryData->_fileType)); _fileTypes->setCurrentIndex(static_cast<int>(_entryData->_fileType));
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition)); _conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
_filePath->SetPath(QString::fromStdString(_entryData->_file)); _filePath->SetPath(_entryData->_file);
_matchText->setPlainText(_entryData->_text); _matchText->setPlainText(_entryData->_text);
_regex->SetRegexConfig(_entryData->_regex); _regex->SetRegexConfig(_entryData->_regex);
_checkModificationDate->setChecked(_entryData->_useTime); _checkModificationDate->setChecked(_entryData->_useTime);

View File

@@ -35,9 +35,8 @@ public:
DATE_CHANGE, DATE_CHANGE,
}; };
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath"); StringVariable _file = obs_module_text("AdvSceneSwitcher.enterPath");
VariableResolvingString _text = StringVariable _text = obs_module_text("AdvSceneSwitcher.enterText");
obs_module_text("AdvSceneSwitcher.enterText");
FileType _fileType = FileType::LOCAL; FileType _fileType = FileType::LOCAL;
ConditionType _condition = ConditionType::MATCH; ConditionType _condition = ConditionType::MATCH;
RegexConfig _regex; RegexConfig _regex;

View File

@@ -30,7 +30,7 @@ public:
SourceSelection _source; SourceSelection _source;
OBSWeakSource _filter; OBSWeakSource _filter;
Condition _condition = Condition::ENABLED; Condition _condition = Condition::ENABLED;
VariableResolvingString _settings = ""; StringVariable _settings = "";
RegexConfig _regex; RegexConfig _regex;
private: private:

View File

@@ -14,7 +14,7 @@ bool MacroConditionIdle::CheckCondition()
{ {
auto seconds = secondsSinceLastInput(); auto seconds = secondsSinceLastInput();
SetVariableValue(std::to_string(seconds)); SetVariableValue(std::to_string(seconds));
return seconds >= _duration.seconds; return seconds >= _duration.Seconds();
} }
bool MacroConditionIdle::Save(obs_data_t *obj) const bool MacroConditionIdle::Save(obs_data_t *obj) const
@@ -37,10 +37,8 @@ MacroConditionIdleEdit::MacroConditionIdleEdit(
{ {
_duration = new DurationSelection(); _duration = new DurationSelection();
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DurationUnitChanged(DurationUnit)));
QHBoxLayout *mainLayout = new QHBoxLayout; QHBoxLayout *mainLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@@ -55,24 +53,14 @@ MacroConditionIdleEdit::MacroConditionIdleEdit(
_loading = false; _loading = false;
} }
void MacroConditionIdleEdit::DurationChanged(double seconds) void MacroConditionIdleEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
}
void MacroConditionIdleEdit::DurationUnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.displayUnit = unit;
} }
void MacroConditionIdleEdit::UpdateEntryData() void MacroConditionIdleEdit::UpdateEntryData()

View File

@@ -41,8 +41,7 @@ public:
} }
private slots: private slots:
void DurationChanged(double seconds); void DurationChanged(const Duration &seconds);
void DurationUnitChanged(DurationUnit unit);
protected: protected:
DurationSelection *_duration; DurationSelection *_duration;

View File

@@ -44,11 +44,12 @@ bool MacroConditionMacro::CheckStateCondition()
// Note: // Note:
// Depending on the order the macro conditions are checked Matched() might // Depending on the order the macro conditions are checked Matched() might
// still return the state of the previous interval // still return the state of the previous interval
if (!_macro.get()) { auto macro = _macro.GetMacro();
if (!macro) {
return false; return false;
} }
return _macro->Matched(); return macro->Matched();
} }
bool MacroConditionMacro::CheckMultiStateCondition() bool MacroConditionMacro::CheckMultiStateCondition()
@@ -57,8 +58,9 @@ bool MacroConditionMacro::CheckMultiStateCondition()
// Depending on the order the macro conditions are checked Matched() might // Depending on the order the macro conditions are checked Matched() might
// still return the state of the previous interval // still return the state of the previous interval
int matchedCount = 0; int matchedCount = 0;
for (const auto &macro : _macros) { for (const auto &m : _macros) {
if (!macro.get()) { auto macro = m.GetMacro();
if (!macro) {
continue; continue;
} }
if (macro->Matched()) { if (macro->Matched()) {
@@ -82,17 +84,18 @@ bool MacroConditionMacro::CheckMultiStateCondition()
bool MacroConditionMacro::CheckCountCondition() bool MacroConditionMacro::CheckCountCondition()
{ {
if (!_macro.get()) { auto macro = _macro.GetMacro();
if (!macro) {
return false; return false;
} }
switch (_counterCondition) { switch (_counterCondition) {
case CounterCondition::BELOW: case CounterCondition::BELOW:
return _macro->RunCount() < _count; return macro->RunCount() < _count;
case CounterCondition::ABOVE: case CounterCondition::ABOVE:
return _macro->RunCount() > _count; return macro->RunCount() > _count;
case CounterCondition::EQUAL: case CounterCondition::EQUAL:
return _macro->RunCount() == _count; return macro->RunCount() == _count;
default: default:
break; break;
} }
@@ -123,10 +126,11 @@ bool MacroConditionMacro::Save(obs_data_t *obj) const
_macro.Save(obj); _macro.Save(obj);
obs_data_set_int(obj, "type", static_cast<int>(_type)); obs_data_set_int(obj, "type", static_cast<int>(_type));
obs_data_set_int(obj, "condition", static_cast<int>(_counterCondition)); obs_data_set_int(obj, "condition", static_cast<int>(_counterCondition));
obs_data_set_int(obj, "count", _count); _count.Save(obj, "count");
obs_data_set_int(obj, "multiStateCount", _multiSateCount); _multiSateCount.Save(obj, "multiStateCount");
obs_data_set_int(obj, "multiStateCondition", obs_data_set_int(obj, "multiStateCondition",
static_cast<int>(_multiSateCondition)); static_cast<int>(_multiSateCondition));
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -138,8 +142,6 @@ bool MacroConditionMacro::Load(obs_data_t *obj)
_type = static_cast<Type>(obs_data_get_int(obj, "type")); _type = static_cast<Type>(obs_data_get_int(obj, "type"));
_counterCondition = static_cast<CounterCondition>( _counterCondition = static_cast<CounterCondition>(
obs_data_get_int(obj, "condition")); obs_data_get_int(obj, "condition"));
_count = obs_data_get_int(obj, "count");
_multiSateCount = obs_data_get_int(obj, "multiStateCount");
// TODO: Remove this fallback in future version // TODO: Remove this fallback in future version
if (!obs_data_has_user_value(obj, "multiStateCondition")) { if (!obs_data_has_user_value(obj, "multiStateCondition")) {
_multiSateCondition = MultiStateCondition::ABOVE; _multiSateCondition = MultiStateCondition::ABOVE;
@@ -147,15 +149,27 @@ bool MacroConditionMacro::Load(obs_data_t *obj)
_multiSateCondition = static_cast<MultiStateCondition>( _multiSateCondition = static_cast<MultiStateCondition>(
obs_data_get_int(obj, "multiStateCondition")); obs_data_get_int(obj, "multiStateCondition"));
} }
if (!obs_data_has_user_value(obj, "version")) {
_count = obs_data_get_int(obj, "count");
_multiSateCount = obs_data_get_int(obj, "multiStateCount");
} else {
_count.Load(obj, "count");
_multiSateCount.Load(obj, "multiStateCount");
}
return true; return true;
} }
bool MacroConditionMacro::PostLoad()
{
return MacroRefCondition::PostLoad() &&
MultiMacroRefCondtition::PostLoad();
}
std::string MacroConditionMacro::GetShortDesc() const std::string MacroConditionMacro::GetShortDesc() const
{ {
if (_macro.get()) { return _macro.Name();
return _macro->Name();
}
return "";
} }
static inline void populateTypeSelection(QComboBox *list) static inline void populateTypeSelection(QComboBox *list)
@@ -183,19 +197,19 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
QWidget *parent, std::shared_ptr<MacroConditionMacro> entryData) QWidget *parent, std::shared_ptr<MacroConditionMacro> entryData)
: QWidget(parent), : QWidget(parent),
_macros(new MacroSelection(parent)), _macros(new MacroSelection(parent)),
_types(new QComboBox(parent)), _types(new QComboBox()),
_counterConditions(new QComboBox(parent)), _counterConditions(new QComboBox()),
_count(new QSpinBox(parent)), _count(new VariableSpinBox()),
_currentCount(new QLabel(parent)), _currentCount(new QLabel()),
_pausedWarning(new QLabel(obs_module_text( _pausedWarning(new QLabel(obs_module_text(
"AdvSceneSwitcher.condition.macro.pausedWarning"))), "AdvSceneSwitcher.condition.macro.pausedWarning"))),
_resetCount(new QPushButton(obs_module_text( _resetCount(new QPushButton(obs_module_text(
"AdvSceneSwitcher.condition.macro.count.reset"))), "AdvSceneSwitcher.condition.macro.count.reset"))),
_settingsLine1(new QHBoxLayout), _settingsLine1(new QHBoxLayout()),
_settingsLine2(new QHBoxLayout), _settingsLine2(new QHBoxLayout()),
_macroList(new MacroList(this, false, false)), _macroList(new MacroList(this, false, false)),
_multiStateConditions(new QComboBox(parent)), _multiStateConditions(new QComboBox()),
_multiStateCount(new QSpinBox(parent)) _multiStateCount(new VariableSpinBox())
{ {
_count->setMaximum(10000000); _count->setMaximum(10000000);
populateTypeSelection(_types); populateTypeSelection(_types);
@@ -210,8 +224,10 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
SLOT(TypeChanged(int))); SLOT(TypeChanged(int)));
QWidget::connect(_counterConditions, SIGNAL(currentIndexChanged(int)), QWidget::connect(_counterConditions, SIGNAL(currentIndexChanged(int)),
this, SLOT(CountConditionChanged(int))); this, SLOT(CountConditionChanged(int)));
QWidget::connect(_count, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(CountChanged(int))); _count,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(CountChanged(const NumberVariable<int> &)));
QWidget::connect(_resetCount, SIGNAL(clicked()), this, QWidget::connect(_resetCount, SIGNAL(clicked()), this,
SLOT(ResetClicked())); SLOT(ResetClicked()));
QWidget::connect(_macroList, SIGNAL(Added(const std::string &)), this, QWidget::connect(_macroList, SIGNAL(Added(const std::string &)), this,
@@ -223,10 +239,13 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
QWidget::connect(_multiStateConditions, QWidget::connect(_multiStateConditions,
SIGNAL(currentIndexChanged(int)), this, SIGNAL(currentIndexChanged(int)), this,
SLOT(MultiStateConditionChanged(int))); SLOT(MultiStateConditionChanged(int)));
QWidget::connect(_multiStateCount, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(MultiStateCountChanged(int))); _multiStateCount,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this,
SLOT(MultiStateCountChanged(const NumberVariable<int> &)));
auto typesLayout = new QHBoxLayout; auto typesLayout = new QHBoxLayout();
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{types}}", _types}, {"{{types}}", _types},
}; };
@@ -234,7 +253,7 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
"AdvSceneSwitcher.condition.macro.type.selection"), "AdvSceneSwitcher.condition.macro.type.selection"),
typesLayout, widgetPlaceholders); typesLayout, widgetPlaceholders);
auto mainLayout = new QVBoxLayout; auto mainLayout = new QVBoxLayout(this);
mainLayout->addLayout(typesLayout); mainLayout->addLayout(typesLayout);
mainLayout->addLayout(_settingsLine1); mainLayout->addLayout(_settingsLine1);
mainLayout->addLayout(_settingsLine2); mainLayout->addLayout(_settingsLine2);
@@ -244,11 +263,13 @@ MacroConditionMacroEdit::MacroConditionMacroEdit(
_entryData = entryData; _entryData = entryData;
connect(&_countTimer, SIGNAL(timeout()), this, SLOT(UpdateCount())); QWidget::connect(&_countTimer, SIGNAL(timeout()), this,
SLOT(UpdateCount()));
_countTimer.start(1000); _countTimer.start(1000);
_pausedWarning->setVisible(false); _pausedWarning->setVisible(false);
connect(&_pausedTimer, SIGNAL(timeout()), this, SLOT(UpdatePaused())); QWidget::connect(&_pausedTimer, SIGNAL(timeout()), this,
SLOT(UpdatePaused()));
_pausedTimer.start(1000); _pausedTimer.start(1000);
UpdateEntryData(); UpdateEntryData();
@@ -270,6 +291,7 @@ void MacroConditionMacroEdit::ClearLayouts()
void MacroConditionMacroEdit::SetupStateWidgets() void MacroConditionMacroEdit::SetupStateWidgets()
{ {
SetWidgetVisibility();
ClearLayouts(); ClearLayouts();
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@@ -278,12 +300,11 @@ void MacroConditionMacroEdit::SetupStateWidgets()
placeWidgets( placeWidgets(
obs_module_text("AdvSceneSwitcher.condition.macro.state.entry"), obs_module_text("AdvSceneSwitcher.condition.macro.state.entry"),
_settingsLine1, widgetPlaceholders); _settingsLine1, widgetPlaceholders);
SetWidgetVisibility();
adjustSize();
} }
void MacroConditionMacroEdit::SetupMultiStateWidgets() void MacroConditionMacroEdit::SetupMultiStateWidgets()
{ {
SetWidgetVisibility();
ClearLayouts(); ClearLayouts();
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@@ -294,12 +315,11 @@ void MacroConditionMacroEdit::SetupMultiStateWidgets()
obs_module_text( obs_module_text(
"AdvSceneSwitcher.condition.macro.multistate.entry"), "AdvSceneSwitcher.condition.macro.multistate.entry"),
_settingsLine1, widgetPlaceholders); _settingsLine1, widgetPlaceholders);
SetWidgetVisibility();
adjustSize();
} }
void MacroConditionMacroEdit::SetupCountWidgets() void MacroConditionMacroEdit::SetupCountWidgets()
{ {
SetWidgetVisibility();
ClearLayouts(); ClearLayouts();
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@@ -317,8 +337,6 @@ void MacroConditionMacroEdit::SetupCountWidgets()
obs_module_text( obs_module_text(
"AdvSceneSwitcher.condition.macro.count.entry.line2"), "AdvSceneSwitcher.condition.macro.count.entry.line2"),
_settingsLine2, widgetPlaceholders); _settingsLine2, widgetPlaceholders);
SetWidgetVisibility();
adjustSize();
} }
void MacroConditionMacroEdit::SetWidgetVisibility() void MacroConditionMacroEdit::SetWidgetVisibility()
@@ -329,7 +347,6 @@ void MacroConditionMacroEdit::SetWidgetVisibility()
_counterConditions->show(); _counterConditions->show();
_count->show(); _count->show();
_currentCount->show(); _currentCount->show();
_pausedWarning->show();
_resetCount->show(); _resetCount->show();
_macroList->hide(); _macroList->hide();
_multiStateConditions->hide(); _multiStateConditions->hide();
@@ -340,7 +357,6 @@ void MacroConditionMacroEdit::SetWidgetVisibility()
_counterConditions->hide(); _counterConditions->hide();
_count->hide(); _count->hide();
_currentCount->hide(); _currentCount->hide();
_pausedWarning->show();
_resetCount->hide(); _resetCount->hide();
_macroList->hide(); _macroList->hide();
_multiStateConditions->hide(); _multiStateConditions->hide();
@@ -360,6 +376,8 @@ void MacroConditionMacroEdit::SetWidgetVisibility()
default: default:
break; break;
} }
adjustSize();
updateGeometry();
} }
void MacroConditionMacroEdit::UpdateEntryData() void MacroConditionMacroEdit::UpdateEntryData()
@@ -368,8 +386,7 @@ void MacroConditionMacroEdit::UpdateEntryData()
return; return;
} }
auto test = _entryData->_type; switch (_entryData->_type) {
switch (test) {
case MacroConditionMacro::Type::COUNT: case MacroConditionMacro::Type::COUNT:
SetupCountWidgets(); SetupCountWidgets();
break; break;
@@ -383,15 +400,15 @@ void MacroConditionMacroEdit::UpdateEntryData()
break; break;
} }
_macros->SetCurrentMacro(_entryData->_macro.get()); _macros->SetCurrentMacro(_entryData->_macro);
_types->setCurrentIndex(static_cast<int>(_entryData->_type)); _types->setCurrentIndex(static_cast<int>(_entryData->_type));
_counterConditions->setCurrentIndex( _counterConditions->setCurrentIndex(
static_cast<int>(_entryData->_counterCondition)); static_cast<int>(_entryData->_counterCondition));
_count->setValue(_entryData->_count); _count->SetValue(_entryData->_count);
_macroList->SetContent(_entryData->_macros); _macroList->SetContent(_entryData->_macros);
_multiStateConditions->setCurrentIndex( _multiStateConditions->setCurrentIndex(
static_cast<int>(_entryData->_multiSateCondition)); static_cast<int>(_entryData->_multiSateCondition));
_multiStateCount->setValue(_entryData->_multiSateCount); _multiStateCount->SetValue(_entryData->_multiSateCount);
} }
void MacroConditionMacroEdit::MacroChanged(const QString &text) void MacroConditionMacroEdit::MacroChanged(const QString &text)
@@ -401,12 +418,12 @@ void MacroConditionMacroEdit::MacroChanged(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_macro.UpdateRef(text); _entryData->_macro = text;
emit HeaderInfoChanged( emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
void MacroConditionMacroEdit::CountChanged(int value) void MacroConditionMacroEdit::CountChanged(const NumberVariable<int> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -433,12 +450,9 @@ void MacroConditionMacroEdit::MacroRemove(const QString &)
return; return;
} }
_entryData->_macro.UpdateRef();
auto it = _entryData->_macros.begin(); auto it = _entryData->_macros.begin();
while (it != _entryData->_macros.end()) { while (it != _entryData->_macros.end()) {
it->UpdateRef(); if (!it->GetMacro()) {
if (it->get() == nullptr) {
it = _entryData->_macros.erase(it); it = _entryData->_macros.erase(it);
} else { } else {
++it; ++it;
@@ -473,18 +487,26 @@ void MacroConditionMacroEdit::TypeChanged(int type)
void MacroConditionMacroEdit::ResetClicked() void MacroConditionMacroEdit::ResetClicked()
{ {
if (_loading || !_entryData || !_entryData->_macro.get()) { if (_loading || !_entryData) {
return; return;
} }
_entryData->_macro->ResetRunCount(); auto macro = _entryData->_macro.GetMacro();
if (!macro) {
return;
}
macro->ResetRunCount();
} }
void MacroConditionMacroEdit::UpdateCount() void MacroConditionMacroEdit::UpdateCount()
{ {
if (_entryData && _entryData->_macro.get()) { if (!_entryData) {
_currentCount->setText( return;
QString::number(_entryData->_macro->RunCount())); }
auto macro = _entryData->_macro.GetMacro();
if (macro) {
_currentCount->setText(QString::number(macro->RunCount()));
} else { } else {
_currentCount->setText("-"); _currentCount->setText("-");
} }
@@ -492,10 +514,11 @@ void MacroConditionMacroEdit::UpdateCount()
void MacroConditionMacroEdit::UpdatePaused() void MacroConditionMacroEdit::UpdatePaused()
{ {
auto macro = _entryData->_macro.GetMacro();
_pausedWarning->setVisible( _pausedWarning->setVisible(
_entryData && _entryData &&
_entryData->_type != MacroConditionMacro::Type::MULTI_STATE && _entryData->_type != MacroConditionMacro::Type::MULTI_STATE &&
_entryData->_macro.get() && _entryData->_macro->Paused()); macro && macro->Paused());
adjustSize(); adjustSize();
} }
@@ -510,7 +533,8 @@ void MacroConditionMacroEdit::MultiStateConditionChanged(int cond)
static_cast<MacroConditionMacro::MultiStateCondition>(cond); static_cast<MacroConditionMacro::MultiStateCondition>(cond);
} }
void MacroConditionMacroEdit::MultiStateCountChanged(int value) void MacroConditionMacroEdit::MultiStateCountChanged(
const NumberVariable<int> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;

View File

@@ -2,6 +2,7 @@
#include "macro.hpp" #include "macro.hpp"
#include "macro-selection.hpp" #include "macro-selection.hpp"
#include "macro-list.hpp" #include "macro-list.hpp"
#include "variable-spinbox.hpp"
#include <QComboBox> #include <QComboBox>
#include <QSpinBox> #include <QSpinBox>
@@ -22,6 +23,7 @@ public:
bool CheckCondition(); bool CheckCondition();
bool Save(obs_data_t *obj) const; bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj); bool Load(obs_data_t *obj);
bool PostLoad() override;
std::string GetShortDesc() const; std::string GetShortDesc() const;
std::string GetId() const { return id; }; std::string GetId() const { return id; };
static std::shared_ptr<MacroCondition> Create(Macro *m) static std::shared_ptr<MacroCondition> Create(Macro *m)
@@ -42,7 +44,7 @@ public:
EQUAL, EQUAL,
}; };
CounterCondition _counterCondition = CounterCondition::BELOW; CounterCondition _counterCondition = CounterCondition::BELOW;
int _count = 0; NumberVariable<int> _count = 0;
enum class MultiStateCondition { enum class MultiStateCondition {
BELOW, BELOW,
@@ -50,7 +52,7 @@ public:
ABOVE, ABOVE,
}; };
MultiStateCondition _multiSateCondition = MultiStateCondition::ABOVE; MultiStateCondition _multiSateCondition = MultiStateCondition::ABOVE;
int _multiSateCount = 0; NumberVariable<int> _multiSateCount = 0;
private: private:
bool CheckCountCondition(); bool CheckCountCondition();
@@ -81,13 +83,13 @@ private slots:
void MacroChanged(const QString &text); void MacroChanged(const QString &text);
void MacroRemove(const QString &name); void MacroRemove(const QString &name);
void TypeChanged(int type); void TypeChanged(int type);
void CountChanged(int value); void CountChanged(const NumberVariable<int> &value);
void CountConditionChanged(int cond); void CountConditionChanged(int cond);
void ResetClicked(); void ResetClicked();
void UpdateCount(); void UpdateCount();
void UpdatePaused(); void UpdatePaused();
void MultiStateConditionChanged(int cond); void MultiStateConditionChanged(int cond);
void MultiStateCountChanged(int value); void MultiStateCountChanged(const NumberVariable<int> &value);
void Add(const std::string &); void Add(const std::string &);
void Remove(int); void Remove(int);
void Replace(int, const std::string &); void Replace(int, const std::string &);
@@ -98,7 +100,7 @@ protected:
MacroSelection *_macros; MacroSelection *_macros;
QComboBox *_types; QComboBox *_types;
QComboBox *_counterConditions; QComboBox *_counterConditions;
QSpinBox *_count; VariableSpinBox *_count;
QLabel *_currentCount; QLabel *_currentCount;
QLabel *_pausedWarning; QLabel *_pausedWarning;
QPushButton *_resetCount; QPushButton *_resetCount;
@@ -106,7 +108,7 @@ protected:
QHBoxLayout *_settingsLine2; QHBoxLayout *_settingsLine2;
MacroList *_macroList; MacroList *_macroList;
QComboBox *_multiStateConditions; QComboBox *_multiStateConditions;
QSpinBox *_multiStateCount; VariableSpinBox *_multiStateCount;
QTimer _countTimer; QTimer _countTimer;
QTimer _pausedTimer; QTimer _pausedTimer;
std::shared_ptr<MacroConditionMacro> _entryData; std::shared_ptr<MacroConditionMacro> _entryData;

View File

@@ -71,18 +71,18 @@ bool MacroConditionMedia::CheckTime()
match = true; match = true;
break; break;
case Time::TIME_RESTRICTION_SHORTER: case Time::TIME_RESTRICTION_SHORTER:
match = currentTime < _time.seconds * 1000; match = currentTime < _time.Milliseconds();
break; break;
case Time::TIME_RESTRICTION_LONGER: case Time::TIME_RESTRICTION_LONGER:
match = currentTime > _time.seconds * 1000; match = currentTime > _time.Milliseconds();
break; break;
case Time::TIME_RESTRICTION_REMAINING_SHORTER: case Time::TIME_RESTRICTION_REMAINING_SHORTER:
match = duration > currentTime && match = duration > currentTime &&
duration - currentTime < _time.seconds * 1000; duration - currentTime < _time.Milliseconds();
break; break;
case Time::TIME_RESTRICTION_REMAINING_LONGER: case Time::TIME_RESTRICTION_REMAINING_LONGER:
match = duration > currentTime && match = duration > currentTime &&
duration - currentTime > _time.seconds * 1000; duration - currentTime > _time.Milliseconds();
break; break;
default: default:
break; break;
@@ -429,10 +429,8 @@ MacroConditionMediaEdit::MacroConditionMediaEdit(
SLOT(StateChanged(int))); SLOT(StateChanged(int)));
QWidget::connect(_timeRestrictions, SIGNAL(currentIndexChanged(int)), QWidget::connect(_timeRestrictions, SIGNAL(currentIndexChanged(int)),
this, SLOT(TimeRestrictionChanged(int))); this, SLOT(TimeRestrictionChanged(int)));
QWidget::connect(_time, SIGNAL(DurationChanged(double)), this, QWidget::connect(_time, SIGNAL(DurationChanged(const Duration &)), this,
SLOT(TimeChanged(double))); SLOT(TimeChanged(const Duration &)));
QWidget::connect(_time, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(TimeUnitChanged(DurationUnit)));
QWidget::connect(_onChange, SIGNAL(stateChanged(int)), this, QWidget::connect(_onChange, SIGNAL(stateChanged(int)), this,
SLOT(OnChangeChanged(int))); SLOT(OnChangeChanged(int)));
@@ -560,27 +558,14 @@ void MacroConditionMediaEdit::TimeRestrictionChanged(int index)
} }
} }
void MacroConditionMediaEdit::TimeChanged(double seconds) void MacroConditionMediaEdit::TimeChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_time.seconds = seconds; _entryData->_time = dur;
if (_entryData->_sourceType != MacroConditionMedia::Type::SOURCE) {
_entryData->UpdateMediaSourcesOfSceneList();
}
}
void MacroConditionMediaEdit::TimeUnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_time.displayUnit = unit;
if (_entryData->_sourceType != MacroConditionMedia::Type::SOURCE) { if (_entryData->_sourceType != MacroConditionMedia::Type::SOURCE) {
_entryData->UpdateMediaSourcesOfSceneList(); _entryData->UpdateMediaSourcesOfSceneList();
} }

View File

@@ -116,8 +116,7 @@ private slots:
void SceneChanged(const SceneSelection &); void SceneChanged(const SceneSelection &);
void StateChanged(int index); void StateChanged(int index);
void TimeRestrictionChanged(int index); void TimeRestrictionChanged(int index);
void TimeChanged(double seconds); void TimeChanged(const Duration &seconds);
void TimeUnitChanged(DurationUnit unit);
void OnChangeChanged(int); void OnChangeChanged(int);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);

View File

@@ -10,41 +10,43 @@ bool MacroConditionStats::_registered = MacroConditionFactory::Register(
{MacroConditionStats::Create, MacroConditionStatsEdit::Create, {MacroConditionStats::Create, MacroConditionStatsEdit::Create,
"AdvSceneSwitcher.condition.stats"}); "AdvSceneSwitcher.condition.stats"});
static std::map<StatsType, std::string> statsTypes = { static std::map<MacroConditionStats::Type, std::string> statsTypes = {
{StatsType::FPS, "AdvSceneSwitcher.condition.stats.type.fps"}, {MacroConditionStats::Type::FPS,
{StatsType::CPU_USAGE, "AdvSceneSwitcher.condition.stats.type.fps"},
{MacroConditionStats::Type::CPU_USAGE,
"AdvSceneSwitcher.condition.stats.type.CPUUsage"}, "AdvSceneSwitcher.condition.stats.type.CPUUsage"},
{StatsType::DISK_USAGE, {MacroConditionStats::Type::DISK_USAGE,
"AdvSceneSwitcher.condition.stats.type.HDDSpaceAvailable"}, "AdvSceneSwitcher.condition.stats.type.HDDSpaceAvailable"},
{StatsType::MEM_USAGE, {MacroConditionStats::Type::MEM_USAGE,
"AdvSceneSwitcher.condition.stats.type.memoryUsage"}, "AdvSceneSwitcher.condition.stats.type.memoryUsage"},
{StatsType::AVG_FRAMETIME, {MacroConditionStats::Type::AVG_FRAMETIME,
"AdvSceneSwitcher.condition.stats.type.averageTimeToRender"}, "AdvSceneSwitcher.condition.stats.type.averageTimeToRender"},
{StatsType::RENDER_LAG, {MacroConditionStats::Type::RENDER_LAG,
"AdvSceneSwitcher.condition.stats.type.missedFrames"}, "AdvSceneSwitcher.condition.stats.type.missedFrames"},
{StatsType::ENCODE_LAG, {MacroConditionStats::Type::ENCODE_LAG,
"AdvSceneSwitcher.condition.stats.type.skippedFrames"}, "AdvSceneSwitcher.condition.stats.type.skippedFrames"},
{StatsType::STREAM_DROPPED_FRAMES, {MacroConditionStats::Type::STREAM_DROPPED_FRAMES,
"AdvSceneSwitcher.condition.stats.type.droppedFrames.stream"}, "AdvSceneSwitcher.condition.stats.type.droppedFrames.stream"},
{StatsType::STREAM_BITRATE, {MacroConditionStats::Type::STREAM_BITRATE,
"AdvSceneSwitcher.condition.stats.type.bitrate.stream"}, "AdvSceneSwitcher.condition.stats.type.bitrate.stream"},
{StatsType::STREAM_MB_SENT, {MacroConditionStats::Type::STREAM_MB_SENT,
"AdvSceneSwitcher.condition.stats.type.megabytesSent.stream"}, "AdvSceneSwitcher.condition.stats.type.megabytesSent.stream"},
{StatsType::RECORDING_DROPPED_FRAMES, {MacroConditionStats::Type::RECORDING_DROPPED_FRAMES,
"AdvSceneSwitcher.condition.stats.type.droppedFrames.recording"}, "AdvSceneSwitcher.condition.stats.type.droppedFrames.recording"},
{StatsType::RECORDING_BITRATE, {MacroConditionStats::Type::RECORDING_BITRATE,
"AdvSceneSwitcher.condition.stats.type.bitrate.recording"}, "AdvSceneSwitcher.condition.stats.type.bitrate.recording"},
{StatsType::RECORDING_MB_SENT, {MacroConditionStats::Type::RECORDING_MB_SENT,
"AdvSceneSwitcher.condition.stats.type.megabytesSent.recording"}, "AdvSceneSwitcher.condition.stats.type.megabytesSent.recording"},
}; };
static std::map<StatsCondition, std::string> statsConditionTypes = { static std::map<MacroConditionStats::Condition, std::string>
{StatsCondition::ABOVE, statsConditionTypes = {
"AdvSceneSwitcher.condition.stats.condition.above"}, {MacroConditionStats::Condition::ABOVE,
{StatsCondition::EQUALS, "AdvSceneSwitcher.condition.stats.condition.above"},
"AdvSceneSwitcher.condition.stats.condition.equals"}, {MacroConditionStats::Condition::EQUALS,
{StatsCondition::BELOW, "AdvSceneSwitcher.condition.stats.condition.equals"},
"AdvSceneSwitcher.condition.stats.condition.below"}, {MacroConditionStats::Condition::BELOW,
"AdvSceneSwitcher.condition.stats.condition.below"},
}; };
MacroConditionStats::MacroConditionStats(Macro *m) MacroConditionStats::MacroConditionStats(Macro *m)
@@ -60,11 +62,11 @@ MacroConditionStats::~MacroConditionStats()
bool MacroConditionStats::CheckFPS() bool MacroConditionStats::CheckFPS()
{ {
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return obs_get_active_fps() > _value; return obs_get_active_fps() > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(obs_get_active_fps(), _value, 0.01); return doubleEquals(obs_get_active_fps(), _value, 0.01);
case StatsCondition::BELOW: case Condition::BELOW:
return obs_get_active_fps() < _value; return obs_get_active_fps() < _value;
default: default:
break; break;
@@ -77,11 +79,11 @@ bool MacroConditionStats::CheckCPU()
double usage = os_cpu_usage_info_query(_cpu_info); double usage = os_cpu_usage_info_query(_cpu_info);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return usage > _value; return usage > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(usage, _value, 0.1); return doubleEquals(usage, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return usage < _value; return usage < _value;
default: default:
break; break;
@@ -95,11 +97,11 @@ bool MacroConditionStats::CheckMemory()
(long double)os_get_proc_resident_size() / (1024.0l * 1024.0l); (long double)os_get_proc_resident_size() / (1024.0l * 1024.0l);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return rss > _value; return rss > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(rss, _value, 0.1); return doubleEquals(rss, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return rss < _value; return rss < _value;
default: default:
break; break;
@@ -112,11 +114,11 @@ bool MacroConditionStats::CheckAvgFrametime()
auto num = (long double)obs_get_average_frame_time_ns() / 1000000.0l; auto num = (long double)obs_get_average_frame_time_ns() / 1000000.0l;
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return num > _value; return num > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(num, _value, 0.1); return doubleEquals(num, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return num < _value; return num < _value;
default: default:
break; break;
@@ -142,11 +144,11 @@ bool MacroConditionStats::CheckRenderLag()
num *= 100.0l; num *= 100.0l;
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return num > _value; return num > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(num, _value, 0.1); return doubleEquals(num, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return num < _value; return num < _value;
default: default:
break; break;
@@ -173,11 +175,11 @@ bool MacroConditionStats::CheckEncodeLag()
num *= 100.0l; num *= 100.0l;
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return num > _value; return num > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(num, _value, 0.1); return doubleEquals(num, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return num < _value; return num < _value;
default: default:
break; break;
@@ -230,11 +232,11 @@ bool MacroConditionStats::CheckStreamDroppedFrames()
obs_output_release(output); obs_output_release(output);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return _streamInfo.dropped_relative > _value; return _streamInfo.dropped_relative > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(_streamInfo.dropped_relative, _value, 0.1); return doubleEquals(_streamInfo.dropped_relative, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return _streamInfo.dropped_relative < _value; return _streamInfo.dropped_relative < _value;
default: default:
break; break;
@@ -249,11 +251,11 @@ bool MacroConditionStats::CheckStreamBitrate()
obs_output_release(output); obs_output_release(output);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return _streamInfo.kbps > _value; return _streamInfo.kbps > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(_streamInfo.kbps, _value, 1.0); return doubleEquals(_streamInfo.kbps, _value, 1.0);
case StatsCondition::BELOW: case Condition::BELOW:
return _streamInfo.kbps < _value; return _streamInfo.kbps < _value;
default: default:
break; break;
@@ -269,11 +271,11 @@ bool MacroConditionStats::CheckStreamMBSent()
long double num = (long double)totalBytes / (1024.0l * 1024.0l); long double num = (long double)totalBytes / (1024.0l * 1024.0l);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return num > _value; return num > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(num, _value, 0.1); return doubleEquals(num, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return num < _value; return num < _value;
default: default:
break; break;
@@ -288,12 +290,12 @@ bool MacroConditionStats::CheckRecordingDroppedFrames()
obs_output_release(output); obs_output_release(output);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return _recordingInfo.dropped_relative > _value; return _recordingInfo.dropped_relative > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(_recordingInfo.dropped_relative, _value, return doubleEquals(_recordingInfo.dropped_relative, _value,
0.1); 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return _recordingInfo.dropped_relative < _value; return _recordingInfo.dropped_relative < _value;
default: default:
break; break;
@@ -308,11 +310,11 @@ bool MacroConditionStats::CheckRecordingBitrate()
obs_output_release(output); obs_output_release(output);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return _recordingInfo.kbps > _value; return _recordingInfo.kbps > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(_recordingInfo.kbps, _value, 1.0); return doubleEquals(_recordingInfo.kbps, _value, 1.0);
case StatsCondition::BELOW: case Condition::BELOW:
return _recordingInfo.kbps < _value; return _recordingInfo.kbps < _value;
default: default:
break; break;
@@ -328,11 +330,11 @@ bool MacroConditionStats::CheckRecordingMBSent()
long double num = (long double)totalBytes / (1024.0l * 1024.0l); long double num = (long double)totalBytes / (1024.0l * 1024.0l);
switch (_condition) { switch (_condition) {
case StatsCondition::ABOVE: case Condition::ABOVE:
return num > _value; return num > _value;
case StatsCondition::EQUALS: case Condition::EQUALS:
return doubleEquals(num, _value, 0.1); return doubleEquals(num, _value, 0.1);
case StatsCondition::BELOW: case Condition::BELOW:
return num < _value; return num < _value;
default: default:
break; break;
@@ -343,32 +345,32 @@ bool MacroConditionStats::CheckRecordingMBSent()
bool MacroConditionStats::CheckCondition() bool MacroConditionStats::CheckCondition()
{ {
switch (_type) { switch (_type) {
case StatsType::FPS: case Type::FPS:
return CheckFPS(); return CheckFPS();
case StatsType::CPU_USAGE: case Type::CPU_USAGE:
return CheckCPU(); return CheckCPU();
case StatsType::DISK_USAGE: case Type::DISK_USAGE:
// TODO: not implemented // TODO: not implemented
break; break;
case StatsType::MEM_USAGE: case Type::MEM_USAGE:
return CheckMemory(); return CheckMemory();
case StatsType::AVG_FRAMETIME: case Type::AVG_FRAMETIME:
return CheckAvgFrametime(); return CheckAvgFrametime();
case StatsType::RENDER_LAG: case Type::RENDER_LAG:
return CheckRenderLag(); return CheckRenderLag();
case StatsType::ENCODE_LAG: case Type::ENCODE_LAG:
return CheckEncodeLag(); return CheckEncodeLag();
case StatsType::STREAM_DROPPED_FRAMES: case Type::STREAM_DROPPED_FRAMES:
return CheckStreamDroppedFrames(); return CheckStreamDroppedFrames();
case StatsType::STREAM_BITRATE: case Type::STREAM_BITRATE:
return CheckStreamBitrate(); return CheckStreamBitrate();
case StatsType::STREAM_MB_SENT: case Type::STREAM_MB_SENT:
return CheckStreamMBSent(); return CheckStreamMBSent();
case StatsType::RECORDING_DROPPED_FRAMES: case Type::RECORDING_DROPPED_FRAMES:
return CheckRecordingDroppedFrames(); return CheckRecordingDroppedFrames();
case StatsType::RECORDING_BITRATE: case Type::RECORDING_BITRATE:
return CheckRecordingBitrate(); return CheckRecordingBitrate();
case StatsType::RECORDING_MB_SENT: case Type::RECORDING_MB_SENT:
return CheckRecordingMBSent(); return CheckRecordingMBSent();
default: default:
break; break;
@@ -380,9 +382,10 @@ bool MacroConditionStats::CheckCondition()
bool MacroConditionStats::Save(obs_data_t *obj) const bool MacroConditionStats::Save(obs_data_t *obj) const
{ {
MacroCondition::Save(obj); MacroCondition::Save(obj);
obs_data_set_double(obj, "value", _value); _value.Save(obj, "value");
obs_data_set_int(obj, "type", static_cast<int>(_type)); obs_data_set_int(obj, "type", static_cast<int>(_type));
obs_data_set_int(obj, "condition", static_cast<int>(_condition)); obs_data_set_int(obj, "condition", static_cast<int>(_condition));
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -390,10 +393,14 @@ bool MacroConditionStats::Load(obs_data_t *obj)
{ {
MacroCondition::Load(obj); MacroCondition::Load(obj);
_value = obs_data_get_double(obj, "value"); if (!obs_data_has_user_value(obj, "version")) {
_type = static_cast<StatsType>(obs_data_get_int(obj, "type")); _value = obs_data_get_double(obj, "value");
_condition = } else {
static_cast<StatsCondition>(obs_data_get_int(obj, "condition")); _value.Load(obj, "value");
}
_type = static_cast<MacroConditionStats::Type>(
obs_data_get_int(obj, "type"));
_condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
return true; return true;
} }
@@ -412,7 +419,7 @@ static inline void populateStatsTypes(QComboBox *list)
for (auto entry : statsTypes) { for (auto entry : statsTypes) {
list->addItem(obs_module_text(entry.second.c_str())); list->addItem(obs_module_text(entry.second.c_str()));
// TODO: not implemented // TODO: not implemented
if (entry.first == StatsType::DISK_USAGE) { if (entry.first == MacroConditionStats::Type::DISK_USAGE) {
qobject_cast<QListView *>(list->view()) qobject_cast<QListView *>(list->view())
->setRowHidden(list->count() - 1, true); ->setRowHidden(list->count() - 1, true);
} }
@@ -430,9 +437,9 @@ static inline void populateConditionSelection(QComboBox *list)
MacroConditionStatsEdit::MacroConditionStatsEdit( MacroConditionStatsEdit::MacroConditionStatsEdit(
QWidget *parent, std::shared_ptr<MacroConditionStats> entryData) QWidget *parent, std::shared_ptr<MacroConditionStats> entryData)
: QWidget(parent), : QWidget(parent),
_stats(new QComboBox), _stats(new QComboBox()),
_condition(new QComboBox), _condition(new QComboBox()),
_value(new QDoubleSpinBox) _value(new VariableDoubleSpinBox())
{ {
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
@@ -442,8 +449,10 @@ MacroConditionStatsEdit::MacroConditionStatsEdit(
setToolTip( setToolTip(
obs_module_text("AdvSceneSwitcher.condition.stats.dockHint")); obs_module_text("AdvSceneSwitcher.condition.stats.dockHint"));
QWidget::connect(_value, SIGNAL(valueChanged(double)), this, QWidget::connect(
SLOT(ValueChanged(double))); _value,
SIGNAL(NumberVariableChanged(const NumberVariable<double> &)),
this, SLOT(ValueChanged(const NumberVariable<double> &)));
QWidget::connect(_stats, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_stats, SIGNAL(currentIndexChanged(int)), this,
SLOT(StatsTypeChanged(int))); SLOT(StatsTypeChanged(int)));
QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_condition, SIGNAL(currentIndexChanged(int)), this,
@@ -464,7 +473,7 @@ MacroConditionStatsEdit::MacroConditionStatsEdit(
_loading = false; _loading = false;
} }
void MacroConditionStatsEdit::ValueChanged(double value) void MacroConditionStatsEdit::ValueChanged(const NumberVariable<double> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -482,10 +491,11 @@ void MacroConditionStatsEdit::StatsTypeChanged(int type)
{ {
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_type = static_cast<StatsType>(type); _entryData->_type =
static_cast<MacroConditionStats::Type>(type);
SetWidgetVisibility(); SetWidgetVisibility();
} }
_value->setValue(0); _value->SetFixedValue(0);
emit HeaderInfoChanged( emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
@@ -497,7 +507,8 @@ void MacroConditionStatsEdit::ConditionChanged(int cond)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_condition = static_cast<StatsCondition>(cond); _entryData->_condition =
static_cast<MacroConditionStats::Condition>(cond);
} }
void MacroConditionStatsEdit::UpdateEntryData() void MacroConditionStatsEdit::UpdateEntryData()
@@ -506,7 +517,7 @@ void MacroConditionStatsEdit::UpdateEntryData()
return; return;
} }
_value->setValue(_entryData->_value); _value->SetValue(_entryData->_value);
_stats->setCurrentIndex(static_cast<int>(_entryData->_type)); _stats->setCurrentIndex(static_cast<int>(_entryData->_type));
_condition->setCurrentIndex(static_cast<int>(_entryData->_condition)); _condition->setCurrentIndex(static_cast<int>(_entryData->_condition));
SetWidgetVisibility(); SetWidgetVisibility();
@@ -519,55 +530,55 @@ void MacroConditionStatsEdit::SetWidgetVisibility()
} }
switch (_entryData->_type) { switch (_entryData->_type) {
case StatsType::FPS: case MacroConditionStats::Type::FPS:
_value->setMaximum(1000); _value->setMaximum(1000);
_value->setSuffix(""); _value->setSuffix("");
break; break;
case StatsType::CPU_USAGE: case MacroConditionStats::Type::CPU_USAGE:
_value->setMaximum(100); _value->setMaximum(100);
_value->setSuffix("%"); _value->setSuffix("%");
break; break;
case StatsType::DISK_USAGE: case MacroConditionStats::Type::DISK_USAGE:
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
_value->setSuffix("MB"); _value->setSuffix("MB");
break; break;
case StatsType::MEM_USAGE: case MacroConditionStats::Type::MEM_USAGE:
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
_value->setSuffix("MB"); _value->setSuffix("MB");
break; break;
case StatsType::AVG_FRAMETIME: case MacroConditionStats::Type::AVG_FRAMETIME:
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
_value->setSuffix("ms"); _value->setSuffix("ms");
break; break;
case StatsType::RENDER_LAG: case MacroConditionStats::Type::RENDER_LAG:
_value->setMaximum(100); _value->setMaximum(100);
_value->setSuffix("%"); _value->setSuffix("%");
break; break;
case StatsType::ENCODE_LAG: case MacroConditionStats::Type::ENCODE_LAG:
_value->setMaximum(100); _value->setMaximum(100);
_value->setSuffix("%"); _value->setSuffix("%");
break; break;
case StatsType::STREAM_DROPPED_FRAMES: case MacroConditionStats::Type::STREAM_DROPPED_FRAMES:
_value->setMaximum(100); _value->setMaximum(100);
_value->setSuffix("%"); _value->setSuffix("%");
break; break;
case StatsType::STREAM_BITRATE: case MacroConditionStats::Type::STREAM_BITRATE:
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
_value->setSuffix("kb/s"); _value->setSuffix("kb/s");
break; break;
case StatsType::STREAM_MB_SENT: case MacroConditionStats::Type::STREAM_MB_SENT:
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
_value->setSuffix("MB"); _value->setSuffix("MB");
break; break;
case StatsType::RECORDING_DROPPED_FRAMES: case MacroConditionStats::Type::RECORDING_DROPPED_FRAMES:
_value->setMaximum(100); _value->setMaximum(100);
_value->setSuffix("%"); _value->setSuffix("%");
break; break;
case StatsType::RECORDING_BITRATE: case MacroConditionStats::Type::RECORDING_BITRATE:
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
_value->setSuffix("kb/s"); _value->setSuffix("kb/s");
break; break;
case StatsType::RECORDING_MB_SENT: case MacroConditionStats::Type::RECORDING_MB_SENT:
_value->setMaximum(999999999999); _value->setMaximum(999999999999);
_value->setSuffix("MB"); _value->setSuffix("MB");
break; break;

View File

@@ -2,31 +2,9 @@
#include "macro.hpp" #include "macro.hpp"
#include <QWidget> #include <QWidget>
#include <QComboBox> #include <QComboBox>
#include <QDoubleSpinBox> #include <variable-spinbox.hpp>
#include <util/platform.h> #include <util/platform.h>
enum class StatsType {
FPS,
CPU_USAGE,
DISK_USAGE, // not implemented
MEM_USAGE,
AVG_FRAMETIME,
RENDER_LAG,
ENCODE_LAG,
STREAM_DROPPED_FRAMES,
STREAM_BITRATE,
STREAM_MB_SENT,
RECORDING_DROPPED_FRAMES, // not sure if this makes sense
RECORDING_BITRATE,
RECORDING_MB_SENT,
};
enum class StatsCondition {
ABOVE,
EQUALS,
BELOW,
};
class MacroConditionStats : public MacroCondition { class MacroConditionStats : public MacroCondition {
public: public:
MacroConditionStats(Macro *m); MacroConditionStats(Macro *m);
@@ -41,9 +19,31 @@ public:
return std::make_shared<MacroConditionStats>(m); return std::make_shared<MacroConditionStats>(m);
} }
double _value = 0; NumberVariable<double> _value = 0.0;
StatsType _type = StatsType::FPS;
StatsCondition _condition = StatsCondition::ABOVE; enum class Type {
FPS,
CPU_USAGE,
DISK_USAGE, // not implemented
MEM_USAGE,
AVG_FRAMETIME,
RENDER_LAG,
ENCODE_LAG,
STREAM_DROPPED_FRAMES,
STREAM_BITRATE,
STREAM_MB_SENT,
RECORDING_DROPPED_FRAMES, // not sure if this makes sense
RECORDING_BITRATE,
RECORDING_MB_SENT,
};
Type _type = Type::FPS;
enum class Condition {
ABOVE,
EQUALS,
BELOW,
};
Condition _condition = Condition::ABOVE;
private: private:
bool CheckFPS(); bool CheckFPS();
@@ -98,7 +98,7 @@ public:
} }
private slots: private slots:
void ValueChanged(double value); void ValueChanged(const NumberVariable<double> &value);
void StatsTypeChanged(int type); void StatsTypeChanged(int type);
void ConditionChanged(int cond); void ConditionChanged(int cond);
@@ -108,7 +108,7 @@ signals:
protected: protected:
QComboBox *_stats; QComboBox *_stats;
QComboBox *_condition; QComboBox *_condition;
QDoubleSpinBox *_value; VariableDoubleSpinBox *_value;
std::shared_ptr<MacroConditionStats> _entryData; std::shared_ptr<MacroConditionStats> _entryData;
private: private:

View File

@@ -0,0 +1,222 @@
#include "macro-condition-edit.hpp"
#include "macro-condition-run.hpp"
#include "utility.hpp"
#include "advanced-scene-switcher.hpp"
#include <QProcess>
#include <QDesktopServices>
const std::string MacroConditionRun::id = "run";
bool MacroConditionRun::_registered = MacroConditionFactory::Register(
MacroConditionRun::id,
{MacroConditionRun::Create, MacroConditionRunEdit::Create,
"AdvSceneSwitcher.condition.run"});
MacroConditionRun::~MacroConditionRun()
{
if (_thread.joinable()) {
_thread.join();
}
}
bool MacroConditionRun::CheckCondition()
{
if (!_threadDone) {
return false;
}
bool ret = false;
switch (_procStatus) {
case MacroConditionRun::Status::FAILED_TO_START:
SetVariableValue("Failed to start process");
ret = false;
break;
case MacroConditionRun::Status::TIMEOUT:
SetVariableValue("Timeout while running process");
ret = false;
break;
case MacroConditionRun::Status::OK:
ret = _checkExitCode ? _exitCode == _procExitCode : true;
SetVariableValue(std::to_string(_procExitCode));
break;
default:
break;
}
if (_thread.joinable()) {
_thread.join();
}
_threadDone = false;
_thread = std::thread(&MacroConditionRun::RunProcess, this);
return ret;
}
void MacroConditionRun::RunProcess()
{
QProcess process;
process.setWorkingDirectory(
QString::fromStdString(_procConfig.WorkingDir()));
process.start(QString::fromStdString(_procConfig.Path()),
_procConfig.Args());
int timeout = _timeout.Milliseconds();
vblog(LOG_INFO, "run \"%s\" with a timeout of %d ms",
_procConfig.Path().c_str(), timeout);
bool procFinishedInTime = process.waitForFinished(timeout);
if (!procFinishedInTime) {
if (process.error() == QProcess::FailedToStart) {
vblog(LOG_INFO, "failed to start \"%s\"!",
_procConfig.Path().c_str());
_procStatus = Status::FAILED_TO_START;
} else {
vblog(LOG_INFO,
"timeout while running \"%s\"\nAttempting to kill process!",
_procConfig.Path().c_str());
process.kill();
process.waitForFinished();
_procStatus = Status::TIMEOUT;
}
}
bool validExitCode = process.exitStatus() == QProcess::NormalExit;
if ((_checkExitCode && !validExitCode) || !procFinishedInTime) {
_threadDone = true;
return;
}
_procExitCode = process.exitCode();
_procStatus = Status::OK;
_threadDone = true;
}
bool MacroConditionRun::Save(obs_data_t *obj) const
{
MacroCondition::Save(obj);
_procConfig.Save(obj);
obs_data_set_bool(obj, "checkExitCode", _checkExitCode);
obs_data_set_int(obj, "exitCode", _exitCode);
_timeout.Save(obj, "timeout");
return true;
}
bool MacroConditionRun::Load(obs_data_t *obj)
{
MacroCondition::Load(obj);
_procConfig.Load(obj);
_checkExitCode = obs_data_get_bool(obj, "checkExitCode");
_exitCode = obs_data_get_int(obj, "exitCode");
_timeout.Load(obj, "timeout");
return true;
}
std::string MacroConditionRun::GetShortDesc() const
{
return _procConfig.UnresolvedPath();
}
MacroConditionRunEdit::MacroConditionRunEdit(
QWidget *parent, std::shared_ptr<MacroConditionRun> entryData)
: QWidget(parent),
_procConfig(new ProcessConfigEdit(this)),
_checkExitCode(new QCheckBox()),
_exitCode(new QSpinBox()),
_timeout(new DurationSelection(this, false, 0.1))
{
_exitCode->setMinimum(-99999);
_exitCode->setMaximum(999999);
QWidget::connect(_procConfig,
SIGNAL(ConfigChanged(const ProcessConfig &)), this,
SLOT(ProcessConfigChanged(const ProcessConfig &)));
QWidget::connect(_timeout, SIGNAL(DurationChanged(const Duration &)),
this, SLOT(TimeoutChanged(const Duration &)));
QWidget::connect(_checkExitCode, SIGNAL(stateChanged(int)), this,
SLOT(CheckExitCodeChanged(int)));
QWidget::connect(_exitCode, SIGNAL(valueChanged(int)), this,
SLOT(ExitCodeChanged(int)));
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{checkExitCode}}", _checkExitCode},
{"{{exitCode}}", _exitCode},
{"{{timeout}}", _timeout},
};
auto exitLayout = new QHBoxLayout();
placeWidgets(
obs_module_text("AdvSceneSwitcher.condition.run.entry.exit"),
exitLayout, widgetPlaceholders);
auto timeoutLayout = new QHBoxLayout();
placeWidgets(obs_module_text("AdvSceneSwitcher.condition.run.entry"),
timeoutLayout, widgetPlaceholders);
auto *layout = new QVBoxLayout;
layout->addLayout(timeoutLayout);
layout->addWidget(_procConfig);
layout->addLayout(exitLayout);
setLayout(layout);
_entryData = entryData;
UpdateEntryData();
_loading = false;
}
void MacroConditionRunEdit::UpdateEntryData()
{
if (!_entryData) {
return;
}
_procConfig->SetProcessConfig(_entryData->_procConfig);
_timeout->SetDuration(_entryData->_timeout);
_checkExitCode->setChecked(_entryData->_checkExitCode);
_exitCode->setValue(_entryData->_exitCode);
}
void MacroConditionRunEdit::TimeoutChanged(const Duration &dur)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_timeout = dur;
}
void MacroConditionRunEdit::CheckExitCodeChanged(int state)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_checkExitCode = state;
}
void MacroConditionRunEdit::ExitCodeChanged(int exitCode)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_exitCode = exitCode;
}
void MacroConditionRunEdit::ProcessConfigChanged(const ProcessConfig &conf)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_procConfig = conf;
adjustSize();
updateGeometry();
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}

View File

@@ -0,0 +1,79 @@
#pragma once
#include "macro.hpp"
#include "process-config.hpp"
#include "duration-control.hpp"
#include <QCheckBox>
#include <QSpinBox>
class MacroConditionRun : public MacroCondition {
public:
MacroConditionRun(Macro *m) : MacroCondition(m, true) {}
~MacroConditionRun();
bool CheckCondition();
bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj);
std::string GetShortDesc() const;
std::string GetId() const { return id; };
static std::shared_ptr<MacroCondition> Create(Macro *m)
{
return std::make_shared<MacroConditionRun>(m);
}
ProcessConfig _procConfig;
bool _checkExitCode = true;
int _exitCode = 0;
Duration _timeout = Duration(0.1);
private:
enum class Status {
NONE,
FAILED_TO_START,
TIMEOUT,
OK,
};
void RunProcess();
std::thread _thread;
std::atomic_bool _threadDone{true};
Status _procStatus = Status::NONE;
int _procExitCode = 0;
static bool _registered;
static const std::string id;
};
class MacroConditionRunEdit : public QWidget {
Q_OBJECT
public:
MacroConditionRunEdit(QWidget *parent,
std::shared_ptr<MacroConditionRun> cond = nullptr);
void UpdateEntryData();
static QWidget *Create(QWidget *parent,
std::shared_ptr<MacroCondition> cond)
{
return new MacroConditionRunEdit(
parent,
std::dynamic_pointer_cast<MacroConditionRun>(cond));
}
private slots:
void ProcessConfigChanged(const ProcessConfig &);
void TimeoutChanged(const Duration &);
void CheckExitCodeChanged(int);
void ExitCodeChanged(int);
signals:
void HeaderInfoChanged(const QString &);
protected:
ProcessConfigEdit *_procConfig;
QCheckBox *_checkExitCode;
QSpinBox *_exitCode;
DurationSelection *_timeout;
std::shared_ptr<MacroConditionRun> _entryData;
private:
bool _loading = true;
};

View File

@@ -10,13 +10,14 @@ bool MacroConditionSceneOrder::_registered = MacroConditionFactory::Register(
{MacroConditionSceneOrder::Create, MacroConditionSceneOrderEdit::Create, {MacroConditionSceneOrder::Create, MacroConditionSceneOrderEdit::Create,
"AdvSceneSwitcher.condition.sceneOrder"}); "AdvSceneSwitcher.condition.sceneOrder"});
static std::map<SceneOrderCondition, std::string> sceneOrderConditionTypes = { static std::map<MacroConditionSceneOrder::Condition, std::string>
{SceneOrderCondition::ABOVE, sceneOrderConditionTypes = {
"AdvSceneSwitcher.condition.sceneOrder.type.above"}, {MacroConditionSceneOrder::Condition::ABOVE,
{SceneOrderCondition::BELOW, "AdvSceneSwitcher.condition.sceneOrder.type.above"},
"AdvSceneSwitcher.condition.sceneOrder.type.below"}, {MacroConditionSceneOrder::Condition::BELOW,
{SceneOrderCondition::POSITION, "AdvSceneSwitcher.condition.sceneOrder.type.below"},
"AdvSceneSwitcher.condition.sceneOrder.type.position"}, {MacroConditionSceneOrder::Condition::POSITION,
"AdvSceneSwitcher.condition.sceneOrder.type.position"},
}; };
struct PosInfo2 { struct PosInfo2 {
@@ -115,13 +116,13 @@ bool MacroConditionSceneOrder::CheckCondition()
bool ret = false; bool ret = false;
switch (_condition) { switch (_condition) {
case SceneOrderCondition::ABOVE: case Condition::ABOVE:
ret = isAbove(positions1, positions2); ret = isAbove(positions1, positions2);
break; break;
case SceneOrderCondition::BELOW: case Condition::BELOW:
ret = isBelow(positions1, positions2); ret = isBelow(positions1, positions2);
break; break;
case SceneOrderCondition::POSITION: case Condition::POSITION:
for (int p : positions1) { for (int p : positions1) {
if (p == _position) if (p == _position)
ret = true; ret = true;
@@ -143,6 +144,8 @@ bool MacroConditionSceneOrder::Save(obs_data_t *obj) const
_source2.Save(obj, "sceneItemSelection2"); _source2.Save(obj, "sceneItemSelection2");
obs_data_set_int(obj, "condition", static_cast<int>(_condition)); obs_data_set_int(obj, "condition", static_cast<int>(_condition));
obs_data_set_int(obj, "position", _position); obs_data_set_int(obj, "position", _position);
_position.Save(obj, "position");
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -168,9 +171,12 @@ bool MacroConditionSceneOrder::Load(obs_data_t *obj)
} else { } else {
_source2.Load(obj, "sceneItemSelection2"); _source2.Load(obj, "sceneItemSelection2");
} }
_condition = static_cast<SceneOrderCondition>( _condition = static_cast<Condition>(obs_data_get_int(obj, "condition"));
obs_data_get_int(obj, "condition")); if (!obs_data_has_user_value(obj, "version")) {
_position = obs_data_get_int(obj, "position"); _position = obs_data_get_int(obj, "position");
} else {
_position.Load(obj, "position");
}
return true; return true;
} }
@@ -181,7 +187,7 @@ std::string MacroConditionSceneOrder::GetShortDesc() const
} }
std::string header = _scene.ToString() + " - " + _source.ToString(); std::string header = _scene.ToString() + " - " + _source.ToString();
if (!_source2.ToString().empty() && if (!_source2.ToString().empty() &&
_condition != SceneOrderCondition::POSITION) { _condition != MacroConditionSceneOrder::Condition::POSITION) {
header += " - " + _source2.ToString(); header += " - " + _source2.ToString();
} }
return header; return header;
@@ -196,19 +202,19 @@ static inline void populateConditionSelection(QComboBox *list)
MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit( MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit(
QWidget *parent, std::shared_ptr<MacroConditionSceneOrder> entryData) QWidget *parent, std::shared_ptr<MacroConditionSceneOrder> entryData)
: QWidget(parent) : QWidget(parent),
_scenes(new SceneSelectionWidget(window(), true, false, false, true)),
_conditions(new QComboBox()),
_sources(new SceneItemSelectionWidget(parent)),
_sources2(new SceneItemSelectionWidget(parent)),
_position(new VariableSpinBox()),
_posInfo(new QLabel(obs_module_text(
"AdvSceneSwitcher.condition.sceneOrder.positionInfo")))
{ {
_scenes = new SceneSelectionWidget(window(), true, false, false, true);
_sources = new SceneItemSelectionWidget(parent);
_sources2 = new SceneItemSelectionWidget(parent);
_conditions = new QComboBox();
_position = new QSpinBox();
_posInfo = new QLabel(obs_module_text(
"AdvSceneSwitcher.condition.sceneOrder.positionInfo"));
populateConditionSelection(_conditions); populateConditionSelection(_conditions);
if (entryData.get()) { if (entryData.get()) {
if (entryData->_condition == SceneOrderCondition::POSITION) { if (entryData->_condition ==
MacroConditionSceneOrder::Condition::POSITION) {
_sources->SetPlaceholderType( _sources->SetPlaceholderType(
SceneItemSelectionWidget::Placeholder::ANY); SceneItemSelectionWidget::Placeholder::ANY);
} else { } else {
@@ -232,8 +238,10 @@ MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit(
SLOT(Source2Changed(const SceneItemSelection &))); SLOT(Source2Changed(const SceneItemSelection &)));
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int))); SLOT(ConditionChanged(int)));
QWidget::connect(_position, SIGNAL(valueChanged(int)), this, QWidget::connect(
SLOT(PositionChanged(int))); _position,
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
this, SLOT(PositionChanged(const NumberVariable<int> &)));
auto entryLayout = new QHBoxLayout(); auto entryLayout = new QHBoxLayout();
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@@ -296,11 +304,12 @@ void MacroConditionSceneOrderEdit::ConditionChanged(int index)
{ {
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_condition = _entryData->_condition =
static_cast<SceneOrderCondition>(index); static_cast<MacroConditionSceneOrder::Condition>(index);
} }
SetWidgetVisibility(_entryData->_condition == SetWidgetVisibility(_entryData->_condition ==
SceneOrderCondition::POSITION); MacroConditionSceneOrder::Condition::POSITION);
if (_entryData->_condition == SceneOrderCondition::POSITION) { if (_entryData->_condition ==
MacroConditionSceneOrder::Condition::POSITION) {
_sources->SetPlaceholderType( _sources->SetPlaceholderType(
SceneItemSelectionWidget::Placeholder::ANY); SceneItemSelectionWidget::Placeholder::ANY);
} else { } else {
@@ -312,7 +321,8 @@ void MacroConditionSceneOrderEdit::ConditionChanged(int index)
QString::fromStdString(_entryData->GetShortDesc())); QString::fromStdString(_entryData->GetShortDesc()));
} }
void MacroConditionSceneOrderEdit::PositionChanged(int value) void MacroConditionSceneOrderEdit::PositionChanged(
const NumberVariable<int> &value)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
@@ -339,8 +349,8 @@ void MacroConditionSceneOrderEdit::UpdateEntryData()
_scenes->SetScene(_entryData->_scene); _scenes->SetScene(_entryData->_scene);
_sources->SetSceneItem(_entryData->_source); _sources->SetSceneItem(_entryData->_source);
_sources2->SetSceneItem(_entryData->_source2); _sources2->SetSceneItem(_entryData->_source2);
_position->setValue(_entryData->_position); _position->SetValue(_entryData->_position);
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition)); _conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
SetWidgetVisibility(_entryData->_condition == SetWidgetVisibility(_entryData->_condition ==
SceneOrderCondition::POSITION); MacroConditionSceneOrder::Condition::POSITION);
} }

View File

@@ -2,16 +2,11 @@
#include "macro.hpp" #include "macro.hpp"
#include "scene-selection.hpp" #include "scene-selection.hpp"
#include "scene-item-selection.hpp" #include "scene-item-selection.hpp"
#include "variable-spinbox.hpp"
#include <QWidget> #include <QWidget>
#include <QComboBox> #include <QComboBox>
enum class SceneOrderCondition {
ABOVE,
BELOW,
POSITION,
};
class MacroConditionSceneOrder : public MacroCondition { class MacroConditionSceneOrder : public MacroCondition {
public: public:
MacroConditionSceneOrder(Macro *m) : MacroCondition(m) {} MacroConditionSceneOrder(Macro *m) : MacroCondition(m) {}
@@ -28,8 +23,14 @@ public:
SceneSelection _scene; SceneSelection _scene;
SceneItemSelection _source; SceneItemSelection _source;
SceneItemSelection _source2; SceneItemSelection _source2;
int _position = 0; NumberVariable<int> _position = 0;
SceneOrderCondition _condition = SceneOrderCondition::ABOVE;
enum class Condition {
ABOVE,
BELOW,
POSITION,
};
Condition _condition = Condition::ABOVE;
private: private:
static bool _registered; static bool _registered;
@@ -58,7 +59,7 @@ private slots:
void SourceChanged(const SceneItemSelection &); void SourceChanged(const SceneItemSelection &);
void Source2Changed(const SceneItemSelection &); void Source2Changed(const SceneItemSelection &);
void ConditionChanged(int cond); void ConditionChanged(int cond);
void PositionChanged(int cond); void PositionChanged(const NumberVariable<int> &);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);
@@ -67,7 +68,7 @@ protected:
QComboBox *_conditions; QComboBox *_conditions;
SceneItemSelectionWidget *_sources; SceneItemSelectionWidget *_sources;
SceneItemSelectionWidget *_sources2; SceneItemSelectionWidget *_sources2;
QSpinBox *_position; VariableSpinBox *_position;
QLabel *_posInfo; QLabel *_posInfo;
std::shared_ptr<MacroConditionSceneOrder> _entryData; std::shared_ptr<MacroConditionSceneOrder> _entryData;

View File

@@ -17,13 +17,15 @@ bool MacroConditionSceneTransform::CheckCondition()
bool ret = false; bool ret = false;
auto items = _source.GetSceneItems(_scene); auto items = _source.GetSceneItems(_scene);
std::string json;
for (auto &item : items) { for (auto &item : items) {
auto json = getSceneItemTransform(item); json = getSceneItemTransform(item);
if (matchJson(json, _settings, _regex)) { if (matchJson(json, _settings, _regex)) {
ret = true; ret = true;
} }
obs_sceneitem_release(item); obs_sceneitem_release(item);
} }
SetVariableValue(json);
return ret; return ret;
} }

View File

@@ -10,7 +10,7 @@
class MacroConditionSceneTransform : public MacroCondition { class MacroConditionSceneTransform : public MacroCondition {
public: public:
MacroConditionSceneTransform(Macro *m) : MacroCondition(m) {} MacroConditionSceneTransform(Macro *m) : MacroCondition(m, true) {}
bool CheckCondition(); bool CheckCondition();
bool Save(obs_data_t *obj) const; bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj); bool Load(obs_data_t *obj);
@@ -24,7 +24,7 @@ public:
SceneSelection _scene; SceneSelection _scene;
SceneItemSelection _source; SceneItemSelection _source;
RegexConfig _regex; RegexConfig _regex;
VariableResolvingString _settings = ""; StringVariable _settings = "";
private: private:
static bool _registered; static bool _registered;

View File

@@ -29,7 +29,7 @@ public:
SourceSelection _source; SourceSelection _source;
SourceCondition _condition = SourceCondition::ACTIVE; SourceCondition _condition = SourceCondition::ACTIVE;
VariableResolvingString _settings = ""; StringVariable _settings = "";
RegexConfig _regex; RegexConfig _regex;
private: private:

View File

@@ -35,12 +35,12 @@ bool MacroConditionTimer::CheckCondition()
void MacroConditionTimer::SetRandomTimeRemaining() void MacroConditionTimer::SetRandomTimeRemaining()
{ {
double min, max; double min, max;
if (_duration.seconds <= _duration2.seconds) { if (_duration.Seconds() <= _duration2.Seconds()) {
min = _duration.seconds; min = _duration.Seconds();
max = _duration2.seconds; max = _duration2.Seconds();
} else { } else {
min = _duration2.seconds; min = _duration2.Seconds();
max = _duration.seconds; max = _duration.Seconds();
} }
std::uniform_real_distribution<double> unif(min, max); std::uniform_real_distribution<double> unif(min, max);
@@ -53,17 +53,18 @@ bool MacroConditionTimer::Save(obs_data_t *obj) const
MacroCondition::Save(obj); MacroCondition::Save(obj);
obs_data_set_int(obj, "type", static_cast<int>(_type)); obs_data_set_int(obj, "type", static_cast<int>(_type));
_duration.Save(obj); _duration.Save(obj);
_duration2.Save(obj, "seconds2", "displayUnit2"); _duration2.Save(obj, "duration2");
if (_saveRemaining) { if (_saveRemaining) {
obs_data_set_double(obj, "remaining", obs_data_set_double(obj, "remaining",
_paused ? _remaining _paused ? _remaining
: _duration.TimeRemaining()); : _duration.TimeRemaining());
} else { } else {
obs_data_set_double(obj, "remaining", _duration.seconds); obs_data_set_double(obj, "remaining", _duration.Seconds());
} }
obs_data_set_bool(obj, "saveRemaining", _saveRemaining); obs_data_set_bool(obj, "saveRemaining", _saveRemaining);
obs_data_set_bool(obj, "paused", _paused); obs_data_set_bool(obj, "paused", _paused);
obs_data_set_bool(obj, "oneshot", _oneshot); obs_data_set_bool(obj, "oneshot", _oneshot);
obs_data_set_int(obj, "version", 1);
return true; return true;
} }
@@ -72,7 +73,14 @@ bool MacroConditionTimer::Load(obs_data_t *obj)
MacroCondition::Load(obj); MacroCondition::Load(obj);
_type = static_cast<TimerType>(obs_data_get_int(obj, "type")); _type = static_cast<TimerType>(obs_data_get_int(obj, "type"));
_duration.Load(obj); _duration.Load(obj);
_duration2.Load(obj, "seconds2", "displayUnit2"); // TODO: remove this fallback
if (obs_data_get_int(obj, "version") == 1) {
_duration2.Load(obj, "duration2");
} else {
_duration2.Load(obj, "seconds2");
_duration2.SetUnit(static_cast<Duration::Unit>(
obs_data_get_int(obj, "displayUnit2")));
}
_remaining = obs_data_get_double(obj, "remaining"); _remaining = obs_data_get_double(obj, "remaining");
_paused = obs_data_get_bool(obj, "paused"); _paused = obs_data_get_bool(obj, "paused");
_saveRemaining = obs_data_get_bool(obj, "saveRemaining"); _saveRemaining = obs_data_get_bool(obj, "saveRemaining");
@@ -103,7 +111,7 @@ void MacroConditionTimer::Continue()
void MacroConditionTimer::Reset() void MacroConditionTimer::Reset()
{ {
_remaining = _duration.seconds; _remaining = _duration.Seconds();
_duration.Reset(); _duration.Reset();
if (_type == TimerType::RANDOM) { if (_type == TimerType::RANDOM) {
SetRandomTimeRemaining(); SetRandomTimeRemaining();
@@ -136,14 +144,10 @@ MacroConditionTimerEdit::MacroConditionTimerEdit(
QWidget::connect(_timerTypes, SIGNAL(currentIndexChanged(int)), this, QWidget::connect(_timerTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(TimerTypeChanged(int))); SLOT(TimerTypeChanged(int)));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this, QWidget::connect(_duration2, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationUnitChanged(DurationUnit))); this, SLOT(Duration2Changed(const Duration &)));
QWidget::connect(_duration2, SIGNAL(DurationChanged(double)), this,
SLOT(Duration2Changed(double)));
QWidget::connect(_duration2, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(Duration2UnitChanged(DurationUnit)));
QWidget::connect(_pauseConinue, SIGNAL(clicked()), this, QWidget::connect(_pauseConinue, SIGNAL(clicked()), this,
SLOT(PauseContinueClicked())); SLOT(PauseContinueClicked()));
QWidget::connect(_reset, SIGNAL(clicked()), this, SLOT(ResetClicked())); QWidget::connect(_reset, SIGNAL(clicked()), this, SLOT(ResetClicked()));
@@ -201,44 +205,24 @@ void MacroConditionTimerEdit::TimerTypeChanged(int type)
SetWidgetVisibility(); SetWidgetVisibility();
} }
void MacroConditionTimerEdit::DurationChanged(double seconds) void MacroConditionTimerEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
} }
void MacroConditionTimerEdit::DurationUnitChanged(DurationUnit unit) void MacroConditionTimerEdit::Duration2Changed(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.displayUnit = unit; _entryData->_duration2 = dur;
}
void MacroConditionTimerEdit::Duration2Changed(double seconds)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration2.seconds = seconds;
}
void MacroConditionTimerEdit::Duration2UnitChanged(DurationUnit unit)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration2.displayUnit = unit;
} }
void MacroConditionTimerEdit::SaveRemainingChanged(int state) void MacroConditionTimerEdit::SaveRemainingChanged(int state)

View File

@@ -63,10 +63,8 @@ public:
private slots: private slots:
void TimerTypeChanged(int type); void TimerTypeChanged(int type);
void DurationChanged(double seconds); void DurationChanged(const Duration &seconds);
void DurationUnitChanged(DurationUnit unit); void Duration2Changed(const Duration &seconds);
void Duration2Changed(double seconds);
void Duration2UnitChanged(DurationUnit unit);
void SaveRemainingChanged(int state); void SaveRemainingChanged(int state);
void AutoResetChanged(int state); void AutoResetChanged(int state);
void PauseContinueClicked(); void PauseContinueClicked();

View File

@@ -70,7 +70,7 @@ bool MacroConditionTransition::CheckCondition()
break; break;
} }
case TransitionCondition::DURATION: case TransitionCondition::DURATION:
ret = _duration.seconds * 1000 == ret = _duration.Milliseconds() ==
obs_frontend_get_transition_duration(); obs_frontend_get_transition_duration();
break; break;
case TransitionCondition::STARTED: case TransitionCondition::STARTED:
@@ -198,8 +198,8 @@ MacroConditionTransitionEdit::MacroConditionTransitionEdit(
SLOT(TransitionChanged(const TransitionSelection &))); SLOT(TransitionChanged(const TransitionSelection &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &))); this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_duration, SIGNAL(DurationChanged(double)), this, QWidget::connect(_duration, SIGNAL(DurationChanged(const Duration &)),
SLOT(DurationChanged(double))); this, SLOT(DurationChanged(const Duration &)));
QHBoxLayout *mainLayout = new QHBoxLayout; QHBoxLayout *mainLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = { std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
@@ -260,14 +260,14 @@ void MacroConditionTransitionEdit::SceneChanged(const SceneSelection &s)
_entryData->_scene = s; _entryData->_scene = s;
} }
void MacroConditionTransitionEdit::DurationChanged(double seconds) void MacroConditionTransitionEdit::DurationChanged(const Duration &dur)
{ {
if (_loading || !_entryData) { if (_loading || !_entryData) {
return; return;
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_duration.seconds = seconds; _entryData->_duration = dur;
} }
void MacroConditionTransitionEdit::SetWidgetVisibility() void MacroConditionTransitionEdit::SetWidgetVisibility()

View File

@@ -68,7 +68,7 @@ private slots:
void ConditionChanged(int cond); void ConditionChanged(int cond);
void TransitionChanged(const TransitionSelection &); void TransitionChanged(const TransitionSelection &);
void SceneChanged(const SceneSelection &); void SceneChanged(const SceneSelection &);
void DurationChanged(double seconds); void DurationChanged(const Duration &seconds);
signals: signals:
void HeaderInfoChanged(const QString &); void HeaderInfoChanged(const QString &);

View File

@@ -36,15 +36,13 @@ const static std::map<MacroConditionVariable::Type, std::string>
static bool isNumber(const Variable &var) static bool isNumber(const Variable &var)
{ {
double _; return var.DoubleValue().has_value();
return var.DoubleValue(_);
} }
static bool compareNumber(const Variable &var, double value, bool less) static bool compareNumber(const Variable &var, double value, bool less)
{ {
double varValue; auto varValue = var.DoubleValue();
if (!varValue.has_value()) {
if (!var.DoubleValue(varValue)) {
return false; return false;
} }
if (less) { if (less) {
@@ -78,15 +76,15 @@ bool MacroConditionVariable::ValueChanged(const Variable &var)
bool MacroConditionVariable::CompareVariables() bool MacroConditionVariable::CompareVariables()
{ {
auto var1 = GetVariableByName(_variableName); auto var1 = _variable.lock();
auto var2 = GetVariableByName(_variable2Name); auto var2 = _variable2.lock();
if (!var1 || !var2) { if (!var1 || !var2) {
return false; return false;
} }
double val1, val2; auto val1 = var1->DoubleValue();
bool validNumbers = var1->DoubleValue(val1); auto val2 = var2->DoubleValue();
validNumbers = validNumbers && var2->DoubleValue(val2); bool validNumbers = val1.has_value() && val2.has_value();
switch (_type) { switch (_type) {
case MacroConditionVariable::Type::EQUALS_VARIABLE: case MacroConditionVariable::Type::EQUALS_VARIABLE:
@@ -107,7 +105,7 @@ bool MacroConditionVariable::CompareVariables()
bool MacroConditionVariable::CheckCondition() bool MacroConditionVariable::CheckCondition()
{ {
auto var = GetVariableByName(_variableName); auto var = _variable.lock();
if (!var) { if (!var) {
return false; return false;
} }
@@ -139,8 +137,10 @@ bool MacroConditionVariable::CheckCondition()
bool MacroConditionVariable::Save(obs_data_t *obj) const bool MacroConditionVariable::Save(obs_data_t *obj) const
{ {
MacroCondition::Save(obj); MacroCondition::Save(obj);
obs_data_set_string(obj, "variableName", _variableName.c_str()); obs_data_set_string(obj, "variableName",
obs_data_set_string(obj, "variable2Name", _variable2Name.c_str()); GetWeakVariableName(_variable).c_str());
obs_data_set_string(obj, "variable2Name",
GetWeakVariableName(_variable2).c_str());
obs_data_set_string(obj, "strValue", _strValue.c_str()); obs_data_set_string(obj, "strValue", _strValue.c_str());
obs_data_set_double(obj, "numValue", _numValue); obs_data_set_double(obj, "numValue", _numValue);
obs_data_set_int(obj, "condition", static_cast<int>(_type)); obs_data_set_int(obj, "condition", static_cast<int>(_type));
@@ -151,8 +151,10 @@ bool MacroConditionVariable::Save(obs_data_t *obj) const
bool MacroConditionVariable::Load(obs_data_t *obj) bool MacroConditionVariable::Load(obs_data_t *obj)
{ {
MacroCondition::Load(obj); MacroCondition::Load(obj);
_variableName = obs_data_get_string(obj, "variableName"); _variable =
_variable2Name = obs_data_get_string(obj, "variable2Name"); GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
_variable2 = GetWeakVariableByName(
obs_data_get_string(obj, "variable2Name"));
_strValue = obs_data_get_string(obj, "strValue"); _strValue = obs_data_get_string(obj, "strValue");
_numValue = obs_data_get_double(obj, "numValue"); _numValue = obs_data_get_double(obj, "numValue");
_type = static_cast<Type>(obs_data_get_int(obj, "condition")); _type = static_cast<Type>(obs_data_get_int(obj, "condition"));
@@ -167,7 +169,7 @@ bool MacroConditionVariable::Load(obs_data_t *obj)
std::string MacroConditionVariable::GetShortDesc() const std::string MacroConditionVariable::GetShortDesc() const
{ {
return _variableName; return GetWeakVariableName(_variable);
} }
static inline void populateConditionSelection(QComboBox *list) static inline void populateConditionSelection(QComboBox *list)
@@ -238,8 +240,8 @@ void MacroConditionVariableEdit::UpdateEntryData()
return; return;
} }
_variables->SetVariable(_entryData->_variableName); _variables->SetVariable(_entryData->_variable);
_variables2->SetVariable(_entryData->_variable2Name); _variables2->SetVariable(_entryData->_variable2);
_conditions->setCurrentIndex(static_cast<int>(_entryData->_type)); _conditions->setCurrentIndex(static_cast<int>(_entryData->_type));
_strValue->setPlainText(QString::fromStdString(_entryData->_strValue)); _strValue->setPlainText(QString::fromStdString(_entryData->_strValue));
_numValue->setValue(_entryData->_numValue); _numValue->setValue(_entryData->_numValue);
@@ -254,7 +256,7 @@ void MacroConditionVariableEdit::VariableChanged(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_variableName = text.toStdString(); _entryData->_variable = GetWeakVariableByQString(text);
} }
void MacroConditionVariableEdit::Variable2Changed(const QString &text) void MacroConditionVariableEdit::Variable2Changed(const QString &text)
@@ -265,7 +267,7 @@ void MacroConditionVariableEdit::Variable2Changed(const QString &text)
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_variable2Name = text.toStdString(); _entryData->_variable2 = GetWeakVariableByQString(text);
} }
void MacroConditionVariableEdit::ConditionChanged(int value) void MacroConditionVariableEdit::ConditionChanged(int value)

View File

@@ -35,8 +35,8 @@ public:
}; };
Type _type = Type::EQUALS; Type _type = Type::EQUALS;
std::string _variableName = ""; std::weak_ptr<Variable> _variable;
std::string _variable2Name = ""; std::weak_ptr<Variable> _variable2;
std::string _strValue = ""; std::string _strValue = "";
double _numValue = 0; double _numValue = 0;
RegexConfig _regex; RegexConfig _regex;

View File

@@ -38,7 +38,7 @@ bool MacroConditionWebsocket::CheckCondition()
messages = &switcher->websocketMessages; messages = &switcher->websocketMessages;
break; break;
case MacroConditionWebsocket::Type::EVENT: { case MacroConditionWebsocket::Type::EVENT: {
auto connection = GetConnectionByName(_connection); auto connection = _connection.lock();
if (!connection) { if (!connection) {
return false; return false;
} }
@@ -76,7 +76,8 @@ bool MacroConditionWebsocket::Save(obs_data_t *obj) const
obs_data_set_int(obj, "type", static_cast<int>(_type)); obs_data_set_int(obj, "type", static_cast<int>(_type));
_message.Save(obj, "message"); _message.Save(obj, "message");
_regex.Save(obj); _regex.Save(obj);
obs_data_set_string(obj, "connection", _connection.c_str()); obs_data_set_string(obj, "connection",
GetWeakConnectionName(_connection).c_str());
return true; return true;
} }
@@ -91,7 +92,8 @@ bool MacroConditionWebsocket::Load(obs_data_t *obj)
_regex.CreateBackwardsCompatibleRegex( _regex.CreateBackwardsCompatibleRegex(
obs_data_get_bool(obj, "useRegex"), false); obs_data_get_bool(obj, "useRegex"), false);
} }
_connection = obs_data_get_string(obj, "connection"); _connection =
GetWeakConnectionByName(obs_data_get_string(obj, "connection"));
return true; return true;
} }
@@ -100,7 +102,7 @@ std::string MacroConditionWebsocket::GetShortDesc() const
if (_type == Type::REQUEST) { if (_type == Type::REQUEST) {
return ""; return "";
} }
return _connection; return GetWeakConnectionName(_connection);
} }
static inline void populateConditionSelection(QComboBox *list) static inline void populateConditionSelection(QComboBox *list)
@@ -237,7 +239,7 @@ void MacroConditionWebsocketEdit::ConnectionSelectionChanged(
} }
std::lock_guard<std::mutex> lock(switcher->m); std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_connection = connection.toStdString(); _entryData->_connection = GetWeakConnectionByQString(connection);
emit(HeaderInfoChanged(connection)); emit(HeaderInfoChanged(connection));
} }

View File

@@ -25,10 +25,9 @@ public:
}; };
Type _type = Type::REQUEST; Type _type = Type::REQUEST;
VariableResolvingString _message = StringVariable _message = obs_module_text("AdvSceneSwitcher.enterText");
obs_module_text("AdvSceneSwitcher.enterText");
RegexConfig _regex; RegexConfig _regex;
std::string _connection; std::weak_ptr<Connection> _connection;
private: private:
static bool _registered; static bool _registered;

View File

@@ -12,24 +12,30 @@ const std::map<LogicType, LogicTypeInfo> MacroCondition::logicTypes = {
}; };
void DurationModifier::Save(obs_data_t *obj, const char *condName, void DurationModifier::Save(obs_data_t *obj, const char *condName,
const char *secondsName, const char *unitName) const const char *duration) const
{ {
obs_data_set_int(obj, condName, static_cast<int>(_type)); obs_data_set_int(obj, condName, static_cast<int>(_type));
_dur.Save(obj, secondsName, unitName); _dur.Save(obj, duration);
} }
void DurationModifier::Load(obs_data_t *obj, const char *condName, void DurationModifier::Load(obs_data_t *obj, const char *condName,
const char *secondsName, const char *unitName) const char *duration)
{ {
// For backwards compatability check if duration value exist without // For backwards compatability check if duration value exist without
// time constraint condition - if so assume DurationCondition::MORE // time constraint condition - if so assume DurationCondition::MORE
if (!obs_data_has_user_value(obj, condName) && if (!obs_data_has_user_value(obj, condName) &&
obs_data_has_user_value(obj, secondsName)) { obs_data_has_user_value(obj, duration)) {
obs_data_set_int(obj, condName, static_cast<int>(Type::MORE)); obs_data_set_int(obj, condName, static_cast<int>(Type::MORE));
} }
_type = static_cast<Type>(obs_data_get_int(obj, condName)); _type = static_cast<Type>(obs_data_get_int(obj, condName));
_dur.Load(obj, secondsName, unitName); _dur.Load(obj, duration);
// TODO: remove this fallback
if (obs_data_has_user_value(obj, "displayUnit")) {
_dur.SetUnit(static_cast<Duration::Unit>(
obs_data_get_int(obj, "displayUnit")));
}
} }
bool DurationModifier::DurationReached() bool DurationModifier::DurationReached()
@@ -127,7 +133,7 @@ void MacroCondition::CheckDurationModifier(bool &val)
case DurationModifier::Type::WITHIN: case DurationModifier::Type::WITHIN:
if (val) { if (val) {
_duration.SetTimeRemaining( _duration.SetTimeRemaining(
_duration.GetDuration().seconds); _duration.GetDuration().Seconds());
} }
val = val || _duration.DurationReached(); val = val || _duration.DurationReached();
break; break;
@@ -141,14 +147,9 @@ void MacroCondition::SetDurationModifier(DurationModifier::Type m)
_duration.SetModifier(m); _duration.SetModifier(m);
} }
void MacroCondition::SetDurationUnit(DurationUnit u) void MacroCondition::SetDuration(const Duration &duration)
{ {
_duration.SetUnit(u); _duration.SetValue(duration);
}
void MacroCondition::SetDuration(double seconds)
{
_duration.SetValue(seconds);
} }
MacroRefCondition::MacroRefCondition(Macro *m, bool supportsVariableValue) MacroRefCondition::MacroRefCondition(Macro *m, bool supportsVariableValue)
@@ -156,9 +157,10 @@ MacroRefCondition::MacroRefCondition(Macro *m, bool supportsVariableValue)
{ {
} }
void MacroRefCondition::ResolveMacroRef() bool MacroRefCondition::PostLoad()
{ {
_macro.UpdateRef(); _macro.PostLoad();
return true;
} }
MultiMacroRefCondtition::MultiMacroRefCondtition(Macro *m, MultiMacroRefCondtition::MultiMacroRefCondtition(Macro *m,
@@ -167,9 +169,10 @@ MultiMacroRefCondtition::MultiMacroRefCondtition(Macro *m,
{ {
} }
void MultiMacroRefCondtition::ResolveMacroRef() bool MultiMacroRefCondtition::PostLoad()
{ {
for (auto &m : _macros) { for (auto &macro : _macros) {
m.UpdateRef(); macro.PostLoad();
} }
return true;
} }

View File

@@ -39,15 +39,12 @@ public:
}; };
void Save(obs_data_t *obj, const char *condName = "time_constraint", void Save(obs_data_t *obj, const char *condName = "time_constraint",
const char *secondsName = "seconds", const char *duration = "seconds") const;
const char *unitName = "displayUnit") const;
void Load(obs_data_t *obj, const char *condName = "time_constraint", void Load(obs_data_t *obj, const char *condName = "time_constraint",
const char *secondsName = "seconds", const char *duration = "seconds");
const char *unitName = "displayUnit");
void SetModifier(Type cond) { _type = cond; } void SetModifier(Type cond) { _type = cond; }
void SetTimeRemaining(const double &val) { _dur.SetTimeRemaining(val); } void SetTimeRemaining(const double &val) { _dur.SetTimeRemaining(val); }
void SetValue(double value) { _dur.seconds = value; } void SetValue(const Duration &value) { _dur = value; }
void SetUnit(DurationUnit u) { _dur.displayUnit = u; }
Type GetType() { return _type; } Type GetType() { return _type; }
Duration GetDuration() { return _dur; } Duration GetDuration() { return _dur; }
bool DurationReached(); bool DurationReached();
@@ -73,8 +70,7 @@ public:
void CheckDurationModifier(bool &val); void CheckDurationModifier(bool &val);
DurationModifier GetDurationModifier() { return _duration; } DurationModifier GetDurationModifier() { return _duration; }
void SetDurationModifier(DurationModifier::Type m); void SetDurationModifier(DurationModifier::Type m);
void SetDurationUnit(DurationUnit u); void SetDuration(const Duration &duration);
void SetDuration(double seconds);
private: private:
LogicType _logic = LogicType::ROOT_NONE; LogicType _logic = LogicType::ROOT_NONE;
@@ -84,13 +80,15 @@ private:
class MacroRefCondition : virtual public MacroCondition { class MacroRefCondition : virtual public MacroCondition {
public: public:
MacroRefCondition(Macro *m, bool supportsVariableValue = false); MacroRefCondition(Macro *m, bool supportsVariableValue = false);
void ResolveMacroRef(); bool PostLoad() override;
MacroRef _macro; MacroRef _macro;
}; };
class MultiMacroRefCondtition : virtual public MacroCondition { class MultiMacroRefCondtition : virtual public MacroCondition {
public: public:
MultiMacroRefCondtition(Macro *m, bool supportsVariableValue = false); MultiMacroRefCondtition(Macro *m, bool supportsVariableValue = false);
void ResolveMacroRef(); bool PostLoad() override;
std::vector<MacroRef> _macros; std::vector<MacroRef> _macros;
}; };

View File

@@ -0,0 +1,98 @@
#include "macro-dock.hpp"
#include "macro.hpp"
#include "utility.hpp"
#include <QLayout>
#include <obs-module.h>
MacroDock::MacroDock(Macro *m, QWidget *parent)
: OBSDock(parent),
_run(new QPushButton(
obs_module_text("AdvSceneSwitcher.macroDock.run"))),
_pauseToggle(new QPushButton()),
_macro(m)
{
if (_macro) {
setWindowTitle(QString::fromStdString(_macro->Name()));
_run->setVisible(_macro->DockHasRunButton());
_pauseToggle->setVisible(_macro->DockHasPauseButton());
} else {
setWindowTitle("<deleted macro>");
}
setFeatures(DockWidgetClosable | DockWidgetMovable |
DockWidgetFloatable);
QWidget::connect(_run, SIGNAL(clicked()), this, SLOT(RunClicked()));
QWidget::connect(_pauseToggle, SIGNAL(clicked()), this,
SLOT(PauseToggleClicked()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(_run);
layout->addWidget(_pauseToggle);
QWidget::connect(&_timer, SIGNAL(timeout()), this,
SLOT(UpdatePauseText()));
_timer.start(1000);
UpdatePauseText();
// QFrame wrapper is necessary to avoid dock being partially
// transparent
QFrame *wrapper = new QFrame;
wrapper->setFrameShape(QFrame::StyledPanel);
wrapper->setFrameShadow(QFrame::Sunken);
wrapper->setLayout(layout);
setWidget(wrapper);
}
void MacroDock::SetName(const QString &name)
{
setWindowTitle(name);
}
void MacroDock::ShowRunButton(bool value)
{
_run->setVisible(value);
}
void MacroDock::ShowPauseButton(bool value)
{
_pauseToggle->setVisible(value);
}
void MacroDock::RunClicked()
{
if (!_macro) {
return;
}
auto ret = _macro->PerformActions();
if (!ret) {
QString err =
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
DisplayMessage(err.arg(QString::fromStdString(_macro->Name())));
}
}
void MacroDock::PauseToggleClicked()
{
if (!_macro) {
return;
}
_macro->SetPaused(!_macro->Paused());
UpdatePauseText();
}
void MacroDock::UpdatePauseText()
{
if (!_macro) {
return;
}
_pauseToggle->setText(
_macro->Paused()
? obs_module_text("AdvSceneSwitcher.macroDock.unpause")
: obs_module_text("AdvSceneSwitcher.macroDock.pause"));
}

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