diff --git a/demo/main.cpp b/demo/main.cpp index a27bd956b..7b2a13876 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -61,6 +61,7 @@ int main(int argc, char* argv[]) brls::Application::registerXMLView("RecyclingListTab", RecyclingListTab::create); brls::Application::registerXMLView("ComponentsTab", ComponentsTab::create); + /* // Add custom values to the theme brls::getLightTheme().addColor("captioned_image/caption", nvgRGB(2, 176, 183)); brls::getDarkTheme().addColor("captioned_image/caption", nvgRGB(51, 186, 227)); @@ -69,6 +70,30 @@ int main(int argc, char* argv[]) brls::getStyle().addMetric("about/padding_top_bottom", 50); brls::getStyle().addMetric("about/padding_sides", 75); brls::getStyle().addMetric("about/description_margin", 50); + */ + + const std::string captionedImageThemeXML = R"xml( + + + + + + + + + + )xml"; + + const std::string aboutThemeXML = R"xml( + + + + + + )xml"; + + brls::Application::getTheme().inflateFromXMLString(captionedImageThemeXML); + brls::Application::getTheme().inflateFromXMLString(aboutThemeXML); // Create and push the main activity to the stack brls::Application::pushActivity(new MainActivity()); diff --git a/library/include/borealis/core/application.hpp b/library/include/borealis/core/application.hpp index 42449fa2e..29428a7af 100644 --- a/library/include/borealis/core/application.hpp +++ b/library/include/borealis/core/application.hpp @@ -98,10 +98,10 @@ class Application inline static Style getStyle() { - return brls::getStyle(); + return *style; } - static Theme getTheme(); + static Theme &getTheme(); static ThemeVariant getThemeVariant(); /** @@ -195,6 +195,8 @@ class Application inline static bool quitRequested = false; inline static Platform* platform = nullptr; + inline static Theme* theme = nullptr; + inline static Style* style = nullptr; inline static std::string title; diff --git a/library/include/borealis/core/frame_context.hpp b/library/include/borealis/core/frame_context.hpp index 3a423275d..552221892 100644 --- a/library/include/borealis/core/frame_context.hpp +++ b/library/include/borealis/core/frame_context.hpp @@ -32,7 +32,7 @@ class FrameContext NVGcontext* vg = nullptr; float pixelRatio = 0.0; FontStash* fontStash = nullptr; - Theme theme = nullptr; + Theme theme; }; } // namespace brls diff --git a/library/include/borealis/core/style.hpp b/library/include/borealis/core/style.hpp index 765b67425..9860d7952 100644 --- a/library/include/borealis/core/style.hpp +++ b/library/include/borealis/core/style.hpp @@ -2,6 +2,7 @@ Copyright 2019-2020 natinusala Copyright 2019 WerWolv Copyright 2019 p-sam + Copyright 2021 EmreTech Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,32 +26,19 @@ namespace brls { -class StyleValues -{ - public: - StyleValues(std::initializer_list> list); - - void addMetric(std::string name, float value); - float getMetric(std::string name); - - private: - std::unordered_map values; -}; +struct Theme; -// Simple wrapper around StyleValues for the array operator -class Style +// Wrapper to grab metrics from a theme +// KEPT FOR BACKWARDS COMPATIBILITY +struct Style { - public: - Style(StyleValues* values); - float operator[](std::string name); - - void addMetric(std::string name, float value); - float getMetric(std::string name); + Style(Theme &theme); + + // Shortcut for Theme.getMetric(name) + float operator[](const std::string name); - private: - StyleValues* values; + private: + Theme &parentTheme; }; -Style getStyle(); - } // namespace brls diff --git a/library/include/borealis/core/theme.hpp b/library/include/borealis/core/theme.hpp index d10f92c5f..5244b8d7d 100644 --- a/library/include/borealis/core/theme.hpp +++ b/library/include/borealis/core/theme.hpp @@ -1,6 +1,7 @@ /* Copyright 2019-2020 natinusala Copyright 2019 p-sam + Copyright 2021 EmreTech Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,8 +19,8 @@ #pragma once #include +#include -#include #include #include @@ -32,33 +33,34 @@ enum class ThemeVariant DARK }; -class ThemeValues +struct Theme { - public: - ThemeValues(std::initializer_list> list); + Theme(std::string name); + Theme() = default; - void addColor(std::string name, NVGcolor color); - NVGcolor getColor(std::string name); + void inflateFromXMLElement(tinyxml2::XMLElement *element); + void inflateFromXMLString(const std::string xml); + void inflateFromXMLFile(const std::string path); - private: - std::unordered_map values; -}; + //float getMetric(const std::string path, ThemeVariant variant); -// Simple wrapper around ThemeValues for the array operator -class Theme -{ - public: - Theme(ThemeValues* values); - NVGcolor operator[](std::string name); + NVGcolor getColor(const std::string path, ThemeVariant variant); + float getMetric(const std::string path); + NVGcolor getColor(const std::string path); - void addColor(std::string name, NVGcolor color); - NVGcolor getColor(std::string name); + // Shortcut for getColor(name) + NVGcolor operator[](const std::string name); - private: - ThemeValues* values; -}; + void getAllMetricKeys(const std::string prefix); -Theme getLightTheme(); -Theme getDarkTheme(); + private: + // Each color/metric has a key of their theme variant + prefix + // An example: "dark/brls/sidebar/background" + + std::unordered_map colors; + std::unordered_map metrics; + + std::string name; +}; } // namespace brls diff --git a/library/lib/core/application.cpp b/library/lib/core/application.cpp index 16dd6beaf..7c6eb16f1 100644 --- a/library/lib/core/application.cpp +++ b/library/lib/core/application.cpp @@ -54,10 +54,80 @@ constexpr uint32_t ORIGINAL_WINDOW_HEIGHT = 720; namespace brls { +const std::string generalThemeXML = R"xml( + + + + + + + + + + + + + + + +)xml"; + +const std::string highlightThemeXML = R"xml( + + + + + + + + + + + + + + + + + + + + +)xml"; + +const std::string animationThemeXML = R"xml( + + + + + + + + + + +)xml"; + +const std::string shadowThemeXML = R"xml( + + + + + + +)xml"; + bool Application::init() { // Init platform Application::platform = Platform::createPlatform(); + Application::theme = new Theme("brls/default"); + Application::style = new Style(*Application::theme); + + Application::theme->inflateFromXMLString(generalThemeXML); + Application::theme->inflateFromXMLString(highlightThemeXML); + Application::theme->inflateFromXMLString(animationThemeXML); + Application::theme->inflateFromXMLString(shadowThemeXML); if (!Application::platform) { @@ -375,10 +445,10 @@ void Application::frame() frameContext.pixelRatio = (float)Application::windowWidth / (float)Application::windowHeight; frameContext.vg = Application::getNVGContext(); frameContext.fontStash = &Application::fontStash; - frameContext.theme = Application::getTheme(); + frameContext.theme = *Application::theme; // Begin frame and clear - NVGcolor backgroundColor = frameContext.theme["brls/background"]; + NVGcolor backgroundColor = frameContext.theme.getColor("brls/background"); videoContext->beginFrame(); videoContext->clear(backgroundColor); @@ -632,12 +702,9 @@ void Application::clear() Application::activitiesStack.clear(); } -Theme Application::getTheme() +Theme &Application::getTheme() { - if (Application::getThemeVariant() == ThemeVariant::LIGHT) - return getLightTheme(); - else - return getDarkTheme(); + return *theme; } ThemeVariant Application::getThemeVariant() diff --git a/library/lib/core/style.cpp b/library/lib/core/style.cpp index d46e3e14f..326d5169f 100644 --- a/library/lib/core/style.cpp +++ b/library/lib/core/style.cpp @@ -2,6 +2,7 @@ Copyright 2019 natinusala Copyright 2019 WerWolv Copyright 2019 p-sam + Copyright 2021 EmreTech Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,14 +18,15 @@ */ #include +#include #include #include namespace brls { - +/* static StyleValues styleValues = { - // Animations + // Animations Done { "brls/animations/show", 250.0f }, { "brls/animations/show_slide", 125.0f }, @@ -34,7 +36,7 @@ static StyleValues styleValues = { { "brls/animations/label_scrolling_timer", 1500.0f }, { "brls/animations/label_scrolling_speed", 0.05f }, - // Highlight + // Highlight Done { "brls/highlight/stroke_width", 5.0f }, { "brls/highlight/corner_radius", 0.5f }, { "brls/highlight/shadow_width", 2.0f }, @@ -42,7 +44,7 @@ static StyleValues styleValues = { { "brls/highlight/shadow_feather", 10.0f }, { "brls/highlight/shadow_opacity", 128.0f }, - // AppletFrame + // AppletFrame Done { "brls/applet_frame/padding_sides", 30.0f }, { "brls/applet_frame/header_height", 88.0f }, @@ -56,12 +58,12 @@ static StyleValues styleValues = { { "brls/applet_frame/footer_padding_top_bottom", 20.0f }, { "brls/applet_frame/footer_padding_sides", 25.0f }, - // TabFrame + // TabFrame Done { "brls/tab_frame/sidebar_width", 410.0f }, { "brls/tab_frame/content_padding_top_bottom", 42.0f }, // unused by the library, here for users { "brls/tab_frame/content_padding_sides", 60.0f }, // unused by the library, here for users - // Sidebar + // Sidebar Done { "brls/sidebar/border_height", 16.0f }, { "brls/sidebar/padding_top", 32.0f }, { "brls/sidebar/padding_bottom", 47.0f }, @@ -74,13 +76,13 @@ static StyleValues styleValues = { { "brls/sidebar/item_font_size", 22.0f }, { "brls/sidebar/separator_height", 30.0f }, - // Label + // Label Done { "brls/label/default_font_size", 20.0f }, { "brls/label/default_line_height", 1.65f }, { "brls/label/scrolling_animation_spacing", 50.0f }, { "brls/label/highlight_padding", 2.0f }, - // Header + // Header Done { "brls/header/padding_top_bottom", 11.0f }, { "brls/header/padding_right", 11.0f }, { "brls/header/rectangle_width", 5.0f }, @@ -88,7 +90,7 @@ static StyleValues styleValues = { { "brls/header/rectangle_margin", 10.0f }, { "brls/header/font_size", 18.0f }, - // Button + // Button Done { "brls/button/padding_top_bottom", 15.0f }, { "brls/button/padding_sides", 25.0f }, { "brls/button/corner_radius", 5.0f }, @@ -96,57 +98,20 @@ static StyleValues styleValues = { { "brls/button/primary_highlight_padding", 2.0f }, { "brls/button/border_thickness", 2.0f }, - // Generic shadow + // Generic shadow Done { "brls/shadow/width", 2.0f }, { "brls/shadow/feather", 10.0f }, { "brls/shadow/opacity", 63.75f }, { "brls/shadow/offset", 10.0f }, }; +*/ -static Style style(&styleValues); - -Style getStyle() -{ - return style; -} - -StyleValues::StyleValues(std::initializer_list> list) -{ - for (std::pair metric : list) - this->values.insert(metric); -} - -void StyleValues::addMetric(std::string name, float metric) -{ - this->values.insert(std::make_pair(name, metric)); -} - -float StyleValues::getMetric(std::string name) -{ - if (this->values.count(name) == 0) - fatal("Unknown style metric \"" + name + "\""); - - return this->values[name]; -} - -Style::Style(StyleValues* values) - : values(values) -{ -} - -float Style::getMetric(std::string name) -{ - return this->values->getMetric(name); -} - -void Style::addMetric(std::string name, float metric) -{ - return this->values->addMetric(name, metric); -} +Style::Style(Theme &theme) : parentTheme(theme) +{} -float Style::operator[](std::string name) +float Style::operator[](const std::string name) { - return this->getMetric(name); + return parentTheme.getMetric(name); } /* diff --git a/library/lib/core/theme.cpp b/library/lib/core/theme.cpp index 8ac0bfc8c..79239b639 100644 --- a/library/lib/core/theme.cpp +++ b/library/lib/core/theme.cpp @@ -1,6 +1,7 @@ /* Copyright 2019 natinusala Copyright 2019 p-sam + Copyright 2021 EmreTech Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,38 +17,42 @@ */ #include +#include +#include #include #include +#include +#include namespace brls { - +/* static ThemeValues lightThemeValues = { - // Generic values + // Generic values Done { "brls/background", nvgRGB(235, 235, 235) }, { "brls/text", nvgRGB(45, 45, 45) }, { "brls/backdrop", nvgRGBA(0, 0, 0, 178) }, { "brls/click_pulse", nvgRGBA(13, 182, 213, 38) }, // same as highlight color1 with different opacity - // Highlight + // Highlight Done { "brls/highlight/background", nvgRGB(252, 255, 248) }, { "brls/highlight/color1", nvgRGB(13, 182, 213) }, { "brls/highlight/color2", nvgRGB(80, 239, 217) }, - // AppletFrame + // AppletFrame Done { "brls/applet_frame/separator", nvgRGB(45, 45, 45) }, - // Sidebar + // Sidebar Done { "brls/sidebar/background", nvgRGB(240, 240, 240) }, { "brls/sidebar/active_item", nvgRGB(49, 79, 235) }, { "brls/sidebar/separator", nvgRGB(208, 208, 208) }, - // Header + // Header Done { "brls/header/border", nvgRGB(207, 207, 207) }, { "brls/header/rectangle", nvgRGB(127, 127, 127) }, { "brls/header/subtitle", nvgRGB(140, 140, 140) }, - // Button + // Button Done { "brls/button/primary_enabled_background", nvgRGB(50, 79, 241) }, { "brls/button/primary_disabled_background", nvgRGB(201, 201, 209) }, { "brls/button/primary_enabled_text", nvgRGB(255, 255, 255) }, @@ -107,57 +112,260 @@ static ThemeValues darkThemeValues = { { "brls/button/enabled_border_color", nvgRGB(255, 255, 255) }, { "brls/button/disabled_border_color", nvgRGB(255, 255, 255) }, }; +*/ -static Theme lightTheme(&lightThemeValues); -static Theme darkTheme(&darkThemeValues); +Theme::Theme(std::string name) : name{name} +{} -ThemeValues::ThemeValues(std::initializer_list> list) +bool validThemeVariant(const std::string themeVariant) { - for (std::pair color : list) - this->values.insert(color); + std::string themeVariantLowercase = themeVariant; + std::transform(themeVariantLowercase.begin(), themeVariantLowercase.end(), + themeVariantLowercase.begin(), [](unsigned char c){ return std::tolower(c); }); + + if (themeVariantLowercase == "dark" || themeVariantLowercase == "light") + return true; + return false; +} + +bool startsWith(const std::string& data, const std::string& prefix) +{ + return data.rfind(prefix, 0) == 0; } -void ThemeValues::addColor(std::string name, NVGcolor color) +NVGcolor processColorValue(const std::string val) { - this->values.insert(std::make_pair(name, color)); + // Hexadecimal + if (startsWith(val, "#")) + { + // RGB + if (val.size() == 6 + 1) + { + unsigned char r, g, b; + int result = sscanf(val.c_str(), "#%02hhx%02hhx%02hhx", &r, &g, &b); + + if (result != 3) + { + Logger::error("Theme: failed to extract hexadecimal color value"); + return nvgRGB(0, 0, 0); + } + + return nvgRGB(r, g, b); + } + // RGBA + else if (val.size() == 8 + 1) + { + unsigned char r, g, b, a; + int result = sscanf(val.c_str(), "#%02hhx%02hhx%02hhx%02hhx", &r, &g, &b, &a); + + if (result != 4) + { + Logger::error("Theme: failed to extract hexadecimal color value"); + return nvgRGBA(0, 0, 0, 0); + } + + return nvgRGBA(r, g, b, a); + } + } + // RGBA "Function" + else if (startsWith(val, "rgba")) + { + unsigned char r, g, b, a; + int result = sscanf(val.c_str(), "rgba(%hhd,%hhd,%hhd,%hhd)", &r, &g, &b, &a); + //Logger::debug("R: {} G: {} B: {} A: {}", r, g, b, a); + + if (result != 4) + { + Logger::error("Theme: failed to extract rgba color value"); + return nvgRGBA(0, 0, 0, 0); + } + + return nvgRGBA(r, g, b, a); + } + // RGB "Function" + else if (startsWith(val, "rgb")) + { + unsigned char r, g, b; + int result = sscanf(val.c_str(), "rgb(%hhd,%hhd,%hhd)", &r, &g, &b); + //Logger::debug("R: {} G: {} B: {}", r, g, b); + + if (result != 3) + { + Logger::error("Theme: failed to extract rgb color value"); + return nvgRGB(0, 0, 0); + } + + return nvgRGB(r, g, b); + } + + Logger::error("Theme: invalid color value"); + return nvgRGBA(0, 0, 0, 0); } -NVGcolor ThemeValues::getColor(std::string name) +float processMetricValue(const std::string val) { - if (this->values.count(name) == 0) - fatal("Unknown theme value \"" + name + "\""); + try + { + return std::stof(val); + } + catch (const std::invalid_argument& e) + { + Logger::error("Theme: invalid metric value"); + return 0.0f; + } + +} - return this->values[name]; +/* +void processValues(tinyxml2::XMLElement *currElem, + const std::string prefix, + const std::string themeVar, + std::unordered_map &colors) +{ + for (tinyxml2::XMLElement *e = currElem->FirstChildElement("brls:Color"); e != NULL; e = e->NextSiblingElement("brls:Color")) + { + std::string elemName = std::string(e->Name()); + std::string name = e->Attribute("name"); + std::string value = e->Attribute("value"); + + colors[themeVar + "/" + prefix + "/" + name] = processColorValue(value); + } } +*/ -Theme::Theme(ThemeValues* values) - : values(values) +void Theme::inflateFromXMLElement(tinyxml2::XMLElement *element) { + if (element == nullptr) + { + Logger::error("Theme: NULL root element. This means the XML file is blank (hasn't been written to yet), or the XML file is broken."); + return; + } + + if (std::strcmp(element->Name(), "brls:Stylesheet") != 0) + { + Logger::error("Theme: read stylesheet that has \"{}\" as a root element", element->Name()); + return; + } + + if (std::strcmp(element->Attribute("theme"), this->name.c_str()) != 0) + { + Logger::error("Theme: read stylesheet that has different theme name than current theme"); + return; + } + + std::string prefix = std::string(element->Attribute("prefix")); + + //tinyxml2::XMLElement *element = nullptr; + for (tinyxml2::XMLElement *e = element->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) + { + if (std::strcmp(e->Name(), "brls:ThemeVariant") == 0) + { + std::string currThemeVariant = e->Attribute("name"); + if (!validThemeVariant(currThemeVariant)) + continue; + + std::transform(currThemeVariant.begin(), currThemeVariant.end(), + currThemeVariant.begin(), [](unsigned char c){ return std::tolower(c); }); + + //processValues(e, prefix, currThemeVariant, colors); + for (tinyxml2::XMLElement *eTwo = e->FirstChildElement("brls:Color"); eTwo != NULL; eTwo = eTwo->NextSiblingElement("brls:Color")) + { + std::string name = eTwo->Attribute("name"); + std::string value = eTwo->Attribute("value"); + + colors[currThemeVariant + "/" + prefix + "/" + name] = processColorValue(value); + } + } + else if (std::strcmp(e->Name(), "brls:Metric") == 0) + { + std::string name = std::string(e->Attribute("name")); + std::string value = std::string(e->Attribute("value")); + + metrics[prefix + "/" + name] = processMetricValue(value); + //Logger::debug("{}/{}", prefix, name); + } + } } -NVGcolor Theme::getColor(std::string name) +void Theme::inflateFromXMLString(const std::string xml) { - return this->values->getColor(name); + tinyxml2::XMLDocument doc; + tinyxml2::XMLError errorCode = doc.Parse(xml.c_str()); + + if (errorCode == tinyxml2::XML_SUCCESS) + return inflateFromXMLElement(doc.RootElement()); + + Logger::error("TinyXML2 could not parse the XML string. Error code {}.", std::to_string(errorCode)); + Logger::error("More details: {}", doc.ErrorStr()); } -void Theme::addColor(std::string name, NVGcolor color) +void Theme::inflateFromXMLFile(const std::string path) { - return this->values->addColor(name, color); + tinyxml2::XMLDocument doc; + tinyxml2::XMLError errorCode = doc.LoadFile(path.c_str()); + + if (errorCode == tinyxml2::XML_SUCCESS) + return inflateFromXMLElement(doc.RootElement()); + + Logger::error("TinyXML2 could not open the file. Error code {}.", std::to_string(errorCode)); + Logger::error("More details: {}", doc.ErrorStr()); } -NVGcolor Theme::operator[](std::string name) +NVGcolor Theme::getColor(const std::string path, ThemeVariant variant) { - return this->getColor(name); + std::string themeVar = "light"; + if (variant == ThemeVariant::DARK) + themeVar = "dark"; + + if (colors.count(themeVar + "/" + path) == 0) + fatal("Unknown theme value \"" + (themeVar + "/" + path) + "\""); + + return colors[themeVar + "/" + path]; +} + +NVGcolor Theme::getColor(const std::string path) +{ + ThemeVariant var = Application::getThemeVariant(); + return getColor(path, var); +} + +/* +float Theme::getMetric(const std::string path, ThemeVariant variant) +{ + std::string themeVar = "light"; + if (variant == ThemeVariant::DARK) + themeVar = "dark"; + + if (metrics.count(themeVar + "/" + path) == 0) + fatal("Unknown theme value \"" + (themeVar + "/" + path) + "\""); + + return metrics[themeVar + "/" + path]; +} +*/ + +float Theme::getMetric(const std::string path) +{ + if (metrics.count(path) == 0) + fatal("Unknown theme value \"" + path + "\""); + + return metrics[path]; } -Theme getLightTheme() +NVGcolor Theme::operator[](const std::string name) { - return lightTheme; + return getColor(name); } -Theme getDarkTheme() +void Theme::getAllMetricKeys(const std::string prefix) { - return darkTheme; + for (const auto &e : metrics) + { + Logger::debug("Metric with name {}: {}", e.first, e.second); + if (startsWith(e.first, prefix)) + { + Logger::debug("Metric under {} prefix: {}", prefix, e.second); + } + } } } // namespace brls diff --git a/library/lib/core/view.cpp b/library/lib/core/view.cpp index ee826ad34..cefa77344 100644 --- a/library/lib/core/view.cpp +++ b/library/lib/core/view.cpp @@ -54,9 +54,7 @@ View::View() this->registerCommonAttributes(); // Default values - Style style = Application::getStyle(); - - this->highlightCornerRadius = style["brls/highlight/corner_radius"]; + this->highlightCornerRadius = Application::getStyle()["brls/highlight/corner_radius"]; } static int shakeAnimation(float t, float a) // a = amplitude @@ -100,7 +98,8 @@ void View::frame(FrameContext* ctx) if (this->visibility != Visibility::VISIBLE) return; - Style style = Application::getStyle(); + Theme theme = Application::getTheme(); + Style style = Style(theme); Theme oldTheme = ctx->theme; nvgSave(ctx->vg); @@ -1385,7 +1384,7 @@ bool View::applyXMLAttribute(std::string name, std::string value) { // Parse the style name std::string styleName = value.substr(7); // length of "@style/" - float value = Application::getStyle()[styleName]; // will throw logic_error if the metric doesn't exist + float value = Application::getTheme().getMetric(styleName); // will throw logic_error if the metric doesn't exist if (this->floatAttributes.count(name) > 0) { diff --git a/library/lib/views/applet_frame.cpp b/library/lib/views/applet_frame.cpp index f9f47dc18..e3b669240 100644 --- a/library/lib/views/applet_frame.cpp +++ b/library/lib/views/applet_frame.cpp @@ -15,6 +15,7 @@ limitations under the License. */ +#include #include #include #include @@ -96,8 +97,35 @@ const std::string appletFrameXML = R"xml( )xml"; +const std::string appletFrameThemeXML = R"xml( + + + + + + + + + + + + + + + + + + + + + + +)xml"; + AppletFrame::AppletFrame() { + Application::getTheme().inflateFromXMLString(appletFrameThemeXML); + this->inflateFromXMLString(appletFrameXML); this->registerStringXMLAttribute("title", [this](std::string value) { diff --git a/library/lib/views/button.cpp b/library/lib/views/button.cpp index e11cd3f94..01d4b6ab1 100644 --- a/library/lib/views/button.cpp +++ b/library/lib/views/button.cpp @@ -48,8 +48,57 @@ const std::string buttonXML = R"xml( )xml"; +const std::string buttonThemeXML = R"xml( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)xml"; + Button::Button() { + Application::getTheme().inflateFromXMLString(buttonThemeXML); + this->inflateFromXMLString(buttonXML); this->forwardXMLAttribute("text", this->label); diff --git a/library/lib/views/header.cpp b/library/lib/views/header.cpp index da2e7a00f..3b268fc20 100644 --- a/library/lib/views/header.cpp +++ b/library/lib/views/header.cpp @@ -15,6 +15,7 @@ limitations under the License. */ +#include #include namespace brls @@ -56,8 +57,33 @@ const std::string headerXML = R"xml( )xml"; +const std::string headerThemeXML = R"xml( + + + + + + + + + + + + + + + + + + + + +)xml"; + Header::Header() { + Application::getTheme().inflateFromXMLString(headerThemeXML); + this->inflateFromXMLString(headerXML); this->registerStringXMLAttribute("title", [this](std::string value) { diff --git a/library/lib/views/label.cpp b/library/lib/views/label.cpp index c31d904a1..fbce44eda 100644 --- a/library/lib/views/label.cpp +++ b/library/lib/views/label.cpp @@ -164,10 +164,20 @@ static YGSize labelMeasureFunc(YGNodeRef node, float width, YGMeasureMode widthM return size; } +const std::string labelThemeXML = R"xml( + + + + + + +)xml"; + Label::Label() { Style style = Application::getStyle(); - Theme theme = Application::getTheme(); + Theme &theme = Application::getTheme(); + theme.inflateFromXMLString(labelThemeXML); // Default attributes this->font = Application::getFont(FONT_REGULAR); diff --git a/library/lib/views/sidebar.cpp b/library/lib/views/sidebar.cpp index d33e914f8..6ec45c70e 100644 --- a/library/lib/views/sidebar.cpp +++ b/library/lib/views/sidebar.cpp @@ -55,6 +55,34 @@ const std::string sidebarItemXML = R"xml( )xml"; +const std::string sidebarThemeXML = R"xml( + + + + + + + + + + + + + + + + + + + + + + + + + +)xml"; + SidebarItem::SidebarItem() : Box(Axis::ROW) { @@ -130,6 +158,7 @@ void SidebarItem::setLabel(std::string label) Sidebar::Sidebar() { + Application::getTheme().inflateFromXMLString(sidebarThemeXML); Style style = Application::getStyle(); this->setScrollingBehavior(ScrollingBehavior::CENTERED); @@ -195,7 +224,7 @@ void SidebarSeparator::draw(NVGcontext* vg, float x, float y, float width, float float midY = y + height / 2; nvgBeginPath(vg); - nvgFillColor(vg, ctx->theme["brls/sidebar/separator"]); + nvgFillColor(vg, ctx->theme.getColor("brls/sidebar/separator")); nvgRect(vg, x, midY, width, 1); nvgFill(vg); } diff --git a/library/lib/views/tab_frame.cpp b/library/lib/views/tab_frame.cpp index d7162d557..a329ff723 100644 --- a/library/lib/views/tab_frame.cpp +++ b/library/lib/views/tab_frame.cpp @@ -16,6 +16,7 @@ limitations under the License. */ +#include #include #include #include @@ -37,11 +38,21 @@ const std::string tabFrameContentXML = R"xml( )xml"; +const std::string tabFrameThemeXML = R"xml( + + + + + +)xml"; + namespace brls { TabFrame::TabFrame() { + Application::getTheme().inflateFromXMLString(tabFrameThemeXML); + View* contentView = View::createFromXMLString(tabFrameContentXML); this->setContentView(contentView); }