Transitions WIP.

--HG--
branch : dev-css-refactor
This commit is contained in:
Martín Lucas Golini
2019-11-29 23:33:22 -03:00
parent 9ba1caba65
commit 44eb8cdf8d
14 changed files with 317 additions and 179 deletions

View File

@@ -8,6 +8,7 @@ ColumnLimit: '100'
CompactNamespaces: 'true'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
ContinuationIndentWidth: '4'
IndentCaseLabels: 'true'
IndentWidth: '4'
PointerAlignment: Left
SpacesInParentheses: 'true'

View File

@@ -278,6 +278,8 @@ class EE_API Node : public Transformable {
void removeActionsByTag( const Uint32& tag );
std::vector<Action *> getActionsByTag( const Uint32& tag );
void clearActions();
Transform getLocalTransform() const;

View File

@@ -80,6 +80,8 @@ class EE_API UITextView : public UIWidget {
void setFontStyleConfig( const UIFontStyleConfig& fontStyleConfig );
virtual bool applyProperty( const StyleSheetProperty& attribute, const Uint32& state = UIState::StateFlagNormal );
virtual std::string getPropertyString( const PropertyDefinition* propertyDef );
protected:
Text * mTextCache;
String mString;

View File

@@ -194,9 +194,11 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
std::vector<UIWidget*> querySelectorAll( const std::string& selector );
virtual std::string getPropertyString( const std::string& property );
std::string getPropertyString( const std::string& property );
virtual std::string getPropertyString( const PropertyDefinition* propertyDef );
bool isSceneNodeLoading() const;
protected:
friend class UIManager;
friend class UISceneNode;
@@ -255,8 +257,6 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
void reportStyleStateChange();
bool isSceneNodeLoading() const;
std::string getLayoutWidthRulesString() const;
std::string getLayoutHeightRulesString() const;

View File

@@ -1296,6 +1296,10 @@ void Node::removeActionsByTag( const Uint32& tag ) {
getActionManager()->removeActionsByTagFromTarget( this, tag );
}
std::vector<Action*> Node::getActionsByTag( const Uint32& tag ) {
return getActionManager()->getActionsByTagFromTarget( this, tag );
}
void Node::clearActions() {
getActionManager()->removeAllActionsFromTarget( this );
}

View File

@@ -51,7 +51,8 @@ const PropertyRelativeTarget& PropertyDefinition::getRelativeTarget() const {
return mRelativeTarget;
}
PropertyDefinition& PropertyDefinition::setRelativeTarget( const PropertyRelativeTarget& relativeTarget ) {
PropertyDefinition&
PropertyDefinition::setRelativeTarget( const PropertyRelativeTarget& relativeTarget ) {
mRelativeTarget = relativeTarget;
return *this;
}

View File

@@ -54,45 +54,45 @@ ShorthandDefinition::parseShorthand( const ShorthandDefinition* shorthand, std::
const std::vector<std::string> propNames( shorthand->getProperties() );
switch ( shorthand->getType() ) {
case ShorthandType::Box: {
if ( propNames.size() != 4 ) {
eePRINTL( "ShorthandType::Box properties must be 4 for %s",
shorthand->getName().c_str() );
return properties;
}
case ShorthandType::Box: {
if ( propNames.size() != 4 ) {
eePRINTL( "ShorthandType::Box properties must be 4 for %s",
shorthand->getName().c_str() );
return properties;
}
auto ltrbSplit = String::split( value, ' ', true );
auto ltrbSplit = String::split( value, ' ', true );
if ( ltrbSplit.size() >= 2 ) {
for ( size_t i = 0; i < ltrbSplit.size(); i++ )
properties.emplace_back( StyleSheetProperty( propNames[i], ltrbSplit[i] ) );
} else if ( ltrbSplit.size() == 1 ) {
for ( size_t i = 0; i < propNames.size(); i++ )
properties.emplace_back( StyleSheetProperty( propNames[i], ltrbSplit[0] ) );
}
if ( ltrbSplit.size() >= 2 ) {
for ( size_t i = 0; i < ltrbSplit.size(); i++ )
properties.emplace_back( StyleSheetProperty( propNames[i], ltrbSplit[i] ) );
} else if ( ltrbSplit.size() == 1 ) {
for ( size_t i = 0; i < propNames.size(); i++ )
properties.emplace_back( StyleSheetProperty( propNames[i], ltrbSplit[0] ) );
}
break;
}
case ShorthandType::Background: {
if ( Color::isColorString( value ) ) {
int pos = getIndexEndingWith( propNames, "-color" );
if ( pos != -1 )
properties.emplace_back( StyleSheetProperty( propNames[pos], value ) );
} else {
int pos = getIndexEndingWith( propNames, "-image" );
if ( pos != -1 )
properties.emplace_back( StyleSheetProperty( propNames[pos], value ) );
break;
}
break;
}
case ShorthandType::Transition: {
break;
}
case ShorthandType::Vector2: {
break;
}
default:
break;
case ShorthandType::Background: {
if ( Color::isColorString( value ) ) {
int pos = getIndexEndingWith( propNames, "-color" );
if ( pos != -1 )
properties.emplace_back( StyleSheetProperty( propNames[pos], value ) );
} else {
int pos = getIndexEndingWith( propNames, "-image" );
if ( pos != -1 )
properties.emplace_back( StyleSheetProperty( propNames[pos], value ) );
}
break;
}
case ShorthandType::Transition: {
break;
}
case ShorthandType::Vector2: {
break;
}
default:
break;
}
return properties;

View File

@@ -1,7 +1,7 @@
#include <eepp/ui/css/stylesheet.hpp>
#include <eepp/ui/css/stylesheetselector.hpp>
#include <eepp/ui/css/stylesheetproperty.hpp>
#include <eepp/ui/css/stylesheetelement.hpp>
#include <eepp/ui/css/stylesheetproperty.hpp>
#include <eepp/ui/css/stylesheetselector.hpp>
#include <iostream>
namespace EE { namespace UI { namespace CSS {
@@ -12,7 +12,7 @@ void StyleSheet::addStyle( const StyleSheetStyle& node ) {
auto nodeIt = mNodes.find( node.getSelector().getName() );
if ( nodeIt == mNodes.end() ) {
mNodes[ node.getSelector().getName() ] = node;
mNodes[node.getSelector().getName()] = node;
} else {
StyleSheetStyle& currentNode = nodeIt->second;
@@ -54,7 +54,8 @@ void StyleSheet::combineStyleSheet( const StyleSheet& styleSheet ) {
}
}
StyleSheetStyleVector StyleSheet::getElementStyles( StyleSheetElement * element , const bool& applyPseudo ) {
StyleSheetStyleVector StyleSheet::getElementStyles( StyleSheetElement* element,
const bool& applyPseudo ) {
StyleSheetStyleVector styles;
for ( const auto& it : mNodes ) {
@@ -73,4 +74,4 @@ const StyleSheetStyleList& StyleSheet::getStyles() const {
return mNodes;
}
}}}
}}} // namespace EE::UI::CSS

View File

@@ -8,13 +8,14 @@ namespace EE { namespace UI { namespace CSS {
bool StyleSheetPropertyTransition::transitionSupported( const PropertyType& type ) {
switch ( type ) {
case PropertyType::NumberFloat:
case PropertyType::NumberInt:
case PropertyType::NumberLength:
case PropertyType::Color:
return true;
default:
return false;
case PropertyType::NumberFloat:
case PropertyType::NumberInt:
case PropertyType::NumberLength:
case PropertyType::Color:
case PropertyType::Vector2:
return true;
default:
return false;
}
}
@@ -39,13 +40,11 @@ StyleSheetPropertyTransition::StyleSheetPropertyTransition( const PropertyDefini
mType( type ) {}
Action* StyleSheetPropertyTransition::clone() const {
return StyleSheetPropertyTransition::New( mProperty, mStartValue, mEndValue, mDuration,
mType );
return StyleSheetPropertyTransition::New( mProperty, mStartValue, mEndValue, mDuration, mType );
}
Action* StyleSheetPropertyTransition::reverse() const {
return StyleSheetPropertyTransition::New( mProperty, mEndValue, mStartValue, mDuration,
mType );
return StyleSheetPropertyTransition::New( mProperty, mEndValue, mStartValue, mDuration, mType );
}
void StyleSheetPropertyTransition::start() {
@@ -83,53 +82,87 @@ void StyleSheetPropertyTransition::onUpdate( const Time& ) {
UIWidget* node = mNode->asType<UIWidget>();
switch ( mProperty->getType() ) {
case PropertyType::NumberFloat:
case PropertyType::NumberInt: {
Float start = node->convertLength( mStartValue, 0 );
Float end = node->convertLength( mEndValue, 0 );
Time time =
mElapsed.asMicroseconds() > mDuration.asMicroseconds() ? mDuration : mElapsed;
Float value = easingCb[mType]( time.asMilliseconds(), start, end - start,
mDuration.asMilliseconds() );
if ( mProperty->getType() == PropertyType::NumberFloat ) {
node->applyProperty(
StyleSheetProperty( mProperty, String::format( "%fpx", value ) ) );
} else {
node->applyProperty( StyleSheetProperty(
mProperty, String::format( "%dpx", static_cast<int>( value ) ) ) );
case PropertyType::NumberFloat:
case PropertyType::NumberInt: {
Float start = node->convertLength( mStartValue, 0 );
Float end = node->convertLength( mEndValue, 0 );
Time time =
mElapsed.asMicroseconds() > mDuration.asMicroseconds() ? mDuration : mElapsed;
Float value = easingCb[mType]( time.asMilliseconds(), start, end - start,
mDuration.asMilliseconds() );
if ( mProperty->getType() == PropertyType::NumberFloat ) {
node->applyProperty(
StyleSheetProperty( mProperty, String::format( "%.2fpx", value ) ) );
} else {
node->applyProperty( StyleSheetProperty(
mProperty, String::format( "%dpx", static_cast<int>( value ) ) ) );
}
break;
}
break;
}
case PropertyType::Color: {
break;
}
case PropertyType::NumberLength: {
Float containerLength = 0;
switch ( mProperty->getRelativeTarget() ) {
case PropertyRelativeTarget::ContainingBlockWidth:
containerLength = node->getParent()->getPixelsSize().getWidth();
case PropertyType::Color: {
Color startColor( mStartValue );
Color endColor( mEndValue );
Time time =
mElapsed.asMicroseconds() > mDuration.asMicroseconds() ? mDuration : mElapsed;
Float progress =
easingCb[mType]( time.asMilliseconds(), 0, 1, mDuration.asMilliseconds() );
Color resColor( startColor );
resColor.r = static_cast<Uint8>( eemin(
static_cast<Int32>( startColor.r + ( endColor.r - startColor.r ) * progress ),
255 ) );
resColor.g = static_cast<Uint8>( eemin(
static_cast<Int32>( startColor.g + ( endColor.g - startColor.g ) * progress ),
255 ) );
resColor.b = static_cast<Uint8>( eemin(
static_cast<Int32>( startColor.b + ( endColor.b - startColor.b ) * progress ),
255 ) );
resColor.a = static_cast<Uint8>( eemin(
static_cast<Int32>( startColor.a + ( endColor.a - startColor.a ) * progress ),
255 ) );
node->applyProperty( StyleSheetProperty( mProperty, resColor.toHexString() ) );
break;
case PropertyRelativeTarget::ContainingBlockHeight:
containerLength = node->getParent()->getPixelsSize().getHeight();
case PropertyRelativeTarget::LocalBlockWidth:
containerLength = node->getPixelsSize().getWidth();
}
case PropertyType::NumberLength: {
Float containerLength = 0;
switch ( mProperty->getRelativeTarget() ) {
case PropertyRelativeTarget::ContainingBlockWidth:
containerLength = node->getParent()->getPixelsSize().getWidth();
break;
case PropertyRelativeTarget::ContainingBlockHeight:
containerLength = node->getParent()->getPixelsSize().getHeight();
case PropertyRelativeTarget::LocalBlockWidth:
containerLength = node->getPixelsSize().getWidth();
break;
case PropertyRelativeTarget::LocalBlockHeight:
containerLength = node->getPixelsSize().getHeight();
default:
break;
}
Float start = node->convertLength( mStartValue, containerLength );
Float end = node->convertLength( mEndValue, containerLength );
Time time =
mElapsed.asMicroseconds() > mDuration.asMicroseconds() ? mDuration : mElapsed;
Float value = easingCb[mType]( time.asMilliseconds(), start, end - start,
mDuration.asMilliseconds() );
node->applyProperty(
StyleSheetProperty( mProperty, String::format( "%.2fpx", value ) ) );
break;
case PropertyRelativeTarget::LocalBlockHeight:
containerLength = node->getPixelsSize().getHeight();
}
case PropertyType::Vector2: {
Vector2f start( StyleSheetProperty( mProperty, mStartValue ).asVector2f() );
Vector2f end( StyleSheetProperty( mProperty, mEndValue ).asVector2f() );
Time time =
mElapsed.asMicroseconds() > mDuration.asMicroseconds() ? mDuration : mElapsed;
Float x = easingCb[mType]( time.asMilliseconds(), start.x, end.x - start.x,
mDuration.asMilliseconds() );
Float y = easingCb[mType]( time.asMilliseconds(), start.y, end.y - start.y,
mDuration.asMilliseconds() );
node->applyProperty(
StyleSheetProperty( mProperty, String::format( "%.2f, %.2f", x, y ) ) );
break;
}
default:
break;
}
Float start = node->convertLength( mStartValue, containerLength );
Float end = node->convertLength( mEndValue, containerLength );
Time time =
mElapsed.asMicroseconds() > mDuration.asMicroseconds() ? mDuration : mElapsed;
Float value = easingCb[mType]( time.asMilliseconds(), start, end - start,
mDuration.asMilliseconds() );
node->applyProperty( StyleSheetProperty( mProperty, String::format( "%fpx", value ) ) );
break;
}
default:
break;
}
}
}

View File

@@ -2,13 +2,11 @@
namespace EE { namespace UI { namespace CSS {
StyleSheetStyle::StyleSheetStyle()
{}
StyleSheetStyle::StyleSheetStyle() {}
StyleSheetStyle::StyleSheetStyle( const std::string& selector, const StyleSheetProperties& properties ) :
mSelector( selector ),
mProperties( properties )
{
StyleSheetStyle::StyleSheetStyle( const std::string& selector,
const StyleSheetProperties& properties ) :
mSelector( selector ), mProperties( properties ) {
for ( auto& it : mProperties ) {
it.second.setSpecificity( mSelector.getSpecificity() );
it.second.setVolatile( !mSelector.isCacheable() );
@@ -20,7 +18,6 @@ std::string StyleSheetStyle::build() {
css += mSelector.getName() + " {";
for ( auto& it : mProperties ) {
StyleSheetProperty& prop = it.second;
@@ -32,7 +29,6 @@ std::string StyleSheetStyle::build() {
return css;
}
const StyleSheetSelector& StyleSheetStyle::getSelector() const {
return mSelector;
}
@@ -50,12 +46,12 @@ StyleSheetProperty StyleSheetStyle::getPropertyByName( const std::string& name )
return StyleSheetProperty();
}
void StyleSheetStyle::setProperty( const StyleSheetProperty & property ) {
mProperties[ property.getName() ] = property;
void StyleSheetStyle::setProperty( const StyleSheetProperty& property ) {
mProperties[property.getName()] = property;
}
void StyleSheetStyle::clearProperties() {
mProperties.clear();
}
}}}
}}} // namespace EE::UI::CSS

View File

@@ -1,9 +1,10 @@
#include <eepp/ui/css/transitiondefinition.hpp>
#include <eepp/core/string.hpp>
#include <eepp/ui/css/transitiondefinition.hpp>
namespace EE { namespace UI { namespace CSS {
std::map<std::string, TransitionDefinition> TransitionDefinition::parseTransitionProperties( const std::vector<StyleSheetProperty>& styleSheetProperties ) {
std::map<std::string, TransitionDefinition> TransitionDefinition::parseTransitionProperties(
const std::vector<StyleSheetProperty>& styleSheetProperties ) {
std::vector<std::string> properties;
std::vector<Time> durations;
std::vector<Time> delays;
@@ -22,29 +23,40 @@ std::map<std::string, TransitionDefinition> TransitionDefinition::parseTransitio
TransitionDefinition transitionDef;
if ( splitTransition.size() >= 2 ) {
std::string property = String::trim( splitTransition[0] );
std::string property = String::trim( splitTransition[0] );
String::toLowerInPlace( property );
Time duration = StyleSheetProperty( prop.getName(), String::toLower( splitTransition[1] ) ).asTime();
Time duration = StyleSheetProperty( prop.getName(),
String::toLower( splitTransition[1] ) )
.asTime();
transitionDef.property = property;
transitionDef.duration = duration;
if ( splitTransition.size() >= 3 ) {
transitionDef.timingFunction = Ease::fromName( String::toLower( splitTransition[2] ) );
transitionDef.timingFunction =
Ease::fromName( String::toLower( splitTransition[2] ) );
if ( transitionDef.timingFunction == Ease::Linear && splitTransition[2] != "linear" && splitTransition.size() == 3 ) {
transitionDef.delay = StyleSheetProperty( prop.getName(), String::toLower( splitTransition[2] ) ).asTime();
if ( transitionDef.timingFunction == Ease::Linear &&
splitTransition[2] != "linear" && splitTransition.size() == 3 ) {
transitionDef.delay =
StyleSheetProperty( prop.getName(),
String::toLower( splitTransition[2] ) )
.asTime();
} else if ( splitTransition.size() >= 4 ) {
transitionDef.delay = StyleSheetProperty( prop.getName(), String::toLower( splitTransition[3] ) ).asTime();
transitionDef.delay =
StyleSheetProperty( prop.getName(),
String::toLower( splitTransition[3] ) )
.asTime();
}
}
transitions[ transitionDef.getProperty() ] = transitionDef;
transitions[transitionDef.getProperty()] = transitionDef;
}
}
}
} else if ( prop.getName() == "transitionduration" || prop.getName() == "transition-duration" ) {
} else if ( prop.getName() == "transitionduration" ||
prop.getName() == "transition-duration" ) {
auto strDurations = String::split( prop.getValue(), ',' );
for ( auto dit = strDurations.begin(); dit != strDurations.end(); ++dit ) {
@@ -60,7 +72,8 @@ std::map<std::string, TransitionDefinition> TransitionDefinition::parseTransitio
String::toLowerInPlace( delay );
delays.push_back( StyleSheetProperty( prop.getName(), delay ).asTime() );
}
} else if ( prop.getName() == "transitiontimingfunction" || prop.getName() == "transition-timing-function" ) {
} else if ( prop.getName() == "transitiontimingfunction" ||
prop.getName() == "transition-timing-function" ) {
auto strTimingFuncs = String::split( prop.getValue(), ',' );
for ( auto dit = strTimingFuncs.begin(); dit != strTimingFuncs.end(); ++dit ) {
@@ -68,7 +81,8 @@ std::map<std::string, TransitionDefinition> TransitionDefinition::parseTransitio
String::toLowerInPlace( timingFunction );
timingFunctions.push_back( Ease::fromName( timingFunction ) );
}
} else if ( prop.getName() == "transitionproperty" || prop.getName() == "transition-property" ) {
} else if ( prop.getName() == "transitionproperty" ||
prop.getName() == "transition-property" ) {
auto strProperties = String::split( prop.getValue(), ',' );
for ( auto dit = strProperties.begin(); dit != strProperties.end(); ++dit ) {
@@ -103,10 +117,10 @@ std::map<std::string, TransitionDefinition> TransitionDefinition::parseTransitio
transitionDef.timingFunction = timingFunctions[0];
}
transitions[ property ] = transitionDef;
transitions[property] = transitionDef;
}
return transitions;
}
}}}
}}} // namespace EE::UI::CSS

View File

@@ -1,23 +1,22 @@
#include <eepp/ui/uistyle.hpp>
#include <eepp/ui/uiwidget.hpp>
#include <eepp/ui/uiscenenode.hpp>
#include <eepp/ui/uithememanager.hpp>
#include <eepp/ui/css/stylesheetspecification.hpp>
#include <eepp/graphics/fontmanager.hpp>
#include <eepp/scene/actions/actions.hpp>
#include <eepp/ui/css/stylesheetpropertytransition.hpp>
#include <eepp/ui/css/stylesheetspecification.hpp>
#include <eepp/ui/uiscenenode.hpp>
#include <eepp/ui/uistyle.hpp>
#include <eepp/ui/uithememanager.hpp>
#include <eepp/ui/uiwidget.hpp>
using namespace EE::UI::CSS;
using namespace EE::Scene;
namespace EE { namespace UI {
UIStyle * UIStyle::New( UIWidget * widget ) {
UIStyle* UIStyle::New( UIWidget* widget ) {
return eeNew( UIStyle, ( widget ) );
}
UIStyle::UIStyle( UIWidget * widget ) :
UIState(),
mWidget( widget ),
mChangingState( false )
{
UIStyle::UIStyle( UIWidget* widget ) : UIState(), mWidget( widget ), mChangingState( false ) {
load();
}
@@ -26,7 +25,7 @@ UIStyle::~UIStyle() {
unsubscribeNonCacheableStyles();
}
bool UIStyle::stateExists( const EE::Uint32& ) const {
bool UIStyle::stateExists( const EE::Uint32& ) const {
return true;
}
@@ -34,7 +33,7 @@ void UIStyle::setStyleSheetProperty( const StyleSheetProperty& attribute ) {
if ( StyleSheetSpecification::instance()->isShorthand( attribute.getName() ) ) {
std::vector<StyleSheetProperty> properties = ShorthandDefinition::parseShorthand(
StyleSheetSpecification::instance()->getShorthand( attribute.getName() ),
attribute.getValue() );
attribute.getValue() );
for ( auto& property : properties )
mElementStyle.setProperty( property );
@@ -51,7 +50,9 @@ void UIStyle::load() {
mElementStyle.clearProperties();
mProperties.clear();
UISceneNode * uiSceneNode = mWidget->getSceneNode()->isUISceneNode() ? static_cast<UISceneNode*>( mWidget->getSceneNode() ) : NULL;
UISceneNode* uiSceneNode = mWidget->getSceneNode()->isUISceneNode()
? static_cast<UISceneNode*>( mWidget->getSceneNode() )
: NULL;
if ( NULL != uiSceneNode ) {
CSS::StyleSheet& styleSheet = uiSceneNode->getStyleSheet();
@@ -83,7 +84,8 @@ void UIStyle::setStyleSheetProperties( const CSS::StyleSheetProperties& properti
}
bool UIStyle::hasTransition( const std::string& propertyName ) {
return mTransitions.find( propertyName ) != mTransitions.end() || mTransitions.find( "all" ) != mTransitions.end();
return mTransitions.find( propertyName ) != mTransitions.end() ||
mTransitions.find( "all" ) != mTransitions.end();
}
TransitionDefinition UIStyle::getTransition( const std::string& propertyName ) {
@@ -102,11 +104,11 @@ const bool& UIStyle::isChangingState() const {
return mChangingState;
}
void UIStyle::subscribeRelated( UIWidget * widget ) {
void UIStyle::subscribeRelated( UIWidget* widget ) {
mRelatedWidgets.insert( widget );
}
void UIStyle::unsubscribeRelated( UIWidget * widget ) {
void UIStyle::unsubscribeRelated( UIWidget* widget ) {
mRelatedWidgets.erase( widget );
}
@@ -116,8 +118,9 @@ void UIStyle::tryApplyStyle( const StyleSheetStyle& style ) {
const StyleSheetProperty& property = prop.second;
const auto& it = mProperties.find( property.getName() );
if ( it == mProperties.end() || property.getSpecificity() >= it->second.getSpecificity() ) {
mProperties[ 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 );
@@ -149,8 +152,74 @@ void UIStyle::onStateChange() {
for ( const auto& prop : mProperties ) {
const StyleSheetProperty& property = prop.second;
const PropertyDefinition* propertyDefinition = property.getPropertyDefinition();
mWidget->applyProperty( property, mCurrentState );
// Save default value if possible and not available.
if ( mCurrentState != UIState::StateFlagNormal ||
( mCurrentState == UIState::StateFlagNormal && property.isVolatile() ) ) {
StyleSheetProperty oldAttribute =
getStatelessStyleSheetProperty( property.getName() );
if ( oldAttribute.isEmpty() && getPreviousState() == UIState::StateFlagNormal ) {
std::string value( mWidget->getPropertyString( propertyDefinition ) );
if ( !value.empty() ) {
setStyleSheetProperty( StyleSheetProperty( propertyDefinition, value ) );
}
}
}
if ( StyleSheetPropertyTransition::transitionSupported(
propertyDefinition->getType() ) ) {
if ( !mWidget->isSceneNodeLoading() && hasTransition( property.getName() ) ) {
std::string startValue = mWidget->getPropertyString( propertyDefinition );
if ( !startValue.empty() && startValue != property.getValue() ) {
TransitionDefinition transitionInfo( getTransition( property.getName() ) );
std::vector<Action*> previousTransitions =
mWidget->getActionsByTag( propertyDefinition->getId() );
Time duration( transitionInfo.getDuration() );
if ( !previousTransitions.empty() ) {
StyleSheetPropertyTransition* prevTransition =
dynamic_cast<StyleSheetPropertyTransition*>(
previousTransitions[0] );
if ( NULL != prevTransition ) {
if ( prevTransition->getEndValue() != property.getValue() ) {
Float currentProgress =
prevTransition->getElapsed().asMilliseconds() /
transitionInfo.getDuration().asMilliseconds();
currentProgress = 1.f - eemin( 1.f, currentProgress );
duration = Milliseconds(
transitionInfo.getDuration().asMilliseconds() *
currentProgress );
mWidget->removeAction( prevTransition );
} else {
continue;
}
}
}
Action* newTransition = StyleSheetPropertyTransition::New(
propertyDefinition, startValue, property.getValue(),
transitionInfo.getDuration(), transitionInfo.getTimingFunction() );
if ( transitionInfo.getDelay().asMicroseconds() > 0 ) {
newTransition = Actions::Sequence::New(
Actions::Delay::New( transitionInfo.getDelay() ), newTransition );
}
newTransition->setTag( propertyDefinition->getId() );
mWidget->runAction( newTransition );
continue;
}
}
mWidget->applyProperty( property, mCurrentState );
} else {
mWidget->applyProperty( property, mCurrentState );
}
}
mWidget->endAttributesTransaction();
@@ -165,9 +234,10 @@ void UIStyle::onStateChange() {
}
}
StyleSheetProperty UIStyle::getStatelessStyleSheetProperty( const std::string& propertyName ) const {
StyleSheetProperty
UIStyle::getStatelessStyleSheetProperty( const std::string& propertyName ) const {
if ( !propertyName.empty() ) {
if ( !mElementStyle.getSelector().hasPseudoClasses() ) {
if ( !mElementStyle.getSelector().hasPseudoClasses() ) {
StyleSheetProperty property = mElementStyle.getPropertyByName( propertyName );
if ( !property.isEmpty() )
@@ -175,7 +245,7 @@ StyleSheetProperty UIStyle::getStatelessStyleSheetProperty( const std::string& p
}
for ( const StyleSheetStyle& style : mCacheableStyles ) {
if ( !style.getSelector().hasPseudoClasses() ) {
if ( !style.getSelector().hasPseudoClasses() ) {
StyleSheetProperty property = style.getPropertyByName( propertyName );
if ( !property.isEmpty() )
@@ -198,11 +268,11 @@ StyleSheetProperty UIStyle::getStyleSheetProperty( const std::string& propertyNa
void UIStyle::updateState() {
for ( int i = StateFlagCount - 1; i >= 0; i-- ) {
if ( ( mState & getStateFlag(i) ) == getStateFlag(i) ) {
if ( stateExists( getStateFlag(i) ) ) {
if ( mCurrentState != getStateFlag(i) ) {
if ( ( mState & getStateFlag( i ) ) == getStateFlag( i ) ) {
if ( stateExists( getStateFlag( i ) ) ) {
if ( mCurrentState != getStateFlag( i ) ) {
mPreviousState = mCurrentState;
mCurrentState = getStateFlag(i);
mCurrentState = getStateFlag( i );
break;
}
}
@@ -214,11 +284,12 @@ void UIStyle::updateState() {
void UIStyle::subscribeNonCacheableStyles() {
for ( auto& style : mNoncacheableStyles ) {
std::vector<CSS::StyleSheetElement*> elements = style.getSelector().getRelatedElements( mWidget, false );
std::vector<CSS::StyleSheetElement*> elements =
style.getSelector().getRelatedElements( mWidget, false );
if ( !elements.empty() ) {
for ( auto& element : elements ) {
UIWidget * widget = dynamic_cast<UIWidget*>( element );
UIWidget* widget = dynamic_cast<UIWidget*>( element );
if ( NULL != widget && NULL != widget->getUIStyle() ) {
widget->getUIStyle()->subscribeRelated( mWidget );
@@ -240,7 +311,7 @@ void UIStyle::unsubscribeNonCacheableStyles() {
mSubscribedWidgets.clear();
}
void UIStyle::removeFromSubscribedWidgets( UIWidget * widget ) {
void UIStyle::removeFromSubscribedWidgets( UIWidget* widget ) {
mSubscribedWidgets.erase( widget );
}
@@ -254,4 +325,4 @@ void UIStyle::removeRelatedWidgets() {
mRelatedWidgets.clear();
}
}}
}} // namespace EE::UI

View File

@@ -559,14 +559,6 @@ void UITextView::resetSelCache() {
onSelectionChange();
}
#define SAVE_NORMAL_STATE_ATTR( ATTR_FORMATED ) \
if ( state != UIState::StateFlagNormal || ( state == UIState::StateFlagNormal && attribute.isVolatile() ) ) { \
CSS::StyleSheetProperty oldAttribute = mStyle->getStatelessStyleSheetProperty( attribute.getName() ); \
if ( oldAttribute.isEmpty() && mStyle->getPreviousState() == UIState::StateFlagNormal ) { \
mStyle->setStyleSheetProperty( CSS::StyleSheetProperty( attribute.getName(), ATTR_FORMATED ) ); \
} \
}
bool UITextView::applyProperty( const StyleSheetProperty& attribute, const Uint32& state ) {
if ( !checkPropertyDefinition( attribute ) ) return false;
@@ -576,11 +568,9 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute, const Uint3
setText( static_cast<UISceneNode*>( mSceneNode )->getTranslatorString( attribute.asString() ) );
break;
case PropertyId::Color:
SAVE_NORMAL_STATE_ATTR( getFontColor().toHexString() );
setFontColor( attribute.asColor() );
break;
case PropertyId::ShadowColor:
SAVE_NORMAL_STATE_ATTR( getFontShadowColor().toHexString() );
setFontShadowColor( attribute.asColor() );
break;
case PropertyId::SelectedColor:
@@ -590,19 +580,15 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute, const Uint3
setSelectionBackColor( attribute.asColor() );
break;
case PropertyId::FontFamily:
SAVE_NORMAL_STATE_ATTR( getFont()->getName() );
setFont( FontManager::instance()->getByName( attribute.asString() ) );
break;
case PropertyId::FontSize:
SAVE_NORMAL_STATE_ATTR( String::format( "%dpx", getCharacterSize() ) );
setCharacterSize( attribute.asDpDimensionI() );
break;
case PropertyId::FontStyle:
{
Uint32 flags = attribute.asFontStyle();
SAVE_NORMAL_STATE_ATTR( Text::styleFlagToString( getFontStyle() ) );
if ( flags & UI_WORD_WRAP ) {
mFlags |= UI_WORD_WRAP;
flags &= ~ UI_WORD_WRAP;
@@ -620,11 +606,9 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute, const Uint3
autoShrink();
break;
case PropertyId::TextStrokeWidth:
SAVE_NORMAL_STATE_ATTR( String::toStr( PixelDensity::dpToPx( getOutlineThickness() ) ) )
setOutlineThickness( PixelDensity::dpToPx( attribute.asDpDimension() ) );
break;
case PropertyId::TextStrokeColor:
SAVE_NORMAL_STATE_ATTR( getOutlineColor().toHexString() );
setOutlineColor( attribute.asColor() );
break;
case PropertyId::TextSelection:
@@ -645,4 +629,31 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute, const Uint3
return true;
}
std::string UITextView::getPropertyString( const PropertyDefinition* propertyDef ) {
if ( NULL == propertyDef ) return "";
switch ( propertyDef->getPropertyId() ) {
case PropertyId::Color:
return getFontColor().toHexString();
case PropertyId::ShadowColor:
return getFontShadowColor().toHexString();
case PropertyId::SelectedColor:
return mFontStyleConfig.FontSelectedColor.toHexString();
case PropertyId::SelectionBackColor:
return getSelectionBackColor().toHexString();
case PropertyId::FontFamily:
return NULL != getFont() ? getFont()->getName() : "";
case PropertyId::FontSize:
return String::format( "%ddp", getCharacterSize() );
case PropertyId::FontStyle:
return Text::styleFlagToString( getFontStyle() );
case PropertyId::TextStrokeWidth:
return String::toStr( PixelDensity::dpToPx( getOutlineThickness() ) );
case PropertyId::TextStrokeColor:
return getOutlineColor().toHexString();
default:
return UIWidget::getPropertyString( propertyDef );
}
}
}}

View File

@@ -920,13 +920,13 @@ std::string UIWidget::getPropertyString( const PropertyDefinition* propertyDef )
switch ( propertyDef->getPropertyId() ) {
case PropertyId::X:
return String::format( "%fdp", getPosition().x );
return String::format( "%.2fdp", getPosition().x );
case PropertyId::Y:
return String::format( "%fdp", getPosition().y );
return String::format( "%.2fdp", getPosition().y );
case PropertyId::Width:
return String::format( "%fdp", getSize().getWidth() );
return String::format( "%.2fdp", getSize().getWidth() );
case PropertyId::Height:
return String::format( "%fdp", getSize().getHeight() );
return String::format( "%.2fdp", getSize().getHeight() );
case PropertyId::MarginLeft:
return String::format( "%ddp", getLayoutMargin().Left );
case PropertyId::MarginTop:
@@ -936,13 +936,13 @@ std::string UIWidget::getPropertyString( const PropertyDefinition* propertyDef )
case PropertyId::MarginBottom:
return String::format( "%ddp", getLayoutMargin().Bottom );
case PropertyId::PaddingLeft:
return String::format( "%fdp", getPadding().Left );
return String::format( "%.2fdp", getPadding().Left );
case PropertyId::PaddingTop:
return String::format( "%fdp", getPadding().Top );
return String::format( "%.2fdp", getPadding().Top );
case PropertyId::PaddingRight:
return String::format( "%fdp", getPadding().Right );
return String::format( "%.2fdp", getPadding().Right );
case PropertyId::PaddingBottom:
return String::format( "%fdp", getPadding().Bottom );
return String::format( "%.2fdp", getPadding().Bottom );
case PropertyId::BackgroundColor:
return getBackgroundColor().toHexString();
case PropertyId::ForegroundColor:
@@ -950,7 +950,7 @@ std::string UIWidget::getPropertyString( const PropertyDefinition* propertyDef )
case PropertyId::BorderColor:
return getBorderColor().toHexString();
case PropertyId::BorderRadius:
return String::format( "%ud", getBorderRadius() );
return String::format( "%u", getBorderRadius() );
case PropertyId::SkinColor:
return getSkinColor().toHexString();
case PropertyId::Rotation:
@@ -970,7 +970,7 @@ void UIWidget::setStyleSheetProperty( const std::string& name, const std::string
if ( mStyle != NULL )
mStyle->setStyleSheetProperty( CSS::StyleSheetProperty( name, value, specificity ) );
}
/*
#define SAVE_NORMAL_STATE_ATTR( ATTR_FORMATED ) \
if ( state != UIState::StateFlagNormal || ( state == UIState::StateFlagNormal && attribute.isVolatile() ) ) { \
CSS::StyleSheetProperty oldAttribute = mStyle->getStatelessStyleSheetProperty( attribute.getName() ); \
@@ -978,6 +978,8 @@ void UIWidget::setStyleSheetProperty( const std::string& name, const std::string
mStyle->setStyleSheetProperty( CSS::StyleSheetProperty( attribute.getName(), ATTR_FORMATED ) ); \
} \
}
*/
#define SAVE_NORMAL_STATE_ATTR( ATTR_FORMATED );
bool UIWidget::applyProperty( const StyleSheetProperty& attribute, const Uint32& state ) {
if ( !checkPropertyDefinition( attribute ) ) return false;