Added min/max value bounding for int and double schema types.

This commit is contained in:
casey langen 2018-06-22 13:26:00 -07:00
parent e71ca2f70f
commit 269140324c
3 changed files with 71 additions and 20 deletions

View File

@ -35,6 +35,8 @@
#pragma once
#include <stddef.h>
#include <float.h>
#include <climits>
#include <vector>
#include <memory>
#include <string>
@ -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*>(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*>(entry));
return *this;
}

View File

@ -53,6 +53,7 @@
#include <ostream>
#include <iomanip>
#include <limits>
using namespace musik::core;
using namespace musik::core::sdk;
@ -192,28 +193,45 @@ class SchemaAdapter: public ScrollAdapterBase {
}
private:
struct IntValidator : public InputOverlay::IValidator {
template <typename T>
struct NumberValidator : public InputOverlay::IValidator {
using Formatter = std::function<std::string(T)>;
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");
if (bounded()) {
std::string result = _TSTR("validator_dialog_number_parse_bounded_error");
ReplaceAll(result, "{{minimum}}", formatter(minimum));
ReplaceAll(result, "{{maximum}}", formatter(maximum));
return result;
}
};
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;
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<T>::min() &&
maximum != std::numeric_limits<T>::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<NumberValidator<int>>(
entry->minValue, entry->maxValue, [](int value) -> std::string {
return std::to_string(value);
});
std::shared_ptr<InputOverlay> dialog(new InputOverlay());
dialog->SetTitle(name)
.SetText(stringValueFor(prefs, entry))
.SetValidator(std::make_shared<IntValidator>())
.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<NumberValidator<double>>(
entry->minValue, entry->maxValue, [](double value) -> std::string {
return stringValueForDouble(value);
});
std::shared_ptr<InputOverlay> dialog(new InputOverlay());
dialog->SetTitle(name)
.SetText(stringValueFor(prefs, entry))
.SetValidator(std::make_shared<DoubleValidator>())
.SetValidator(validator)
.SetInputAcceptedCallback([this, name](const std::string& value) {
this->prefs->SetDouble(name, std::stod(value));
this->changed = true;

View File

@ -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",