diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 9ffc42f0..cad3b4f3 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -1410,6 +1410,7 @@ AdvSceneSwitcher.action.variable.layout.truncate="{{actions}}of{{variables}}to l AdvSceneSwitcher.action.variable.layout.substringIndex="Substring start:{{subStringStart}}Substring size:{{subStringSize}}{{subStringRegex}}" AdvSceneSwitcher.action.variable.layout.substringRegex="Assign value of{{regexMatchIdx}}match using regular expression:{{subStringRegex}}" AdvSceneSwitcher.action.variable.layout.findAndReplace="{{findStr}}{{findRegex}}{{replaceStr}}" +AdvSceneSwitcher.action.variable.layout.userInput.type="Input type:{{inputType}}" AdvSceneSwitcher.action.variable.layout.userInput.customPrompt="{{useCustomPrompt}}Use custom prompt{{inputPrompt}}" AdvSceneSwitcher.action.variable.layout.userInput.placeholder="{{useInputPlaceholder}}Fill with placeholder{{inputPlaceholder}}" AdvSceneSwitcher.action.variable.layout.randomNumber="Generate random number in range from{{randomNumberStart}}to{{randomNumberEnd}}" diff --git a/lib/macro/macro-action-variable.cpp b/lib/macro/macro-action-variable.cpp index 0b110e7a..4bcdd308 100644 --- a/lib/macro/macro-action-variable.cpp +++ b/lib/macro/macro-action-variable.cpp @@ -266,11 +266,16 @@ void MacroActionVariable::PickRandomValue(Variable *var) } struct AskForInputParams { - AskForInputParams(const QString &prompt_, const QString &placeholder_) + AskForInputParams(const QString &prompt_, const QString &placeholder_, + ValueInputType type_, const QStringList &options_) : prompt(prompt_), - placeholder(placeholder_){}; + placeholder(placeholder_), + type(type_), + options(options_){}; QString prompt; QString placeholder; + ValueInputType type; + QStringList options; std::optional result; std::atomic_bool resultReady = {false}; }; @@ -279,9 +284,18 @@ static void askForInput(void *param) { auto parameters = *static_cast *>(param); - auto dialog = new NonModalMessageDialog( - parameters->prompt, NonModalMessageDialog::Type::INPUT, false); - dialog->SetInput(parameters->placeholder); + NonModalMessageDialog *dialog = nullptr; + if (parameters->type == ValueInputType::String) { + dialog = new NonModalMessageDialog( + parameters->prompt, NonModalMessageDialog::Type::INPUT, + false); + dialog->SetInput(parameters->placeholder); + } else { + dialog = new NonModalMessageDialog( + parameters->prompt, parameters->type, + parameters->placeholder.toStdString(), + parameters->options); + } parameters->result = dialog->GetInput(); parameters->resultReady = true; } @@ -395,6 +409,10 @@ bool MacroActionVariable::PerformAction() return true; } case Action::USER_INPUT: { + QStringList options; + for (const auto &option : _inputOptions) { + options << QString::fromStdString(option); + } auto params = std::make_shared( _useCustomPrompt ? QString::fromStdString(_inputPrompt) @@ -404,7 +422,8 @@ bool MacroActionVariable::PerformAction() var->Name())), _useCustomPrompt && _useInputPlaceholder ? QString::fromStdString(_inputPlaceholder) - : ""); + : "", + _inputType, options); obs_queue_task(OBS_TASK_UI, askForInput, ¶ms, false); while (!params->resultReady) { if (GetMacro()->GetStop()) { @@ -548,6 +567,8 @@ bool MacroActionVariable::Save(obs_data_t *obj) const _inputPrompt.Save(obj, "inputPrompt"); obs_data_set_bool(obj, "useInputPlaceholder", _useInputPlaceholder); _inputPlaceholder.Save(obj, "inputPlaceholder"); + obs_data_set_int(obj, "inputType", static_cast(_inputType)); + _inputOptions.Save(obj, "inputOptions", "value"); _envVariableName.Save(obj, "environmentVariableName"); _scene.Save(obj); _tempVar.Save(obj, GetMacro()); @@ -591,6 +612,11 @@ bool MacroActionVariable::Load(obs_data_t *obj) _inputPrompt.Load(obj, "inputPrompt"); _useInputPlaceholder = obs_data_get_bool(obj, "useInputPlaceholder"); _inputPlaceholder.Load(obj, "inputPlaceholder"); + obs_data_set_default_int(obj, "inputType", + static_cast(ValueInputType::String)); + _inputType = + static_cast(obs_data_get_int(obj, "inputType")); + _inputOptions.Load(obj, "inputOptions", "value"); _envVariableName.Load(obj, "environmentVariableName"); _scene.Load(obj); _tempVar.Load(obj, GetMacro()); @@ -723,6 +749,7 @@ void MacroActionVariable::ResolveVariablesToFixedValues() _mathExpression.ResolveVariables(); _inputPrompt.ResolveVariables(); _inputPlaceholder.ResolveVariables(); + _inputOptions.ResolveVariables(); _envVariableName.ResolveVariables(); _scene.ResolveVariables(); _sceneItemIndex.ResolveVariables(); @@ -890,6 +917,9 @@ MacroActionVariableEdit::MacroActionVariableEdit( _placeholderLayout(new QHBoxLayout()), _useInputPlaceholder(new QCheckBox()), _inputPlaceholder(new VariableLineEdit(this)), + _inputTypeLayout(new QHBoxLayout()), + _inputType(new QComboBox(this)), + _inputOptions(new StringListEdit(this)), _envVariable(new VariableLineEdit(this)), _scenes(new SceneSelectionWidget(this, true, false, true, true, true)), @@ -954,11 +984,13 @@ MacroActionVariableEdit::MacroActionVariableEdit( populateActionSelection(_actions); populateDirectionSelection(_direction); populateCaseTypeSelection(_caseType); + PopulateValueInputTypeSelection(_inputType); _randomNumberStart->setMinimum(-9999999999); _randomNumberStart->setMaximum(9999999999); _randomNumberEnd->setMinimum(-9999999999); _randomNumberEnd->setMaximum(9999999999); _randomValues->SetMaxStringSize(99999999); + _inputOptions->SetMaxStringSize(99999999); _jsonIndex->setMaximum(999); auto jsonExtractSingleLayout = new QHBoxLayout(); jsonExtractSingleLayout->addWidget(_jsonExtractSingle); @@ -1018,6 +1050,11 @@ MacroActionVariableEdit::MacroActionVariableEdit( SLOT(UseInputPlaceholderChanged(int))); QWidget::connect(_inputPlaceholder, SIGNAL(editingFinished()), this, SLOT(InputPlaceholderChanged())); + QWidget::connect(_inputType, SIGNAL(currentIndexChanged(int)), this, + SLOT(InputTypeChanged(int))); + QWidget::connect(_inputOptions, + SIGNAL(StringListChanged(const StringList &)), this, + SLOT(InputOptionsChanged(const StringList &))); QWidget::connect(_envVariable, SIGNAL(editingFinished()), this, SLOT(EnvVariableChanged())); QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)), @@ -1081,6 +1118,7 @@ MacroActionVariableEdit::MacroActionVariableEdit( {"{{inputPrompt}}", _inputPrompt}, {"{{useInputPlaceholder}}", _useInputPlaceholder}, {"{{inputPlaceholder}}", _inputPlaceholder}, + {"{{inputType}}", _inputType}, {"{{envVariableName}}", _envVariable}, {"{{scenes}}", _scenes}, {"{{tempVars}}", _tempVars}, @@ -1111,6 +1149,10 @@ MacroActionVariableEdit::MacroActionVariableEdit( "AdvSceneSwitcher.action.variable.layout.findAndReplace"), _findReplaceLayout, widgetPlaceholders, false); + PlaceWidgets( + obs_module_text( + "AdvSceneSwitcher.action.variable.layout.userInput.type"), + _inputTypeLayout, widgetPlaceholders); PlaceWidgets( obs_module_text( "AdvSceneSwitcher.action.variable.layout.userInput.customPrompt"), @@ -1147,6 +1189,8 @@ MacroActionVariableEdit::MacroActionVariableEdit( layout->addWidget(_segmentValue); layout->addLayout(_findReplaceLayout); layout->addWidget(_mathExpressionResult); + layout->addLayout(_inputTypeLayout); + layout->addWidget(_inputOptions); layout->addLayout(_promptLayout); layout->addLayout(_placeholderLayout); layout->addLayout(_randomNumberLayout); @@ -1196,6 +1240,9 @@ void MacroActionVariableEdit::UpdateEntryData() _inputPrompt->setText(_entryData->_inputPrompt); _useInputPlaceholder->setChecked(_entryData->_useInputPlaceholder); _inputPlaceholder->setText(_entryData->_inputPlaceholder); + _inputType->setCurrentIndex( + _inputType->findData(static_cast(_entryData->_inputType))); + _inputOptions->SetStringList(_entryData->_inputOptions); _envVariable->setText(_entryData->_envVariableName); _scenes->SetScene(_entryData->_scene); _tempVars->SetVariable(_entryData->_tempVar); @@ -1477,6 +1524,20 @@ void MacroActionVariableEdit::InputPlaceholderChanged() _entryData->_inputPlaceholder = _inputPlaceholder->text().toStdString(); } +void MacroActionVariableEdit::InputTypeChanged(int) +{ + GUARD_LOADING_AND_LOCK(); + _entryData->_inputType = + static_cast(_inputType->currentData().toInt()); + SetWidgetVisibility(); +} + +void MacroActionVariableEdit::InputOptionsChanged(const StringList &options) +{ + GUARD_LOADING_AND_LOCK(); + _entryData->_inputOptions = options; +} + void MacroActionVariableEdit::EnvVariableChanged() { GUARD_LOADING_AND_LOCK(); @@ -1714,6 +1775,13 @@ void MacroActionVariableEdit::SetWidgetVisibility() _entryData->_action == MacroActionVariable::Action::MATH_EXPRESSION); _mathExpressionResult->hide(); + SetLayoutVisible(_inputTypeLayout, + _entryData->_action == + MacroActionVariable::Action::USER_INPUT); + _inputOptions->setVisible( + _entryData->_action == + MacroActionVariable::Action::USER_INPUT && + _entryData->_inputType == ValueInputType::Selection); SetLayoutVisible(_promptLayout, _entryData->_action == MacroActionVariable::Action::USER_INPUT); diff --git a/lib/macro/macro-action-variable.hpp b/lib/macro/macro-action-variable.hpp index b68ae3be..ce91fd70 100644 --- a/lib/macro/macro-action-variable.hpp +++ b/lib/macro/macro-action-variable.hpp @@ -7,6 +7,7 @@ #include "scene-selection.hpp" #include "single-char-selection.hpp" #include "string-list.hpp" +#include "value-input.hpp" #include "variable-line-edit.hpp" #include "variable-text-edit.hpp" #include "variable-spinbox.hpp" @@ -84,6 +85,8 @@ public: bool _useInputPlaceholder = false; StringVariable _inputPlaceholder = obs_module_text("AdvSceneSwitcher.enterText"); + ValueInputType _inputType = ValueInputType::String; + StringList _inputOptions = {"value1", "value2", "value3"}; #ifdef _WIN32 StringVariable _envVariableName = "USERPROFILE"; #else @@ -173,6 +176,8 @@ private slots: void InputPromptChanged(); void UseInputPlaceholderChanged(int); void InputPlaceholderChanged(); + void InputTypeChanged(int); + void InputOptionsChanged(const StringList &); void EnvVariableChanged(); void SceneChanged(const SceneSelection &); void SelectionChanged(const TempVariableRef &var); @@ -224,6 +229,9 @@ private: QHBoxLayout *_placeholderLayout; QCheckBox *_useInputPlaceholder; VariableLineEdit *_inputPlaceholder; + QHBoxLayout *_inputTypeLayout; + QComboBox *_inputType; + StringListEdit *_inputOptions; VariableLineEdit *_envVariable; SceneSelectionWidget *_scenes; TempVariableSelection *_tempVars; diff --git a/lib/utils/non-modal-dialog.cpp b/lib/utils/non-modal-dialog.cpp index 8f0df6f8..af96d1e1 100644 --- a/lib/utils/non-modal-dialog.cpp +++ b/lib/utils/non-modal-dialog.cpp @@ -23,6 +23,19 @@ NonModalMessageDialog::NonModalMessageDialog(const QString &message, { } +NonModalMessageDialog::NonModalMessageDialog(const QString &message, + ValueInputType inputType, + const std::string &defaultValue, + const QStringList &options) + : NonModalMessageDialog(message, Type::INPUT) +{ + _valueInput = + new ValueInputWidget(inputType, defaultValue, options, this); + layout()->replaceWidget(_inputEdit, _valueInput); + delete _inputEdit; + _inputEdit = nullptr; +} + NonModalMessageDialog::~NonModalMessageDialog() { std::lock_guard lock(mutex); @@ -101,16 +114,21 @@ std::optional NonModalMessageDialog::GetInput() { show(); - // Trigger resize - _inputEdit->setPlainText(_inputEdit->toPlainText()); + if (_inputEdit) { + // Trigger resize + _inputEdit->setPlainText(_inputEdit->toPlainText()); + } exec(); deleteLater(); - if (_answer == QMessageBox::Yes) { - return _input.toStdString(); + if (_answer != QMessageBox::Yes) { + return {}; } - return {}; + if (_valueInput) { + return _valueInput->Value(); + } + return _input.toStdString(); } void NonModalMessageDialog::SetInput(const QString &input) diff --git a/lib/utils/non-modal-dialog.hpp b/lib/utils/non-modal-dialog.hpp index c057b27b..5e927b2b 100644 --- a/lib/utils/non-modal-dialog.hpp +++ b/lib/utils/non-modal-dialog.hpp @@ -1,5 +1,6 @@ #pragma once #include "resizing-text-edit.hpp" +#include "value-input.hpp" #include #include @@ -19,6 +20,9 @@ public: bool focusAdvssWindow = false); NonModalMessageDialog(const QString &message, bool question, bool focusAdvssWindow = false); + NonModalMessageDialog(const QString &message, ValueInputType inputType, + const std::string &defaultValue, + const QStringList &options); ~NonModalMessageDialog(); QMessageBox::StandardButton ShowMessage(); std::optional GetInput(); @@ -34,6 +38,7 @@ private: const Type _type; QString _input = ""; ResizingPlainTextEdit *_inputEdit = nullptr; + ValueInputWidget *_valueInput = nullptr; QMessageBox::StandardButton _answer; };