mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-30 18:16:31 +03:00
Several UI related fixes ( wrong updates, bad rendering, a segfault, and more ).
This commit is contained in:
@@ -44,7 +44,9 @@ class EE_API ActionManager {
|
||||
|
||||
protected:
|
||||
std::list<Action*> mActions;
|
||||
std::list<Action*> mActionsRemoveList;
|
||||
Mutex mMutex;
|
||||
bool mUpdating;
|
||||
};
|
||||
|
||||
}} // namespace EE::Scene
|
||||
|
||||
@@ -67,8 +67,6 @@ class EE_API StyleSheetPropertyTransition : public Action {
|
||||
Time mDuration;
|
||||
Time mElapsed;
|
||||
Ease::Interpolation mType;
|
||||
|
||||
Float getContainerLength( UIWidget* node );
|
||||
};
|
||||
|
||||
}}} // namespace EE::UI::CSS
|
||||
|
||||
@@ -92,6 +92,8 @@ class EE_API UINode : public Node {
|
||||
|
||||
UINode* setBackgroundDrawable( Drawable* drawable, bool ownIt = false, int index = 0 );
|
||||
|
||||
UINode* setBackgroundDrawable( const std::string& drawable, int index );
|
||||
|
||||
UINode* setBackgroundColor( const Color& color );
|
||||
|
||||
UINode* setBackgroundPositionX( const std::string& positionX, int index = 0 );
|
||||
@@ -112,6 +114,8 @@ class EE_API UINode : public Node {
|
||||
|
||||
UINode* setForegroundDrawable( Drawable* drawable, bool ownIt = false, int index = 0 );
|
||||
|
||||
UINode* setForegroundDrawable( const std::string& drawable, int index = 0 );
|
||||
|
||||
UINode* setForegroundColor( const Color& color );
|
||||
|
||||
UINode* setForegroundPositionX( const std::string& positionX, int index = 0 );
|
||||
@@ -216,7 +220,7 @@ class EE_API UINode : public Node {
|
||||
Uint32 mState;
|
||||
UISkinState* mSkinState;
|
||||
UINodeDrawable* mBackground;
|
||||
UINodeDrawable* mForegroundState;
|
||||
UINodeDrawable* mForeground;
|
||||
RectangleDrawable* mBorder;
|
||||
Vector2f mDragPoint;
|
||||
Uint32 mDragButton;
|
||||
|
||||
@@ -43,8 +43,12 @@ class EE_API UINodeDrawable : public Drawable {
|
||||
|
||||
Drawable* getDrawable() const;
|
||||
|
||||
const std::string& getDrawableRef() const;
|
||||
|
||||
void setDrawable( Drawable* drawable, const bool& ownIt );
|
||||
|
||||
void setDrawable( const std::string& drawableRef );
|
||||
|
||||
void setOffset( const Vector2f& offset );
|
||||
|
||||
const Vector2f& getOffset() const;
|
||||
@@ -90,12 +94,15 @@ class EE_API UINodeDrawable : public Drawable {
|
||||
bool mNeedsUpdate;
|
||||
bool mOwnsDrawable;
|
||||
Drawable* mDrawable;
|
||||
std::string mDrawableRef;
|
||||
Uint32 mResourceChangeCbId;
|
||||
Repeat mRepeat;
|
||||
|
||||
virtual void onPositionChange();
|
||||
|
||||
void update();
|
||||
|
||||
Drawable* createDrawable( const std::string& value, const Sizef& size, bool& ownIt );
|
||||
};
|
||||
|
||||
static UINodeDrawable* New( UINode* owner );
|
||||
@@ -130,6 +137,8 @@ class EE_API UINodeDrawable : public Drawable {
|
||||
|
||||
void setDrawable( int index, Drawable* drawable, bool ownIt );
|
||||
|
||||
void setDrawable( int index, const std::string& drawable );
|
||||
|
||||
void setDrawablePositionX( int index, const std::string& positionX );
|
||||
|
||||
void setDrawablePositionY( int index, const std::string& positionY );
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef EE_UIUIWIDGET_HPP
|
||||
#define EE_UIUIWIDGET_HPP
|
||||
|
||||
#include <eepp/ui/css/propertydefinition.hpp>
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
#include <eepp/ui/css/stylesheetselector.hpp>
|
||||
#include <eepp/ui/uinode.hpp>
|
||||
@@ -185,12 +186,16 @@ class EE_API UIWidget : public UINode {
|
||||
return reinterpret_cast<T*>( findByTag( tag ) );
|
||||
}
|
||||
|
||||
UIWidget* querySelector( const CSS::StyleSheetSelector& selector );
|
||||
|
||||
UIWidget* querySelector( const std::string& selector );
|
||||
|
||||
template <typename T> T* querySelector( const std::string& selector ) {
|
||||
return reinterpret_cast<T*>( querySelector( selector ) );
|
||||
}
|
||||
|
||||
std::vector<UIWidget*> querySelectorAll( const CSS::StyleSheetSelector& selector );
|
||||
|
||||
std::vector<UIWidget*> querySelectorAll( const std::string& selector );
|
||||
|
||||
std::string getPropertyString( const std::string& property );
|
||||
@@ -199,6 +204,17 @@ class EE_API UIWidget : public UINode {
|
||||
|
||||
bool isSceneNodeLoading() const;
|
||||
|
||||
Float
|
||||
getPropertyRelativeTargetContainerLength( const CSS::PropertyRelativeTarget& relativeTarget,
|
||||
const Float& defaultValue = 0 );
|
||||
|
||||
Float lengthFromValue( const std::string& value,
|
||||
const CSS::PropertyRelativeTarget& relativeTarget,
|
||||
const Float& defaultValue = 0, const Float& defaultContainerValue = 0 );
|
||||
|
||||
Float lengthFromValue( const StyleSheetProperty& property,
|
||||
const Float& defaultValue = 0, const Float& defaultContainerValue = 0 );
|
||||
|
||||
protected:
|
||||
friend class UIManager;
|
||||
friend class UISceneNode;
|
||||
@@ -267,14 +283,6 @@ class EE_API UIWidget : public UINode {
|
||||
|
||||
std::string getFlagsString() const;
|
||||
|
||||
bool
|
||||
drawablePropertySet( const std::string& propertyName, const std::string& value,
|
||||
std::function<void( Drawable* drawable, bool ownIt, int index )> funcSet );
|
||||
|
||||
UIWidget* querySelector( const CSS::StyleSheetSelector& selector );
|
||||
|
||||
std::vector<UIWidget*> querySelectorAll( const CSS::StyleSheetSelector& selector );
|
||||
|
||||
bool checkPropertyDefinition( const StyleSheetProperty& property );
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ ActionManager* ActionManager::New() {
|
||||
return eeNew( ActionManager, () );
|
||||
}
|
||||
|
||||
ActionManager::ActionManager() {}
|
||||
ActionManager::ActionManager() : mUpdating( false ) {}
|
||||
|
||||
ActionManager::~ActionManager() {
|
||||
clear();
|
||||
@@ -84,6 +84,7 @@ void ActionManager::update( const Time& time ) {
|
||||
|
||||
{
|
||||
Lock lock( mMutex );
|
||||
mUpdating = true;
|
||||
|
||||
for ( auto it = mActions.begin(); it != mActions.end(); ++it ) {
|
||||
Action* action = ( *it );
|
||||
@@ -96,8 +97,15 @@ void ActionManager::update( const Time& time ) {
|
||||
removeList.push_back( action );
|
||||
}
|
||||
}
|
||||
|
||||
mUpdating = false;
|
||||
}
|
||||
|
||||
for ( auto it = mActionsRemoveList.begin(); it != mActionsRemoveList.end(); ++it )
|
||||
removeAction( ( *it ) );
|
||||
|
||||
mActionsRemoveList.clear();
|
||||
|
||||
for ( auto it = removeList.begin(); it != removeList.end(); ++it )
|
||||
removeAction( ( *it ) );
|
||||
}
|
||||
@@ -130,9 +138,17 @@ void ActionManager::removeAction( Action* action ) {
|
||||
Lock lock( mMutex );
|
||||
|
||||
if ( NULL != action ) {
|
||||
mActions.remove( action );
|
||||
if ( !mUpdating ) {
|
||||
bool found = std::find( mActions.begin(), mActions.end(), action ) != mActions.end();
|
||||
|
||||
eeSAFE_DELETE( action );
|
||||
if ( found ) {
|
||||
mActions.remove( action );
|
||||
|
||||
eeSAFE_DELETE( action );
|
||||
}
|
||||
} else {
|
||||
mActionsRemoveList.push_back( action );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,8 @@ void StyleSheetPropertyTransition::onUpdate( const Time& ) {
|
||||
break;
|
||||
}
|
||||
case PropertyType::NumberLength: {
|
||||
Float containerLength = getContainerLength( node );
|
||||
Float containerLength = node->getPropertyRelativeTargetContainerLength(
|
||||
mProperty->getRelativeTarget() );
|
||||
Float start = node->convertLength( mStartValue, containerLength );
|
||||
Float end = node->convertLength( mEndValue, containerLength );
|
||||
Time time =
|
||||
@@ -201,42 +202,6 @@ void StyleSheetPropertyTransition::onUpdate( const Time& ) {
|
||||
}
|
||||
}
|
||||
|
||||
Float StyleSheetPropertyTransition::getContainerLength( UIWidget* node ) {
|
||||
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();
|
||||
break;
|
||||
case PropertyRelativeTarget::BackgroundWidth:
|
||||
containerLength = node->getPixelsSize().getWidth() -
|
||||
node->getBackground()->getLayer( 0 )->getDrawableSize().getWidth();
|
||||
break;
|
||||
case PropertyRelativeTarget::BackgroundHeight:
|
||||
containerLength = node->getPixelsSize().getHeight() -
|
||||
node->getBackground()->getLayer( 0 )->getDrawableSize().getHeight();
|
||||
break;
|
||||
case PropertyRelativeTarget::ForegroundWidth:
|
||||
containerLength = node->getPixelsSize().getWidth() -
|
||||
node->getForeground()->getLayer( 0 )->getDrawableSize().getWidth();
|
||||
break;
|
||||
case PropertyRelativeTarget::ForegroundHeight:
|
||||
containerLength = node->getPixelsSize().getHeight() -
|
||||
node->getForeground()->getLayer( 0 )->getDrawableSize().getHeight();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return containerLength;
|
||||
}
|
||||
|
||||
const Time& StyleSheetPropertyTransition::getElapsed() const {
|
||||
return mElapsed;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ UINode::UINode() :
|
||||
mState( UIState::StateFlagNormal ),
|
||||
mSkinState( NULL ),
|
||||
mBackground( NULL ),
|
||||
mForegroundState( NULL ),
|
||||
mForeground( NULL ),
|
||||
mBorder( NULL ),
|
||||
mDragButton( EE_BUTTON_LMASK ),
|
||||
mSkinColor( Color::White ) {
|
||||
@@ -49,7 +49,7 @@ UINode::~UINode() {
|
||||
removeSkin();
|
||||
|
||||
eeSAFE_DELETE( mBackground );
|
||||
eeSAFE_DELETE( mForegroundState );
|
||||
eeSAFE_DELETE( mForeground );
|
||||
eeSAFE_DELETE( mBorder );
|
||||
|
||||
if ( isDragging() )
|
||||
@@ -407,6 +407,11 @@ UINode* UINode::setBackgroundDrawable( Drawable* drawable, bool ownIt, int index
|
||||
return this;
|
||||
}
|
||||
|
||||
UINode* UINode::setBackgroundDrawable( const std::string& drawable, int index ) {
|
||||
setBackgroundFillEnabled( true )->setDrawable( index, drawable );
|
||||
return this;
|
||||
}
|
||||
|
||||
UINode* UINode::setBackgroundColor( const Color& color ) {
|
||||
setBackgroundFillEnabled( true )->setBackgroundColor( color );
|
||||
return this;
|
||||
@@ -449,13 +454,13 @@ Uint32 UINode::getBorderRadius() const {
|
||||
UINodeDrawable* UINode::setForegroundFillEnabled( bool enabled ) {
|
||||
writeFlag( UI_FILL_FOREGROUND, enabled ? 1 : 0 );
|
||||
|
||||
if ( enabled && NULL == mForegroundState ) {
|
||||
if ( enabled && NULL == mForeground ) {
|
||||
getForeground();
|
||||
}
|
||||
|
||||
invalidateDraw();
|
||||
|
||||
return mForegroundState;
|
||||
return mForeground;
|
||||
}
|
||||
|
||||
UINode* UINode::setForegroundDrawable( Drawable* drawable, bool ownIt, int index ) {
|
||||
@@ -463,8 +468,13 @@ UINode* UINode::setForegroundDrawable( Drawable* drawable, bool ownIt, int index
|
||||
return this;
|
||||
}
|
||||
|
||||
UINode* UINode::setForegroundDrawable( const std::string& drawable, int index ) {
|
||||
setForegroundFillEnabled( true )->setDrawable( index, drawable );
|
||||
return this;
|
||||
}
|
||||
|
||||
Color UINode::getForegroundColor() const {
|
||||
return NULL != mForegroundState ? mForegroundState->getBackgroundColor() : Color::Transparent;
|
||||
return NULL != mForeground ? mForeground->getBackgroundColor() : Color::Transparent;
|
||||
}
|
||||
|
||||
UINode* UINode::setForegroundColor( const Color& color ) {
|
||||
@@ -498,7 +508,7 @@ UINode* UINode::setForegroundRadius( const unsigned int& corners ) {
|
||||
}
|
||||
|
||||
Uint32 UINode::getForegroundRadius() const {
|
||||
return NULL != mForegroundState ? mForegroundState->getBorderRadius() : 0;
|
||||
return NULL != mForeground ? mForeground->getBorderRadius() : 0;
|
||||
}
|
||||
|
||||
RectangleDrawable* UINode::setBorderEnabled( bool enabled ) {
|
||||
@@ -543,7 +553,7 @@ UINode* UINode::setFlags( const Uint32& flags ) {
|
||||
if ( NULL == mBackground && ( flags & UI_FILL_BACKGROUND ) )
|
||||
setBackgroundFillEnabled( true );
|
||||
|
||||
if ( NULL == mForegroundState && ( flags & UI_FILL_FOREGROUND ) )
|
||||
if ( NULL == mForeground && ( flags & UI_FILL_FOREGROUND ) )
|
||||
setForegroundFillEnabled( true );
|
||||
|
||||
if ( NULL == mBorder && ( flags & UI_BORDER ) )
|
||||
@@ -583,8 +593,8 @@ void UINode::drawBackground() {
|
||||
}
|
||||
|
||||
void UINode::drawForeground() {
|
||||
if ( ( mFlags & UI_FILL_FOREGROUND ) && NULL != mForegroundState ) {
|
||||
mForegroundState->draw( Vector2f( mScreenPosi.x, mScreenPosi.y ),
|
||||
if ( ( mFlags & UI_FILL_FOREGROUND ) && NULL != mForeground ) {
|
||||
mForeground->draw( Vector2f( mScreenPosi.x, mScreenPosi.y ),
|
||||
Sizef( eefloor( mSize.getWidth() ), eefloor( mSize.getHeight() ) ),
|
||||
(Uint32)mAlpha );
|
||||
}
|
||||
@@ -648,11 +658,11 @@ UINodeDrawable* UINode::getBackground() {
|
||||
}
|
||||
|
||||
UINodeDrawable* UINode::getForeground() {
|
||||
if ( NULL == mForegroundState ) {
|
||||
mForegroundState = UINodeDrawable::New( this );
|
||||
if ( NULL == mForeground ) {
|
||||
mForeground = UINodeDrawable::New( this );
|
||||
}
|
||||
|
||||
return mForegroundState;
|
||||
return mForeground;
|
||||
}
|
||||
|
||||
RectangleDrawable* UINode::getBorder() {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#include <eepp/core/core.hpp>
|
||||
#include <eepp/graphics/circledrawable.hpp>
|
||||
#include <eepp/graphics/drawableresource.hpp>
|
||||
#include <eepp/graphics/drawablesearcher.hpp>
|
||||
#include <eepp/graphics/rectangledrawable.hpp>
|
||||
#include <eepp/graphics/renderer/renderer.hpp>
|
||||
#include <eepp/graphics/triangledrawable.hpp>
|
||||
#include <eepp/math/easing.hpp>
|
||||
#include <eepp/system/functionstring.hpp>
|
||||
#include <eepp/ui/css/stylesheetlength.hpp>
|
||||
#include <eepp/ui/uinode.hpp>
|
||||
#include <eepp/ui/uinodedrawable.hpp>
|
||||
@@ -71,6 +76,12 @@ void UINodeDrawable::setDrawable( int index, Drawable* drawable, bool ownIt ) {
|
||||
}
|
||||
}
|
||||
|
||||
void UINodeDrawable::setDrawable( int index, const std::string& drawable ) {
|
||||
if ( drawable != getLayer( index )->getDrawableRef() ) {
|
||||
getLayer( index )->setDrawable( drawable );
|
||||
}
|
||||
}
|
||||
|
||||
void UINodeDrawable::setDrawablePositionX( int index, const std::string& positionX ) {
|
||||
getLayer( index )->setPositionX( positionX );
|
||||
}
|
||||
@@ -321,6 +332,10 @@ Drawable* UINodeDrawable::LayerDrawable::getDrawable() const {
|
||||
return mDrawable;
|
||||
}
|
||||
|
||||
const std::string& UINodeDrawable::LayerDrawable::getDrawableRef() const {
|
||||
return mDrawableRef;
|
||||
}
|
||||
|
||||
void UINodeDrawable::LayerDrawable::setDrawable( Drawable* drawable, const bool& ownIt ) {
|
||||
if ( drawable == mDrawable )
|
||||
return;
|
||||
@@ -337,6 +352,7 @@ void UINodeDrawable::LayerDrawable::setDrawable( Drawable* drawable, const bool&
|
||||
}
|
||||
|
||||
mDrawable = drawable;
|
||||
mDrawableRef = "";
|
||||
mOwnsDrawable = ownIt;
|
||||
invalidate();
|
||||
|
||||
@@ -354,6 +370,215 @@ void UINodeDrawable::LayerDrawable::setDrawable( Drawable* drawable, const bool&
|
||||
}
|
||||
}
|
||||
|
||||
void UINodeDrawable::LayerDrawable::setDrawable( const std::string& drawableRef ) {
|
||||
bool ownIt;
|
||||
Drawable* drawable = createDrawable( drawableRef, mSize, ownIt );
|
||||
|
||||
if ( NULL != drawable ) {
|
||||
setDrawable( drawable, ownIt );
|
||||
|
||||
mDrawableRef = drawableRef;
|
||||
}
|
||||
}
|
||||
|
||||
Drawable* UINodeDrawable::LayerDrawable::createDrawable( const std::string& value,
|
||||
const Sizef& size, bool& ownIt ) {
|
||||
FunctionString functionType = FunctionString::parse( value );
|
||||
Drawable* res = NULL;
|
||||
ownIt = false;
|
||||
|
||||
if ( !functionType.isEmpty() ) {
|
||||
if ( functionType.getName() == "linear-gradient" &&
|
||||
functionType.getParameters().size() >= 2 ) {
|
||||
RectangleDrawable* drawable = RectangleDrawable::New();
|
||||
RectColors rectColors;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
if ( Color::isColorString( params.at( 0 ) ) && params.size() >= 2 ) {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 0 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
} else if ( params.size() >= 3 ) {
|
||||
std::string direction = params.at( 0 );
|
||||
String::toLowerInPlace( direction );
|
||||
|
||||
if ( direction == "to bottom" ) {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 1 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
} else if ( direction == "to left" ) {
|
||||
rectColors.TopLeft = rectColors.BottomLeft =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
rectColors.TopRight = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
} else if ( direction == "to right" ) {
|
||||
rectColors.TopLeft = rectColors.BottomLeft =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
rectColors.TopRight = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
} else if ( direction == "to top" ) {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 2 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
} else {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 1 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
}
|
||||
} else {
|
||||
mContainer->setBackgroundColor( Color::fromString( params.at( 0 ) ) );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drawable->setRectColors( rectColors );
|
||||
ownIt = true;
|
||||
return drawable;
|
||||
} else if ( functionType.getName() == "circle" &&
|
||||
functionType.getParameters().size() >= 1 ) {
|
||||
CircleDrawable* drawable = CircleDrawable::New();
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
CSS::StyleSheetLength length( params[0] );
|
||||
drawable->setRadius(
|
||||
mContainer->getOwner()->convertLength( length, size.getWidth() / 2.f ) );
|
||||
|
||||
if ( params.size() >= 2 ) {
|
||||
drawable->setColor( Color::fromString( params[1] ) );
|
||||
}
|
||||
|
||||
if ( params.size() >= 3 ) {
|
||||
std::string fillMode( String::toLower( params[2] ) );
|
||||
if ( fillMode == "line" || fillMode == "solid" || fillMode == "fill" ) {
|
||||
drawable->setFillMode( fillMode == "line" ? DRAW_LINE : DRAW_FILL );
|
||||
}
|
||||
}
|
||||
|
||||
drawable->setOffset( drawable->getSize() / 2.f );
|
||||
ownIt = true;
|
||||
return drawable;
|
||||
} else if ( functionType.getName() == "rectangle" &&
|
||||
functionType.getParameters().size() >= 1 ) {
|
||||
RectangleDrawable* drawable = RectangleDrawable::New();
|
||||
RectColors rectColors;
|
||||
std::vector<Color> colors;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
for ( size_t i = 0; i < params.size(); i++ ) {
|
||||
std::string param( String::toLower( params[i] ) );
|
||||
|
||||
if ( param == "solid" || param == "fill" ) {
|
||||
drawable->setFillMode( DRAW_FILL );
|
||||
} else if ( String::startsWith( param, "line" ) ) {
|
||||
drawable->setFillMode( DRAW_LINE );
|
||||
|
||||
std::vector<std::string> parts( String::split( param, ' ' ) );
|
||||
|
||||
if ( parts.size() >= 2 ) {
|
||||
CSS::StyleSheetLength length( parts[1] );
|
||||
drawable->setLineWidth(
|
||||
mContainer->getOwner()->convertLength( length, size.getWidth() ) );
|
||||
}
|
||||
} else if ( param.find( "º" ) != std::string::npos ) {
|
||||
String::replaceAll( param, "º", "" );
|
||||
Float floatVal;
|
||||
if ( String::fromString( floatVal, param ) ) {
|
||||
drawable->setRotation( floatVal );
|
||||
}
|
||||
} else if ( Color::isColorString( param ) ) {
|
||||
colors.push_back( Color::fromString( param ) );
|
||||
} else {
|
||||
int intVal = 0;
|
||||
|
||||
if ( String::fromString( intVal, param ) ) {
|
||||
drawable->setCorners( intVal );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( colors.size() > 0 ) {
|
||||
while ( colors.size() < 4 ) {
|
||||
colors.push_back( colors[colors.size() - 1] );
|
||||
};
|
||||
|
||||
rectColors.TopLeft = colors[0];
|
||||
rectColors.BottomLeft = colors[1];
|
||||
rectColors.BottomRight = colors[2];
|
||||
rectColors.TopRight = colors[3];
|
||||
drawable->setRectColors( rectColors );
|
||||
ownIt = true;
|
||||
return drawable;
|
||||
} else {
|
||||
eeSAFE_DELETE( drawable );
|
||||
}
|
||||
} else if ( functionType.getName() == "triangle" &&
|
||||
functionType.getParameters().size() >= 2 ) {
|
||||
TriangleDrawable* drawable = TriangleDrawable::New();
|
||||
std::vector<Color> colors;
|
||||
std::vector<Vector2f> vertices;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
for ( size_t i = 0; i < params.size(); i++ ) {
|
||||
std::string param( String::toLower( params[i] ) );
|
||||
|
||||
if ( Color::isColorString( param ) ) {
|
||||
colors.push_back( Color::fromString( param ) );
|
||||
} else {
|
||||
std::vector<std::string> vertex( String::split( param, ',' ) );
|
||||
|
||||
if ( vertex.size() == 3 ) {
|
||||
for ( size_t v = 0; v < vertex.size(); v++ ) {
|
||||
vertex[v] = String::trim( vertex[v] );
|
||||
std::vector<std::string> coords( String::split( vertex[v], ' ' ) );
|
||||
|
||||
if ( coords.size() == 2 ) {
|
||||
CSS::StyleSheetLength posX( coords[0] );
|
||||
CSS::StyleSheetLength posY( coords[1] );
|
||||
vertices.push_back( Vector2f(
|
||||
mContainer->getOwner()->convertLength( posX, size.getWidth() ),
|
||||
mContainer->getOwner()->convertLength( posY,
|
||||
size.getHeight() ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( vertices.size() == 3 && !colors.empty() ) {
|
||||
Triangle2f triangle;
|
||||
|
||||
for ( size_t i = 0; i < 3; i++ ) {
|
||||
triangle.V[i] = vertices[i];
|
||||
}
|
||||
|
||||
if ( colors.size() == 3 ) {
|
||||
drawable->setTriangleColors( colors[0], colors[1], colors[2] );
|
||||
} else {
|
||||
drawable->setColor( colors[0] );
|
||||
}
|
||||
|
||||
drawable->setTriangle( triangle );
|
||||
ownIt = true;
|
||||
return drawable;
|
||||
} else {
|
||||
eeSAFE_DELETE( drawable );
|
||||
}
|
||||
} else if ( functionType.getName() == "url" && functionType.getParameters().size() >= 1 ) {
|
||||
if ( NULL != ( res = DrawableSearcher::searchByName(
|
||||
functionType.getParameters().at( 0 ) ) ) ) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
} else if ( NULL != ( res = DrawableSearcher::searchByName( value ) ) ) {
|
||||
return res;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Vector2f& UINodeDrawable::LayerDrawable::getOffset() const {
|
||||
if ( mNeedsUpdate )
|
||||
const_cast<LayerDrawable*>( this )->update();
|
||||
@@ -563,6 +788,10 @@ void UINodeDrawable::LayerDrawable::update() {
|
||||
if ( mDrawable == NULL )
|
||||
return;
|
||||
|
||||
if ( !mDrawableRef.empty() ) {
|
||||
setDrawable( mDrawableRef );
|
||||
}
|
||||
|
||||
mDrawableSize = calcDrawableSize( mSizeEq );
|
||||
mOffset = calcPosition( mPositionX + " " + mPositionY );
|
||||
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
#include <algorithm>
|
||||
#include <eepp/graphics/circledrawable.hpp>
|
||||
#include <eepp/graphics/drawablesearcher.hpp>
|
||||
#include <eepp/graphics/rectangledrawable.hpp>
|
||||
#include <eepp/graphics/triangledrawable.hpp>
|
||||
#include <eepp/scene/actions/actions.hpp>
|
||||
#include <eepp/system/functionstring.hpp>
|
||||
#include <eepp/ui/css/shorthanddefinition.hpp>
|
||||
#include <eepp/ui/css/stylesheetproperty.hpp>
|
||||
#include <eepp/ui/css/stylesheetselector.hpp>
|
||||
@@ -399,6 +394,13 @@ void UIWidget::onVisibilityChange() {
|
||||
|
||||
void UIWidget::onSizeChange() {
|
||||
UINode::onSizeChange();
|
||||
|
||||
if ( mBackground != NULL )
|
||||
mBackground->invalidate();
|
||||
|
||||
if ( mForeground != NULL )
|
||||
mForeground->invalidate();
|
||||
|
||||
notifyLayoutAttrChange();
|
||||
}
|
||||
|
||||
@@ -501,6 +503,58 @@ bool UIWidget::isSceneNodeLoading() const {
|
||||
: false;
|
||||
}
|
||||
|
||||
Float UIWidget::getPropertyRelativeTargetContainerLength(
|
||||
const PropertyRelativeTarget& relativeTarget, const Float& defaultValue ) {
|
||||
Float containerLength = defaultValue;
|
||||
switch ( relativeTarget ) {
|
||||
case PropertyRelativeTarget::ContainingBlockWidth:
|
||||
containerLength = getParent()->getPixelsSize().getWidth();
|
||||
break;
|
||||
case PropertyRelativeTarget::ContainingBlockHeight:
|
||||
containerLength = getParent()->getPixelsSize().getHeight();
|
||||
case PropertyRelativeTarget::LocalBlockWidth:
|
||||
containerLength = getPixelsSize().getWidth();
|
||||
break;
|
||||
case PropertyRelativeTarget::LocalBlockHeight:
|
||||
containerLength = getPixelsSize().getHeight();
|
||||
break;
|
||||
case PropertyRelativeTarget::BackgroundWidth:
|
||||
containerLength = getPixelsSize().getWidth() -
|
||||
getBackground()->getLayer( 0 )->getDrawableSize().getWidth();
|
||||
break;
|
||||
case PropertyRelativeTarget::BackgroundHeight:
|
||||
containerLength = getPixelsSize().getHeight() -
|
||||
getBackground()->getLayer( 0 )->getDrawableSize().getHeight();
|
||||
break;
|
||||
case PropertyRelativeTarget::ForegroundWidth:
|
||||
containerLength = getPixelsSize().getWidth() -
|
||||
getForeground()->getLayer( 0 )->getDrawableSize().getWidth();
|
||||
break;
|
||||
case PropertyRelativeTarget::ForegroundHeight:
|
||||
containerLength = getPixelsSize().getHeight() -
|
||||
getForeground()->getLayer( 0 )->getDrawableSize().getHeight();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return containerLength;
|
||||
}
|
||||
|
||||
Float UIWidget::lengthFromValue( const std::string& value,
|
||||
const PropertyRelativeTarget& relativeTarget,
|
||||
const Float& defaultValue, const Float& defaultContainerValue ) {
|
||||
Float containerLength =
|
||||
getPropertyRelativeTargetContainerLength( relativeTarget, defaultValue );
|
||||
return convertLength( CSS::StyleSheetLength( value, defaultValue ), containerLength );
|
||||
}
|
||||
|
||||
Float UIWidget::lengthFromValue( const StyleSheetProperty& property, const Float& defaultValue,
|
||||
const Float& defaultContainerValue ) {
|
||||
return lengthFromValue( property.getValue(),
|
||||
property.getPropertyDefinition()->getRelativeTarget(), defaultValue,
|
||||
defaultContainerValue );
|
||||
}
|
||||
|
||||
const Rectf& UIWidget::getPadding() const {
|
||||
return mPadding;
|
||||
}
|
||||
@@ -578,19 +632,15 @@ const std::vector<std::string>& UIWidget::getStyleSheetClasses() const {
|
||||
}
|
||||
|
||||
UIWidget* UIWidget::getStyleSheetParentElement() const {
|
||||
return NULL != mParentCtrl && mParentCtrl->isWidget()
|
||||
? mParentCtrl->asType<UIWidget>()
|
||||
: NULL;
|
||||
return NULL != mParentCtrl && mParentCtrl->isWidget() ? mParentCtrl->asType<UIWidget>() : NULL;
|
||||
}
|
||||
|
||||
UIWidget* UIWidget::getStyleSheetPreviousSiblingElement() const {
|
||||
return NULL != mPrev && mPrev->isWidget() ? mPrev->asType<UIWidget>()
|
||||
: NULL;
|
||||
return NULL != mPrev && mPrev->isWidget() ? mPrev->asType<UIWidget>() : NULL;
|
||||
}
|
||||
|
||||
UIWidget* UIWidget::getStyleSheetNextSiblingElement() const {
|
||||
return NULL != mNext && mNext->isWidget() ? mNext->asType<UIWidget>()
|
||||
: NULL;
|
||||
return NULL != mNext && mNext->isWidget() ? mNext->asType<UIWidget>() : NULL;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& UIWidget::getStyleSheetPseudoClasses() const {
|
||||
@@ -1077,10 +1127,7 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
setBackgroundColor( attribute.asColor() );
|
||||
break;
|
||||
case PropertyId::BackgroundImage:
|
||||
drawablePropertySet( "background", attribute.getValue(),
|
||||
[&]( Drawable* drawable, bool ownIt, int index ) {
|
||||
setBackgroundDrawable( drawable, ownIt, index );
|
||||
} );
|
||||
setBackgroundDrawable( attribute.getValue(), 0 );
|
||||
break;
|
||||
case PropertyId::BackgroundRepeat:
|
||||
setBackgroundRepeat( attribute.value(), 0 );
|
||||
@@ -1092,10 +1139,7 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
setForegroundColor( attribute.asColor() );
|
||||
break;
|
||||
case PropertyId::ForegroundImage:
|
||||
drawablePropertySet( "foreground", attribute.getValue(),
|
||||
[&]( Drawable* drawable, bool ownIt, int index ) {
|
||||
setForegroundDrawable( drawable, ownIt, index );
|
||||
} );
|
||||
setForegroundDrawable( attribute.getValue(), 0 );
|
||||
break;
|
||||
case PropertyId::ForegroundRadius:
|
||||
setForegroundRadius( attribute.asUint() );
|
||||
@@ -1107,10 +1151,10 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
setBorderColor( attribute.asColor() );
|
||||
break;
|
||||
case PropertyId::BorderWidth:
|
||||
setBorderWidth( PixelDensity::dpToPxI( attribute.asDpDimensionI( "1" ) ) );
|
||||
setBorderWidth( lengthFromValue( attribute, PixelDensity::dpToPx( 1 ) ) );
|
||||
break;
|
||||
case PropertyId::BorderRadius:
|
||||
setBorderRadius( PixelDensity::dpToPxI( attribute.asDpDimensionUint() ) );
|
||||
setBorderRadius( lengthFromValue( attribute ) );
|
||||
break;
|
||||
case PropertyId::Visible:
|
||||
setVisible( attribute.asBool() );
|
||||
@@ -1257,8 +1301,12 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
} else {
|
||||
unsetFlags( UI_AUTO_SIZE );
|
||||
setLayoutWidthRule( LayoutSizeRule::Fixed );
|
||||
setInternalWidth( PixelDensity::toDpFromStringI( val ) );
|
||||
onSizeChange();
|
||||
Float newVal = eefloor( PixelDensity::toDpFromString( val ) );
|
||||
if ( !( newVal == 0 && getLayoutWeight() != 0 &&
|
||||
getParent()->isType( UI_TYPE_LINEAR_LAYOUT ) ) ) {
|
||||
setInternalWidth( newVal );
|
||||
onSizeChange();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1276,8 +1324,12 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
|
||||
} else {
|
||||
unsetFlags( UI_AUTO_SIZE );
|
||||
setLayoutHeightRule( LayoutSizeRule::Fixed );
|
||||
setInternalHeight( PixelDensity::toDpFromStringI( val ) );
|
||||
onSizeChange();
|
||||
Float newVal = eefloor( PixelDensity::toDpFromString( val ) );
|
||||
if ( !( newVal == 0 && getLayoutWeight() != 0 &&
|
||||
getParent()->isType( UI_TYPE_LINEAR_LAYOUT ) ) ) {
|
||||
setInternalHeight( newVal );
|
||||
onSizeChange();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1454,203 +1506,4 @@ std::string UIWidget::getFlagsString() const {
|
||||
return String::join( flagvec, '|' );
|
||||
}
|
||||
|
||||
bool UIWidget::drawablePropertySet( const std::string& propertyName, const std::string& value,
|
||||
std::function<void( Drawable*, bool, int )> funcSet ) {
|
||||
FunctionString functionType = FunctionString::parse( value );
|
||||
Drawable* res = NULL;
|
||||
int index = 0;
|
||||
bool attributeSet = true;
|
||||
|
||||
if ( !functionType.isEmpty() ) {
|
||||
if ( functionType.getName() == "linear-gradient" &&
|
||||
functionType.getParameters().size() >= 2 ) {
|
||||
RectangleDrawable* drawable = RectangleDrawable::New();
|
||||
RectColors rectColors;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
if ( Color::isColorString( params.at( 0 ) ) && params.size() >= 2 ) {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 0 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
} else if ( params.size() >= 3 ) {
|
||||
std::string direction = params.at( 0 );
|
||||
String::toLowerInPlace( direction );
|
||||
|
||||
if ( direction == "to bottom" ) {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 1 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
} else if ( direction == "to left" ) {
|
||||
rectColors.TopLeft = rectColors.BottomLeft =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
rectColors.TopRight = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
} else if ( direction == "to right" ) {
|
||||
rectColors.TopLeft = rectColors.BottomLeft =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
rectColors.TopRight = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
} else if ( direction == "to top" ) {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 2 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 1 ) );
|
||||
} else {
|
||||
rectColors.TopLeft = rectColors.TopRight = Color::fromString( params.at( 1 ) );
|
||||
rectColors.BottomLeft = rectColors.BottomRight =
|
||||
Color::fromString( params.at( 2 ) );
|
||||
}
|
||||
} else {
|
||||
return applyProperty(
|
||||
StyleSheetProperty( propertyName + "-color", params.at( 0 ) ) );
|
||||
}
|
||||
|
||||
drawable->setRectColors( rectColors );
|
||||
|
||||
funcSet( drawable, true, index );
|
||||
} else if ( functionType.getName() == "circle" &&
|
||||
functionType.getParameters().size() >= 1 ) {
|
||||
CircleDrawable* drawable = CircleDrawable::New();
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
CSS::StyleSheetLength length( params[0] );
|
||||
drawable->setRadius( convertLength( length, getPixelsSize().getWidth() / 2.f ) );
|
||||
|
||||
if ( params.size() >= 2 ) {
|
||||
drawable->setColor( Color::fromString( params[1] ) );
|
||||
}
|
||||
|
||||
if ( params.size() >= 3 ) {
|
||||
std::string fillMode( String::toLower( params[2] ) );
|
||||
if ( fillMode == "line" || fillMode == "solid" || fillMode == "fill" ) {
|
||||
drawable->setFillMode( fillMode == "line" ? DRAW_LINE : DRAW_FILL );
|
||||
}
|
||||
}
|
||||
|
||||
drawable->setOffset( drawable->getSize() / 2.f );
|
||||
|
||||
funcSet( drawable, true, index );
|
||||
} else if ( functionType.getName() == "rectangle" &&
|
||||
functionType.getParameters().size() >= 1 ) {
|
||||
RectangleDrawable* drawable = RectangleDrawable::New();
|
||||
RectColors rectColors;
|
||||
std::vector<Color> colors;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
for ( size_t i = 0; i < params.size(); i++ ) {
|
||||
std::string param( String::toLower( params[i] ) );
|
||||
|
||||
if ( param == "solid" || param == "fill" ) {
|
||||
drawable->setFillMode( DRAW_FILL );
|
||||
} else if ( String::startsWith( param, "line" ) ) {
|
||||
drawable->setFillMode( DRAW_LINE );
|
||||
|
||||
std::vector<std::string> parts( String::split( param, ' ' ) );
|
||||
|
||||
if ( parts.size() >= 2 ) {
|
||||
CSS::StyleSheetLength length( parts[1] );
|
||||
drawable->setLineWidth(
|
||||
convertLength( length, getPixelsSize().getWidth() ) );
|
||||
}
|
||||
} else if ( param.find( "º" ) != std::string::npos ) {
|
||||
String::replaceAll( param, "º", "" );
|
||||
Float floatVal;
|
||||
if ( String::fromString( floatVal, param ) ) {
|
||||
drawable->setRotation( floatVal );
|
||||
}
|
||||
} else if ( Color::isColorString( param ) ) {
|
||||
colors.push_back( Color::fromString( param ) );
|
||||
} else {
|
||||
int intVal = 0;
|
||||
|
||||
if ( String::fromString( intVal, param ) ) {
|
||||
drawable->setCorners( intVal );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( colors.size() > 0 ) {
|
||||
while ( colors.size() < 4 ) {
|
||||
colors.push_back( colors[colors.size() - 1] );
|
||||
};
|
||||
|
||||
rectColors.TopLeft = colors[0];
|
||||
rectColors.BottomLeft = colors[1];
|
||||
rectColors.BottomRight = colors[2];
|
||||
rectColors.TopRight = colors[3];
|
||||
drawable->setRectColors( rectColors );
|
||||
|
||||
funcSet( drawable, true, index );
|
||||
} else {
|
||||
eeSAFE_DELETE( drawable );
|
||||
}
|
||||
} else if ( functionType.getName() == "triangle" &&
|
||||
functionType.getParameters().size() >= 2 ) {
|
||||
TriangleDrawable* drawable = TriangleDrawable::New();
|
||||
std::vector<Color> colors;
|
||||
std::vector<Vector2f> vertices;
|
||||
|
||||
const std::vector<std::string>& params( functionType.getParameters() );
|
||||
|
||||
for ( size_t i = 0; i < params.size(); i++ ) {
|
||||
std::string param( String::toLower( params[i] ) );
|
||||
|
||||
if ( Color::isColorString( param ) ) {
|
||||
colors.push_back( Color::fromString( param ) );
|
||||
} else {
|
||||
std::vector<std::string> vertex( String::split( param, ',' ) );
|
||||
|
||||
if ( vertex.size() == 3 ) {
|
||||
for ( size_t v = 0; v < vertex.size(); v++ ) {
|
||||
vertex[v] = String::trim( vertex[v] );
|
||||
std::vector<std::string> coords( String::split( vertex[v], ' ' ) );
|
||||
|
||||
if ( coords.size() == 2 ) {
|
||||
CSS::StyleSheetLength posX( coords[0] );
|
||||
CSS::StyleSheetLength posY( coords[1] );
|
||||
vertices.push_back( Vector2f(
|
||||
convertLength( posX, getPixelsSize().getWidth() ),
|
||||
convertLength( posY, getPixelsSize().getHeight() ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( vertices.size() == 3 && !colors.empty() ) {
|
||||
Triangle2f triangle;
|
||||
|
||||
for ( size_t i = 0; i < 3; i++ ) {
|
||||
triangle.V[i] = vertices[i];
|
||||
}
|
||||
|
||||
if ( colors.size() == 3 ) {
|
||||
drawable->setTriangleColors( colors[0], colors[1], colors[2] );
|
||||
} else {
|
||||
drawable->setColor( colors[0] );
|
||||
}
|
||||
|
||||
drawable->setTriangle( triangle );
|
||||
|
||||
funcSet( drawable, true, index );
|
||||
} else {
|
||||
eeSAFE_DELETE( drawable );
|
||||
}
|
||||
} else if ( functionType.getName() == "url" && functionType.getParameters().size() >= 1 ) {
|
||||
if ( NULL != ( res = DrawableSearcher::searchByName(
|
||||
functionType.getParameters().at( 0 ) ) ) ) {
|
||||
funcSet( res, res->getDrawableType() == Drawable::SPRITE, index );
|
||||
}
|
||||
}
|
||||
} else if ( NULL != ( res = DrawableSearcher::searchByName( value ) ) ) {
|
||||
funcSet( res, res->getDrawableType() == Drawable::SPRITE, index );
|
||||
} else {
|
||||
attributeSet = false;
|
||||
}
|
||||
|
||||
return attributeSet;
|
||||
}
|
||||
|
||||
}} // namespace EE::UI
|
||||
|
||||
Reference in New Issue
Block a user