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");
+}