Improvements for CSS Transitions.

Reimplemented UINode border.

--HG--
branch : dev
This commit is contained in:
Martín Lucas Golini
2019-01-07 23:59:19 -03:00
parent d376f6506f
commit fa57c2393e
12 changed files with 119 additions and 110 deletions

View File

@@ -68,14 +68,17 @@ Tooltip {
}
#tpad {
scale: 1;
rotation: 0;
transition: scale 0.25s, rotation 0.25s 0.25s;
/* scale: 1;*/
/* rotation: 0;*/
borderWidth: 2dp;
/* borderColor: #66666666;*/
transition: scale 0.25s, rotation 0.25s 0.25s, borderColor 0.25;
}
#tpad:hover {
scale: 1.1;
rotation: -3;
borderColor: #99999999;
}
#tpad2 {
@@ -94,8 +97,8 @@ Tooltip {
}
#tres {
width: 32dp;
height: 32dp;
/* width: 32dp;
height: 32dp;*/
transition: all 0.25s;
}

View File

@@ -219,6 +219,8 @@ class EE_API Color : public tColor<Uint8>
Colorf toHsl();
std::string toHexString();
static Color fromHsl( const Colorf& hsl );
/** Blend a source color to destination color */

View File

@@ -10,7 +10,9 @@
namespace EE { namespace Graphics {
class Drawable;
class RectangleDrawable;
}}
namespace EE { namespace Scene {
class Action;
class ActionManager;
@@ -125,18 +127,12 @@ class EE_API UINode : public Node {
UINode * setForegroundCorners( const unsigned int& corners );
UISkin * setBorderEnabled( bool enabled );
UINode * setBorderColor( const Uint32 & state, const Color& color );
RectangleDrawable * setBorderEnabled( bool enabled );
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 );
const Uint32& getFlags() const;
@@ -151,7 +147,7 @@ class EE_API UINode : public Node {
UISkin * getForeground();
UISkin * getBorder();
RectangleDrawable * getBorder();
void setThemeByName( const std::string& Theme );
@@ -206,7 +202,7 @@ class EE_API UINode : public Node {
UISkinState * mSkinState;
UISkinState * mBackgroundState;
UISkinState * mForegroundState;
UISkinState * mBorderState;
RectangleDrawable * mBorder;
Vector2f mDragPoint;
Uint32 mDragButton;

View File

@@ -72,6 +72,8 @@ class EE_API UIStyle : public UIState {
NodeAttribute getAttribute( const Uint32& state, const std::string& attributeName ) const;
bool hasAttribute( const Uint32& state, const std::string& attributeName ) const;
NodeAttribute getAttributeFromNames( const Uint32& state, const std::vector<std::string>& attributeNames ) const;
void addStyleSheetProperties( const Uint32& state, const CSS::StyleSheetProperties& properties );

View File

@@ -395,7 +395,7 @@ void MapEditor::createLighContainer() {
mUIBaseColor->setPosition( Txt->getPosition().x, Txt->getPosition().y + Txt->getSize().getHeight() + 4 );
mUIBaseColor->setSize( 58, 64 );
mUIBaseColor->setBackgroundColor( Color(255,255,255,255) );
mUIBaseColor->getBorder()->setColor( Color( 100, 100, 100, 200 ) );
mUIBaseColor->setBorderColor( Color( 100, 100, 100, 200 ) );
Txt = createTextBox( "R:", mLightCont, Sizef(), Vector2f( mUIBaseColor->getPosition().x + mUIBaseColor->getSize().getWidth() + 4, mUIBaseColor->getPosition().y ), UI_CONTROL_DEFAULT_FLAGS | UI_AUTO_SIZE, Text::Shadow );

View File

@@ -47,7 +47,7 @@ TileMapProperties::TileMapProperties( TileMap * Map ) :
mUIBaseColor->setPosition( Txt->getPosition().x, Txt->getPosition().y + Txt->getSize().getHeight() + 4 );
mUIBaseColor->setSize( 64, 64 );
mUIBaseColor->setBackgroundColor( mMap->getBaseColor() );
mUIBaseColor->getBorder()->setColor( Color( 100, 100, 100, 200 ) );
mUIBaseColor->setBorderColor( Color( 100, 100, 100, 200 ) );
Txt = createTextBox( "Red Color:", mUIWindow->getContainer(), Sizef(), Vector2f( mUIBaseColor->getPosition().x + mUIBaseColor->getSize().getWidth() + 4, mUIBaseColor->getPosition().y ), UI_CONTROL_DEFAULT_FLAGS | UI_AUTO_SIZE, Text::Shadow );
mUIRedSlider = UISlider::New()->setOrientation( UI_HORIZONTAL );

View File

@@ -135,7 +135,7 @@ UIMapNew::UIMapNew( UIMap * Map, std::function<void()> NewMapCb, bool ResizeMap
mUIBaseColor = UIWidget::New();
mUIBaseColor->setFlags( UI_FILL_BACKGROUND | UI_BORDER );
mUIBaseColor->getBorder()->setColor( Color( 100, 100, 100, 200 ) );
mUIBaseColor->setBorderColor( Color( 100, 100, 100, 200 ) );
mUIBaseColor->setBackgroundColor( ResizeMap ? mUIMap->Map()->getBaseColor() : Color( 255, 255, 255, 255 ) );
mUIBaseColor->setParent( mUIWindow->getContainer() )->setPosition( Txt->getPosition().x, Txt->getPosition().y + Txt->getSize().getHeight() + 4 )->setSize( 64, 64 );

View File

@@ -160,7 +160,7 @@ void Tint::onUpdate( const Time& ) {
}
case Border:
{
widget->setBorderColor( widget->getStyleState(),
widget->setBorderColor(
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),

View File

@@ -3,6 +3,7 @@
#include <eepp/math/math.hpp>
#include <cstdlib>
#include <ctype.h>
#include <iomanip>
namespace EE { namespace System {
@@ -225,6 +226,12 @@ Colorf Color::toHsl() {
return hsl;
}
std::string Color::toHexString() {
std::stringstream stream;
stream << "#" << std::setfill ('0') << std::setw(sizeof(Color)*2) << std::hex << getValue();
return stream.str();
}
static Float hue2rgb( Float p, Float q, Float t) {
if(t < 0.f) t += 1.f;
if(t > 1.f) t -= 1.f;

View File

@@ -35,7 +35,7 @@ UINode::UINode() :
mSkinState( NULL ),
mBackgroundState( NULL ),
mForegroundState( NULL ),
mBorderState( NULL ),
mBorder( NULL ),
mDragButton( EE_BUTTON_LMASK )
{
mNodeFlags |= NODE_FLAG_UINODE | NODE_FLAG_OVER_FIND_ALLOWED;
@@ -53,12 +53,9 @@ UINode::~UINode() {
if ( NULL != mForegroundState && NULL != mForegroundState->getSkin() )
eeDelete( mForegroundState->getSkin() );
if ( NULL != mBorderState && NULL != mBorderState->getSkin() )
eeDelete( mBorderState->getSkin() );
eeSAFE_DELETE( mBackgroundState );
eeSAFE_DELETE( mForegroundState );
eeSAFE_DELETE( mBorderState );
eeSAFE_DELETE( mBorder );
}
void UINode::worldToNodeTranslation( Vector2f& Pos ) const {
@@ -555,10 +552,10 @@ UINode * UINode::setForegroundCorners( const unsigned int& corners ) {
return setForegroundCorners( UIState::StateFlagNormal, corners );
}
UISkin * UINode::setBorderEnabled( bool enabled ) {
RectangleDrawable * UINode::setBorderEnabled( bool enabled ) {
writeFlag( UI_BORDER, enabled ? 1 : 0 );
if ( enabled && NULL == mBorderState ) {
if ( enabled && NULL == mBorder ) {
getBorder();
if ( NULL == mBackgroundState ) {
@@ -568,73 +565,21 @@ UISkin * UINode::setBorderEnabled( bool enabled ) {
invalidateDraw();
return NULL != mBorderState ? mBorderState->getSkin() : NULL;
}
UINode * UINode::setBorderColor( const Uint32& state, const Color& color ) {
UISkin * border = setBorderEnabled( true );
Drawable * stateDrawable = border->getStateDrawable( state );
if ( NULL == stateDrawable ) {
RectangleDrawable * borderDrawable = RectangleDrawable::New();
borderDrawable->setFillMode( PrimitiveFillMode::DRAW_LINE );
borderDrawable->setColor( color );
border->setStateDrawable( state, borderDrawable, true );
} else {
stateDrawable->setColor( color );
}
return this;
return NULL != mBorder ? mBorder : NULL;
}
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 );
Drawable * stateDrawable = border->getStateDrawable( state );
RectangleDrawable * borderDrawable;
if ( NULL == stateDrawable ) {
borderDrawable = RectangleDrawable::New();
borderDrawable->setFillMode( PrimitiveFillMode::DRAW_LINE );
borderDrawable->setLineWidth( width );
border->setStateDrawable( state, borderDrawable, true );
} else if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) {
borderDrawable = static_cast<RectangleDrawable*>( stateDrawable );
borderDrawable->setLineWidth( width );
}
setBorderEnabled( true )->setColor( color );
return this;
}
Color UINode::getBorderColor() {
return setBorderEnabled( true )->getColor();
}
UINode * UINode::setBorderWidth( const unsigned int& width ) {
return setBorderWidth( UIState::StateFlagNormal, width );
setBorderEnabled( true )->setLineWidth( width );
return this;
}
const Uint32& UINode::getFlags() const {
@@ -648,7 +593,7 @@ UINode * UINode::setFlags( const Uint32& flags ) {
if ( NULL == mForegroundState && ( flags & UI_FILL_FOREGROUND ) )
setForegroundFillEnabled( true );
if ( NULL == mBorderState && ( flags & UI_BORDER ) )
if ( NULL == mBorder && ( flags & UI_BORDER ) )
setBorderEnabled( true );
if ( fontHAlignGet( flags ) || fontVAlignGet( flags ) ) {
@@ -689,20 +634,21 @@ void UINode::drawForeground() {
}
void UINode::drawBorder() {
if ( ( mFlags & UI_BORDER ) && NULL != mBorderState ) {
if ( NULL != mBorderState->getSkin() && NULL != mBackgroundState && NULL != mBackgroundState->getSkin() ) {
Drawable * drawable = mBorderState->getSkin()->getStateDrawable( mBorderState->getCurrentState() );
Drawable * backDrawable = mBackgroundState->getSkin()->getStateDrawable( mBorderState->getCurrentState() );
if ( ( mFlags & UI_BORDER ) && NULL != mBorder ) {
if ( NULL != mBorder && NULL != mBackgroundState && NULL != mBackgroundState->getSkin() ) {
Drawable * backDrawable = mBackgroundState->getSkin()->getStateDrawable( mBackgroundState->getCurrentState() );
if ( NULL != backDrawable && NULL != drawable && backDrawable->getDrawableType() == Drawable::RECTANGLE && drawable->getDrawableType() == Drawable::RECTANGLE ) {
RectangleDrawable * borderDrawable = static_cast<RectangleDrawable*>( drawable );
if ( NULL != backDrawable && backDrawable->getDrawableType() == Drawable::RECTANGLE ) {
RectangleDrawable * backgroundDrawable = static_cast<RectangleDrawable*>( backDrawable );
borderDrawable->setCorners( backgroundDrawable->getCorners() );
getBorder()->setCorners( backgroundDrawable->getCorners() );
}
}
mBorderState->draw( mScreenPosi.x, mScreenPosi.y, eefloor(mSize.getWidth()), eefloor(mSize.getHeight()), (Uint32)mAlpha );
Uint8 alpha = mBorder->getAlpha();
mBorder->setAlpha( eemax<Uint32>( mAlpha * alpha / 255.f, 255 ) );
mBorder->draw( Vector2f( mScreenPosi.x, mScreenPosi.y ), Sizef( eefloor(mSize.getWidth()), eefloor(mSize.getHeight()) ) );
mBorder->setAlpha( alpha );
}
}
@@ -751,12 +697,14 @@ UISkin * UINode::getForeground() {
return mForegroundState->getSkin();
}
UISkin * UINode::getBorder() {
if ( NULL == mBorderState ) {
mBorderState = UISkinState::New( UISkin::New() );
RectangleDrawable * UINode::getBorder() {
if ( NULL == mBorder ) {
mBorder = RectangleDrawable::New();
mBorder->setFillMode( PrimitiveFillMode::DRAW_LINE );
mBorder->setLineWidth( PixelDensity::dpToPx(1) );
}
return mBorderState->getSkin();
return mBorder;
}
void UINode::setThemeByName( const std::string& Theme ) {
@@ -855,9 +803,6 @@ void UINode::pushState(const Uint32& State , bool emitEvent) {
if ( NULL != mForegroundState )
mForegroundState->pushState( State );
if ( NULL != mBorderState )
mBorderState->pushState( State );
if ( emitEvent ) {
onStateChange();
} else {
@@ -877,9 +822,6 @@ void UINode::popState(const Uint32& State , bool emitEvent) {
if ( NULL != mForegroundState )
mForegroundState->popState( State );
if ( NULL != mBorderState )
mBorderState->popState( State );
if ( emitEvent ) {
onStateChange();
} else {

View File

@@ -155,6 +155,15 @@ NodeAttribute UIStyle::getAttribute( const Uint32& state, const std::string& att
return NodeAttribute();
}
bool UIStyle::hasAttribute(const Uint32 & state, const std::string & attributeName) const {
if ( !attributeName.empty() && stateExists( state ) ) {
const AttributesMap& attributesMap = mStates.at( state );
return attributesMap.find( attributeName ) != attributesMap.end();
}
return false;
}
NodeAttribute UIStyle::getAttributeFromNames( const Uint32& state, const std::vector<std::string>& attributeNames ) const {
if ( !attributeNames.empty() && stateExists( state ) ) {
const AttributesMap& attributesMap = mStates.at( state );

View File

@@ -587,8 +587,14 @@ bool UIWidget::setAttribute( const std::string& name, const std::string& value,
return setAttribute( NodeAttribute( name, value ), state );
}
#define SAVE_NORMAL_STATE_ATTR( ATTR_FORMATED ) \
NodeAttribute oldAttribute = mStyle->getAttribute( UIState::StateFlagNormal, attribute.getName() ); \
if ( oldAttribute.isEmpty() && mStyle->getPreviousState() == UIState::StateFlagNormal ) \
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), ATTR_FORMATED ) ); \
bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state ) {
std::string name = attribute.getName();
const std::string& name = attribute.getName();
bool attributeSet = true;
@@ -599,12 +605,16 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
} else if ( "y" == name ) {
setInternalPosition( Vector2f( mDpPos.x, attribute.asDpDimension() ) );
} else if ( "width" == name ) {
setLayoutWidthRules( FIXED );
Float newWidth = attribute.asDpDimensionI();
if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) {
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Float start( getSize().getWidth() );
SAVE_NORMAL_STATE_ATTR( String::strFormated( "%.2f", mDpSize.getWidth() ) );
Action * action = Actions::ResizeWidth::New( start, newWidth, transitionInfo.duration, transitionInfo.timingFunction );
if ( Time::Zero != transitionInfo.delay )
@@ -612,17 +622,20 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
runAction( action );
} else {
setLayoutWidthRules( FIXED );
setInternalWidth( newWidth );
notifyLayoutAttrChange();
}
} else if ( "height" == name ) {
setLayoutHeightRules( FIXED );
Float newHeight = attribute.asDpDimensionI();
if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) {
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Float start( getSize().getHeight() );
SAVE_NORMAL_STATE_ATTR( String::strFormated( "%.2f", mDpSize.getHeight() ) );
Action * action = Actions::ResizeHeight::New( start, newHeight, transitionInfo.duration, transitionInfo.timingFunction );
if ( Time::Zero != transitionInfo.delay )
@@ -630,7 +643,6 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
runAction( action );
} else {
setLayoutHeightRules( FIXED );
setInternalHeight( newHeight );
notifyLayoutAttrChange();
}
@@ -693,7 +705,9 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
if ( !isSceneNodeLoading() && NULL != mStyle && mStyle->hasTransition( state, attribute.getName() ) ) {
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Color start( getBorderColor( getStylePreviousState() ) );
Color start( getBorderColor() );
SAVE_NORMAL_STATE_ATTR( start.toHexString() )
Action * action = Actions::Tint::New( start, color, false, transitionInfo.duration, transitionInfo.timingFunction, Actions::Tint::Border );
@@ -702,10 +716,10 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
runAction( action );
} else {
setBorderColor( state, color );
setBorderColor( color );
}
} else if ( "borderwidth" == name ) {
setBorderWidth( state, attribute.asDpDimensionI("1") );
setBorderWidth( attribute.asDpDimensionI("1") );
} else if ( "bordercorners" == name || "backgroundcorners" == name ) {
setBackgroundCorners( state, attribute.asUint() );
} else if ( "visible" == name ) {
@@ -795,6 +809,20 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Action * action = Actions::MarginMove::New( mLayoutMargin, margin, transitionInfo.duration, transitionInfo.timingFunction );
NodeAttribute oldAttribute = mStyle->getAttribute( UIState::StateFlagNormal, attribute.getName() );
if ( oldAttribute.isEmpty() && mStyle->getPreviousState() == UIState::StateFlagNormal ) {
if ( "layout_margin" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%d %d %d %d", mLayoutMargin.Left, mLayoutMargin.Top, mLayoutMargin.Right, mLayoutMargin.Bottom ) ) );
else if ( "layout_marginleft" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%d", mLayoutMargin.Left ) ) );
else if ( "layout_marginright" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%d", mLayoutMargin.Right ) ) );
else if ( "layout_margintop" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%d", mLayoutMargin.Top ) ) );
else if ( "layout_marginbottom" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%d", mLayoutMargin.Bottom ) ) );
}
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );
@@ -897,6 +925,8 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
Float newRotation( mStyle->getAttribute( state, attribute.getName() ).asFloat() );
Action * action = Actions::Rotate::New( mRotation, newRotation, transitionInfo.duration, transitionInfo.timingFunction );
SAVE_NORMAL_STATE_ATTR( String::strFormated( "%2.f", mRotation ) )
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );
@@ -910,6 +940,8 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
Vector2f newScale( mStyle->getAttribute( state, attribute.getName() ).asVector2f() );
Action * action = Actions::Scale::New( mScale, newScale, transitionInfo.duration, transitionInfo.timingFunction );
SAVE_NORMAL_STATE_ATTR( String::strFormated( "%2.f, %2.f", mScale.x, mScale.y ) )
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );
@@ -941,6 +973,20 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Action * action = Actions::PaddingTransition::New( mPadding, padding, transitionInfo.duration, transitionInfo.timingFunction );
NodeAttribute oldAttribute = mStyle->getAttribute( UIState::StateFlagNormal, attribute.getName() );
if ( oldAttribute.isEmpty() && mStyle->getPreviousState() == UIState::StateFlagNormal ) {
if ( "padding" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%2.f %2.f %2.f %2.f", mPadding.Left, mPadding.Top, mPadding.Right, mPadding.Bottom ) ) );
else if ( "paddingleft" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%2.f", mPadding.Left ) ) );
else if ( "paddingright" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%2.f", mPadding.Right ) ) );
else if ( "paddingtop" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%2.f", mPadding.Top ) ) );
else if ( "paddingbottom" == name )
mStyle->addAttribute( UIState::StateFlagNormal, NodeAttribute( attribute.getName(), String::strFormated( "%2.f", mPadding.Bottom ) ) );
}
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );
@@ -955,6 +1001,8 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
UIStyle::TransitionInfo transitionInfo( mStyle->getTransition( state, attribute.getName() ) );
Action * action = Actions::Fade::New( mAlpha, alpha, transitionInfo.duration, transitionInfo.timingFunction );
SAVE_NORMAL_STATE_ATTR( String::strFormated( "%2.f", mAlpha ) )
if ( Time::Zero != transitionInfo.delay )
action = Actions::Sequence::New( Actions::Delay::New( transitionInfo.delay ), action );