diff --git a/include/eepp/ui/css/stylesheet.hpp b/include/eepp/ui/css/stylesheet.hpp index f0b6c68e9..9146e01bf 100644 --- a/include/eepp/ui/css/stylesheet.hpp +++ b/include/eepp/ui/css/stylesheet.hpp @@ -13,6 +13,8 @@ class EE_API StyleSheet { public: StyleSheet(); + void clear(); + void addStyle( std::shared_ptr node ); bool isEmpty() const; @@ -54,6 +56,8 @@ class EE_API StyleSheet { bool markerExists( const Uint32& marker ) const; + StyleSheet getAllWithMarker( const Uint32& marker ) const; + std::vector> findStyleFromSelectorName( const std::string& selector ) const; diff --git a/include/eepp/ui/css/stylesheetparser.hpp b/include/eepp/ui/css/stylesheetparser.hpp index 013d7d1d1..ce4a17134 100644 --- a/include/eepp/ui/css/stylesheetparser.hpp +++ b/include/eepp/ui/css/stylesheetparser.hpp @@ -6,8 +6,6 @@ #include #include #include -#include -#include #include using namespace EE; using namespace EE::System; @@ -32,6 +30,8 @@ class EE_API StyleSheetParser { bool loadFromString( const std::string& str ); + bool loadFromString( const std::string_view& str ); + void print(); StyleSheet& getStyleSheet(); diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index d5aa068ca..cc928ae88 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -13,6 +13,7 @@ class Font; namespace EE { namespace UI { +class UITheme; class UIThemeManager; class UIIconThemeManager; class UIEventDispatcher; @@ -86,7 +87,7 @@ class EE_API UISceneNode : public SceneNode { const bool& forceReloadStyle = true ); void combineStyleSheet( const std::string& inlineStyleSheet, - const bool& forceReloadStyle = true ); + const bool& forceReloadStyle = true, const Uint32& marker = 0 ); CSS::StyleSheet& getStyleSheet(); @@ -167,6 +168,8 @@ class EE_API UISceneNode : public SceneNode { void setThreadPool( const std::shared_ptr& threadPool ); + void setTheme( UITheme* theme ); + protected: friend class EE::UI::UIWindow; friend class EE::UI::UIWidget; @@ -240,6 +243,8 @@ class EE_API UISceneNode : public SceneNode { CSS::MediaFeatures getMediaFeatures() const; std::vector loadNode( pugi::xml_node node, Node* parent, const Uint32& marker ); + + void setTheme( UITheme* theme, Node* to ); }; }} // namespace EE::UI diff --git a/src/eepp/ui/css/stylesheet.cpp b/src/eepp/ui/css/stylesheet.cpp index fc9841ee9..0cfd3734b 100644 --- a/src/eepp/ui/css/stylesheet.cpp +++ b/src/eepp/ui/css/stylesheet.cpp @@ -9,6 +9,16 @@ namespace EE { namespace UI { namespace CSS { StyleSheet::StyleSheet() {} +void StyleSheet::clear() { + mVersion = 1; + mMarker = 0; + mNodes.clear(); + mNodeIndex.clear(); + mMediaQueryList.clear(); + mKeyframesMap.clear(); + mNodeCache.clear(); +} + template inline void HashCombine( std::size_t& seed, const T& v ) { std::hash hasher; seed ^= hasher( v ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 ); @@ -98,6 +108,16 @@ void StyleSheet::removeAllWithMarker( const Uint32& marker ) { invalidateCache(); } +StyleSheet StyleSheet::getAllWithMarker( const Uint32& marker ) const { + StyleSheet style; + std::vector> hits; + for ( auto node : mNodes ) { + if ( node->getMarker() == marker ) + style.addStyle( node ); + } + return style; +} + bool StyleSheet::markerExists( const Uint32& marker ) const { for ( auto node : mNodes ) { if ( node->getMarker() == marker ) diff --git a/src/eepp/ui/css/stylesheetparser.cpp b/src/eepp/ui/css/stylesheetparser.cpp index 133e558f1..c0689ab4f 100644 --- a/src/eepp/ui/css/stylesheetparser.cpp +++ b/src/eepp/ui/css/stylesheetparser.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace EE::Network; using namespace EE::System; @@ -87,6 +88,13 @@ bool StyleSheetParser::loadFromString( const std::string& str ) { return loadFromMemory( (const Uint8*)&str[0], str.size() ); } +bool StyleSheetParser::loadFromString( const std::string_view& str ) { + if ( str.empty() ) + return false; + + return loadFromMemory( (const Uint8*)str.data(), str.size() ); +} + StyleSheet& StyleSheetParser::getStyleSheet() { return mStyleSheet; } diff --git a/src/eepp/ui/tools/uicolorpicker.cpp b/src/eepp/ui/tools/uicolorpicker.cpp index db726f7a2..f3805146b 100644 --- a/src/eepp/ui/tools/uicolorpicker.cpp +++ b/src/eepp/ui/tools/uicolorpicker.cpp @@ -231,7 +231,7 @@ UIColorPicker::UIColorPicker( UIWindow* attachTo, const UIColorPicker::ColorPick UISceneNode* uiSceneNode = mUIContainer->getSceneNode()->asType(); if ( !sStyleSheetParser.isLoaded() ) { - sStyleSheetParser.loadFromString( std::string( COLOR_PICKER_STYLE ) ); + sStyleSheetParser.loadFromString( std::string_view{ COLOR_PICKER_STYLE } ); } if ( sLastSceneNode != uiSceneNode ) { diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 975bdf1a7..782fbaac3 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -304,7 +304,7 @@ std::vector UISceneNode::loadNode( pugi::xml_node node, Node* parent, } else if ( String::toLower( std::string( widget.name() ) ) == "style" ) { CSS::StyleSheetParser parser; - if ( parser.loadFromString( widget.text().as_string() ) ) { + if ( parser.loadFromString( std::string_view{ widget.text().as_string() } ) ) { parser.getStyleSheet().setMarker( marker ); combineStyleSheet( parser.getStyleSheet(), false ); } @@ -383,11 +383,14 @@ void UISceneNode::combineStyleSheet( const CSS::StyleSheet& styleSheet, } void UISceneNode::combineStyleSheet( const std::string& inlineStyleSheet, - const bool& forceReloadStyle ) { + const bool& forceReloadStyle, const Uint32& marker ) { CSS::StyleSheetParser parser; - if ( parser.loadFromString( inlineStyleSheet ) ) + if ( parser.loadFromString( inlineStyleSheet ) ) { + parser.getStyleSheet().setMarker( marker ); + combineStyleSheet( parser.getStyleSheet(), forceReloadStyle ); + } } CSS::StyleSheet& UISceneNode::getStyleSheet() { @@ -652,6 +655,18 @@ UIThemeManager* UISceneNode::getUIThemeManager() const { return mUIThemeManager; } +void UISceneNode::setTheme( UITheme* theme ) { + setTheme( theme, mRoot ); +} + +void UISceneNode::setTheme( UITheme* theme, Node* to ) { + to->forEachChild( [theme, this]( Node* node ) { + if ( node->isWidget() ) + node->asType()->setTheme( theme ); + setTheme( theme, node ); + } ); +} + UIWidget* UISceneNode::getRoot() const { return mRoot; } diff --git a/src/examples/http_request/http_request.cpp b/src/examples/http_request/http_request.cpp index ed5fc1fc9..3515eedff 100644 --- a/src/examples/http_request/http_request.cpp +++ b/src/examples/http_request/http_request.cpp @@ -1,5 +1,6 @@ #include #include +#include // Prints the response headers void printResponseHeaders( Http::Response& response ) { diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 0d8e91767..fe894fcbf 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -44,6 +44,8 @@ bool firstFrame = true; bool firstUpdate = true; App* appInstance = nullptr; +static const Uint32 APP_LAYOUT_STYLE_MARKER = String::hash( "app_layout_style" ); + void appLoop() { appInstance->mainLoop(); } @@ -1779,6 +1781,10 @@ void App::setTheme( const std::string& path ) { } mUISceneNode->setStyleSheet( theme->getStyleSheet() ); + + if ( !mAppStyleSheet.isEmpty() ) + mUISceneNode->getStyleSheet().combineStyleSheet( mAppStyleSheet ); + mUISceneNode ->getUIThemeManager() //->setDefaultEffectsEnabled( true ) @@ -1787,6 +1793,8 @@ void App::setTheme( const std::string& path ) { ->setDefaultFontSize( mConfig.ui.fontSize.asPixels( 0, Sizef(), mDisplayDPI ) ) ->add( theme ); + mUISceneNode->setTheme( theme ); + mUISceneNode->getRoot()->addClass( "appbackground" ); if ( mTheme ) @@ -3490,7 +3498,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe } )css", mConfig.ui.panelFontSize.toString().c_str() ) ); - mUISceneNode->combineStyleSheet( panelUI, false ); + mUISceneNode->combineStyleSheet( panelUI, false, APP_LAYOUT_STYLE_MARKER ); const auto baseUI = ( #include "applayout.xml.hpp" @@ -3510,7 +3518,8 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe UIWidgetCreator::registerWidget( "mainlayout", UIMainLayout::New ); UIWidgetCreator::registerWidget( "statusbar", UIStatusBar::New ); UIWidgetCreator::registerWidget( "rellayce", UIRelativeLayoutCommandExecuter::New ); - mUISceneNode->loadLayoutFromString( baseUI ); + mUISceneNode->loadLayoutFromString( baseUI, nullptr, APP_LAYOUT_STYLE_MARKER ); + mAppStyleSheet = mUISceneNode->getStyleSheet().getAllWithMarker( APP_LAYOUT_STYLE_MARKER ); mUISceneNode->bind( "main_layout", mMainLayout ); mUISceneNode->bind( "code_container", mBaseLayout ); mUISceneNode->bind( "image_container", mImageLayout ); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index c9c281e37..6ad19b2a6 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -512,6 +512,7 @@ class App : public UICodeEditorSplitter::Client { UITheme* mTheme{ nullptr }; UIStatusBar* mStatusBar{ nullptr }; UISplitter* mMainSplitter{ nullptr }; + StyleSheet mAppStyleSheet; void saveAllProcess(); diff --git a/src/tools/eterm/eterm.cpp b/src/tools/eterm/eterm.cpp index e87b7fd4a..1e3b5e926 100644 --- a/src/tools/eterm/eterm.cpp +++ b/src/tools/eterm/eterm.cpp @@ -1,6 +1,7 @@ #include #include #include +#include EE::Window::Window* win = NULL; std::shared_ptr terminal = nullptr; diff --git a/src/tools/uieditor/uieditor.cpp b/src/tools/uieditor/uieditor.cpp index 4048801f8..7fd8b4a76 100644 --- a/src/tools/uieditor/uieditor.cpp +++ b/src/tools/uieditor/uieditor.cpp @@ -1,6 +1,7 @@ #include "uieditor.hpp" #include #define PUGIXML_HEADER_ONLY +#include #include namespace uieditor {