mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-11 17:17:42 +03:00
Transitions WIP.
--HG-- branch : dev-css-refactor
This commit is contained in:
@@ -8,6 +8,7 @@ ColumnLimit: '100'
|
||||
CompactNamespaces: 'true'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
|
||||
ContinuationIndentWidth: '4'
|
||||
IndentCaseLabels: 'true'
|
||||
IndentWidth: '4'
|
||||
PointerAlignment: Left
|
||||
SpacesInParentheses: 'true'
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user