Added more qualifiers to the Stylesheet system

This commit is contained in:
OmniaX-Dev 2026-04-05 04:52:16 +02:00
parent aebf9c1d14
commit 234aa60ddd
6 changed files with 105 additions and 35 deletions

View file

@ -30,8 +30,23 @@ window.backgroundColor = Color(rgba(40, 0, 0, 255))
borderColor = Color(rgb(0, 255, 0))
}
(label:pressed) {
textColor = Color(#FF0000FF)
}
(@testLabel label:hover) {
borderColor = $color2
}
(@testLabel label:pressed) {
backgroundColor = Color(#0040AAFF)
textColor = Color(#505050FF)
}
(label:disabled) {
backgroundColor = Color(#EEEEEEFF)
textColor = Color(#505050FF)
borderColor = Color(#000000FF)
}
% ===================================================

View file

@ -333,6 +333,29 @@ namespace ogfx
}
}
void Widget::setThemeQualifier(const ostd::String& qualifier, bool value)
{
for (auto& [name, state] : m_qualifierList)
{
if (name == qualifier)
{
state = value;
reloadTheme();
return;
}
}
}
bool Widget::getThemeQualifier(const ostd::String& qualifier)
{
for (auto& [name, state] : m_qualifierList)
{
if (name == qualifier)
return state;
}
return false;
}
void Widget::__draw(ogfx::BasicRenderer2D& gfx)
{
if (isDrawBoxEnabled())
@ -351,6 +374,7 @@ namespace ogfx
void Widget::__onMousePressed(const Event& event)
{
setThemeQualifier("pressed");
if (hasChildren())
m_widgets.onMousePressed(event);
if (!event.isHandled())
@ -364,6 +388,7 @@ namespace ogfx
void Widget::__onMouseReleased(const Event& event)
{
setThemeQualifier("pressed", false);
m_pressedButton = ogfx::MouseEventData::eButton::None;
if (hasChildren())
m_widgets.onMouseReleased(event);
@ -389,8 +414,7 @@ namespace ogfx
void Widget::__onMouseEntered(const Event& event)
{
m_qualifier = "hover";
reloadTheme();
setThemeQualifier("hover");
if (callback_onMouseEntered)
callback_onMouseEntered(event);
onMouseEntered(event);
@ -398,8 +422,7 @@ namespace ogfx
void Widget::__onMouseExited(const Event& event)
{
m_qualifier = "";
reloadTheme();
setThemeQualifier("hover", false);
if (callback_onMouseExited)
callback_onMouseExited(event);
onMouseExited(event);
@ -528,7 +551,7 @@ namespace ogfx
void RootWidget::applyTheme(const ostd::Stylesheet& theme)
{
m_color = theme.get<ostd::Color>("window.backgroundColor", getWindow().getClearColor(), getThemeID(), getThemeQualifier());
m_color = theme.get<ostd::Color>("window.backgroundColor", getWindow().getClearColor(), getThemeID(), getThemeQualifierList());
}
void RootWidget::onDraw(ogfx::BasicRenderer2D& gfx)
@ -552,15 +575,15 @@ namespace ogfx
void Label::applyTheme(const ostd::Stylesheet& theme)
{
setColor(theme.get<ostd::Color>("label.textColor", ostd::Colors::White, getThemeID(), getThemeQualifier()));
setBackGroundColor(theme.get<ostd::Color>("label.backgroundColor", ostd::Colors::Transparent, getThemeID(), getThemeQualifier()));
setFontSize(theme.get<int32_t>("label.fontSize", 20, getThemeID(), getThemeQualifier()));
m_borderRadius = theme.get<int32_t>("label.borderRadius", 10, getThemeID(), getThemeQualifier());
m_borderWidth = theme.get<int32_t>("label.borderWidth", 2, getThemeID(), getThemeQualifier());
m_showBorder = theme.get<bool>("label.showBorder", false, getThemeID(), getThemeQualifier());
m_borderColor = theme.get<ostd::Color>("label.borderColor", ostd::Colors::White, getThemeID(), getThemeQualifier());
enableBackground(theme.get<bool>("label.showBackground", false, getThemeID(), getThemeQualifier()));
setPadding(theme.get<ostd::Rectangle>("label.padding", { 5, 5, 5, 5 }, getThemeID(), getThemeQualifier()));
setColor(theme.get<ostd::Color>("label.textColor", ostd::Colors::White, getThemeID(), getThemeQualifierList()));
setBackGroundColor(theme.get<ostd::Color>("label.backgroundColor", ostd::Colors::Transparent, getThemeID(), getThemeQualifierList()));
setFontSize(theme.get<int32_t>("label.fontSize", 20, getThemeID(), getThemeQualifierList()));
m_borderRadius = theme.get<int32_t>("label.borderRadius", 10, getThemeID(), getThemeQualifierList());
m_borderWidth = theme.get<int32_t>("label.borderWidth", 2, getThemeID(), getThemeQualifierList());
m_showBorder = theme.get<bool>("label.showBorder", false, getThemeID(), getThemeQualifierList());
m_borderColor = theme.get<ostd::Color>("label.borderColor", ostd::Colors::White, getThemeID(), getThemeQualifierList());
enableBackground(theme.get<bool>("label.showBackground", false, getThemeID(), getThemeQualifierList()));
setPadding(theme.get<ostd::Rectangle>("label.padding", { 5, 5, 5, 5 }, getThemeID(), getThemeQualifierList()));
}
void Label::onDraw(ogfx::BasicRenderer2D& gfx)

View file

@ -88,6 +88,9 @@ namespace ogfx
virtual void applyTheme(const ostd::Stylesheet& theme) = 0;
void addThemeOverride(const ostd::String& key, ostd::Stylesheet::TypeVariant value, const ostd::String& themeID = "", const ostd::String& qualifier = "", bool propagate = true);
void reloadTheme(void);
void setThemeQualifier(const ostd::String& qualifier, bool value = true);
bool getThemeQualifier(const ostd::String& qualifier);
inline const ostd::Stylesheet::QualifierList& getThemeQualifierList(void) const { return m_qualifierList; }
inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { }
inline virtual void onUpdate(void) { }
@ -154,7 +157,6 @@ namespace ogfx
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 ostd::String getThemeQualifier(void) const { return m_qualifier; }
protected:
inline void disableChildren(void) { m_allowChildren = false; }
@ -193,7 +195,13 @@ namespace ogfx
MouseEventData::eButton m_pressedButton { MouseEventData::eButton::None };
ostd::String m_themeID { "" };
ostd::String m_qualifier { "" };
ostd::Stylesheet::QualifierList m_qualifierList {
{ "disabled", false },
{ "pressed", false },
{ "hover", false },
{ "focused", false },
{ "active", false }
};
std::vector<ThemeOverride> m_themeOverrides;
bool m_drawBox { true };

View file

@ -34,16 +34,17 @@ namespace ostd
return *this;
}
Stylesheet& Stylesheet::loadFromFile(const ostd::String& filePath)
Stylesheet& Stylesheet::loadFromFile(const ostd::String& filePath, bool clearCurrentRules)
{
ostd::String outContent = "";
ostd::FileSystem::readTextFileRaw(filePath, outContent);
return loadFromString(outContent, filePath);
return loadFromString(outContent, filePath, clearCurrentRules);
}
Stylesheet& Stylesheet::loadFromString(const ostd::String& content, const ostd::String& filePath)
Stylesheet& Stylesheet::loadFromString(const ostd::String& content, const ostd::String& filePath, bool clearCurrentRules)
{
if (clearCurrentRules)
m_values.clear();
std::vector<ostd::String> lines = content.tokenize("\n", false, true).getRawData();
uint32_t lineNumber = 0;
ostd::String lineCopy = "";
@ -121,7 +122,6 @@ namespace ostd
}
ostd::String rawSelector = line.new_substr(1, line.indexOf(")")).trim();
groupSelector = parseGroupSelector(rawSelector);
std::cout << groupSelector << "\n";
if (line.contains("{"))
{
line.substr(line.indexOf("{")).trim();
@ -151,31 +151,43 @@ namespace ostd
m_values[fullKey] = std::move(value);
}
const Stylesheet::TypeVariant* Stylesheet::getVariant(const ostd::String& key, const ostd::String& themeID, const ostd::String& qualifier) const
const Stylesheet::TypeVariant* Stylesheet::getVariant(const ostd::String& key, const ostd::String& themeID, const QualifierList& qualifierList) const
{
if (auto v = getFull("@" + themeID + ":" + qualifier + "." + key))
for (const auto&[qualifier, state] : qualifierList)
{
return v;
const TypeVariant* v = (state ? getFull("@" + themeID + ":" + qualifier + "." + key) : nullptr);
// std::cout << "0: " << "@" + themeID + ":" + qualifier + "." + key << "\n";
if (v)
{
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;
}
}
else if (auto v = getFull("@:" + qualifier + "." + key))
{
return v;
}
else if (auto v = getFull("@" + themeID + "." + key))
if (auto v = getFull("@" + themeID + "." + key))
{
std::cout << "3: " << "@" + themeID + "." + key << "\n";
return v;
}
else if (auto v = getFull("@." + key))
{
std::cout << "4: " << "@." + key << "\n";
return v;
}
std::cout << "\n\n";
return nullptr;
}
const Stylesheet::TypeVariant* Stylesheet::getFull(const ostd::String& fullKey) const
{
// std::cout << " GET: " << key << "\n";
auto it = m_values.find(fullKey);
// if (it != m_values.end())
// std::cout << " GET: " << fullKey << "\n";
return it != m_values.end() ? &it->second : nullptr;
}
@ -286,4 +298,12 @@ namespace ostd
newLines.push_back(selector.new_add(".").new_add(property));
return newLines;
}
void Stylesheet::debugPrint(void)
{
for (const auto&[key, value] : m_values)
{
std::cout << key << "\n";
}
}
}

View file

@ -29,21 +29,22 @@ namespace ostd
{
class Stylesheet
{
public: using QualifierList = std::vector<std::pair<const ostd::String, bool>>;
public: using TypeVariant = std::variant<int32_t, float, bool, ostd::String, ostd::Color, ostd::Rectangle, ostd::Vec2>;
public:
Stylesheet(void);
Stylesheet& clear(void);
Stylesheet& loadFromFile(const ostd::String& filePath);
Stylesheet& loadFromString(const ostd::String& content, const ostd::String& filePath = "memory://");
Stylesheet& loadFromFile(const ostd::String& filePath, bool clearCurrentRules = true);
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 ostd::String& qualifier) const;
const TypeVariant* getVariant(const ostd::String& key, const ostd::String& themeID, const QualifierList& qualifierList) const;
const TypeVariant* getFull(const ostd::String& fullKey) const;
template<typename T>
inline T get(const ostd::String& key, const T& fallback, const ostd::String& themeID, const ostd::String& qualifier) const
inline T get(const ostd::String& key, const T& fallback, const ostd::String& themeID, const QualifierList& qualifierList) const
{
if (auto v = getVariant(key, themeID, qualifier))
if (auto v = getVariant(key, themeID, qualifierList))
{
if (auto p = std::get_if<T>(v))
return *p;
@ -51,6 +52,8 @@ namespace ostd
return fallback;
}
void debugPrint(void);
private:
bool parseThemeFileLine(const ostd::String& line);
ostd::String parseGroupSelector(const ostd::String& rawSelector) const;

View file

@ -63,6 +63,7 @@ class Window : public ogfx::gui::Window
// m_label1.applyThemeValue(m_theme, "label.backgroundColor", ostd::Colors::DarkGreen, false);
// });
addWidget(m_label1);
m_label1.setThemeQualifier("disabled");
m_label2.setPosition(100, 400);
m_label2.setText("Ciccia Bella!");