diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 004e1e3e..14847ec1 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -109,10 +109,12 @@ set(HDR_REQUEST source/scwx/qt/request/nexrad_file_request.hpp) set(SRC_REQUEST source/scwx/qt/request/nexrad_file_request.cpp) set(HDR_SETTINGS source/scwx/qt/settings/general_settings.hpp source/scwx/qt/settings/map_settings.hpp - source/scwx/qt/settings/palette_settings.hpp) + source/scwx/qt/settings/palette_settings.hpp + source/scwx/qt/settings/settings_variable.hpp) set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp source/scwx/qt/settings/map_settings.cpp - source/scwx/qt/settings/palette_settings.cpp) + source/scwx/qt/settings/palette_settings.cpp + source/scwx/qt/settings/settings_variable.cpp) set(HDR_TYPES source/scwx/qt/types/qt_types.hpp source/scwx/qt/types/radar_product_record.hpp source/scwx/qt/types/text_event_key.hpp) diff --git a/scwx-qt/source/scwx/qt/settings/settings_variable.cpp b/scwx-qt/source/scwx/qt/settings/settings_variable.cpp new file mode 100644 index 00000000..e0aa7d3f --- /dev/null +++ b/scwx-qt/source/scwx/qt/settings/settings_variable.cpp @@ -0,0 +1,159 @@ +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace settings +{ + +template class SettingsVariable; +template class SettingsVariable; +template class SettingsVariable; +template class SettingsVariable>; + +static const std::string logPrefix_ = "scwx::qt::settings::settings_variable"; + +template +class SettingsVariable::Impl +{ +public: + explicit Impl(const std::string& name) : name_ {name} {} + + ~Impl() {} + + bool Validate(const T& value); + + const std::string name_; + T value_ {}; + T default_ {}; + std::optional staged_ {}; + std::optional minimum_ {}; + std::optional maximum_ {}; + std::function validator_ {nullptr}; +}; + +template +SettingsVariable::SettingsVariable(const std::string& name) : + p(std::make_unique(name)) +{ +} +template +SettingsVariable::~SettingsVariable() = default; + +template +SettingsVariable::SettingsVariable(SettingsVariable&&) noexcept = default; +template +SettingsVariable& +SettingsVariable::operator=(SettingsVariable&&) noexcept = default; + +template +std::string SettingsVariable::name() const +{ + return p->name_; +} + +template +T SettingsVariable::GetValue() const +{ + return p->value_; +} + +template +bool SettingsVariable::SetValue(const T& value) +{ + bool validated = false; + + if (p->Validate(value)) + { + p->value_ = value; + validated = true; + } + + return validated; +} + +template +bool SettingsVariable::SetValueOrDefault(const T& value) +{ + bool validated = false; + + if (p->Validate(value)) + { + p->value_ = value; + validated = true; + } + else + { + p->value_ = p->default_; + } + + return validated; +} + +template +bool SettingsVariable::StageValue(const T& value) +{ + bool validated = false; + + if (p->Validate(value)) + { + p->staged_ = value; + validated = true; + } + + return validated; +} + +template +void SettingsVariable::Commit() +{ + if (p->staged_.has_value()) + { + p->value_ = std::move(p->staged_.value()); + p->staged_.reset(); + } +} + +template +T SettingsVariable::GetDefault() const +{ + return p->default_; +} + +template +void SettingsVariable::SetDefault(const T& value) +{ + p->default_ = value; +} + +template +void SettingsVariable::SetMinimum(const T& value) +{ + p->minimum_ = value; +} + +template +void SettingsVariable::SetMaximum(const T& value) +{ + p->maximum_ = value; +} + +template +void SettingsVariable::SetValidator(std::function validator) +{ + p->validator_ = validator; +} + +template +bool SettingsVariable::Impl::Validate(const T& value) +{ + return ((!minimum_.has_value() || value >= minimum_) && // Validate minimum + (!maximum_.has_value() || value <= maximum_) && // Validate maximum + (validator_ == nullptr || validator_(value))); // User-validation +} + +} // namespace settings +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/settings/settings_variable.hpp b/scwx-qt/source/scwx/qt/settings/settings_variable.hpp new file mode 100644 index 00000000..ffe4aa0a --- /dev/null +++ b/scwx-qt/source/scwx/qt/settings/settings_variable.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include + +namespace scwx +{ +namespace qt +{ +namespace settings +{ + +template +class SettingsVariable +{ +public: + explicit SettingsVariable(const std::string& name); + ~SettingsVariable(); + + SettingsVariable(const SettingsVariable&) = delete; + SettingsVariable& operator=(const SettingsVariable&) = delete; + + SettingsVariable(SettingsVariable&&) noexcept; + SettingsVariable& operator=(SettingsVariable&&) noexcept; + + std::string name() const; + + T GetValue() const; + bool SetValue(const T& value); + bool SetValueOrDefault(const T& value); + + bool StageValue(const T& value); + void Commit(); + + T GetDefault() const; + + void SetDefault(const T& value); + void SetMinimum(const T& value); + void SetMaximum(const T& value); + void SetValidator(std::function validator); + +private: + class Impl; + std::unique_ptr p; +}; + +// Instantiated templates: +// template class SettingsVariable; +// template class SettingsVariable; +// template class SettingsVariable; +// template class SettingsVariable>; + +} // namespace settings +} // namespace qt +} // namespace scwx diff --git a/test/source/scwx/qt/settings/settings_variable.test.cpp b/test/source/scwx/qt/settings/settings_variable.test.cpp new file mode 100644 index 00000000..3c3cf3ec --- /dev/null +++ b/test/source/scwx/qt/settings/settings_variable.test.cpp @@ -0,0 +1,34 @@ +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace settings +{ + +TEST(SettingsVariableTest, String) +{ + SettingsVariable stringVariable {"string"}; + stringVariable.SetDefault("Default"); + stringVariable.SetValidator([](const std::string& value) + { return !value.empty(); }); + stringVariable.SetValue("Hello World"); + + EXPECT_EQ(stringVariable.name(), "string"); + EXPECT_EQ(stringVariable.GetValue(), "Hello World"); + EXPECT_EQ(stringVariable.SetValue(""), false); + EXPECT_EQ(stringVariable.GetValue(), "Hello World"); + EXPECT_EQ(stringVariable.SetValueOrDefault(""), false); + EXPECT_EQ(stringVariable.GetValue(), "Default"); + EXPECT_EQ(stringVariable.SetValue("Value 1"), true); + EXPECT_EQ(stringVariable.GetValue(), "Value 1"); + EXPECT_EQ(stringVariable.SetValueOrDefault("Value 2"), true); + EXPECT_EQ(stringVariable.GetValue(), "Value 2"); +} + +} // namespace settings +} // namespace qt +} // namespace scwx diff --git a/test/test.cmake b/test/test.cmake index dcd547ca..9843c2f0 100644 --- a/test/test.cmake +++ b/test/test.cmake @@ -23,6 +23,7 @@ set(SRC_QT_CONFIG_TESTS source/scwx/qt/config/county_database.test.cpp source/scwx/qt/config/radar_site.test.cpp) set(SRC_QT_MANAGER_TESTS source/scwx/qt/manager/settings_manager.test.cpp) set(SRC_QT_MODEL_TESTS source/scwx/qt/model/imgui_context_model.test.cpp) +set(SRC_QT_SETTINGS_TESTS source/scwx/qt/settings/settings_variable.test.cpp) set(SRC_UTIL_TESTS source/scwx/util/float.test.cpp source/scwx/util/rangebuf.test.cpp source/scwx/util/streams.test.cpp @@ -41,20 +42,22 @@ add_executable(wxtest ${SRC_MAIN} ${SRC_QT_CONFIG_TESTS} ${SRC_QT_MANAGER_TESTS} ${SRC_QT_MODEL_TESTS} + ${SRC_QT_SETTINGS_TESTS} ${SRC_UTIL_TESTS} ${SRC_WSR88D_TESTS} ${CMAKE_FILES}) -source_group("Source Files\\main" FILES ${SRC_MAIN}) -source_group("Source Files\\awips" FILES ${SRC_AWIPS_TESTS}) -source_group("Source Files\\common" FILES ${SRC_COMMON_TESTS}) -source_group("Source Files\\network" FILES ${SRC_NETWORK_TESTS}) -source_group("Source Files\\provider" FILES ${SRC_PROVIDER_TESTS}) -source_group("Source Files\\qt\\config" FILES ${SRC_QT_CONFIG_TESTS}) -source_group("Source Files\\qt\\manager" FILES ${SRC_QT_MANAGER_TESTS}) -source_group("Source Files\\qt\\model" FILES ${SRC_QT_MODEL_TESTS}) -source_group("Source Files\\util" FILES ${SRC_UTIL_TESTS}) -source_group("Source Files\\wsr88d" FILES ${SRC_WSR88D_TESTS}) +source_group("Source Files\\main" FILES ${SRC_MAIN}) +source_group("Source Files\\awips" FILES ${SRC_AWIPS_TESTS}) +source_group("Source Files\\common" FILES ${SRC_COMMON_TESTS}) +source_group("Source Files\\network" FILES ${SRC_NETWORK_TESTS}) +source_group("Source Files\\provider" FILES ${SRC_PROVIDER_TESTS}) +source_group("Source Files\\qt\\config" FILES ${SRC_QT_CONFIG_TESTS}) +source_group("Source Files\\qt\\manager" FILES ${SRC_QT_MANAGER_TESTS}) +source_group("Source Files\\qt\\model" FILES ${SRC_QT_MODEL_TESTS}) +source_group("Source Files\\qt\\settings" FILES ${SRC_QT_SETTINGS_TESTS}) +source_group("Source Files\\util" FILES ${SRC_UTIL_TESTS}) +source_group("Source Files\\wsr88d" FILES ${SRC_WSR88D_TESTS}) target_include_directories(wxtest PRIVATE ${GTest_INCLUDE_DIRS})