diff --git a/CMakeLists.txt b/CMakeLists.txt index 969abb2b6..4699a6b75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,8 @@ target_sources( src/macro-core/macro-action-wait.hpp src/macro-core/macro-action-websocket.cpp src/macro-core/macro-action-websocket.hpp + src/macro-core/macro-action-widget.cpp + src/macro-core/macro-action-widget.hpp src/macro-core/macro-action.cpp src/macro-core/macro-action.hpp src/macro-core/macro-condition-audio.cpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 840755859..9e5ca2a5c 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -824,6 +824,11 @@ AdvSceneSwitcher.action.twitch.announcement.blue="Blue" AdvSceneSwitcher.action.twitch.announcement.green="Green" AdvSceneSwitcher.action.twitch.announcement.orange="Orange" AdvSceneSwitcher.action.twitch.announcement.purple="Purple" +AdvSceneSwitcher.action.widget="Widget" +AdvSceneSwitcher.action.widget.type.messageDialog="Display message popup" +AdvSceneSwitcher.action.widget.type.errorDialog="Display error popup" +AdvSceneSwitcher.action.widget.messageDialog.message="Enter message" +AdvSceneSwitcher.action.widget.errorDialog.errorMessage="Enter error message" ; Hotkey AdvSceneSwitcher.hotkey.startSwitcherHotkey="Start the Advanced Scene Switcher" diff --git a/src/macro-core/macro-action-widget.cpp b/src/macro-core/macro-action-widget.cpp new file mode 100644 index 000000000..33bd2b57b --- /dev/null +++ b/src/macro-core/macro-action-widget.cpp @@ -0,0 +1,176 @@ +#include "macro-action-widget.hpp" + +#include +#include + +namespace advss { + +const std::string MacroActionWidget::id = "widget"; + +bool MacroActionWidget::_registered = MacroActionFactory::Register( + MacroActionWidget::id, + {MacroActionWidget::Create, MacroActionWidgetEdit::Create, + "AdvSceneSwitcher.action.widget"}); + +const static std::map actionTypes = { + {MacroActionWidget::Action::MESSAGE_DIALOG, + "AdvSceneSwitcher.action.widget.type.messageDialog"}, + {MacroActionWidget::Action::ERROR_DIALOG, + "AdvSceneSwitcher.action.widget.type.errorDialog"}, +}; + +bool MacroActionWidget::PerformAction() +{ + switch (_action) { + case MacroActionWidget::Action::MESSAGE_DIALOG: + DisplayMessageDialog(); + break; + case MacroActionWidget::Action::ERROR_DIALOG: + DisplayErrorDialog(); + break; + default: + break; + } + + return true; +} + +void MacroActionWidget::DisplayMessageDialog() const +{ + auto message = std::string(_message); + + if (message.empty()) { + blog(LOG_WARNING, "No message for popup provided."); + } + + DisplayMessage(message.c_str()); +} + +void MacroActionWidget::DisplayErrorDialog() const +{ + auto errorMessage = std::string(_errorMessage); + + if (errorMessage.empty()) { + blog(LOG_WARNING, "No error message for popup provided."); + } + + DisplayErrorMessage(errorMessage.c_str()); +} + +bool MacroActionWidget::Save(obs_data_t *obj) const +{ + MacroAction::Save(obj); + obs_data_set_int(obj, "action", static_cast(_action)); + _message.Save(obj, "message"); + _errorMessage.Save(obj, "errorMessage"); + + return true; +} + +bool MacroActionWidget::Load(obs_data_t *obj) +{ + MacroAction::Load(obj); + _action = static_cast(obs_data_get_int(obj, "action")); + _message.Load(obj, "message"); + _errorMessage.Load(obj, "errorMessage"); + + return true; +} + +static inline void populateActionSelection(QComboBox *list) +{ + for (const auto &[_, name] : actionTypes) { + list->addItem(obs_module_text(name.c_str())); + } +} + +MacroActionWidgetEdit::MacroActionWidgetEdit( + QWidget *parent, std::shared_ptr entryData) + : QWidget(parent), + _actions(new QComboBox()), + _message(new VariableTextEdit(this)), + _errorMessage(new VariableTextEdit(this)) +{ + populateActionSelection(_actions); + + QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, + SLOT(ActionChanged(int))); + QWidget::connect(_message, SIGNAL(textChanged()), this, + SLOT(MessageChanged())); + QWidget::connect(_errorMessage, SIGNAL(textChanged()), this, + SLOT(ErrorMessageChanged())); + + auto mainLayout = new QVBoxLayout(); + mainLayout->addWidget(_actions); + mainLayout->addWidget(_message); + mainLayout->addWidget(_errorMessage); + setLayout(mainLayout); + + _entryData = entryData; + UpdateEntryData(); + _loading = false; +} + +void MacroActionWidgetEdit::ActionChanged(int value) +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_action = static_cast(value); + + SetupWidgetVisibility(); +} + +void MacroActionWidgetEdit::MessageChanged() +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_message = _message->toPlainText().toStdString(); + + adjustSize(); + updateGeometry(); +} + +void MacroActionWidgetEdit::ErrorMessageChanged() +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_errorMessage = _errorMessage->toPlainText().toStdString(); + + adjustSize(); + updateGeometry(); +} + +void MacroActionWidgetEdit::SetupWidgetVisibility() +{ + _message->setVisible(_entryData->_action == + MacroActionWidget::Action::MESSAGE_DIALOG); + _errorMessage->setVisible(_entryData->_action == + MacroActionWidget::Action::ERROR_DIALOG); + + adjustSize(); + updateGeometry(); +} + +void MacroActionWidgetEdit::UpdateEntryData() +{ + if (!_entryData) { + return; + } + + _actions->setCurrentIndex(static_cast(_entryData->_action)); + _message->setPlainText(_entryData->_message); + _errorMessage->setPlainText(_entryData->_errorMessage); + + SetupWidgetVisibility(); +} + +} // namespace advss diff --git a/src/macro-core/macro-action-widget.hpp b/src/macro-core/macro-action-widget.hpp new file mode 100644 index 000000000..330fb59b2 --- /dev/null +++ b/src/macro-core/macro-action-widget.hpp @@ -0,0 +1,73 @@ +#pragma once +#include "macro-action-edit.hpp" + +#include + +namespace advss { + +class MacroActionWidget : public MacroAction { +public: + MacroActionWidget(Macro *m) : MacroAction(m) {} + static std::shared_ptr Create(Macro *m) + { + return std::make_shared(m); + } + bool PerformAction(); + bool Save(obs_data_t *obj) const; + bool Load(obs_data_t *obj); + std::string GetId() const { return id; }; + + enum class Action { + MESSAGE_DIALOG, + ERROR_DIALOG, + }; + + Action _action = Action::MESSAGE_DIALOG; + StringVariable _message = obs_module_text( + "AdvSceneSwitcher.action.widget.messageDialog.message"); + StringVariable _errorMessage = obs_module_text( + "AdvSceneSwitcher.action.widget.errorDialog.errorMessage"); + +private: + static bool _registered; + static const std::string id; + + void DisplayMessageDialog() const; + void DisplayErrorDialog() const; +}; + +class MacroActionWidgetEdit : public QWidget { + Q_OBJECT + +public: + MacroActionWidgetEdit( + QWidget *parent, + std::shared_ptr entryData = nullptr); + static QWidget *Create(QWidget *parent, + std::shared_ptr action) + { + return new MacroActionWidgetEdit( + parent, + std::dynamic_pointer_cast(action)); + } + void UpdateEntryData(); + +protected: + std::shared_ptr _entryData; + +private slots: + void ActionChanged(int); + void MessageChanged(); + void ErrorMessageChanged(); + +private: + void SetupWidgetVisibility(); + + bool _loading = true; + + QComboBox *_actions; + VariableTextEdit *_message; + VariableTextEdit *_errorMessage; +}; + +} // namespace advss diff --git a/src/macro-external/twitch/macro-action-twitch.cpp b/src/macro-external/twitch/macro-action-twitch.cpp index d40dfaf8e..e053b5093 100644 --- a/src/macro-external/twitch/macro-action-twitch.cpp +++ b/src/macro-external/twitch/macro-action-twitch.cpp @@ -375,8 +375,6 @@ MacroActionTwitchEdit::MacroActionTwitchEdit( _markerDescription->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); _markerDescription->setMaxLength(140); - _announcementMessage->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::Preferred); _announcementMessage->setMaxLength(500); auto spinBox = _duration->SpinBox(); diff --git a/src/utils/utility.cpp b/src/utils/utility.cpp index 934e583e7..26b86bf70 100644 --- a/src/utils/utility.cpp +++ b/src/utils/utility.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -543,10 +544,18 @@ bool DisplayMessage(const QString &msg, bool question, bool modal) QMessageBox Msgbox; Msgbox.setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle")); Msgbox.setText(msg); + Msgbox.setTextInteractionFlags(Qt::TextBrowserInteraction); Msgbox.exec(); return false; } +void DisplayErrorMessage(const QString &msg) +{ + QErrorMessage dialog; + dialog.showMessage(msg); + dialog.exec(); +} + void DisplayTrayMessage(const QString &title, const QString &msg, const QIcon &icon) { diff --git a/src/utils/utility.hpp b/src/utils/utility.hpp index 1ac319a39..24f0cfcd1 100644 --- a/src/utils/utility.hpp +++ b/src/utils/utility.hpp @@ -107,6 +107,7 @@ int FindIdxInRagne(QComboBox *list, int start, int stop, bool DisplayMessage(const QString &msg, bool question = false, bool modal = true); +void DisplayErrorMessage(const QString &msg); void DisplayTrayMessage(const QString &title, const QString &msg, const QIcon &icon = QIcon()); bool WindowPosValid(QPoint pos);