Added nested selectors to stylesheets
This commit is contained in:
parent
40b51bf3dc
commit
777124579f
7 changed files with 116 additions and 47 deletions
|
|
@ -30,7 +30,7 @@ window.backgroundColor = rgba(160, 160, 160, 255)
|
|||
titlebarHeight = 18
|
||||
titlebarFontSize = 18
|
||||
titlebarTextAlign = text_left
|
||||
% scrollSpeed = Vec2(0.8, 0.8)
|
||||
scrollSpeed = Vec2(0.8, 0.8)
|
||||
padding = Rect(15, 15, 15, 15)
|
||||
margin = Rect(0, 0, 0, 0)
|
||||
}
|
||||
|
|
@ -39,11 +39,25 @@ window.backgroundColor = rgba(160, 160, 160, 255)
|
|||
|
||||
|
||||
% ====== Scrollbar ======
|
||||
% (scrollbar) {
|
||||
% (handle) {
|
||||
|
||||
% }
|
||||
% }
|
||||
(scrollbar) {
|
||||
width = 20
|
||||
(handle) {
|
||||
color = #333333FF
|
||||
}
|
||||
(track) {
|
||||
color = #555555FF
|
||||
}
|
||||
}
|
||||
(scrollbar:handle_hover) {
|
||||
(handle) {
|
||||
color = $accentColorDark
|
||||
}
|
||||
}
|
||||
(scrollbar:handle_pressed) {
|
||||
(handle) {
|
||||
color = $accentColorDark
|
||||
}
|
||||
}
|
||||
% =======================
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ namespace ogfx
|
|||
connectSignal(ostd::BuiltinSignals::FileDragAndDropped);
|
||||
connectSignal(ostd::BuiltinSignals::TextDragAndDropped);
|
||||
|
||||
setCursor(eCursor::Default);
|
||||
|
||||
__on_window_init(width, height, title);
|
||||
setSize(m_windowWidth, m_windowHeight);
|
||||
}
|
||||
|
|
@ -237,12 +239,41 @@ namespace ogfx
|
|||
case eCursor::W_Resize:
|
||||
SDL_SetCursor(m_cursor_W_Resize);
|
||||
break;
|
||||
case eCursor::NoCursor:
|
||||
default:
|
||||
SDL_SetCursor(m_cursor_Default);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WindowCore::eCursor WindowCore::getCurosr(void) const
|
||||
{
|
||||
auto cur = SDL_GetCursor();
|
||||
if (cur == m_cursor_Default) return eCursor::Default;
|
||||
if (cur == m_cursor_Text) return eCursor::Text;
|
||||
if (cur == m_cursor_Wait) return eCursor::Wait;
|
||||
if (cur == m_cursor_Crosshair) return eCursor::Crosshair;
|
||||
if (cur == m_cursor_Progress) return eCursor::Progress;
|
||||
if (cur == m_cursor_NWSE_Resize) return eCursor::NWSE_Resize;
|
||||
if (cur == m_cursor_NESW_Resize) return eCursor::NESW_Resize;
|
||||
if (cur == m_cursor_EW_Resize) return eCursor::EW_Resize;
|
||||
if (cur == m_cursor_NS_Resize) return eCursor::NS_Resize;
|
||||
if (cur == m_cursor_Move) return eCursor::Move;
|
||||
if (cur == m_cursor_NotAllowed) return eCursor::NotAllowed;
|
||||
if (cur == m_cursor_Pointer) return eCursor::Pointer;
|
||||
|
||||
if (cur == m_cursor_NW_Resize) return eCursor::NW_Resize;
|
||||
if (cur == m_cursor_N_Resize) return eCursor::N_Resize;
|
||||
if (cur == m_cursor_NE_Resize) return eCursor::NE_Resize;
|
||||
if (cur == m_cursor_E_Resize) return eCursor::E_Resize;
|
||||
if (cur == m_cursor_SE_Resize) return eCursor::SE_Resize;
|
||||
if (cur == m_cursor_S_Resize) return eCursor::S_Resize;
|
||||
if (cur == m_cursor_SW_Resize) return eCursor::SW_Resize;
|
||||
if (cur == m_cursor_W_Resize) return eCursor::W_Resize;
|
||||
|
||||
return eCursor::Default;
|
||||
}
|
||||
|
||||
void WindowCore::enableResizable(bool enable)
|
||||
{
|
||||
SDL_SetWindowResizable(m_window, enable);
|
||||
|
|
@ -443,6 +474,7 @@ namespace ogfx
|
|||
m_defaultStylesheetVariables["cursor_s_resize"] = { String("").add(cast<i32>(eCursor::S_Resize)), true };
|
||||
m_defaultStylesheetVariables["cursor_sw_resize"] = { String("").add(cast<i32>(eCursor::SW_Resize)), true };
|
||||
m_defaultStylesheetVariables["cursor_w_resize"] = { String("").add(cast<i32>(eCursor::W_Resize)), true };
|
||||
m_defaultStylesheetVariables["cursor_inherit"] = { String("").add(cast<i32>(eCursor::NoCursor)), true };
|
||||
|
||||
// Colors
|
||||
m_defaultStylesheetVariables["color_transparent"] = { "Color(" + Colors::Transparent.hexString(true, "#") + ")", true };
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@ namespace ogfx
|
|||
SW_Resize,
|
||||
W_Resize,
|
||||
|
||||
Count
|
||||
Count,
|
||||
NoCursor = 255
|
||||
};
|
||||
public: enum class eTextAlign : u8 {
|
||||
Default = 0,
|
||||
|
|
@ -74,6 +75,7 @@ namespace ogfx
|
|||
void setSize(i32 width, i32 height);
|
||||
void setTitle(const String& title);
|
||||
void setCursor(eCursor cursor);
|
||||
eCursor getCurosr(void) const;
|
||||
void enableResizable(bool enable = true);
|
||||
void setIcon(const String& iconFilePath);
|
||||
void setBlockingEventsRefreshFPS(u32 fps);
|
||||
|
|
|
|||
|
|
@ -82,13 +82,13 @@ namespace ogfx
|
|||
f32 maxScroll = -(ext.h - cont.h);
|
||||
if (event.mouse->scroll == MouseEventData::eScrollDirection::Down && m_scrollOffset.y > maxScroll)
|
||||
{
|
||||
m_scrollOffset -= (m_scrollSpeed * 15.0f);
|
||||
m_scrollOffset.y -= (m_scrollSpeed.y * 15.0f);
|
||||
if (m_scrollOffset.y < maxScroll)
|
||||
m_scrollOffset.y = maxScroll;
|
||||
}
|
||||
else if (event.mouse->scroll == MouseEventData::eScrollDirection::Up && m_scrollOffset.y < 0)
|
||||
{
|
||||
m_scrollOffset += (m_scrollSpeed * 15.0f);
|
||||
m_scrollOffset.y += (m_scrollSpeed.y * 15.0f);
|
||||
if (m_scrollOffset.y > 0)
|
||||
m_scrollOffset.y = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace ostd
|
|||
{
|
||||
Stylesheet::Stylesheet(void)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
Stylesheet& Stylesheet::clear(void)
|
||||
|
|
@ -47,10 +48,9 @@ namespace ostd
|
|||
m_values.clear();
|
||||
stdvec<String> lines = content.tokenize("\n", false, true).getRawData();
|
||||
stdvec<String> originalLines = lines;
|
||||
auto richLines = getRichStringLines(lines);
|
||||
u32 lineNumber = 0;
|
||||
auto l_warn = [&](const String& msg) -> void {
|
||||
OX_WARN("%s in theme line. File: <%s:%d>", msg.c_str(), filePath.c_str(), lineNumber, originalLines[lineNumber - 1].c_str());
|
||||
OX_WARN("%s in theme line. File: <%s:%d>\n %s", msg.c_str(), filePath.c_str(), lineNumber, originalLines[lineNumber - 1].c_str());
|
||||
};
|
||||
auto l_parseLine = [&](String& line) -> void {
|
||||
if (!parseThemeFileLine(line, variables))
|
||||
|
|
@ -60,17 +60,18 @@ namespace ostd
|
|||
String groupSelector = "";
|
||||
bool groupLines = true;
|
||||
stdvec<String> group;
|
||||
u32 groupSelectorCount = 0;
|
||||
bool debug_print = false;
|
||||
for (auto& line : lines)
|
||||
{
|
||||
lineNumber++;
|
||||
line.trim();
|
||||
if (line.startsWith("%"))
|
||||
goto custom_continue;
|
||||
continue;
|
||||
if (line.contains("%"))
|
||||
line.substr(0, line.indexOf("%")).trim();
|
||||
if (line == "")
|
||||
goto custom_continue;
|
||||
continue;
|
||||
if (line.startsWith("const ") || line.startsWith("$"))
|
||||
{
|
||||
bool is_const = false;
|
||||
|
|
@ -83,29 +84,37 @@ namespace ostd
|
|||
if (line.count("=") != 1 || line.endsWith("="))
|
||||
{
|
||||
l_warn("Invalid variable");
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
String varName = line.new_substr(0, line.indexOf("=")).trim();
|
||||
String varValue = line.new_substr(line.indexOf("=") + 1).trim();
|
||||
if (!varName.regexMatches(m_validNameRegex))
|
||||
{
|
||||
l_warn("Invalid variable name");
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
auto var = variables.find("$" + varName);
|
||||
if (var != variables.end() && var->second.second)
|
||||
{
|
||||
l_warn("Trying to re-assign a const variable");
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
variables["$" + varName] = { varValue, is_const };
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
if (groupSelector != "")
|
||||
{
|
||||
if (groupLines)
|
||||
{
|
||||
if (line == "}")
|
||||
if (line.endsWith("{"))
|
||||
{
|
||||
groupSelectorCount++;
|
||||
}
|
||||
else if (line == "}" && groupSelectorCount > 1)
|
||||
{
|
||||
groupSelectorCount--;
|
||||
}
|
||||
else if (line == "}" && groupSelectorCount == 1)
|
||||
{
|
||||
groupLines = false;
|
||||
auto newLines = parseGroup(groupSelector, group);
|
||||
|
|
@ -117,31 +126,35 @@ namespace ostd
|
|||
lineNumber++;
|
||||
}
|
||||
groupSelector = "";
|
||||
groupSelectorCount = 0;
|
||||
group.clear();
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
group.push_back(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line == "{")
|
||||
{
|
||||
groupLines = true;
|
||||
groupSelectorCount++;
|
||||
}
|
||||
}
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("("))
|
||||
{
|
||||
if (line.count(")") != 1 || line.indexOf(")") < 3)
|
||||
{
|
||||
l_warn("Invalid group selector");
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
String rawSelector = line.new_substr(1, line.indexOf(")")).trim();
|
||||
groupSelector = parseGroupSelector(rawSelector);
|
||||
if (groupSelector == "")
|
||||
{
|
||||
l_warn("Invalid group selector");
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
if (line.contains("{"))
|
||||
{
|
||||
|
|
@ -149,17 +162,15 @@ namespace ostd
|
|||
if (line != "{")
|
||||
{
|
||||
l_warn("Invalid group selector");
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
groupLines = true;
|
||||
groupSelectorCount = 1;
|
||||
}
|
||||
goto custom_continue;
|
||||
continue;
|
||||
}
|
||||
l_parseLine(line);
|
||||
continue;
|
||||
custom_continue:
|
||||
if (debug_print)
|
||||
std::cout << String("").add(lineNumber).addLeftPadding(lineNumberMaxWidth, ' ') << "| " << richLines[lineNumber - 1] << "\n";
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -243,7 +254,6 @@ custom_continue:
|
|||
(value.startsWith("rgb(") && value.endsWith(")")) ||
|
||||
(value.startsWith("rgba(") && value.endsWith(")")))
|
||||
{
|
||||
|
||||
return value;
|
||||
}
|
||||
return "";
|
||||
|
|
@ -273,7 +283,7 @@ custom_continue:
|
|||
}
|
||||
else if (value.startsWith("vec2(") && value.endsWith(")"))
|
||||
{
|
||||
value.substr(4, value.len() - 1).trim();
|
||||
value.substr(5, value.len() - 1).trim();
|
||||
auto tokens = value.tokenize(",");
|
||||
if (tokens.count() != 2)
|
||||
return false;
|
||||
|
|
@ -359,8 +369,35 @@ custom_continue:
|
|||
if (selector.new_trim() == "" || group.size() == 0)
|
||||
return {};
|
||||
stdvec<String> newLines;
|
||||
stdvec<String> subSelectorStack;
|
||||
for (const auto& property : group)
|
||||
newLines.push_back(selector.new_add(".").new_add(property));
|
||||
{
|
||||
String p = property.new_trim();
|
||||
if (p.startsWith("(") && p.lastIndexOf(")") > 1 && p.endsWith("{") && p.len() > 3)
|
||||
{
|
||||
String ss = p.substr(1, p.lastIndexOf(")")).trim();
|
||||
if (!ss.regexMatches(m_validNameRegex))
|
||||
return {};
|
||||
subSelectorStack.push_back(ss);
|
||||
}
|
||||
else if (p == "}")
|
||||
{
|
||||
if (subSelectorStack.size() > 0)
|
||||
subSelectorStack.pop_back();
|
||||
else
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
String fullSelector = selector;
|
||||
for (const auto& ss : subSelectorStack)
|
||||
fullSelector.add(".").add(ss);
|
||||
newLines.push_back(fullSelector.new_add(".").new_add(property));
|
||||
}
|
||||
}
|
||||
// for (const auto& l : newLines)
|
||||
// std::cout << l << "\n";
|
||||
// std::cout << "\n\n\n";
|
||||
return newLines;
|
||||
}
|
||||
|
||||
|
|
@ -391,20 +428,4 @@ custom_continue:
|
|||
return *p;
|
||||
return "";
|
||||
}
|
||||
|
||||
stdvec<ostd::RegexRichString> Stylesheet::getRichStringLines(const stdvec<String>& lines)
|
||||
{
|
||||
stdvec<ostd::RegexRichString> richLines;
|
||||
for (auto line : lines)
|
||||
{
|
||||
ostd::RegexRichString rgxrstr(line);
|
||||
rgxrstr.fg("\\{|\\}|\\+|\\*|\\-|\\/|\\(|\\)|\\[|\\]", "Red"); //Operators
|
||||
rgxrstr.fg("0x[0-9A-Fa-f]+|0b[0-1]+|(?<!\\w)[0-9]+(?!\\w)", "Blue"); //Number Constants
|
||||
rgxrstr.fg("(?<!\\w)(r[1-9]|r10|fl|pp|rv|fp|sp|ip|acc)(?!\\w)", "BrightGreen", true); //Registers
|
||||
rgxrstr.fg("\\%low", "Magenta");
|
||||
rgxrstr.fg("\\$\\w+", "Cyan"); //Labels
|
||||
richLines.push_back(rgxrstr);
|
||||
}
|
||||
return richLines;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ namespace ostd
|
|||
|
||||
void debugPrint(void);
|
||||
String typeVariantToString(const TypeVariant& v);
|
||||
stdvec<ostd::RegexRichString> getRichStringLines(const stdvec<String>& lines);
|
||||
|
||||
private:
|
||||
bool parseThemeFileLine(const String& line, const VariableList& variables, bool exitCondition = false);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ class Window : public ogfx::gui::Window
|
|||
m_label1.addThemeOverride("@.label.borderColor", Colors::DarkMagenta);
|
||||
m_label1.addThemeOverride("@:pressed.label.backgroundColor", Colors::Crimson);
|
||||
m_label1.addThemeOverride("@:hover.label.backgroundColor", Colors::DarkRed);
|
||||
m_label1.addThemeOverride("@:hover.label.cursor", cast<i32>(ogfx::WindowCore::eCursor::Pointer));
|
||||
m_label1.reloadTheme();
|
||||
|
||||
m_check1.setText("Check this out!");
|
||||
|
|
|
|||
Loading…
Reference in a new issue