From a901f59f0f982bc5980e3b38c16225fdff528496 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Sun, 18 Dec 2022 16:41:25 +0100 Subject: [PATCH] Add option to interact with source settings buttons --- data/locale/en-US.ini | 4 +- data/locale/es-ES.ini | 2 +- data/locale/tr-TR.ini | 2 +- data/locale/zh-CN.ini | 2 +- src/macro-core/macro-action-source.cpp | 114 ++++++++++++++++++++++++- src/macro-core/macro-action-source.hpp | 13 +++ 6 files changed, 130 insertions(+), 7 deletions(-) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index bc6b2c0b..3cd38c56 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -442,8 +442,10 @@ AdvSceneSwitcher.action.source.type.enable="Enable" AdvSceneSwitcher.action.source.type.disable="Disable" AdvSceneSwitcher.action.source.type.settings="Set settings" AdvSceneSwitcher.action.source.type.refreshSettings="Refresh source settings" +AdvSceneSwitcher.action.source.type.pressSettingsButton="Press settings button" AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="Can be used to refresh browser, media, etc. sources" -AdvSceneSwitcher.action.source.entry="{{actions}} {{sources}}" +AdvSceneSwitcher.action.source.noSettingsButtons="No buttons found!" +AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}" AdvSceneSwitcher.action.source.warning="Warning: Enabling and disabling sources globally cannot be controlled by the OBS UI" AdvSceneSwitcher.action.source.getSettings="Get current settings" AdvSceneSwitcher.action.media="Media" diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index 4c9ad0a1..ca2e52ce 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -382,7 +382,7 @@ AdvSceneSwitcher.action.source="Fuente" AdvSceneSwitcher.action.source.type.enable="Habilitar" AdvSceneSwitcher.action.source.type.disable="Deshabilitar" AdvSceneSwitcher.action.source.type.settings="Establecer configuración" -AdvSceneSwitcher.action.source.entry="{{actions}} {{sources}}" +AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}" AdvSceneSwitcher.action.source.warning="Advertencia: la IU de OBS no puede controlar la habilitación y deshabilitación global de fuentes" AdvSceneSwitcher.action.source.getSettings="Obtener la configuración actual" AdvSceneSwitcher.action.media="Medios" diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index 9874c276..1e78e292 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -312,7 +312,7 @@ AdvSceneSwitcher.action.source="Kaynak" AdvSceneSwitcher.action.source.type.enable="Etkin" AdvSceneSwitcher.action.source.type.disable="Etkisiz" AdvSceneSwitcher.action.source.type.settings="Ayarları yap" -AdvSceneSwitcher.action.source.entry="{{actions}} {{sources}}" +AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}" AdvSceneSwitcher.action.source.warning="Uyarı: Kaynakların global olarak etkinleştirilmesi ve devre dışı bırakılması, OBS UI tarafından kontrol edilemez" AdvSceneSwitcher.action.source.getSettings="Mevcut Ayarları yap" AdvSceneSwitcher.action.media="Medya" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 81d54c5c..99f3469b 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -428,7 +428,7 @@ AdvSceneSwitcher.action.source.type.disable="停用" AdvSceneSwitcher.action.source.type.settings="配置设置" AdvSceneSwitcher.action.source.type.refreshSettings="刷新源设置" AdvSceneSwitcher.action.source.type.refreshSettings.tooltip="可用于刷新浏览器、媒体等源" -AdvSceneSwitcher.action.source.entry="{{actions}} {{sources}}" +AdvSceneSwitcher.action.source.entry="{{actions}}{{sources}}{{settingsButtons}}" AdvSceneSwitcher.action.source.warning="警告:OBS UI无法控制全局启用和禁用源,注意,通过这个设置禁用,我测试,你必须通过这个在启用才行,不然点击小眼睛你无法显示!" AdvSceneSwitcher.action.source.getSettings="获取当前设置" AdvSceneSwitcher.action.media="媒体" diff --git a/src/macro-core/macro-action-source.cpp b/src/macro-core/macro-action-source.cpp index 4e1985df..53c2e847 100644 --- a/src/macro-core/macro-action-source.cpp +++ b/src/macro-core/macro-action-source.cpp @@ -2,6 +2,8 @@ #include "advanced-scene-switcher.hpp" #include "utility.hpp" +Q_DECLARE_METATYPE(SourceSettingButton); + const std::string MacroActionSource::id = "source"; bool MacroActionSource::_registered = MacroActionFactory::Register( @@ -16,9 +18,42 @@ const static std::map actionTypes = { "AdvSceneSwitcher.action.source.type.settings"}, {SourceAction::REFRESH_SETTINGS, "AdvSceneSwitcher.action.source.type.refreshSettings"}, + {SourceAction::SETTINGS_BUTTON, + "AdvSceneSwitcher.action.source.type.pressSettingsButton"}, }; -void refreshSourceSettings(obs_source_t *s) +static std::vector getSourceButtons(OBSWeakSource source) +{ + auto s = obs_weak_source_get_source(source); + std::vector buttons; + obs_properties_t *sourceProperties = obs_source_properties(s); + auto it = obs_properties_first(sourceProperties); + do { + if (!it || obs_property_get_type(it) != OBS_PROPERTY_BUTTON) { + continue; + } + SourceSettingButton button = {obs_property_name(it), + obs_property_description(it)}; + buttons.emplace_back(button); + } while (obs_property_next(&it)); + obs_source_release(s); + return buttons; +} + +static void pressSourceButton(const SourceSettingButton &button, + obs_source_t *source) +{ + obs_properties_t *sourceProperties = obs_source_properties(source); + obs_property_t *property = + obs_properties_get(sourceProperties, button.id.c_str()); + if (!obs_property_button_clicked(property, source)) { + blog(LOG_WARNING, "Failed to press settings button '%s' for %s", + button.id.c_str(), obs_source_get_name(source)); + } + obs_properties_destroy(sourceProperties); +} + +static void refreshSourceSettings(obs_source_t *s) { if (!s) { return; @@ -55,6 +90,9 @@ bool MacroActionSource::PerformAction() case SourceAction::REFRESH_SETTINGS: refreshSourceSettings(s); break; + case SourceAction::SETTINGS_BUTTON: + pressSourceButton(_button, s); + break; default: break; } @@ -80,6 +118,7 @@ bool MacroActionSource::Save(obs_data_t *obj) obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str()); obs_data_set_int(obj, "action", static_cast(_action)); obs_data_set_string(obj, "settings", _settings.c_str()); + _button.Save(obj); return true; } @@ -90,6 +129,7 @@ bool MacroActionSource::Load(obs_data_t *obj) _source = GetWeakSourceByName(sourceName); _action = static_cast(obs_data_get_int(obj, "action")); _settings = obs_data_get_string(obj, "settings"); + _button.Load(obj); return true; } @@ -115,12 +155,30 @@ static inline void populateActionSelection(QComboBox *list) } } +static inline void populateSourceButtonSelection(QComboBox *list, + OBSWeakSource source) +{ + list->clear(); + auto buttons = getSourceButtons(source); + if (buttons.empty()) { + list->addItem(obs_module_text( + "AdvSceneSwitcher.action.source.noSettingsButtons")); + } + + for (const auto &button : buttons) { + QVariant value; + value.setValue(button); + list->addItem(QString::fromStdString(button.ToString()), value); + } +} + MacroActionSourceEdit::MacroActionSourceEdit( QWidget *parent, std::shared_ptr entryData) : QWidget(parent) { _sources = new QComboBox(); _actions = new QComboBox(); + _settingsButtons = new QComboBox(); _getSettings = new QPushButton( obs_module_text("AdvSceneSwitcher.action.source.getSettings")); _settings = new ResizingPlainTextEdit(this); @@ -132,6 +190,8 @@ MacroActionSourceEdit::MacroActionSourceEdit( QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, SLOT(ActionChanged(int))); + QWidget::connect(_settingsButtons, SIGNAL(currentIndexChanged(int)), + this, SLOT(ButtonChanged(int))); QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)), this, SLOT(SourceChanged(const QString &))); QWidget::connect(_getSettings, SIGNAL(clicked()), this, @@ -147,6 +207,7 @@ MacroActionSourceEdit::MacroActionSourceEdit( {"{{actions}}", _actions}, {"{{settings}}", _settings}, {"{{getSettings}}", _getSettings}, + {"{{settingsButtons}}", _settingsButtons}, }; placeWidgets(obs_module_text("AdvSceneSwitcher.action.source.entry"), entryLayout, widgetPlaceholders); @@ -169,10 +230,14 @@ void MacroActionSourceEdit::UpdateEntryData() return; } + populateSourceButtonSelection(_settingsButtons, _entryData->_source); + _actions->setCurrentIndex(static_cast(_entryData->_action)); _sources->setCurrentText( GetWeakSourceName(_entryData->_source).c_str()); _settings->setPlainText(QString::fromStdString(_entryData->_settings)); + _settingsButtons->setCurrentText( + QString::fromStdString(_entryData->_button.ToString())); SetWidgetVisibility(); adjustSize(); @@ -185,8 +250,11 @@ void MacroActionSourceEdit::SourceChanged(const QString &text) return; } - std::lock_guard lock(switcher->m); - _entryData->_source = GetWeakSourceByQString(text); + { + std::lock_guard lock(switcher->m); + _entryData->_source = GetWeakSourceByQString(text); + } + populateSourceButtonSelection(_settingsButtons, _entryData->_source); emit HeaderInfoChanged( QString::fromStdString(_entryData->GetShortDesc())); } @@ -202,6 +270,17 @@ void MacroActionSourceEdit::ActionChanged(int value) SetWidgetVisibility(); } +void MacroActionSourceEdit::ButtonChanged(int idx) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_button = qvariant_cast( + _settingsButtons->itemData(idx)); +} + void MacroActionSourceEdit::GetSettingsClicked() { if (_loading || !_entryData || !_entryData->_source) { @@ -233,5 +312,34 @@ void MacroActionSourceEdit::SetWidgetVisibility() _settings->setVisible(showSettings); _getSettings->setVisible(showSettings); _warning->setVisible(showWarning); + _settingsButtons->setVisible(_entryData->_action == + SourceAction::SETTINGS_BUTTON); adjustSize(); } + +bool SourceSettingButton::Save(obs_data_t *obj) const +{ + auto data = obs_data_create(); + obs_data_set_string(data, "id", id.c_str()); + obs_data_set_string(data, "description", description.c_str()); + obs_data_set_obj(obj, "sourceSettingButton", data); + obs_data_release(data); + return true; +} + +bool SourceSettingButton::Load(obs_data_t *obj) +{ + auto data = obs_data_get_obj(obj, "sourceSettingButton"); + id = obs_data_get_string(data, "id"); + description = obs_data_get_string(data, "description"); + obs_data_release(data); + return true; +} + +std::string SourceSettingButton::ToString() const +{ + if (id.empty()) { + return ""; + } + return "[" + id + "] " + description; +} diff --git a/src/macro-core/macro-action-source.hpp b/src/macro-core/macro-action-source.hpp index ed599348..a24808a1 100644 --- a/src/macro-core/macro-action-source.hpp +++ b/src/macro-core/macro-action-source.hpp @@ -12,6 +12,16 @@ enum class SourceAction { DISABLE, SETTINGS, REFRESH_SETTINGS, + SETTINGS_BUTTON, +}; + +struct SourceSettingButton { + bool Save(obs_data_t *obj) const; + bool Load(obs_data_t *obj); + std::string ToString() const; + + std::string id = ""; + std::string description = ""; }; class MacroActionSource : public MacroAction { @@ -30,6 +40,7 @@ public: OBSWeakSource _source; std::string _settings = ""; + SourceSettingButton _button; SourceAction _action = SourceAction::ENABLE; private: @@ -56,6 +67,7 @@ public: private slots: void SourceChanged(const QString &text); void ActionChanged(int value); + void ButtonChanged(int idx); void GetSettingsClicked(); void SettingsChanged(); signals: @@ -64,6 +76,7 @@ signals: protected: QComboBox *_sources; QComboBox *_actions; + QComboBox *_settingsButtons; QPushButton *_getSettings; ResizingPlainTextEdit *_settings; QLabel *_warning;