From 269140324c68a26672e9bfb80bef9c346789358d Mon Sep 17 00:00:00 2001 From: casey langen Date: Fri, 22 Jun 2018 13:26:00 -0700 Subject: [PATCH] Added min/max value bounding for int and double schema types. --- src/core/sdk/ISchema.h | 24 +++++++- src/musikcube/app/overlay/PluginOverlay.cpp | 63 +++++++++++++++------ src/musikcube/data/locales/en_US.json | 4 +- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/core/sdk/ISchema.h b/src/core/sdk/ISchema.h index fae2e2d08..e9355e88a 100644 --- a/src/core/sdk/ISchema.h +++ b/src/core/sdk/ISchema.h @@ -35,6 +35,8 @@ #pragma once #include +#include +#include #include #include #include @@ -59,11 +61,15 @@ namespace musik { namespace core { namespace sdk { struct IntEntry { Entry entry; + int minValue; + int maxValue; int defaultValue; }; struct DoubleEntry { Entry entry; + double minValue; + double maxValue; double defaultValue; }; @@ -130,20 +136,34 @@ namespace musik { namespace core { namespace sdk { return *this; } - TSchema& AddInt(const std::string& name, int defaultValue) { + TSchema& AddInt( + const std::string& name, + int defaultValue, + int min = INT_MIN, + int max = INT_MAX) + { auto entry = new IntEntry(); entry->entry.type = ISchema::Type::Int; entry->entry.name = AllocString(name); entry->defaultValue = defaultValue; + entry->minValue = min; + entry->maxValue = max; entries.push_back(reinterpret_cast(entry)); return *this; } - TSchema& AddDouble(const std::string& name, double defaultValue) { + TSchema& AddDouble( + const std::string& name, + double defaultValue, + double min = DBL_MIN, + double max = DBL_MAX) + { auto entry = new DoubleEntry(); entry->entry.type = ISchema::Type::Double; entry->entry.name = AllocString(name); entry->defaultValue = defaultValue; + entry->minValue = min; + entry->maxValue = max; entries.push_back(reinterpret_cast(entry)); return *this; } diff --git a/src/musikcube/app/overlay/PluginOverlay.cpp b/src/musikcube/app/overlay/PluginOverlay.cpp index f517608b3..cf11555c5 100644 --- a/src/musikcube/app/overlay/PluginOverlay.cpp +++ b/src/musikcube/app/overlay/PluginOverlay.cpp @@ -53,6 +53,7 @@ #include #include +#include using namespace musik::core; using namespace musik::core::sdk; @@ -192,28 +193,45 @@ class SchemaAdapter: public ScrollAdapterBase { } private: - struct IntValidator : public InputOverlay::IValidator { + template + struct NumberValidator : public InputOverlay::IValidator { + using Formatter = std::function; + + NumberValidator(T minimum, T maximum, Formatter formatter) + : minimum(minimum), maximum(maximum), formatter(formatter) { + } + virtual bool IsValid(const std::string& input) const override { - try { std::stoi(input); } - catch (std::invalid_argument) { return false; } + try { + int result = std::stoi(input); + if (bounded() && (result < minimum || result > maximum)) { + return false; + } + } + catch (std::invalid_argument) { + return false; + } return true; } virtual const std::string ErrorMessage() const { - return _TSTR("validator_dialog_int_parse_error"); - } - }; - - struct DoubleValidator : public InputOverlay::IValidator { - virtual bool IsValid(const std::string& input) const override { - try { std::stod(input); } - catch (std::invalid_argument) { return false; } - return true; + if (bounded()) { + std::string result = _TSTR("validator_dialog_number_parse_bounded_error"); + ReplaceAll(result, "{{minimum}}", formatter(minimum)); + ReplaceAll(result, "{{maximum}}", formatter(maximum)); + return result; + } + return _TSTR("validator_dialog_number_parse_error"); } - virtual const std::string ErrorMessage() const { - return _TSTR("validator_dialog_double_parse_error"); + bool bounded() const { + return + minimum != std::numeric_limits::min() && + maximum != std::numeric_limits::max(); } + + Formatter formatter; + T minimum, maximum; }; void ShowListOverlay( @@ -263,10 +281,17 @@ class SchemaAdapter: public ScrollAdapterBase { void ShowIntOverlay(const ISchema::IntEntry* entry) { auto name = entry->entry.name; + + auto validator = std::make_shared>( + entry->minValue, entry->maxValue, [](int value) -> std::string { + return std::to_string(value); + }); + std::shared_ptr dialog(new InputOverlay()); + dialog->SetTitle(name) .SetText(stringValueFor(prefs, entry)) - .SetValidator(std::make_shared()) + .SetValidator(validator) .SetInputAcceptedCallback([this, name](const std::string& value) { this->prefs->SetInt(name, std::stoi(value)); this->changed = true; @@ -276,10 +301,16 @@ class SchemaAdapter: public ScrollAdapterBase { void ShowDoubleOverlay(const ISchema::DoubleEntry* entry) { auto name = entry->entry.name; + + auto validator = std::make_shared>( + entry->minValue, entry->maxValue, [](double value) -> std::string { + return stringValueForDouble(value); + }); + std::shared_ptr dialog(new InputOverlay()); dialog->SetTitle(name) .SetText(stringValueFor(prefs, entry)) - .SetValidator(std::make_shared()) + .SetValidator(validator) .SetInputAcceptedCallback([this, name](const std::string& value) { this->prefs->SetDouble(name, std::stod(value)); this->changed = true; diff --git a/src/musikcube/data/locales/en_US.json b/src/musikcube/data/locales/en_US.json index 69b7064ec..690f8a348 100644 --- a/src/musikcube/data/locales/en_US.json +++ b/src/musikcube/data/locales/en_US.json @@ -118,8 +118,8 @@ "settings_no_plugin_config_message": "plugin \"{{name}}\" does not provide any configurable settings.", "validator_dialog_title": "validation error", - "validator_dialog_int_parse_error": "please enter a number to continue", - "validator_dialog_double_parse_error": "please enter a number to continue", + "validator_dialog_number_parse_bounded_error": "please enter a number between {{minimum}} and {{maximum}} to continue.", + "validator_dialog_number_parse_error": "please enter a number to continue.", "track_filter_title": "track filter results",