Compare commits

..

6 Commits

Author SHA1 Message Date
WarmUpTill
f8212da80f debug 2025-11-06 20:09:00 +01:00
WarmUpTill
862bc420ad force 2025-11-06 20:09:00 +01:00
WarmUpTill
f832d6c52e debug 2025-11-06 20:09:00 +01:00
WarmUpTill
790d0095f3 use old cache 2025-11-06 20:09:00 +01:00
WarmUpTill
81409ba22d Revert "Update based on obs-plugintemplate to enable switch to OBS 31.1.1"
This reverts commit 1494b1db6c.
2025-11-06 20:09:00 +01:00
WarmUpTill
e687cf139a Revert "buildspec: Update OBS Studio dependency to 31.1.1"
This reverts commit 5f2237ac2a.
2025-11-06 20:09:00 +01:00
49 changed files with 666 additions and 1622 deletions

View File

@@ -6,7 +6,7 @@ on:
description: "Project name detected by parsing build spec file"
value: ${{ jobs.check-event.outputs.pluginName }}
env:
DEP_DIR: .deps/advss-build-dependencies-3
DEP_DIR: .deps/advss-build-dependencies-2
jobs:
check-event:
name: Check GitHub Event Data 🔎

View File

@@ -146,8 +146,6 @@ target_sources(
lib/macro/macro-ref.hpp
lib/macro/macro-run-button.cpp
lib/macro/macro-run-button.hpp
lib/macro/macro-search.cpp
lib/macro/macro-search.hpp
lib/macro/macro-segment-copy-paste.cpp
lib/macro/macro-segment-copy-paste.hpp
lib/macro/macro-segment-list.cpp

View File

@@ -1,33 +1,33 @@
{
"dependencies": {
"obs-studio": {
"version": "31.1.1",
"version": "30.1.2",
"baseUrl": "https://github.com/obsproject/obs-studio/archive/refs/tags",
"label": "OBS sources",
"hashes": {
"macos": "39751f067bacc13d44b116c5138491b5f1391f91516d3d590d874edd21292291",
"windows-x64": "2c8427c10b55ac6d68008df2e9a3e82f4647aaad18f105e30d4713c2de678ccf"
"macos": "490bae1c392b3b344b0270afd8cb887da4bc50bd92c0c426e96713c1ccb9701a",
"windows-x64": "c2dd03fa7fd01fad5beafce8f7156da11f9ed9a588373fd40b44a06f4c03b867"
}
},
"prebuilt": {
"version": "2025-07-11",
"version": "2024-03-19",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built obs-deps",
"hashes": {
"macos": "495687e63383d1a287684b6e2e9bfe246bb8f156fe265926afb1a325af1edd2a",
"windows-x64": "c8c642c1070dc31ce9a0f1e4cef5bb992f4bff4882255788b5da12129e85caa7"
"macos": "2e9bfb55a5e0e4c1086fa1fda4cf268debfead473089df2aaea80e1c7a3ca7ff",
"windows-x64": "6e86068371526a967e805f6f9903f9407adb683c21820db5f07da8f30d11e998"
}
},
"qt6": {
"version": "2025-07-11",
"version": "2024-03-19",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built Qt6",
"hashes": {
"macos": "d3f5f04b6ea486e032530bdf0187cbda9a54e0a49621a4c8ba984c5023998867",
"windows-x64": "0e76bf0555dd5382838850b748d3dcfab44a1e1058441309ab54e1a65b156d0a"
"macos": "694f1e639c017e3b1f456f735330dc5afae287cbea85757101af1368de3142c8",
"windows-x64": "72d1df34a0ef7413a681d5fcc88cae81da60adc03dcd23ef17862ab170bcc0dd"
},
"debugSymbols": {
"windows-x64": "11b7be92cf66a273299b8f3515c07a5cfb61614b59a4e67f7fc5ecba5e2bdf21"
"windows-x64": "fbddd1f659c360f2291911ac5709b67b6f8182e6bca519d24712e4f6fd3cc865"
}
}
},

View File

@@ -65,16 +65,17 @@ function(_setup_obs_studio)
if(OS_WINDOWS)
set(_cmake_generator "${CMAKE_GENERATOR}")
set(_cmake_arch
"-A ${arch},version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
set(_cmake_arch "-A ${arch}")
set(_cmake_extra
"-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} -DCMAKE_ENABLE_SCRIPTING=OFF"
)
set(_cmake_version "2.0.0")
elseif(OS_MACOS)
set(_cmake_generator "Xcode")
set(_cmake_arch "-DCMAKE_OSX_ARCHITECTURES:STRING='arm64;x86_64'")
set(_cmake_extra
"-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
set(_cmake_version "3.0.0")
endif()
message(STATUS "Configure ${label} (${arch})")
@@ -82,42 +83,32 @@ function(_setup_obs_studio)
COMMAND
"${CMAKE_COMMAND}" -S "${dependencies_dir}/${_obs_destination}" -B
"${dependencies_dir}/${_obs_destination}/build_${arch}" -G
${_cmake_generator} "${_cmake_arch}" -DOBS_CMAKE_VERSION:STRING=3.0.0
-DENABLE_PLUGINS:BOOL=OFF -DENABLE_FRONTEND:BOOL=OFF
-DOBS_VERSION_OVERRIDE:STRING=${_obs_version}
${_cmake_generator} "${_cmake_arch}"
-DOBS_CMAKE_VERSION:STRING=${_cmake_version} -DENABLE_PLUGINS:BOOL=OFF
-DENABLE_UI:BOOL=OFF -DOBS_VERSION_OVERRIDE:STRING=${_obs_version}
"-DCMAKE_PREFIX_PATH='${CMAKE_PREFIX_PATH}'" ${_is_fresh} ${_cmake_extra}
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
message(STATUS "Configure ${label} (${arch}) - done")
message(STATUS "Build ${label} (Debug - ${arch})")
message(STATUS "Build ${label} (${arch})")
execute_process(
COMMAND "${CMAKE_COMMAND}" --build build_${arch} --target obs-frontend-api
--config Debug --parallel
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
message(STATUS "Build ${label} (Debug - ${arch}) - done")
message(STATUS "Build ${label} (Release - ${arch})")
execute_process(
COMMAND "${CMAKE_COMMAND}" --build build_${arch} --target obs-frontend-api
--config Release --parallel
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
message(STATUS "Build ${label} (Reelase - ${arch}) - done")
message(STATUS "Build ${label} (${arch}) - done")
message(STATUS "Install ${label} (${arch})")
if(OS_WINDOWS)
set(_cmake_extra "--component obs_libraries")
else()
set(_cmake_extra "")
endif()
execute_process(
COMMAND "${CMAKE_COMMAND}" --install build_${arch} --component Development
--config Debug --prefix "${dependencies_dir}"
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
execute_process(
COMMAND "${CMAKE_COMMAND}" --install build_${arch} --component Development
--config Release --prefix "${dependencies_dir}"
--config Debug --prefix "${dependencies_dir}" ${_cmake_extra}
WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}"
RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY
OUTPUT_QUIET)
@@ -180,46 +171,24 @@ function(_check_dependencies)
set(url ${url}/${version}/${file})
endif()
set(MAX_DOWNLOAD_RETRIES 3)
set(RETRY_DELAY 60) # seconds
if(NOT EXISTS "${dependencies_dir}/${file}")
message(STATUS "Downloading ${url}")
file(
DOWNLOAD "${url}" "${dependencies_dir}/${file}"
STATUS download_status
EXPECTED_HASH SHA256=${hash})
set(download_success FALSE)
foreach(i RANGE 1 ${MAX_DOWNLOAD_RETRIES})
message(STATUS "Attempt ${i}/${MAX_DOWNLOAD_RETRIES} for ${url}")
file(
DOWNLOAD "${url}" "${dependencies_dir}/${file}"
STATUS download_status
EXPECTED_HASH SHA256=${hash})
list(GET download_status 0 error_code)
list(GET download_status 1 error_message)
if(error_code EQUAL 0)
message(STATUS "Downloading ${url} - success on attempt ${i}")
set(download_success TRUE)
break()
else()
message(WARNING "Download failed (attempt ${i}): ${error_message}")
file(REMOVE "${dependencies_dir}/${file}")
if(NOT i EQUAL MAX_DOWNLOAD_RETRIES)
message(STATUS "Retrying in ${RETRY_DELAY} seconds...")
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${RETRY_DELAY})
endif()
endif()
endforeach()
if(NOT download_success)
list(GET download_status 0 error_code)
list(GET download_status 1 error_message)
if(error_code GREATER 0)
message(STATUS "Downloading ${url} - Failure")
message(
FATAL_ERROR
"Unable to download ${url} after ${MAX_DOWNLOAD_RETRIES} attempts")
"Unable to download ${url}, failed with error: ${error_message}")
file(REMOVE "${dependencies_dir}/${file}")
else()
message(STATUS "Downloading ${url} - done")
endif()
message(STATUS "Downloading ${url} - done")
endif()
if(NOT EXISTS "${dependencies_dir}/${destination}")

View File

@@ -4,7 +4,6 @@
# ---------------------------------------------------------------------------
if(WIN32 AND (NOT OpenSSL_FOUND))
set(_openssl_roots
"$ENV{ProgramFiles}/OpenSSL-Win64" "$ENV{ProgramFiles}/OpenSSL"
"$ENV{ProgramW6432}/OpenSSL-Win64")
@@ -47,20 +46,33 @@ if(WIN32 AND (NOT OpenSSL_FOUND))
AND EXISTS "${_root}/${_suffix}/libcrypto.lib")
set(OPENSSL_ROOT_DIR
"${_root}"
CACHE PATH "Path to OpenSSL root")
CACHE PATH "Path to OpenSSL root" FORCE)
set(OPENSSL_CRYPTO_LIBRARY
"${_root}/${_suffix}/libcrypto.lib"
CACHE FILEPATH "OpenSSL crypto lib")
CACHE FILEPATH "OpenSSL crypto lib" FORCE)
set(OPENSSL_SSL_LIBRARY
"${_root}/${_suffix}/libssl.lib"
CACHE FILEPATH "OpenSSL ssl lib")
CACHE FILEPATH "OpenSSL ssl lib" FORCE)
set(OPENSSL_INCLUDE_DIR
"${_root}/include"
CACHE PATH "OpenSSL include dir")
CACHE PATH "OpenSSL include dir" FORCE)
set(OpenSSL_FOUND
TRUE
CACHE BOOL "Whether OpenSSL was found")
CACHE BOOL "Whether OpenSSL was found" FORCE)
message(STATUS "Found OpenSSL at: ${_root}/${_suffix}")
# Recursively list all files under OPENSSL_ROOT_DIR
file(GLOB_RECURSE OPENSSL_FILES "${OPENSSL_ROOT_DIR}/*")
message(STATUS "Listing contents of OPENSSL_ROOT_DIR:")
foreach(file ${OPENSSL_FILES})
message(STATUS " ${file}")
endforeach()
get_cmake_property(_variableNames VARIABLES)
list(SORT _variableNames)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
return()
endif()
endforeach()

View File

@@ -43,7 +43,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="Display warni
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="The plugin installation seems to be corrupted and might crash!\nPlease make sure the plugin was installed correctly!"
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowMacroSearch="Always show macro search"
AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache="Disable macro widget caching"
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
AdvSceneSwitcher.generalTab.priority="Priority"
AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)"
@@ -74,7 +74,6 @@ AdvSceneSwitcher.generalTab.setTransitionBy="When changing transitions:"
AdvSceneSwitcher.generalTab.transitionOverride="Set transition overrides"
AdvSceneSwitcher.generalTab.adjustActiveTransitionType="Change active transition type"
AdvSceneSwitcher.generalTab.transitionBehaviorSelectionError="At least one option must be enabled:\n\n - Use transition overrides\n\n - Change active transition type"
AdvSceneSwitcher.generalTab.uiBehavior="UI settings"
# Variables Tab
AdvSceneSwitcher.variableTab.title="Variables"
@@ -92,12 +91,6 @@ AdvSceneSwitcher.variableTab.lastUsed.text.never="Never"
AdvSceneSwitcher.variableTab.lastChanged.header="Last changed"
AdvSceneSwitcher.variableTab.lastChanged.text.none="No change since launch"
AdvSceneSwitcher.variableTab.lastChanged.tooltip="Times changed: %1\n\nPrevious value: %2"
AdvSceneSwitcher.variableTab.search.placeholder="Search ..."
AdvSceneSwitcher.variableTab.search.all="All columns"
AdvSceneSwitcher.variableTab.search.name="Name column"
AdvSceneSwitcher.variableTab.search.value="Value column"
AdvSceneSwitcher.variableTab.addDock="Add dock"
AdvSceneSwitcher.variableTab.clear="Clear"
# Action Queue Tab
AdvSceneSwitcher.actionQueueTab.title="Action Queues"
@@ -277,13 +270,6 @@ AdvSceneSwitcher.macroTab.tooltip.elseActionUpButton="Move selected action up in
AdvSceneSwitcher.macroTab.tooltip.elseActionDownButton="Move selected action down in the else section"
AdvSceneSwitcher.macroTab.tooltip.elseActionBottomButton="Move selected action to the bottom in the else section"
AdvSceneSwitcher.macroTab.tooltip.openMacroSettingsButton="Open macro settings"
AdvSceneSwitcher.macroTab.search.placeholder="Search ..."
AdvSceneSwitcher.macroTab.search.showSettings="Show search settings"
AdvSceneSwitcher.macroTab.search.name="Name"
AdvSceneSwitcher.macroTab.search.allSegments="Segment type"
AdvSceneSwitcher.macroTab.search.conditions="Condition type"
AdvSceneSwitcher.macroTab.search.actions="Action type"
AdvSceneSwitcher.macroTab.search.label="Segment label"
AdvSceneSwitcher.macroDock.pause="Pause"
AdvSceneSwitcher.macroDock.unpause="Unpause"
@@ -942,9 +928,6 @@ AdvSceneSwitcher.action.source.type.deinterlaceOrder="Set deinterlace field orde
AdvSceneSwitcher.action.source.type.openInteractionDialog="Open interaction dialog"
AdvSceneSwitcher.action.source.type.openFilterDialog="Open filter dialog"
AdvSceneSwitcher.action.source.type.openPropertiesDialog="Open properties dialog"
AdvSceneSwitcher.action.source.type.closeInteractionDialog="Close interaction dialog"
AdvSceneSwitcher.action.source.type.closeFilterDialog="Close filter dialog"
AdvSceneSwitcher.action.source.type.closePropertiesDialog="Close properties dialog"
AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}{{deinterlaceMode}}{{deinterlaceOrder}}{{refresh}}"
AdvSceneSwitcher.action.source.entry.settings="{{settings}}{{settingsInputMethod}}{{settingValue}}{{tempVar}}"
AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI\nYou might be looking for \"Scene item visibility\""
@@ -966,7 +949,6 @@ AdvSceneSwitcher.action.source.inputMethod.individualTempvar="Set to macro prope
AdvSceneSwitcher.action.source.inputMethod.json="Set setting JSON string"
AdvSceneSwitcher.action.source.refresh="Refresh"
AdvSceneSwitcher.action.source.refresh.tooltip="Repopulate the source settings selection with the settings of the source which's name matches the variable value."
AdvSceneSwitcher.action.source.dialog.accept="Accept changes"
AdvSceneSwitcher.action.media="Media"
AdvSceneSwitcher.action.media.type.play="Play"
AdvSceneSwitcher.action.media.type.pause="Pause"
@@ -1163,7 +1145,6 @@ AdvSceneSwitcher.action.http.entry.line2="Timeout:{{timeout}}seconds"
AdvSceneSwitcher.action.variable="Variable"
AdvSceneSwitcher.action.variable.type.set="Set to value"
AdvSceneSwitcher.action.variable.type.append="Append"
AdvSceneSwitcher.action.variable.type.copy="Copy variable"
AdvSceneSwitcher.action.variable.type.appendVar="Append variable"
AdvSceneSwitcher.action.variable.type.increment="Increment"
AdvSceneSwitcher.action.variable.type.decrement="Decrement"
@@ -1615,11 +1596,7 @@ AdvSceneSwitcher.twitchToken.moderator.chat.settings.manage="Manage channel's ch
AdvSceneSwitcher.twitchToken.user.whispers.manage="Manage user's whispers."
AdvSceneSwitcher.twitchToken.chat.read="View live stream chat messages."
AdvSceneSwitcher.twitchToken.chat.edit="Send live stream chat messages."
AdvSceneSwitcher.twitchToken.validateTimestamps="Validate timestamps of received Twitch event messages."
AdvSceneSwitcher.twitchToken.validateTimestamps.tooltip="Verifies that incoming Twitch messages have valid timestamps to prevent replayed or spoofed messages.\nDisabling this wont affect normal functionality, and you can try turning it off if you experience issues with the Twitch connection."
AdvSceneSwitcher.twitchToken.warnIfInvalid="Display warning if the token expired or is invalid."
AdvSceneSwitcher.twitchToken.warnIfInvalid.doNotShowAgain="Don't show again for this connection"
AdvSceneSwitcher.twitchToken.warnIfInvalid.message="The Twitch connection \"%1\" is invalid.\nOpen connection settings or ignore?"
AdvSceneSwitcher.twitchToken.validateTimestamps="Validate timestamps of received Twitch event messages. (Recommended)"
AdvSceneSwitcher.twitch.selection.channel.open="Open channel"
AdvSceneSwitcher.twitch.selection.channel.open.tooltip.details="Open channel in external application handling the HTTPS protocol."
@@ -2335,9 +2312,6 @@ AdvSceneSwitcher.tempVar.mqtt.message="Message"
AdvSceneSwitcher.tempVar.cursor.x="Cursor position (X)"
AdvSceneSwitcher.tempVar.cursor.y="Cursor position (Y)"
AdvSceneSwitcher.tempVar.replay.lastSavePath="Last save path"
AdvSceneSwitcher.tempVar.replay.lastSavePath.description="The file path of the last replay buffer saved."
AdvSceneSwitcher.selectScene="--select scene--"
AdvSceneSwitcher.selectCanvas="--select canvas--"
AdvSceneSwitcher.selectPreviousScene="Previous Scene"

View File

@@ -42,6 +42,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="プラグイ
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>次のプラグイン ライブラリの読み込みに失敗したため、一部の高機能シーンスイッチャーが利用できなくなる可能性があります:%1詳細については、OBS ログを確認してください。<br>このメッセージは、[全般] タブで無効にすることができます。 </body></html>"
AdvSceneSwitcher.generalTab.generalBehavior.warnCorruptedInstallMessage="プラグインが正しくインストールできておらずクラッシュする可能性があります!\nプラグインが正しくインストールされているか確認してください"
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="旧来型マクロ設定のタブを非表示にする(廃止予定タブ)"
AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache="マクロウィジェットのキャッシングを無効にする"
AdvSceneSwitcher.generalTab.matchBehavior="マッチした場合の動作(廃止予定の設定項目)"
AdvSceneSwitcher.generalTab.priority="優先順位"
AdvSceneSwitcher.generalTab.priority.description="切り替え方法の優先順位(優先順位が高いものが上)"

View File

@@ -68,162 +68,365 @@
<x>0</x>
<y>0</y>
<width>962</width>
<height>1132</height>
<height>1057</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_19">
<item>
<widget class="QGroupBox" name="statusBox">
<property name="title">
<string>AdvSceneSwitcher.generalTab.status</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QGridLayout" name="statusLayout">
<item row="4" column="1">
<widget class="QComboBox" name="autoStartEvent"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.autoStart.startup</string>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_33">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.checkInterval</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="checkIntervalTooLowWarning">
<property name="text">
<string/>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_31">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="statusBox">
<property name="title">
<string>AdvSceneSwitcher.generalTab.status</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<layout class="QGridLayout" name="statusLayout">
<item row="4" column="1">
<widget class="QComboBox" name="autoStartEvent"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.autoStart.startup</string>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_33">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.checkInterval</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="checkIntervalTooLowWarning">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="startupBehavior"/>
</item>
<item row="1" column="1">
<widget class="QWidget" name="placeholder3" native="true"/>
</item>
<item row="1" column="0">
<widget class="QWidget" name="placeholder" native="true"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_64">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.onStartup</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QWidget" name="placeholder2" native="true"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.hotkeytips</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="checkInterval">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="suffix">
<string notr="true">ms</string>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>20000</number>
</property>
<property name="value">
<number>300</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="autoStartSceneEnable">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.autoStart.scene</string>
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="autoStartSceneLayout">
<item>
<widget class="advss::SceneSelectionWidget" name="autoStartScene" native="true"/>
</item>
<item>
<widget class="advss::VariableLineEdit" name="autoStartSceneName"/>
</item>
<item>
<widget class="advss::RegexConfigWidget" name="autoStartSceneNameRegex" native="true"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="startupBehavior"/>
</item>
<item row="1" column="1">
<widget class="QWidget" name="placeholder3" native="true"/>
</item>
<item row="1" column="0">
<widget class="QWidget" name="placeholder" native="true"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_64">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.onStartup</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QWidget" name="placeholder2" native="true"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.hotkeytips</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="checkInterval">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="suffix">
<string notr="true">ms</string>
</property>
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>20000</number>
</property>
<property name="value">
<number>300</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="autoStartSceneEnable">
<property name="text">
<string>AdvSceneSwitcher.generalTab.status.autoStart.scene</string>
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="autoStartSceneLayout">
</widget>
</item>
<item>
<widget class="QGroupBox" name="generalSettingsBox">
<property name="title">
<string>AdvSceneSwitcher.generalTab.generalBehavior</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
<item>
<widget class="advss::SceneSelectionWidget" name="autoStartScene" native="true"/>
<layout class="QHBoxLayout" name="horizontalLayout_52">
<item>
<widget class="QLabel" name="label_21">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="logLevel"/>
</item>
<item>
<spacer name="horizontalSpacer_49">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="advss::VariableLineEdit" name="autoStartSceneName"/>
<layout class="QHBoxLayout" name="horizontalLayout_50">
<item>
<widget class="QCheckBox" name="saveWindowGeo">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_55">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="advss::RegexConfigWidget" name="autoStartSceneNameRegex" native="true"/>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="showTrayNotifications">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_48">
<item>
<widget class="QCheckBox" name="uiHintsDisable">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_52">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QCheckBox" name="disableComboBoxFilter">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.comboBoxFilterDisable</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QCheckBox" name="disableMacroWidgetCache">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableMacroWidgetCache</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_26">
<item>
<widget class="QCheckBox" name="warnPluginLoadFailure">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_19">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_24">
<item>
<widget class="QCheckBox" name="hideLegacyTabs">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_16">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_18">
<item>
<widget class="QGroupBox" name="saveLoadBox">
<property name="title">
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_17">
<item>
<widget class="QPushButton" name="exportSettings">
<property name="text">
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.export</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="importSettings">
<property name="text">
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.import</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="saveLoadBox">
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings</string>
<string>AdvSceneSwitcher.generalTab.matchBehavior</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_17">
<layout class="QVBoxLayout" name="verticalLayout_37">
<item>
<widget class="QPushButton" name="exportSettings">
<property name="text">
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.export</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="importSettings">
<property name="text">
<string>AdvSceneSwitcher.generalTab.saveOrLoadsettings.import</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="generalSettingsBox">
<property name="title">
<string>AdvSceneSwitcher.generalTab.generalBehavior</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_52">
<layout class="QHBoxLayout" name="cooldownLayout">
<item>
<widget class="QLabel" name="label_21">
<widget class="QCheckBox" name="enableCooldown">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.logLevel</string>
<string>AdvSceneSwitcher.generalTab.generalBehavior.cooldown</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="logLevel"/>
<widget class="advss::DurationSelection" name="cooldownTime" native="true"/>
</item>
<item>
<spacer name="horizontalSpacer_49">
<spacer name="horizontalSpacer_21">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -238,62 +441,80 @@
</layout>
</item>
<item>
<widget class="QCheckBox" name="showTrayNotifications">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="warnPluginLoadFailure">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>AdvSceneSwitcher.generalTab.uiBehavior</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="saveWindowGeo">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="uiHintsDisable">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="disableComboBoxFilter">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.comboBoxFilterDisable</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="alwaysShowMacroSearch">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.alwaysShowMacroSearch</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="hideLegacyTabs">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs</string>
</property>
</widget>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_43">
<item>
<widget class="QRadioButton" name="noMatchDontSwitch">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.dontSwitch</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_45">
<item>
<widget class="QRadioButton" name="noMatchRandomSwitch">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchToRandom</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="noMatchSwitch">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchTo</string>
</property>
</widget>
</item>
<item>
<widget class="advss::SceneSelectionWidget" name="noMatchSwitchScene">
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="noMatchLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
@@ -341,109 +562,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="matchBehaviorBox">
<property name="title">
<string>AdvSceneSwitcher.generalTab.matchBehavior</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_37">
<item>
<layout class="QHBoxLayout" name="cooldownLayout">
<item>
<widget class="QCheckBox" name="enableCooldown">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.cooldown</string>
</property>
</widget>
</item>
<item>
<widget class="advss::DurationSelection" name="cooldownTime" native="true"/>
</item>
<item>
<spacer name="horizontalSpacer_21">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2">
<widget class="QRadioButton" name="noMatchDontSwitch">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.dontSwitch</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QRadioButton" name="noMatchRandomSwitch">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchToRandom</string>
</property>
</widget>
</item>
<item row="1" column="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QRadioButton" name="noMatchSwitch">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch.switchTo</string>
</property>
</widget>
</item>
<item>
<widget class="advss::SceneSelectionWidget" name="noMatchSwitchScene" native="true"/>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="noMatchLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.onNoMatch</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="priorityBox">
<property name="title">
@@ -458,7 +576,15 @@
</widget>
</item>
<item>
<widget class="QListWidget" name="priorityList"/>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_41">
<item>
<widget class="QListWidget" name="priorityList"/>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_32">
@@ -595,55 +721,6 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="macroSearchLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="macroSearchText">
<property name="placeholderText">
<string>AdvSceneSwitcher.macroTab.search.placeholder</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="macroSearchClear">
<property name="toolTip">
<string>AdvSceneSwitcher.variableTab.clear</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="macroSearchType"/>
</item>
<item>
<widget class="advss::RegexConfigWidget" name="macroSearchRegex" native="true"/>
</item>
<item>
<widget class="QPushButton" name="macroSearchShowSettings">
<property name="toolTip">
<string>AdvSceneSwitcher.macroTab.search.showSettings</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="advss::MacroTree" name="macros">
<property name="showDropIndicator" stdset="0">
@@ -4087,7 +4164,12 @@
<tabstop>autoStartSceneName</tabstop>
<tabstop>autoStartSceneNameRegex</tabstop>
<tabstop>logLevel</tabstop>
<tabstop>saveWindowGeo</tabstop>
<tabstop>showTrayNotifications</tabstop>
<tabstop>uiHintsDisable</tabstop>
<tabstop>disableComboBoxFilter</tabstop>
<tabstop>warnPluginLoadFailure</tabstop>
<tabstop>hideLegacyTabs</tabstop>
<tabstop>exportSettings</tabstop>
<tabstop>importSettings</tabstop>
<tabstop>noMatchDontSwitch</tabstop>

View File

@@ -65,6 +65,7 @@ public slots:
void on_showTrayNotifications_stateChanged(int state);
void on_uiHintsDisable_stateChanged(int state);
void on_disableComboBoxFilter_stateChanged(int state);
void on_disableMacroWidgetCache_stateChanged(int state);
void on_warnPluginLoadFailure_stateChanged(int state);
void on_hideLegacyTabs_stateChanged(int state);
void on_priorityUp_clicked();

View File

@@ -3,7 +3,6 @@
#include "filter-combo-box.hpp"
#include "layout-helpers.hpp"
#include "macro.hpp"
#include "macro-search.hpp"
#include "macro-settings.hpp"
#include "path-helpers.hpp"
#include "selection-helpers.hpp"
@@ -186,6 +185,16 @@ void AdvSceneSwitcher::on_disableComboBoxFilter_stateChanged(int state)
FilterComboBox::SetFilterBehaviourEnabled(!state);
}
void AdvSceneSwitcher::on_disableMacroWidgetCache_stateChanged(int state)
{
if (loading) {
return;
}
switcher->disableMacroWidgetCache = state;
MacroSegmentList::SetCachingEnabled(!state);
}
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
{
if (loading) {
@@ -522,6 +531,8 @@ void SwitcherData::SaveGeneralSettings(obs_data_t *obj)
obs_data_set_bool(obj, "disableHints", disableHints);
obs_data_set_bool(obj, "disableFilterComboboxFilter",
disableFilterComboboxFilter);
obs_data_set_bool(obj, "disableMacroWidgetCache",
disableMacroWidgetCache);
obs_data_set_bool(obj, "warnPluginLoadFailure", warnPluginLoadFailure);
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
@@ -591,6 +602,8 @@ void SwitcherData::LoadGeneralSettings(obs_data_t *obj)
disableHints = obs_data_get_bool(obj, "disableHints");
disableFilterComboboxFilter =
obs_data_get_bool(obj, "disableFilterComboboxFilter");
disableMacroWidgetCache =
obs_data_get_bool(obj, "disableMacroWidgetCache");
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
@@ -914,6 +927,9 @@ void AdvSceneSwitcher::SetupGeneralTab()
switcher->disableFilterComboboxFilter);
FilterComboBox::SetFilterBehaviourEnabled(
!switcher->disableFilterComboboxFilter);
ui->disableMacroWidgetCache->setChecked(
switcher->disableMacroWidgetCache);
MacroSegmentList::SetCachingEnabled(!switcher->disableMacroWidgetCache);
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
@@ -997,19 +1013,6 @@ void AdvSceneSwitcher::SetupGeneralTab()
switcher->CheckAutoStart();
});
ui->alwaysShowMacroSearch->setChecked(
GetMacroSearchSettings().showAlways);
connect(ui->alwaysShowMacroSearch, &QCheckBox::stateChanged, this,
[this](int enabled) {
GetMacroSearchSettings().showAlways = enabled;
if (loading) {
return;
}
CheckMacroSearchVisibility();
});
// Set up status control
auto statusControl = new StatusControl(this, true);
ui->statusLayout->addWidget(statusControl->StatusPrefixLabel(), 1, 0);

View File

@@ -286,14 +286,6 @@ bool MacroActionVariable::PerformAction()
case Action::APPEND:
apppend(*var, _strValue);
break;
case Action::COPY_VAR: {
auto var2 = _variable2.lock();
if (!var2) {
return true;
}
var->SetValue(var2->Value());
break;
}
case Action::APPEND_VAR: {
auto var2 = _variable2.lock();
if (!var2) {
@@ -678,8 +670,6 @@ static inline void populateActionSelection(QComboBox *list)
actions = {
{MacroActionVariable::Action::SET_VALUE,
"AdvSceneSwitcher.action.variable.type.set"},
{MacroActionVariable::Action::COPY_VAR,
"AdvSceneSwitcher.action.variable.type.copy"},
{MacroActionVariable::Action::APPEND,
"AdvSceneSwitcher.action.variable.type.append"},
{MacroActionVariable::Action::PAD,
@@ -1531,7 +1521,6 @@ void MacroActionVariableEdit::SetWidgetVisibility()
}
_variables2->setVisible(
_entryData->_action == MacroActionVariable::Action::COPY_VAR ||
_entryData->_action ==
MacroActionVariable::Action::APPEND_VAR ||
_entryData->_action ==

View File

@@ -55,7 +55,6 @@ public:
RANDOM_NUMBER,
QUERY_JSON,
ARRAY_JSON,
COPY_VAR,
};
Action _action = Action::SET_VALUE;

View File

@@ -110,7 +110,7 @@ void MacroDock::RunClicked()
return;
}
auto ret = macro->PerformActions(true, true, true);
auto ret = macro->PerformActions(true);
if (!ret) {
QString err =
obs_module_text("AdvSceneSwitcher.macroTab.runFail");

View File

@@ -63,33 +63,6 @@ std::deque<std::shared_ptr<Macro>> GetAllMacros()
return macros;
}
Macro *GetMacroByName(const char *name)
{
for (const auto &m : GetTopLevelMacros()) {
if (m->Name() == name) {
return m.get();
}
}
return nullptr;
}
Macro *GetMacroByQString(const QString &name)
{
return GetMacroByName(name.toUtf8().constData());
}
std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
{
for (const auto &m : GetTopLevelMacros()) {
if (m->Name() == name) {
return m;
}
}
return {};
}
std::optional<std::deque<std::shared_ptr<MacroAction>>>
GetMacroActions(Macro *macro)
{

View File

@@ -1,8 +1,6 @@
#pragma once
#include "export-symbol-helper.hpp"
#include <QString>
#include <atomic>
#include <chrono>
#include <condition_variable>
@@ -24,10 +22,6 @@ EXPORT std::deque<std::shared_ptr<Macro>> &GetTopLevelMacros();
std::deque<std::shared_ptr<Macro>> &GetTemporaryMacros();
EXPORT std::deque<std::shared_ptr<Macro>> GetAllMacros();
Macro *GetMacroByName(const char *name);
Macro *GetMacroByQString(const QString &name);
std::weak_ptr<Macro> GetWeakMacroByName(const char *name);
EXPORT std::optional<std::deque<std::shared_ptr<MacroAction>>>
GetMacroActions(Macro *);
EXPORT std::optional<std::deque<std::shared_ptr<MacroAction>>>

View File

@@ -1,336 +0,0 @@
#include "macro-search.hpp"
#include "layout-helpers.hpp"
#include "macro.hpp"
#include "macro-action-factory.hpp"
#include "macro-condition-factory.hpp"
#include "macro-helpers.hpp"
#include "macro-signals.hpp"
#include "plugin-state-helpers.hpp"
#include "ui-helpers.hpp"
#include <obs.hpp>
#include <QComboBox>
#include <QLayout>
#include <QLineEdit>
#include <QPushButton>
namespace advss {
static bool searchEnabled = false;
static bool setup();
static bool setupDone = setup();
static QLayout *searchLayout = nullptr;
static QComboBox *searchType = nullptr;
static RegexConfigWidget *searchRegex = nullptr;
static QPushButton *showSettings = nullptr;
static std::function<void()> refreshFilter;
static void save(obs_data_t *data)
{
GetMacroSearchSettings().Save(data, "macroSearchSettings");
}
static void load(obs_data_t *data)
{
GetMacroSearchSettings().Load(data, "macroSearchSettings");
}
static bool setup()
{
AddSaveStep(save);
AddLoadStep(load);
return true;
}
void MacroSearchSettings::Save(obs_data_t *data, const char *name)
{
OBSDataAutoRelease settings = obs_data_create();
obs_data_set_bool(settings, "showAlways", showAlways);
obs_data_set_int(settings, "searchType", static_cast<int>(searchType));
obs_data_set_string(settings, "searchString", searchString.c_str());
regex.Save(settings);
obs_data_set_obj(data, name, settings);
}
void MacroSearchSettings::Load(obs_data_t *data, const char *name)
{
OBSDataAutoRelease settings = obs_data_get_obj(data, name);
showAlways = obs_data_get_bool(settings, "showAlways");
searchType = static_cast<SearchType>(
obs_data_get_int(settings, "searchType"));
searchString = obs_data_get_string(settings, "searchString");
regex.Load(settings);
}
static void showAdvancedSearchSettings(bool show)
{
assert(searchType);
assert(searchRegex);
searchType->setVisible(show);
searchRegex->setVisible(show);
}
static bool shouldShowSearch()
{
static const int showSearchThreshold = 10;
return GetMacroSearchSettings().showAlways ||
GetTopLevelMacros().size() >= showSearchThreshold;
}
void CheckMacroSearchVisibility()
{
assert(searchLayout);
assert(searchType);
assert(searchRegex);
assert(showSettings);
searchEnabled = shouldShowSearch();
SetLayoutVisible(searchLayout, searchEnabled);
showAdvancedSearchSettings(false);
showSettings->setChecked(false);
refreshFilter();
}
void SetupMacroSearchWidgets(QLayout *searchLayoutArg, QLineEdit *searchText,
QPushButton *searchClear, QComboBox *searchTypeArg,
RegexConfigWidget *searchRegexArg,
QPushButton *showSettingsArg,
const std::function<void()> &refreshArg)
{
searchLayout = searchLayoutArg;
searchType = searchTypeArg;
searchRegex = searchRegexArg;
refreshFilter = refreshArg;
showSettings = showSettingsArg;
searchClear->setMaximumWidth(22);
SetButtonIcon(searchClear, GetThemeTypeName() == "Light"
? "theme:Light/close.svg"
: "theme:Dark/close.svg");
searchClear->setDisabled(GetMacroSearchSettings().searchString.empty());
QWidget::connect(searchClear, &QPushButton::clicked, searchClear,
[=]() {
searchText->setText("");
searchClear->setDisabled(true);
});
const auto ph = searchText->placeholderText();
const QFontMetrics fm(searchText->font());
const int width = fm.horizontalAdvance(ph);
// Add a little padding so the text isn't cramped
searchText->setMinimumWidth(width + 10);
searchText->setText(
QString::fromStdString(GetMacroSearchSettings().searchString));
QWidget::connect(searchText, &QLineEdit::textChanged, searchText,
[searchClear](const QString &text) {
GetMacroSearchSettings().searchString =
text.toStdString();
searchClear->setDisabled(text.isEmpty());
refreshFilter();
});
searchType->addItem(
obs_module_text("AdvSceneSwitcher.macroTab.search.name"),
static_cast<int>(MacroSearchSettings::SearchType::NAME));
searchType->addItem(
obs_module_text("AdvSceneSwitcher.macroTab.search.allSegments"),
static_cast<int>(
MacroSearchSettings::SearchType::ALL_SEGMENTS));
searchType->addItem(
obs_module_text("AdvSceneSwitcher.macroTab.search.conditions"),
static_cast<int>(MacroSearchSettings::SearchType::CONDITIONS));
searchType->addItem(
obs_module_text("AdvSceneSwitcher.macroTab.search.actions"),
static_cast<int>(MacroSearchSettings::SearchType::ACTIONS));
searchType->addItem(
obs_module_text("AdvSceneSwitcher.macroTab.search.label"),
static_cast<int>(MacroSearchSettings::SearchType::LABEL));
searchType->setCurrentIndex(searchType->findData(
static_cast<int>(GetMacroSearchSettings().searchType)));
QWidget::connect(
searchType, &QComboBox::currentIndexChanged, searchType, []() {
GetMacroSearchSettings().searchType =
static_cast<MacroSearchSettings::SearchType>(
searchType->currentData().toInt());
refreshFilter();
});
searchRegex->SetRegexConfig(GetMacroSearchSettings().regex);
QWidget::connect(searchRegex, &RegexConfigWidget::RegexConfigChanged,
searchRegex, [](const RegexConfig &regex) {
GetMacroSearchSettings().regex = regex;
refreshFilter();
});
showSettings->setCheckable(true);
showSettings->setMaximumWidth(11);
SetButtonIcon(showSettings, GetThemeTypeName() == "Light"
? ":/res/images/dots-vert.svg"
: "theme:Dark/dots-vert.svg");
QWidget::connect(showSettings, &QPushButton::toggled, showSettings,
showAdvancedSearchSettings);
QWidget::connect(MacroSignalManager::Instance(),
&MacroSignalManager::Rename, searchText,
[]() { refreshFilter(); });
CheckMacroSearchVisibility();
}
MacroSearchSettings &GetMacroSearchSettings()
{
static MacroSearchSettings settings;
return settings;
}
static bool stringMatches(const std::string &text)
{
const auto &settings = GetMacroSearchSettings();
const auto &regex = settings.regex;
const auto &searchString = settings.searchString;
if (regex.Enabled()) {
return regex.Matches(text, searchString);
}
return QString::fromStdString(text).contains(
QString::fromStdString(searchString), Qt::CaseInsensitive);
}
static bool segmentTypeMatches(MacroSegment *segment, bool isCondition)
{
if (!segment) {
return false;
}
const auto getNameFromId =
isCondition ? MacroConditionFactory::GetConditionName
: MacroActionFactory::GetActionName;
const auto name = getNameFromId(segment->GetId());
return stringMatches(obs_module_text(name.c_str()));
}
static bool segmentLabelMatches(MacroSegment *segment)
{
if (!segment) {
return false;
}
if (!segment->GetUseCustomLabel()) {
return false;
}
const auto label = segment->GetCustomLabel();
return stringMatches(label);
}
bool MacroMatchesSearchFilter(Macro *macro)
{
assert(macro);
if (!searchEnabled) {
return true;
}
const auto &settings = GetMacroSearchSettings();
if (settings.searchString.empty()) {
return true;
}
if (macro->IsGroup()) {
std::vector<std::shared_ptr<Macro>> subItems;
subItems.reserve(macro->GroupSize());
const auto &macros = GetTopLevelMacros();
for (auto it = macros.begin(); it < macros.end(); it++) {
if ((*it)->Name() != macro->Name()) {
continue;
}
for (uint32_t i = 1; i <= macro->GroupSize(); i++) {
subItems.emplace_back(*std::next(it, i));
}
break;
}
for (const auto &item : subItems) {
if (MacroMatchesSearchFilter(item.get())) {
return true;
}
}
return false;
}
switch (settings.searchType) {
case MacroSearchSettings::SearchType::NAME: {
const auto name = macro->Name();
return stringMatches(name);
}
case MacroSearchSettings::SearchType::ALL_SEGMENTS:
for (const auto &condition : macro->Conditions()) {
if (segmentTypeMatches(condition.get(), true)) {
return true;
}
}
for (const auto &action : macro->Actions()) {
if (segmentTypeMatches(action.get(), false)) {
return true;
}
}
for (const auto &action : macro->ElseActions()) {
if (segmentTypeMatches(action.get(), false)) {
return true;
}
}
return false;
case MacroSearchSettings::SearchType::CONDITIONS:
for (const auto &condition : macro->Conditions()) {
if (segmentTypeMatches(condition.get(), true)) {
return true;
}
}
return false;
case MacroSearchSettings::SearchType::ACTIONS:
for (const auto &action : macro->Actions()) {
if (segmentTypeMatches(action.get(), false)) {
return true;
}
}
for (const auto &action : macro->ElseActions()) {
if (segmentTypeMatches(action.get(), false)) {
return true;
}
}
return false;
case MacroSearchSettings::SearchType::LABEL:
for (const auto &condition : macro->Conditions()) {
if (segmentLabelMatches(condition.get())) {
return true;
}
}
for (const auto &action : macro->Actions()) {
if (segmentLabelMatches(action.get())) {
return true;
}
}
for (const auto &action : macro->ElseActions()) {
if (segmentLabelMatches(action.get())) {
return true;
}
}
return false;
default:
break;
}
// Unhandled search type
assert(false);
return true;
}
} // namespace advss

View File

@@ -1,43 +0,0 @@
#pragma once
#include "regex-config.hpp"
#include <functional>
#include <string>
class QComboBox;
class QLayout;
class QLineEdit;
class QPushButton;
namespace advss {
class Macro;
struct MacroSearchSettings {
void Save(obs_data_t *data, const char *name);
void Load(obs_data_t *data, const char *name);
enum class SearchType {
NAME = 0,
ALL_SEGMENTS = 10,
CONDITIONS = 20,
ACTIONS = 30,
LABEL = 40,
};
SearchType searchType = SearchType::NAME;
std::string searchString;
RegexConfig regex;
bool showAlways = false;
};
void CheckMacroSearchVisibility();
void SetupMacroSearchWidgets(QLayout *searchLayout, QLineEdit *searchText,
QPushButton *searchClear, QComboBox *searchType,
RegexConfigWidget *searchRegex,
QPushButton *showSettings,
const std::function<void()> &refresh);
MacroSearchSettings &GetMacroSearchSettings();
bool MacroMatchesSearchFilter(Macro *macro);
} // namespace advss

View File

@@ -4,7 +4,6 @@
#include "macro-condition-edit.hpp"
#include "macro-export-import-dialog.hpp"
#include "macro-settings.hpp"
#include "macro-search.hpp"
#include "macro-signals.hpp"
#include "macro-tree.hpp"
#include "macro.hpp"
@@ -208,7 +207,7 @@ void AdvSceneSwitcher::RemoveMacro(std::shared_ptr<Macro> &macro)
// Don't cache widgets for about to be deleted macros
MacroSegmentList::SetCachingEnabled(false);
ui->macros->Remove(macro);
MacroSegmentList::SetCachingEnabled(true);
MacroSegmentList::SetCachingEnabled(!switcher->disableMacroWidgetCache);
MacroSignalManager::Instance()->Remove(name);
}
@@ -616,20 +615,17 @@ setupToolBar(const std::initializer_list<std::initializer_list<QWidget *>>
auto toolbar = new QToolBar();
toolbar->setIconSize({16, 16});
QAction *lastSeparator = nullptr;
QAction *lastSeperator = nullptr;
for (const auto &widgetGroup : widgetGroups) {
for (const auto &widget : widgetGroup) {
if (!widget) {
continue;
}
toolbar->addWidget(widget);
}
lastSeparator = toolbar->addSeparator();
lastSeperator = toolbar->addSeparator();
}
if (lastSeparator) {
toolbar->removeAction(lastSeparator);
if (lastSeperator) {
toolbar->removeAction(lastSeperator);
}
// Prevent "extension" button from showing up
@@ -642,9 +638,7 @@ void AdvSceneSwitcher::SetupMacroTab()
{
ui->macros->installEventFilter(this);
auto &macros = GetTopLevelMacros();
if (macros.size() == 0 && !switcher->disableHints) {
if (GetTopLevelMacros().size() == 0 && !switcher->disableHints) {
addPulse = HighlightWidget(ui->macroAdd, QColor(Qt::green));
}
@@ -652,7 +646,8 @@ void AdvSceneSwitcher::SetupMacroTab()
{ui->macroUp, ui->macroDown}});
ui->macroControlLayout->addWidget(macroControls);
ui->macros->Reset(macros, GetGlobalMacroSettings()._highlightExecuted);
ui->macros->Reset(GetTopLevelMacros(),
GetGlobalMacroSettings()._highlightExecuted);
connect(ui->macros, SIGNAL(MacroSelectionChanged()), this,
SLOT(MacroSelectionChanged()));
ui->runMacro->SetMacroTree(ui->macros);
@@ -681,12 +676,6 @@ void AdvSceneSwitcher::SetupMacroTab()
switcher->macroListMacroEditSplitterPosition);
}
}
SetupMacroSearchWidgets(ui->macroSearchLayout, ui->macroSearchText,
ui->macroSearchClear, ui->macroSearchType,
ui->macroSearchRegex,
ui->macroSearchShowSettings,
[this]() { ui->macros->RefreshFilter(); });
}
void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos)

View File

@@ -1,6 +1,5 @@
#include "macro-tree.hpp"
#include "macro.hpp"
#include "macro-search.hpp"
#include "macro-signals.hpp"
#include "path-helpers.hpp"
#include "sync-helpers.hpp"
@@ -784,8 +783,7 @@ void MacroTree::Reset(std::deque<std::shared_ptr<Macro>> &macros,
bool highlight)
{
_highlight = highlight;
auto mtm = new MacroTreeModel(this, macros);
MacroTreeModel *mtm = new MacroTreeModel(this, macros);
setModel(mtm);
GetModel()->Reset(macros);
connect(selectionModel(),
@@ -871,7 +869,7 @@ void MacroTree::UpdateWidgets(bool force)
for (int i = 0; i < (int)mtm->_macros.size(); i++) {
std::shared_ptr<Macro> item = mtm->_macros[i];
auto widget = GetItemWidget(i);
MacroTreeItem *widget = GetItemWidget(i);
if (!widget) {
UpdateWidget(mtm->createIndex(i, 0, nullptr), item);
@@ -1206,12 +1204,6 @@ void MacroTree::CollapseGroup(std::shared_ptr<Macro> item) const
mtm->CollapseGroup(item);
}
void MacroTree::RefreshFilter()
{
UpdateWidgets();
doItemsLayout();
}
void MacroTree::MoveItemBefore(const std::shared_ptr<Macro> &item,
const std::shared_ptr<Macro> &after) const
{
@@ -1226,7 +1218,7 @@ void MacroTree::MoveItemAfter(const std::shared_ptr<Macro> &item,
MacroTreeModel *MacroTree::GetModel() const
{
return qobject_cast<MacroTreeModel *>(model());
return reinterpret_cast<MacroTreeModel *>(model());
}
void MacroTree::Remove(std::shared_ptr<Macro> item) const
@@ -1341,8 +1333,8 @@ void MacroTree::SelectionChangedHelper(const QItemSelection &,
inline MacroTreeItem *MacroTree::GetItemWidget(int idx) const
{
auto widget = indexWidget(GetModel()->createIndex(idx, 0, nullptr));
return qobject_cast<MacroTreeItem *>(widget);
QWidget *widget = indexWidget(GetModel()->createIndex(idx, 0, nullptr));
return reinterpret_cast<MacroTreeItem *>(widget);
}
void MacroTree::paintEvent(QPaintEvent *event)
@@ -1369,25 +1361,14 @@ MacroTreeDelegate::MacroTreeDelegate(QObject *parent)
QSize MacroTreeDelegate::sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
auto tree = qobject_cast<MacroTree *>(parent());
auto widget = tree->indexWidget(index);
MacroTree *tree = qobject_cast<MacroTree *>(parent());
QWidget *item = tree->indexWidget(index);
if (!widget) {
if (!item) {
return QStyledItemDelegate::sizeHint(option, index);
}
auto name = index.data(Qt::AccessibleTextRole).toString();
auto macro = GetMacroByQString(name);
if (!macro) {
return QStyledItemDelegate::sizeHint(option, index);
}
if (MacroMatchesSearchFilter(macro)) {
return QSize(widget->sizeHint());
}
return QSize(0, 0);
return QSize(item->sizeHint());
}
} // namespace advss

View File

@@ -142,7 +142,6 @@ public:
bool GroupsExist() const;
void ExpandGroup(std::shared_ptr<Macro> item) const;
void CollapseGroup(std::shared_ptr<Macro> item) const;
void RefreshFilter();
public slots:
void GroupSelectedItems();

View File

@@ -1255,6 +1255,33 @@ void StopAllMacros()
}
}
Macro *GetMacroByName(const char *name)
{
for (const auto &m : GetTopLevelMacros()) {
if (m->Name() == name) {
return m.get();
}
}
return nullptr;
}
Macro *GetMacroByQString(const QString &name)
{
return GetMacroByName(name.toUtf8().constData());
}
std::weak_ptr<Macro> GetWeakMacroByName(const char *name)
{
for (const auto &m : GetTopLevelMacros()) {
if (m->Name() == name) {
return m;
}
}
return {};
}
void InvalidateMacroTempVarValues()
{
for (const auto &m : GetTopLevelMacros()) {

View File

@@ -9,6 +9,8 @@
#include "temp-variable.hpp"
#include <future>
#include <QString>
#include <QByteArray>
#include <string>
#include <deque>
#include <memory>
@@ -218,6 +220,9 @@ void SaveMacros(obs_data_t *obj);
bool CheckMacros();
bool RunMacros();
void StopAllMacros();
Macro *GetMacroByName(const char *name);
Macro *GetMacroByQString(const QString &name);
std::weak_ptr<Macro> GetWeakMacroByName(const char *name);
void InvalidateMacroTempVarValues();
std::shared_ptr<Macro> GetMacroWithInvalidConditionInterval();

View File

@@ -423,7 +423,7 @@ void ImportQueues(obs_data_t *data)
importedQueues->emplace_back(queue);
}
QueueUITask(signalImportedQueues, importedQueues);
QeueUITask(signalImportedQueues, importedQueues);
}
std::weak_ptr<ActionQueue> GetWeakActionQueueByName(const std::string &name)

View File

@@ -163,6 +163,7 @@ public:
bool warnPluginLoadFailure = true;
bool disableHints = false;
bool disableFilterComboboxFilter = false;
bool disableMacroWidgetCache = false;
bool hideLegacyTabs = true;
bool saveWindowGeo = false;
QPoint windowPos = {};

View File

@@ -67,7 +67,7 @@ int GetCanvasCount()
return 1;
#else
static const auto enumCanvases = [](void *countPtr,
obs_canvas_t *) -> bool {
obs_canvas_t *canvas) -> bool {
auto count = static_cast<int *>(countPtr);
(*count)++;
return true;
@@ -145,15 +145,6 @@ OBSWeakSource GetActiveCanvasScene(const OBSWeakCanvas &weakCanvas)
}
#endif
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
// The frontend scene order does not necessarily match the order of the
// scenes in the canvas.
if (canvas == mainCanvas) {
OBSSourceAutoRelease scene = obs_frontend_get_current_scene();
return OBSGetWeakRef(scene);
}
static const auto enumCanvasScenes = [](void *scenePtr,
obs_source_t *source) -> bool {
auto scene = static_cast<OBSWeakSource *>(scenePtr);
@@ -190,25 +181,6 @@ OBSWeakSource GetSceneAtIndex(const OBSWeakCanvas &weakCanvas, int idx)
}
#endif
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
// The frontend scene order does not necessarily match the order of the
// scenes in the canvas.
// So, rely on obs_frontend_get_scenes() in case of the main canvas
// instead.
if (canvas == mainCanvas) {
struct obs_frontend_source_list scenes = {0};
obs_frontend_get_scenes(&scenes);
if (idx >= (int)scenes.sources.num) {
obs_frontend_source_list_free(&scenes);
return nullptr;
}
auto scene = OBSGetWeakRef(scenes.sources.array[idx]);
obs_frontend_source_list_free(&scenes);
return scene;
}
struct Data {
const int idx;
int currentIdx;
@@ -251,29 +223,6 @@ int GetIndexOfScene(const OBSWeakCanvas &weakCanvas, const OBSWeakSource &scene)
return 0;
}
#endif
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
// The frontend scene order does not necessarily match the order of the
// scenes in the canvas.
// So, rely on obs_frontend_get_scenes() in case of the main canvas
// instead.
if (canvas == mainCanvas) {
struct obs_frontend_source_list scenes = {0};
obs_frontend_get_scenes(&scenes);
OBSSourceAutoRelease sceneSource = OBSGetStrongRef(scene);
int idx = 0;
for (size_t i = 0; i < scenes.sources.num; i++) {
if (scenes.sources.array[i] == sceneSource) {
idx = i;
break;
}
}
obs_frontend_source_list_free(&scenes);
return idx;
}
struct Data {
int idx;
@@ -297,12 +246,6 @@ int GetIndexOfScene(const OBSWeakCanvas &weakCanvas, const OBSWeakSource &scene)
return data.idx;
}
OBSWeakCanvas GetMainCanvas()
{
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
return OBSGetWeakRef(mainCanvas);
}
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
obs_canvas_t *obs_canvas_get_ref(obs_canvas_t *)

View File

@@ -42,7 +42,6 @@ EXPORT OBSWeakSource GetActiveCanvasScene(const OBSWeakCanvas &canvas);
EXPORT OBSWeakSource GetSceneAtIndex(const OBSWeakCanvas &weakCanvas, int idx);
EXPORT int GetIndexOfScene(const OBSWeakCanvas &weakCanvas,
const OBSWeakSource &scene);
EXPORT OBSWeakCanvas GetMainCanvas();
class CanvasSelection : public FilterComboBox {
Q_OBJECT

View File

@@ -8,7 +8,7 @@
namespace advss {
ResourceTable::ResourceTable(QWidget *parent, const QString &help,
ResourceTable::ResourceTable(QTabWidget *parent, const QString &help,
const QString &addToolTip,
const QString &removeToolTip,
const QStringList &headers,

View File

@@ -14,7 +14,7 @@ class ADVSS_EXPORT ResourceTable : public QWidget {
Q_OBJECT
public:
ResourceTable(QWidget *parent, const QString &help,
ResourceTable(QTabWidget *parent, const QString &help,
const QString &addToolTip, const QString &removeToolTip,
const QStringList &headers,
const std::function<void()> &openSettings);

View File

@@ -103,11 +103,10 @@ void SceneSelection::Load(obs_data_t *obj, const char *name,
OBSDataAutoRelease data =
obs_data_get_obj(obj, selectionSaveName.data());
const char *canvasName =
obs_data_get_string(data, canvasSaveName.data());
_canvas = GetWeakCanvasByName(
obs_data_get_string(data, canvasSaveName.data()));
if (strcmp(canvasName, "") == 0) {
if (obs_data_has_user_value(data, canvasSaveName.data())) {
_canvas = GetWeakCanvasByName(
obs_data_get_string(data, canvasSaveName.data()));
} else {
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
_canvas = obs_canvas_get_weak_canvas(mainCanvas);
obs_weak_canvas_release(_canvas);

View File

@@ -30,7 +30,7 @@ public:
private:
OBSWeakSource _scene;
OBSWeakCanvas _canvas = GetMainCanvas();
OBSWeakCanvas _canvas;
SceneGroup *_group = nullptr;
std::weak_ptr<Variable> _variable;
Type _type = Type::SCENE;

View File

@@ -178,7 +178,7 @@ std::string GetThemeTypeName()
#endif
}
void QueueUITask(void (*task)(void *param), void *param)
void QeueUITask(void (*task)(void *param), void *param)
{
obs_queue_task(OBS_TASK_UI, task, param, false);
}

View File

@@ -35,7 +35,7 @@ EXPORT void DisplayTrayMessage(const QString &title, const QString &msg,
EXPORT std::string GetThemeTypeName();
EXPORT QWidget *GetSettingsWindow();
EXPORT void QueueUITask(void (*task)(void *param), void *param);
void QeueUITask(void (*task)(void *param), void *param);
bool IsCursorInWidgetArea(QWidget *widget);

View File

@@ -8,9 +8,6 @@
#include "ui-helpers.hpp"
#include "variable.hpp"
#include <obs-frontend-api.h>
#include <QLayout>
#include <QTimer>
namespace advss {
@@ -19,62 +16,14 @@ static bool registerTab();
static void setupTab(QTabWidget *);
static bool registerTabDone = registerTab();
static VariableTable *dockWidget = nullptr;
static bool addDock = false;
static VariableTable::Settings tabSettings;
static VariableTable::Settings dockSettings;
static void save(obs_data_t *data)
{
tabSettings.Save(data, "tabSettings");
dockSettings.Save(data, "dockSettings");
obs_data_set_bool(data, "addVariablesDock", addDock);
}
static void enableDock(bool enable)
{
if (OBSIsShuttingDown()) {
return;
}
obs_frontend_remove_dock("advss-variable-dock");
addDock = enable;
if (!addDock) {
return;
}
dockWidget = new VariableTable(dockSettings);
dockWidget->HideDockOptions();
if (obs_frontend_add_dock_by_id(
"advss-variable-dock",
obs_module_text("AdvSceneSwitcher.variableTab.title"),
dockWidget)) {
return;
}
blog(LOG_INFO, "failed to register variable dock!");
dockWidget->deleteLater();
dockWidget = nullptr;
}
static void load(obs_data_t *data)
{
tabSettings.Load(data, "tabSettings");
dockSettings.Load(data, "dockSettings");
enableDock(obs_data_get_bool(data, "addVariablesDock"));
}
static VariableTable *tabWidget = nullptr;
static bool registerTab()
{
AddPluginInitStep([]() {
AddSetupTabCallback("variableTab",
VariableTable::CreateTabTable, setupTab);
AddSetupTabCallback("variableTab", VariableTable::Create,
setupTab);
});
AddSaveStep(save);
AddLoadStep(load);
return true;
}
@@ -85,14 +34,10 @@ static void setTabVisible(QTabWidget *tabWidget, bool visible)
obs_module_text("AdvSceneSwitcher.variableTab.title"));
}
VariableTable *VariableTable::CreateTabTable()
VariableTable *VariableTable::Create()
{
return new VariableTable(tabSettings);
}
void VariableTable::HideDockOptions() const
{
_addDock->hide();
tabWidget = new VariableTable();
return tabWidget;
}
void VariableTable::Add()
@@ -218,14 +163,15 @@ static void updateVariableStatus(QTableWidget *table)
}
}
static void openSettingsDialog(VariableTable *table)
static void openSettingsDialog()
{
auto selectedRows = table->Table()->selectionModel()->selectedRows();
auto selectedRows =
tabWidget->Table()->selectionModel()->selectedRows();
if (selectedRows.empty()) {
return;
}
auto cell = table->Table()->item(selectedRows.last().row(), 0);
auto cell = tabWidget->Table()->item(selectedRows.last().row(), 0);
if (!cell) {
return;
}
@@ -248,14 +194,15 @@ static void openSettingsDialog(VariableTable *table)
void VariableTable::Remove()
{
auto selectedRows = Table()->selectionModel()->selectedRows();
auto selectedRows =
tabWidget->Table()->selectionModel()->selectedRows();
if (selectedRows.empty()) {
return;
}
QStringList varNames;
for (const auto &row : selectedRows) {
auto cell = Table()->item(row.row(), 0);
auto cell = tabWidget->Table()->item(row.row(), 0);
if (!cell) {
continue;
}
@@ -288,52 +235,7 @@ void VariableTable::Remove()
}
}
void VariableTable::Filter()
{
const auto itemMatches = [&](const QTableWidgetItem *item) {
if (!item) {
return false;
}
if (_settings.searchString.empty()) {
return true;
}
const auto text = item->text();
if (_settings.regex.Enabled()) {
return _settings.regex.Matches(text.toStdString(),
_settings.searchString);
}
return text.contains(
QString::fromStdString(_settings.searchString),
Qt::CaseInsensitive);
};
for (int row = 0; row < Table()->rowCount(); ++row) {
bool match = false;
if (_settings.searchType == Settings::SearchType::ALL) {
for (int col = 0; col < Table()->columnCount(); ++col) {
if (itemMatches(Table()->item(row, col))) {
match = true;
break;
}
}
} else {
if (itemMatches(Table()->item(
row,
static_cast<int>(_settings.searchType)))) {
match = true;
}
}
Table()->setRowHidden(row, !match);
}
}
VariableTable::VariableTable(Settings &settings, QWidget *parent)
VariableTable::VariableTable(QTabWidget *parent)
: ResourceTable(
parent, obs_module_text("AdvSceneSwitcher.variableTab.help"),
obs_module_text(
@@ -351,113 +253,13 @@ VariableTable::VariableTable(Settings &settings, QWidget *parent)
"AdvSceneSwitcher.variableTab.lastUsed.header")
<< obs_module_text(
"AdvSceneSwitcher.variableTab.lastChanged.header"),
[this]() { openSettingsDialog(this); }),
_searchField(new QLineEdit(this)),
_clear(new QPushButton(this)),
_searchType(new QComboBox(this)),
_regexWidget(new RegexConfigWidget(this)),
_addDock(new QCheckBox(
obs_module_text("AdvSceneSwitcher.variableTab.addDock"))),
_settings(settings)
openSettingsDialog)
{
_clear->setMaximumWidth(22);
SetButtonIcon(_clear, GetThemeTypeName() == "Light"
? "theme:Light/close.svg"
: "theme:Dark/close.svg");
_clear->setToolTip(
obs_module_text("AdvSceneSwitcher.variableTab.clear"));
_clear->setDisabled(_settings.searchString.empty());
connect(_clear, &QPushButton::clicked, this, [this]() {
_searchField->setText("");
_clear->setDisabled(true);
});
for (const auto &variable : GetVariables()) {
auto v = std::static_pointer_cast<Variable>(variable);
AddItemTableRow(Table(), getCellLabels(v.get()));
}
connect(Table(), &QTableWidget::itemChanged, this,
[this]() { Filter(); });
_searchField->setPlaceholderText(obs_module_text(
("AdvSceneSwitcher.variableTab.search.placeholder")));
_searchField->setText(QString::fromStdString(_settings.searchString));
connect(_searchField, &QLineEdit::textChanged, this,
[this](const QString &text) {
_settings.searchString = text.toStdString();
_clear->setDisabled(text.isEmpty());
Filter();
});
_searchType->addItem(
obs_module_text("AdvSceneSwitcher.variableTab.search.all"),
Settings::SearchType::ALL);
_searchType->addItem(
obs_module_text("AdvSceneSwitcher.variableTab.search.name"),
Settings::SearchType::NAME);
_searchType->addItem(
obs_module_text("AdvSceneSwitcher.variableTab.search.value"),
Settings::SearchType::VALUE);
_searchType->setCurrentIndex(
_searchType->findData(_settings.searchType));
connect(_searchType, &QComboBox::currentIndexChanged, this, [this]() {
_settings.searchType = static_cast<Settings::SearchType>(
_searchType->currentData().toInt());
});
_regexWidget->SetRegexConfig(_settings.regex);
connect(_regexWidget, &RegexConfigWidget::RegexConfigChanged, this,
[this](const RegexConfig &regex) {
_settings.regex = regex;
Filter();
});
_addDock->setChecked(addDock);
connect(_addDock, &QCheckBox::stateChanged, this,
[this](int checked) { enableDock(checked); });
QWidget::connect(VariableSignalManager::Instance(),
&VariableSignalManager::Rename, this,
[this](const QString &oldName,
const QString &newName) {
RenameItemTableRow(Table(), oldName, newName);
});
QWidget::connect(
VariableSignalManager::Instance(), &VariableSignalManager::Add,
this, [this](const QString &name) {
AddItemTableRow(
Table(),
getCellLabels(GetVariableByQString(name)));
SetHelpVisible(false);
HighlightAddButton(false);
});
QWidget::connect(VariableSignalManager::Instance(),
&VariableSignalManager::Remove, this,
[this](const QString &name) {
RemoveItemTableRow(Table(), name);
if (Table()->rowCount() == 0) {
SetHelpVisible(true);
HighlightAddButton(true);
}
});
auto timer = new QTimer(this);
timer->setInterval(1000);
QWidget::connect(timer, &QTimer::timeout,
[this]() { updateVariableStatus(Table()); });
timer->start();
auto searchLayout = new QHBoxLayout();
searchLayout->addWidget(_searchField);
searchLayout->addWidget(_clear);
searchLayout->addWidget(_searchType);
searchLayout->addWidget(_regexWidget);
searchLayout->addWidget(_addDock);
qobject_cast<QVBoxLayout *>(layout())->insertLayout(0, searchLayout);
SetHelpVisible(GetVariables().empty());
}
@@ -467,27 +269,37 @@ static void setupTab(QTabWidget *tab)
setTabVisible(tab, false);
}
QWidget::connect(VariableSignalManager::Instance(),
&VariableSignalManager::Rename, tab,
[](const QString &oldName, const QString &newName) {
RenameItemTableRow(tabWidget->Table(), oldName,
newName);
});
QWidget::connect(
VariableSignalManager::Instance(), &VariableSignalManager::Add,
tab, [tab](const QString &name) { setTabVisible(tab, true); });
}
tab, [tab](const QString &name) {
AddItemTableRow(
tabWidget->Table(),
getCellLabels(GetVariableByQString(name)));
tabWidget->SetHelpVisible(false);
tabWidget->HighlightAddButton(false);
setTabVisible(tab, true);
});
QWidget::connect(VariableSignalManager::Instance(),
&VariableSignalManager::Remove, tab,
[](const QString &name) {
RemoveItemTableRow(tabWidget->Table(), name);
if (tabWidget->Table()->rowCount() == 0) {
tabWidget->SetHelpVisible(true);
tabWidget->HighlightAddButton(true);
}
});
void VariableTable::Settings::Save(obs_data_t *data, const char *name)
{
OBSDataAutoRelease settings = obs_data_create();
obs_data_set_int(settings, "searchType", static_cast<int>(searchType));
obs_data_set_string(settings, "searchString", searchString.c_str());
regex.Save(settings);
obs_data_set_obj(data, name, settings);
}
void VariableTable::Settings::Load(obs_data_t *data, const char *name)
{
OBSDataAutoRelease settings = obs_data_get_obj(data, name);
searchType = static_cast<SearchType>(
obs_data_get_int(settings, "searchType"));
searchString = obs_data_get_string(settings, "searchString");
regex.Load(settings);
auto timer = new QTimer(tabWidget);
timer->setInterval(1000);
QWidget::connect(timer, &QTimer::timeout,
[]() { updateVariableStatus(tabWidget->Table()); });
timer->start();
}
} // namespace advss

View File

@@ -1,8 +1,5 @@
#pragma once
#include "resource-table.hpp"
#include "regex-config.hpp"
#include <QComboBox>
namespace advss {
@@ -10,34 +7,14 @@ class VariableTable final : public ResourceTable {
Q_OBJECT
public:
struct Settings {
void Save(obs_data_t *data, const char *name);
void Load(obs_data_t *data, const char *name);
enum SearchType { ALL = -1, NAME = 0, VALUE = 1 };
SearchType searchType = SearchType::ALL;
std::string searchString;
RegexConfig regex;
};
VariableTable(Settings &settings, QWidget *parent = nullptr);
static VariableTable *CreateTabTable();
void HideDockOptions() const;
static VariableTable *Create();
private slots:
void Add();
void Remove();
void Filter();
private:
QLineEdit *_searchField;
QPushButton *_clear;
QComboBox *_searchType;
RegexConfigWidget *_regexWidget;
QCheckBox *_addDock;
Settings &_settings;
VariableTable(QTabWidget *parent = nullptr);
};
} // namespace advss

View File

@@ -456,7 +456,7 @@ void ImportVariables(obs_data_t *data)
obs_data_array_release(array);
QueueUITask(signalImportedVariables, importedVars);
QeueUITask(signalImportedVariables, importedVars);
}
std::chrono::high_resolution_clock::time_point GetLastVariableChangeTime()

View File

@@ -601,10 +601,10 @@ static void populateHotkeyNames(QComboBox *list,
MacroActionHotkeyEdit::MacroActionHotkeyEdit(
QWidget *parent, std::shared_ptr<MacroActionHotkey> entryData)
: QWidget(parent),
_actionType(new FilterComboBox()),
_hotkeyType(new FilterComboBox()),
_obsHotkeys(new FilterComboBox()),
_keys(new FilterComboBox()),
_actionType(new QComboBox()),
_hotkeyType(new QComboBox()),
_obsHotkeys(new QComboBox()),
_keys(new QComboBox()),
_leftShift(new QCheckBox(
obs_module_text("AdvSceneSwitcher.action.hotkey.leftShift"))),
_rightShift(new QCheckBox(obs_module_text(

View File

@@ -85,14 +85,11 @@ private slots:
void DurationChanged(const Duration &);
void OnlySendToOBSChanged(int state);
private:
void RepopulateOBSHotkeySelection();
void SetWidgetVisibility();
FilterComboBox *_actionType;
FilterComboBox *_hotkeyType;
FilterComboBox *_obsHotkeys;
FilterComboBox *_keys;
protected:
QComboBox *_actionType;
QComboBox *_hotkeyType;
QComboBox *_obsHotkeys;
QComboBox *_keys;
QCheckBox *_leftShift;
QCheckBox *_rightShift;
QCheckBox *_leftCtrl;
@@ -104,10 +101,15 @@ private:
DurationSelection *_duration;
QCheckBox *_onlySendToOBS;
QLabel *_noKeyPressSimulationWarning;
QHBoxLayout *_entryLayout;
QHBoxLayout *_keyConfigLayout;
std::shared_ptr<MacroActionHotkey> _entryData;
private:
void RepopulateOBSHotkeySelection();
void SetWidgetVisibility();
QHBoxLayout *_entryLayout;
QHBoxLayout *_keyConfigLayout;
bool _loading = true;
};

View File

@@ -137,51 +137,31 @@ bool MacroActionSwitchScene::WaitForTransition(OBSWeakSource &scene,
bool MacroActionSwitchScene::PerformAction()
{
OBSWeakSource sceneToSwitchTo;
OBSWeakCanvas canvasToSwitchFor;
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
OBSWeakCanvas mainCanvasWeak = OBSGetWeakRef(mainCanvas);
const auto getActiveSceneHelper = [this](const OBSWeakCanvas &canvas) {
OBSWeakSource activeScene;
if (IsMainCanvas(canvas) && _sceneType == SceneType::PREVIEW) {
OBSSourceAutoRelease previewSource =
obs_frontend_get_current_preview_scene();
return OBSGetWeakRef(previewSource);
} else {
return GetActiveCanvasScene(canvas);
}
};
OBSWeakCanvas canvas;
switch (_action) {
case Action::SCENE_NAME:
sceneToSwitchTo = _scene.GetScene();
canvasToSwitchFor = _scene.GetCanvas();
canvas = _scene.GetCanvas();
break;
case Action::SCENE_LIST_NEXT: {
canvasToSwitchFor = _canvas ? _canvas : mainCanvasWeak;
const auto activeScene =
getActiveSceneHelper(canvasToSwitchFor);
const int currentIndex =
GetIndexOfScene(canvasToSwitchFor, activeScene);
sceneToSwitchTo =
GetSceneAtIndex(canvasToSwitchFor, currentIndex + 1);
const auto activeScene = GetActiveCanvasScene(_canvas);
const int currentIndex = GetIndexOfScene(_canvas, activeScene);
sceneToSwitchTo = GetSceneAtIndex(_canvas, currentIndex + 1);
canvas = _canvas;
break;
}
case Action::SCENE_LIST_PREVIOUS: {
canvasToSwitchFor = _canvas ? _canvas : mainCanvasWeak;
const auto activeScene =
getActiveSceneHelper(canvasToSwitchFor);
const int currentIndex =
GetIndexOfScene(canvasToSwitchFor, activeScene);
sceneToSwitchTo =
GetSceneAtIndex(canvasToSwitchFor, currentIndex - 1);
const auto activeScene = GetActiveCanvasScene(_canvas);
const int currentIndex = GetIndexOfScene(_canvas, activeScene);
sceneToSwitchTo = GetSceneAtIndex(_canvas, currentIndex - 1);
canvas = _canvas;
break;
}
case Action::SCENE_LIST_INDEX: {
canvasToSwitchFor = _canvas ? _canvas : mainCanvasWeak;
sceneToSwitchTo = GetSceneAtIndex(canvasToSwitchFor,
_index.GetValue() - 1);
sceneToSwitchTo =
GetSceneAtIndex(_canvas, _index.GetValue() - 1);
canvas = _canvas;
break;
}
default:
@@ -196,12 +176,11 @@ bool MacroActionSwitchScene::PerformAction()
}
auto transition = _transition.GetTransition();
SwitchScene(
{sceneToSwitchTo, transition, (int)(_duration.Milliseconds())},
obs_frontend_preview_program_mode_active(), canvasToSwitchFor);
SwitchScene({sceneToSwitchTo, transition,
(int)(_duration.Milliseconds())},
obs_frontend_preview_program_mode_active(), canvas);
if (_blockUntilTransitionDone && sceneToSwitchTo &&
sceneToSwitchTo != GetCurrentScene() &&
IsMainCanvas(canvasToSwitchFor)) {
sceneToSwitchTo != GetCurrentScene() && IsMainCanvas(canvas)) {
return WaitForTransition(sceneToSwitchTo, transition);
}
return true;
@@ -413,7 +392,6 @@ void MacroActionSwitchSceneEdit::SetWidgetData() const
_sceneTypes->setCurrentIndex(_sceneTypes->findData(
static_cast<int>(_entryData->_sceneType)));
_scenes->SetScene(_entryData->_scene);
_canvas->SetCanvas(_entryData->_canvas);
_transitions->SetTransition(_entryData->_transition);
_duration->SetDuration(_entryData->_duration);
_blockUntilTransitionDone->setChecked(
@@ -583,17 +561,9 @@ void MacroActionSwitchSceneEdit::SetWidgetVisibility()
{{"{{transitions}}", _transitions},
{"{{duration}}", _duration}});
OBSWeakCanvas canvas;
if (action == MacroActionSwitchScene::Action::SCENE_NAME) {
canvas = _entryData->_scene.GetCanvas();
} else {
if (_entryData->_canvas) {
canvas = _entryData->_canvas;
} else {
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
canvas = OBSGetWeakRef(mainCanvas);
}
}
const auto canvas = action == MacroActionSwitchScene::Action::SCENE_NAME
? _entryData->_scene.GetCanvas()
: _entryData->_canvas;
const bool isMainCanvas = IsMainCanvas(canvas);
SetLayoutVisible(_transitionLayout, isMainCanvas);
_blockUntilTransitionDone->setVisible(isMainCanvas);
@@ -610,7 +580,7 @@ void MacroActionSwitchSceneEdit::SetWidgetVisibility()
_notSupportedWarning->setText(
fmt.arg(QString::fromStdString(GetWeakCanvasName(canvas))));
_notSupportedWarning->setVisible(
!isMainCanvas &&
!IsMainCanvas(canvas) &&
_entryData->_sceneType ==
MacroActionSwitchScene::SceneType::PREVIEW);

View File

@@ -7,8 +7,6 @@
#include <obs-frontend-api.h>
#include <QMainWindow>
namespace advss {
const std::string MacroActionSource::id = "source";
@@ -39,12 +37,6 @@ const static std::map<MacroActionSource::Action, std::string> actionTypes = {
"AdvSceneSwitcher.action.source.type.openFilterDialog"},
{MacroActionSource::Action::OPEN_PROPERTIES_DIALOG,
"AdvSceneSwitcher.action.source.type.openPropertiesDialog"},
{MacroActionSource::Action::CLOSE_INTERACTION_DIALOG,
"AdvSceneSwitcher.action.source.type.closeInteractionDialog"},
{MacroActionSource::Action::CLOSE_FILTER_DIALOG,
"AdvSceneSwitcher.action.source.type.closeFilterDialog"},
{MacroActionSource::Action::CLOSE_PROPERTIES_DIALOG,
"AdvSceneSwitcher.action.source.type.closePropertiesDialog"},
};
const static std::map<obs_deinterlace_mode, std::string> deinterlaceModes = {
@@ -116,81 +108,9 @@ static bool isInteractable(obs_source_t *source)
return (flags & OBS_SOURCE_INTERACTION) != 0;
}
static void closeSourceDialog(obs_source_t *source, bool accept,
const char *className)
{
if (!source) {
return;
}
auto mainWindow =
reinterpret_cast<QMainWindow *>(obs_frontend_get_main_window());
if (!mainWindow) {
return;
}
for (const auto widget : mainWindow->children()) {
auto dialog = qobject_cast<QDialog *>(widget);
if (!dialog) {
continue;
}
if (dialog->metaObject()->className() != QString(className)) {
continue;
}
const char *name = obs_source_get_name(source);
if (!name) {
continue;
}
if (!dialog->windowTitle().contains(QString(name))) {
continue;
}
if (accept) {
dialog->accept();
return;
}
// dialog->reject() will ask for confirmation
// Try to avoid this by finding and pressing the cancel button
for (const auto widget : dialog->children()) {
auto buttons = qobject_cast<QDialogButtonBox *>(widget);
if (!buttons) {
continue;
}
for (auto *button : buttons->buttons()) {
if (buttons->buttonRole(button) ==
QDialogButtonBox::RejectRole) {
button->click();
break;
}
}
}
}
}
template<typename F> void QueueUITaskLambda(F &&func)
{
using FnType = std::decay_t<F>;
auto *heapFunc = new FnType(std::forward<F>(func));
QueueUITask(
[](void *param) {
std::unique_ptr<FnType> fn(
static_cast<FnType *>(param));
(*fn)();
},
heapFunc);
}
bool MacroActionSource::PerformAction()
{
OBSSource s = obs_weak_source_get_source(_source.GetSource());
obs_source_release(s);
auto s = obs_weak_source_get_source(_source.GetSource());
switch (_action) {
case Action::ENABLE:
obs_source_set_enabled(s, true);
@@ -252,31 +172,10 @@ bool MacroActionSource::PerformAction()
case Action::OPEN_PROPERTIES_DIALOG:
obs_frontend_open_source_properties(s);
break;
case Action::CLOSE_INTERACTION_DIALOG:
if (!isInteractable(s)) {
// Nothing to do
break;
}
QueueUITaskLambda([&]() {
closeSourceDialog(s, true, "OBSBasicInteraction");
});
break;
case Action::CLOSE_FILTER_DIALOG:
QueueUITaskLambda([&]() {
closeSourceDialog(s, _acceptDialog, "OBSBasicFilters");
});
break;
case Action::CLOSE_PROPERTIES_DIALOG:
QueueUITaskLambda([&]() {
closeSourceDialog(s, _acceptDialog,
"OBSBasicProperties");
});
break;
default:
break;
}
obs_source_release(s);
return true;
}
@@ -308,7 +207,6 @@ bool MacroActionSource::Save(obs_data_t *obj) const
static_cast<int>(_deinterlaceMode));
obs_data_set_int(obj, "deinterlaceOrder",
static_cast<int>(_deinterlaceOrder));
obs_data_set_bool(obj, "acceptDialog", _acceptDialog);
return true;
}
@@ -333,7 +231,6 @@ bool MacroActionSource::Load(obs_data_t *obj)
obs_data_get_int(obj, "deinterlaceMode"));
_deinterlaceOrder = static_cast<obs_deinterlace_field_order>(
obs_data_get_int(obj, "deinterlaceOrder"));
_acceptDialog = obs_data_get_bool(obj, "acceptDialog");
return true;
}
@@ -410,9 +307,7 @@ MacroActionSourceEdit::MacroActionSourceEdit(
_warning(new QLabel(
obs_module_text("AdvSceneSwitcher.action.source.warning"))),
_refreshSettingSelection(new QPushButton(
obs_module_text("AdvSceneSwitcher.action.source.refresh"))),
_acceptDialog(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.action.source.dialog.accept")))
obs_module_text("AdvSceneSwitcher.action.source.refresh")))
{
populateActionSelection(_actions);
@@ -452,8 +347,6 @@ MacroActionSourceEdit::MacroActionSourceEdit(
SLOT(SelectionChanged(const SourceSetting &)));
QWidget::connect(_refreshSettingSelection, SIGNAL(clicked()), this,
SLOT(RefreshVariableSourceSelectionValue()));
QWidget::connect(_acceptDialog, SIGNAL(stateChanged(int)), this,
SLOT(AcceptDialogChanged(int)));
auto entryLayout = new QHBoxLayout;
entryLayout->setContentsMargins(0, 0, 0, 0);
@@ -481,7 +374,6 @@ MacroActionSourceEdit::MacroActionSourceEdit(
mainLayout->addLayout(_settingsLayout);
mainLayout->addWidget(_warning);
mainLayout->addWidget(_settingsString);
mainLayout->addWidget(_acceptDialog);
auto buttonLayout = new QHBoxLayout;
buttonLayout->setContentsMargins(0, 0, 0, 0);
buttonLayout->addWidget(_getSettings);
@@ -514,7 +406,6 @@ void MacroActionSourceEdit::UpdateEntryData()
static_cast<int>(_entryData->_settingsInputMethod)));
_tempVars->SetVariable(_entryData->_tempVar);
_manualSettingValue->setPlainText(_entryData->_manualSettingValue);
_acceptDialog->setChecked(_entryData->_acceptDialog);
SetWidgetVisibility();
}
@@ -640,12 +531,6 @@ void MacroActionSourceEdit::RefreshVariableSourceSelectionValue()
_sourceSettings->SetSource(_entryData->_source.GetSource());
}
void MacroActionSourceEdit::AcceptDialogChanged(int state)
{
GUARD_LOADING_AND_LOCK();
_entryData->_acceptDialog = state;
}
static QString GetIndividualListEntryName()
{
static const auto matchesInput =
@@ -728,12 +613,6 @@ void MacroActionSourceEdit::SetWidgetVisibility()
_entryData->_source.GetType() ==
SourceSelection::Type::VARIABLE);
_acceptDialog->setVisible(
_entryData->_action ==
MacroActionSource::Action::CLOSE_FILTER_DIALOG ||
_entryData->_action ==
MacroActionSource::Action::CLOSE_PROPERTIES_DIALOG);
adjustSize();
updateGeometry();
}

View File

@@ -5,10 +5,9 @@
#include "source-selection.hpp"
#include "source-setting.hpp"
#include <QCheckBox>
#include <QComboBox>
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
namespace advss {
@@ -34,7 +33,6 @@ public:
OBS_DEINTERLACE_FIELD_ORDER_TOP;
TempVariableRef _tempVar;
SourceSetting _setting;
bool _acceptDialog = false;
enum class Action {
ENABLE,
@@ -47,9 +45,6 @@ public:
OPEN_INTERACTION_DIALOG,
OPEN_FILTER_DIALOG,
OPEN_PROPERTIES_DIALOG,
CLOSE_INTERACTION_DIALOG,
CLOSE_FILTER_DIALOG,
CLOSE_PROPERTIES_DIALOG,
};
Action _action = Action::SETTINGS;
@@ -96,7 +91,6 @@ private slots:
void SelectionChanged(const SourceSetting &);
void ManualSettingsValueChanged();
void RefreshVariableSourceSelectionValue();
void AcceptDialogChanged(int);
signals:
void HeaderInfoChanged(const QString &);
@@ -118,7 +112,6 @@ private:
QComboBox *_deinterlaceOrder;
QLabel *_warning;
QPushButton *_refreshSettingSelection;
QCheckBox *_acceptDialog;
std::shared_ptr<MacroActionSource> _entryData;
bool _loading = true;

View File

@@ -58,10 +58,6 @@ bool MacroConditionReplayBuffer::ReplayBufferWasSaved()
bool MacroConditionReplayBuffer::CheckCondition()
{
char *lastSavePath = obs_frontend_get_last_replay();
SetTempVarValue("lastSavePath", lastSavePath ? lastSavePath : "");
bfree(lastSavePath);
switch (_state) {
case Condition::STOP:
return !obs_frontend_replay_buffer_active();
@@ -89,16 +85,6 @@ bool MacroConditionReplayBuffer::Load(obs_data_t *obj)
return true;
}
void MacroConditionReplayBuffer::SetupTempVars()
{
MacroCondition::SetupTempVars();
AddTempvar(
"lastSavePath",
obs_module_text("AdvSceneSwitcher.tempVar.replay.lastSavePath"),
obs_module_text(
"AdvSceneSwitcher.tempVar.replay.lastSavePath.description"));
}
static inline void populateStateSelection(QComboBox *list)
{
for (const auto &entry : conditions) {

View File

@@ -6,7 +6,7 @@
namespace advss {
class MacroConditionReplayBuffer final : public MacroCondition {
class MacroConditionReplayBuffer : public MacroCondition {
public:
MacroConditionReplayBuffer(Macro *m) : MacroCondition(m) {}
bool CheckCondition();
@@ -27,7 +27,6 @@ public:
Condition _state = Condition::STOP;
private:
void SetupTempVars();
bool ReplayBufferWasSaved();
bool _saveTimeInitialized = false;
@@ -36,7 +35,7 @@ private:
static const std::string id;
};
class MacroConditionReplayBufferEdit final : public QWidget {
class MacroConditionReplayBufferEdit : public QWidget {
Q_OBJECT
public:
@@ -56,10 +55,11 @@ public:
private slots:
void StateChanged(int value);
private:
protected:
QComboBox *_state;
std::shared_ptr<MacroConditionReplayBuffer> _entryData;
private:
bool _loading = true;
};

View File

@@ -10,6 +10,12 @@ if(OS_MACOS)
endif()
find_package(OpenSSL)
get_cmake_property(_variableNames VARIABLES)
list(SORT _variableNames)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
find_package(PahoMqttCpp)
if(NOT PahoMqttCpp_FOUND)
message(WARNING "PahoMqttCpp not found!\n"

View File

@@ -1,7 +1,6 @@
#include "token.hpp"
#include "twitch-helpers.hpp"
#include <help-icon.hpp>
#include <layout-helpers.hpp>
#include <log-helper.hpp>
#include <obs-module-helper.hpp>
@@ -164,8 +163,7 @@ TwitchToken::TwitchToken(const TwitchToken &other)
_userID(other._userID),
_tokenOptions(other._tokenOptions),
_eventSub(),
_validateEventSubTimestamps(other._validateEventSubTimestamps),
_warnIfInvalid(other._warnIfInvalid)
_validateEventSubTimestamps(other._validateEventSubTimestamps)
{
}
@@ -176,7 +174,6 @@ TwitchToken &TwitchToken::operator=(const TwitchToken &other)
_userID = other._userID;
_tokenOptions = other._tokenOptions;
_validateEventSubTimestamps = other._validateEventSubTimestamps;
_warnIfInvalid = other._warnIfInvalid;
return *this;
}
@@ -188,9 +185,6 @@ void TwitchToken::Load(obs_data_t *obj)
obs_data_set_default_bool(obj, "validateEventSubTimestamps", true);
_validateEventSubTimestamps =
obs_data_get_bool(obj, "validateEventSubTimestamps");
_warnIfInvalid = obs_data_has_user_value(obj, "warnIfInvalid")
? obs_data_get_bool(obj, "warnIfInvalid")
: true;
_tokenOptions.clear();
OBSDataArrayAutoRelease options = obs_data_get_array(obj, "options");
size_t count = obs_data_array_count(options);
@@ -209,7 +203,6 @@ void TwitchToken::Save(obs_data_t *obj) const
obs_data_set_string(obj, "userID", _userID.c_str());
obs_data_set_bool(obj, "validateEventSubTimestamps",
_validateEventSubTimestamps);
obs_data_set_bool(obj, "warnIfInvalid", _warnIfInvalid);
OBSDataArrayAutoRelease options = obs_data_array_create();
for (auto &option : _tokenOptions) {
OBSDataAutoRelease arrayObj = obs_data_create();
@@ -484,9 +477,7 @@ TwitchTokenSettingsDialog::TwitchTokenSettingsDialog(
_tokenStatus(new QLabel()),
_generalSettingsGrid(new QGridLayout()),
_validateTimestamps(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.twitchToken.validateTimestamps"))),
_warnIfInvalid(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.twitchToken.warnIfInvalid")))
"AdvSceneSwitcher.twitchToken.validateTimestamps")))
{
_showToken->setMaximumWidth(22);
_showToken->setFlat(true);
@@ -548,18 +539,11 @@ TwitchTokenSettingsDialog::TwitchTokenSettingsDialog(
scrollArea->setWidgetResizable(true);
scrollArea->setFrameShape(QFrame::NoFrame);
auto timestampsLayout = new QHBoxLayout();
timestampsLayout->addWidget(_validateTimestamps);
auto timestampHelp = new HelpIcon(obs_module_text(
"AdvSceneSwitcher.twitchToken.validateTimestamps.tooltip"));
timestampsLayout->addWidget(timestampHelp);
auto contentWidget = new QWidget(scrollArea);
auto layout = new QVBoxLayout(contentWidget);
layout->addLayout(_generalSettingsGrid);
layout->addWidget(optionsBox);
layout->addLayout(timestampsLayout);
layout->addWidget(_warnIfInvalid);
layout->addWidget(_validateTimestamps);
layout->setContentsMargins(0, 0, 0, 0);
scrollArea->setWidget(contentWidget);
@@ -585,7 +569,6 @@ TwitchTokenSettingsDialog::TwitchTokenSettingsDialog(
#ifndef VERIFY_TIMESTAMPS
_validateTimestamps->hide();
#endif
_warnIfInvalid->setChecked(settings._warnIfInvalid);
_currentToken = settings;
@@ -794,8 +777,6 @@ bool TwitchTokenSettingsDialog::AskForSettings(QWidget *parent,
settings._tokenOptions = dialog.GetEnabledOptions();
settings._validateEventSubTimestamps =
dialog._validateTimestamps->isChecked();
settings._warnIfInvalid = dialog._warnIfInvalid->isChecked();
if (settings._eventSub) {
settings._eventSub->EnableTimestampValidation(
settings._validateEventSubTimestamps);

View File

@@ -55,8 +55,6 @@ public:
std::shared_ptr<EventSub> GetEventSub();
bool ValidateTimestamps() const { return _validateEventSubTimestamps; }
bool IsValid(bool forceUpdate = false) const;
bool WarnIfInvalid() const { return _warnIfInvalid; }
void SetWarnIfInvalid(bool value) { _warnIfInvalid = value; }
size_t PermissionCount() const { return _tokenOptions.size(); }
private:
@@ -69,7 +67,6 @@ private:
std::set<TokenOption> _tokenOptions = TokenOption::GetAllTokenOptions();
std::shared_ptr<EventSub> _eventSub;
bool _validateEventSubTimestamps = false;
bool _warnIfInvalid = true;
static bool _setup;
@@ -134,7 +131,6 @@ private:
TwitchToken _currentToken;
std::unordered_map<std::string, QCheckBox *> _optionWidgets;
QCheckBox *_validateTimestamps;
QCheckBox *_warnIfInvalid;
QTimer _validationTimer;
};

View File

@@ -144,14 +144,9 @@ static void handleThrottling(const httplib::Result &response)
return;
}
if (sleepDuration < std::chrono::seconds(1)) {
sleepDuration = std::chrono::seconds(1);
}
blog(LOG_WARNING,
"Twitch API access is throttled for %lld milliseconds!",
blog(LOG_WARNING, "Twitch API access is throttled for %lld seconds!",
static_cast<long long int>(
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::duration_cast<std::chrono::seconds>(
sleepDuration)
.count()));
apiIsThrottling = true;

View File

@@ -1,47 +1,24 @@
#include "twitch-tab.hpp"
#include "obs-module-helper.hpp"
#include "plugin-state-helpers.hpp"
#include "sync-helpers.hpp"
#include "tab-helpers.hpp"
#include "token.hpp"
#include "ui-helpers.hpp"
#include <QDialogButtonBox>
#include <QTabWidget>
namespace advss {
static bool setup();
static bool registerTab();
static void setupTab(QTabWidget *);
static bool setupDone = setup();
static bool registerTabDone = registerTab();
static TwitchConnectionsTable *tabWidget = nullptr;
static QStringList getInvalidTokens();
static bool setup()
static bool registerTab()
{
AddSetupTabCallback("twitchConnectionTab",
TwitchConnectionsTable::Create, setupTab);
static const auto showInvalidWarnings = []() {
const auto invalidTokens = getInvalidTokens();
for (const auto &token : invalidTokens) {
QueueUITask(
[](void *tokenPtr) {
auto tokenName = static_cast<QString *>(
tokenPtr);
InvalidTokenDialog::ShowWarning(
*tokenName);
},
(void *)&token);
}
};
AddLoadStep([](obs_data_t *) {
AddPostLoadStep([]() { showInvalidWarnings(); });
});
return true;
}
@@ -211,25 +188,6 @@ static void updateConnectionStatus(QTableWidget *table)
}
}
static QStringList getInvalidTokens()
{
QStringList tokens;
for (const auto &t : GetTwitchTokens()) {
if (!t) {
continue;
}
auto token = std::static_pointer_cast<TwitchToken>(t);
if (!token->WarnIfInvalid() || token->IsValid(true)) {
continue;
}
tokens << QString::fromStdString(token->GetName());
}
return tokens;
}
static void setupTab(QTabWidget *tab)
{
if (GetTwitchTokens().empty()) {
@@ -264,63 +222,6 @@ static void setupTab(QTabWidget *tab)
updateConnectionStatus(tabWidget->Table());
}
});
const auto invalidTokens = getInvalidTokens();
for (const auto &token : invalidTokens) {
// Constructing the warning dialog in the constructor of the settings
// window might lead to a crash, so wait for the settings window
// constructor to complete
QTimer::singleShot(0, tab, [token]() {
InvalidTokenDialog::ShowWarning(token);
});
}
}
void InvalidTokenDialog::ShowWarning(const QString &tokenName)
{
auto weakToken = GetWeakTwitchTokenByQString(tokenName);
auto token = weakToken.lock();
if (!token) {
return;
}
auto dialog = new InvalidTokenDialog(tokenName);
dialog->setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle"));
const bool ignore = dialog->exec() != DialogCode::Accepted;
token->SetWarnIfInvalid(!dialog->_doNotShowAgain->isChecked());
dialog->deleteLater();
if (ignore) {
return;
}
TwitchTokenSettingsDialog::AskForSettings(GetSettingsWindow(),
*token.get());
}
InvalidTokenDialog::InvalidTokenDialog(const QString &name)
: QDialog(GetSettingsWindow()),
_doNotShowAgain(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.twitchToken.warnIfInvalid.doNotShowAgain")))
{
auto buttons = new QDialogButtonBox(QDialogButtonBox::Ignore |
QDialogButtonBox::Open);
connect(buttons->button(QDialogButtonBox::Ignore),
&QPushButton::clicked, this, &QDialog::reject);
connect(buttons->button(QDialogButtonBox::Open), &QPushButton::clicked,
this, &QDialog::accept);
buttons->setCenterButtons(true);
const QString format(obs_module_text(
"AdvSceneSwitcher.twitchToken.warnIfInvalid.message"));
const QString message = format.arg(name);
auto layout = new QVBoxLayout;
layout->addWidget(new QLabel(message));
layout->addWidget(_doNotShowAgain);
layout->addWidget(buttons);
setLayout(layout);
}
} // namespace advss

View File

@@ -1,9 +1,6 @@
#pragma once
#include "resource-table.hpp"
#include <QCheckBox>
#include <QDialog>
namespace advss {
class TwitchConnectionsTable final : public ResourceTable {
@@ -20,14 +17,4 @@ private:
TwitchConnectionsTable(QTabWidget *parent = nullptr);
};
class InvalidTokenDialog : public QDialog {
Q_OBJECT
public:
static void ShowWarning(const QString &name);
private:
InvalidTokenDialog(const QString &name);
QCheckBox *_doNotShowAgain;
};
} // namespace advss

View File

@@ -40,7 +40,7 @@ std::string GetThemeTypeName()
return "Dark";
}
void QueueUITask(void (*task)(void *param), void *) {}
void QeueUITask(void (*task)(void *param), void *) {}
QWidget *GetSettingsWindow()
{