From 5eab4ab11aed7c934af804bbb8bf4529baf14b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 1 Feb 2019 21:30:08 -0300 Subject: [PATCH 01/19] Working on orienting the UI to CSS states, and removing states from the base UIWidget. --HG-- branch : dev-css --- include/eepp/ui/css/stylesheetselector.hpp | 4 + .../eepp/ui/css/stylesheetselectorrule.hpp | 2 +- include/eepp/ui/css/stylesheetstyle.hpp | 2 + include/eepp/ui/uinode.hpp | 18 -- include/eepp/ui/uistate.hpp | 2 + include/eepp/ui/uistyle.hpp | 26 +- src/eepp/scene/actions/resizeborderradius.cpp | 2 +- src/eepp/scene/actions/tint.cpp | 4 +- src/eepp/ui/css/stylesheetproperty.cpp | 3 +- src/eepp/ui/css/stylesheetselector.cpp | 13 +- src/eepp/ui/css/stylesheetselectorrule.cpp | 4 +- src/eepp/ui/css/stylesheetstyle.cpp | 9 + src/eepp/ui/uinode.cpp | 88 ++----- src/eepp/ui/uistate.cpp | 10 + src/eepp/ui/uistyle.cpp | 227 +++++++----------- src/eepp/ui/uitextview.cpp | 16 +- src/eepp/ui/uiwidget.cpp | 144 ++++++----- src/test/eetest.cpp | 4 +- 18 files changed, 271 insertions(+), 307 deletions(-) diff --git a/include/eepp/ui/css/stylesheetselector.hpp b/include/eepp/ui/css/stylesheetselector.hpp index 7d1b367fd..1ee04a27b 100644 --- a/include/eepp/ui/css/stylesheetselector.hpp +++ b/include/eepp/ui/css/stylesheetselector.hpp @@ -23,6 +23,10 @@ class EE_API StyleSheetSelector { bool select( StyleSheetElement * element, const bool& applyPseudo = true ) const; const bool& isCacheable() const; + + bool hasPseudoClass(const std::string& cls) const; + + bool hasPseudoClasses() const; protected: std::string mName; std::string mPseudoClass; diff --git a/include/eepp/ui/css/stylesheetselectorrule.hpp b/include/eepp/ui/css/stylesheetselectorrule.hpp index 3c081b1a0..5bddc40c1 100644 --- a/include/eepp/ui/css/stylesheetselectorrule.hpp +++ b/include/eepp/ui/css/stylesheetselectorrule.hpp @@ -57,7 +57,7 @@ class StyleSheetSelectorRule { bool hasPseudoClasses() const; - bool hasPseudoClass(const std::string & cls) const; + bool hasPseudoClass(const std::string& cls) const; const std::vector& getPseudoClasses() const; diff --git a/include/eepp/ui/css/stylesheetstyle.hpp b/include/eepp/ui/css/stylesheetstyle.hpp index 0ef26ac12..4520e3c73 100644 --- a/include/eepp/ui/css/stylesheetstyle.hpp +++ b/include/eepp/ui/css/stylesheetstyle.hpp @@ -18,6 +18,8 @@ class EE_API StyleSheetStyle { const StyleSheetProperties& getProperties() const; + StyleSheetProperty getPropertyByName( const std::string& name ) const; + void setProperty( const StyleSheetProperty& property ); protected: StyleSheetSelector mSelector; diff --git a/include/eepp/ui/uinode.hpp b/include/eepp/ui/uinode.hpp index d2f023253..6740c057b 100644 --- a/include/eepp/ui/uinode.hpp +++ b/include/eepp/ui/uinode.hpp @@ -89,42 +89,24 @@ class EE_API UINode : public Node { UISkin * setBackgroundFillEnabled( bool enabled ); - UINode * setBackgroundDrawable( const Uint32 & state, Drawable * drawable , bool ownIt = false ); - UINode * setBackgroundDrawable( Drawable * drawable , bool ownIt = false ); - UINode * setBackgroundColor( const Uint32 & state, const Color& color ); - UINode * setBackgroundColor( const Color& color ); - Color getBackgroundColor( const Uint32 & state ) const; - Color getBackgroundColor() const; - UINode * setBorderRadius( const Uint32 & state, const unsigned int& corners ); - UINode * setBorderRadius( const unsigned int& corners ); - Uint32 getBorderRadius( const Uint32& state ) const; - Uint32 getBorderRadius() const; UISkin * setForegroundFillEnabled( bool enabled ); - UINode * setForegroundDrawable( const Uint32 & state, Drawable * drawable , bool ownIt = false ); - UINode * setForegroundDrawable( Drawable * drawable , bool ownIt = false ); - UINode * setForegroundColor( const Uint32 & state, const Color& color ); - UINode * setForegroundColor( const Color& color ); - Color getForegroundColor( const Uint32 & state ) const; - Color getForegroundColor() const; - UINode * setForegroundRadius( const Uint32 & state, const unsigned int& corners ); - UINode * setForegroundRadius( const unsigned int& corners ); RectangleDrawable * setBorderEnabled( bool enabled ); diff --git a/include/eepp/ui/uistate.hpp b/include/eepp/ui/uistate.hpp index 74d059218..b7f235441 100644 --- a/include/eepp/ui/uistate.hpp +++ b/include/eepp/ui/uistate.hpp @@ -37,6 +37,8 @@ class EE_API UIState { static int getStateNumber(const std::string & State); + static const char * getStateNameFromStateFlag( const Uint32& stateFlag ); + static const Uint32& getStateFlag( const Uint32& stateIndex ); static Uint32 getStateFlagFromName( const std::string& name ); diff --git a/include/eepp/ui/uistyle.hpp b/include/eepp/ui/uistyle.hpp index 697356a9a..ef51719eb 100644 --- a/include/eepp/ui/uistyle.hpp +++ b/include/eepp/ui/uistyle.hpp @@ -53,33 +53,33 @@ class EE_API UIStyle : public UIState { void onStateChange(); - CSS::StyleSheetProperty getStyleSheetProperty( const Uint32& state, const std::string& attributeName ) const; + CSS::StyleSheetProperty getStatelessStyleSheetProperty( const std::string& propertyName ) const; - CSS::StyleSheetProperty getStyleSheetPropertyFromNames( const Uint32& state, const std::vector& propertiesNames ) const; + CSS::StyleSheetProperty getStyleSheetProperty( const std::string& propertyName ) const; - NodeAttribute getNodeAttribute( const Uint32& state, const std::string& attributeName ) const; + NodeAttribute getNodeAttribute(const std::string& attributeName ) const; - bool hasStyleSheetProperty( const Uint32& state, const std::string& propertyName ) const; + void addStyleSheetProperties( const CSS::StyleSheetProperties& properties ); - void addStyleSheetProperties( const Uint32& state, const CSS::StyleSheetProperties& properties ); + void addStyleSheetProperty( const CSS::StyleSheetProperty& property ); - void addStyleSheetProperty( const Uint32& state, const CSS::StyleSheetProperty& property ); + bool hasTransition( const std::string& propertyName ); - bool hasTransition( const Uint32& state, const std::string& propertyName ); - - TransitionInfo getTransition( const Uint32& state, const std::string& propertyName ); + TransitionInfo getTransition( const std::string& propertyName ); protected: typedef std::map TransitionsMap; UIWidget * mWidget; - std::map mStates; - std::map mTransitions; - std::map> mTransitionAttributes; + CSS::StyleSheetStyleVector mCacheableStyles; CSS::StyleSheetStyleVector mNoncacheableStyles; + CSS::StyleSheetStyle mElementStyle; + CSS::StyleSheetProperties mProperties; + std::vector mTransitionAttributes; + TransitionsMap mTransitions; void updateState(); - void parseTransitions( const Uint32& state ); + void parseTransitions(); }; }} diff --git a/src/eepp/scene/actions/resizeborderradius.cpp b/src/eepp/scene/actions/resizeborderradius.cpp index 167c7260f..cc612a1ab 100644 --- a/src/eepp/scene/actions/resizeborderradius.cpp +++ b/src/eepp/scene/actions/resizeborderradius.cpp @@ -24,7 +24,7 @@ void ResizeBorderRadius::onUpdate( const Time& ) { if ( NULL != mNode && mNode->isWidget() ) { UIWidget * widget = static_cast( mNode ); - widget->setBorderRadius( widget->getStyleState(), mInterpolation.getPosition() ); + widget->setBorderRadius( mInterpolation.getPosition() ); } } diff --git a/src/eepp/scene/actions/tint.cpp b/src/eepp/scene/actions/tint.cpp index 263d19caa..61fef1d32 100644 --- a/src/eepp/scene/actions/tint.cpp +++ b/src/eepp/scene/actions/tint.cpp @@ -126,7 +126,7 @@ void Tint::onUpdate( const Time& ) { switch ( mColorInterpolationType ) { case Background: { - widget->setBackgroundColor( widget->getStyleState(), + widget->setBackgroundColor( Color( mInterpolationR.getPosition(), mInterpolationG.getPosition(), mInterpolationB.getPosition(), @@ -137,7 +137,7 @@ void Tint::onUpdate( const Time& ) { } case Foreground: { - widget->setForegroundColor( widget->getStyleState(), + widget->setForegroundColor( Color( mInterpolationR.getPosition(), mInterpolationG.getPosition(), mInterpolationB.getPosition(), diff --git a/src/eepp/ui/css/stylesheetproperty.cpp b/src/eepp/ui/css/stylesheetproperty.cpp index c66e8402a..ab46d2820 100644 --- a/src/eepp/ui/css/stylesheetproperty.cpp +++ b/src/eepp/ui/css/stylesheetproperty.cpp @@ -12,7 +12,8 @@ StyleSheetProperty::StyleSheetProperty() StyleSheetProperty::StyleSheetProperty( const std::string& name, const std::string& value ) : mName( String::toLower( String::trim( name ) ) ), - mValue( String::trim( value ) ) + mValue( String::trim( value ) ), + mSpecificity( 0 ) {} StyleSheetProperty::StyleSheetProperty( const std::string & name, const std::string& value, const Uint32 & specificity ) : diff --git a/src/eepp/ui/css/stylesheetselector.cpp b/src/eepp/ui/css/stylesheetselector.cpp index ad653d3fb..694148895 100644 --- a/src/eepp/ui/css/stylesheetselector.cpp +++ b/src/eepp/ui/css/stylesheetselector.cpp @@ -4,9 +4,12 @@ namespace EE { namespace UI { namespace CSS { StyleSheetSelector::StyleSheetSelector() : + mName( "*" ), mSpecificity(0), mCacheable(true) -{} +{ + parseSelector( mName ); +} StyleSheetSelector::StyleSheetSelector( const std::string& selectorName ) : mName( String::toLower( selectorName ) ), @@ -105,6 +108,14 @@ const bool &StyleSheetSelector::isCacheable() const { return mCacheable; } +bool StyleSheetSelector::hasPseudoClass( const std::string& cls ) const { + return mSelectorRules.empty() ? false : ( cls.empty() ? true : mSelectorRules[0].hasPseudoClass( cls ) ); +} + +bool StyleSheetSelector::hasPseudoClasses() const { + return mSelectorRules.empty() || mSelectorRules[0].hasPseudoClasses(); +} + bool StyleSheetSelector::select( StyleSheetElement * element, const bool& applyPseudo ) const { if ( mSelectorRules.empty() ) return false; diff --git a/src/eepp/ui/css/stylesheetselectorrule.cpp b/src/eepp/ui/css/stylesheetselectorrule.cpp index a5baf5330..584b3705e 100644 --- a/src/eepp/ui/css/stylesheetselectorrule.cpp +++ b/src/eepp/ui/css/stylesheetselectorrule.cpp @@ -255,9 +255,7 @@ bool StyleSheetSelectorRule::matches( StyleSheetElement * element, const bool& a } if ( applyPseudo ) { - if ( mPseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) { - flags |= PseudoClass; - } else if ( !mPseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) { + if ( !mPseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) { bool hasPseudoClasses = false; const std::vector& elPseudoClasses = element->getStyleSheetPseudoClasses(); diff --git a/src/eepp/ui/css/stylesheetstyle.cpp b/src/eepp/ui/css/stylesheetstyle.cpp index ddf070c78..9d2ce4770 100644 --- a/src/eepp/ui/css/stylesheetstyle.cpp +++ b/src/eepp/ui/css/stylesheetstyle.cpp @@ -34,6 +34,15 @@ const StyleSheetProperties &StyleSheetStyle::getProperties() const { return mProperties; } +StyleSheetProperty StyleSheetStyle::getPropertyByName( const std::string& name ) const { + auto it = mProperties.find( name ); + + if ( it != mProperties.end() ) + return it->second; + + return StyleSheetProperty(); +} + void StyleSheetStyle::setProperty( const StyleSheetProperty & property ) { mProperties[ property.getName() ] = property; } diff --git a/src/eepp/ui/uinode.cpp b/src/eepp/ui/uinode.cpp index a4240ebd8..8e44547f2 100644 --- a/src/eepp/ui/uinode.cpp +++ b/src/eepp/ui/uinode.cpp @@ -390,53 +390,41 @@ UISkin * UINode::setBackgroundFillEnabled( bool enabled ) { return NULL != mBackgroundState ? mBackgroundState->getSkin() : NULL; } -UINode * UINode::setBackgroundDrawable( const Uint32& state, Drawable * drawable, bool ownIt ) { - setBackgroundFillEnabled( true )->setStateDrawable( state, drawable, ownIt ); +UINode * UINode::setBackgroundDrawable( Drawable * drawable, bool ownIt ) { + setBackgroundFillEnabled( true )->setStateDrawable( UIState::StateFlagNormal, drawable, ownIt ); return this; } -UINode * UINode::setBackgroundDrawable( Drawable * drawable, bool ownIt ) { - return setBackgroundDrawable( UIState::StateFlagNormal, drawable, ownIt ); -} - -UINode * UINode::setBackgroundColor( const Uint32 & state, const Color& color ) { +UINode * UINode::setBackgroundColor( const Color& color ) { UISkin * background = setBackgroundFillEnabled( true ); - Drawable * stateDrawable = background->getStateDrawable( state ); + Drawable * stateDrawable = background->getStateDrawable( UIState::StateFlagNormal ); if ( NULL == stateDrawable ) - setBackgroundDrawable( state, RectangleDrawable::New(), true ); + setBackgroundDrawable( RectangleDrawable::New(), true ); if ( NULL != mBackgroundState ) - mBackgroundState->setStateColor( state, color ); + mBackgroundState->setStateColor( UIState::StateFlagNormal, color ); return this; } Color UINode::getBackgroundColor() const { - return getBackgroundColor( mState ); -} - -Color UINode::getBackgroundColor( const Uint32 & state ) const { if ( NULL != mBackgroundState ) - return mBackgroundState->getStateColor( state ); + return mBackgroundState->getStateColor( UIState::StateFlagNormal ); - return Color::White; + return Color::Transparent; } -UINode * UINode::setBackgroundColor( const Color& color ) { - return setBackgroundColor( UIState::StateFlagNormal, color ); -} - -UINode * UINode::setBorderRadius( const Uint32 & state, const unsigned int& corners ) { +UINode * UINode::setBorderRadius( const unsigned int& corners ) { UISkin * background = setBackgroundFillEnabled( true ); - Drawable * stateDrawable = background->getStateDrawable( state ); + Drawable * stateDrawable = background->getStateDrawable( UIState::StateFlagNormal ); if ( NULL == stateDrawable ) { - setBackgroundColor( state, Color::Black ); + setBackgroundColor( Color::Black ); - stateDrawable = background->getStateDrawable( state ); + stateDrawable = background->getStateDrawable( UIState::StateFlagNormal ); } if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) { @@ -448,9 +436,9 @@ UINode * UINode::setBorderRadius( const Uint32 & state, const unsigned int& corn return this; } -Uint32 UINode::getBorderRadius( const Uint32& state ) const { +Uint32 UINode::getBorderRadius() const { if ( NULL != mBackgroundState && NULL != mBackgroundState->getSkin() ) { - Drawable * stateDrawable = mBackgroundState->getSkin()->getStateDrawable( state ); + Drawable * stateDrawable = mBackgroundState->getSkin()->getStateDrawable( UIState::StateFlagNormal ); if ( NULL != stateDrawable ) { if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) { @@ -464,14 +452,6 @@ Uint32 UINode::getBorderRadius( const Uint32& state ) const { return 0; } -Uint32 UINode::getBorderRadius() const { - return getBorderRadius( UIState::StateFlagNormal ); -} - -UINode * UINode::setBorderRadius( const unsigned int& corners ) { - return setBorderRadius( UIState::StateFlagNormal, corners ); -} - UISkin * UINode::setForegroundFillEnabled( bool enabled ) { writeFlag( UI_FILL_FOREGROUND, enabled ? 1 : 0 ); @@ -484,53 +464,41 @@ UISkin * UINode::setForegroundFillEnabled( bool enabled ) { return NULL != mForegroundState ? mForegroundState->getSkin() : NULL; } -UINode * UINode::setForegroundDrawable( const Uint32 & state, Drawable * drawable, bool ownIt ) { - setForegroundFillEnabled( true )->setStateDrawable( state, drawable, ownIt ); - return this; -} - UINode * UINode::setForegroundDrawable( Drawable * drawable, bool ownIt ) { - return setForegroundDrawable( UIState::StateFlagNormal, drawable, ownIt ); + setForegroundFillEnabled( true )->setStateDrawable( UIState::StateFlagNormal, drawable, ownIt ); + return this; } Color UINode::getForegroundColor() const { - return getForegroundColor( mState ); -} - -Color UINode::getForegroundColor( const Uint32 & state ) const { if ( NULL != mForegroundState ) - return mForegroundState->getStateColor( state ); + return mForegroundState->getStateColor( UIState::StateFlagNormal ); - return Color::White; + return Color::Transparent; } -UINode * UINode::setForegroundColor( const Uint32 & state, const Color& color ) { +UINode * UINode::setForegroundColor( const Color& color ) { UISkin * foreground = setForegroundFillEnabled( true ); - Drawable * stateDrawable = foreground->getStateDrawable( state ); + Drawable * stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal ); if ( NULL == stateDrawable ) - setForegroundDrawable( state, RectangleDrawable::New(), true ); + setForegroundDrawable( RectangleDrawable::New(), true ); if ( NULL != mForegroundState ) - mForegroundState->setStateColor( state, color ); + mForegroundState->setStateColor( UIState::StateFlagNormal, color ); return this; } -UINode * UINode::setForegroundColor( const Color& color ) { - return setForegroundColor( UIState::StateFlagNormal, color ); -} - -UINode * UINode::setForegroundRadius( const Uint32& state, const unsigned int& corners ) { +UINode * UINode::setForegroundRadius( const unsigned int& corners ) { UISkin * foreground = setForegroundFillEnabled( true ); - Drawable * stateDrawable = foreground->getStateDrawable( state ); + Drawable * stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal ); if ( NULL == stateDrawable ) { - setForegroundColor( state, Color::Black ); + setForegroundColor( Color::Black ); - stateDrawable = foreground->getStateDrawable( state ); + stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal ); } if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) { @@ -542,10 +510,6 @@ UINode * UINode::setForegroundRadius( const Uint32& state, const unsigned int& c return this; } -UINode * UINode::setForegroundRadius( const unsigned int& corners ) { - return setForegroundRadius( UIState::StateFlagNormal, corners ); -} - RectangleDrawable * UINode::setBorderEnabled( bool enabled ) { writeFlag( UI_BORDER, enabled ? 1 : 0 ); diff --git a/src/eepp/ui/uistate.cpp b/src/eepp/ui/uistate.cpp index ba4fd9737..f80dcdb3b 100644 --- a/src/eepp/ui/uistate.cpp +++ b/src/eepp/ui/uistate.cpp @@ -39,6 +39,16 @@ int UIState::getStateNumber( const std::string& State ) { return -1; } +const char * UIState::getStateNameFromStateFlag( const Uint32& stateFlag ) { + for ( int i = 0; i < UIState::StateCount; i++ ) { + if ( stateFlag == UIStateFlags[i] ) { + return UIStatesNames[i]; + } + } + + return NULL; +} + const Uint32& UIState::getStateFlag( const Uint32& stateIndex ) { return UIStateFlags[ stateIndex ]; } diff --git a/src/eepp/ui/uistyle.cpp b/src/eepp/ui/uistyle.cpp index f09645e6b..674f6afa3 100644 --- a/src/eepp/ui/uistyle.cpp +++ b/src/eepp/ui/uistyle.cpp @@ -21,39 +21,31 @@ UIStyle::UIStyle( UIWidget * widget ) : UIStyle::~UIStyle() {} -bool UIStyle::stateExists( const EE::Uint32 & state ) const { - return mStates.find( state ) != mStates.end(); +bool UIStyle::stateExists( const EE::Uint32& ) const { + //return mStates.find( state ) != mStates.end(); + return true; } -void UIStyle::addStyleSheetProperty( const Uint32& state, const StyleSheetProperty& attribute ) { - if ( attribute.getName() == "padding" ) { +void UIStyle::addStyleSheetProperty( const StyleSheetProperty& attribute ) { + /*if ( attribute.getName() == "padding" ) { Rectf rect( NodeAttribute( attribute.getName(), attribute.getValue() ).asRectf() ); - mStates[ state ][ "paddingleft" ] = StyleSheetProperty( "paddingleft", String::toStr( rect.Left ), attribute.getSpecificity() ); - mStates[ state ][ "paddingright" ] = StyleSheetProperty( "paddingright", String::toStr( rect.Right ), attribute.getSpecificity() ); - mStates[ state ][ "paddingtop" ] = StyleSheetProperty( "paddingtop", String::toStr( rect.Top ), attribute.getSpecificity() ); - mStates[ state ][ "paddingbottom" ] = StyleSheetProperty( "paddingbottom", String::toStr( rect.Bottom ), attribute.getSpecificity() ); + mElementStyle.setProperty( StyleSheetProperty( "paddingleft", String::toStr( rect.Left ), attribute.getSpecificity() ) ); + mElementStyle.setProperty( StyleSheetProperty( "paddingright", String::toStr( rect.Right ), attribute.getSpecificity() ) ); + mElementStyle.setProperty( StyleSheetProperty( "paddingtop", String::toStr( rect.Top ), attribute.getSpecificity() ) ); + mElementStyle.setProperty( StyleSheetProperty( "paddingbottom", String::toStr( rect.Bottom ), attribute.getSpecificity() ) ); } else if ( attribute.getName() == "layout_margin" ) { Rect rect( NodeAttribute( attribute.getName(), attribute.getValue() ).asRect() ); - mStates[ state ][ "layout_marginleft" ] = StyleSheetProperty( "layout_marginleft", String::toStr( rect.Left ), attribute.getSpecificity() ); - mStates[ state ][ "layout_marginright" ] = StyleSheetProperty( "layout_marginright", String::toStr( rect.Right ), attribute.getSpecificity() ); - mStates[ state ][ "layout_margintop" ] = StyleSheetProperty( "layout_margintop", String::toStr( rect.Top ), attribute.getSpecificity() ); - mStates[ state ][ "layout_marginbottom" ] = StyleSheetProperty( "layout_marginbottom", String::toStr( rect.Bottom ), attribute.getSpecificity() ); - } else { - mStates[ state ][ attribute.getName() ] = attribute; - } - - if ( String::startsWith( attribute.getName(), "transition" ) ) { - mTransitionAttributes[ state ].push_back( attribute ); - - parseTransitions( state ); + mElementStyle.setProperty( StyleSheetProperty( "layout_marginleft", String::toStr( rect.Left ), attribute.getSpecificity() ) ); + mElementStyle.setProperty( StyleSheetProperty( "layout_marginright", String::toStr( rect.Right ), attribute.getSpecificity() ) ); + mElementStyle.setProperty( StyleSheetProperty( "layout_margintop", String::toStr( rect.Top ), attribute.getSpecificity() ) ); + mElementStyle.setProperty( StyleSheetProperty( "layout_marginbottom", String::toStr( rect.Bottom ), attribute.getSpecificity() ) ); + } else*/ { + mElementStyle.setProperty( attribute ); } } void UIStyle::load() { - mStates.clear(); mNoncacheableStyles.clear(); - mTransitions.clear(); - mTransitionAttributes.clear(); UISceneNode * uiSceneNode = mWidget->getSceneNode()->isUISceneNode() ? static_cast( mWidget->getSceneNode() ) : NULL; @@ -61,76 +53,33 @@ void UIStyle::load() { CSS::StyleSheet& styleSheet = uiSceneNode->getStyleSheet(); if ( !styleSheet.isEmpty() ) { - CSS::StyleSheet::StyleSheetPseudoClassProperties propertiesByPseudoClass = styleSheet.getElementPropertiesByState( mWidget ); - - if ( !propertiesByPseudoClass.empty() ) { - Uint32 stateFlag; - - for ( auto it = propertiesByPseudoClass.begin(); it != propertiesByPseudoClass.end(); ++it ) { - stateFlag = getStateFlagFromName( it->first ); - - if ( eeINDEX_NOT_FOUND != stateFlag ) - addStyleSheetProperties( stateFlag, it->second ); - } - } - + mCacheableStyles = styleSheet.getCacheableElementStyles( mWidget ); mNoncacheableStyles = styleSheet.getNoncacheableElementStyles( mWidget ); } } } -void UIStyle::addStyleSheetProperties(const Uint32 & state, const CSS::StyleSheetProperties& properties ) { +void UIStyle::addStyleSheetProperties( const CSS::StyleSheetProperties& properties ) { if ( !properties.empty() ) { for ( auto it = properties.begin(); it != properties.end(); ++it ) { CSS::StyleSheetProperty property = it->second; - addStyleSheetProperty( state, property ); + addStyleSheetProperty( property ); } } } -bool UIStyle::hasTransition( const Uint32& state, const std::string& propertyName ) { - bool ret = mTransitions.find( state ) != mTransitions.end() && - ( mTransitions[ state ].find( propertyName ) != mTransitions[ state ].end() || - mTransitions[ state ].find( "all" ) != mTransitions[ state ].end() - ); - - // When transitions are declared without state are global - if ( !ret && state != StateFlagNormal ) { - ret = mTransitions.find( StateFlagNormal ) != mTransitions.end() && ( - mTransitions[ StateFlagNormal ].find( propertyName ) != mTransitions[ StateFlagNormal ].end() || - mTransitions[ StateFlagNormal ].find( "all" ) != mTransitions[ StateFlagNormal ].end() - ); - } - - return ret; +bool UIStyle::hasTransition( const std::string& propertyName ) { + return mTransitions.find( propertyName ) != mTransitions.end() || mTransitions.find( "all" ) != mTransitions.end(); } -UIStyle::TransitionInfo UIStyle::getTransition( const Uint32& state, const std::string& propertyName ) { - if ( mTransitions.find( state ) != mTransitions.end() ) { - auto propertyTransitionIt = mTransitions[ state ].find( propertyName ); +UIStyle::TransitionInfo UIStyle::getTransition( const std::string& propertyName ) { + auto propertyTransitionIt = mTransitions.find( propertyName ); - if ( propertyTransitionIt != mTransitions[ state ].end() ) { - return propertyTransitionIt->second; - } else if ( ( propertyTransitionIt = mTransitions[ state ].find( "all" ) ) != mTransitions[ state ].end() ) { - return propertyTransitionIt->second; - } else if ( mTransitions.find( StateFlagNormal ) != mTransitions.end() ) { - propertyTransitionIt = mTransitions[ StateFlagNormal ].find( propertyName ); - - if ( propertyTransitionIt != mTransitions[ StateFlagNormal ].end() ) { - return propertyTransitionIt->second; - } else if ( ( propertyTransitionIt = mTransitions[ StateFlagNormal ].find( "all" ) ) != mTransitions[ state ].end() ) { - return propertyTransitionIt->second; - } - } - } else if ( mTransitions.find( StateFlagNormal ) != mTransitions.end() ) { - auto propertyTransitionIt = mTransitions[ StateFlagNormal ].find( propertyName ); - - if ( propertyTransitionIt != mTransitions[ StateFlagNormal ].end() ) { - return propertyTransitionIt->second; - } else if ( ( propertyTransitionIt = mTransitions[ StateFlagNormal ].find( "all" ) ) != mTransitions[ state ].end() ) { - return propertyTransitionIt->second; - } + if ( propertyTransitionIt != mTransitions.end() ) { + return propertyTransitionIt->second; + } else if ( ( propertyTransitionIt = mTransitions.find( "all" ) ) != mTransitions.end() ) { + return propertyTransitionIt->second; } return TransitionInfo(); @@ -138,16 +87,36 @@ UIStyle::TransitionInfo UIStyle::getTransition( const Uint32& state, const std:: void UIStyle::onStateChange() { if ( NULL != mWidget ) { - StyleSheetProperties properties; + mProperties.clear(); + mTransitionAttributes.clear(); - auto& props = mStates[ mCurrentState ]; + if ( mElementStyle.getSelector().select( mWidget ) ) { + for ( auto& prop : mElementStyle.getProperties() ) { + auto& property = prop.second; + auto it = mProperties.find( property.getName() ); - for ( auto& prop : props ) { - auto& property = prop.second; - auto it = properties.find( property.getName() ); + if ( it == mProperties.end() || property.getSpecificity() >= it->second.getSpecificity() ) { + mProperties[ property.getName() ] = property; - if ( it == properties.end() || property.getSpecificity() >= it->second.getSpecificity() ) { - properties[ property.getName() ] = property; + if ( String::startsWith( property.getName(), "transition" ) ) + mTransitionAttributes.push_back( property ); + } + } + } + + for ( auto& style : mCacheableStyles ) { + if ( style.getSelector().select( mWidget ) ) { + for ( auto& prop : style.getProperties() ) { + auto& property = prop.second; + auto it = mProperties.find( property.getName() ); + + if ( it == mProperties.end() || property.getSpecificity() >= it->second.getSpecificity() ) { + mProperties[ property.getName() ] = property; + + if ( String::startsWith( property.getName(), "transition" ) ) + mTransitionAttributes.push_back( property ); + } + } } } @@ -155,18 +124,23 @@ void UIStyle::onStateChange() { if ( style.getSelector().select( mWidget ) ) { for ( auto& prop : style.getProperties() ) { auto& property = prop.second; - auto it = properties.find( property.getName() ); + auto it = mProperties.find( property.getName() ); - if ( it == properties.end() || property.getSpecificity() >= it->second.getSpecificity() ) { - properties[ property.getName() ] = property; + if ( it == mProperties.end() || property.getSpecificity() >= it->second.getSpecificity() ) { + mProperties[ property.getName() ] = property; + + if ( String::startsWith( property.getName(), "transition" ) ) + mTransitionAttributes.push_back( property ); } } } } + parseTransitions(); + mWidget->beginAttributesTransaction(); - for ( auto& prop : properties ) { + for ( auto& prop : mProperties ) { auto& property = prop.second; mWidget->setAttribute( property.getName(), property.getValue(), mCurrentState ); @@ -176,50 +150,40 @@ void UIStyle::onStateChange() { } } -StyleSheetProperty UIStyle::getStyleSheetProperty( const Uint32& state, const std::string& attributeName ) const { - if ( !attributeName.empty() && stateExists( state ) ) { - auto& attributesMap = mStates.at( state ); +StyleSheetProperty UIStyle::getStatelessStyleSheetProperty( const std::string& propertyName ) const { + if ( !propertyName.empty() ) { + if ( !mElementStyle.getSelector().hasPseudoClasses() ) { + StyleSheetProperty property = mElementStyle.getPropertyByName( propertyName ); - auto attributeFound = attributesMap.find( attributeName ); - - if ( attributeFound != attributesMap.end() ) { - return attributeFound->second; + if ( !property.isEmpty() ) + return property; } - } - return StyleSheetProperty(); -} + for ( const StyleSheetStyle& style : mCacheableStyles ) { + if ( !style.getSelector().hasPseudoClasses() ) { + StyleSheetProperty property = style.getPropertyByName( propertyName ); -StyleSheetProperty UIStyle::getStyleSheetPropertyFromNames( const Uint32& state, const std::vector& propertiesNames ) const { - if ( !propertiesNames.empty() && stateExists( state ) ) { - auto& attributesMap = mStates.at( state ); - - for ( size_t i = 0; i < propertiesNames.size(); i++ ) { - const std::string& name = propertiesNames[i]; - auto attributeFound = attributesMap.find( name ); - - if ( attributeFound != attributesMap.end() ) { - return attributeFound->second; + if ( !property.isEmpty() ) + return property; } - } } return StyleSheetProperty(); } -NodeAttribute UIStyle::getNodeAttribute( const Uint32& state, const std::string& attributeName ) const { - StyleSheetProperty property( getStyleSheetProperty( state, attributeName ) ); - return NodeAttribute( property.getName(), property.getValue() ); +StyleSheetProperty UIStyle::getStyleSheetProperty( const std::string& propertyName ) const { + auto propertyIt = mProperties.find( propertyName ); + + if ( propertyIt != mProperties.end() ) + return propertyIt->second; + + return StyleSheetProperty(); } -bool UIStyle::hasStyleSheetProperty( const Uint32 & state, const std::string& propertyName ) const { - if ( !propertyName.empty() && stateExists( state ) ) { - auto& attributesMap = mStates.at( state ); - return attributesMap.find( propertyName ) != attributesMap.end(); - } - - return false; +NodeAttribute UIStyle::getNodeAttribute( const std::string& attributeName ) const { + StyleSheetProperty property( getStyleSheetProperty( attributeName ) ); + return NodeAttribute( property.getName(), property.getValue() ); } void UIStyle::updateState() { @@ -229,36 +193,23 @@ void UIStyle::updateState() { if ( mCurrentState != getStateFlag(i) ) { mPreviousState = mCurrentState; mCurrentState = getStateFlag(i); - onStateChange(); + break; } - - return; } } } - Uint32 currentState = mCurrentState; - - mCurrentState = StateFlagNormal; - - if ( currentState != StateFlagNormal ) { - onStateChange(); - } + onStateChange(); } -void UIStyle::parseTransitions( const Uint32& state ) { +void UIStyle::parseTransitions() { std::vector properties; std::vector