CSS Transitions WIP.

--HG--
branch : dev
This commit is contained in:
Martín Lucas Golini
2019-01-07 03:51:08 -03:00
parent ab1715c9c5
commit ecbf592eb3
13 changed files with 404 additions and 8 deletions

View File

@@ -81,7 +81,8 @@ Tooltip {
#tpad2 {
layout_marginLeft: 0;
padding: 24dp;
opacity: 0.5;
opacity: 0.8;
backgroundColor: #333;
transition: all 0.25s;
}
@@ -89,4 +90,5 @@ Tooltip {
layout_marginLeft: 8dp;
padding: 28dp;
opacity: 1;
backgroundColor: #656;
}

View File

@@ -15,6 +15,7 @@
#include <eepp/scene/actions/close.hpp>
#include <eepp/scene/actions/disable.hpp>
#include <eepp/scene/actions/visible.hpp>
#include <eepp/scene/actions/colorinterpolation.hpp>
#endif

View File

@@ -0,0 +1,71 @@
#ifndef EE_SCENE_ACTIONS_COLORINTERPOLATION_HPP
#define EE_SCENE_ACTIONS_COLORINTERPOLATION_HPP
#include <eepp/scene/action.hpp>
#include <eepp/math/interpolation1d.hpp>
#include <eepp/math/rect.hpp>
#include <eepp/system/color.hpp>
using namespace EE::Math;
namespace EE { namespace Scene { namespace Actions {
class EE_API ColorInterpolation : public Action {
public:
enum ColorInterpolationType {
Background,
Foreground,
Skin,
Border,
Text
};
static ColorInterpolation * New( const Color& start, const Color& end, const bool& interpolateAlpha, const Time& duration, const Ease::Interpolation& type = Ease::Linear, const ColorInterpolationType& colorInterpolationType = Background );
void start() override;
void stop() override;
void update( const Time& time ) override;
bool isDone() override;
virtual Action * clone() const override;
Action * reverse() const override;
Interpolation1d getInterpolationR() const;
void setInterpolationR(const Interpolation1d & interpolationR);
Interpolation1d getInterpolationG() const;
void setInterpolationG(const Interpolation1d & interpolationG);
Interpolation1d getInterpolationB() const;
void setInterpolationB(const Interpolation1d & interpolationB);
Interpolation1d getInterpolationA() const;
void setInterpolationA(const Interpolation1d & interpolationA);
protected:
ColorInterpolation( const Color& start, const Color& end, const bool& interpolateAlpha, const Time & duration, const Ease::Interpolation & type, const ColorInterpolationType& colorInterpolationType );
void onStart() override;
virtual void onUpdate( const Time& time ) override;
ColorInterpolation();
Interpolation1d mInterpolationR;
Interpolation1d mInterpolationG;
Interpolation1d mInterpolationB;
Interpolation1d mInterpolationA;
ColorInterpolationType mColorInterpolationType;
bool mInterpolateAlpha;
};
}}}
#endif

View File

@@ -99,6 +99,10 @@ class EE_API UINode : public Node {
UINode * setBackgroundColor( const Color& color );
Color getBackgroundColor( const Uint32 & state );
Color getBackgroundColor();
UINode * setBackgroundCorners( const Uint32 & state, const unsigned int& corners );
UINode * setBackgroundCorners( const unsigned int& corners );
@@ -113,6 +117,10 @@ class EE_API UINode : public Node {
UINode * setForegroundColor( const Color& color );
Color getForegroundColor( const Uint32 & state );
Color getForegroundColor();
UINode * setForegroundCorners( const Uint32 & state, const unsigned int& corners );
UINode * setForegroundCorners( const unsigned int& corners );
@@ -123,6 +131,10 @@ class EE_API UINode : public Node {
UINode * setBorderColor( const Color& color );
Color getBorderColor( const Uint32 & state );
Color getBorderColor();
UINode * setBorderWidth( const Uint32 & state, const unsigned int& width );
UINode * setBorderWidth( const unsigned int& width );

View File

@@ -57,10 +57,13 @@ class EE_API UIState {
virtual bool stateExists( const Uint32& State ) const = 0;
Uint32 getCurrentState() const;
const Uint32& getCurrentState() const;
const Uint32& getPreviousState() const;
protected:
Uint32 mState;
Uint32 mCurrentState;
Uint32 mPreviousState;
virtual void updateState() = 0;

View File

@@ -133,6 +133,10 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
void beginAttributesTransaction();
void endAttributesTransaction();
const Uint32& getStyleState() const;
const Uint32& getStylePreviousState() const;
protected:
friend class UIManager;
friend class UISceneNode;

View File

@@ -210,6 +210,7 @@
../../include/eepp/scene/actions/actioninterpolation2d.hpp
../../include/eepp/scene/actions/actions.hpp
../../include/eepp/scene/actions/close.hpp
../../include/eepp/scene/actions/colorinterpolation.hpp
../../include/eepp/scene/actions/delay.hpp
../../include/eepp/scene/actions/disable.hpp
../../include/eepp/scene/actions/enable.hpp
@@ -632,6 +633,7 @@
../../src/eepp/scene/actions/actioninterpolation1d.cpp
../../src/eepp/scene/actions/actioninterpolation2d.cpp
../../src/eepp/scene/actions/close.cpp
../../src/eepp/scene/actions/colorinterpolation.cpp
../../src/eepp/scene/actions/delay.cpp
../../src/eepp/scene/actions/disable.cpp
../../src/eepp/scene/actions/enable.cpp

View File

@@ -0,0 +1,189 @@
#include <eepp/scene/actions/colorinterpolation.hpp>
#include <eepp/ui/uiwidget.hpp>
#include <eepp/ui/uitextview.hpp>
using namespace EE::UI;
namespace EE { namespace Scene { namespace Actions {
ColorInterpolation * ColorInterpolation::New( const Color& start, const Color& end, const bool& interpolateAlpha, const Time& duration, const Ease::Interpolation& type, const ColorInterpolationType& colorInterpolationType ) {
return eeNew( ColorInterpolation, ( start, end, interpolateAlpha, duration, type, colorInterpolationType ) );
}
ColorInterpolation::ColorInterpolation()
{}
Interpolation1d ColorInterpolation::getInterpolationA() const {
return mInterpolationA;
}
void ColorInterpolation::setInterpolationA(const Interpolation1d & interpolationA) {
mInterpolationA = interpolationA;
}
Interpolation1d ColorInterpolation::getInterpolationB() const {
return mInterpolationB;
}
void ColorInterpolation::setInterpolationB(const Interpolation1d& interpolationB) {
mInterpolationB = interpolationB;
}
Interpolation1d ColorInterpolation::getInterpolationG() const {
return mInterpolationG;
}
void ColorInterpolation::setInterpolationG(const Interpolation1d & interpolationG) {
mInterpolationG = interpolationG;
}
Interpolation1d ColorInterpolation::getInterpolationR() const {
return mInterpolationR;
}
void ColorInterpolation::setInterpolationR(const Interpolation1d & interpolationR) {
mInterpolationR = interpolationR;
}
ColorInterpolation::ColorInterpolation( const Color& start, const Color & end, const bool& interpolateAlpha, const Time& duration, const Ease::Interpolation& type, const ColorInterpolationType& colorInterpolationType ) :
mColorInterpolationType( colorInterpolationType ),
mInterpolateAlpha( interpolateAlpha )
{
mInterpolationR.clear().add( start.r, duration ).add( end.r ).setType( type );
mInterpolationG.clear().add( start.g, duration ).add( end.g ).setType( type );
mInterpolationB.clear().add( start.b, duration ).add( end.b ).setType( type );
if ( interpolateAlpha )
mInterpolationA.clear().add( start.a, duration ).add( end.a ).setType( type );
}
void ColorInterpolation::start() {
mInterpolationR.start();
mInterpolationG.start();
mInterpolationB.start();
if ( mInterpolateAlpha )
mInterpolationA.start();
onStart();
sendEvent( ActionType::OnStart );
}
void ColorInterpolation::stop() {
mInterpolationR.stop();
mInterpolationG.stop();
mInterpolationB.stop();
if ( mInterpolateAlpha )
mInterpolationA.stop();
onStop();
sendEvent( ActionType::OnStop );
}
void ColorInterpolation::update( const Time& time ) {
mInterpolationR.update( time );
mInterpolationG.update( time );
mInterpolationB.update( time );
mInterpolationA.update( time );
onUpdate( time );
}
bool ColorInterpolation::isDone() {
return mInterpolationR.ended() &&
mInterpolationG.ended() &&
mInterpolationB.ended() && (
!mInterpolateAlpha ||
mInterpolationA.ended() );
}
void ColorInterpolation::onStart() {
if ( NULL != mNode && mNode->isWidget() ) {
onUpdate( Time::Zero );
}
}
Action * ColorInterpolation::clone() const {
ColorInterpolation * action = eeNew( ColorInterpolation, () );
action->setInterpolationR( mInterpolationR );
action->setInterpolationG( mInterpolationG );
action->setInterpolationB( mInterpolationB );
action->setInterpolationA( mInterpolationA );
return action;
}
Action * ColorInterpolation::reverse() const {
return NULL;
}
void ColorInterpolation::onUpdate( const Time& ) {
if ( NULL != mNode && mNode->isWidget() ) {
UIWidget * widget = static_cast<UIWidget*>( mNode );
switch ( mColorInterpolationType ) {
case Background:
{
widget->setBackgroundColor( widget->getStyleState(),
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
mInterpolateAlpha ? mInterpolationA.getPosition() : 255
) );
break;
}
case Foreground:
{
widget->setForegroundColor( widget->getStyleState(),
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
mInterpolateAlpha ? mInterpolationA.getPosition() : 255
) );
break;
}
case Skin:
{
/*
widget->setSkinColor( widget->getStyleState(),
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
mInterpolateAlpha ? mInterpolationA.getPosition() : 255
) );
*/
break;
}
case Border:
{
widget->setBorderColor( widget->getStyleState(),
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
mInterpolateAlpha ? mInterpolationA.getPosition() : 255
) );
break;
}
case Text:
{
if ( widget->isType( UI_TYPE_TEXTVIEW ) ) {
UITextView * textView = static_cast<UITextView*>( widget );
textView->setFontColor( Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
mInterpolateAlpha ? mInterpolationA.getPosition() : 255 ) );
}
break;
}
}
}
}
}}}

View File

@@ -31,7 +31,7 @@ UINode * UINode::New() {
UINode::UINode() :
Node(),
mFlags( UI_CONTROL_DEFAULT_FLAGS ),
mState(0),
mState(UIState::StateFlagNormal),
mSkinState( NULL ),
mBackgroundState( NULL ),
mForegroundState( NULL ),
@@ -424,6 +424,24 @@ UINode * UINode::setBackgroundColor( const Uint32 & state, const Color& color )
return this;
}
Color UINode::getBackgroundColor() {
return getBackgroundColor( mState );
}
Color UINode::getBackgroundColor( const Uint32 & state ) {
UISkin * background = setBackgroundFillEnabled( true );
Drawable * stateDrawable = background->getStateDrawable( state );
if ( NULL == stateDrawable ) {
RectangleDrawable * colorDrawable = RectangleDrawable::New();
return colorDrawable->getColor();
} else {
return stateDrawable->getColor();
}
}
UINode * UINode::setBackgroundColor( const Color& color ) {
return setBackgroundColor( UIState::StateFlagNormal, color );
}
@@ -473,6 +491,24 @@ UINode * UINode::setForegroundDrawable( Drawable * drawable, bool ownIt ) {
return setForegroundDrawable( UIState::StateFlagNormal, drawable, ownIt );
}
Color UINode::getForegroundColor() {
return getForegroundColor( mState );
}
Color UINode::getForegroundColor( const Uint32 & state ) {
UISkin * foreground = setForegroundFillEnabled( true );
Drawable * stateDrawable = foreground->getStateDrawable( state );
if ( NULL == stateDrawable ) {
RectangleDrawable * colorDrawable = RectangleDrawable::New();
return colorDrawable->getColor();
} else {
return stateDrawable->getColor();
}
}
UINode * UINode::setForegroundColor( const Uint32 & state, const Color& color ) {
UISkin * foreground = setForegroundFillEnabled( true );
@@ -557,6 +593,25 @@ UINode * UINode::setBorderColor( const Color& color ) {
return setBorderColor( UIState::StateFlagNormal, color );
}
Color UINode::getBorderColor() {
return getBorderColor( mState );
}
Color UINode::getBorderColor( const Uint32 & state ) {
UISkin * border = setBorderEnabled( true );
Drawable * stateDrawable = border->getStateDrawable( state );
if ( NULL == stateDrawable ) {
RectangleDrawable * borderDrawable = RectangleDrawable::New();
borderDrawable->setFillMode( PrimitiveFillMode::DRAW_LINE );
return borderDrawable->getColor();
} else {
return stateDrawable->getColor();
}
}
UINode * UINode::setBorderWidth( const Uint32& state, const unsigned int& width ) {
UISkin * border = setBorderEnabled( true );

View File

@@ -37,6 +37,7 @@ void UISkinState::updateState() {
for ( int i = StateFlagCount - 1; i >= 0; i-- ) {
if ( ( mState & getStateFlag(i) ) == getStateFlag(i) ) {
if ( stateExists( getStateFlag(i) ) ) {
mPreviousState = mCurrentState;
mCurrentState = getStateFlag(i);
onStateChange();
return;

View File

@@ -67,7 +67,8 @@ bool UIState::isStateName( const std::string& State ) {
UIState::UIState() :
mState(StateFlagNormal),
mCurrentState(StateFlagNormal)
mCurrentState(StateFlagNormal),
mPreviousState(StateFlagNormal)
{
}
@@ -102,10 +103,14 @@ void UIState::popState(const Uint32 & State) {
}
}
Uint32 UIState::getCurrentState() const {
const Uint32& UIState::getCurrentState() const {
return mCurrentState;
}
const Uint32 &UIState::getPreviousState() const {
return mPreviousState;
}
void UIState::onStateChange() {
}

View File

@@ -240,6 +240,7 @@ void UIStyle::updateState() {
if ( ( mState & getStateFlag(i) ) == getStateFlag(i) ) {
if ( stateExists( getStateFlag(i) ) ) {
if ( mCurrentState != getStateFlag(i) ) {
mPreviousState = mCurrentState;
mCurrentState = getStateFlag(i);
onStateChange();
}

View File

@@ -570,6 +570,14 @@ void UIWidget::endAttributesTransaction() {
}
}
const Uint32& UIWidget::getStyleState() const {
return NULL != mStyle ? mStyle->getCurrentState() : mState;
}
const Uint32& UIWidget::getStylePreviousState() const {
return NULL != mStyle ? mStyle->getPreviousState() : mState;
}
bool UIWidget::setAttribute( const std::string& name, const std::string& value, const Uint32& state ) {
return setAttribute( NodeAttribute( name, value ), state );
}
@@ -604,7 +612,21 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
setBackgroundDrawable( state, res, res->getDrawableType() == Drawable::SPRITE );
}
} else if ( "backgroundcolor" == name ) {
setBackgroundColor( state, attribute.asColor() );
Color color = attribute.asColor();
if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) {
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Color start( getBackgroundColor( getStylePreviousState() ) );
Action * action = Actions::ColorInterpolation::New( start, color, false, transitionInfo.duration, transitionInfo.timingFunction, Actions::ColorInterpolation::Background );
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );
runAction( action );
} else {
setBackgroundColor( state, color );
}
} else if ( "foreground" == name ) {
Drawable * res = NULL;
@@ -616,11 +638,39 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
setForegroundDrawable( state, res, res->getDrawableType() == Drawable::SPRITE );
}
} else if ( "foregroundcolor" == name ) {
setForegroundColor( state, attribute.asColor() );
Color color = attribute.asColor();
if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) {
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Color start( getForegroundColor( getStylePreviousState() ) );
Action * action = Actions::ColorInterpolation::New( start, color, false, transitionInfo.duration, transitionInfo.timingFunction, Actions::ColorInterpolation::Foreground );
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );
runAction( action );
} else {
setForegroundColor( state, color );
}
} else if ( "foregroundcorners" == name ) {
setForegroundCorners( state, attribute.asUint() );
} else if ( "bordercolor" == name ) {
setBorderColor( state, attribute.asColor() );
Color color = attribute.asColor();
if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) {
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Color start( getBorderColor( getStylePreviousState() ) );
Action * action = Actions::ColorInterpolation::New( start, color, false, transitionInfo.duration, transitionInfo.timingFunction, Actions::ColorInterpolation::Border );
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );
runAction( action );
} else {
setBorderColor( state, color );
}
} else if ( "borderwidth" == name ) {
setBorderWidth( state, attribute.asDpDimensionI("1") );
} else if ( "bordercorners" == name || "backgroundcorners" == name ) {