From 379060b8c7fb7cc588aa5510ce8bb2d7ae62dbe1 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Thu, 17 Jul 2025 12:39:24 -0400 Subject: [PATCH] Can now set a color to another already existing color. --- assets/config.json | 15 +------------ assets/palette.json | 31 +++++++++++++------------- backend.cpp | 47 +++++++++++++++------------------------- palette.cpp | 53 +++++++++++++++++++++++++++++---------------- tests/palette.cpp | 4 ++-- 5 files changed, 69 insertions(+), 81 deletions(-) diff --git a/assets/config.json b/assets/config.json index fa61427..b4ff6c5 100644 --- a/assets/config.json +++ b/assets/config.json @@ -229,24 +229,11 @@ "NW": 8598 }, "theme": { - "black": [0, 0, 0, 255], - "dark_dark": [10, 10, 10, 255], - "dark_mid": [30, 30, 30, 255], - "dark_light": [60, 60, 60, 255], - "mid": [100, 100, 100, 255], - "light_dark": [150, 150, 150, 255], - "light_mid": [200, 200, 200, 255], - "light_light": [230, 230, 230, 255], - "white": [255, 255, 255, 255], + "NOTE": "colors are in assets/palette.json", "padding": 3, "border_px": 1, "text_size": 20, "label_size": 20, - "fill_color": "dark_mid", - "text_color": "light_light", - "bg_color": "mid", - "border_color": "dark_dark", - "bg_color_dark": "black", "font_file_name": "assets/text.otf" } } diff --git a/assets/palette.json b/assets/palette.json index 116cf7d..1f132f6 100644 --- a/assets/palette.json +++ b/assets/palette.json @@ -2,22 +2,21 @@ "color": { "transparent": [255, 255, 255, 255] }, - "gui/line": { - "light": [200,200,200], - "mid": [100,100,100], - "dark": [10,10,10] - }, - - "gui/text": { - "light": [200,200,200], - "mid": [100,100,100], - "dark": [10,10,10] - }, - - "gui/accent": { - "light": [200,200,200], - "mid": [100,100,100], - "dark": [10,10,10] + "gui/theme": { + "black": [0, 0, 0, 255], + "dark_dark": [10, 10, 10, 255], + "dark_mid": [30, 30, 30, 255], + "dark_light": [60, 60, 60, 255], + "mid": [100, 100, 100, 255], + "light_dark": [150, 150, 150, 255], + "light_mid": [200, 200, 200, 255], + "light_light": [230, 230, 230, 255], + "white": [255, 255, 255, 255], + "fill_color": "gui/theme:dark_mid", + "text_color": "gui/theme:light_light", + "bg_color": "gui/theme:mid", + "border_color": "gui/theme:dark_dark", + "bg_color_dark": "gui/theme:black" }, "items/fg": { "flame": [24, 120, 189], diff --git a/backend.cpp b/backend.cpp index 1b1bbe0..5bb4f25 100644 --- a/backend.cpp +++ b/backend.cpp @@ -3,6 +3,7 @@ #include "sound.hpp" #include "textures.hpp" #include "config.hpp" +#include "palette.hpp" namespace sfml { using namespace nlohmann; @@ -39,46 +40,32 @@ namespace sfml { } } - inline sf::Color to_color(json& config, const std::string& name) { - json& val = config[name]; - if(val.type() == json::value_t::array) { - return sf::Color{val[0], val[1], val[2], val[3]}; - } else if(val.type() == json::value_t::string) { - json& array = config[val]; - return sf::Color{array[0], array[1], array[2], array[3]}; - } else { - dbc::sentinel(fmt::format( - "theme config {} has invalid color setting," - "either use an array of 4 ints or a string" - "referencing another config with 4 ints.", name)); - } - } - guecs::Theme Backend::theme() { + palette::init(); auto config = Config("assets/config.json")["theme"]; guecs::Theme theme { - .BLACK=to_color(config, "black"), - .DARK_DARK=to_color(config, "dark_dark"), - .DARK_MID=to_color(config, "dark_mid"), - .DARK_LIGHT=to_color(config, "dark_light"), - .MID=to_color(config, "mid"), - .LIGHT_DARK=to_color(config, "light_dark"), - .LIGHT_MID=to_color(config, "light_mid"), - .LIGHT_LIGHT=to_color(config, "light_light"), - .WHITE=to_color(config, "white"), - .TRANSPARENT = sf::Color::Transparent + .BLACK=palette::get("gui/theme:black"), + .DARK_DARK=palette::get("gui/theme:dark_dark"), + .DARK_MID=palette::get("gui/theme:dark_mid"), + .DARK_LIGHT=palette::get("gui/theme:dark_light"), + .MID=palette::get("gui/theme:mid"), + .LIGHT_DARK=palette::get("gui/theme:light_dark"), + .LIGHT_MID=palette::get("gui/theme:light_mid"), + .LIGHT_LIGHT=palette::get("gui/theme:light_light"), + .WHITE=palette::get("gui/theme:white"), + .TRANSPARENT = palette::get("color:transparent") }; theme.PADDING = config["padding"]; theme.BORDER_PX = config["border_px"]; theme.TEXT_SIZE = config["text_size"]; theme.LABEL_SIZE = config["label_size"]; - theme.FILL_COLOR = to_color(config, "fill_color"); - theme.TEXT_COLOR = to_color(config, "text_color"); - theme.BG_COLOR = to_color(config, "bg_color"); - theme.BORDER_COLOR = to_color(config, "border_color"); - theme.BG_COLOR_DARK = to_color(config, "bg_color_dark"); + theme.FILL_COLOR = palette::get("gui/theme:fill_color"); + theme.TEXT_COLOR = palette::get("gui/theme:text_color"); + theme.BG_COLOR = palette::get("gui/theme:bg_color"); + theme.BORDER_COLOR = palette::get("gui/theme:border_color"); + theme.BG_COLOR_DARK = palette::get("gui/theme:bg_color_dark"); theme.FONT_FILE_NAME = Config::path_to(config["font_file_name"]).string(); return theme; diff --git a/palette.cpp b/palette.cpp index cb689fb..04823c8 100644 --- a/palette.cpp +++ b/palette.cpp @@ -10,30 +10,50 @@ namespace palette { struct PaletteMgr { std::unordered_map palettes; std::string config; + std::unordered_map pending_refs; + bool initialized = false; }; static PaletteMgr COLOR; void init(const string &json_file) { - COLOR.config = json_file; - Config config(json_file); - json& colors = config.json(); + if(!COLOR.initialized) { + COLOR.initialized = true; - for(auto [key, value_specs] : colors.items()) { - const string& base_key = key; + COLOR.config = json_file; + Config config(json_file); + json& colors = config.json(); - for(auto [value, rgba] : value_specs.items()) { - auto color_path = base_key + ":" + value; - dbc::check(!COLOR.palettes.contains(color_path), - fmt::format("PALLETES config {} already has a color path {}", COLOR.config, color_path)); + for(auto [key, value_specs] : colors.items()) { + const string& base_key = key; - uint8_t alpha = rgba.size() == 3 ? 255 : (uint8_t)rgba[3]; + for(auto [value, rgba] : value_specs.items()) { + auto color_path = base_key + ":" + value; + dbc::check(!COLOR.palettes.contains(color_path), + fmt::format("PALLETES config {} already has a color path {}", COLOR.config, color_path)); - sf::Color color{rgba[0], rgba[1], rgba[2], alpha}; - - COLOR.palettes.try_emplace(color_path, color); + if(rgba.type() == json::value_t::string) { + COLOR.pending_refs.try_emplace(color_path, rgba); + } else { + uint8_t alpha = rgba.size() == 3 ? 255 : (uint8_t)rgba[3]; + sf::Color color{rgba[0], rgba[1], rgba[2], alpha}; + COLOR.palettes.try_emplace(color_path, color); + } + } } } + + for(auto [color_path, ref] : COLOR.pending_refs) { + dbc::check(COLOR.palettes.contains(ref), + fmt::format("In {} you have {} referring to {} but {} doesn't exist.", + COLOR.config, color_path, ref, ref)); + dbc::check(!COLOR.palettes.contains(color_path), + fmt::format("Color {} with ref {} is duplicated.", color_path, ref)); + + auto color = COLOR.palettes.at(ref); + + COLOR.palettes.try_emplace(color_path, color); + } } sf::Color get(const string& key) { @@ -43,11 +63,6 @@ namespace palette { } sf::Color get(const string& key, const string& value) { - std::string color{key + ":" + value}; - - dbc::check(COLOR.palettes.contains(color), - fmt::format("COLOR {} is missing from {}", color, COLOR.config)); - - return COLOR.palettes.at(color); + return get(key + ":" + value); } } diff --git a/tests/palette.cpp b/tests/palette.cpp index 1fd28c2..988e565 100644 --- a/tests/palette.cpp +++ b/tests/palette.cpp @@ -9,10 +9,10 @@ TEST_CASE("color palette test", "[color-palette]") { palette::init(); sf::Color expect{10, 10, 10, 255}; - auto gui_text = palette::get("gui/text:dark"); + auto gui_text = palette::get("gui/theme:dark_dark"); REQUIRE(gui_text == expect); - gui_text = palette::get("gui/text", "mid"); + gui_text = palette::get("gui/theme", "mid"); REQUIRE(gui_text != expect); expect = {100, 100, 100, 255};