From fb02eed8ccfd9d0c9dc83777d9ba676069b007d5 Mon Sep 17 00:00:00 2001 From: OmniaX-Dev Date: Fri, 10 Apr 2026 05:43:44 +0200 Subject: [PATCH] Added some default variables for gui window stylesheet --- .clangd | 3 +- extra/testTheme.txt | 6 +-- other/build.nr | 2 +- src/ogfx/gui/Window.cpp | 79 +++++++++++++++++++++++++++++++++++++- src/ogfx/gui/Window.hpp | 5 ++- src/ostd/io/Stylesheet.cpp | 29 ++++++++++---- src/ostd/io/Stylesheet.hpp | 7 ++-- src/test/GuiTest.cpp | 2 +- 8 files changed, 114 insertions(+), 19 deletions(-) diff --git a/.clangd b/.clangd index 122ab09..32169b9 100644 --- a/.clangd +++ b/.clangd @@ -1,2 +1,3 @@ CompileFlags: - CompilationDatabase: bin \ No newline at end of file + CompilationDatabase: bin + Add: ["--target=x86_64-w64-mingw32"] \ No newline at end of file diff --git a/extra/testTheme.txt b/extra/testTheme.txt index ac7cc05..0712b7a 100644 --- a/extra/testTheme.txt +++ b/extra/testTheme.txt @@ -53,12 +53,12 @@ $accentColor = Color(rgb(255, 0, 0)) } (label:hover) { - textColor = Color(rgb(0, 255, 0)) + textColor = color_green borderColor = Color(rgb(0, 255, 0)) } (label:pressed) { - textColor = Color(#FF00FFFF) + textColor = color_firebrick } (@testLabel label:hover) { @@ -66,7 +66,7 @@ $accentColor = Color(rgb(255, 0, 0)) } (@testLabel label:pressed) { - backgroundColor = Color(#0040AAFF) + backgroundColor = color_firebrick textColor = Color(#505050FF) } diff --git a/other/build.nr b/other/build.nr index 6a36181..fd57c18 100644 --- a/other/build.nr +++ b/other/build.nr @@ -1 +1 @@ -2053 +2054 diff --git a/src/ogfx/gui/Window.cpp b/src/ogfx/gui/Window.cpp index 8965a65..e1f900c 100644 --- a/src/ogfx/gui/Window.cpp +++ b/src/ogfx/gui/Window.cpp @@ -74,7 +74,8 @@ namespace ogfx if (m_initialized) return; SDLSysten::acquire(); - DefaultTheme.loadFromString(DefaultThemeStyle); + __load_default_stylesheet_variables(); + DefaultTheme.loadFromString(DefaultThemeStyle, "memory://", true, getDefaultStylesheetVariableList()); m_windowWidth = width; m_windowHeight = height; @@ -407,6 +408,82 @@ namespace ogfx __on_event(event); } + void WindowCore::__load_default_stylesheet_variables(void) + { + // Cursors + m_defaultStylesheetVariables["cursor_default"] = { ostd::String("").add(static_cast(eCursor::Default)), true }; + m_defaultStylesheetVariables["cursor_text"] = { ostd::String("").add(static_cast(eCursor::Text)), true }; + m_defaultStylesheetVariables["cursor_wait"] = { ostd::String("").add(static_cast(eCursor::Wait)), true }; + m_defaultStylesheetVariables["cursor_crosshair"] = { ostd::String("").add(static_cast(eCursor::Crosshair)), true }; + m_defaultStylesheetVariables["cursor_progress"] = { ostd::String("").add(static_cast(eCursor::Progress)), true }; + m_defaultStylesheetVariables["cursor_nwse_resize"] = { ostd::String("").add(static_cast(eCursor::NWSE_Resize)), true }; + m_defaultStylesheetVariables["cursor_nesw_resize"] = { ostd::String("").add(static_cast(eCursor::NESW_Resize)), true }; + m_defaultStylesheetVariables["cursor_ew_resize"] = { ostd::String("").add(static_cast(eCursor::EW_Resize)), true }; + m_defaultStylesheetVariables["cursor_ns_resize"] = { ostd::String("").add(static_cast(eCursor::NS_Resize)), true }; + m_defaultStylesheetVariables["cursor_move"] = { ostd::String("").add(static_cast(eCursor::Move)), true }; + m_defaultStylesheetVariables["cursor_no_allowed"] = { ostd::String("").add(static_cast(eCursor::NotAllowed)), true }; + m_defaultStylesheetVariables["cursor_pointer"] = { ostd::String("").add(static_cast(eCursor::Pointer)), true }; + m_defaultStylesheetVariables["cursor_nw_resize"] = { ostd::String("").add(static_cast(eCursor::NW_Resize)), true }; + m_defaultStylesheetVariables["cursor_n_resize"] = { ostd::String("").add(static_cast(eCursor::N_Resize)), true }; + m_defaultStylesheetVariables["cursor_ne_resize"] = { ostd::String("").add(static_cast(eCursor::NE_Resize)), true }; + m_defaultStylesheetVariables["cursor_e_resize"] = { ostd::String("").add(static_cast(eCursor::E_Resize)), true }; + m_defaultStylesheetVariables["cursor_se_resize"] = { ostd::String("").add(static_cast(eCursor::SE_Resize)), true }; + m_defaultStylesheetVariables["cursor_s_resize"] = { ostd::String("").add(static_cast(eCursor::S_Resize)), true }; + m_defaultStylesheetVariables["cursor_sw_resize"] = { ostd::String("").add(static_cast(eCursor::SW_Resize)), true }; + m_defaultStylesheetVariables["cursor_w_resize"] = { ostd::String("").add(static_cast(eCursor::W_Resize)), true }; + + // Colors + m_defaultStylesheetVariables["color_transparent"] = { "Color(" + ostd::Colors::Transparent.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_black"] = { "Color(" + ostd::Colors::Black.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_white"] = { "Color(" + ostd::Colors::White.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_gray"] = { "Color(" + ostd::Colors::Gray.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_lightgray"] = { "Color(" + ostd::Colors::LightGray.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkgray"] = { "Color(" + ostd::Colors::DarkGray.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_red"] = { "Color(" + ostd::Colors::Red.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_green"] = { "Color(" + ostd::Colors::Green.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_blue"] = { "Color(" + ostd::Colors::Blue.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_yellow"] = { "Color(" + ostd::Colors::Yellow.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_cyan"] = { "Color(" + ostd::Colors::Cyan.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_magenta"] = { "Color(" + ostd::Colors::Magenta.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_orange"] = { "Color(" + ostd::Colors::Orange.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_purple"] = { "Color(" + ostd::Colors::Purple.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_brown"] = { "Color(" + ostd::Colors::Brown.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_pink"] = { "Color(" + ostd::Colors::Pink.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_lime"] = { "Color(" + ostd::Colors::Lime.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_olive"] = { "Color(" + ostd::Colors::Olive.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_teal"] = { "Color(" + ostd::Colors::Teal.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_navy"] = { "Color(" + ostd::Colors::Navy.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_maroon"] = { "Color(" + ostd::Colors::Maroon.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_indigo"] = { "Color(" + ostd::Colors::Indigo.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_gold"] = { "Color(" + ostd::Colors::Gold.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_silver"] = { "Color(" + ostd::Colors::Silver.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_beige"] = { "Color(" + ostd::Colors::Beige.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_coral"] = { "Color(" + ostd::Colors::Coral.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_salmon"] = { "Color(" + ostd::Colors::Salmon.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_chocolate"] = { "Color(" + ostd::Colors::Chocolate.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_khaki"] = { "Color(" + ostd::Colors::Khaki.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_lavender"] = { "Color(" + ostd::Colors::Lavender.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_mint"] = { "Color(" + ostd::Colors::Mint.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_skyblue"] = { "Color(" + ostd::Colors::SkyBlue.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_royalblue"] = { "Color(" + ostd::Colors::RoyalBlue.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_deepskyblue"] = { "Color(" + ostd::Colors::DeepSkyBlue.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_turquoise"] = { "Color(" + ostd::Colors::Turquoise.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_aquamarine"] = { "Color(" + ostd::Colors::Aquamarine.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_forestgreen"] = { "Color(" + ostd::Colors::ForestGreen.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_seagreen"] = { "Color(" + ostd::Colors::SeaGreen.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_springgreen"] = { "Color(" + ostd::Colors::SpringGreen.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_firebrick"] = { "Color(" + ostd::Colors::Firebrick.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_crimson"] = { "Color(" + ostd::Colors::Crimson.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_tomato"] = { "Color(" + ostd::Colors::Tomato.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkorange"] = { "Color(" + ostd::Colors::DarkOrange.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkred"] = { "Color(" + ostd::Colors::DarkRed.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkblue"] = { "Color(" + ostd::Colors::DarkBlue.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkgreen"] = { "Color(" + ostd::Colors::DarkGreen.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkcyan"] = { "Color(" + ostd::Colors::DarkCyan.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkmagenta"] = { "Color(" + ostd::Colors::DarkMagenta.hexString(true, "#") + ")", true }; + m_defaultStylesheetVariables["color_darkyellow"] = { "Color(" + ostd::Colors::DarkYellow.hexString(true, "#") + ")", true }; + } + diff --git a/src/ogfx/gui/Window.hpp b/src/ogfx/gui/Window.hpp index 049ed2b..b6a168d 100644 --- a/src/ogfx/gui/Window.hpp +++ b/src/ogfx/gui/Window.hpp @@ -77,6 +77,7 @@ namespace ogfx inline const ostd::Stylesheet* theme(void) const { return m_guiTheme; } inline void loadDefaultTHeme(void) { setTheme(DefaultTheme); } + inline ostd::Stylesheet::VariableList& getDefaultStylesheetVariableList(void) { return m_defaultStylesheetVariables; } inline virtual void setTheme(const ostd::Stylesheet& theme) { } inline bool isInitialized(void) const { return m_initialized; } @@ -110,6 +111,7 @@ namespace ogfx private: void __handle_event(SDL_Event& event); + void __load_default_stylesheet_variables(void); protected: SDL_Window* m_window { nullptr }; @@ -160,6 +162,8 @@ namespace ogfx private: inline static ostd::Stylesheet DefaultTheme; + std::unordered_map> m_defaultStylesheetVariables; + }; class GraphicsWindow : public WindowCore { @@ -202,7 +206,6 @@ namespace ogfx inline Window(void) { } inline Window(int32_t width, int32_t height, const ostd::String& title) { initialize(width, height, title); } void addWidget(Widget& widget); - void setTheme(const ostd::Stylesheet& theme) override; inline virtual void onInitialize(void) { } diff --git a/src/ostd/io/Stylesheet.cpp b/src/ostd/io/Stylesheet.cpp index f4662cd..f107f66 100644 --- a/src/ostd/io/Stylesheet.cpp +++ b/src/ostd/io/Stylesheet.cpp @@ -34,14 +34,14 @@ namespace ostd return *this; } - Stylesheet& Stylesheet::loadFromFile(const ostd::String& filePath, bool clearCurrentRules) + Stylesheet& Stylesheet::loadFromFile(const ostd::String& filePath, bool clearCurrentRules, VariableList variable) { ostd::String outContent = ""; ostd::FileSystem::readTextFileRaw(filePath, outContent); - return loadFromString(outContent, filePath, clearCurrentRules); + return loadFromString(outContent, filePath, clearCurrentRules, variable); } - Stylesheet& Stylesheet::loadFromString(const ostd::String& content, const ostd::String& filePath, bool clearCurrentRules, std::unordered_map> variables) + Stylesheet& Stylesheet::loadFromString(const ostd::String& content, const ostd::String& filePath, bool clearCurrentRules, VariableList variables) { if (clearCurrentRules) m_values.clear(); @@ -53,11 +53,11 @@ namespace ostd OX_WARN("%s in theme line. File: <%s:%d>", msg.c_str(), filePath.c_str(), lineNumber, originalLines[lineNumber - 1].c_str()); }; auto l_parseLine = [&](ostd::String& line) -> void { - for (const auto&[var, val] : variables) - line.replaceAll(var, val.first); - if (!parseThemeFileLine(line)) + if (!parseThemeFileLine(line, variables)) l_warn("Error"); }; + for (const auto&[var, val] : variables) + std::cout << var << " = " << val.first << "\n"; uint8_t lineNumberMaxWidth = ostd::String("").add(lines.size()).len(); ostd::String groupSelector = ""; bool groupLines = true; @@ -223,7 +223,7 @@ custom_continue: return it != m_values.end() ? &it->second : nullptr; } - bool Stylesheet::parseThemeFileLine(const ostd::String& line) + bool Stylesheet::parseThemeFileLine(const ostd::String& line, const VariableList& variables, bool exitCondition) { if (!line.contains("=")) return false; @@ -287,7 +287,20 @@ custom_continue: set(key, ostd::Rectangle(vec[0], vec[1], vec[2], vec[3]), themeID); } else - return false; + { + if (exitCondition) + return false; + ostd::String lineCopy = line; + for (const auto&[var, val] : variables) + { + if (lineCopy.contains(var)) + { + lineCopy.replaceAll(var, val.first); + break; + } + } + return parseThemeFileLine(lineCopy, variables, true); + } return true; } diff --git a/src/ostd/io/Stylesheet.hpp b/src/ostd/io/Stylesheet.hpp index 57568b1..383371f 100644 --- a/src/ostd/io/Stylesheet.hpp +++ b/src/ostd/io/Stylesheet.hpp @@ -31,12 +31,13 @@ namespace ostd class Stylesheet { public: using QualifierList = std::vector>; + public: using VariableList = std::unordered_map>; public: using TypeVariant = std::variant; public: Stylesheet(void); Stylesheet& clear(void); - Stylesheet& loadFromFile(const ostd::String& filePath, bool clearCurrentRules = true); - Stylesheet& loadFromString(const ostd::String& content, const ostd::String& filePath = "memory://", bool clearCurrentRules = true, std::unordered_map> variables = {}); + Stylesheet& loadFromFile(const ostd::String& filePath, bool clearCurrentRules = true, VariableList variables = {}); + Stylesheet& loadFromString(const ostd::String& content, const ostd::String& filePath = "memory://", bool clearCurrentRules = true, VariableList variables = {}); void set(const std::string& key, TypeVariant value, const ostd::String& themeID); void removeRule(const ostd::String& fullKey); void setFull(const ostd::String& fullKey, TypeVariant value); @@ -59,7 +60,7 @@ namespace ostd std::vector getRichStringLines(const std::vector& lines); private: - bool parseThemeFileLine(const ostd::String& line); + bool parseThemeFileLine(const ostd::String& line, const VariableList& variables, bool exitCondition = false); ostd::String parseGroupSelector(const ostd::String& rawSelector) const; std::vector parseGroup(const ostd::String& selector, const std::vector& group); diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index b49e0ea..7082670 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -91,7 +91,7 @@ class Window : public ogfx::gui::Window m_label1.addThemeOverride("@:pressed.label.textColor", ostd::Colors::Crimson); - m_theme.loadFromFile("./testTheme.txt"); + m_theme.loadFromFile("./testTheme.txt", true, getDefaultStylesheetVariableList()); m_label2.addThemeOverride("@:hover.label.showBackground", true); m_label2.addThemeOverride("@:hover.label.backgroundColor", ostd::Colors::DarkGreen);