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
|
titlebarHeight = 18
|
||||||
titlebarFontSize = 18
|
titlebarFontSize = 18
|
||||||
titlebarTextAlign = text_left
|
titlebarTextAlign = text_left
|
||||||
% scrollSpeed = Vec2(0.8, 0.8)
|
scrollSpeed = Vec2(0.8, 0.8)
|
||||||
padding = Rect(15, 15, 15, 15)
|
padding = Rect(15, 15, 15, 15)
|
||||||
margin = Rect(0, 0, 0, 0)
|
margin = Rect(0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
@ -39,11 +39,25 @@ window.backgroundColor = rgba(160, 160, 160, 255)
|
||||||
|
|
||||||
|
|
||||||
% ====== Scrollbar ======
|
% ====== Scrollbar ======
|
||||||
% (scrollbar) {
|
(scrollbar) {
|
||||||
% (handle) {
|
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::FileDragAndDropped);
|
||||||
connectSignal(ostd::BuiltinSignals::TextDragAndDropped);
|
connectSignal(ostd::BuiltinSignals::TextDragAndDropped);
|
||||||
|
|
||||||
|
setCursor(eCursor::Default);
|
||||||
|
|
||||||
__on_window_init(width, height, title);
|
__on_window_init(width, height, title);
|
||||||
setSize(m_windowWidth, m_windowHeight);
|
setSize(m_windowWidth, m_windowHeight);
|
||||||
}
|
}
|
||||||
|
|
@ -237,12 +239,41 @@ namespace ogfx
|
||||||
case eCursor::W_Resize:
|
case eCursor::W_Resize:
|
||||||
SDL_SetCursor(m_cursor_W_Resize);
|
SDL_SetCursor(m_cursor_W_Resize);
|
||||||
break;
|
break;
|
||||||
|
case eCursor::NoCursor:
|
||||||
default:
|
default:
|
||||||
SDL_SetCursor(m_cursor_Default);
|
SDL_SetCursor(m_cursor_Default);
|
||||||
break;
|
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)
|
void WindowCore::enableResizable(bool enable)
|
||||||
{
|
{
|
||||||
SDL_SetWindowResizable(m_window, 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_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_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_w_resize"] = { String("").add(cast<i32>(eCursor::W_Resize)), true };
|
||||||
|
m_defaultStylesheetVariables["cursor_inherit"] = { String("").add(cast<i32>(eCursor::NoCursor)), true };
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
m_defaultStylesheetVariables["color_transparent"] = { "Color(" + Colors::Transparent.hexString(true, "#") + ")", true };
|
m_defaultStylesheetVariables["color_transparent"] = { "Color(" + Colors::Transparent.hexString(true, "#") + ")", true };
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,8 @@ namespace ogfx
|
||||||
SW_Resize,
|
SW_Resize,
|
||||||
W_Resize,
|
W_Resize,
|
||||||
|
|
||||||
Count
|
Count,
|
||||||
|
NoCursor = 255
|
||||||
};
|
};
|
||||||
public: enum class eTextAlign : u8 {
|
public: enum class eTextAlign : u8 {
|
||||||
Default = 0,
|
Default = 0,
|
||||||
|
|
@ -74,6 +75,7 @@ namespace ogfx
|
||||||
void setSize(i32 width, i32 height);
|
void setSize(i32 width, i32 height);
|
||||||
void setTitle(const String& title);
|
void setTitle(const String& title);
|
||||||
void setCursor(eCursor cursor);
|
void setCursor(eCursor cursor);
|
||||||
|
eCursor getCurosr(void) const;
|
||||||
void enableResizable(bool enable = true);
|
void enableResizable(bool enable = true);
|
||||||
void setIcon(const String& iconFilePath);
|
void setIcon(const String& iconFilePath);
|
||||||
void setBlockingEventsRefreshFPS(u32 fps);
|
void setBlockingEventsRefreshFPS(u32 fps);
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,13 @@ namespace ogfx
|
||||||
f32 maxScroll = -(ext.h - cont.h);
|
f32 maxScroll = -(ext.h - cont.h);
|
||||||
if (event.mouse->scroll == MouseEventData::eScrollDirection::Down && m_scrollOffset.y > maxScroll)
|
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)
|
if (m_scrollOffset.y < maxScroll)
|
||||||
m_scrollOffset.y = maxScroll;
|
m_scrollOffset.y = maxScroll;
|
||||||
}
|
}
|
||||||
else if (event.mouse->scroll == MouseEventData::eScrollDirection::Up && m_scrollOffset.y < 0)
|
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)
|
if (m_scrollOffset.y > 0)
|
||||||
m_scrollOffset.y = 0;
|
m_scrollOffset.y = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ namespace ostd
|
||||||
{
|
{
|
||||||
Stylesheet::Stylesheet(void)
|
Stylesheet::Stylesheet(void)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
Stylesheet& Stylesheet::clear(void)
|
Stylesheet& Stylesheet::clear(void)
|
||||||
|
|
@ -47,10 +48,9 @@ namespace ostd
|
||||||
m_values.clear();
|
m_values.clear();
|
||||||
stdvec<String> lines = content.tokenize("\n", false, true).getRawData();
|
stdvec<String> lines = content.tokenize("\n", false, true).getRawData();
|
||||||
stdvec<String> originalLines = lines;
|
stdvec<String> originalLines = lines;
|
||||||
auto richLines = getRichStringLines(lines);
|
|
||||||
u32 lineNumber = 0;
|
u32 lineNumber = 0;
|
||||||
auto l_warn = [&](const String& msg) -> void {
|
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 {
|
auto l_parseLine = [&](String& line) -> void {
|
||||||
if (!parseThemeFileLine(line, variables))
|
if (!parseThemeFileLine(line, variables))
|
||||||
|
|
@ -60,17 +60,18 @@ namespace ostd
|
||||||
String groupSelector = "";
|
String groupSelector = "";
|
||||||
bool groupLines = true;
|
bool groupLines = true;
|
||||||
stdvec<String> group;
|
stdvec<String> group;
|
||||||
|
u32 groupSelectorCount = 0;
|
||||||
bool debug_print = false;
|
bool debug_print = false;
|
||||||
for (auto& line : lines)
|
for (auto& line : lines)
|
||||||
{
|
{
|
||||||
lineNumber++;
|
lineNumber++;
|
||||||
line.trim();
|
line.trim();
|
||||||
if (line.startsWith("%"))
|
if (line.startsWith("%"))
|
||||||
goto custom_continue;
|
continue;
|
||||||
if (line.contains("%"))
|
if (line.contains("%"))
|
||||||
line.substr(0, line.indexOf("%")).trim();
|
line.substr(0, line.indexOf("%")).trim();
|
||||||
if (line == "")
|
if (line == "")
|
||||||
goto custom_continue;
|
continue;
|
||||||
if (line.startsWith("const ") || line.startsWith("$"))
|
if (line.startsWith("const ") || line.startsWith("$"))
|
||||||
{
|
{
|
||||||
bool is_const = false;
|
bool is_const = false;
|
||||||
|
|
@ -83,29 +84,37 @@ namespace ostd
|
||||||
if (line.count("=") != 1 || line.endsWith("="))
|
if (line.count("=") != 1 || line.endsWith("="))
|
||||||
{
|
{
|
||||||
l_warn("Invalid variable");
|
l_warn("Invalid variable");
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
String varName = line.new_substr(0, line.indexOf("=")).trim();
|
String varName = line.new_substr(0, line.indexOf("=")).trim();
|
||||||
String varValue = line.new_substr(line.indexOf("=") + 1).trim();
|
String varValue = line.new_substr(line.indexOf("=") + 1).trim();
|
||||||
if (!varName.regexMatches(m_validNameRegex))
|
if (!varName.regexMatches(m_validNameRegex))
|
||||||
{
|
{
|
||||||
l_warn("Invalid variable name");
|
l_warn("Invalid variable name");
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto var = variables.find("$" + varName);
|
auto var = variables.find("$" + varName);
|
||||||
if (var != variables.end() && var->second.second)
|
if (var != variables.end() && var->second.second)
|
||||||
{
|
{
|
||||||
l_warn("Trying to re-assign a const variable");
|
l_warn("Trying to re-assign a const variable");
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
variables["$" + varName] = { varValue, is_const };
|
variables["$" + varName] = { varValue, is_const };
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (groupSelector != "")
|
if (groupSelector != "")
|
||||||
{
|
{
|
||||||
if (groupLines)
|
if (groupLines)
|
||||||
{
|
{
|
||||||
if (line == "}")
|
if (line.endsWith("{"))
|
||||||
|
{
|
||||||
|
groupSelectorCount++;
|
||||||
|
}
|
||||||
|
else if (line == "}" && groupSelectorCount > 1)
|
||||||
|
{
|
||||||
|
groupSelectorCount--;
|
||||||
|
}
|
||||||
|
else if (line == "}" && groupSelectorCount == 1)
|
||||||
{
|
{
|
||||||
groupLines = false;
|
groupLines = false;
|
||||||
auto newLines = parseGroup(groupSelector, group);
|
auto newLines = parseGroup(groupSelector, group);
|
||||||
|
|
@ -117,31 +126,35 @@ namespace ostd
|
||||||
lineNumber++;
|
lineNumber++;
|
||||||
}
|
}
|
||||||
groupSelector = "";
|
groupSelector = "";
|
||||||
|
groupSelectorCount = 0;
|
||||||
group.clear();
|
group.clear();
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
group.push_back(line);
|
group.push_back(line);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (line == "{")
|
if (line == "{")
|
||||||
|
{
|
||||||
groupLines = true;
|
groupLines = true;
|
||||||
|
groupSelectorCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.startsWith("("))
|
if (line.startsWith("("))
|
||||||
{
|
{
|
||||||
if (line.count(")") != 1 || line.indexOf(")") < 3)
|
if (line.count(")") != 1 || line.indexOf(")") < 3)
|
||||||
{
|
{
|
||||||
l_warn("Invalid group selector");
|
l_warn("Invalid group selector");
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
String rawSelector = line.new_substr(1, line.indexOf(")")).trim();
|
String rawSelector = line.new_substr(1, line.indexOf(")")).trim();
|
||||||
groupSelector = parseGroupSelector(rawSelector);
|
groupSelector = parseGroupSelector(rawSelector);
|
||||||
if (groupSelector == "")
|
if (groupSelector == "")
|
||||||
{
|
{
|
||||||
l_warn("Invalid group selector");
|
l_warn("Invalid group selector");
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (line.contains("{"))
|
if (line.contains("{"))
|
||||||
{
|
{
|
||||||
|
|
@ -149,17 +162,15 @@ namespace ostd
|
||||||
if (line != "{")
|
if (line != "{")
|
||||||
{
|
{
|
||||||
l_warn("Invalid group selector");
|
l_warn("Invalid group selector");
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
groupLines = true;
|
groupLines = true;
|
||||||
|
groupSelectorCount = 1;
|
||||||
}
|
}
|
||||||
goto custom_continue;
|
continue;
|
||||||
}
|
}
|
||||||
l_parseLine(line);
|
l_parseLine(line);
|
||||||
continue;
|
continue;
|
||||||
custom_continue:
|
|
||||||
if (debug_print)
|
|
||||||
std::cout << String("").add(lineNumber).addLeftPadding(lineNumberMaxWidth, ' ') << "| " << richLines[lineNumber - 1] << "\n";
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -243,7 +254,6 @@ custom_continue:
|
||||||
(value.startsWith("rgb(") && value.endsWith(")")) ||
|
(value.startsWith("rgb(") && value.endsWith(")")) ||
|
||||||
(value.startsWith("rgba(") && value.endsWith(")")))
|
(value.startsWith("rgba(") && value.endsWith(")")))
|
||||||
{
|
{
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|
@ -273,7 +283,7 @@ custom_continue:
|
||||||
}
|
}
|
||||||
else if (value.startsWith("vec2(") && value.endsWith(")"))
|
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(",");
|
auto tokens = value.tokenize(",");
|
||||||
if (tokens.count() != 2)
|
if (tokens.count() != 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -359,8 +369,35 @@ custom_continue:
|
||||||
if (selector.new_trim() == "" || group.size() == 0)
|
if (selector.new_trim() == "" || group.size() == 0)
|
||||||
return {};
|
return {};
|
||||||
stdvec<String> newLines;
|
stdvec<String> newLines;
|
||||||
|
stdvec<String> subSelectorStack;
|
||||||
for (const auto& property : group)
|
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;
|
return newLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,20 +428,4 @@ custom_continue:
|
||||||
return *p;
|
return *p;
|
||||||
return "";
|
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);
|
void debugPrint(void);
|
||||||
String typeVariantToString(const TypeVariant& v);
|
String typeVariantToString(const TypeVariant& v);
|
||||||
stdvec<ostd::RegexRichString> getRichStringLines(const stdvec<String>& lines);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool parseThemeFileLine(const String& line, const VariableList& variables, bool exitCondition = false);
|
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("@.label.borderColor", Colors::DarkMagenta);
|
||||||
m_label1.addThemeOverride("@:pressed.label.backgroundColor", Colors::Crimson);
|
m_label1.addThemeOverride("@:pressed.label.backgroundColor", Colors::Crimson);
|
||||||
m_label1.addThemeOverride("@:hover.label.backgroundColor", Colors::DarkRed);
|
m_label1.addThemeOverride("@:hover.label.backgroundColor", Colors::DarkRed);
|
||||||
|
m_label1.addThemeOverride("@:hover.label.cursor", cast<i32>(ogfx::WindowCore::eCursor::Pointer));
|
||||||
m_label1.reloadTheme();
|
m_label1.reloadTheme();
|
||||||
|
|
||||||
m_check1.setText("Check this out!");
|
m_check1.setText("Check this out!");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue