diff --git a/extra/testTheme.txt b/extra/testTheme.txt index abfffa4..2ea4098 100644 --- a/extra/testTheme.txt +++ b/extra/testTheme.txt @@ -1,28 +1,37 @@ % ================== testTheme.txt ================== +% ---- Variables ---- $accentColor = Color(rgba(255, 0, 255, 255)) +$color2 = Color(#0000FFFF) +% ------------------- -% Window window.backgroundColor = Color(rgba(40, 0, 0, 255)) -% Label -label.textColor = $accentColor -label.backgroundColor = Color(#000000FF) -label.borderColor = $accentColor -label.fontSize = 30 -label.borderRadius = 20 -label.borderWidth = 2 -label.showBackground = true -label.showBorder = true -label.padding = Rect(15, 15, 15, 15) +(label) { + textColor = $accentColor + backgroundColor = Color(#000000FF) + borderColor = $accentColor + fontSize = 50 + borderRadius = 20 + borderWidth = 2 + showBackground = true + showBorder = true + padding = Rect(15, 15, 15, 15) +} -% Format: -% @ID:QUALIFIER PROPERTY = VALUE +(@testLabel label) { + 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:hover label.textColor = Color(#000040FF) -@testLabel:hover label.backgroundColor = Color(#400040FF) -@testWindow window.backgroundColor = Color(#004000FF) +(@testLabel label:hover) { + borderColor = $color2 +} % =================================================== diff --git a/other/build.nr b/other/build.nr index c05d464..9adbd23 100644 --- a/other/build.nr +++ b/other/build.nr @@ -1 +1 @@ -2041 +2042 diff --git a/src/ogfx/gui/Widgets.cpp b/src/ogfx/gui/Widgets.cpp index 4b065c6..0edd3e0 100644 --- a/src/ogfx/gui/Widgets.cpp +++ b/src/ogfx/gui/Widgets.cpp @@ -571,7 +571,7 @@ namespace ogfx gfx.fillRoundRect({ getGlobalPosition(), getSize() }, m_backgroundColor, m_borderRadius); if (m_showBorder) 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) diff --git a/src/ostd/io/Stylesheet.cpp b/src/ostd/io/Stylesheet.cpp index e30b964..2f6b273 100644 --- a/src/ostd/io/Stylesheet.cpp +++ b/src/ostd/io/Stylesheet.cpp @@ -43,10 +43,23 @@ namespace ostd Stylesheet& Stylesheet::loadFromString(const ostd::String& content, const ostd::String& filePath) { + std::vector lines = content.tokenize("\n", false, true).getRawData(); uint32_t lineNumber = 0; ostd::String lineCopy = ""; std::unordered_map 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 group; for (auto& line : lines) { lineNumber++; @@ -63,23 +76,65 @@ namespace ostd line.substr(1); 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; } ostd::String varName = line.new_substr(0, line.indexOf("=")).trim(); ostd::String varValue = line.new_substr(line.indexOf("=") + 1).trim(); 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; } variables["$" + varName] = varValue; continue; } - for (const auto&[var, val] : variables) - line.replaceAll(var, val); - if (!parseThemeFileLine(line)) - OX_WARN("Invalid theme line: File <%s:%d>:\n\t%s", filePath.c_str(), lineNumber, lineCopy.c_str()); + if (groupSelector != "") + { + if (groupLines) + { + 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; } @@ -191,4 +246,44 @@ namespace ostd return false; 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 Stylesheet::parseGroup(const ostd::String& selector, const std::vector& group) + { + if (selector.new_trim() == "" || group.size() == 0) + return {}; + std::vector newLines; + for (const auto& property : group) + newLines.push_back(selector.new_add(".").new_add(property)); + return newLines; + } } diff --git a/src/ostd/io/Stylesheet.hpp b/src/ostd/io/Stylesheet.hpp index 485006f..2e083d1 100644 --- a/src/ostd/io/Stylesheet.hpp +++ b/src/ostd/io/Stylesheet.hpp @@ -53,6 +53,8 @@ namespace ostd private: bool parseThemeFileLine(const ostd::String& line); + ostd::String parseGroupSelector(const ostd::String& rawSelector) const; + std::vector parseGroup(const ostd::String& selector, const std::vector& group); private: std::unordered_map m_values;