diff --git a/bin/assets/layouts/test.css b/bin/assets/layouts/test.css
index 5ca62475d..e2830b334 100644
--- a/bin/assets/layouts/test.css
+++ b/bin/assets/layouts/test.css
@@ -79,6 +79,8 @@ Tooltip {
backgroundColor: #33FF3333;
backgroundImage: linear-gradient( #8c8886, #585857 );
borderRadius: 12;
+ textSize: 24dp;
+ padding: 12dp;
transition: scale 0.25s, rotation 0.25s 0.25s, borderColor 0.25s, backgroundColor 0.25s, borderRadius 0.25s;
}
@@ -94,6 +96,7 @@ Tooltip {
layout_marginLeft: 0;
padding: 24dp;
opacity: 0.8;
+ textSize: 24dp;
backgroundColor: #333;
transition: all 0.25s;
}
@@ -132,9 +135,16 @@ Tooltip {
padding: 22dp 12dp 120dp 12dp;
}
+#chbox,
+#rdbut {
+ textSize:24dp;
+ padding: 12dp;
+ backgroundColor: #333;
+}
+
#tres {
-/* width: 32dp;
- height: 32dp;*/
+ backgroundColor: #444;
+ padding: 8dp;
transition: all 0.25s;
}
@@ -150,3 +160,171 @@ Tooltip {
#pbut:hover {
skinColor: #66ff44;
}
+
+#test_2 > #rtest {
+ padding: 8dp;
+ background: #221122;
+}
+
+#test_2 > #rtest #rttv {
+ background: #333;
+ textSize: 24dp;
+ borderRadius: 8;
+ padding: 8dp;
+ transition: all 0.125s;
+}
+
+#test_2 > #rtest #rttv:hover {
+ background: #666;
+}
+
+#test_2 > #rtest:hover #rttv {
+ background: #005522;
+}
+
+#test_2 > #rtest:hover #rttv:hover {
+ background: #008822;
+}
+
+#test_2 > #rtest:hover #rttv:pressed {
+ background: lime;
+ textColor: #333;
+}
+
+#test_3 {
+ background: #221122;
+}
+
+#test_3 > .rooter {
+ background: red;
+}
+
+#test_3 > .rooter .outer {
+ background: blue;
+ transition: all 0.125s;
+}
+
+#test_3 > .rooter:hover .outer {
+ background: green;
+}
+
+#test_3 > .rooter:hover .outer:hover {
+ background: yellow;
+}
+
+#test_3 > .rooter .inner {
+ background: #123456;
+ transition: all 0.125s;
+}
+
+#test_3 > .rooter:hover .outer:hover .inner {
+ background: #DABA22;
+ layout_marginLeft: 16dp;
+}
+
+#test_3 > .rooter:hover .outer:hover .inner:hover {
+ background: #CCC;
+}
+
+#test_4 {
+ backgroundColor: #221122;
+}
+
+#test_4 > RelativeLayout {
+ backgroundColor: #331133;
+ padding: 8dp;
+ transition: all 0.125s;
+}
+
+#test_4 > RelativeLayout:hover {
+ backgroundColor: #442244;
+ cursor: hand;
+}
+
+#test_4 > RelativeLayout:pressed {
+ backgroundColor: #662266;
+}
+
+#test_4 > RelativeLayout > TextView {
+ transition: all 0.125s;
+}
+
+#test_4 > RelativeLayout:hover > TextView {
+ layout_marginLeft: 8dp;
+}
+
+TabWidget {
+ paddingLeft: 8dp;
+ paddingRight: 8dp;
+ paddingBottom: 8dp;
+ paddingTop: 20dp;
+ backgroundColor: #656565;
+}
+
+#lvbox {
+ backgroundColor: #222;
+ padding: 12dp;
+}
+
+.list {
+ textSize: 16dp;
+ padding: 8dp;
+}
+
+#tviewl {
+ textSize: 24dp;
+ backgroundColor: #333;
+}
+
+#tinput {
+ textSize: 24dp;
+ padding: 24dp;
+}
+
+#rvbox {
+ backgroundColor: #323232;
+ padding: 12dp;
+}
+
+#rrl {
+ backgroundColor: #999;
+ padding: 24dp;
+}
+
+#rrl > #tmap {
+ textSize: 24dp;
+ padding: 12dp;
+ backgroundColor: #333;
+}
+
+.eltv {
+ textSize: 24dp;
+ padding: 12dp;
+ backgroundColor: #242424;
+}
+
+#rrl > #el2,
+#rrl > #tm,
+#rrl > #tmp {
+ layout_margin: 12dp;
+}
+
+#rrl > #slider {
+ padding: 32dp;
+ backgroundColor: #555;
+}
+
+#rrl > #scrollbar {
+ padding: 8dp;
+ backgroundColor: #12345666;
+}
+
+#rrl > #spinbox {
+ padding: 8dp;
+ backgroundColor: #54345666;
+}
+
+#rrl > TextEdit {
+ padding: 16dp;
+ layout_marginBottom: 140dp;
+}
diff --git a/bin/assets/layouts/test.xml b/bin/assets/layouts/test.xml
index 5627678a5..c543d255e 100644
--- a/bin/assets/layouts/test.xml
+++ b/bin/assets/layouts/test.xml
@@ -1,56 +1,71 @@
-
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
- Test
- Test 2
- Test 3
-
+
- Test
- Test 2
- Test 3
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/assets/layouts/test_widgets.xml b/bin/assets/layouts/test_widgets.xml
index f89f09682..fee28a16a 100644
--- a/bin/assets/layouts/test_widgets.xml
+++ b/bin/assets/layouts/test_widgets.xml
@@ -1,7 +1,7 @@
-
+
-
+
@@ -31,17 +31,17 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
diff --git a/include/eepp/graphics/fonthelper.hpp b/include/eepp/graphics/fonthelper.hpp
index c6a6a8f56..9b32d6741 100644
--- a/include/eepp/graphics/fonthelper.hpp
+++ b/include/eepp/graphics/fonthelper.hpp
@@ -1,6 +1,8 @@
#ifndef EE_GRAPHICSFONTHELPER_HPP
#define EE_GRAPHICSFONTHELPER_HPP
+#include
+
namespace EE { namespace Graphics {
enum EE_FONT_TYPE {
diff --git a/include/eepp/graphics/fontsprite.hpp b/include/eepp/graphics/fontsprite.hpp
index ad57bf509..7ae7f9d0e 100644
--- a/include/eepp/graphics/fontsprite.hpp
+++ b/include/eepp/graphics/fontsprite.hpp
@@ -21,13 +21,13 @@ class EE_API FontSprite : public Font {
~FontSprite();
- bool loadFromFile(const std::string& filename, Color key = Color::Magenta, Uint32 firstChar = 32, int spacing = 0);
+ bool loadFromFile(const std::string& filename, Color key = Color::Fuchsia, Uint32 firstChar = 32, int spacing = 0);
- bool loadFromMemory(const void* data, std::size_t sizeInBytes, Color key = Color::Magenta, Uint32 firstChar = 32, int spacing = 0);
+ bool loadFromMemory(const void* data, std::size_t sizeInBytes, Color key = Color::Fuchsia, Uint32 firstChar = 32, int spacing = 0);
- bool loadFromStream( IOStream& stream, Color key = Color::Magenta, Uint32 firstChar = 32, int spacing = 0 );
+ bool loadFromStream( IOStream& stream, Color key = Color::Fuchsia, Uint32 firstChar = 32, int spacing = 0 );
- bool loadFromPack( Pack * pack, std::string filePackPath, Color key = Color::Magenta, Uint32 firstChar = 32, int spacing = 0 );
+ bool loadFromPack( Pack * pack, std::string filePackPath, Color key = Color::Fuchsia, Uint32 firstChar = 32, int spacing = 0 );
const Font::Info& getInfo() const;
diff --git a/include/eepp/graphics/texturefactory.hpp b/include/eepp/graphics/texturefactory.hpp
index d16bf5051..d0fadbd8b 100755
--- a/include/eepp/graphics/texturefactory.hpp
+++ b/include/eepp/graphics/texturefactory.hpp
@@ -26,9 +26,10 @@ class EE_API TextureFactory : protected Mutex {
* @param ClampMode Defines the CLAMP MODE
* @param CompressTexture If use the DXT compression on the texture loading ( if the card can display them, will convert RGB to DXT1, RGBA to DXT5 )
* @param KeepLocalCopy Keep the array data copy. ( useful if want to reload the texture )
+ * @param FileName A filename to recognize the texture.
* @return Internal Texture Id
*/
- Uint32 createEmptyTexture( const unsigned int& Width, const unsigned int& Height, const unsigned int& Channels = 4, const Color& DefaultColor = Color(0,0,0,255), const bool& Mipmap = false, const Texture::ClampMode& ClampMode = Texture::ClampMode::ClampToEdge, const bool& CompressTexture = false, const bool& KeepLocalCopy = false );
+ Uint32 createEmptyTexture( const unsigned int& Width, const unsigned int& Height, const unsigned int& Channels = 4, const Color& DefaultColor = Color(0,0,0,255), const bool& Mipmap = false, const Texture::ClampMode& ClampMode = Texture::ClampMode::ClampToEdge, const bool& CompressTexture = false, const bool& KeepLocalCopy = false, const std::string& Filename = std::string("") );
/** Loads a RAW Texture from Memory
* @param Pixels The Texture array
diff --git a/include/eepp/graphics/textureloader.hpp b/include/eepp/graphics/textureloader.hpp
index 5bae18e83..c10ccf10c 100644
--- a/include/eepp/graphics/textureloader.hpp
+++ b/include/eepp/graphics/textureloader.hpp
@@ -109,20 +109,20 @@ class EE_API TextureLoader : public ObjectLoader {
Int32 mImgHeight;
std::string mFilepath;
- unsigned int mWidth;
- unsigned int mHeight;
+ unsigned int mWidth;
+ unsigned int mHeight;
bool mMipmap;
Int32 mChannels;
Texture::ClampMode mClampMode;
bool mCompressTexture;
bool mLocalCopy;
- Pack * mPack;
+ Pack * mPack;
IOStream * mStream;
const Uint8 * mImagePtr;
Uint32 mSize;
- RGB * mColorKey;
+ RGB * mColorKey;
Image::FormatConfiguration mFormatConfiguration;
void start();
diff --git a/include/eepp/math/originpoint.hpp b/include/eepp/math/originpoint.hpp
index d0953d782..289242fde 100644
--- a/include/eepp/math/originpoint.hpp
+++ b/include/eepp/math/originpoint.hpp
@@ -3,6 +3,7 @@
#include
#include
+#include
namespace EE { namespace Math {
@@ -40,6 +41,8 @@ class tOriginPoint : public Vector2 {
{
}
+ std::string toString() const;
+
tOriginPoint& operator=(const Vector2& v);
};
@@ -50,6 +53,13 @@ tOriginPoint& tOriginPoint::operator=(const Vector2& v) {
return *this;
}
+template
+std::string tOriginPoint::toString() const {
+ if ( OriginType == OriginCenter ) return "center";
+ else if ( OriginType == OriginTopLeft ) return "topleft";
+ return String::toStr(this->x) + "," + String::toStr(this->y);
+}
+
typedef tOriginPoint OriginPoint;
typedef tOriginPoint OriginPointi;
diff --git a/include/eepp/scene/event.hpp b/include/eepp/scene/event.hpp
index 344f8790d..8830deb22 100644
--- a/include/eepp/scene/event.hpp
+++ b/include/eepp/scene/event.hpp
@@ -52,6 +52,7 @@ class EE_API Event {
OnClose, // Warning: Only some controls will report this event.
OnDragStart,
OnDragStop,
+ OnPaddingChange,
UserEvent,
NoEvent = eeINDEX_NOT_FOUND
};
diff --git a/include/eepp/scene/node.hpp b/include/eepp/scene/node.hpp
index 4c5c7124c..38bde727d 100644
--- a/include/eepp/scene/node.hpp
+++ b/include/eepp/scene/node.hpp
@@ -289,7 +289,7 @@ class EE_API Node : public Transformable {
void disableReportSizeChangeToChilds();
- bool reportSizeChangeToChilds();
+ bool reportSizeChangeToChilds() const;
void centerHorizontal();
diff --git a/include/eepp/scene/nodeattribute.hpp b/include/eepp/scene/nodeattribute.hpp
index 7ed311d21..acf32f196 100644
--- a/include/eepp/scene/nodeattribute.hpp
+++ b/include/eepp/scene/nodeattribute.hpp
@@ -62,7 +62,7 @@ class NodeAttribute {
const std::string& getName() const;
- const std::vector getParameters() const;
+ const std::vector& getParameters() const;
bool isEmpty() const;
protected:
@@ -73,10 +73,12 @@ class NodeAttribute {
NodeAttribute();
- NodeAttribute( std::string name, std::string value );
+ NodeAttribute( std::string name, std::string value, bool isVolatile = false );
bool isEmpty() const;
+ bool isVolatile() const;
+
std::string getName() const;
void setName(const std::string & name);
@@ -141,6 +143,7 @@ class NodeAttribute {
protected:
std::string mName;
std::string mValue;
+ bool mVolatile;
};
}}
diff --git a/include/eepp/system/color.hpp b/include/eepp/system/color.hpp
index 98e38c7f5..4d7d36b25 100755
--- a/include/eepp/system/color.hpp
+++ b/include/eepp/system/color.hpp
@@ -241,22 +241,22 @@ class EE_API Color : public tColor
static bool isColorString( std::string str );
static const Color Transparent;
- static const Color White;
static const Color Black;
- static const Color Red;
- static const Color Green;
- static const Color Blue;
- static const Color Yellow;
- static const Color Cyan;
- static const Color Magenta;
static const Color Silver;
static const Color Gray;
+ static const Color White;
static const Color Maroon;
- static const Color Olive;
- static const Color OfficeGreen;
+ static const Color Red;
static const Color Purple;
- static const Color Teal;
+ static const Color Fuchsia;
+ static const Color Green;
+ static const Color Lime;
+ static const Color Olive;
+ static const Color Yellow;
static const Color Navy;
+ static const Color Blue;
+ static const Color Teal;
+ static const Color Aqua;
};
typedef Color ColorA;
diff --git a/include/eepp/ui/css/stylesheet.hpp b/include/eepp/ui/css/stylesheet.hpp
index 869b55891..d82e7899d 100644
--- a/include/eepp/ui/css/stylesheet.hpp
+++ b/include/eepp/ui/css/stylesheet.hpp
@@ -23,14 +23,8 @@ class EE_API StyleSheet {
void combineStyleSheet( const StyleSheet& styleSheet );
- StyleSheetPseudoClassProperties getElementPropertiesByState( StyleSheetElement * element );
-
StyleSheetStyleVector getElementStyles( StyleSheetElement * element, const bool& applyPseudo = false );
- StyleSheetStyleVector getCacheableElementStyles( StyleSheetElement * element, const bool& applyPseudo = false );
-
- StyleSheetStyleVector getNoncacheableElementStyles( StyleSheetElement * element, const bool& applyPseudo = false );
-
const StyleSheetStyleList& getStyles() const;
protected:
StyleSheetStyleList mNodes;
diff --git a/include/eepp/ui/css/stylesheetpropertiesparser.hpp b/include/eepp/ui/css/stylesheetpropertiesparser.hpp
index b85cf438b..8ccaad29b 100644
--- a/include/eepp/ui/css/stylesheetpropertiesparser.hpp
+++ b/include/eepp/ui/css/stylesheetpropertiesparser.hpp
@@ -26,7 +26,7 @@ class EE_API StyleSheetPropertiesParser {
ReadingComment
};
- ReadState prevRs;
+ ReadState mPrevRs;
StyleSheetProperties mProperties;
@@ -39,6 +39,8 @@ class EE_API StyleSheetPropertiesParser {
int readComment( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
int readValueUrl( ReadState& rs, std::size_t pos, std::string& buffer, const std::string& str );
+
+ void addProperty( const std::string& name, std::string value );
};
}}}
diff --git a/include/eepp/ui/css/stylesheetproperty.hpp b/include/eepp/ui/css/stylesheetproperty.hpp
index 9dff66cae..1c2b6f42d 100644
--- a/include/eepp/ui/css/stylesheetproperty.hpp
+++ b/include/eepp/ui/css/stylesheetproperty.hpp
@@ -13,7 +13,7 @@ class EE_API StyleSheetProperty {
explicit StyleSheetProperty( const std::string& name, const std::string& value );
- explicit StyleSheetProperty( const std::string& name, const std::string& value, const Uint32& specificity );
+ explicit StyleSheetProperty( const std::string& name, const std::string& value, const Uint32& specificity, const bool& isVolatile = false );
const std::string& getName() const;
@@ -28,10 +28,15 @@ class EE_API StyleSheetProperty {
void setName(const std::string & name);
void setValue(const std::string & value);
+
+ const bool& isVolatile() const;
+
+ void setVolatile( const bool& isVolatile );
protected:
std::string mName;
std::string mValue;
Uint32 mSpecificity;
+ bool mVolatile;
};
typedef std::map StyleSheetProperties;
diff --git a/include/eepp/ui/css/stylesheetselector.hpp b/include/eepp/ui/css/stylesheetselector.hpp
index 7d1b367fd..d2f519abe 100644
--- a/include/eepp/ui/css/stylesheetselector.hpp
+++ b/include/eepp/ui/css/stylesheetselector.hpp
@@ -23,6 +23,12 @@ class EE_API StyleSheetSelector {
bool select( StyleSheetElement * element, const bool& applyPseudo = true ) const;
const bool& isCacheable() const;
+
+ bool hasPseudoClass(const std::string& cls) const;
+
+ bool hasPseudoClasses() const;
+
+ std::vector getRelatedElements( StyleSheetElement * element, const bool& applyPseudo = true ) const;
protected:
std::string mName;
std::string mPseudoClass;
diff --git a/include/eepp/ui/css/stylesheetselectorrule.hpp b/include/eepp/ui/css/stylesheetselectorrule.hpp
index 3c081b1a0..8674f94b6 100644
--- a/include/eepp/ui/css/stylesheetselectorrule.hpp
+++ b/include/eepp/ui/css/stylesheetselectorrule.hpp
@@ -26,6 +26,8 @@ class StyleSheetSelectorRule {
};
enum SpecificityVal {
+ SpecificityImportant = UINT32_MAX,
+ SpecificityInline = UINT32_MAX - 1,
SpecificityId = 1000000,
SpecificityClass = 100000,
SpecificityTag = 10000,
@@ -57,7 +59,7 @@ class StyleSheetSelectorRule {
bool hasPseudoClasses() const;
- bool hasPseudoClass(const std::string & cls) const;
+ bool hasPseudoClass(const std::string& cls) const;
const std::vector& getPseudoClasses() const;
diff --git a/include/eepp/ui/css/stylesheetstyle.hpp b/include/eepp/ui/css/stylesheetstyle.hpp
index 0ef26ac12..bfe65926d 100644
--- a/include/eepp/ui/css/stylesheetstyle.hpp
+++ b/include/eepp/ui/css/stylesheetstyle.hpp
@@ -12,32 +12,24 @@ class EE_API StyleSheetStyle {
explicit StyleSheetStyle( const std::string& selector, const StyleSheetProperties& properties );
- void print();
+ std::string build();
const StyleSheetSelector& getSelector() const;
const StyleSheetProperties& getProperties() const;
+ StyleSheetProperty getPropertyByName( const std::string& name ) const;
+
void setProperty( const StyleSheetProperty& property );
+
+ void clearProperties();
protected:
StyleSheetSelector mSelector;
StyleSheetProperties mProperties;
};
-class EE_API StyleSheetStyleUsed {
- public:
- StyleSheetStyle style;
- bool used;
-
- StyleSheetStyleUsed( StyleSheetStyle style, bool used ) :
- style( style ),
- used( used )
- {}
-};
-
typedef std::map StyleSheetStyleList;
typedef std::vector StyleSheetStyleVector;
-typedef std::vector StyleSheetStyleUsedVector;
}}}
diff --git a/include/eepp/ui/uicombobox.hpp b/include/eepp/ui/uicombobox.hpp
index 075028870..3a1b3520f 100644
--- a/include/eepp/ui/uicombobox.hpp
+++ b/include/eepp/ui/uicombobox.hpp
@@ -42,6 +42,8 @@ class EE_API UIComboBox : public UIWidget {
virtual void onPositionChange();
+ virtual void onPaddingChange();
+
virtual void onAutoSize();
};
diff --git a/include/eepp/ui/uinode.hpp b/include/eepp/ui/uinode.hpp
index d2f023253..9def26262 100644
--- a/include/eepp/ui/uinode.hpp
+++ b/include/eepp/ui/uinode.hpp
@@ -89,44 +89,28 @@ class EE_API UINode : public Node {
UISkin * setBackgroundFillEnabled( bool enabled );
- UINode * setBackgroundDrawable( const Uint32 & state, Drawable * drawable , bool ownIt = false );
-
UINode * setBackgroundDrawable( Drawable * drawable , bool ownIt = false );
- UINode * setBackgroundColor( const Uint32 & state, const Color& color );
-
UINode * setBackgroundColor( const Color& color );
- Color getBackgroundColor( const Uint32 & state ) const;
-
Color getBackgroundColor() const;
- UINode * setBorderRadius( const Uint32 & state, const unsigned int& corners );
-
UINode * setBorderRadius( const unsigned int& corners );
- Uint32 getBorderRadius( const Uint32& state ) const;
-
Uint32 getBorderRadius() const;
UISkin * setForegroundFillEnabled( bool enabled );
- UINode * setForegroundDrawable( const Uint32 & state, Drawable * drawable , bool ownIt = false );
-
UINode * setForegroundDrawable( Drawable * drawable , bool ownIt = false );
- UINode * setForegroundColor( const Uint32 & state, const Color& color );
-
UINode * setForegroundColor( const Color& color );
- Color getForegroundColor( const Uint32 & state ) const;
-
Color getForegroundColor() const;
- UINode * setForegroundRadius( const Uint32 & state, const unsigned int& corners );
-
UINode * setForegroundRadius( const unsigned int& corners );
+ Uint32 getForegroundRadius() const;
+
RectangleDrawable * setBorderEnabled( bool enabled );
UINode * setBorderColor( const Color& color );
@@ -135,6 +119,8 @@ class EE_API UINode : public Node {
UINode * setBorderWidth( const unsigned int& width );
+ Float getBorderWidth() const;
+
const Uint32& getFlags() const;
virtual UINode * setFlags( const Uint32& flags );
@@ -165,13 +151,9 @@ class EE_API UINode : public Node {
UINode * setSkin( UISkin * skin );
- UINode * setSkinColor( const Uint32& state, const Color& color );
-
UINode * setSkinColor( const Color& color );
- Color getSkinColor( const Uint32& state )const;
-
- Color getSkinColor() const;
+ const Color& getSkinColor() const;
void removeSkin();
@@ -213,6 +195,7 @@ class EE_API UINode : public Node {
RectangleDrawable * mBorder;
Vector2f mDragPoint;
Uint32 mDragButton;
+ Color mSkinColor;
virtual Uint32 onMouseDown( const Vector2i& position, const Uint32& flags );
diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp
index 5efa9dd1c..ac73484c4 100644
--- a/include/eepp/ui/uiscenenode.hpp
+++ b/include/eepp/ui/uiscenenode.hpp
@@ -44,8 +44,12 @@ class EE_API UISceneNode : public SceneNode {
void setStyleSheet( const CSS::StyleSheet& styleSheet );
+ void setStyleSheet( const std::string& inlineStyleSheet );
+
void combineStyleSheet( const CSS::StyleSheet& styleSheet );
+ void combineStyleSheet( const std::string& inlineStyleSheet );
+
CSS::StyleSheet& getStyleSheet();
bool hasStyleSheet();
diff --git a/include/eepp/ui/uiscrollview.hpp b/include/eepp/ui/uiscrollview.hpp
index 7767f2da8..e7fc5e044 100644
--- a/include/eepp/ui/uiscrollview.hpp
+++ b/include/eepp/ui/uiscrollview.hpp
@@ -38,7 +38,7 @@ class EE_API UIScrollView : public UITouchDragableWidget {
UIScrollBar * getHorizontalScrollBar() const;
- UINode * getContainer() const;
+ UIWidget * getContainer() const;
virtual bool setAttribute( const NodeAttribute& attribute, const Uint32& state = UIState::StateFlagNormal );
protected:
@@ -47,7 +47,7 @@ class EE_API UIScrollView : public UITouchDragableWidget {
UI_SCROLLBAR_MODE mHScrollMode;
UIScrollBar * mVScroll;
UIScrollBar * mHScroll;
- UINode * mContainer;
+ UIWidget * mContainer;
Node * mScrollView;
Uint32 mSizeChangeCb;
diff --git a/include/eepp/ui/uistate.hpp b/include/eepp/ui/uistate.hpp
index 74d059218..b7f235441 100644
--- a/include/eepp/ui/uistate.hpp
+++ b/include/eepp/ui/uistate.hpp
@@ -37,6 +37,8 @@ class EE_API UIState {
static int getStateNumber(const std::string & State);
+ static const char * getStateNameFromStateFlag( const Uint32& stateFlag );
+
static const Uint32& getStateFlag( const Uint32& stateIndex );
static Uint32 getStateFlagFromName( const std::string& name );
diff --git a/include/eepp/ui/uistyle.hpp b/include/eepp/ui/uistyle.hpp
index 697356a9a..812387880 100644
--- a/include/eepp/ui/uistyle.hpp
+++ b/include/eepp/ui/uistyle.hpp
@@ -7,6 +7,8 @@
#include
#include
#include
+#include
+#include
using namespace EE::Scene;
@@ -31,7 +33,7 @@ class EE_API UIStyle : public UIState {
Ease::Interpolation getTimingFunction() const { return timingFunction; }
- const Time& getDelay() const { return delay; };
+ const Time& getDelay() const { return delay; }
const Time& getDuration() const { return duration; }
@@ -53,33 +55,49 @@ class EE_API UIStyle : public UIState {
void onStateChange();
- CSS::StyleSheetProperty getStyleSheetProperty( const Uint32& state, const std::string& attributeName ) const;
+ CSS::StyleSheetProperty getStatelessStyleSheetProperty( const std::string& propertyName ) const;
- CSS::StyleSheetProperty getStyleSheetPropertyFromNames( const Uint32& state, const std::vector& propertiesNames ) const;
+ CSS::StyleSheetProperty getStyleSheetProperty( const std::string& propertyName ) const;
- NodeAttribute getNodeAttribute( const Uint32& state, const std::string& attributeName ) const;
+ NodeAttribute getNodeAttribute(const std::string& attributeName ) const;
- bool hasStyleSheetProperty( const Uint32& state, const std::string& propertyName ) const;
+ void setStyleSheetProperties( const CSS::StyleSheetProperties& properties );
- void addStyleSheetProperties( const Uint32& state, const CSS::StyleSheetProperties& properties );
+ void setStyleSheetProperty( const CSS::StyleSheetProperty& property );
- void addStyleSheetProperty( const Uint32& state, const CSS::StyleSheetProperty& property );
+ bool hasTransition( const std::string& propertyName );
- bool hasTransition( const Uint32& state, const std::string& propertyName );
-
- TransitionInfo getTransition( const Uint32& state, const std::string& propertyName );
+ TransitionInfo getTransition( const std::string& propertyName );
protected:
typedef std::map TransitionsMap;
UIWidget * mWidget;
- std::map mStates;
- std::map mTransitions;
- std::map> mTransitionAttributes;
+ CSS::StyleSheetStyleVector mCacheableStyles;
CSS::StyleSheetStyleVector mNoncacheableStyles;
+ CSS::StyleSheetStyle mElementStyle;
+ CSS::StyleSheetProperties mProperties;
+ std::vector mTransitionAttributes;
+ TransitionsMap mTransitions;
+ std::set mRelatedWidgets;
+ std::set mSubscribedWidgets;
+
+ void tryApplyStyle( const CSS::StyleSheetStyle& style );
void updateState();
- void parseTransitions( const Uint32& state );
+ void parseTransitions();
+
+ void subscribeNonCacheableStyles();
+
+ void unsubscribeNonCacheableStyles();
+
+ void subscribeRelated( UIWidget * widget );
+
+ void unsubscribeRelated( UIWidget * widget );
+
+ void removeFromSubscribedWidgets( UIWidget * widget );
+
+ void removeRelatedWidgets();
};
}}
diff --git a/include/eepp/ui/uiwidget.hpp b/include/eepp/ui/uiwidget.hpp
index d99a9f64a..9463425d6 100644
--- a/include/eepp/ui/uiwidget.hpp
+++ b/include/eepp/ui/uiwidget.hpp
@@ -92,7 +92,7 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
void notifyLayoutAttrChangeParent();
- bool setAttribute( const std::string& name, const std::string& value, const Uint32& state = UIState::StateFlagNormal );
+ void setStyleSheetProperty( const std::string& name, const std::string& value, const Uint32& specificity = UINT32_MAX - 1/*SpecificityInline*/ );
virtual bool setAttribute( const NodeAttribute& attribute, const Uint32& state = UIState::StateFlagNormal );
@@ -191,6 +191,8 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
virtual void onThemeLoaded();
+ virtual void onParentChange();
+
void updateAnchors( const Vector2f & SizeChange );
void alignAgainstLayout();
@@ -198,6 +200,16 @@ class EE_API UIWidget : public UINode, public CSS::StyleSheetElement {
void reportStyleStateChange();
bool isSceneNodeLoading() const;
+
+ std::string getLayoutWidthRulesString() const;
+
+ std::string getLayoutHeightRulesString() const;
+
+ std::string getLayoutGravityString() const;
+
+ std::string getGravityString() const;
+
+ std::string getFlagsString() const;
};
}}
diff --git a/src/eepp/graphics/fontsprite.cpp b/src/eepp/graphics/fontsprite.cpp
index 022079d28..98e5b5077 100644
--- a/src/eepp/graphics/fontsprite.cpp
+++ b/src/eepp/graphics/fontsprite.cpp
@@ -130,7 +130,7 @@ bool FontSprite::loadFromStream( IOStream& stream, Color key, Uint32 firstChar,
xPosToRead = charSpacing;
}
- img.createMaskFromColor( Color::Magenta, 0 );
+ img.createMaskFromColor( Color::Fuchsia, 0 );
Uint32 texId = TextureFactory::instance()->loadFromPixels( img.getPixelsPtr(), img.getWidth(), img.getHeight(), img.getChannels() );
diff --git a/src/eepp/graphics/rectangledrawable.cpp b/src/eepp/graphics/rectangledrawable.cpp
index 8b2024e7e..3e4290182 100644
--- a/src/eepp/graphics/rectangledrawable.cpp
+++ b/src/eepp/graphics/rectangledrawable.cpp
@@ -94,9 +94,11 @@ Uint32 RectangleDrawable::getCorners() const {
}
void RectangleDrawable::setCorners(const Uint32 & corners) {
- mCorners = corners;
- mNeedsUpdate = true;
- mRecreateVertexBuffer = true;
+ if ( corners != mCorners ) {
+ mCorners = corners;
+ mNeedsUpdate = true;
+ mRecreateVertexBuffer = true;
+ }
}
RectColors RectangleDrawable::getRectColors() const {
diff --git a/src/eepp/graphics/texture.cpp b/src/eepp/graphics/texture.cpp
index 8ea9c2b0a..8c60e482c 100755
--- a/src/eepp/graphics/texture.cpp
+++ b/src/eepp/graphics/texture.cpp
@@ -7,6 +7,10 @@
#include
#include
#include
+#include
+#include
+
+using namespace EE::Window;
using namespace EE::Graphics::Private;
namespace EE { namespace Graphics {
@@ -123,8 +127,14 @@ void Texture::setName(const std::string & name) {
}
Uint8 * Texture::iLock( const bool& ForceRGBA, const bool& KeepFormat ) {
+ bool threaded = Engine::instance()->isSharedGLContextEnabled() &&
+ Thread::getCurrentThreadId() != Engine::instance()->getMainThreadId();
+
#ifndef EE_GLES
if ( !( mFlags & TEX_FLAG_LOCKED ) ) {
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->setGLContextThread();
+
if ( ForceRGBA )
mChannels = 4;
@@ -163,29 +173,40 @@ Uint8 * Texture::iLock( const bool& ForceRGBA, const bool& KeepFormat ) {
mFlags |= TEX_FLAG_LOCKED;
}
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->unsetGLContextThread();
+
return &mPixels[0];
#else
if ( !( mFlags & TEX_FLAG_LOCKED ) ) {
- TextureSaver saver( mTexture );
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->setGLContextThread();
- GLuint frameBuffer = 0;
- GLi->genFramebuffers(1, &frameBuffer);
+ {
+ TextureSaver saver( mTexture );
- if ( frameBuffer ) {
- allocate( mWidth * mHeight * 4 );
+ GLuint frameBuffer = 0;
+ GLi->genFramebuffers(1, &frameBuffer);
- GLint previousFrameBuffer;
- glGetIntegerv( GL_FRAMEBUFFER_BINDING, &previousFrameBuffer );
- GLi->bindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
- GLi->framebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0 );
- glReadPixels( 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, &mPixels[0] );
- GLi->deleteFramebuffers(1, &frameBuffer);
- GLi->bindFramebuffer( GL_FRAMEBUFFER, previousFrameBuffer );
+ if ( frameBuffer ) {
+ allocate( mWidth * mHeight * 4 );
- mFlags |= TEX_FLAG_LOCKED;
+ GLint previousFrameBuffer;
+ glGetIntegerv( GL_FRAMEBUFFER_BINDING, &previousFrameBuffer );
+ GLi->bindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
+ GLi->framebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0 );
+ glReadPixels( 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, &mPixels[0] );
+ GLi->deleteFramebuffers(1, &frameBuffer);
+ GLi->bindFramebuffer( GL_FRAMEBUFFER, previousFrameBuffer );
- return &mPixels[0];
+ mFlags |= TEX_FLAG_LOCKED;
+ }
}
+
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->unsetGLContextThread();
+
+ return NULL != mPixels ? &mPixels[0] : NULL;
}
return NULL;
@@ -389,38 +410,49 @@ void Texture::reload() {
Int32 width = (Int32)mWidth;
Int32 height = (Int32)mHeight;
- TextureSaver saver( mTexture );
+ bool threaded = Engine::instance()->isSharedGLContextEnabled() &&
+ Thread::getCurrentThreadId() != Engine::instance()->getMainThreadId();
- Uint32 flags = ( mFlags & TEX_FLAG_MIPMAP ) ? SOIL_FLAG_MIPMAPS : 0;
- flags = (mClampMode == ClampRepeat) ? (flags | SOIL_FLAG_TEXTURE_REPEATS) : flags;
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->setGLContextThread();
- if ( ( mFlags & TEX_FLAG_COMPRESSED ) ) {
- if ( isGrabed() )
- mTexture = SOIL_create_OGL_texture( reinterpret_cast ( &mPixels[0] ), &width, &height, mChannels, mTexture, flags | SOIL_FLAG_COMPRESS_TO_DXT );
- else
- glCompressedTexImage2D( mTexture, 0, mInternalFormat, width, height, 0, mSize, &mPixels[0] );
- } else {
- mTexture = SOIL_create_OGL_texture( reinterpret_cast ( &mPixels[0] ), &width, &height, mChannels, mTexture, flags );
+ {
+ TextureSaver saver( mTexture );
- TextureFactory::instance()->mMemSize -= mSize;
+ Uint32 flags = ( mFlags & TEX_FLAG_MIPMAP ) ? SOIL_FLAG_MIPMAPS : 0;
+ flags = (mClampMode == ClampRepeat) ? (flags | SOIL_FLAG_TEXTURE_REPEATS) : flags;
- mSize = mWidth * mHeight * mChannels;
+ if ( ( mFlags & TEX_FLAG_COMPRESSED ) ) {
+ if ( isGrabed() )
+ mTexture = SOIL_create_OGL_texture( reinterpret_cast ( &mPixels[0] ), &width, &height, mChannels, mTexture, flags | SOIL_FLAG_COMPRESS_TO_DXT );
+ else
+ glCompressedTexImage2D( mTexture, 0, mInternalFormat, width, height, 0, mSize, &mPixels[0] );
+ } else {
+ mTexture = SOIL_create_OGL_texture( reinterpret_cast ( &mPixels[0] ), &width, &height, mChannels, mTexture, flags );
- if ( getMipmap() ) {
- int w = mWidth;
- int h = mHeight;
+ TextureFactory::instance()->mMemSize -= mSize;
- while( w > 2 && h > 2 ) {
- w>>=1;
- h>>=1;
- mSize += ( w * h * mChannels );
+ mSize = mWidth * mHeight * mChannels;
+
+ if ( getMipmap() ) {
+ int w = mWidth;
+ int h = mHeight;
+
+ while( w > 2 && h > 2 ) {
+ w>>=1;
+ h>>=1;
+ mSize += ( w * h * mChannels );
+ }
}
+
+ TextureFactory::instance()->mMemSize += mSize;
}
- TextureFactory::instance()->mMemSize += mSize;
+ iTextureFilter( mFilter );
}
- iTextureFilter( mFilter );
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->unsetGLContextThread();
} else {
iLock(false,true);
reload();
@@ -442,15 +474,26 @@ static unsigned int convertPixelFormatToGLFormat( Image::PixelFormat pf ) {
void Texture::update( const Uint8* pixels, Uint32 width, Uint32 height, Uint32 x, Uint32 y, PixelFormat pf ) {
if ( NULL != pixels && mTexture && x + width <= mWidth && y + height <= mHeight ) {
- TextureSaver saver( mTexture );
+ bool threaded = Engine::instance()->isSharedGLContextEnabled() &&
+ Thread::getCurrentThreadId() != Engine::instance()->getMainThreadId();
- glTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, (unsigned int)convertPixelFormatToGLFormat( pf ), GL_UNSIGNED_BYTE, pixels );
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->setGLContextThread();
- if ( hasLocalCopy() ) {
- Image image( pixels, width, height, mChannels );
+ {
+ TextureSaver saver( mTexture );
- Image::copyImage( &image, x, y );
+ glTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, (unsigned int)convertPixelFormatToGLFormat( pf ), GL_UNSIGNED_BYTE, pixels );
+
+ if ( hasLocalCopy() ) {
+ Image image( pixels, width, height, mChannels );
+
+ Image::copyImage( &image, x, y );
+ }
}
+
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->unsetGLContextThread();
}
}
@@ -463,27 +506,38 @@ void Texture::update( Image *image, Uint32 x, Uint32 y ) {
}
void Texture::replace( Image * image ) {
- Uint32 flags = ( mFlags & TEX_FLAG_MIPMAP ) ? SOIL_FLAG_MIPMAPS : 0;
- flags = (mClampMode == ClampRepeat) ? (flags | SOIL_FLAG_TEXTURE_REPEATS) : flags;
+ bool threaded = Engine::instance()->isSharedGLContextEnabled() &&
+ Thread::getCurrentThreadId() != Engine::instance()->getMainThreadId();
- TextureSaver textureSaver;
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->setGLContextThread();
- Int32 width = (Int32)image->getWidth();
- Int32 height = (Int32)image->getHeight();
- mTexture = SOIL_create_OGL_texture( image->getPixelsPtr(), &width, &height, image->getChannels(), mTexture, flags );
- mWidth = mImgWidth = width;
- mHeight = mImgHeight = height;
- mChannels = image->getChannels();
+ {
+ Uint32 flags = ( mFlags & TEX_FLAG_MIPMAP ) ? SOIL_FLAG_MIPMAPS : 0;
+ flags = (mClampMode == ClampRepeat) ? (flags | SOIL_FLAG_TEXTURE_REPEATS) : flags;
- TextureFactory::instance()->mMemSize -= mSize;
- mSize = mWidth * mHeight * mChannels;
- TextureFactory::instance()->mMemSize += mSize;
+ TextureSaver textureSaver;
- if ( hasLocalCopy() ) {
- // Renew the local copy
- allocate( image->getMemSize(), Color(0,0,0,0), false );
- Image::copyImage( image );
+ Int32 width = (Int32)image->getWidth();
+ Int32 height = (Int32)image->getHeight();
+ mTexture = SOIL_create_OGL_texture( image->getPixelsPtr(), &width, &height, image->getChannels(), mTexture, flags );
+ mWidth = mImgWidth = width;
+ mHeight = mImgHeight = height;
+ mChannels = image->getChannels();
+
+ TextureFactory::instance()->mMemSize -= mSize;
+ mSize = mWidth * mHeight * mChannels;
+ TextureFactory::instance()->mMemSize += mSize;
+
+ if ( hasLocalCopy() ) {
+ // Renew the local copy
+ allocate( image->getMemSize(), Color(0,0,0,0), false );
+ Image::copyImage( image );
+ }
}
+
+ if ( threaded )
+ Engine::instance()->getCurrentWindow()->unsetGLContextThread();
}
const Uint32& Texture::getHashName() const {
diff --git a/src/eepp/graphics/texturefactory.cpp b/src/eepp/graphics/texturefactory.cpp
index 7dc9817d9..724b321fe 100755
--- a/src/eepp/graphics/texturefactory.cpp
+++ b/src/eepp/graphics/texturefactory.cpp
@@ -31,9 +31,9 @@ TextureFactory::~TextureFactory() {
unloadTextures();
}
-Uint32 TextureFactory::createEmptyTexture( const unsigned int& Width, const unsigned int& Height, const unsigned int& Channels, const Color& DefaultColor, const bool& Mipmap, const Texture::ClampMode& ClampMode, const bool& CompressTexture, const bool& KeepLocalCopy ) {
+Uint32 TextureFactory::createEmptyTexture( const unsigned int& Width, const unsigned int& Height, const unsigned int& Channels, const Color& DefaultColor, const bool& Mipmap, const Texture::ClampMode& ClampMode, const bool& CompressTexture, const bool& KeepLocalCopy, const std::string& Filename ) {
Image TmpImg( Width, Height, Channels, DefaultColor );
- return loadFromPixels( TmpImg.getPixelsPtr(), Width, Height, Channels, Mipmap, ClampMode, CompressTexture, KeepLocalCopy );
+ return loadFromPixels( TmpImg.getPixelsPtr(), Width, Height, Channels, Mipmap, ClampMode, CompressTexture, KeepLocalCopy, Filename );
}
Uint32 TextureFactory::loadFromPixels( const unsigned char * Pixels, const unsigned int& Width, const unsigned int& Height, const unsigned int& Channels, const bool& Mipmap, const Texture::ClampMode& ClampMode, const bool& CompressTexture, const bool& KeepLocalCopy, const std::string& FileName ) {
diff --git a/src/eepp/scene/actions/resizeborderradius.cpp b/src/eepp/scene/actions/resizeborderradius.cpp
index 167c7260f..cc612a1ab 100644
--- a/src/eepp/scene/actions/resizeborderradius.cpp
+++ b/src/eepp/scene/actions/resizeborderradius.cpp
@@ -24,7 +24,7 @@ void ResizeBorderRadius::onUpdate( const Time& ) {
if ( NULL != mNode && mNode->isWidget() ) {
UIWidget * widget = static_cast( mNode );
- widget->setBorderRadius( widget->getStyleState(), mInterpolation.getPosition() );
+ widget->setBorderRadius( mInterpolation.getPosition() );
}
}
diff --git a/src/eepp/scene/actions/tint.cpp b/src/eepp/scene/actions/tint.cpp
index 263d19caa..1f5cfa783 100644
--- a/src/eepp/scene/actions/tint.cpp
+++ b/src/eepp/scene/actions/tint.cpp
@@ -126,7 +126,7 @@ void Tint::onUpdate( const Time& ) {
switch ( mColorInterpolationType ) {
case Background:
{
- widget->setBackgroundColor( widget->getStyleState(),
+ widget->setBackgroundColor(
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
@@ -137,7 +137,7 @@ void Tint::onUpdate( const Time& ) {
}
case Foreground:
{
- widget->setForegroundColor( widget->getStyleState(),
+ widget->setForegroundColor(
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
@@ -148,7 +148,7 @@ void Tint::onUpdate( const Time& ) {
}
case Skin:
{
- widget->setSkinColor( widget->getStyleState(),
+ widget->setSkinColor(
Color( mInterpolationR.getPosition(),
mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
diff --git a/src/eepp/scene/node.cpp b/src/eepp/scene/node.cpp
index abac3fad6..f80571023 100644
--- a/src/eepp/scene/node.cpp
+++ b/src/eepp/scene/node.cpp
@@ -1386,7 +1386,7 @@ void Node::sendParentSizeChange( const Vector2f& SizeChange ) {
}
}
-bool Node::reportSizeChangeToChilds() {
+bool Node::reportSizeChangeToChilds() const {
return 0 != ( mNodeFlags & NODE_FLAG_REPORT_SIZE_CHANGE_TO_CHILDS );
}
diff --git a/src/eepp/scene/nodeattribute.cpp b/src/eepp/scene/nodeattribute.cpp
index 4672c61d6..2557fad6c 100644
--- a/src/eepp/scene/nodeattribute.cpp
+++ b/src/eepp/scene/nodeattribute.cpp
@@ -33,15 +33,20 @@ const std::vector& NodeAttribute::Info::getNames() const {
NodeAttribute::NodeAttribute()
{}
-NodeAttribute::NodeAttribute( std::string name, std::string value ) :
+NodeAttribute::NodeAttribute( std::string name, std::string value, bool isVolatile ) :
mName( String::toLower( name ) ),
- mValue( value )
+ mValue( value ),
+ mVolatile( isVolatile )
{}
bool NodeAttribute::isEmpty() const {
return mName.empty();
}
+bool NodeAttribute::isVolatile() const {
+ return mVolatile;
+}
+
std::string NodeAttribute::getName() const {
return mName;
}
@@ -133,8 +138,8 @@ static OriginPoint toOriginPoint( std::string val ) {
Float x = 0;
Float y = 0;
- bool Res1 = String::fromString( x, parts[0] );
- bool Res2 = String::fromString( y, parts[1] );
+ bool Res1 = String::fromString( x, String::trim(parts[0]) );
+ bool Res2 = String::fromString( y, String::trim(parts[1]) );
if ( Res1 && Res2 ) {
return OriginPoint( x, y );
@@ -174,8 +179,8 @@ Vector2f NodeAttribute::asVector2f( const Vector2f & defaultValue ) const {
if ( xySplit.size() == 2 ) {
Float val;
- vector.x = String::fromString( val, xySplit[0] ) ? val : defaultValue.x;
- vector.y = String::fromString( val, xySplit[1] ) ? val : defaultValue.y;
+ vector.x = String::fromString( val, String::trim(xySplit[0]) ) ? val : defaultValue.x;
+ vector.y = String::fromString( val, String::trim(xySplit[1]) ) ? val : defaultValue.y;
return vector;
} else if ( xySplit.size() == 1 ) {
@@ -198,8 +203,8 @@ Vector2i NodeAttribute::asVector2i( const Vector2i & defaultValue ) const {
if ( xySplit.size() == 2 ) {
int val;
- vector.x = String::fromString( val, xySplit[0] ) ? val : defaultValue.x;
- vector.y = String::fromString( val, xySplit[1] ) ? val : defaultValue.y;
+ vector.x = String::fromString( val, String::trim(xySplit[0]) ) ? val : defaultValue.x;
+ vector.y = String::fromString( val, String::trim(xySplit[1]) ) ? val : defaultValue.y;
return vector;
} else if ( xySplit.size() == 1 ) {
@@ -365,7 +370,7 @@ const std::string& NodeAttribute::FunctionType::getName() const {
return name;
}
-const std::vector NodeAttribute::FunctionType::getParameters() const {
+const std::vector& NodeAttribute::FunctionType::getParameters() const {
return parameters;
}
diff --git a/src/eepp/scene/scenemanager.cpp b/src/eepp/scene/scenemanager.cpp
index 87f821f3d..f43c3ddf7 100644
--- a/src/eepp/scene/scenemanager.cpp
+++ b/src/eepp/scene/scenemanager.cpp
@@ -22,8 +22,7 @@ SceneManager::~SceneManager() {
mResources.clear();
}
-void SceneManager::draw()
-{
+void SceneManager::draw() {
for ( auto it = mResources.begin() ; it != mResources.end(); it++ ) {
SceneNode * sceneNode = (*it);
@@ -43,8 +42,7 @@ void SceneManager::update() {
update( mClock.getElapsed() );
}
-bool SceneManager::isShootingDown() const
-{
+bool SceneManager::isShootingDown() const {
return mIsShootingDown;
}
diff --git a/src/eepp/system/color.cpp b/src/eepp/system/color.cpp
index 95d3e1234..0741667af 100644
--- a/src/eepp/system/color.cpp
+++ b/src/eepp/system/color.cpp
@@ -7,23 +7,25 @@
namespace EE { namespace System {
-const Color Color::Transparent = Color(0,0,0,0);
-const Color Color::White = Color(255,255,255);
-const Color Color::Black = Color(0,0,0);
-const Color Color::Red = Color(255,0,0);
-const Color Color::Green = Color(0,255,0);
-const Color Color::Blue = Color(0,0,255);
-const Color Color::Yellow = Color(255,255,0);
-const Color Color::Cyan = Color(0,255,255);
-const Color Color::Magenta = Color(255,0,255);
-const Color Color::Silver = Color(192,0,192);
-const Color Color::Gray = Color(128,128,128);
-const Color Color::Maroon = Color(128,0,0);
-const Color Color::Olive = Color(128,128,0);
-const Color Color::OfficeGreen = Color(0,128,0);
-const Color Color::Purple = Color(128,0,128);
-const Color Color::Teal = Color(0,128,128);
-const Color Color::Navy = Color(0,0,128);
+// @TODO: Support all CSS3 color keywords.
+// Reference: https://www.w3.org/TR/2018/REC-css-color-3-20180619/
+const Color Color::Transparent = Color(0x00000000);
+const Color Color::Black = Color(0x000000FF);
+const Color Color::Silver = Color(0xC0C0C0FF);
+const Color Color::Gray = Color(0x808080FF);
+const Color Color::White = Color(0xFFFFFFFF);
+const Color Color::Maroon = Color(0x800000FF);
+const Color Color::Red = Color(0xFF0000FF);
+const Color Color::Purple = Color(0x800080FF);
+const Color Color::Fuchsia = Color(0xFF00FFFF);
+const Color Color::Green = Color(0x008000FF);
+const Color Color::Lime = Color(0x00FF00FF);
+const Color Color::Olive = Color(0x808000FF);
+const Color Color::Yellow = Color(0xFFFF00FF);
+const Color Color::Navy = Color(0x000080FF);
+const Color Color::Blue = Color(0x0000FFFF);
+const Color Color::Teal = Color(0x008080FF);
+const Color Color::Aqua = Color(0x00FFFFFF);
RGB::RGB() : tRGB()
{
@@ -303,22 +305,22 @@ Color Color::fromString( std::string str ) {
} else if ( size >= 3 && isalpha( str[0] ) && isalpha( str[1] ) && isalpha( str[2] ) ) {
String::toLowerInPlace( str );
if ( "transparent" == str ) return Color::Transparent;
- else if ( "white" == str ) return Color::White;
else if ( "black" == str ) return Color::Black;
- else if ( "red" == str ) return Color::Red;
- else if ( "green" == str ) return Color::Green;
- else if ( "blue" == str ) return Color::Blue;
- else if ( "yellow" == str ) return Color::Yellow;
- else if ( "cyan" == str ) return Color::Cyan;
- else if ( "magenta" == str ) return Color::Magenta;
else if ( "silver" == str ) return Color::Silver;
else if ( "gray" == str ) return Color::Gray;
+ else if ( "white" == str ) return Color::White;
else if ( "maroon" == str ) return Color::Maroon;
- else if ( "olive" == str ) return Color::Olive;
- else if ( "officegreen" == str ) return Color::OfficeGreen;
+ else if ( "red" == str ) return Color::Red;
else if ( "purple" == str ) return Color::Purple;
- else if ( "teal" == str ) return Color::Teal;
+ else if ( "fuchsia" == str ) return Color::Fuchsia;
+ else if ( "green" == str ) return Color::Green;
+ else if ( "lime" == str ) return Color::Lime;
+ else if ( "olive" == str ) return Color::Olive;
+ else if ( "yellow" == str ) return Color::Yellow;
else if ( "navy" == str ) return Color::Navy;
+ else if ( "blue" == str ) return Color::Blue;
+ else if ( "teal" == str ) return Color::Teal;
+ else if ( "aqua" == str ) return Color::Aqua;
}
if ( size < 6 ) {
@@ -343,22 +345,22 @@ bool Color::isColorString( std::string str ) {
String::toLowerInPlace( str );
if ( "transparent" == str ) return true;
- else if ( "white" == str ) return true;
else if ( "black" == str ) return true;
- else if ( "red" == str ) return true;
- else if ( "green" == str ) return true;
- else if ( "blue" == str ) return true;
- else if ( "yellow" == str ) return true;
- else if ( "cyan" == str ) return true;
- else if ( "magenta" == str ) return true;
else if ( "silver" == str ) return true;
else if ( "gray" == str ) return true;
+ else if ( "white" == str ) return true;
else if ( "maroon" == str ) return true;
- else if ( "olive" == str ) return true;
- else if ( "officegreen" == str ) return true;
+ else if ( "red" == str ) return true;
else if ( "purple" == str ) return true;
- else if ( "teal" == str ) return true;
+ else if ( "fuchsia" == str ) return true;
+ else if ( "green" == str ) return true;
+ else if ( "lime" == str ) return true;
+ else if ( "olive" == str ) return true;
+ else if ( "yellow" == str ) return true;
else if ( "navy" == str ) return true;
+ else if ( "blue" == str ) return true;
+ else if ( "teal" == str ) return true;
+ else if ( "aqua" == str ) return true;
return false;
}
diff --git a/src/eepp/ui/css/stylesheet.cpp b/src/eepp/ui/css/stylesheet.cpp
index 58aca908d..da58a5ca7 100644
--- a/src/eepp/ui/css/stylesheet.cpp
+++ b/src/eepp/ui/css/stylesheet.cpp
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
namespace EE { namespace UI { namespace CSS {
@@ -20,8 +21,8 @@ void StyleSheet::combineStyle( const StyleSheetStyle& node ) {
auto currentNode = nodeIt->second;
if ( node.getSelector().getSpecificity() > currentNode.getSelector().getSpecificity() ) {
- for ( auto pit = node.getProperties().begin(); pit != node.getProperties().end(); ++pit )
- currentNode.setProperty( pit->second );
+ for ( auto& pit : node.getProperties() )
+ currentNode.setProperty( pit.second );
}
}
}
@@ -31,46 +32,24 @@ bool StyleSheet::isEmpty() const {
}
void StyleSheet::print() {
- for ( auto it = mNodes.begin(); it != mNodes.end(); ++it ) {
- StyleSheetStyle& style = it->second;
+ for ( auto& it : mNodes ) {
+ StyleSheetStyle& style = it.second;
- style.print();
+ std::cout << style.build();
}
}
void StyleSheet::combineStyleSheet( const StyleSheet& styleSheet ) {
- for ( auto it = styleSheet.getStyles().begin(); it != styleSheet.getStyles().end(); ++it ) {
- combineStyle( it->second );
+ for ( auto& it : styleSheet.getStyles() ) {
+ combineStyle( it.second );
}
}
-StyleSheet::StyleSheetPseudoClassProperties StyleSheet::getElementPropertiesByState( StyleSheetElement * element ) {
- StyleSheetPseudoClassProperties propertiesSelectedByPseudoClass;
-
- for ( auto it = mNodes.begin(); it != mNodes.end(); ++it ) {
- StyleSheetStyle& node = it->second;
- const StyleSheetSelector& selector = node.getSelector();
-
- if ( selector.isCacheable() && selector.select( element, false ) ) {
- for ( auto pit = node.getProperties().begin(); pit != node.getProperties().end(); ++pit ) {
- StyleSheetProperties& pseudoClassProperties = propertiesSelectedByPseudoClass[selector.getPseudoClass()];
- auto pcit = pseudoClassProperties.find( pit->second.getName() );
-
- if ( pcit == pseudoClassProperties.end() || pit->second.getSpecificity() >= pcit->second.getSpecificity() ) {
- pseudoClassProperties[ pit->second.getName() ] = pit->second;
- }
- }
- }
- }
-
- return propertiesSelectedByPseudoClass;
-}
-
StyleSheetStyleVector StyleSheet::getElementStyles( StyleSheetElement * element , const bool& applyPseudo ) {
StyleSheetStyleVector styles;
- for ( auto it = mNodes.begin(); it != mNodes.end(); ++it ) {
- StyleSheetStyle& node = it->second;
+ for ( const auto& it : mNodes ) {
+ const StyleSheetStyle& node = it.second;
const StyleSheetSelector& selector = node.getSelector();
if ( selector.select( element, applyPseudo ) ) {
@@ -81,36 +60,6 @@ StyleSheetStyleVector StyleSheet::getElementStyles( StyleSheetElement * element
return styles;
}
-StyleSheetStyleVector StyleSheet::getCacheableElementStyles( StyleSheetElement * element, const bool& applyPseudo ) {
- StyleSheetStyleVector styles;
-
- for ( auto it = mNodes.begin(); it != mNodes.end(); ++it ) {
- StyleSheetStyle& node = it->second;
- const StyleSheetSelector& selector = node.getSelector();
-
- if ( selector.isCacheable() && selector.select( element, applyPseudo ) ) {
- styles.push_back( node );
- }
- }
-
- return styles;
-}
-
-StyleSheetStyleVector StyleSheet::getNoncacheableElementStyles( StyleSheetElement * element, const bool& applyPseudo ) {
- StyleSheetStyleVector styles;
-
- for ( auto it = mNodes.begin(); it != mNodes.end(); ++it ) {
- StyleSheetStyle& node = it->second;
- const StyleSheetSelector& selector = node.getSelector();
-
- if ( !selector.isCacheable() && selector.select( element, applyPseudo ) ) {
- styles.push_back( node );
- }
- }
-
- return styles;
-}
-
const StyleSheetStyleList& StyleSheet::getStyles() const {
return mNodes;
}
diff --git a/src/eepp/ui/css/stylesheetpropertiesparser.cpp b/src/eepp/ui/css/stylesheetpropertiesparser.cpp
index cceb7b0cd..78255891d 100644
--- a/src/eepp/ui/css/stylesheetpropertiesparser.cpp
+++ b/src/eepp/ui/css/stylesheetpropertiesparser.cpp
@@ -1,4 +1,9 @@
#include
+#include
+#include
+
+using namespace EE::UI;
+using namespace EE::Scene;
namespace EE { namespace UI { namespace CSS {
@@ -18,7 +23,7 @@ const StyleSheetProperties & StyleSheetPropertiesParser::getProperties() const {
void StyleSheetPropertiesParser::parse( std::string propsstr ) {
ReadState rs = ReadingPropertyName;
- prevRs = rs;
+ mPrevRs = rs;
std::size_t pos = 0;
std::string buffer;
@@ -45,7 +50,7 @@ void StyleSheetPropertiesParser::parse( std::string propsstr ) {
}
int StyleSheetPropertiesParser::readPropertyName(StyleSheetPropertiesParser::ReadState & rs, std::size_t pos, std::string & buffer, const std::string& str) {
- prevRs = rs;
+ mPrevRs = rs;
buffer.clear();
while ( pos < str.size() ) {
@@ -73,7 +78,7 @@ int StyleSheetPropertiesParser::readPropertyValue(StyleSheetPropertiesParser::Re
buffer.clear();
- prevRs = rs;
+ mPrevRs = rs;
while ( pos < str.size() ) {
if ( str[pos] == '/' && str.size() > pos + 1 && str[pos+1] == '*' ) {
@@ -89,7 +94,7 @@ int StyleSheetPropertiesParser::readPropertyValue(StyleSheetPropertiesParser::Re
if ( str[pos] == ';' ) {
rs = ReadingPropertyName;
- mProperties[ propName ] = StyleSheetProperty( propName, buffer );
+ addProperty( propName, buffer );
return pos + 1;
}
@@ -102,7 +107,7 @@ int StyleSheetPropertiesParser::readPropertyValue(StyleSheetPropertiesParser::Re
if ( pos == str.size() ) {
rs = ReadingPropertyName;
- mProperties[ propName ] = StyleSheetProperty( propName, buffer );
+ addProperty( propName, buffer );
return pos + 1;
}
@@ -116,7 +121,7 @@ int StyleSheetPropertiesParser::readComment(StyleSheetPropertiesParser::ReadStat
while ( pos < str.size() ) {
if ( str[pos] == '*' && str.size() > pos + 1 && str[pos+1] == '/' ) {
- rs = prevRs;
+ rs = mPrevRs;
return pos + 2;
}
@@ -159,4 +164,25 @@ int StyleSheetPropertiesParser::readValueUrl(StyleSheetPropertiesParser::ReadSta
return pos;
}
+void StyleSheetPropertiesParser::addProperty( const std::string& name, std::string value ) {
+ if ( name == "padding" ) {
+ value = String::toLower( String::trim( value ) );
+ Rectf rect( NodeAttribute( name, value ).asRectf() );
+ mProperties[ "paddingleft" ] = StyleSheetProperty( "paddingleft", String::toStr( rect.Left ) );
+ mProperties[ "paddingright" ] = StyleSheetProperty( "paddingright", String::toStr( rect.Right ) );
+ mProperties[ "paddingtop" ] = StyleSheetProperty( "paddingtop", String::toStr( rect.Top ) );
+ mProperties[ "paddingbottom" ] = StyleSheetProperty( "paddingbottom", String::toStr( rect.Bottom ) );
+ } else if ( name == "layout_margin" ) {
+ value = String::toLower( String::trim( value ) );
+ Rect rect( NodeAttribute( name, value ).asRect() );
+ mProperties[ "layout_marginleft" ] = StyleSheetProperty( "layout_marginleft", String::toStr( rect.Left ) );
+ mProperties[ "layout_marginright" ] = StyleSheetProperty( "layout_marginright", String::toStr( rect.Right ) );
+ mProperties[ "layout_margintop" ] = StyleSheetProperty( "layout_margintop", String::toStr( rect.Top ) );
+ mProperties[ "layout_marginbottom" ] = StyleSheetProperty( "layout_marginbottom", String::toStr( rect.Bottom ) );
+ } else {
+ mProperties[ name ] = StyleSheetProperty( name, value );
+ }
+}
+
}}}
+
diff --git a/src/eepp/ui/css/stylesheetproperty.cpp b/src/eepp/ui/css/stylesheetproperty.cpp
index c66e8402a..95f7e2e4e 100644
--- a/src/eepp/ui/css/stylesheetproperty.cpp
+++ b/src/eepp/ui/css/stylesheetproperty.cpp
@@ -12,13 +12,15 @@ StyleSheetProperty::StyleSheetProperty()
StyleSheetProperty::StyleSheetProperty( const std::string& name, const std::string& value ) :
mName( String::toLower( String::trim( name ) ) ),
- mValue( String::trim( value ) )
+ mValue( String::trim( value ) ),
+ mSpecificity( 0 )
{}
-StyleSheetProperty::StyleSheetProperty( const std::string & name, const std::string& value, const Uint32 & specificity ) :
+StyleSheetProperty::StyleSheetProperty( const std::string & name, const std::string& value, const Uint32 & specificity, const bool& isVolatile ) :
mName( String::toLower( String::trim( name ) ) ),
mValue( String::trim( value ) ),
- mSpecificity( specificity )
+ mSpecificity( specificity ),
+ mVolatile( isVolatile )
{}
const std::string &StyleSheetProperty::getName() const {
@@ -49,4 +51,12 @@ void StyleSheetProperty::setValue( const std::string& value ) {
mValue = value;
}
+const bool &StyleSheetProperty::isVolatile() const {
+ return mVolatile;
+}
+
+void StyleSheetProperty::setVolatile( const bool & isVolatile ) {
+ mVolatile = isVolatile;
+}
+
}}}
diff --git a/src/eepp/ui/css/stylesheetselector.cpp b/src/eepp/ui/css/stylesheetselector.cpp
index ad653d3fb..95585b6a8 100644
--- a/src/eepp/ui/css/stylesheetselector.cpp
+++ b/src/eepp/ui/css/stylesheetselector.cpp
@@ -4,9 +4,12 @@
namespace EE { namespace UI { namespace CSS {
StyleSheetSelector::StyleSheetSelector() :
+ mName( "*" ),
mSpecificity(0),
mCacheable(true)
-{}
+{
+ parseSelector( mName );
+}
StyleSheetSelector::StyleSheetSelector( const std::string& selectorName ) :
mName( String::toLower( selectorName ) ),
@@ -22,13 +25,14 @@ const std::string &StyleSheetSelector::getName() const {
const std::string& StyleSheetSelector::getPseudoClass() const {
return mPseudoClass;
-};
+}
const Uint32& StyleSheetSelector::getSpecificity() const {
return mSpecificity;
}
void removeExtraSpaces( std::string& string ) {
+ // @TODO: Optimize this
string = String::trim( string );
String::replaceAll( string, " ", " " );
String::replaceAll( string, " ", " " );
@@ -105,6 +109,14 @@ const bool &StyleSheetSelector::isCacheable() const {
return mCacheable;
}
+bool StyleSheetSelector::hasPseudoClass( const std::string& cls ) const {
+ return mSelectorRules.empty() ? false : ( cls.empty() ? true : mSelectorRules[0].hasPseudoClass( cls ) );
+}
+
+bool StyleSheetSelector::hasPseudoClasses() const {
+ return mSelectorRules.empty() || mSelectorRules[0].hasPseudoClasses();
+}
+
bool StyleSheetSelector::select( StyleSheetElement * element, const bool& applyPseudo ) const {
if ( mSelectorRules.empty() )
return false;
@@ -194,4 +206,113 @@ bool StyleSheetSelector::select( StyleSheetElement * element, const bool& applyP
return true;
}
+std::vector StyleSheetSelector::getRelatedElements( StyleSheetElement * element, const bool& applyPseudo ) const {
+ static std::vector EMPTY_ELEMENTS;
+ std::vector elements;
+ if ( mSelectorRules.empty() )
+ return elements;
+
+ StyleSheetElement * curElement = element;
+
+ for ( size_t i = 0; i < mSelectorRules.size(); i++ ) {
+ const StyleSheetSelectorRule& selectorRule = mSelectorRules[i];
+
+ switch ( selectorRule.getPatternMatch() ) {
+ case StyleSheetSelectorRule::ANY:
+ {
+ if ( !selectorRule.matches( curElement, applyPseudo ) )
+ return EMPTY_ELEMENTS;
+
+ break; // continue evaluating
+ }
+ case StyleSheetSelectorRule::DESCENDANT:
+ {
+ bool foundDescendant = false;
+
+ curElement = curElement->getStyleSheetParentElement();
+
+ while ( NULL != curElement && !foundDescendant ) {
+ if ( selectorRule.matches( curElement, applyPseudo ) ) {
+ foundDescendant = true;
+ } else {
+ curElement = curElement->getStyleSheetParentElement();
+ }
+ }
+
+ if ( !foundDescendant )
+ return EMPTY_ELEMENTS;
+
+ if ( 0 != i && ( selectorRule.hasPseudoClasses() || selectorRule.hasStructuralPseudoClasses() ) ) {
+ elements.push_back( curElement );
+ }
+
+ break; // continue evaluating
+ }
+ case StyleSheetSelectorRule::CHILD:
+ {
+ curElement = curElement->getStyleSheetParentElement();
+
+ if ( NULL == curElement || !selectorRule.matches( curElement, applyPseudo ) )
+ return EMPTY_ELEMENTS;
+
+ if ( 0 != i && ( selectorRule.hasPseudoClasses() || selectorRule.hasStructuralPseudoClasses() ) ) {
+ elements.push_back( curElement );
+ }
+
+ break; // continue evaluating
+ }
+ case StyleSheetSelectorRule::DIRECT_SIBLING:
+ {
+ curElement = curElement->getStyleSheetPreviousSiblingElement();
+
+ if ( NULL == curElement || !selectorRule.matches( curElement, applyPseudo ) )
+ return EMPTY_ELEMENTS;
+
+ if ( 0 != i && ( selectorRule.hasPseudoClasses() || selectorRule.hasStructuralPseudoClasses() ) ) {
+ elements.push_back( curElement );
+ }
+
+ break; // continue evaluating
+ }
+ case StyleSheetSelectorRule::SIBLING:
+ {
+ bool foundSibling = false;
+ StyleSheetElement * prevSibling = curElement->getStyleSheetPreviousSiblingElement();
+ StyleSheetElement * nextSibling = curElement->getStyleSheetNextSiblingElement();
+
+ while ( NULL != prevSibling && !foundSibling ) {
+ if ( selectorRule.matches( prevSibling, applyPseudo ) ) {
+ foundSibling = true;
+ curElement = prevSibling;
+ } else {
+ prevSibling = prevSibling->getStyleSheetPreviousSiblingElement();
+ }
+ }
+
+ if ( !foundSibling ) {
+ while ( NULL != nextSibling && !foundSibling ) {
+ if ( selectorRule.matches( nextSibling, applyPseudo ) ) {
+ foundSibling = true;
+ curElement = nextSibling;
+ } else {
+ nextSibling = nextSibling->getStyleSheetNextSiblingElement();
+ }
+ }
+ }
+
+ if ( !foundSibling )
+ return EMPTY_ELEMENTS;
+
+ if ( 0 != i && ( selectorRule.hasPseudoClasses() || selectorRule.hasStructuralPseudoClasses() ) ) {
+ elements.push_back( curElement );
+ }
+
+ break; // continue evaluating
+ }
+ }
+ }
+
+ return elements;
+}
+
}}}
diff --git a/src/eepp/ui/css/stylesheetselectorparser.cpp b/src/eepp/ui/css/stylesheetselectorparser.cpp
index 5b222d53e..da5db7e8a 100644
--- a/src/eepp/ui/css/stylesheetselectorparser.cpp
+++ b/src/eepp/ui/css/stylesheetselectorparser.cpp
@@ -4,12 +4,10 @@ namespace EE { namespace UI { namespace CSS {
StyleSheetSelectorParser::StyleSheetSelectorParser(){}
-StyleSheetSelectorParser::StyleSheetSelectorParser( std::string name )
-{
+StyleSheetSelectorParser::StyleSheetSelectorParser( std::string name ) {
std::vector sels = String::split( name, ',' );
- for ( auto it = sels.begin(); it != sels.end(); ++it )
- {
+ for ( auto it = sels.begin(); it != sels.end(); ++it ) {
std::string cur = String::trim( *it );
String::replaceAll( cur, "\n", "" );
String::replaceAll( cur, "\t", "" );
diff --git a/src/eepp/ui/css/stylesheetselectorrule.cpp b/src/eepp/ui/css/stylesheetselectorrule.cpp
index a5baf5330..0a63392ef 100644
--- a/src/eepp/ui/css/stylesheetselectorrule.cpp
+++ b/src/eepp/ui/css/stylesheetselectorrule.cpp
@@ -242,8 +242,8 @@ bool StyleSheetSelectorRule::matches( StyleSheetElement * element, const bool& a
if ( !mClasses.empty() && !element->getStyleSheetClasses().empty() ) {
bool hasClasses = true;
- for ( auto cit = element->getStyleSheetClasses().begin(); cit != element->getStyleSheetClasses().end(); ++cit ) {
- if ( !hasClass( *cit ) ) {
+ for ( const auto& cls : element->getStyleSheetClasses() ) {
+ if ( !hasClass( cls ) ) {
hasClasses = false;
break;
}
@@ -255,14 +255,12 @@ bool StyleSheetSelectorRule::matches( StyleSheetElement * element, const bool& a
}
if ( applyPseudo ) {
- if ( mPseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) {
- flags |= PseudoClass;
- } else if ( !mPseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) {
+ if ( !mPseudoClasses.empty() && !element->getStyleSheetPseudoClasses().empty() ) {
bool hasPseudoClasses = false;
const std::vector& elPseudoClasses = element->getStyleSheetPseudoClasses();
- for ( auto cit = elPseudoClasses.begin(); cit != elPseudoClasses.end(); ++cit ) {
- if ( hasPseudoClass( *cit ) ) {
+ for ( const auto& cls : elPseudoClasses ) {
+ if ( hasPseudoClass( cls ) ) {
hasPseudoClasses = true;
break;
}
diff --git a/src/eepp/ui/css/stylesheetstyle.cpp b/src/eepp/ui/css/stylesheetstyle.cpp
index ddf070c78..5db6fd7f7 100644
--- a/src/eepp/ui/css/stylesheetstyle.cpp
+++ b/src/eepp/ui/css/stylesheetstyle.cpp
@@ -1,5 +1,4 @@
#include
-#include
namespace EE { namespace UI { namespace CSS {
@@ -10,32 +9,53 @@ StyleSheetStyle::StyleSheetStyle( const std::string& selector, const StyleSheetP
mSelector( selector ),
mProperties( properties )
{
- for ( auto it = mProperties.begin(); it != mProperties.end(); ++it )
- it->second.setSpecificity( mSelector.getSpecificity() );
+ for ( auto& it : mProperties ) {
+ it.second.setSpecificity( mSelector.getSpecificity() );
+ it.second.setVolatile( !mSelector.isCacheable() );
+ }
}
-void StyleSheetStyle::print() {
- std::cout << mSelector.getName() << " {" << std::endl;
+std::string StyleSheetStyle::build() {
+ std::string css;
- for ( StyleSheetProperties::iterator it = mProperties.begin(); it != mProperties.end(); ++it ) {
- StyleSheetProperty& prop = it->second;
+ css += mSelector.getName() + " {";
- std::cout << "\t" << prop.getName() << ": " << prop.getValue() << ";" << std::endl;
+
+ for ( auto& it : mProperties ) {
+ StyleSheetProperty& prop = it.second;
+
+ css += "\t" + prop.getName() + ": " + prop.getValue() + ";\n";
}
- std::cout << "}" << std::endl;
+ css += "}\n";
+
+ return css;
}
-const StyleSheetSelector &StyleSheetStyle::getSelector() const {
+
+const StyleSheetSelector& StyleSheetStyle::getSelector() const {
return mSelector;
}
-const StyleSheetProperties &StyleSheetStyle::getProperties() const {
+const StyleSheetProperties& StyleSheetStyle::getProperties() const {
return mProperties;
}
+StyleSheetProperty StyleSheetStyle::getPropertyByName( const std::string& name ) const {
+ auto it = mProperties.find( name );
+
+ if ( it != mProperties.end() )
+ return it->second;
+
+ return StyleSheetProperty();
+}
+
void StyleSheetStyle::setProperty( const StyleSheetProperty & property ) {
mProperties[ property.getName() ] = property;
}
+void StyleSheetStyle::clearProperties() {
+ mProperties.clear();
+}
+
}}}
diff --git a/src/eepp/ui/uicombobox.cpp b/src/eepp/ui/uicombobox.cpp
index 1f5b64ff4..2344dd048 100644
--- a/src/eepp/ui/uicombobox.cpp
+++ b/src/eepp/ui/uicombobox.cpp
@@ -37,6 +37,9 @@ void UIComboBox::setTheme( UITheme * Theme ) {
mDropDownList->setEnabled( true );
mDropDownList->setAllowEditing( true );
mDropDownList->getInputTextBuffer()->setFreeEditing( true );
+ mDropDownList->addEventListener( Event::OnPaddingChange, [this](const Event*) {
+ this->onPaddingChange();
+ });
}
if ( NULL == mButton ) {
@@ -84,6 +87,8 @@ void UIComboBox::loadFromXmlNode(const pugi::xml_node& node) {
mDropDownList->loadFromXmlNode( node );
endAttributesTransaction();
+
+ updateControls();
}
Uint32 UIComboBox::onMessage( const NodeMessage * Msg ) {
@@ -109,19 +114,26 @@ void UIComboBox::updateControls() {
}
void UIComboBox::onSizeChange() {
- UIWidget::onSizeChange();
-
updateControls();
+
+ UIWidget::onSizeChange();
}
void UIComboBox::onPositionChange() {
- UIWidget::onPositionChange();
-
updateControls();
+
+ UIWidget::onPositionChange();
+}
+
+void UIComboBox::onPaddingChange() {
+ updateControls();
+
+ UIWidget::onPaddingChange();
}
void UIComboBox::onAutoSize() {
- setInternalHeight( mDropDownList->getSkinSize().getHeight() + mDropDownList->getPadding().Top + mDropDownList->getPadding().Bottom );
+ if ( NULL != mDropDownList )
+ setInternalHeight( mDropDownList->getSkinSize().getHeight() + mDropDownList->getPadding().Top + mDropDownList->getPadding().Bottom );
}
}}
diff --git a/src/eepp/ui/uidropdownlist.cpp b/src/eepp/ui/uidropdownlist.cpp
index fb92c0e57..8fa488d26 100644
--- a/src/eepp/ui/uidropdownlist.cpp
+++ b/src/eepp/ui/uidropdownlist.cpp
@@ -58,9 +58,9 @@ void UIDropDownList::setTheme( UITheme * Theme ) {
}
void UIDropDownList::onSizeChange() {
- UIWidget::onSizeChange();
-
onAutoSize();
+
+ UIWidget::onSizeChange();
}
void UIDropDownList::onThemeLoaded() {
diff --git a/src/eepp/ui/uilinearlayout.cpp b/src/eepp/ui/uilinearlayout.cpp
index 6c2e6ce55..c3e719431 100644
--- a/src/eepp/ui/uilinearlayout.cpp
+++ b/src/eepp/ui/uilinearlayout.cpp
@@ -97,7 +97,7 @@ void UILinearLayout::packVertical() {
{
int w = mDpSize.getWidth() - widget->getLayoutMargin().Left - widget->getLayoutMargin().Right - mPadding.Left - mPadding.Right;
- if ( widget->getSize().getWidth() != w )
+ if ( (int)widget->getSize().getWidth() != w )
widget->setSize( w, widget->getSize().getHeight() );
break;
@@ -166,14 +166,14 @@ void UILinearLayout::packVertical() {
if ( getLayoutHeightRules() == WRAP_CONTENT ) {
curY += mPadding.Bottom;
- if ( curY != mDpSize.getHeight() ) {
+ if ( curY != (int)mDpSize.getHeight() ) {
setInternalHeight( curY );
notifyLayoutAttrChangeParent();
}
} else if ( getLayoutHeightRules() == MATCH_PARENT ) {
int h = getParent()->getSize().getHeight() - mLayoutMargin.Top - mLayoutMargin.Bottom;
- if ( h != mDpSize.getHeight() )
+ if ( h != (int)mDpSize.getHeight() )
setInternalHeight( h );
}
@@ -215,7 +215,7 @@ void UILinearLayout::packHorizontal() {
{
int h = mDpSize.getHeight() - widget->getLayoutMargin().Top - widget->getLayoutMargin().Bottom - mPadding.Top - mPadding.Bottom;
- if ( h != widget->getSize().getHeight() )
+ if ( h != (int)widget->getSize().getHeight() )
widget->setSize( widget->getSize().getWidth(), h );
break;
@@ -284,14 +284,14 @@ void UILinearLayout::packHorizontal() {
if ( getLayoutWidthRules() == WRAP_CONTENT ) {
curX += mPadding.Right;
- if ( curX != mDpSize.getWidth() ) {
+ if ( curX != (int)mDpSize.getWidth() ) {
setInternalWidth( curX );
notifyLayoutAttrChangeParent();
}
} else if ( getLayoutWidthRules() == MATCH_PARENT ) {
int w = getParent()->getSize().getWidth() - mLayoutMargin.Left - mLayoutMargin.Right;
- if ( w != mDpSize.getWidth() )
+ if ( w != (int)mDpSize.getWidth() )
setInternalWidth( w );
}
diff --git a/src/eepp/ui/uinode.cpp b/src/eepp/ui/uinode.cpp
index a4240ebd8..0a28b34c3 100644
--- a/src/eepp/ui/uinode.cpp
+++ b/src/eepp/ui/uinode.cpp
@@ -36,7 +36,8 @@ UINode::UINode() :
mBackgroundState( NULL ),
mForegroundState( NULL ),
mBorder( NULL ),
- mDragButton( EE_BUTTON_LMASK )
+ mDragButton( EE_BUTTON_LMASK ),
+ mSkinColor( Color::White )
{
mNodeFlags |= NODE_FLAG_UINODE | NODE_FLAG_OVER_FIND_ALLOWED;
@@ -56,6 +57,9 @@ UINode::~UINode() {
eeSAFE_DELETE( mBackgroundState );
eeSAFE_DELETE( mForegroundState );
eeSAFE_DELETE( mBorder );
+
+ if ( isDragging() )
+ getEventDispatcher()->setNodeDragging( NULL );
}
void UINode::worldToNodeTranslation( Vector2f& Pos ) const {
@@ -258,6 +262,8 @@ void UINode::drawBox() {
void UINode::drawSkin() {
if ( NULL != mSkinState ) {
+ mSkinState->setStateColor( mSkinState->getCurrentState(), mSkinColor );
+
if ( mFlags & UI_SKIN_KEEP_SIZE_ON_DRAW ) {
Sizef rSize = PixelDensity::dpToPx( getSkinSize( getSkin(), mSkinState->getCurrentState() ) );
Sizef diff = ( mSize - rSize ) * 0.5f;
@@ -390,88 +396,59 @@ UISkin * UINode::setBackgroundFillEnabled( bool enabled ) {
return NULL != mBackgroundState ? mBackgroundState->getSkin() : NULL;
}
-UINode * UINode::setBackgroundDrawable( const Uint32& state, Drawable * drawable, bool ownIt ) {
- setBackgroundFillEnabled( true )->setStateDrawable( state, drawable, ownIt );
+UINode * UINode::setBackgroundDrawable( Drawable * drawable, bool ownIt ) {
+ setBackgroundFillEnabled( true )->setStateDrawable( UIState::StateFlagNormal, drawable, ownIt );
return this;
}
-UINode * UINode::setBackgroundDrawable( Drawable * drawable, bool ownIt ) {
- return setBackgroundDrawable( UIState::StateFlagNormal, drawable, ownIt );
-}
-
-UINode * UINode::setBackgroundColor( const Uint32 & state, const Color& color ) {
+UINode * UINode::setBackgroundColor( const Color& color ) {
UISkin * background = setBackgroundFillEnabled( true );
- Drawable * stateDrawable = background->getStateDrawable( state );
+ Drawable * stateDrawable = background->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable )
- setBackgroundDrawable( state, RectangleDrawable::New(), true );
+ setBackgroundDrawable( RectangleDrawable::New(), true );
if ( NULL != mBackgroundState )
- mBackgroundState->setStateColor( state, color );
+ mBackgroundState->setStateColor( UIState::StateFlagNormal, color );
return this;
}
Color UINode::getBackgroundColor() const {
- return getBackgroundColor( mState );
-}
-
-Color UINode::getBackgroundColor( const Uint32 & state ) const {
if ( NULL != mBackgroundState )
- return mBackgroundState->getStateColor( state );
+ return mBackgroundState->getStateColor( UIState::StateFlagNormal );
- return Color::White;
+ return Color::Transparent;
}
-UINode * UINode::setBackgroundColor( const Color& color ) {
- return setBackgroundColor( UIState::StateFlagNormal, color );
-}
+UINode * UINode::setBorderRadius( const unsigned int& corners ) {
+ setBorderEnabled( true )->setCorners( corners );
-UINode * UINode::setBorderRadius( const Uint32 & state, const unsigned int& corners ) {
UISkin * background = setBackgroundFillEnabled( true );
- Drawable * stateDrawable = background->getStateDrawable( state );
+ Drawable * stateDrawable = background->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable ) {
- setBackgroundColor( state, Color::Black );
+ setBackgroundColor( Color::Transparent );
- stateDrawable = background->getStateDrawable( state );
+ stateDrawable = background->getStateDrawable( UIState::StateFlagNormal );
}
if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) {
- RectangleDrawable * rectangleDrawable = static_cast( stateDrawable );
-
- rectangleDrawable->setCorners( corners );
+ static_cast( stateDrawable )->setCorners( corners );
}
return this;
}
-Uint32 UINode::getBorderRadius( const Uint32& state ) const {
- if ( NULL != mBackgroundState && NULL != mBackgroundState->getSkin() ) {
- Drawable * stateDrawable = mBackgroundState->getSkin()->getStateDrawable( state );
-
- if ( NULL != stateDrawable ) {
- if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) {
- RectangleDrawable * rectangleDrawable = static_cast( stateDrawable );
-
- return rectangleDrawable->getCorners();
- }
- }
- }
+Uint32 UINode::getBorderRadius() const {
+ if ( NULL != mBorder )
+ return mBorder->getCorners();
return 0;
}
-Uint32 UINode::getBorderRadius() const {
- return getBorderRadius( UIState::StateFlagNormal );
-}
-
-UINode * UINode::setBorderRadius( const unsigned int& corners ) {
- return setBorderRadius( UIState::StateFlagNormal, corners );
-}
-
UISkin * UINode::setForegroundFillEnabled( bool enabled ) {
writeFlag( UI_FILL_FOREGROUND, enabled ? 1 : 0 );
@@ -484,53 +461,41 @@ UISkin * UINode::setForegroundFillEnabled( bool enabled ) {
return NULL != mForegroundState ? mForegroundState->getSkin() : NULL;
}
-UINode * UINode::setForegroundDrawable( const Uint32 & state, Drawable * drawable, bool ownIt ) {
- setForegroundFillEnabled( true )->setStateDrawable( state, drawable, ownIt );
- return this;
-}
-
UINode * UINode::setForegroundDrawable( Drawable * drawable, bool ownIt ) {
- return setForegroundDrawable( UIState::StateFlagNormal, drawable, ownIt );
+ setForegroundFillEnabled( true )->setStateDrawable( UIState::StateFlagNormal, drawable, ownIt );
+ return this;
}
Color UINode::getForegroundColor() const {
- return getForegroundColor( mState );
-}
-
-Color UINode::getForegroundColor( const Uint32 & state ) const {
if ( NULL != mForegroundState )
- return mForegroundState->getStateColor( state );
+ return mForegroundState->getStateColor( UIState::StateFlagNormal );
- return Color::White;
+ return Color::Transparent;
}
-UINode * UINode::setForegroundColor( const Uint32 & state, const Color& color ) {
+UINode * UINode::setForegroundColor( const Color& color ) {
UISkin * foreground = setForegroundFillEnabled( true );
- Drawable * stateDrawable = foreground->getStateDrawable( state );
+ Drawable * stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable )
- setForegroundDrawable( state, RectangleDrawable::New(), true );
+ setForegroundDrawable( RectangleDrawable::New(), true );
if ( NULL != mForegroundState )
- mForegroundState->setStateColor( state, color );
+ mForegroundState->setStateColor( UIState::StateFlagNormal, color );
return this;
}
-UINode * UINode::setForegroundColor( const Color& color ) {
- return setForegroundColor( UIState::StateFlagNormal, color );
-}
-
-UINode * UINode::setForegroundRadius( const Uint32& state, const unsigned int& corners ) {
+UINode * UINode::setForegroundRadius( const unsigned int& corners ) {
UISkin * foreground = setForegroundFillEnabled( true );
- Drawable * stateDrawable = foreground->getStateDrawable( state );
+ Drawable * stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal );
if ( NULL == stateDrawable ) {
- setForegroundColor( state, Color::Black );
+ setForegroundColor( Color::Black );
- stateDrawable = foreground->getStateDrawable( state );
+ stateDrawable = foreground->getStateDrawable( UIState::StateFlagNormal );
}
if ( stateDrawable->getDrawableType() == Drawable::RECTANGLE ) {
@@ -542,8 +507,18 @@ UINode * UINode::setForegroundRadius( const Uint32& state, const unsigned int& c
return this;
}
-UINode * UINode::setForegroundRadius( const unsigned int& corners ) {
- return setForegroundRadius( UIState::StateFlagNormal, corners );
+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( stateDrawable );
+
+ return rectangleDrawable->getCorners();
+ }
+ }
+
+ return 0;
}
RectangleDrawable * UINode::setBorderEnabled( bool enabled ) {
@@ -576,6 +551,10 @@ UINode * UINode::setBorderWidth( const unsigned int& width ) {
return this;
}
+Float UINode::getBorderWidth() const {
+ return NULL != mBorder ? mBorder->getLineWidth() : 1.f;
+}
+
const Uint32& UINode::getFlags() const {
return mFlags;
}
@@ -610,7 +589,7 @@ UINode * UINode::unsetFlags(const Uint32 & flags) {
return this;
}
-UINode *UINode::resetFlags( Uint32 newFlags ) {
+UINode * UINode::resetFlags( Uint32 newFlags ) {
mFlags = newFlags;
return this;
}
@@ -629,18 +608,8 @@ void UINode::drawForeground() {
void UINode::drawBorder() {
if ( ( mFlags & UI_BORDER ) && NULL != mBorder ) {
- if ( NULL != mBorder && NULL != mBackgroundState && NULL != mBackgroundState->getSkin() ) {
- Drawable * backDrawable = mBackgroundState->getSkin()->getStateDrawable( mBackgroundState->getCurrentState() );
-
- if ( NULL != backDrawable && backDrawable->getDrawableType() == Drawable::RECTANGLE ) {
- RectangleDrawable * backgroundDrawable = static_cast( backDrawable );
-
- getBorder()->setCorners( backgroundDrawable->getCorners() );
- }
- }
-
Uint8 alpha = mBorder->getAlpha();
- mBorder->setAlpha( eemax( mAlpha * alpha / 255.f, 255 ) );
+ mBorder->setAlpha( eemin( mAlpha * alpha / 255.f, 255 ) );
mBorder->draw( Vector2f( mScreenPosi.x, mScreenPosi.y ), Sizef( eefloor(mSize.getWidth()), eefloor(mSize.getHeight()) ) );
mBorder->setAlpha( alpha );
}
@@ -694,6 +663,7 @@ UISkin * UINode::getForeground() {
RectangleDrawable * UINode::getBorder() {
if ( NULL == mBorder ) {
mBorder = RectangleDrawable::New();
+ mBorder->setColor( Color::Transparent );
mBorder->setFillMode( PrimitiveFillMode::DRAW_LINE );
mBorder->setLineWidth( PixelDensity::dpToPx(1) );
}
@@ -757,26 +727,13 @@ UINode * UINode::setSkin( UISkin * skin ) {
return this;
}
-UINode * UINode::setSkinColor( const Uint32& state, const Color& color ) {
- if ( NULL != mSkinState )
- mSkinState->setStateColor( state, color );
-
+UINode * UINode::setSkinColor( const Color& color ) {
+ mSkinColor = color;
return this;
}
-UINode * UINode::setSkinColor( const Color& color ) {
- return setSkinColor( UIState::StateFlagNormal, color );
-}
-
-Color UINode::getSkinColor( const Uint32& state ) const {
- if ( NULL != mSkinState )
- return mSkinState->getStateColor( state );
-
- return Color::White;
-}
-
-Color UINode::getSkinColor() const {
- return getSkinColor( UIState::StateFlagNormal );
+const Color& UINode::getSkinColor() const {
+ return mSkinColor;
}
void UINode::removeSkin() {
diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp
index cc454ee3c..b258db4db 100644
--- a/src/eepp/ui/uiscenenode.cpp
+++ b/src/eepp/ui/uiscenenode.cpp
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include
namespace EE { namespace UI {
@@ -29,7 +30,7 @@ UISceneNode::UISceneNode( EE::Window::Window * window ) :
}
void UISceneNode::resizeControl( EE::Window::Window * ) {
- setSize( (Float)mWindow->getWidth() / PixelDensity::getPixelDensity(), (Float)mWindow->getHeight() / PixelDensity::getPixelDensity() );
+ setSize( eefloor( mWindow->getWidth() / PixelDensity::getPixelDensity() ), eefloor(mWindow->getHeight() / PixelDensity::getPixelDensity()) );
sendMsg( this, NodeMessage::WindowResize );
}
@@ -123,12 +124,26 @@ void UISceneNode::setStyleSheet( const CSS::StyleSheet& styleSheet ) {
reloadStyle();
}
-void UISceneNode::combineStyleSheet(const CSS::StyleSheet & styleSheet) {
+void UISceneNode::setStyleSheet( const std::string& inlineStyleSheet ) {
+ CSS::StyleSheetParser parser;
+
+ if ( parser.loadFromString( inlineStyleSheet ) )
+ setStyleSheet( parser.getStyleSheet() );
+}
+
+void UISceneNode::combineStyleSheet( const CSS::StyleSheet& styleSheet ) {
mStyleSheet.combineStyleSheet( styleSheet );
reloadStyle();
}
+void UISceneNode::combineStyleSheet( const std::string& inlineStyleSheet ) {
+ CSS::StyleSheetParser parser;
+
+ if ( parser.loadFromString( inlineStyleSheet ) )
+ combineStyleSheet( parser.getStyleSheet() );
+}
+
CSS::StyleSheet& UISceneNode::getStyleSheet() {
return mStyleSheet;
}
diff --git a/src/eepp/ui/uiscrollview.cpp b/src/eepp/ui/uiscrollview.cpp
index ab8ac9bc5..15598d19d 100644
--- a/src/eepp/ui/uiscrollview.cpp
+++ b/src/eepp/ui/uiscrollview.cpp
@@ -15,7 +15,7 @@ UIScrollView::UIScrollView() :
mHScrollMode( UI_SCROLLBAR_AUTO ),
mVScroll( UIScrollBar::NewVertical() ),
mHScroll( UIScrollBar::NewHorizontal() ),
- mContainer( UINode::New() ),
+ mContainer( UIWidget::NewWithTag( "scrollview::container" ) ),
mScrollView( NULL ),
mSizeChangeCb( 0 )
{
@@ -131,7 +131,7 @@ UIScrollBar * UIScrollView::getHorizontalScrollBar() const {
return mHScroll;
}
-UINode * UIScrollView::getContainer() const {
+UIWidget * UIScrollView::getContainer() const {
return mContainer;
}
diff --git a/src/eepp/ui/uistate.cpp b/src/eepp/ui/uistate.cpp
index ba4fd9737..f80dcdb3b 100644
--- a/src/eepp/ui/uistate.cpp
+++ b/src/eepp/ui/uistate.cpp
@@ -39,6 +39,16 @@ int UIState::getStateNumber( const std::string& State ) {
return -1;
}
+const char * UIState::getStateNameFromStateFlag( const Uint32& stateFlag ) {
+ for ( int i = 0; i < UIState::StateCount; i++ ) {
+ if ( stateFlag == UIStateFlags[i] ) {
+ return UIStatesNames[i];
+ }
+ }
+
+ return NULL;
+}
+
const Uint32& UIState::getStateFlag( const Uint32& stateIndex ) {
return UIStateFlags[ stateIndex ];
}
diff --git a/src/eepp/ui/uistyle.cpp b/src/eepp/ui/uistyle.cpp
index f09645e6b..6730ba65c 100644
--- a/src/eepp/ui/uistyle.cpp
+++ b/src/eepp/ui/uistyle.cpp
@@ -8,7 +8,7 @@ using namespace EE::UI::CSS;
namespace EE { namespace UI {
-UIStyle * EE::UI::UIStyle::New( UIWidget * widget ) {
+UIStyle * UIStyle::New( UIWidget * widget ) {
return eeNew( UIStyle, ( widget ) );
}
@@ -18,42 +18,38 @@ UIStyle::UIStyle( UIWidget * widget ) :
load();
}
-UIStyle::~UIStyle()
-{}
-
-bool UIStyle::stateExists( const EE::Uint32 & state ) const {
- return mStates.find( state ) != mStates.end();
+UIStyle::~UIStyle() {
+ removeRelatedWidgets();
+ unsubscribeNonCacheableStyles();
}
-void UIStyle::addStyleSheetProperty( const Uint32& state, const StyleSheetProperty& attribute ) {
+bool UIStyle::stateExists( const EE::Uint32& ) const {
+ return true;
+}
+
+void UIStyle::setStyleSheetProperty( const StyleSheetProperty& attribute ) {
if ( attribute.getName() == "padding" ) {
Rectf rect( NodeAttribute( attribute.getName(), attribute.getValue() ).asRectf() );
- mStates[ state ][ "paddingleft" ] = StyleSheetProperty( "paddingleft", String::toStr( rect.Left ), attribute.getSpecificity() );
- mStates[ state ][ "paddingright" ] = StyleSheetProperty( "paddingright", String::toStr( rect.Right ), attribute.getSpecificity() );
- mStates[ state ][ "paddingtop" ] = StyleSheetProperty( "paddingtop", String::toStr( rect.Top ), attribute.getSpecificity() );
- mStates[ state ][ "paddingbottom" ] = StyleSheetProperty( "paddingbottom", String::toStr( rect.Bottom ), attribute.getSpecificity() );
+ mElementStyle.setProperty( StyleSheetProperty( "paddingleft", String::toStr( rect.Left ), attribute.getSpecificity(), attribute.isVolatile() ) );
+ mElementStyle.setProperty( StyleSheetProperty( "paddingright", String::toStr( rect.Right ), attribute.getSpecificity(), attribute.isVolatile() ) );
+ mElementStyle.setProperty( StyleSheetProperty( "paddingtop", String::toStr( rect.Top ), attribute.getSpecificity(), attribute.isVolatile() ) );
+ mElementStyle.setProperty( StyleSheetProperty( "paddingbottom", String::toStr( rect.Bottom ), attribute.getSpecificity(), attribute.isVolatile() ) );
} else if ( attribute.getName() == "layout_margin" ) {
Rect rect( NodeAttribute( attribute.getName(), attribute.getValue() ).asRect() );
- mStates[ state ][ "layout_marginleft" ] = StyleSheetProperty( "layout_marginleft", String::toStr( rect.Left ), attribute.getSpecificity() );
- mStates[ state ][ "layout_marginright" ] = StyleSheetProperty( "layout_marginright", String::toStr( rect.Right ), attribute.getSpecificity() );
- mStates[ state ][ "layout_margintop" ] = StyleSheetProperty( "layout_margintop", String::toStr( rect.Top ), attribute.getSpecificity() );
- mStates[ state ][ "layout_marginbottom" ] = StyleSheetProperty( "layout_marginbottom", String::toStr( rect.Bottom ), attribute.getSpecificity() );
+ mElementStyle.setProperty( StyleSheetProperty( "layout_marginleft", String::toStr( rect.Left ), attribute.getSpecificity(), attribute.isVolatile() ) );
+ mElementStyle.setProperty( StyleSheetProperty( "layout_marginright", String::toStr( rect.Right ), attribute.getSpecificity(), attribute.isVolatile() ) );
+ mElementStyle.setProperty( StyleSheetProperty( "layout_margintop", String::toStr( rect.Top ), attribute.getSpecificity(), attribute.isVolatile() ) );
+ mElementStyle.setProperty( StyleSheetProperty( "layout_marginbottom", String::toStr( rect.Bottom ), attribute.getSpecificity(), attribute.isVolatile() ) );
} else {
- mStates[ state ][ attribute.getName() ] = attribute;
- }
-
- if ( String::startsWith( attribute.getName(), "transition" ) ) {
- mTransitionAttributes[ state ].push_back( attribute );
-
- parseTransitions( state );
+ mElementStyle.setProperty( attribute );
}
}
void UIStyle::load() {
- mStates.clear();
+ unsubscribeNonCacheableStyles();
+
+ mCacheableStyles.clear();
mNoncacheableStyles.clear();
- mTransitions.clear();
- mTransitionAttributes.clear();
UISceneNode * uiSceneNode = mWidget->getSceneNode()->isUISceneNode() ? static_cast( mWidget->getSceneNode() ) : NULL;
@@ -61,165 +57,140 @@ void UIStyle::load() {
CSS::StyleSheet& styleSheet = uiSceneNode->getStyleSheet();
if ( !styleSheet.isEmpty() ) {
- CSS::StyleSheet::StyleSheetPseudoClassProperties propertiesByPseudoClass = styleSheet.getElementPropertiesByState( mWidget );
+ StyleSheetStyleVector styles = styleSheet.getElementStyles( mWidget );
- if ( !propertiesByPseudoClass.empty() ) {
- Uint32 stateFlag;
+ for ( auto& style : styles ) {
+ const StyleSheetSelector& selector = style.getSelector();
- for ( auto it = propertiesByPseudoClass.begin(); it != propertiesByPseudoClass.end(); ++it ) {
- stateFlag = getStateFlagFromName( it->first );
-
- if ( eeINDEX_NOT_FOUND != stateFlag )
- addStyleSheetProperties( stateFlag, it->second );
+ if ( selector.isCacheable() ) {
+ mCacheableStyles.push_back( style );
+ } else {
+ mNoncacheableStyles.push_back( style );
}
}
- mNoncacheableStyles = styleSheet.getNoncacheableElementStyles( mWidget );
+ subscribeNonCacheableStyles();
}
}
}
-void UIStyle::addStyleSheetProperties(const Uint32 & state, const CSS::StyleSheetProperties& properties ) {
+void UIStyle::setStyleSheetProperties( const CSS::StyleSheetProperties& properties ) {
if ( !properties.empty() ) {
- for ( auto it = properties.begin(); it != properties.end(); ++it ) {
- CSS::StyleSheetProperty property = it->second;
-
- addStyleSheetProperty( state, property );
+ for ( const auto& it : properties ) {
+ setStyleSheetProperty( it.second );
}
}
}
-bool UIStyle::hasTransition( const Uint32& state, const std::string& propertyName ) {
- bool ret = mTransitions.find( state ) != mTransitions.end() &&
- ( mTransitions[ state ].find( propertyName ) != mTransitions[ state ].end() ||
- mTransitions[ state ].find( "all" ) != mTransitions[ state ].end()
- );
-
- // When transitions are declared without state are global
- if ( !ret && state != StateFlagNormal ) {
- ret = mTransitions.find( StateFlagNormal ) != mTransitions.end() && (
- mTransitions[ StateFlagNormal ].find( propertyName ) != mTransitions[ StateFlagNormal ].end() ||
- mTransitions[ StateFlagNormal ].find( "all" ) != mTransitions[ StateFlagNormal ].end()
- );
- }
-
- return ret;
+bool UIStyle::hasTransition( const std::string& propertyName ) {
+ return mTransitions.find( propertyName ) != mTransitions.end() || mTransitions.find( "all" ) != mTransitions.end();
}
-UIStyle::TransitionInfo UIStyle::getTransition( const Uint32& state, const std::string& propertyName ) {
- if ( mTransitions.find( state ) != mTransitions.end() ) {
- auto propertyTransitionIt = mTransitions[ state ].find( propertyName );
+UIStyle::TransitionInfo UIStyle::getTransition( const std::string& propertyName ) {
+ auto propertyTransitionIt = mTransitions.find( propertyName );
- if ( propertyTransitionIt != mTransitions[ state ].end() ) {
- return propertyTransitionIt->second;
- } else if ( ( propertyTransitionIt = mTransitions[ state ].find( "all" ) ) != mTransitions[ state ].end() ) {
- return propertyTransitionIt->second;
- } else if ( mTransitions.find( StateFlagNormal ) != mTransitions.end() ) {
- propertyTransitionIt = mTransitions[ StateFlagNormal ].find( propertyName );
-
- if ( propertyTransitionIt != mTransitions[ StateFlagNormal ].end() ) {
- return propertyTransitionIt->second;
- } else if ( ( propertyTransitionIt = mTransitions[ StateFlagNormal ].find( "all" ) ) != mTransitions[ state ].end() ) {
- return propertyTransitionIt->second;
- }
- }
- } else if ( mTransitions.find( StateFlagNormal ) != mTransitions.end() ) {
- auto propertyTransitionIt = mTransitions[ StateFlagNormal ].find( propertyName );
-
- if ( propertyTransitionIt != mTransitions[ StateFlagNormal ].end() ) {
- return propertyTransitionIt->second;
- } else if ( ( propertyTransitionIt = mTransitions[ StateFlagNormal ].find( "all" ) ) != mTransitions[ state ].end() ) {
- return propertyTransitionIt->second;
- }
+ if ( propertyTransitionIt != mTransitions.end() ) {
+ return propertyTransitionIt->second;
+ } else if ( ( propertyTransitionIt = mTransitions.find( "all" ) ) != mTransitions.end() ) {
+ return propertyTransitionIt->second;
}
return TransitionInfo();
}
+void UIStyle::subscribeRelated( UIWidget * widget ) {
+ mRelatedWidgets.insert( widget );
+}
+
+void UIStyle::unsubscribeRelated( UIWidget * widget ) {
+ mRelatedWidgets.erase( widget );
+}
+
+void UIStyle::tryApplyStyle( const StyleSheetStyle& style ) {
+ if ( style.getSelector().select( mWidget ) ) {
+ for ( const auto& prop : style.getProperties() ) {
+ const StyleSheetProperty& property = prop.second;
+ const auto& it = mProperties.find( property.getName() );
+
+ if ( it == mProperties.end() || property.getSpecificity() >= it->second.getSpecificity() ) {
+ mProperties[ property.getName() ] = property;
+
+ if ( String::startsWith( property.getName(), "transition" ) )
+ mTransitionAttributes.push_back( property );
+ }
+ }
+ }
+}
+
void UIStyle::onStateChange() {
if ( NULL != mWidget ) {
- StyleSheetProperties properties;
+ mProperties.clear();
+ mTransitionAttributes.clear();
- auto& props = mStates[ mCurrentState ];
+ tryApplyStyle( mElementStyle );
- for ( auto& prop : props ) {
- auto& property = prop.second;
- auto it = properties.find( property.getName() );
-
- if ( it == properties.end() || property.getSpecificity() >= it->second.getSpecificity() ) {
- properties[ property.getName() ] = property;
- }
+ for ( auto& style : mCacheableStyles ) {
+ tryApplyStyle( style );
}
for ( auto& style : mNoncacheableStyles ) {
- if ( style.getSelector().select( mWidget ) ) {
- for ( auto& prop : style.getProperties() ) {
- auto& property = prop.second;
- auto it = properties.find( property.getName() );
-
- if ( it == properties.end() || property.getSpecificity() >= it->second.getSpecificity() ) {
- properties[ property.getName() ] = property;
- }
- }
- }
+ tryApplyStyle( style );
}
+ parseTransitions();
+
mWidget->beginAttributesTransaction();
- for ( auto& prop : properties ) {
- auto& property = prop.second;
+ for ( const auto& prop : mProperties ) {
+ const StyleSheetProperty& property = prop.second;
- mWidget->setAttribute( property.getName(), property.getValue(), mCurrentState );
+ mWidget->setAttribute( NodeAttribute( property.getName(), property.getValue(), property.isVolatile() ), mCurrentState );
}
mWidget->endAttributesTransaction();
- }
-}
-StyleSheetProperty UIStyle::getStyleSheetProperty( const Uint32& state, const std::string& attributeName ) const {
- if ( !attributeName.empty() && stateExists( state ) ) {
- auto& attributesMap = mStates.at( state );
-
- auto attributeFound = attributesMap.find( attributeName );
-
- if ( attributeFound != attributesMap.end() ) {
- return attributeFound->second;
- }
- }
-
- return StyleSheetProperty();
-}
-
-StyleSheetProperty UIStyle::getStyleSheetPropertyFromNames( const Uint32& state, const std::vector& propertiesNames ) const {
- if ( !propertiesNames.empty() && stateExists( state ) ) {
- auto& attributesMap = mStates.at( state );
-
- for ( size_t i = 0; i < propertiesNames.size(); i++ ) {
- const std::string& name = propertiesNames[i];
- auto attributeFound = attributesMap.find( name );
-
- if ( attributeFound != attributesMap.end() ) {
- return attributeFound->second;
+ for ( auto& related : mRelatedWidgets ) {
+ if ( NULL != related->getUIStyle() ) {
+ related->getUIStyle()->onStateChange();
}
+ }
+ }
+}
+StyleSheetProperty UIStyle::getStatelessStyleSheetProperty( const std::string& propertyName ) const {
+ if ( !propertyName.empty() ) {
+ if ( !mElementStyle.getSelector().hasPseudoClasses() ) {
+ StyleSheetProperty property = mElementStyle.getPropertyByName( propertyName );
+
+ if ( !property.isEmpty() )
+ return property;
+ }
+
+ for ( const StyleSheetStyle& style : mCacheableStyles ) {
+ if ( !style.getSelector().hasPseudoClasses() ) {
+ StyleSheetProperty property = style.getPropertyByName( propertyName );
+
+ if ( !property.isEmpty() )
+ return property;
+ }
}
}
return StyleSheetProperty();
}
-NodeAttribute UIStyle::getNodeAttribute( const Uint32& state, const std::string& attributeName ) const {
- StyleSheetProperty property( getStyleSheetProperty( state, attributeName ) );
- return NodeAttribute( property.getName(), property.getValue() );
+StyleSheetProperty UIStyle::getStyleSheetProperty( const std::string& propertyName ) const {
+ auto propertyIt = mProperties.find( propertyName );
+
+ if ( propertyIt != mProperties.end() )
+ return propertyIt->second;
+
+ return StyleSheetProperty();
}
-bool UIStyle::hasStyleSheetProperty( const Uint32 & state, const std::string& propertyName ) const {
- if ( !propertyName.empty() && stateExists( state ) ) {
- auto& attributesMap = mStates.at( state );
- return attributesMap.find( propertyName ) != attributesMap.end();
- }
-
- return false;
+NodeAttribute UIStyle::getNodeAttribute( const std::string& attributeName ) const {
+ StyleSheetProperty property( getStyleSheetProperty( attributeName ) );
+ return NodeAttribute( property.getName(), property.getValue() );
}
void UIStyle::updateState() {
@@ -229,36 +200,65 @@ void UIStyle::updateState() {
if ( mCurrentState != getStateFlag(i) ) {
mPreviousState = mCurrentState;
mCurrentState = getStateFlag(i);
- onStateChange();
+ break;
}
-
- return;
}
}
}
- Uint32 currentState = mCurrentState;
+ onStateChange();
+}
- mCurrentState = StateFlagNormal;
+void UIStyle::subscribeNonCacheableStyles() {
+ for ( auto& style : mNoncacheableStyles ) {
+ std::vector elements = style.getSelector().getRelatedElements( mWidget, false );
- if ( currentState != StateFlagNormal ) {
- onStateChange();
+ if ( !elements.empty() ) {
+ for ( auto& element : elements ) {
+ UIWidget * widget = dynamic_cast( element );
+
+ if ( NULL != widget && NULL != widget->getUIStyle() ) {
+ widget->getUIStyle()->subscribeRelated( mWidget );
+
+ mSubscribedWidgets.insert( widget );
+ }
+ }
+ }
}
}
-void UIStyle::parseTransitions( const Uint32& state ) {
+void UIStyle::unsubscribeNonCacheableStyles() {
+ for ( auto& widget : mSubscribedWidgets ) {
+ if ( NULL != widget->getUIStyle() ) {
+ widget->getUIStyle()->unsubscribeRelated( mWidget );
+ }
+ }
+
+ mSubscribedWidgets.clear();
+}
+
+void UIStyle::removeFromSubscribedWidgets( UIWidget * widget ) {
+ mSubscribedWidgets.erase( widget );
+}
+
+void UIStyle::removeRelatedWidgets() {
+ for ( auto& widget : mRelatedWidgets ) {
+ if ( NULL != widget->getUIStyle() ) {
+ widget->getUIStyle()->removeFromSubscribedWidgets( mWidget );
+ }
+ }
+
+ mRelatedWidgets.clear();
+}
+
+void UIStyle::parseTransitions() {
std::vector properties;
std::vector