Added selector groups to stylesheets

This commit is contained in:
OmniaX-Dev 2026-04-04 14:13:58 +02:00
parent 39c9798760
commit 91bbfaf36f
5 changed files with 131 additions and 25 deletions

View file

@ -1,28 +1,37 @@
% ================== testTheme.txt ================== % ================== testTheme.txt ==================
% ---- Variables ----
$accentColor = Color(rgba(255, 0, 255, 255)) $accentColor = Color(rgba(255, 0, 255, 255))
$color2 = Color(#0000FFFF)
% -------------------
% Window
window.backgroundColor = Color(rgba(40, 0, 0, 255)) window.backgroundColor = Color(rgba(40, 0, 0, 255))
% Label (label) {
label.textColor = $accentColor textColor = $accentColor
label.backgroundColor = Color(#000000FF) backgroundColor = Color(#000000FF)
label.borderColor = $accentColor borderColor = $accentColor
label.fontSize = 30 fontSize = 50
label.borderRadius = 20 borderRadius = 20
label.borderWidth = 2 borderWidth = 2
label.showBackground = true showBackground = true
label.showBorder = true showBorder = true
label.padding = Rect(15, 15, 15, 15) padding = Rect(15, 15, 15, 15)
}
% Format: (@testLabel label) {
% @ID:QUALIFIER PROPERTY = VALUE textColor = $color2
backgroundColor = Color(#000000FF)
fontSize = 20
}
(label:hover) {
textColor = Color(rgb(0, 255, 0))
borderColor = Color(rgb(0, 255, 0))
}
@testLabel label.textColor = Color(#004000FF) (@testLabel label:hover) {
@testLabel:hover label.textColor = Color(#000040FF) borderColor = $color2
@testLabel:hover label.backgroundColor = Color(#400040FF) }
@testWindow window.backgroundColor = Color(#004000FF)
% =================================================== % ===================================================

View file

@ -1 +1 @@
2041 2042

View file

@ -571,7 +571,7 @@ namespace ogfx
gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius); gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius);
if (m_showBorder) if (m_showBorder)
gfx.drawRoundRect({ getGlobalPosition(), getSize() }, m_borderColor, m_borderRadius, m_borderWidth); gfx.drawRoundRect({ getGlobalPosition(), getSize() }, m_borderColor, m_borderRadius, m_borderWidth);
gfx.drawString(getText(), getGlobalPosition() + ostd::Vec2 { getPadding().left(), getPadding().top() }, getColor()); gfx.drawString(getText(), getGlobalPosition() + ostd::Vec2 { getPadding().left(), getPadding().top() }, getColor(), getFontSize());
} }
void Label::setText(const ostd::String& text) void Label::setText(const ostd::String& text)

View file

@ -43,10 +43,23 @@ namespace ostd
Stylesheet& Stylesheet::loadFromString(const ostd::String& content, const ostd::String& filePath) Stylesheet& Stylesheet::loadFromString(const ostd::String& content, const ostd::String& filePath)
{ {
std::vector<ostd::String> lines = content.tokenize("\n", false, true).getRawData(); std::vector<ostd::String> lines = content.tokenize("\n", false, true).getRawData();
uint32_t lineNumber = 0; uint32_t lineNumber = 0;
ostd::String lineCopy = ""; ostd::String lineCopy = "";
std::unordered_map<ostd::String, ostd::String> variables; std::unordered_map<ostd::String, ostd::String> variables;
auto l_warn = [&](const ostd::String& msg) -> void {
OX_WARN("%s in theme line. File: <%s:%d>:\n\t%s", msg.c_str(), filePath.c_str(), lineNumber, lineCopy.c_str());
};
auto l_parseLine = [&](ostd::String& line) -> void {
for (const auto&[var, val] : variables)
line.replaceAll(var, val);
if (!parseThemeFileLine(line))
l_warn("Error");
};
ostd::String groupSelector = "";
bool groupLines = false;
std::vector<ostd::String> group;
for (auto& line : lines) for (auto& line : lines)
{ {
lineNumber++; lineNumber++;
@ -63,23 +76,65 @@ namespace ostd
line.substr(1); line.substr(1);
if (line.count("=") != 1 || line.endsWith("=")) if (line.count("=") != 1 || line.endsWith("="))
{ {
OX_WARN("Invalid variable in theme line. File: <%s:%d>:\n\t%s", filePath.c_str(), lineNumber, lineCopy.c_str()); l_warn("Invalid variable");
continue; continue;
} }
ostd::String varName = line.new_substr(0, line.indexOf("=")).trim(); ostd::String varName = line.new_substr(0, line.indexOf("=")).trim();
ostd::String varValue = line.new_substr(line.indexOf("=") + 1).trim(); ostd::String varValue = line.new_substr(line.indexOf("=") + 1).trim();
if (!varName.regexMatches(m_validNameRegex)) if (!varName.regexMatches(m_validNameRegex))
{ {
OX_WARN("Invalid variable name in theme line. File: <%s:%d>:\n\t%s", filePath.c_str(), lineNumber, lineCopy.c_str()); l_warn("Invalid variable name");
continue; continue;
} }
variables["$" + varName] = varValue; variables["$" + varName] = varValue;
continue; continue;
} }
for (const auto&[var, val] : variables) if (groupSelector != "")
line.replaceAll(var, val); {
if (!parseThemeFileLine(line)) if (groupLines)
OX_WARN("Invalid theme line: File <%s:%d>:\n\t%s", filePath.c_str(), lineNumber, lineCopy.c_str()); {
if (line == "}")
{
groupLines = false;
auto newLines = parseGroup(groupSelector, group);
for (auto& l : newLines)
l_parseLine(l);
groupSelector = "";
group.clear();
continue;
}
group.push_back(line);
}
else
{
if (line == "{")
groupLines = true;
}
continue;
}
if (line.startsWith("("))
{
if (line.count(")") != 1 || line.indexOf(")") < 3)
{
l_warn("Invalid group selector");
continue;
}
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();
if (line != "{")
{
l_warn("Invalid group selector");
continue;
}
groupLines = true;
}
continue;
}
l_parseLine(line);
} }
return *this; return *this;
} }
@ -191,4 +246,44 @@ namespace ostd
return false; return false;
return true; return true;
} }
ostd::String Stylesheet::parseGroupSelector(const ostd::String& rawSelector) const
{
ostd::String sel = rawSelector.new_trim();
if (sel == "") return "";
ostd::String id = "";
ostd::String name = sel;
ostd::String qual = "";
if (sel.contains(" "))
{
id = sel.new_substr(0, sel.indexOf(" ")).trim();
name = sel.new_substr(sel.indexOf(" ") + 1).trim();
}
if (name.contains(":"))
{
if (name.startsWith(":") || name.endsWith(":") || name.count(":") != 1)
return "";
qual = name.new_substr(name.indexOf(":") + 1).trim();
name.substr(0, name.indexOf(":")).trim();
}
if (qual != "")
{
if (!id.startsWith("@"))
id = "@" + id;
id += ":" + qual;
}
id += " " + name;
id.trim();
return id;
}
std::vector<ostd::String> Stylesheet::parseGroup(const ostd::String& selector, const std::vector<ostd::String>& group)
{
if (selector.new_trim() == "" || group.size() == 0)
return {};
std::vector<ostd::String> newLines;
for (const auto& property : group)
newLines.push_back(selector.new_add(".").new_add(property));
return newLines;
}
} }

View file

@ -53,6 +53,8 @@ namespace ostd
private: private:
bool parseThemeFileLine(const ostd::String& line); bool parseThemeFileLine(const ostd::String& line);
ostd::String parseGroupSelector(const ostd::String& rawSelector) const;
std::vector<ostd::String> parseGroup(const ostd::String& selector, const std::vector<ostd::String>& group);
private: private:
std::unordered_map<ostd::String, TypeVariant> m_values; std::unordered_map<ostd::String, TypeVariant> m_values;