CSS clean up.

--HG--
branch : dev
This commit is contained in:
Martín Lucas Golini
2019-01-21 00:51:27 -03:00
parent 066ad513ff
commit eea0f6dfbc
8 changed files with 455 additions and 332 deletions

View File

@@ -20,6 +20,8 @@ class EE_API StyleSheetElement {
virtual StyleSheetElement * getStyleSheetPreviousSiblingElement() const = 0;
virtual StyleSheetElement * getStyleSheetNextSiblingElement() const = 0;
virtual const std::vector<std::string>& getStyleSheetPseudoClasses() const = 0;
};
}}}

View File

@@ -2,6 +2,7 @@
#define EE_UI_CSS_STYLESHEETSELECTOR_HPP
#include <eepp/core.hpp>
#include <eepp/ui/css/stylesheetselectorrule.hpp>
namespace EE { namespace UI { namespace CSS {
@@ -9,72 +10,6 @@ class StyleSheetElement;
class EE_API StyleSheetSelector {
public:
enum SelectorType {
TagName = 1 << 0,
Id = 1 << 1,
Class = 1 << 2,
PseudoClass = 1 << 3
};
enum SpecificityVal {
SpecificityId = 1000000,
SpecificityClass = 100000,
SpecificityTag = 10000,
SpecificityPseudoClass = 100,
SpecificityGlobal = 1
};
enum PatternMatch {
ANY = '*',
DESCENDANT = ' ',
CHILD = '>',
DIRECT_SIBLING = '+',
SIBLING = '~'
};
enum SelectoryTypeIdentifier {
TAG = 0,
GLOBAL = '*',
CLASS = '.',
ID = '#',
PSEUDO_CLASS = ':',
STRUCTURAL_PSEUDO_CLASS = ':'
};
class SelectorRule {
public:
SelectorRule( const std::string& selectorFragment, PatternMatch patternMatch );
void pushSelectorTypeIdentifier( SelectoryTypeIdentifier selectorTypeIdentifier, std::string name );
void parseFragment( const std::string& selectorFragment );
const PatternMatch& getPatternMatch() const { return patternMatch; }
const int& getSpecificity() const { return specificity; }
bool matches( StyleSheetElement * element ) const;
bool hasClass( const std::string& cls ) const;
bool hasPseudoClasses() const;
const std::vector<std::string>& getPseudoClasses() const;
bool hasStructuralPseudoClasses() const;
const std::vector<std::string>& getStructuralPseudoClasses() const;
int specificity;
PatternMatch patternMatch;
std::string tagName;
std::string id;
std::vector<std::string> classes;
std::vector<std::string> pseudoClasses;
std::vector<std::string> structuralPseudoClasses;
Uint32 requirementFlags;
};
StyleSheetSelector();
explicit StyleSheetSelector( const std::string& selectorName );
@@ -86,13 +21,16 @@ class EE_API StyleSheetSelector {
const Uint32& getSpecificity() const;
bool matches( StyleSheetElement * element ) const;
const bool& isCacheable() const;
protected:
std::string mName;
std::string mPseudoClass;
Uint32 mSpecificity;
std::vector<SelectorRule> mSelectorRules;
std::vector<StyleSheetSelectorRule> mSelectorRules;
bool mCacheable;
void addSelectorRule(std::string& buffer, PatternMatch& curPatternMatch, const PatternMatch & newPatternMatch );
void addSelectorRule(std::string& buffer, StyleSheetSelectorRule::PatternMatch& curPatternMatch, const StyleSheetSelectorRule::PatternMatch & newPatternMatch );
void parseSelector( std::string selector );
};

View File

@@ -0,0 +1,82 @@
#ifndef STYLESHEETSELECTORRULE_HPP
#define STYLESHEETSELECTORRULE_HPP
#include <eepp/core.hpp>
namespace EE { namespace UI { namespace CSS {
class StyleSheetElement;
class StyleSheetSelectorRule {
public:
enum TypeIdentifier {
TAG = 0,
GLOBAL = '*',
CLASS = '.',
ID = '#',
PSEUDO_CLASS = ':',
STRUCTURAL_PSEUDO_CLASS = ':'
};
enum SelectorType {
TagName = 1 << 0,
Id = 1 << 1,
Class = 1 << 2,
PseudoClass = 1 << 3
};
enum SpecificityVal {
SpecificityId = 1000000,
SpecificityClass = 100000,
SpecificityTag = 10000,
SpecificityPseudoClass = 100,
SpecificityGlobal = 1
};
enum PatternMatch {
ANY = '*',
DESCENDANT = ' ',
CHILD = '>',
DIRECT_SIBLING = '+',
SIBLING = '~'
};
StyleSheetSelectorRule( const std::string& selectorFragment, PatternMatch mPatternMatch );
void pushSelectorTypeIdentifier( TypeIdentifier selectorTypeIdentifier, std::string name );
void parseFragment( const std::string& selectorFragment );
const PatternMatch& getPatternMatch() const { return mPatternMatch; }
const int& getSpecificity() const { return mSpecificity; }
bool matches( StyleSheetElement * element ) const;
bool hasClass( const std::string& cls ) const;
bool hasPseudoClasses() const;
bool hasPseudoClass(const std::string & cls) const;
const std::vector<std::string>& getPseudoClasses() const;
bool hasStructuralPseudoClasses() const;
const std::vector<std::string>& getStructuralPseudoClasses() const;
bool hasStructuralPseudoClass(const std::string & cls) const;
int mSpecificity;
PatternMatch mPatternMatch;
std::string mTagName;
std::string mId;
std::vector<std::string> mClasses;
std::vector<std::string> mPseudoClasses;
std::vector<std::string> mStructuralPseudoClasses;
Uint32 mRequirementFlags;
};
}}}
#endif

View File

@@ -112,6 +112,8 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
StyleSheetElement * getStyleSheetNextSiblingElement() const;
const std::vector<std::string>& getStyleSheetPseudoClasses() const;
void addClass( const std::string& cls );
void addClasses( const std::vector<std::string>& classes );
@@ -161,9 +163,12 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
int mAttributesTransactionCount;
std::string mSkinName;
std::vector<std::string> mClasses;
std::vector<std::string> mPseudoClasses;
explicit UIWidget( const std::string& tag );
void updatePseudoClasses();
void createTooltip();
virtual Uint32 onMouseMove( const Vector2i& Pos, const Uint32& Flags );

View File

@@ -310,6 +310,7 @@
../../include/eepp/ui/css/stylesheetproperty.hpp
../../include/eepp/ui/css/stylesheetselector.hpp
../../include/eepp/ui/css/stylesheetselectorparser.hpp
../../include/eepp/ui/css/stylesheetselectorrule.hpp
../../include/eepp/ui/marginmove/scale.hpp
../../include/eepp/ui/tools/textureatlaseditor.hpp
../../include/eepp/ui/uicheckbox.hpp
@@ -719,6 +720,7 @@
../../src/eepp/ui/css/stylesheetproperty.cpp
../../src/eepp/ui/css/stylesheetselector.cpp
../../src/eepp/ui/css/stylesheetselectorparser.cpp
../../src/eepp/ui/css/stylesheetselectorrule.cpp
../../src/eepp/ui/tools/textureatlaseditor.cpp
../../src/eepp/ui/tools/textureatlasnew.cpp
../../src/eepp/ui/tools/textureatlasnew.hpp

View File

@@ -1,252 +1,17 @@
#include <eepp/ui/css/stylesheetselector.hpp>
#include <eepp/ui/css/stylesheetelement.hpp>
#include <algorithm>
namespace EE { namespace UI { namespace CSS {
static const char * StatePseudoClasses[] = {
"normal",
"focus",
"selected",
"hover",
"pressed",
"selectedhover",
"selectedpressed",
"disabled"
};
static bool isPseudoClassState( const std::string& pseudoClass ) {
for ( Uint32 i = 0; i < eeARRAY_SIZE(StatePseudoClasses); i++ ) {
if ( pseudoClass == StatePseudoClasses[i] )
return true;
}
return false;
}
static const char * StructuralPseudoClasses[] = {
"root",
"nth-child",
"nth-last-child",
"nth-of-type",
"nth-last-of-type",
"nth-child",
"nth-last-child",
"first-of-type",
"last-of-type",
"only-child",
"only-of-type",
"empty"
};
static bool isStructuralPseudoClass( const std::string& pseudoClass ) {
for ( Uint32 i = 0; i < eeARRAY_SIZE(StructuralPseudoClasses); i++ ) {
if ( String::startsWith( StructuralPseudoClasses[i], pseudoClass ) )
return true;
}
return false;
}
static void splitSelectorPseudoClass( const std::string& selector, std::string& realSelector, std::string& realPseudoClass ) {
if ( !selector.empty() ) {
bool lastWasColon = false;
for ( int i = (Int32)selector.size() - 1; i >= 0; i-- ) {
char curChar = selector[i];
if ( lastWasColon ) {
if ( StyleSheetSelector::PSEUDO_CLASS == curChar ) {
// no pseudo class
realSelector = selector;
} else {
if ( i+2 <= (int)selector.size() ) {
realSelector = selector.substr(0,i+1);
realPseudoClass = selector.substr(i+2);
} else {
realSelector = selector;
}
}
return;
} else if ( StyleSheetSelector::PSEUDO_CLASS == curChar ) {
lastWasColon = true;
}
}
if ( lastWasColon ) {
if ( selector.size() > 1 )
realPseudoClass = selector.substr(1);
} else {
realSelector = selector;
}
}
}
StyleSheetSelector::SelectorRule::SelectorRule( const std::string& selectorFragment, StyleSheetSelector::PatternMatch patternMatch ) :
specificity(0),
patternMatch( patternMatch ),
requirementFlags(0)
{
parseFragment( selectorFragment );
}
void StyleSheetSelector::SelectorRule::pushSelectorTypeIdentifier( SelectoryTypeIdentifier selectorTypeIdentifier, std::string name ) {
switch ( selectorTypeIdentifier ) {
case GLOBAL:
tagName = name;
specificity += StyleSheetSelector::SpecificityGlobal;
case TAG:
tagName = name;
specificity += StyleSheetSelector::SpecificityTag;
break;
case CLASS:
classes.push_back( name );
specificity += StyleSheetSelector::SpecificityClass;
break;
case ID:
id = name;
specificity += StyleSheetSelector::SpecificityId;
break;
default:
break;
}
}
void StyleSheetSelector::SelectorRule::parseFragment( const std::string& selectorFragment ) {
std::string selector = selectorFragment;
std::string realSelector = "";
std::string pseudoClass = "";
do {
pseudoClass.clear();
realSelector.clear();
splitSelectorPseudoClass( selector, realSelector, pseudoClass );
if ( !pseudoClass.empty() ) {
if ( isPseudoClassState( pseudoClass ) ) {
pseudoClasses.push_back( pseudoClass );
} else if ( isStructuralPseudoClass( pseudoClass ) ) {
structuralPseudoClasses.push_back( pseudoClass );
}
selector = realSelector;
}
} while ( !pseudoClass.empty() );
SelectoryTypeIdentifier curSelectorType = TAG;
std::string buffer;
for ( auto charIt = selector.begin(); charIt != selector.end(); ++charIt ) {
char curChar = *charIt;
switch ( curChar ) {
case CLASS:
{
if ( !buffer.empty() ) {
pushSelectorTypeIdentifier( curSelectorType, buffer );
buffer.clear();
}
curSelectorType = CLASS;
break;
}
case ID:
{
if ( !buffer.empty() ) {
pushSelectorTypeIdentifier( curSelectorType, buffer );
buffer.clear();
}
curSelectorType = ID;
break;
}
default:
{
buffer += curChar;
break;
}
}
}
if ( !buffer.empty() ) {
if ( buffer.size() == 1 && buffer[0] == GLOBAL )
curSelectorType = GLOBAL;
pushSelectorTypeIdentifier( curSelectorType, buffer );
}
if ( !tagName.empty() )
requirementFlags |= StyleSheetSelector::TagName;
if ( !id.empty() )
requirementFlags |= StyleSheetSelector::Id;
if ( !classes.empty() )
requirementFlags |= StyleSheetSelector::Class;
}
bool StyleSheetSelector::SelectorRule::hasClass( const std::string& cls ) const {
return std::find(classes.begin(), classes.end(), cls) != classes.end();
}
bool StyleSheetSelector::SelectorRule::hasPseudoClasses() const {
return !pseudoClasses.empty();
}
const std::vector<std::string> &StyleSheetSelector::SelectorRule::getPseudoClasses() const {
return pseudoClasses;
}
bool StyleSheetSelector::SelectorRule::hasStructuralPseudoClasses() const {
return !structuralPseudoClasses.empty();
}
const std::vector<std::string> &StyleSheetSelector::SelectorRule::getStructuralPseudoClasses() const {
return structuralPseudoClasses;
}
bool StyleSheetSelector::SelectorRule::matches( StyleSheetElement * element ) const {
Uint32 flags = 0;
if ( tagName == "*" )
return true;
if ( !tagName.empty() && !element->getStyleSheetTag().empty() && tagName == element->getStyleSheetTag() ) {
flags |= StyleSheetSelector::TagName;
}
if ( !id.empty() && !element->getStyleSheetId().empty() && id == element->getStyleSheetId() ) {
flags |= StyleSheetSelector::Id;
}
if ( !classes.empty() && !element->getStyleSheetClasses().empty() ) {
bool hasClasses = true;
for ( auto cit = element->getStyleSheetClasses().begin(); cit != element->getStyleSheetClasses().end(); ++cit ) {
if ( !hasClass( *cit ) ) {
hasClasses = false;
break;
}
}
if ( hasClasses ) {
flags |= StyleSheetSelector::Class;
}
}
return requirementFlags == flags;
}
StyleSheetSelector::StyleSheetSelector() :
mSpecificity(0)
mSpecificity(0),
mCacheable(true)
{}
StyleSheetSelector::StyleSheetSelector( const std::string& selectorName ) :
mName( String::toLower( selectorName ) ),
mSpecificity(0)
mSpecificity(0),
mCacheable(true)
{
parseSelector( mName );
}
@@ -272,8 +37,8 @@ void removeExtraSpaces( std::string& string ) {
String::replaceAll( string, " ~ ", "~" );
}
void StyleSheetSelector::addSelectorRule(std::string& buffer, PatternMatch& curPatternMatch , const PatternMatch& newPatternMatch ) {
SelectorRule selectorRule( buffer, curPatternMatch );
void StyleSheetSelector::addSelectorRule(std::string& buffer, StyleSheetSelectorRule::PatternMatch& curPatternMatch , const StyleSheetSelectorRule::PatternMatch& newPatternMatch ) {
StyleSheetSelectorRule selectorRule( buffer, curPatternMatch );
mSelectorRules.push_back( selectorRule );
curPatternMatch = newPatternMatch;
buffer.clear();
@@ -290,23 +55,23 @@ void StyleSheetSelector::parseSelector( std::string selector ) {
removeExtraSpaces( selector );
std::string buffer;
PatternMatch curPatternMatch = ANY;
StyleSheetSelectorRule::PatternMatch curPatternMatch = StyleSheetSelectorRule::ANY;
for ( auto charIt = selector.rbegin(); charIt != selector.rend(); ++charIt ) {
char curChar = *charIt;
switch ( curChar ) {
case DESCENDANT:
addSelectorRule( buffer, curPatternMatch, DESCENDANT );
case StyleSheetSelectorRule::DESCENDANT:
addSelectorRule( buffer, curPatternMatch, StyleSheetSelectorRule::DESCENDANT );
break;
case CHILD:
addSelectorRule( buffer, curPatternMatch, CHILD );
case StyleSheetSelectorRule::CHILD:
addSelectorRule( buffer, curPatternMatch, StyleSheetSelectorRule::CHILD );
break;
case DIRECT_SIBLING:
addSelectorRule( buffer, curPatternMatch, DIRECT_SIBLING );
case StyleSheetSelectorRule::DIRECT_SIBLING:
addSelectorRule( buffer, curPatternMatch, StyleSheetSelectorRule::DIRECT_SIBLING );
break;
case SIBLING:
addSelectorRule( buffer, curPatternMatch, SIBLING );
case StyleSheetSelectorRule::SIBLING:
addSelectorRule( buffer, curPatternMatch, StyleSheetSelectorRule::SIBLING );
break;
default:
buffer = curChar + buffer;
@@ -315,16 +80,31 @@ void StyleSheetSelector::parseSelector( std::string selector ) {
}
if ( !buffer.empty() ) {
addSelectorRule( buffer, curPatternMatch, ANY );
addSelectorRule( buffer, curPatternMatch, StyleSheetSelectorRule::ANY );
buffer.clear();
}
if ( !mSelectorRules.empty() && mSelectorRules[0].hasPseudoClasses() ) {
mPseudoClass = mSelectorRules[0].getPseudoClasses()[0];
}
if ( !mSelectorRules.empty() && mSelectorRules.size() > 1 ) {
mCacheable = true;
for ( size_t i = 1; i < mSelectorRules.size(); i++ ) {
if ( mSelectorRules[i].hasPseudoClasses() || mSelectorRules[i].hasStructuralPseudoClasses() ) {
mCacheable = false;
break;
}
}
}
}
}
const bool &StyleSheetSelector::isCacheable() const {
return mCacheable;
}
bool StyleSheetSelector::matches( StyleSheetElement * element ) const {
if ( mSelectorRules.empty() )
return false;
@@ -332,17 +112,17 @@ bool StyleSheetSelector::matches( StyleSheetElement * element ) const {
StyleSheetElement * curElement = element;
for ( size_t i = 0; i < mSelectorRules.size(); i++ ) {
const SelectorRule& selectorRule = mSelectorRules[i];
const StyleSheetSelectorRule& selectorRule = mSelectorRules[i];
switch ( selectorRule.getPatternMatch() ) {
case ANY:
case StyleSheetSelectorRule::ANY:
{
if ( !selectorRule.matches( curElement ) )
return false;
break; // continue evaluating
}
case DESCENDANT:
case StyleSheetSelectorRule::DESCENDANT:
{
bool foundDescendant = false;
@@ -361,7 +141,7 @@ bool StyleSheetSelector::matches( StyleSheetElement * element ) const {
break; // continue evaluating
}
case CHILD:
case StyleSheetSelectorRule::CHILD:
{
curElement = curElement->getStyleSheetParentElement();
@@ -370,7 +150,7 @@ bool StyleSheetSelector::matches( StyleSheetElement * element ) const {
break; // continue evaluating
}
case DIRECT_SIBLING:
case StyleSheetSelectorRule::DIRECT_SIBLING:
{
curElement = curElement->getStyleSheetPreviousSiblingElement();
@@ -379,7 +159,7 @@ bool StyleSheetSelector::matches( StyleSheetElement * element ) const {
break; // continue evaluating
}
case SIBLING:
case StyleSheetSelectorRule::SIBLING:
{
bool foundSibling = false;
StyleSheetElement * prevSibling = curElement->getStyleSheetPreviousSiblingElement();

View File

@@ -0,0 +1,279 @@
#include <eepp/ui/css/stylesheetselectorrule.hpp>
#include <eepp/ui/css/stylesheetelement.hpp>
#include <algorithm>
namespace EE { namespace UI { namespace CSS {
static const char * StatePseudoClasses[] = {
"normal",
"focus",
"selected",
"hover",
"pressed",
"selectedhover",
"selectedpressed",
"disabled"
};
static bool isPseudoClassState( const std::string& pseudoClass ) {
for ( Uint32 i = 0; i < eeARRAY_SIZE(StatePseudoClasses); i++ ) {
if ( pseudoClass == StatePseudoClasses[i] )
return true;
}
return false;
}
static const char * StructuralPseudoClasses[] = {
"root",
"nth-child",
"nth-last-child",
"nth-of-type",
"nth-last-of-type",
"nth-child",
"nth-last-child",
"first-of-type",
"last-of-type",
"only-child",
"only-of-type",
"empty"
};
static bool isStructuralPseudoClass( const std::string& pseudoClass ) {
for ( Uint32 i = 0; i < eeARRAY_SIZE(StructuralPseudoClasses); i++ ) {
if ( String::startsWith( StructuralPseudoClasses[i], pseudoClass ) )
return true;
}
return false;
}
static void splitSelectorPseudoClass( const std::string& selector, std::string& realSelector, std::string& realPseudoClass ) {
if ( !selector.empty() ) {
bool lastWasColon = false;
for ( int i = (Int32)selector.size() - 1; i >= 0; i-- ) {
char curChar = selector[i];
if ( lastWasColon ) {
if ( StyleSheetSelectorRule::PSEUDO_CLASS == curChar ) {
// no pseudo class
realSelector = selector;
} else {
if ( i+2 <= (int)selector.size() ) {
realSelector = selector.substr(0,i+1);
realPseudoClass = selector.substr(i+2);
} else {
realSelector = selector;
}
}
return;
} else if ( StyleSheetSelectorRule::PSEUDO_CLASS == curChar ) {
lastWasColon = true;
}
}
if ( lastWasColon ) {
if ( selector.size() > 1 )
realPseudoClass = selector.substr(1);
} else {
realSelector = selector;
}
}
}
StyleSheetSelectorRule::StyleSheetSelectorRule( const std::string& selectorFragment, PatternMatch patternMatch ) :
mSpecificity(0),
mPatternMatch( patternMatch ),
mRequirementFlags(0)
{
parseFragment( selectorFragment );
}
void StyleSheetSelectorRule::pushSelectorTypeIdentifier( TypeIdentifier selectorTypeIdentifier, std::string name ) {
switch ( selectorTypeIdentifier ) {
case GLOBAL:
mTagName = name;
mSpecificity += SpecificityGlobal;
case TAG:
mTagName = name;
mSpecificity += SpecificityTag;
break;
case CLASS:
mClasses.push_back( name );
mSpecificity += SpecificityClass;
break;
case ID:
mId = name;
mSpecificity += SpecificityId;
break;
default:
break;
}
}
void StyleSheetSelectorRule::parseFragment( const std::string& selectorFragment ) {
std::string selector = selectorFragment;
std::string realSelector = "";
std::string pseudoClass = "";
do {
pseudoClass.clear();
realSelector.clear();
splitSelectorPseudoClass( selector, realSelector, pseudoClass );
if ( !pseudoClass.empty() ) {
if ( isPseudoClassState( pseudoClass ) ) {
mPseudoClasses.push_back( pseudoClass );
} else if ( isStructuralPseudoClass( pseudoClass ) ) {
mStructuralPseudoClasses.push_back( pseudoClass );
}
selector = realSelector;
}
} while ( !pseudoClass.empty() );
TypeIdentifier curSelectorType = TAG;
std::string buffer;
for ( auto charIt = selector.begin(); charIt != selector.end(); ++charIt ) {
char curChar = *charIt;
switch ( curChar ) {
case CLASS:
{
if ( !buffer.empty() ) {
pushSelectorTypeIdentifier( curSelectorType, buffer );
buffer.clear();
}
curSelectorType = CLASS;
break;
}
case ID:
{
if ( !buffer.empty() ) {
pushSelectorTypeIdentifier( curSelectorType, buffer );
buffer.clear();
}
curSelectorType = ID;
break;
}
default:
{
buffer += curChar;
break;
}
}
}
if ( !buffer.empty() ) {
if ( buffer.size() == 1 && buffer[0] == GLOBAL )
curSelectorType = GLOBAL;
pushSelectorTypeIdentifier( curSelectorType, buffer );
}
if ( !mTagName.empty() )
mRequirementFlags |= TagName;
if ( !mId.empty() )
mRequirementFlags |= Id;
if ( !mClasses.empty() )
mRequirementFlags |= Class;
if ( !mPseudoClasses.empty() ) {
//requirementFlags |= PseudoClass;
for ( auto it = mPseudoClasses.begin(); it != mPseudoClasses.end(); ++it ) {
mSpecificity += SpecificityPseudoClass;
}
}
}
bool StyleSheetSelectorRule::hasClass( const std::string& cls ) const {
return std::find(mClasses.begin(), mClasses.end(), cls) != mClasses.end();
}
bool StyleSheetSelectorRule::hasPseudoClasses() const {
return !mPseudoClasses.empty();
}
bool StyleSheetSelectorRule::hasPseudoClass( const std::string& cls ) const {
return std::find(mPseudoClasses.begin(), mPseudoClasses.end(), cls) != mPseudoClasses.end();
}
const std::vector<std::string> &StyleSheetSelectorRule::getPseudoClasses() const {
return mPseudoClasses;
}
bool StyleSheetSelectorRule::hasStructuralPseudoClasses() const {
return !mStructuralPseudoClasses.empty();
}
const std::vector<std::string> &StyleSheetSelectorRule::getStructuralPseudoClasses() const {
return mStructuralPseudoClasses;
}
bool StyleSheetSelectorRule::hasStructuralPseudoClass( const std::string& cls ) const {
return std::find(mStructuralPseudoClasses.begin(), mStructuralPseudoClasses.end(), cls) != mStructuralPseudoClasses.end();
}
bool StyleSheetSelectorRule::matches( StyleSheetElement * element ) const {
Uint32 flags = 0;
if ( mTagName == "*" )
return true;
if ( !mTagName.empty() && !element->getStyleSheetTag().empty() && mTagName == element->getStyleSheetTag() ) {
flags |= TagName;
}
if ( !mId.empty() && !element->getStyleSheetId().empty() && mId == element->getStyleSheetId() ) {
flags |= Id;
}
if ( !mClasses.empty() && !element->getStyleSheetClasses().empty() ) {
bool hasClasses = true;
for ( auto cit = element->getStyleSheetClasses().begin(); cit != element->getStyleSheetClasses().end(); ++cit ) {
if ( !hasClass( *cit ) ) {
hasClasses = false;
break;
}
}
if ( hasClasses ) {
flags |= Class;
}
}
/*if ( pseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) {
flags |= PseudoClass;
} else if ( !pseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) {
bool hasPseudoClasses = false;
const std::vector<std::string>& elPseudoClasses = element->getStyleSheetPseudoClasses();
for ( auto cit = elPseudoClasses.begin(); cit != elPseudoClasses.end(); ++cit ) {
if ( hasPseudoClass( *cit ) ) {
hasPseudoClasses = true;
break;
}
}
if ( hasPseudoClasses ) {
flags |= PseudoClass;
}
}*/
return mRequirementFlags == flags;
}
}}}

View File

@@ -480,6 +480,31 @@ CSS::StyleSheetElement * UIWidget::getStyleSheetNextSiblingElement() const {
return NULL != mNext && mNext->isWidget() ? dynamic_cast<CSS::StyleSheetElement*>( mNext ) : NULL;
}
const std::vector<std::string> &UIWidget::getStyleSheetPseudoClasses() const {
return mPseudoClasses;
}
void UIWidget::updatePseudoClasses() {
mPseudoClasses.clear();
if ( mState & UIState::StateFlagHover )
mPseudoClasses.push_back( "hover" );
if ( mState & UIState::StateFlagFocus )
mPseudoClasses.push_back( "focus" );
if ( mState & UIState::StateFlagSelected )
mPseudoClasses.push_back( "selected" );
if ( mState & UIState::StateFlagPressed )
mPseudoClasses.push_back( "pressed" );
if ( mState & UIState::StateFlagDisabled )
mPseudoClasses.push_back( "disabled" );
invalidateDraw();
}
void UIWidget::addClass( const std::string& cls ) {
if ( !cls.empty() && !containsClass( cls ) ) {
mClasses.push_back( cls );
@@ -528,19 +553,29 @@ const std::string& UIWidget::getElementTag() const {
void UIWidget::pushState( const Uint32& State, bool emitEvent ) {
if ( !( mState & ( 1 << State ) ) ) {
if ( NULL != mStyle )
mStyle->pushState( State );
UINode::pushState( State, false );
UINode::pushState( State, emitEvent );
if ( NULL != mStyle ) {
mStyle->pushState( State );
updatePseudoClasses();
}
if ( emitEvent )
onStateChange();
}
}
void UIWidget::popState( const Uint32& State, bool emitEvent ) {
if ( mState & ( 1 << State ) ) {
if ( NULL != mStyle )
mStyle->popState( State );
UINode::popState( State, false );
UINode::popState( State, emitEvent );
if ( NULL != mStyle ) {
mStyle->popState( State );
updatePseudoClasses();
}
if ( emitEvent )
onStateChange();
}
}
@@ -556,7 +591,7 @@ void UIWidget::reloadStyle( const bool& reloadChilds ) {
if ( NULL != mStyle ) {
mStyle->load();
mStyle->onStateChange();
reportStyleStateChange();
if ( NULL != mChild && reloadChilds ) {
Node * ChildLoop = mChild;