diff --git a/src/Gui/Dialogs/DlgThemeEditor.cpp b/src/Gui/Dialogs/DlgThemeEditor.cpp index eeabf70581..03d614d588 100644 --- a/src/Gui/Dialogs/DlgThemeEditor.cpp +++ b/src/Gui/Dialogs/DlgThemeEditor.cpp @@ -30,6 +30,7 @@ #include "ui_DlgThemeEditor.h" #include "BitmapFactory.h" +#include #include #include @@ -67,7 +68,7 @@ QString typeOfTokenValue(const Gui::StyleParameters::Value& value) [](const Gui::StyleParameters::Length&) { return QWidget::tr("Length"); }, - [](const QColor&) { + [](const Base::Color&) { return QWidget::tr("Color"); } }, @@ -529,8 +530,8 @@ QVariant StyleParametersModel::data(const QModelIndex& index, int role) const } if (role == Qt::DecorationRole) { - if (index.column() == ParameterPreview && std::holds_alternative(value)) { - return colorPreview(std::get(value)); + if (index.column() == ParameterPreview && std::holds_alternative(value)) { + return colorPreview(std::get(value).asValue()); } } } diff --git a/src/Gui/StyleParameters/ParameterManager.cpp b/src/Gui/StyleParameters/ParameterManager.cpp index 939e3aa55b..5347634ca2 100644 --- a/src/Gui/StyleParameters/ParameterManager.cpp +++ b/src/Gui/StyleParameters/ParameterManager.cpp @@ -95,9 +95,9 @@ std::string Value::toString() const return fmt::format("{}{}", value, unit); } - if (std::holds_alternative(*this)) { - auto color = std::get(*this); - return fmt::format("#{:0>6x}", 0xFFFFFF & color.rgb()); // NOLINT(*-magic-numbers) + if (std::holds_alternative(*this)) { + auto color = std::get(*this); + return fmt::format("#{:0>6x}", color.getPackedRGB() >> 8); // NOLINT(*-magic-numbers) } return std::get(*this); diff --git a/src/Gui/StyleParameters/ParameterManager.h b/src/Gui/StyleParameters/ParameterManager.h index 8736755c99..8e53747c09 100644 --- a/src/Gui/StyleParameters/ParameterManager.h +++ b/src/Gui/StyleParameters/ParameterManager.h @@ -107,9 +107,9 @@ private: * * As a rule, operations can be only performed over values of the same type. */ -struct Value : std::variant +struct Value : std::variant { - using std::variant::variant; + using std::variant::variant; /** * Converts the object into its string representation. diff --git a/src/Gui/StyleParameters/Parser.cpp b/src/Gui/StyleParameters/Parser.cpp index 99910a6a5e..3cd22bc226 100644 --- a/src/Gui/StyleParameters/Parser.cpp +++ b/src/Gui/StyleParameters/Parser.cpp @@ -26,6 +26,7 @@ #include "Parser.h" #include "ParameterManager.h" +#include #include #ifndef _PreComp_ @@ -67,12 +68,12 @@ Value FunctionCall::evaluate(const EvaluationContext& context) const auto colorArg = arguments[0]->evaluate(context); auto amountArg = arguments[1]->evaluate(context); - if (!std::holds_alternative(colorArg)) { + if (!std::holds_alternative(colorArg)) { THROWM(Base::ExpressionError, fmt::format("'{}' is not supported for colors", functionName)); } - auto color = std::get(colorArg); + auto color = std::get(colorArg).asValue(); // In Qt if you want to make color 20% darker or lighter, you need to pass 120 as the value // we, however, want users to pass only the relative difference, hence we need to add the @@ -82,11 +83,11 @@ Value FunctionCall::evaluate(const EvaluationContext& context) const auto amount = 100 + static_cast(std::get(amountArg).value); if (functionName == "lighten") { - return color.lighter(amount); + return Base::Color::fromValue(color.lighter(amount)); } if (functionName == "darken") { - return color.darker(amount); + return Base::Color::fromValue(color.darker(amount)); } return {}; @@ -104,25 +105,25 @@ Value FunctionCall::evaluate(const EvaluationContext& context) const auto secondColorArg = arguments[1]->evaluate(context); auto amountArg = arguments[2]->evaluate(context); - if (!std::holds_alternative(firstColorArg)) { + if (!std::holds_alternative(firstColorArg)) { THROWM(Base::ExpressionError, fmt::format("first argument of '{}' must be color", functionName)); } - if (!std::holds_alternative(secondColorArg)) { + if (!std::holds_alternative(secondColorArg)) { THROWM(Base::ExpressionError, fmt::format("second argument of '{}' must be color", functionName)); } - auto firstColor = std::get(firstColorArg); - auto secondColor = std::get(secondColorArg); + auto firstColor = std::get(firstColorArg); + auto secondColor = std::get(secondColorArg); - auto amount = Base::fromPercent(std::get(amountArg).value); + auto amount = Base::fromPercent(static_cast(std::get(amountArg).value)); - return QColor::fromRgbF( - (1 - amount) * firstColor.redF() + amount * secondColor.redF(), - (1 - amount) * firstColor.greenF() + amount * secondColor.greenF(), - (1 - amount) * firstColor.blueF() + amount * secondColor.blueF() + return Base::Color( + (1 - amount) * firstColor.r + amount * secondColor.r, + (1 - amount) * firstColor.g + amount * secondColor.g, + (1 - amount) * firstColor.b + amount * secondColor.b ); }; @@ -169,7 +170,7 @@ Value BinaryOp::evaluate(const EvaluationContext& context) const Value UnaryOp::evaluate(const EvaluationContext& context) const { Value val = operand->evaluate(context); - if (std::holds_alternative(val)) { + if (std::holds_alternative(val)) { THROWM(Base::ExpressionError, "Unary operations on colors are not supported"); } @@ -286,7 +287,7 @@ std::unique_ptr Parser::parseColor() int b = std::stoi(input.substr(pos, 2), nullptr, hexadecimalBase); pos += 2; - return std::make_unique(QColor(r, g, b)); + return std::make_unique(Base::Color(r / 255.0, g / 255.0, b / 255.0)); }; const auto parseFunctionStyleColor = [&]() { @@ -313,7 +314,7 @@ std::unique_ptr Parser::parseColor() if (!match(')')) { THROWM(Base::ParserError, fmt::format("Expected ')' after color arguments, got '{}'", input[pos])); } - return std::make_unique(QColor(r, g, b, a)); + return std::make_unique(Base::Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0)); }; skipWhitespace(); diff --git a/src/Gui/StyleParameters/Parser.h b/src/Gui/StyleParameters/Parser.h index 3e7867cae9..34ff09ce6d 100644 --- a/src/Gui/StyleParameters/Parser.h +++ b/src/Gui/StyleParameters/Parser.h @@ -83,9 +83,9 @@ struct GuiExport Number: public Expr struct GuiExport Color: public Expr { - QColor color; + Base::Color color; - explicit Color(QColor color) + explicit Color(Base::Color color) : color(std::move(color)) {} diff --git a/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp b/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp index 09c40cf13b..fd5e98cc6f 100644 --- a/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp +++ b/tests/src/Gui/StyleParameters/ParameterManagerTest.cpp @@ -24,6 +24,7 @@ #include #include +#include #include using namespace Gui::StyleParameters; @@ -73,20 +74,20 @@ TEST_F(ParameterManagerTest, BasicParameterResolution) { auto result = manager.resolve("PrimaryColor"); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 255); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 1); + EXPECT_EQ(color.g, 0); + EXPECT_EQ(color.b, 0); } { auto result = manager.resolve("SecondaryColor"); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 0); - EXPECT_EQ(color.green(), 255); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 0); + EXPECT_EQ(color.g, 1); + EXPECT_EQ(color.b, 0); } } @@ -294,10 +295,10 @@ TEST_F(ParameterManagerTest, ComplexExpressions) { auto result = manager.resolve("ColorWithFunction"); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result).asValue(); // Should be lighter than the original red - EXPECT_GT(color.lightness(), QColor("#ff0000").lightness()); + EXPECT_GT(color.lightness(), QColor(0xff0000).lightness()); } } diff --git a/tests/src/Gui/StyleParameters/ParserTest.cpp b/tests/src/Gui/StyleParameters/ParserTest.cpp index a7e1b50734..563c1265e7 100644 --- a/tests/src/Gui/StyleParameters/ParserTest.cpp +++ b/tests/src/Gui/StyleParameters/ParserTest.cpp @@ -23,7 +23,7 @@ #include -#include +#include #include #include @@ -103,56 +103,56 @@ TEST_F(ParserTest, ParseColors) Parser parser("#ff0000"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 255); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 1); + EXPECT_EQ(color.g, 0); + EXPECT_EQ(color.b, 0); } { Parser parser("#00ff00"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 0); - EXPECT_EQ(color.green(), 255); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 0); + EXPECT_EQ(color.g, 1); + EXPECT_EQ(color.b, 0); } { Parser parser("#0000ff"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 0); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 255); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 0); + EXPECT_EQ(color.g, 0); + EXPECT_EQ(color.b, 1); } { Parser parser("rgb(255, 0, 0)"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 255); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 1); + EXPECT_EQ(color.g, 0); + EXPECT_EQ(color.b, 0); } { Parser parser("rgba(255, 0, 0, 128)"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 255); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 0); - EXPECT_EQ(color.alpha(), 128); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_DOUBLE_EQ(color.r, 1); + EXPECT_DOUBLE_EQ(color.g, 0); + EXPECT_DOUBLE_EQ(color.b, 0); + EXPECT_NEAR(color.a, 128 / 255.0, 1e-6); } } @@ -173,11 +173,11 @@ TEST_F(ParserTest, ParseParameterReferences) Parser parser("@TestColor"); auto expr = parser.parse(); auto result = expr->evaluate({.manager = &manager, .context = {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 255); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 1); + EXPECT_EQ(color.g, 0); + EXPECT_EQ(color.b, 0); } { @@ -360,30 +360,30 @@ TEST_F(ParserTest, ParseFunctionCalls) Parser parser("lighten(#ff0000, 20)"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result).asValue(); // The result should be lighter than the original red - EXPECT_GT(color.lightness(), QColor("#ff0000").lightness()); + EXPECT_GT(color.lightness(), QColor(0xff0000).lightness()); } { Parser parser("darken(#ff0000, 20)"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result).asValue(); // The result should be darker than the original red - EXPECT_LT(color.lightness(), QColor("#ff0000").lightness()); + EXPECT_LT(color.lightness(), QColor(0xff0000).lightness()); } { Parser parser("lighten(@TestColor, 20)"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result).asValue(); // The result should be lighter than the original red - EXPECT_GT(color.lightness(), QColor("#ff0000").lightness()); + EXPECT_GT(color.lightness(), QColor(0xff0000).lightness()); } } @@ -496,11 +496,11 @@ TEST_F(ParserTest, ParseWhitespace) Parser parser("rgb(255,0,0)"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 255); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 1); + EXPECT_EQ(color.g, 0); + EXPECT_EQ(color.b, 0); } } @@ -539,11 +539,11 @@ TEST_F(ParserTest, ParseEdgeCases) Parser parser("#ff0000"); auto expr = parser.parse(); auto result = expr->evaluate({&manager, {}}); - EXPECT_TRUE(std::holds_alternative(result)); - auto color = std::get(result); - EXPECT_EQ(color.red(), 255); - EXPECT_EQ(color.green(), 0); - EXPECT_EQ(color.blue(), 0); + EXPECT_TRUE(std::holds_alternative(result)); + auto color = std::get(result); + EXPECT_EQ(color.r, 1); + EXPECT_EQ(color.g, 0); + EXPECT_EQ(color.b, 0); } // Single parameter reference