From fae2b5e01e2a6ca39ed144cdcba336651b604690 Mon Sep 17 00:00:00 2001 From: Almamu Date: Wed, 20 Aug 2025 01:41:01 +0200 Subject: [PATCH] chore: parse hex colors in properties --- .../Core/Projects/CPropertyColor.cpp | 24 +++++++++++++++++++ .../Core/Projects/CPropertyCombo.cpp | 10 ++++++-- .../Data/Parsers/ProjectParser.cpp | 14 ++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/WallpaperEngine/Core/Projects/CPropertyColor.cpp b/src/WallpaperEngine/Core/Projects/CPropertyColor.cpp index a60ff88..045f6f9 100644 --- a/src/WallpaperEngine/Core/Projects/CPropertyColor.cpp +++ b/src/WallpaperEngine/Core/Projects/CPropertyColor.cpp @@ -14,6 +14,30 @@ glm::vec3 ParseColor (std::string value) { } if (value.find ('.') == std::string::npos && value != "0 0 0" && value != "1 1 1") { + if (value.find ('#') == 0) { + // hex color, parse it to int color and then convert it to float + auto number = value.substr (1); + + if (number.size () == 3) { + // CSS short-number, expand to the proper size + number = number[0] + number[0] + number[1] + number[1] + number[2] + number[2]; + } + + // remove alpha if it's present, should look into it more closely + if (number.size () > 6) { + sLog.error ("Color value has alpha channel, which is not supported"); + number = number.substr (0, 6); + } + + const auto color = std::stoi (number, nullptr, 16); + + return { + (((color >> 16) & 0xFF) / 255.0), + (((color >> 8) & 0xFF) / 255.0), + (((color >> 0) & 0xFF) / 255.0) + }; + } + const auto intcolor = VectorBuilder::parse (value); return {intcolor.r / 255.0, intcolor.g / 255.0, intcolor.b / 255.0}; diff --git a/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp b/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp index e73fd2a..2784802 100644 --- a/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp +++ b/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp @@ -19,17 +19,23 @@ std::shared_ptr CPropertyCombo::fromJSON (const JSON& data, std: if (!cur.is_object ()) continue; + const auto valueIt = cur.require ("value", "Value is required for a property combo option"); + auto value = valueIt.is_number () ? std::to_string (valueIt.get ()) : valueIt.get (); + // check for label and value to ensure they're there values.push_back ({ .label = cur.require ("label", "Label is required for a property combo option"), - .value = cur.require ("value", "Value is required for a property combo option") + .value = value }); } + const auto valueIt = data.require ("value", "Value is required for a property combo"); + auto value = valueIt.is_number () ? std::to_string (valueIt.get ()) : valueIt.get (); + return std::make_shared ( std::move(name), data.optional ("text", ""), - data.require ("value", "Value is required for a property combo"), + value, values ); } diff --git a/src/WallpaperEngine/Data/Parsers/ProjectParser.cpp b/src/WallpaperEngine/Data/Parsers/ProjectParser.cpp index 9f2c7c7..6b6b325 100644 --- a/src/WallpaperEngine/Data/Parsers/ProjectParser.cpp +++ b/src/WallpaperEngine/Data/Parsers/ProjectParser.cpp @@ -14,15 +14,27 @@ static int backgroundId = 0; ProjectUniquePtr ProjectParser::parse (const JSON& data, ContainerUniquePtr container) { const auto general = data.optional ("general"); + const auto workshopId = data.optional ("workshopid"); + auto actualWorkshopId = std::to_string (--backgroundId); auto type = data.require ("type", "Project type missing"); + if (workshopId.has_value ()) { + if (workshopId->is_number ()) { + actualWorkshopId = std::to_string (workshopId->get ()); + } else if (workshopId->is_string ()) { + actualWorkshopId = workshopId->get (); + } else { + sLog.error ("Invalid workshop id: ", workshopId->dump ()); + } + } + // lowercase for consistency std::transform (type.begin (), type.end (), type.begin (), tolower); auto result = std::make_unique (Project { .title = data.require ("title", "Project title missing"), .type = parseType (type), - .workshopId = data.optional ("workshopid", std::to_string (--backgroundId)), + .workshopId = actualWorkshopId, .supportsAudioProcessing = general.has_value () && general.value ().optional ("supportsaudioprocessing", false), .properties = parseProperties (general), .container = std::move(container),