From da03225f3bf4ad931cc5548bbce94fd121bf5a97 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sun, 10 Aug 2025 23:12:52 +0200 Subject: [PATCH] Gui: Add ParameterDefinition to Style Parameters This adds a way to define parameters within code, that allows developers to easily encapsulate the parameters and their default values. --- src/Gui/StyleParameters/ParameterManager.h | 61 ++++++++++++++++++- .../StyleParameters/ParameterManagerTest.cpp | 19 ++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/Gui/StyleParameters/ParameterManager.h b/src/Gui/StyleParameters/ParameterManager.h index 50902db46e..53d3ed3703 100644 --- a/src/Gui/StyleParameters/ParameterManager.h +++ b/src/Gui/StyleParameters/ParameterManager.h @@ -37,6 +37,14 @@ #include #include +// That macro uses inline const because some older compilers to not properly support constexpr +// for std::string. It should be changed into static constepxr once we migrate to newer compiler. +#define DEFINE_STYLE_PARAMETER(_name_, _defaultValue_) \ + static inline const Gui::StyleParameters::ParameterDefinition _name_ { \ + .name = #_name_, \ + .defaultValue = (_defaultValue_), \ + } + namespace Gui::StyleParameters { @@ -56,7 +64,7 @@ struct Numeric /// Numeric value of the length. double value; /// Unit of the length, empty if the value is dimensionless. - std::string unit; + std::string unit = ""; /** * @name Operators @@ -119,6 +127,33 @@ struct Value : std::variant std::string toString() const; }; +/** + * @brief A structure to define parameters which can be referenced in the code. + * + * @tparam T The type of the parameter. + * + * This structure allows defining parameters which encapsulate a name and a corresponding + * default value. Parameters defined this way can be reused across the codebase for consistency. + * The supported value types include: + * - Numeric types. + * - Colors using `Base::Color`. + * - Strings. + * + * Example Usage: + * @code{.cpp} + * DEFINE_STYLE_PARAMETER(SomeParameter, Numeric { 10 }); + * DEFINE_STYLE_PARAMETER(TextColor, Base::Color(0.5F, 0.2F, 0.8F)); + * @endcode + */ +template +struct ParameterDefinition +{ + /// The name of the parameter, must be unique. + const char* name; + /// The default value of the parameter. + T defaultValue; +}; + /** * @struct Parameter * @@ -413,7 +448,29 @@ public: * @param context Resolution context for handling circular references * @return The resolved value */ - Value resolve(const std::string& name, ResolveContext context = {}) const; + std::optional resolve(const std::string& name, ResolveContext context = {}) const; + + /** + * @brief Resolves a parameter to its final value, based on definition. + * + * This method evaluates the parameter's expression and returns the computed + * value or default one from definition if the parameter is not available. + * + * @param definition Definition of the parameter to resolve + * @param context Resolution context for handling circular references + * @return The resolved value + */ + template + T resolve(const ParameterDefinition& definition, ResolveContext context = {}) const + { + auto value = resolve(definition.name, std::move(context)); + + if (!value || !std::holds_alternative(*value)) { + return definition.defaultValue; + } + + return std::get(*value); + } /** * @brief Evaluates an expression string and returns the result. diff --git a/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp b/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp index ceefab2298..57bb79656c 100644 --- a/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp +++ b/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp @@ -328,3 +328,22 @@ TEST_F(ParameterManagerTest, ErrorHandling) EXPECT_TRUE(invalidResult.has_value()); EXPECT_TRUE(std::holds_alternative(*invalidResult)); } + +DEFINE_STYLE_PARAMETER(BaseSize, Numeric(8, "px")); + +TEST_F(ParameterManagerTest, ResolveParameterDefinition) +{ + auto result = manager.resolve(BaseSize); + EXPECT_DOUBLE_EQ(result.value, 16); + EXPECT_EQ(result.unit, "px"); +} + + +DEFINE_STYLE_PARAMETER(MarginSize, Numeric(16, "px")); + +TEST_F(ParameterManagerTest, ResolveParameterDefinitionDefault) +{ + auto result = manager.resolve(MarginSize); + EXPECT_DOUBLE_EQ(result.value, 16); + EXPECT_EQ(result.unit, "px"); +}