diff --git a/extra/testTheme.txt b/extra/testTheme.txt index d681e43..4748451 100644 --- a/extra/testTheme.txt +++ b/extra/testTheme.txt @@ -25,13 +25,25 @@ window.backgroundColor = Color(rgba(40, 0, 0, 255)) fontSize = 20 } +(@testLabel2 label) { + showBackground = false +} + +(@testLabel2 label:hover) { + borderColor = Color(#208080FF) +} + +(@testLabel2 label:pressed) { + showBackground = true +} + (label:hover) { textColor = Color(rgb(0, 255, 0)) borderColor = Color(rgb(0, 255, 0)) } (label:pressed) { - textColor = Color(#FF0000FF) + textColor = Color(#FF00FFFF) } (@testLabel label:hover) { @@ -45,8 +57,8 @@ window.backgroundColor = Color(rgba(40, 0, 0, 255)) (label:disabled) { backgroundColor = Color(#EEEEEEFF) - textColor = Color(#505050FF) - borderColor = Color(#000000FF) + %textColor = Color(#505050FF) + %borderColor = Color(#000000FF) } % =================================================== diff --git a/src/ogfx/gui/Widgets.cpp b/src/ogfx/gui/Widgets.cpp index 26c470d..eb34147 100644 --- a/src/ogfx/gui/Widgets.cpp +++ b/src/ogfx/gui/Widgets.cpp @@ -20,6 +20,7 @@ #include "Widgets.hpp" #include "gui/Events.hpp" +#include "io/Memory.hpp" #include "utils/Keycodes.hpp" #include #include @@ -356,6 +357,22 @@ namespace ogfx return false; } + bool Widget::addThemeID(const ostd::String& id) + { + if (STDVEC_CONTAINS(m_themeIDList, id)) + return false; + m_themeIDList.push_back(id); + return true; + } + + bool Widget::removeThemeID(const ostd::String& id) + { + if (!STDVEC_CONTAINS(m_themeIDList, id)) + return false; + STDVEC_REMOVE(m_themeIDList, id); + return true; + } + void Widget::__draw(ogfx::BasicRenderer2D& gfx) { if (isDrawBoxEnabled()) @@ -551,7 +568,7 @@ namespace ogfx void RootWidget::applyTheme(const ostd::Stylesheet& theme) { - m_color = theme.get("window.backgroundColor", getWindow().getClearColor(), getThemeID(), getThemeQualifierList()); + m_color = getThemeValue(theme, "window.backgroundColor", getWindow().getClearColor()); } void RootWidget::onDraw(ogfx::BasicRenderer2D& gfx) @@ -575,15 +592,15 @@ namespace ogfx void Label::applyTheme(const ostd::Stylesheet& theme) { - setColor(theme.get("label.textColor", ostd::Colors::White, getThemeID(), getThemeQualifierList())); - setBackGroundColor(theme.get("label.backgroundColor", ostd::Colors::Transparent, getThemeID(), getThemeQualifierList())); - setFontSize(theme.get("label.fontSize", 20, getThemeID(), getThemeQualifierList())); - m_borderRadius = theme.get("label.borderRadius", 10, getThemeID(), getThemeQualifierList()); - m_borderWidth = theme.get("label.borderWidth", 2, getThemeID(), getThemeQualifierList()); - m_showBorder = theme.get("label.showBorder", false, getThemeID(), getThemeQualifierList()); - m_borderColor = theme.get("label.borderColor", ostd::Colors::White, getThemeID(), getThemeQualifierList()); - enableBackground(theme.get("label.showBackground", false, getThemeID(), getThemeQualifierList())); - setPadding(theme.get("label.padding", { 5, 5, 5, 5 }, getThemeID(), getThemeQualifierList())); + setColor(getThemeValue(theme, "label.textColor", ostd::Colors::White)); + setBackGroundColor(getThemeValue(theme, "label.backgroundColor", ostd::Colors::Transparent)); + setFontSize(getThemeValue(theme, "label.fontSize", 20)); + m_borderRadius = getThemeValue(theme, "label.borderRadius", 10); + m_borderWidth = getThemeValue(theme, "label.borderWidth", 2); + m_showBorder = getThemeValue(theme, "label.showBorder", false); + m_borderColor = getThemeValue(theme, "label.borderColor", ostd::Colors::White); + enableBackground(getThemeValue(theme, "label.showBackground", false)); + setPadding(getThemeValue(theme, "label.padding", { 5, 5, 5, 5 })); } void Label::onDraw(ogfx::BasicRenderer2D& gfx) diff --git a/src/ogfx/gui/Widgets.hpp b/src/ogfx/gui/Widgets.hpp index d73bb2f..0015e6b 100644 --- a/src/ogfx/gui/Widgets.hpp +++ b/src/ogfx/gui/Widgets.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #include namespace ogfx @@ -90,6 +91,8 @@ namespace ogfx void reloadTheme(void); void setThemeQualifier(const ostd::String& qualifier, bool value = true); bool getThemeQualifier(const ostd::String& qualifier); + bool addThemeID(const ostd::String& id); + bool removeThemeID(const ostd::String& id); inline const ostd::Stylesheet::QualifierList& getThemeQualifierList(void) const { return m_qualifierList; } inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { } @@ -155,8 +158,13 @@ namespace ogfx inline Rectangle getPadding(void) { return m_padding; } inline bool isMouseInside(void) const { return m_mouseInside; } inline ogfx::MouseEventData::eButton getPressedMouseButton(void) const { return m_pressedButton; } - inline ostd::String getThemeID(void) const { return m_themeID; } - inline void setThemeID(const ostd::String& id) { m_themeID = id; } + inline const std::vector& getThemeIDList(void) const { return m_themeIDList; } + + template + inline T getThemeValue(const ostd::Stylesheet &theme, const ostd::String& key, const T& fallback) + { + return theme.get(key, fallback, getThemeIDList(), getThemeQualifierList()); + } protected: inline void disableChildren(void) { m_allowChildren = false; } @@ -194,7 +202,7 @@ namespace ogfx bool m_mouseInside { false }; MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None }; - ostd::String m_themeID { "" }; + std::vector m_themeIDList; ostd::Stylesheet::QualifierList m_qualifierList { { "disabled", false }, { "pressed", false }, diff --git a/src/ostd/io/Memory.hpp b/src/ostd/io/Memory.hpp index 58d9203..71d09a5 100644 --- a/src/ostd/io/Memory.hpp +++ b/src/ostd/io/Memory.hpp @@ -25,6 +25,7 @@ #include #define STDVEC_CONTAINS(vec, elem) (std::find(vec.begin(), vec.end(), elem) != vec.end()) +#define STDVEC_REMOVE(vec, elem) (vec.erase(std::remove(vec.begin(), vec.end(), elem), vec.end())) namespace ostd { diff --git a/src/ostd/io/Stylesheet.cpp b/src/ostd/io/Stylesheet.cpp index b1e53d2..e91f02c 100644 --- a/src/ostd/io/Stylesheet.cpp +++ b/src/ostd/io/Stylesheet.cpp @@ -151,35 +151,35 @@ namespace ostd m_values[fullKey] = std::move(value); } - const Stylesheet::TypeVariant* Stylesheet::getVariant(const ostd::String& key, const ostd::String& themeID, const QualifierList& qualifierList) const + const Stylesheet::TypeVariant* Stylesheet::getVariant(const ostd::String& key, const std::vector& themeIDList, const QualifierList& qualifierList) const { + std::vector emptyThemeIDList { "" }; + const std::vector& __themeIDList = (themeIDList.size() == 0 ? emptyThemeIDList : themeIDList); for (const auto&[qualifier, state] : qualifierList) { - const TypeVariant* v = (state ? getFull("@" + themeID + ":" + qualifier + "." + key) : nullptr); - // std::cout << "0: " << "@" + themeID + ":" + qualifier + "." + key << "\n"; - if (v) + const TypeVariant* v = nullptr; + for (int32_t i = __themeIDList.size() - 1; i >= 0; i--) { - std::cout << "1: " << "@" + themeID + ":" + qualifier + "." + key << "\n"; - return v; - } - v = (state ? getFull("@:" + qualifier + "." + key) : nullptr); - if (v) - { - std::cout << "2: " << "@:" + qualifier + "." + key << "\n"; - return v; + const ostd::String& themeID = __themeIDList[i]; + v = (state ? getFull("@" + themeID + ":" + qualifier + "." + key) : nullptr); + if (v) + return v; } } - if (auto v = getFull("@" + themeID + "." + key)) + for (const auto&[qualifier, state] : qualifierList) { - std::cout << "3: " << "@" + themeID + "." + key << "\n"; - return v; + const TypeVariant* v = (state ? getFull("@:" + qualifier + "." + key) : nullptr); + if (v) + return v; } - else if (auto v = getFull("@." + key)) + for (int32_t i = __themeIDList.size() - 1; i >= 0; i--) { - std::cout << "4: " << "@." + key << "\n"; - return v; + const ostd::String& themeID = __themeIDList[i]; + if (auto v = getFull("@" + themeID + "." + key)) + return v; } - std::cout << "\n\n"; + if (auto v = getFull("@." + key)) + return v; return nullptr; } diff --git a/src/ostd/io/Stylesheet.hpp b/src/ostd/io/Stylesheet.hpp index d6791c7..bd84d6e 100644 --- a/src/ostd/io/Stylesheet.hpp +++ b/src/ostd/io/Stylesheet.hpp @@ -38,13 +38,13 @@ namespace ostd Stylesheet& loadFromString(const ostd::String& content, const ostd::String& filePath = "memory://", bool clearCurrentRules = true); void set(const std::string& key, TypeVariant value, const ostd::String& themeID); void setFull(const ostd::String& fullKey, TypeVariant value); - const TypeVariant* getVariant(const ostd::String& key, const ostd::String& themeID, const QualifierList& qualifierList) const; + const TypeVariant* getVariant(const ostd::String& key, const std::vector& themeIDList, const QualifierList& qualifierList) const; const TypeVariant* getFull(const ostd::String& fullKey) const; template - inline T get(const ostd::String& key, const T& fallback, const ostd::String& themeID, const QualifierList& qualifierList) const + inline T get(const ostd::String& key, const T& fallback, const std::vector& themeIDList, const QualifierList& qualifierList) const { - if (auto v = getVariant(key, themeID, qualifierList)) + if (auto v = getVariant(key, themeIDList, qualifierList)) { if (auto p = std::get_if(v)) return *p; diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index 3aa8871..3ae5964 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -62,16 +62,18 @@ class Window : public ogfx::gui::Window // m_label1.setMouseDraggedCallback([&](const ogfx::gui::Event& event) -> void { // m_label1.applyThemeValue(m_theme, "label.backgroundColor", ostd::Colors::DarkGreen, false); // }); - addWidget(m_label1); - m_label1.setThemeQualifier("disabled"); + // addWidget(m_label1); + // m_label1.setThemeQualifier("disabled"); m_label2.setPosition(100, 400); m_label2.setText("Ciccia Bella!"); - m_label2.setThemeID("testLabel"); + m_label2.addThemeID("testLabel"); + m_label2.addThemeID("testLabel2"); addWidget(m_label2); m_theme.loadFromFile("./testTheme.txt"); setTheme(m_theme); + m_theme.debugPrint(); } inline void onSignal(ostd::Signal& signal) override