UINodeDrawable replacing UISkinState for UINode background and foreground.

WIP new properties support.
Added "text-align" property to UITextView.
Fixed a bug in StyleSheetSelectorRule.

--HG--
branch : dev
This commit is contained in:
Martín Lucas Golini
2019-11-13 17:40:38 -03:00
parent 54a88adff5
commit 45cf7f4f73
15 changed files with 564 additions and 146 deletions

View File

@@ -75,8 +75,7 @@ Tooltip {
margin-top: 0dp;
border-width: 2dp;
border-color: #66666666;
background-color: #33FF3333;
background-image: linear-gradient( #8c8886, #585857 );
background-color: #33FF3310;
border-radius: 12;
font-size: 24dp;
padding: 12dp;
@@ -86,7 +85,7 @@ Tooltip {
#lvbox > #tpad:hover {
scale: 1.1;
rotation: -3;
background-color: #FF333333;
background-color: #FF333310;
border-color: #99999999;
border-radius: 4;
}

View File

@@ -25,6 +25,8 @@ class EE_API Drawable {
NINEPATCH,
STATELIST,
SKIN,
UINODEDRAWABLE,
UINODEDRAWABLE_LAYERDRAWABLE,
CUSTOM
};

View File

@@ -22,6 +22,7 @@ using namespace EE::Scene;
namespace EE { namespace UI {
class UITheme;
class UINodeDrawable;
class EE_API UINode : public Node {
public:
@@ -85,24 +86,32 @@ class EE_API UINode : public Node {
UINode * setGravity( Uint32 hvalign );
UISkin * setBackgroundFillEnabled( bool enabled );
UINodeDrawable * setBackgroundFillEnabled( bool enabled );
UINode * setBackgroundDrawable( Drawable * drawable , bool ownIt = false );
UINode * setBackgroundDrawable( Drawable * drawable, bool ownIt = false, int index = 0 );
UINode * setBackgroundColor( const Color& color );
UINode * setBackgroundPosition( const std::string& positionEq, int index = 0 );
UINode * setBackgroundRepeat( const std::string& repeatRule, int index = 0 );
Color getBackgroundColor() const;
UINode * setBorderRadius( const unsigned int& corners );
Uint32 getBorderRadius() const;
UISkin * setForegroundFillEnabled( bool enabled );
UINodeDrawable * setForegroundFillEnabled( bool enabled );
UINode * setForegroundDrawable( Drawable * drawable , bool ownIt = false );
UINode * setForegroundDrawable( Drawable * drawable , bool ownIt = false, int index = 0 );
UINode * setForegroundColor( const Color& color );
UINode * setForegroundPosition( const std::string& positionEq, int index = 0 );
UINode * setForegroundRepeat( const std::string& repeatRule, int index = 0 ) ;
Color getForegroundColor() const;
UINode * setForegroundRadius( const unsigned int& corners );
@@ -127,9 +136,9 @@ class EE_API UINode : public Node {
virtual UINode * resetFlags( Uint32 newFlags = 0 );
UISkin * getBackground();
UINodeDrawable * getBackground();
UISkin * getForeground();
UINodeDrawable* getForeground();
RectangleDrawable * getBorder();
@@ -188,8 +197,8 @@ class EE_API UINode : public Node {
Uint32 mFlags;
Uint32 mState;
UISkinState * mSkinState;
UISkinState * mBackgroundState;
UISkinState * mForegroundState;
UINodeDrawable * mBackground;
UINodeDrawable * mForegroundState;
RectangleDrawable * mBorder;
Vector2f mDragPoint;
Uint32 mDragButton;

View File

@@ -0,0 +1,130 @@
#ifndef EE_UI_UINODEDRAWABLE_HPP
#define EE_UI_UINODEDRAWABLE_HPP
#include <eepp/graphics/drawable.hpp>
#include <eepp/graphics/rectangledrawable.hpp>
#include <vector>
#include <map>
using namespace EE::Graphics;
namespace EE { namespace UI {
class EE_API UINodeDrawable : public Drawable {
public:
enum Repeat {
RepeatXY,
RepeatX,
RepeatY,
NoRepeat
};
static Repeat repeatFromText( const std::string& text );
class EE_API LayerDrawable : public Drawable {
public:
static LayerDrawable * New( UINodeDrawable * container );
LayerDrawable( UINodeDrawable * container );
virtual ~LayerDrawable();
bool isStateful() { return false; }
virtual void draw();
virtual void draw( const Vector2f& position );
virtual void draw( const Vector2f& position, const Sizef& size );
virtual Sizef getSize();
virtual void setSize( const Sizef& size );
Drawable* getDrawable() const;
void setDrawable( Drawable* drawable, const bool& ownIt );
const Vector2f& getOffset() const;
void setPositionEq( const std::string& offset );
const Repeat& getRepeat() const;
void setRepeat( const Repeat& repeat );
protected:
UINodeDrawable * mContainer;
Sizef mSize;
Vector2f mOffset;
std::string mPositionEq;
bool mNeedsUpdate;
bool mUpdatePosEq;
bool mOwnsDrawable;
Drawable * mDrawable;
Uint32 mResourceChangeCbId;
Repeat mRepeat;
virtual void onPositionChange();
void update();
};
static UINodeDrawable * New();
UINodeDrawable();
virtual ~UINodeDrawable();
virtual Sizef getSize();
virtual void setSize( const Sizef& size );
virtual void draw();
virtual void draw( const Vector2f& position );
virtual void draw( const Vector2f& position, const Sizef& size );
void draw( const Vector2f& position, const Sizef& size, const Uint32& alpha );
virtual bool isStateful() { return false; }
void clearDrawables();
void setBorderRadius( const Uint32& corners );
Uint32 getBorderRadius() const;
LayerDrawable * getLayer( int index );
void setDrawable( int index, Drawable * drawable, bool ownIt );
void setDrawablePosition( int index, const std::string& positionEq );
void setDrawableRepeat( int index, const std::string& repeatRule );
void setBackgroundColor( const Color& color );
Color getBackgroundColor() const;
bool getClipEnabled() const;
void setClipEnabled(bool clipEnabled);
protected:
RectangleDrawable mBackgroundColor;
std::map<int,LayerDrawable*> mGroup;
std::map<int,std::string> mPosEq;
Sizef mSize;
bool mNeedsUpdate;
bool mClipEnabled;
virtual void onPositionChange();
virtual void onSizeChange();
void update();
};
}}
#endif

View File

@@ -239,7 +239,7 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
std::string getFlagsString() const;
bool drawablePropertySet( const std::string& propertyName, const std::string& value, std::function<void(Drawable * drawable, bool ownIt)> funcSet);
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 );

View File

@@ -324,6 +324,7 @@
../../include/eepp/ui/uimenusubmenu.hpp
../../include/eepp/ui/uimessagebox.hpp
../../include/eepp/ui/uinode.hpp
../../include/eepp/ui/uinodedrawable.hpp
../../include/eepp/ui/uipopupmenu.hpp
../../include/eepp/ui/uiprogressbar.hpp
../../include/eepp/ui/uipushbutton.hpp
@@ -742,6 +743,7 @@
../../src/eepp/ui/uimenusubmenu.cpp
../../src/eepp/ui/uimessagebox.cpp
../../src/eepp/ui/uinode.cpp
../../src/eepp/ui/uinodedrawable.cpp
../../src/eepp/ui/uipopupmenu.cpp
../../src/eepp/ui/uiprogressbar.cpp
../../src/eepp/ui/uipushbutton.cpp

View File

@@ -595,12 +595,12 @@ void MapEditor::onNewLight( const Event * Event ) {
if ( MEvent->getFlags() & EE_BUTTON_LMASK ) {
Vector2f Pos = mUIMap->Map()->getMouseMapPosf();
mUIMap->addLight( eeNew( MapLight, ( mLightRadius->getValue(), Pos.x, Pos.y, mUIBaseColor->getBackground()->getColor().toRGB(), mLightTypeChk->isActive() ? LIGHT_ISOMETRIC : LIGHT_NORMAL ) ) );
mUIMap->addLight( eeNew( MapLight, ( mLightRadius->getValue(), Pos.x, Pos.y, mUIBaseColor->getBackgroundColor().toRGB(), mLightTypeChk->isActive() ? LIGHT_ISOMETRIC : LIGHT_NORMAL ) ) );
}
}
void MapEditor::onRedChange( const Event * Event ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.r = (Uint8)mUIRedSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIRedTxt->setText( String::toStr( (Int32)mUIRedSlider->getValue() ) );
@@ -613,7 +613,7 @@ void MapEditor::onRedChange( const Event * Event ) {
}
void MapEditor::onGreenChange( const Event * Event ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.g = (Uint8)mUIGreenSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIGreenTxt->setText( String::toStr( (Uint32)mUIGreenSlider->getValue() ) );
@@ -626,7 +626,7 @@ void MapEditor::onGreenChange( const Event * Event ) {
}
void MapEditor::onBlueChange( const Event * Event ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.b = (Uint8)mUIBlueSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIBlueTxt->setText( String::toStr( (Uint32)mUIBlueSlider->getValue() ) );

View File

@@ -140,7 +140,7 @@ TileMapProperties::~TileMapProperties() {
}
void TileMapProperties::onRedChange( const Event * ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.r = (Uint8)mUIRedSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIRedTxt->setText( String::toStr( (Int32)mUIRedSlider->getValue() ) );
@@ -151,7 +151,7 @@ void TileMapProperties::onRedChange( const Event * ) {
}
void TileMapProperties::onGreenChange( const Event * ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.g = (Uint8)mUIGreenSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIGreenTxt->setText( String::toStr( (Uint32)mUIGreenSlider->getValue() ) );
@@ -162,7 +162,7 @@ void TileMapProperties::onGreenChange( const Event * ) {
}
void TileMapProperties::onBlueChange( const Event * ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.b = (Uint8)mUIBlueSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIBlueTxt->setText( String::toStr( (Uint32)mUIBlueSlider->getValue() ) );

View File

@@ -202,21 +202,21 @@ UIMapNew::~UIMapNew() {
}
void UIMapNew::onRedChange( const Event * ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.r = (Uint8)mUIRedSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIRedTxt->setText( String::toStr( (Int32)mUIRedSlider->getValue() ) );
}
void UIMapNew::onGreenChange( const Event * ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.g = (Uint8)mUIGreenSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIGreenTxt->setText( String::toStr( (Uint32)mUIGreenSlider->getValue() ) );
}
void UIMapNew::onBlueChange( const Event * ) {
Color Col = mUIBaseColor->getBackground()->getColor();
Color Col = mUIBaseColor->getBackgroundColor();
Col.b = (Uint8)mUIBlueSlider->getValue();
mUIBaseColor->setBackgroundColor( Col );
mUIBlueTxt->setText( String::toStr( (Uint32)mUIBlueSlider->getValue() ) );
@@ -246,7 +246,7 @@ void UIMapNew::onOKClick( const Event * ) {
if ( w > 0 && h > 0 && tw > 0 && th > 0 && ml > 0 ) {
if ( !mResizeMap ) {
mUIMap->Map()->create( Sizei( w, h ), ml, Sizei( tw, th ), Flags, mUIMap->Map()->getViewSize() );
mUIMap->Map()->setBaseColor( mUIBaseColor->getBackground()->getColor() );
mUIMap->Map()->setBaseColor( mUIBaseColor->getBackgroundColor() );
} else {
std::string oldPath( mUIMap->Map()->getPath() );
std::string mapPath( Sys::getTempPath() + "temp.eepp.map.eem" );

View File

@@ -248,8 +248,10 @@ bool StyleSheetSelectorRule::matches( StyleSheetElement * element, const bool& a
if ( !mClasses.empty() && !element->getStyleSheetClasses().empty() ) {
bool hasClasses = true;
for ( const auto& cls : element->getStyleSheetClasses() ) {
if ( !hasClass( cls ) ) {
const std::vector<std::string>& elClasses = element->getStyleSheetClasses();
for ( const auto& cls : mClasses ) {
if ( std::find(elClasses.begin(), elClasses.end(), cls) == elClasses.end() ) {
hasClasses = false;
break;
}

View File

@@ -21,6 +21,7 @@
#include <eepp/ui/uiscenenode.hpp>
#include <eepp/ui/uiskin.hpp>
#include <eepp/ui/uiskinstate.hpp>
#include <eepp/ui/uinodedrawable.hpp>
namespace EE { namespace UI {
@@ -33,7 +34,7 @@ UINode::UINode() :
mFlags( UI_CONTROL_DEFAULT_FLAGS ),
mState(UIState::StateFlagNormal),
mSkinState( NULL ),
mBackgroundState( NULL ),
mBackground( NULL ),
mForegroundState( NULL ),
mBorder( NULL ),
mDragButton( EE_BUTTON_LMASK ),
@@ -48,13 +49,7 @@ UINode::UINode() :
UINode::~UINode() {
removeSkin();
if ( NULL != mBackgroundState && NULL != mBackgroundState->getSkin() )
eeDelete( mBackgroundState->getSkin() );
if ( NULL != mForegroundState && NULL != mForegroundState->getSkin() )
eeDelete( mForegroundState->getSkin() );
eeSAFE_DELETE( mBackgroundState );
eeSAFE_DELETE( mBackground );
eeSAFE_DELETE( mForegroundState );
eeSAFE_DELETE( mBorder );
@@ -384,72 +379,53 @@ UINode * UINode::setGravity( Uint32 hvalign ) {
return this;
}
UISkin * UINode::setBackgroundFillEnabled( bool enabled ) {
UINodeDrawable * UINode::setBackgroundFillEnabled( bool enabled ) {
writeFlag( UI_FILL_BACKGROUND, enabled ? 1 : 0 );
if ( enabled && NULL == mBackgroundState ) {
if ( enabled && NULL == mBackground ) {
getBackground();
}
invalidateDraw();
return NULL != mBackgroundState ? mBackgroundState->getSkin() : NULL;
return mBackground;
}
UINode * UINode::setBackgroundDrawable( Drawable * drawable, bool ownIt ) {
setBackgroundFillEnabled( true )->setStateDrawable( UIState::StateFlagNormal, drawable, ownIt );
UINode * UINode::setBackgroundDrawable( Drawable * drawable, bool ownIt, int index ) {
setBackgroundFillEnabled( true )->setDrawable( index, drawable, ownIt );
return this;
}
UINode * UINode::setBackgroundColor( const Color& color ) {
UISkin * background = setBackgroundFillEnabled( true );
setBackgroundFillEnabled( true )->setBackgroundColor( color );
return this;
}
Drawable * stateDrawable = background->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable )
setBackgroundDrawable( RectangleDrawable::New(), true );
if ( NULL != mBackgroundState )
mBackgroundState->setStateColor( UIState::StateFlagNormal, color );
UINode* UINode::setBackgroundPosition( const std::string& positionEq, int index ) {
setBackgroundFillEnabled( true )->setDrawablePosition( index, positionEq );
return this;
}
UINode* UINode::setBackgroundRepeat( const std::string& repeatRule, int index ) {
setBackgroundFillEnabled( true )->setDrawableRepeat( index, repeatRule );
return this;
}
Color UINode::getBackgroundColor() const {
if ( NULL != mBackgroundState )
return mBackgroundState->getStateColor( UIState::StateFlagNormal );
return Color::Transparent;
return NULL != mBackground ? mBackground->getBackgroundColor() : Color::Transparent;
}
UINode * UINode::setBorderRadius( const unsigned int& corners ) {
setBorderEnabled( true )->setCorners( corners );
UISkin * background = setBackgroundFillEnabled( true );
Drawable * stateDrawable = background->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable ) {
setBackgroundColor( Color::Transparent );
stateDrawable = background->getStateDrawable( UIState::StateFlagNormal );
}
if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) {
static_cast<RectangleDrawable*>( stateDrawable )->setCorners( corners );
}
setBackgroundFillEnabled( true )->setBorderRadius( corners );
return this;
}
Uint32 UINode::getBorderRadius() const {
if ( NULL != mBorder )
return mBorder->getCorners();
return 0;
return NULL != mBorder ? mBorder->getCorners() : 0;
}
UISkin * UINode::setForegroundFillEnabled( bool enabled ) {
UINodeDrawable * UINode::setForegroundFillEnabled( bool enabled ) {
writeFlag( UI_FILL_FOREGROUND, enabled ? 1 : 0 );
if ( enabled && NULL == mForegroundState ) {
@@ -458,67 +434,40 @@ UISkin * UINode::setForegroundFillEnabled( bool enabled ) {
invalidateDraw();
return NULL != mForegroundState ? mForegroundState->getSkin() : NULL;
return mForegroundState;
}
UINode * UINode::setForegroundDrawable( Drawable * drawable, bool ownIt ) {
setForegroundFillEnabled( true )->setStateDrawable( UIState::StateFlagNormal, drawable, ownIt );
UINode * UINode::setForegroundDrawable( Drawable * drawable, bool ownIt, int index ) {
setForegroundFillEnabled( true )->setDrawable( index, drawable, ownIt );
return this;
}
Color UINode::getForegroundColor() const {
if ( NULL != mForegroundState )
return mForegroundState->getStateColor( UIState::StateFlagNormal );
return Color::Transparent;
return NULL != mForegroundState ? mForegroundState->getBackgroundColor() : Color::Transparent;
}
UINode * UINode::setForegroundColor( const Color& color ) {
UISkin * foreground = setForegroundFillEnabled( true );
setForegroundFillEnabled( true )->setBackgroundColor(color );
return this;
}
Drawable * stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable )
setForegroundDrawable( RectangleDrawable::New(), true );
if ( NULL != mForegroundState )
mForegroundState->setStateColor( UIState::StateFlagNormal, color );
UINode* UINode::setForegroundPosition( const std::string& positionEq, int index ) {
setForegroundFillEnabled( true )->setDrawablePosition( index, positionEq );
return this;
}
UINode* UINode::setForegroundRepeat( const std::string& repeatRule, int index ) {
setBackgroundFillEnabled( true )->setDrawableRepeat( index, repeatRule );
return this;
}
UINode * UINode::setForegroundRadius( const unsigned int& corners ) {
UISkin * foreground = setForegroundFillEnabled( true );
Drawable * stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable ) {
setForegroundColor( Color::Black );
stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal );
}
if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) {
RectangleDrawable * rectangleDrawable = static_cast<RectangleDrawable*>( stateDrawable );
rectangleDrawable->setCorners( corners );
}
setForegroundFillEnabled( true )->setBorderRadius( corners );
return this;
}
Uint32 UINode::getForegroundRadius() const {
if ( NULL != mForegroundState && NULL != mForegroundState->getSkin() ) {
Drawable * stateDrawable = mForegroundState->getSkin()->getStateDrawable( UIState::StateFlagNormal );
if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) {
RectangleDrawable * rectangleDrawable = static_cast<RectangleDrawable*>( stateDrawable );
return rectangleDrawable->getCorners();
}
}
return 0;
return NULL != mForegroundState ? mForegroundState->getBorderRadius() : 0;
}
RectangleDrawable * UINode::setBorderEnabled( bool enabled ) {
@@ -527,7 +476,7 @@ RectangleDrawable * UINode::setBorderEnabled( bool enabled ) {
if ( enabled && NULL == mBorder ) {
getBorder();
if ( NULL == mBackgroundState ) {
if ( NULL == mBackground ) {
getBackground();
}
}
@@ -560,7 +509,7 @@ const Uint32& UINode::getFlags() const {
}
UINode * UINode::setFlags( const Uint32& flags ) {
if ( NULL == mBackgroundState && ( flags & UI_FILL_BACKGROUND ) )
if ( NULL == mBackground && ( flags & UI_FILL_BACKGROUND ) )
setBackgroundFillEnabled( true );
if ( NULL == mForegroundState && ( flags & UI_FILL_FOREGROUND ) )
@@ -595,14 +544,14 @@ UINode * UINode::resetFlags( Uint32 newFlags ) {
}
void UINode::drawBackground() {
if ( ( mFlags & UI_FILL_BACKGROUND ) && NULL != mBackgroundState ) {
mBackgroundState->draw( mScreenPosi.x, mScreenPosi.y, eefloor(mSize.getWidth()), eefloor(mSize.getHeight()), (Uint32)mAlpha );
if ( ( mFlags & UI_FILL_BACKGROUND ) && NULL != mBackground ) {
mBackground->draw( Vector2f( mScreenPosi.x, mScreenPosi.y ), Sizef( eefloor(mSize.getWidth()), eefloor(mSize.getHeight()) ), mAlpha );
}
}
void UINode::drawForeground() {
if ( ( mFlags & UI_FILL_FOREGROUND ) && NULL != mForegroundState ) {
mForegroundState->draw( mScreenPosi.x, mScreenPosi.y, eefloor(mSize.getWidth()), eefloor(mSize.getHeight()), (Uint32)mAlpha );
mForegroundState->draw( Vector2f( mScreenPosi.x, mScreenPosi.y ), Sizef( eefloor(mSize.getWidth()), eefloor(mSize.getHeight()) ), (Uint32)mAlpha );
}
}
@@ -651,20 +600,20 @@ void UINode::internalDraw() {
}
}
UISkin * UINode::getBackground() {
if ( NULL == mBackgroundState ) {
mBackgroundState = UISkinState::New( UISkin::New() );
UINodeDrawable * UINode::getBackground() {
if ( NULL == mBackground ) {
mBackground = UINodeDrawable::New();
}
return mBackgroundState->getSkin();
return mBackground;
}
UISkin * UINode::getForeground() {
UINodeDrawable * UINode::getForeground() {
if ( NULL == mForegroundState ) {
mForegroundState = UISkinState::New( UISkin::New() );
mForegroundState = UINodeDrawable::New();
}
return mForegroundState->getSkin();
return mForegroundState;
}
RectangleDrawable * UINode::getBorder() {
@@ -781,12 +730,6 @@ void UINode::pushState(const Uint32& State , bool emitEvent) {
if ( NULL != mSkinState )
mSkinState->pushState( State );
if ( NULL != mBackgroundState )
mBackgroundState->pushState( State );
if ( NULL != mForegroundState )
mForegroundState->pushState( State );
if ( emitEvent ) {
onStateChange();
} else {
@@ -802,12 +745,6 @@ void UINode::popState(const Uint32& State , bool emitEvent) {
if ( NULL != mSkinState )
mSkinState->popState( State );
if ( NULL != mBackgroundState )
mBackgroundState->popState( State );
if ( NULL != mForegroundState )
mForegroundState->popState( State );
if ( emitEvent ) {
onStateChange();
} else {

View File

@@ -0,0 +1,304 @@
#include <eepp/ui/uinodedrawable.hpp>
#include <eepp/core/core.hpp>
#include <eepp/graphics/renderer/renderer.hpp>
#include <eepp/graphics/drawableresource.hpp>
namespace EE { namespace UI {
UINodeDrawable::Repeat UINodeDrawable::repeatFromText( const std::string& text ) {
if ( "repeat" == text ) return UINodeDrawable::Repeat::RepeatXY;
if ( "repeat-x" == text ) return UINodeDrawable::Repeat::RepeatX;
if ( "repeat-y" == text ) return UINodeDrawable::Repeat::RepeatY;
return UINodeDrawable::Repeat::NoRepeat;
}
UINodeDrawable * UINodeDrawable::New() {
return eeNew( UINodeDrawable, () );
}
UINodeDrawable::UINodeDrawable() :
Drawable( Drawable::UINODEDRAWABLE ),
mNeedsUpdate(true),
mClipEnabled(false)
{
mBackgroundColor.setColor(Color::Transparent);
}
UINodeDrawable::~UINodeDrawable() {
clearDrawables();
}
void UINodeDrawable::clearDrawables() {
for ( auto& drawable : mGroup ) {
eeDelete( drawable.second );
}
mGroup.clear();
mBackgroundColor.setColor(Color::Transparent);
}
void UINodeDrawable::setBorderRadius( const Uint32& corners ) {
mBackgroundColor.setCorners( corners );
}
Uint32 UINodeDrawable::getBorderRadius() const {
return mBackgroundColor.getCorners();
}
UINodeDrawable::LayerDrawable* UINodeDrawable::getLayer( int index ) {
auto it = mGroup.find(index);
if ( it == mGroup.end() )
mGroup[ index ] = UINodeDrawable::LayerDrawable::New( this );
return mGroup[ index ];
}
void UINodeDrawable::setDrawable( int index, Drawable* drawable, bool ownIt ) {
if ( drawable != getLayer( index )->getDrawable() ) {
getLayer( index )->setDrawable( drawable, ownIt );
mNeedsUpdate = true;
}
}
void UINodeDrawable::setDrawablePosition( int index, const std::string& positionEq ) {
if ( mPosEq[index] != positionEq ) {
mPosEq[index] = positionEq;
mNeedsUpdate = true;
}
}
void UINodeDrawable::setDrawableRepeat( int index, const std::string& repeatRule ) {
getLayer( index )->setRepeat( repeatFromText( repeatRule ) );
}
void UINodeDrawable::setBackgroundColor(const Color& color) {
mBackgroundColor.setColor( color );
}
Color UINodeDrawable::getBackgroundColor() const {
return mBackgroundColor.getColor();
}
bool UINodeDrawable::getClipEnabled() const {
return mClipEnabled;
}
void UINodeDrawable::setClipEnabled(bool clipEnabled) {
mClipEnabled = clipEnabled;
}
Sizef UINodeDrawable::getSize() {
return mSize;
}
void UINodeDrawable::setSize( const Sizef& size ) {
if ( size != mSize ) {
mSize = size;
onSizeChange();
}
}
void UINodeDrawable::draw( const Vector2f& position, const Sizef& size ) {
draw( position, size, 255 );
}
void UINodeDrawable::draw( const Vector2f& position, const Sizef& size, const Uint32& alpha ) {
if ( position != mPosition ) {
mPosition = position;
mNeedsUpdate = true;
}
if ( size != mSize ) {
mSize = size;
mNeedsUpdate = true;
}
if ( mNeedsUpdate )
update();
if ( mClipEnabled )
GLi->getClippingMask()->clipPlaneEnable( mPosition.x, mPosition.y, mSize.x, mSize.y );
if ( mBackgroundColor.getColor().a != 0 ) {
if ( alpha != 255 ) {
Color color = mBackgroundColor.getColor();
mBackgroundColor.setAlpha( alpha * color.a / 255 );
mBackgroundColor.draw( position, size );
mBackgroundColor.setAlpha( color.a );
} else {
mBackgroundColor.draw( position, size );
}
}
for ( auto& drawableIt : mGroup ) {
UINodeDrawable::LayerDrawable * drawable = drawableIt.second;
if ( alpha != 255 ) {
Color color = drawable->getColor();
drawable->setAlpha( alpha * color.a / 255 );
drawable->draw( position, size );
drawable->setAlpha( color.a );
} else {
drawable->draw( position, size );
}
}
if ( mClipEnabled )
GLi->getClippingMask()->clipPlaneDisable();
}
void UINodeDrawable::draw(const Vector2f & position) {
draw( position, mSize );
}
void UINodeDrawable::draw() {
draw( mPosition, mSize );
}
void UINodeDrawable::onPositionChange() {
mNeedsUpdate = true;
}
void UINodeDrawable::onSizeChange() {
mNeedsUpdate = true;
}
void UINodeDrawable::update() {
mBackgroundColor.setPosition( mPosition );
mBackgroundColor.setSize( mSize );
for ( size_t i = 0; i < mGroup.size(); i++ ) {
UINodeDrawable::LayerDrawable * drawable = mGroup[i];
drawable->setPosition( mPosition );
drawable->setPositionEq( mPosEq[i] );
drawable->setSize( mSize );
}
mNeedsUpdate = false;
}
UINodeDrawable::LayerDrawable * UINodeDrawable::LayerDrawable::New( UINodeDrawable * container ) {
return eeNew( UINodeDrawable::LayerDrawable, ( container ) );
}
UINodeDrawable::LayerDrawable::LayerDrawable( UINodeDrawable * container ) :
Drawable(UINODEDRAWABLE_LAYERDRAWABLE),
mContainer(container),
mNeedsUpdate(false),
mUpdatePosEq(false),
mOwnsDrawable(false),
mDrawable(NULL),
mResourceChangeCbId(0)
{}
UINodeDrawable::LayerDrawable::~LayerDrawable() {
if ( mOwnsDrawable )
eeSAFE_DELETE( mDrawable );
}
void UINodeDrawable::LayerDrawable::draw() {
draw( mPosition, mSize );
}
void UINodeDrawable::LayerDrawable::draw( const Vector2f& position ) {
draw( position, mSize );
}
void UINodeDrawable::LayerDrawable::draw( const Vector2f& position, const Sizef& size ) {
if ( position != mPosition ) {
mPosition = position;
mNeedsUpdate = true;
}
if ( size != mSize ) {
mSize = size;
mNeedsUpdate = true;
}
if ( mDrawable == NULL )
return;
if ( mNeedsUpdate )
update();
mDrawable->draw( mPosition + mOffset, mSize );
}
Sizef UINodeDrawable::LayerDrawable::getSize() {
return mSize;
}
void UINodeDrawable::LayerDrawable::setSize(const Sizef& size) {
if ( size != mSize ) {
mSize = size;
mNeedsUpdate = true;
mUpdatePosEq = true;
}
}
Drawable* UINodeDrawable::LayerDrawable::getDrawable() const {
return mDrawable;
}
void UINodeDrawable::LayerDrawable::setDrawable( Drawable* drawable, const bool& ownIt ) {
if ( drawable == mDrawable )
return;
if ( NULL != mDrawable ) {
if ( mDrawable->isDrawableResource() ) {
reinterpret_cast<DrawableResource*>( mDrawable )->popResourceChangeCallback( mResourceChangeCbId );
}
if ( mOwnsDrawable ) {
eeSAFE_DELETE( mDrawable );
}
}
mDrawable = drawable;
mOwnsDrawable = ownIt;
if ( mDrawable->isDrawableResource() ) {
mResourceChangeCbId = reinterpret_cast<DrawableResource*>( mDrawable )->pushResourceChangeCallback( [&] ( DrawableResource::Event, DrawableResource* ) {
mNeedsUpdate = true;
} );
}
}
const Vector2f& UINodeDrawable::LayerDrawable::getOffset() const {
return mOffset;
}
void UINodeDrawable::LayerDrawable::setPositionEq( const std::string& positionEq ) {
if ( mPositionEq != positionEq ) {
mPositionEq = positionEq;
mUpdatePosEq = true;
mNeedsUpdate = true;
}
}
const UINodeDrawable::Repeat& UINodeDrawable::LayerDrawable::getRepeat() const {
return mRepeat;
}
void UINodeDrawable::LayerDrawable::setRepeat( const UINodeDrawable::Repeat& repeat ) {
mRepeat = repeat;
mNeedsUpdate = true;
mUpdatePosEq = true;
}
void UINodeDrawable::LayerDrawable::onPositionChange() {
mNeedsUpdate = true;
mUpdatePosEq = true;
}
void UINodeDrawable::LayerDrawable::update() {
// TODO: Implement background-position and background-repeat
if ( mUpdatePosEq ) {
mUpdatePosEq = false;
}
}
}}

View File

@@ -659,6 +659,12 @@ bool UITextView::setAttribute( const NodeAttribute& attribute, const Uint32& sta
}
} else if ( "text-selection" == name || "textselection" == name ) {
mFlags|= UI_TEXT_SELECTION_ENABLED;
} else if ( "text-align" == name || "textalign" == name ) {
std::string align = String::toLower( attribute.value() );
if ( align == "center" ) setFlags( UI_HALIGN_CENTER );
else if ( align == "left" ) setFlags( UI_HALIGN_LEFT );
else if ( align == "right" ) setFlags( UI_HALIGN_RIGHT );
} else {
return UIWidget::setAttribute( attribute, state );
}

View File

@@ -920,9 +920,13 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
setBackgroundColor( color );
}
} else if ( "background-image" == name || "backgroundimage" == name ) {
drawablePropertySet( "background", attribute.getValue(), [&] ( Drawable * drawable, bool ownIt ) {
setBackgroundDrawable( drawable, ownIt );
drawablePropertySet( "background", attribute.getValue(), [&] ( Drawable * drawable, bool ownIt, int index ) {
setBackgroundDrawable( drawable, ownIt, index );
} );
} else if ( "background-position" == name || "backgroundposition" == name ) {
setBackgroundPosition( attribute.value(), 0 );
} else if ( "background-repeat" == name || "backgroundrepeat" == name ) {
setBackgroundRepeat( attribute.value(), 0 );
} else if ( "foreground" == name ) {
if ( Color::isColorString( attribute.getValue() ) ) {
setAttribute( NodeAttribute( "foreground-color", attribute.getValue() ) );
@@ -948,8 +952,8 @@ bool UIWidget::setAttribute( const NodeAttribute& attribute, const Uint32& state
setForegroundColor( color );
}
} else if ( "foreground-image" == name || "foregroundimage" == name ) {
drawablePropertySet( "foreground", attribute.getValue(), [&] ( Drawable * drawable, bool ownIt ) {
setForegroundDrawable( drawable, ownIt );
drawablePropertySet( "foreground", attribute.getValue(), [&] ( Drawable * drawable, bool ownIt, int index ) {
setForegroundDrawable( drawable, ownIt, index );
} );
} else if ( "foreground-radius" == name || "foregroundradius" == name ) {
SAVE_NORMAL_STATE_ATTR( String::toStr( getForegroundRadius() ) );
@@ -1397,9 +1401,10 @@ 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)> funcSet) {
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() ) {
@@ -1438,14 +1443,14 @@ bool UIWidget::drawablePropertySet(const std::string& propertyName, const std::s
drawable->setRectColors( rectColors );
funcSet( drawable, true );
funcSet( drawable, true, index );
} else if ( functionType.getName() == "url" && functionType.getParameters().size() >= 1 ) {
if ( NULL != ( res = DrawableSearcher::searchByName( functionType.getParameters().at(0) ) ) ) {
funcSet( res, res->getDrawableType() == Drawable::SPRITE );
funcSet( res, res->getDrawableType() == Drawable::SPRITE, index );
}
}
} else if ( NULL != ( res = DrawableSearcher::searchByName( value ) ) ) {
funcSet( res, res->getDrawableType() == Drawable::SPRITE );
funcSet( res, res->getDrawableType() == Drawable::SPRITE, index );
} else {
attributeSet = false;
}

View File

@@ -53,6 +53,7 @@ bool updateStyleSheet = false;
Clock waitClock;
Clock cssWaitClock;
efsw::WatchID watch = 0;
efsw::WatchID styleSheetWatch = 0;
std::map<std::string, std::string> widgetRegistered;
std::string basePath;
@@ -209,6 +210,25 @@ static void loadStyleSheet( std::string cssPath ) {
uiSceneNode->setStyleSheet( parser.getStyleSheet() );
currentStyleSheet = cssPath;
std::string folder( FileSystem::fileRemoveFileName( cssPath ) );
bool keepWatch = false;
for ( auto& directory : fileWatcher->directories() ) {
if ( directory == folder ) {
keepWatch = true;
}
}
if ( !keepWatch ) {
if ( styleSheetWatch != 0 ) {
fileWatcher->removeWatch( styleSheetWatch );
}
styleSheetWatch = fileWatcher->addWatch( folder, listener );
}
}
}
@@ -519,8 +539,8 @@ static void loadProjectNodes( pugi::xml_node node ) {
if ( !styleSheetNode.empty() ) {
std::string cssPath( styleSheetNode.attribute( "path" ).as_string() );
if ( isCSS( cssPath ) && FileSystem::fileExists( cssPath ) ) {
loadStyleSheet( cssPath );
if ( isCSS( cssPath ) && FileSystem::fileExists( basePath + cssPath ) ) {
loadStyleSheet( basePath + cssPath );
}
}
@@ -608,6 +628,8 @@ void loadProject( std::string projectPath ) {
basePath = FileSystem::fileRemoveFileName( projectPath );
FileSystem::changeWorkingDirectory( basePath );
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file( projectPath.c_str() );