diff --git a/include/eepp/ui/css/stylesheetproperty.hpp b/include/eepp/ui/css/stylesheetproperty.hpp index 0d6a09862..fc3f53f61 100644 --- a/include/eepp/ui/css/stylesheetproperty.hpp +++ b/include/eepp/ui/css/stylesheetproperty.hpp @@ -35,7 +35,8 @@ class EE_API StyleSheetProperty { StyleSheetProperty(); explicit StyleSheetProperty( const PropertyDefinition* definition, const std::string& value, - const Uint32& index = 0, bool trimValue = true ); + const Uint32& index = 0, bool trimValue = true, + bool cachedProperty = false ); explicit StyleSheetProperty( const std::string& name, const std::string& value, const bool& trimValue = true, const Uint32& specificity = 0, @@ -177,6 +178,10 @@ class EE_API StyleSheetProperty { const std::vector& getVarCache() const; + StyleSheetProperty& setCachedProperty( bool cached ); + + bool isCachedProperty() const; + protected: std::string mName; String::HashType mNameHash; @@ -187,6 +192,7 @@ class EE_API StyleSheetProperty { bool mVolatile; bool mImportant; bool mIsVarValue; + bool mCachedProperty{ false }; const PropertyDefinition* mPropertyDefinition; const ShorthandDefinition* mShorthandDefinition; std::vector mIndexedProperty; diff --git a/include/eepp/ui/css/stylesheetstyle.hpp b/include/eepp/ui/css/stylesheetstyle.hpp index bebc46226..31305cb54 100644 --- a/include/eepp/ui/css/stylesheetstyle.hpp +++ b/include/eepp/ui/css/stylesheetstyle.hpp @@ -39,6 +39,8 @@ class EE_API StyleSheetStyle { void clearProperties(); + void clearCachedProperties(); + bool hasProperties() const; bool hasProperty( PropertyId id ) const; diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index f5991faa9..fc67be50a 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -157,7 +157,8 @@ class EE_API UISceneNode : public SceneNode { void nodeToWorldTranslation( Vector2f& Pos ) const; - void reloadStyle( bool disableAnimations = false, bool forceReApplyProperties = false ); + void reloadStyle( bool disableAnimations = false, bool forceReApplyProperties = false, + bool resetPropertiesCache = false ); bool hasThreadPool() const; diff --git a/include/eepp/ui/uistyle.hpp b/include/eepp/ui/uistyle.hpp index 64b5263b1..37d84c1a9 100644 --- a/include/eepp/ui/uistyle.hpp +++ b/include/eepp/ui/uistyle.hpp @@ -77,6 +77,8 @@ class EE_API UIStyle : public UIState { void resetGlobalDefinition(); + void resetCachedProperties(); + protected: UIWidget* mWidget; std::shared_ptr mElementStyle; diff --git a/include/eepp/ui/uiwidget.hpp b/include/eepp/ui/uiwidget.hpp index 41d17a5d7..c6f910a68 100644 --- a/include/eepp/ui/uiwidget.hpp +++ b/include/eepp/ui/uiwidget.hpp @@ -197,9 +197,9 @@ class EE_API UIWidget : public UINode { UIStyle* getUIStyle() const; - void reloadStyle( const bool& reloadChilds = true, const bool& disableAnimations = false, - const bool& reportStateChange = true, - const bool& forceReApplyProperties = false ); + void reloadStyle( bool reloadChilds = true, bool disableAnimations = false, + bool reportStateChange = true, bool forceReApplyProperties = false, + bool resetPropertyCache = false ); void beginAttributesTransaction(); diff --git a/src/eepp/ui/css/stylesheetproperty.cpp b/src/eepp/ui/css/stylesheetproperty.cpp index 2c4e45484..66f175154 100644 --- a/src/eepp/ui/css/stylesheetproperty.cpp +++ b/src/eepp/ui/css/stylesheetproperty.cpp @@ -18,7 +18,7 @@ StyleSheetProperty::StyleSheetProperty() : StyleSheetProperty::StyleSheetProperty( const PropertyDefinition* definition, const std::string& value, const Uint32& index, - bool trimValue ) : + bool trimValue, bool cachedProperty ) : mName( definition->getName() ), mNameHash( definition->getId() ), mValue( trimValue ? String::trim( value ) : value ), @@ -28,6 +28,7 @@ StyleSheetProperty::StyleSheetProperty( const PropertyDefinition* definition, mVolatile( false ), mImportant( false ), mIsVarValue( false ), + mCachedProperty( cachedProperty ), mPropertyDefinition( definition ), mShorthandDefinition( NULL ) { if ( trimValue ) @@ -406,17 +407,14 @@ Vector2f StyleSheetProperty::asVector2f( const Vector2f& defaultValue ) const { if ( xySplit.size() == 2 ) { Float val; - vector.x = - String::fromString( val, String::trim( xySplit[0] ) ) ? val : defaultValue.x; - vector.y = - String::fromString( val, String::trim( xySplit[1] ) ) ? val : defaultValue.y; + vector.x = String::fromString( val, String::trim( xySplit[0] ) ) ? val : defaultValue.x; + vector.y = String::fromString( val, String::trim( xySplit[1] ) ) ? val : defaultValue.y; return vector; } else if ( xySplit.size() == 1 ) { Float val; - vector.x = vector.y = - String::fromString( val, xySplit[0] ) ? val : defaultValue.x; + vector.x = vector.y = String::fromString( val, xySplit[0] ) ? val : defaultValue.x; return vector; } @@ -433,10 +431,8 @@ Vector2i StyleSheetProperty::asVector2i( const Vector2i& defaultValue ) const { if ( xySplit.size() == 2 ) { int val; - vector.x = - String::fromString( val, String::trim( xySplit[0] ) ) ? val : defaultValue.x; - vector.y = - String::fromString( val, String::trim( xySplit[1] ) ) ? val : defaultValue.y; + vector.x = String::fromString( val, String::trim( xySplit[0] ) ) ? val : defaultValue.x; + vector.y = String::fromString( val, String::trim( xySplit[1] ) ) ? val : defaultValue.y; return vector; } else if ( xySplit.size() == 1 ) { @@ -669,4 +665,13 @@ const std::vector& StyleSheetProperty::getVarCache() cons return mVarCache; } +StyleSheetProperty& StyleSheetProperty::setCachedProperty( bool cached ) { + mCachedProperty = cached; + return *this; +} + +bool StyleSheetProperty::isCachedProperty() const { + return mCachedProperty; +} + }}} // namespace EE::UI::CSS diff --git a/src/eepp/ui/css/stylesheetstyle.cpp b/src/eepp/ui/css/stylesheetstyle.cpp index 6666474e5..a7938e60a 100644 --- a/src/eepp/ui/css/stylesheetstyle.cpp +++ b/src/eepp/ui/css/stylesheetstyle.cpp @@ -145,6 +145,17 @@ void StyleSheetStyle::clearProperties() { mProperties.clear(); } +void StyleSheetStyle::clearCachedProperties() { + StyleSheetProperties::iterator it; + do { + it = std::find_if( + mProperties.begin(), mProperties.end(), + []( const auto& model ) { return model.second.isCachedProperty(); } ); + if ( it != mProperties.end() ) + mProperties.erase( it ); + } while ( it != mProperties.end() ); +} + bool StyleSheetStyle::hasProperties() const { return !mProperties.empty(); } diff --git a/src/eepp/ui/uimenu.cpp b/src/eepp/ui/uimenu.cpp index d24b3a67e..9cf2d7382 100644 --- a/src/eepp/ui/uimenu.cpp +++ b/src/eepp/ui/uimenu.cpp @@ -768,6 +768,14 @@ void UIMenu::findBestMenuPos( Vector2f& pos, UIWidget* menu, UIMenu* parent, pos.x = 0; if ( pos.y < 0 ) pos.y = 0; + + qPos.Left = qParent.Right; + qPos.Top = pos.y; + qPos.Right = qPos.Left + menu->getPixelsSize().getWidth(); + qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); + if ( qScreen.contains( qPos ) && ( !clipMenu || !qPrevMenu.overlap( qPos ) ) ) { + pos.x = qPos.Left; + } } } } diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index f10da6a98..2a584207a 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -396,14 +396,15 @@ bool UISceneNode::hasStyleSheet() { return !mStyleSheet.isEmpty(); } -void UISceneNode::reloadStyle( bool disableAnimations, bool forceReApplyProperties ) { +void UISceneNode::reloadStyle( bool disableAnimations, bool forceReApplyProperties, + bool resetPropertiesCache ) { if ( NULL != mChild ) { Node* child = mChild; while ( NULL != child ) { if ( child->isWidget() ) { - child->asType()->reloadStyle( true, disableAnimations, true, - forceReApplyProperties ); + child->asType()->reloadStyle( + true, disableAnimations, true, forceReApplyProperties, resetPropertiesCache ); } child = child->getNextNode(); diff --git a/src/eepp/ui/uistyle.cpp b/src/eepp/ui/uistyle.cpp index 6f91edd38..0441a9605 100644 --- a/src/eepp/ui/uistyle.cpp +++ b/src/eepp/ui/uistyle.cpp @@ -68,6 +68,10 @@ void UIStyle::resetGlobalDefinition() { mLoadedVersion = stylesheet.getVersion(); } +void UIStyle::resetCachedProperties() { + mElementStyle->clearCachedProperties(); +} + void UIStyle::load() { removeStructurallyVolatileWidgetFromParent(); @@ -423,8 +427,8 @@ void UIStyle::applyStyleSheetProperty( const StyleSheetProperty& property, std::string value( mWidget->getPropertyString( propertyDefinition, property.getIndex() ) ); if ( !value.empty() ) { - setStyleSheetProperty( - StyleSheetProperty( propertyDefinition, value, property.getIndex() ) ); + setStyleSheetProperty( StyleSheetProperty( propertyDefinition, value, + property.getIndex(), true, true ) ); } } } diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index b6596a9af..88462d26c 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -568,7 +568,8 @@ void UIWidget::notifyLayoutAttrChange() { } void UIWidget::notifyLayoutAttrChangeParent() { - if ( NULL == mParentNode ) return; + if ( NULL == mParentNode ) + return; if ( 0 == mAttributesTransactionCount ) { NodeMessage msg( this, NodeMessage::LayoutAttributeChange ); @@ -1100,8 +1101,8 @@ UIStyle* UIWidget::getUIStyle() const { return mStyle; } -void UIWidget::reloadStyle( const bool& reloadChilds, const bool& disableAnimations, - const bool& reportStateChange, const bool& forceReApplyProperties ) { +void UIWidget::reloadStyle( bool reloadChilds, bool disableAnimations, bool reportStateChange, + bool forceReApplyProperties, bool resetPropertyCache ) { createStyle(); if ( NULL == mStyle ) @@ -1109,13 +1110,17 @@ void UIWidget::reloadStyle( const bool& reloadChilds, const bool& disableAnimati mStyle->load(); + if ( resetPropertyCache ) + mStyle->resetCachedProperties(); + if ( NULL != getFirstChild() && reloadChilds ) { Node* child = getFirstChild(); while ( NULL != child ) { if ( child->isWidget() ) child->asType()->reloadStyle( reloadChilds, disableAnimations, - reportStateChange, forceReApplyProperties ); + reportStateChange, forceReApplyProperties, + resetPropertyCache ); child = child->getNextNode(); } diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 1b318fe8c..f7cfffc12 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1669,7 +1669,7 @@ void App::setTheme( const std::string& path ) { mTheme = theme; - mUISceneNode->reloadStyle( true, true ); + mUISceneNode->reloadStyle( true, true, true ); if ( !firstFrame ) mPluginManager->setUIThemeReloaded(); diff --git a/src/tools/ecode/settingsmenu.cpp b/src/tools/ecode/settingsmenu.cpp index 27c1e751a..a17d30a20 100644 --- a/src/tools/ecode/settingsmenu.cpp +++ b/src/tools/ecode/settingsmenu.cpp @@ -233,9 +233,11 @@ UIMenu* SettingsMenu::createFileTypeMenu( bool emptyMenu ) { mSplitter->getCurEditor()->getSyntaxDefinition().getLanguageName() == name ); if ( mFileTypeMenues.size() == 1 && menu->getCount() == 1 ) { + auto menuBar = mUISceneNode->findByType( UI_TYPE_MENUBAR ); menu->reloadStyle( true, true ); Float height = menu->getPixelsSize().getHeight(); - Float tHeight = mUISceneNode->getPixelsSize().getHeight(); + Float tHeight = mUISceneNode->getPixelsSize().getHeight() - + ( menuBar ? menuBar->getPixelsSize().getHeight() : 0 ); maxItems = (int)eeceil( tHeight / height ) - 2; } @@ -276,9 +278,11 @@ UIMenu* SettingsMenu::createColorSchemeMenu( bool emptyMenu ) { mSplitter->getCurrentColorSchemeName() == colorScheme.first ); if ( mColorSchemeMenues.size() == 1 && menu->getCount() == 1 ) { + auto menuBar = mUISceneNode->findByType( UI_TYPE_MENUBAR ); menu->reloadStyle( true, true ); Float height = menu->getPixelsSize().getHeight(); - Float tHeight = mUISceneNode->getPixelsSize().getHeight(); + Float tHeight = mUISceneNode->getPixelsSize().getHeight() - + ( menuBar ? menuBar->getPixelsSize().getHeight() : 0 ); maxItems = (int)eeceil( tHeight / height ) - 2; }