diff --git a/include/eepp/scene/node.hpp b/include/eepp/scene/node.hpp index aca4cc758..abdeebd45 100644 --- a/include/eepp/scene/node.hpp +++ b/include/eepp/scene/node.hpp @@ -299,6 +299,8 @@ class EE_API Node : public Transformable { virtual void setFocus(); + Node* getFirstWidget() const; + Node* getNextWidget() const; Node* getParentWidget() const; diff --git a/include/eepp/ui/css/stylesheetproperty.hpp b/include/eepp/ui/css/stylesheetproperty.hpp index 14a139fea..aa568cfdb 100644 --- a/include/eepp/ui/css/stylesheetproperty.hpp +++ b/include/eepp/ui/css/stylesheetproperty.hpp @@ -28,7 +28,8 @@ class EE_API StyleSheetProperty { explicit StyleSheetProperty( const PropertyDefinition* definition, const std::string& value, const Uint32& index = 0 ); - explicit StyleSheetProperty( const std::string& name, const std::string& value ); + explicit StyleSheetProperty( const std::string& name, const std::string& value, + const bool& trimValue = true ); explicit StyleSheetProperty( const std::string& name, const std::string& value, const Uint32& specificity, const bool& isVolatile = false, diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index ba094db9f..d2ccaefe2 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -106,6 +106,8 @@ class EE_API UISceneNode : public SceneNode { void processStyleSheetAtRules( const CSS::StyleSheet& styleSheet ); void loadFontFaces( const CSS::StyleSheetStyleVector& styles ); + + UIWidget* loadNode( pugi::xml_node node, Node* parent ); }; }} // namespace EE::UI diff --git a/include/eepp/ui/uiviewpager.hpp b/include/eepp/ui/uiviewpager.hpp index e08910436..04c2b7b2f 100644 --- a/include/eepp/ui/uiviewpager.hpp +++ b/include/eepp/ui/uiviewpager.hpp @@ -69,6 +69,7 @@ class EE_API UIViewPager : public UIWidget { Int32 mCurrentPage; Int32 mTotalPages; Ease::Interpolation mTimingFunction; + Vector2f mMouseDownPos; UIViewPager(); diff --git a/include/eepp/ui/uiwidget.hpp b/include/eepp/ui/uiwidget.hpp index ea5b8b1b4..167096df3 100644 --- a/include/eepp/ui/uiwidget.hpp +++ b/include/eepp/ui/uiwidget.hpp @@ -277,6 +277,8 @@ class EE_API UIWidget : public UINode { void createTooltip(); + virtual void onChildCountChange( Node* child, const bool& removed ); + virtual Uint32 onMouseMove( const Vector2i& Pos, const Uint32& Flags ); virtual Uint32 onMouseLeave( const Vector2i& Pos, const Uint32& Flags ); @@ -316,6 +318,8 @@ class EE_API UIWidget : public UINode { std::string getFlagsString() const; bool checkPropertyDefinition( const StyleSheetProperty& property ); + + void reloadChildsStyleState(); }; }} // namespace EE::UI diff --git a/src/eepp/scene/node.cpp b/src/eepp/scene/node.cpp index 3e22e0ba0..fd3eaf423 100644 --- a/src/eepp/scene/node.cpp +++ b/src/eepp/scene/node.cpp @@ -1416,6 +1416,17 @@ bool Node::hasFocus() const { void Node::setFocus() {} +Node* Node::getFirstWidget() const { + Node* childLoop = mChild; + while ( NULL != childLoop ) { + if ( childLoop->isWidget() ) { + return childLoop; + } + childLoop = childLoop->getNextNode(); + } + return NULL; +} + Node* Node::getNextWidget() const { Node* Found = NULL; Node* ChildLoop = mChild; diff --git a/src/eepp/ui/css/stylesheetproperty.cpp b/src/eepp/ui/css/stylesheetproperty.cpp index 3016c5322..45db79cec 100644 --- a/src/eepp/ui/css/stylesheetproperty.cpp +++ b/src/eepp/ui/css/stylesheetproperty.cpp @@ -57,10 +57,11 @@ StyleSheetProperty::StyleSheetProperty( const bool& isVolatile, } } -StyleSheetProperty::StyleSheetProperty( const std::string& name, const std::string& value ) : +StyleSheetProperty::StyleSheetProperty( const std::string& name, const std::string& value, + const bool& trimValue ) : mName( String::toLower( String::trim( name ) ) ), mNameHash( String::hash( mName ) ), - mValue( String::trim( value ) ), + mValue( trimValue ? String::trim( value ) : value ), mSpecificity( 0 ), mIndex( 0 ), mVolatile( false ), diff --git a/src/eepp/ui/uigridlayout.cpp b/src/eepp/ui/uigridlayout.cpp index b1adfa460..9b34e4728 100644 --- a/src/eepp/ui/uigridlayout.cpp +++ b/src/eepp/ui/uigridlayout.cpp @@ -14,7 +14,9 @@ UIGridLayout::UIGridLayout() : mColumnWeight( 0.25f ), mColumnWidth( 0 ), mRowWeight( 0.25f ), - mRowHeight( 0 ) {} + mRowHeight( 0 ) { + mFlags |= UI_OWNS_CHILDS_POSITION; +} Uint32 UIGridLayout::getType() const { return UI_TYPE_GRID_LAYOUT; @@ -127,7 +129,9 @@ void UIGridLayout::onParentSizeChange( const Vector2f& SizeChange ) { void UIGridLayout::pack() { Sizef oldSize( getSize() ); - setInternalPosition( Vector2f( mLayoutMargin.Left, mLayoutMargin.Top ) ); + if ( getParent()->isUINode() && !getParent()->asType()->ownsChildPosition() ) { + setInternalPosition( Vector2f( mLayoutMargin.Left, mLayoutMargin.Top ) ); + } if ( getLayoutWidthRule() == LayoutSizeRule::MatchParent ) { setInternalWidth( getParent()->getSize().getWidth() - mLayoutMargin.Left - @@ -143,9 +147,18 @@ void UIGridLayout::pack() { Vector2f pos( mPadding.Left, mPadding.Top ); Sizef targetSize( getTargetElementSize() ); + Float initX = 0.f; if ( getHorizontalAlign() == UI_HALIGN_RIGHT ) - pos.x = getSize().getWidth() - mPadding.Right; + pos.x = getSize().getWidth() - targetSize.getWidth() - mPadding.Right; + else if ( getHorizontalAlign() == UI_HALIGN_CENTER && getSize().getWidth() > 0 ) { + initX = + mPadding.Left + eeceil( ( (Int32)targetSize.getWidth() % + ( static_cast( getSize().getWidth() - mPadding.Left - + mPadding.Right ) ) ) * + 0.5f ); + pos.x = initX; + } bool usedLastRow = true; @@ -169,9 +182,14 @@ void UIGridLayout::pack() { if ( pos.x < mPadding.Left || pos.x + targetSize.x > getSize().getWidth() - mPadding.Right || pos.x + targetSize.x + mSpan.x > getSize().getWidth() - mPadding.Right ) { - pos.x = getHorizontalAlign() == UI_HALIGN_RIGHT - ? getSize().getWidth() - mPadding.Right - : mPadding.Left; + + if ( getHorizontalAlign() == UI_HALIGN_CENTER ) { + pos.x = initX; + } else if ( getHorizontalAlign() == UI_HALIGN_RIGHT ) { + pos.x = getSize().getWidth() - mPadding.Right; + } else { + pos.x = mPadding.Left; + } pos.y += targetSize.getHeight() + mSpan.y; usedLastRow = false; diff --git a/src/eepp/ui/uilinearlayout.cpp b/src/eepp/ui/uilinearlayout.cpp index ca93bd878..43af71c06 100644 --- a/src/eepp/ui/uilinearlayout.cpp +++ b/src/eepp/ui/uilinearlayout.cpp @@ -20,6 +20,7 @@ UILinearLayout::UILinearLayout() : mOrientation( UIOrientation::Vertical ), mHPacking( false ), mVPacking( false ) { + mFlags |= UI_OWNS_CHILDS_POSITION; clipEnable(); } diff --git a/src/eepp/ui/uirelativelayout.cpp b/src/eepp/ui/uirelativelayout.cpp index ceef6ebc8..11cb8bf97 100644 --- a/src/eepp/ui/uirelativelayout.cpp +++ b/src/eepp/ui/uirelativelayout.cpp @@ -6,7 +6,9 @@ UIRelativeLayout* UIRelativeLayout::New() { return eeNew( UIRelativeLayout, () ); } -UIRelativeLayout::UIRelativeLayout() : UILayout( "relativelayout" ) {} +UIRelativeLayout::UIRelativeLayout() : UILayout( "relativelayout" ) { + mFlags |= UI_OWNS_CHILDS_POSITION; +} Uint32 UIRelativeLayout::getType() const { return UI_TYPE_RELATIVE_LAYOUT; diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 58684a73f..5211dfd65 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -112,8 +112,7 @@ bool UISceneNode::windowExists( UIWindow* win ) { return mWindowsList.end() != std::find( mWindowsList.begin(), mWindowsList.end(), win ); } -UIWidget* UISceneNode::loadLayoutNodes( pugi::xml_node node, Node* parent ) { - mIsLoading = true; +UIWidget* UISceneNode::loadNode( pugi::xml_node node, Node* parent ) { UIWidget* firstWidget = NULL; if ( NULL == parent ) @@ -131,16 +130,25 @@ UIWidget* UISceneNode::loadLayoutNodes( pugi::xml_node node, Node* parent ) { uiwidget->loadFromXmlNode( widget ); if ( widget.first_child() ) { - loadLayoutNodes( widget.first_child(), uiwidget ); + loadNode( widget.first_child(), uiwidget ); } - uiwidget->reloadStyle( false ); + //uiwidget->reloadStyle( false ); uiwidget->onWidgetCreated(); } else if ( String::toLower( widget.name() ) == "style" ) { combineStyleSheet( widget.text().as_string() ); } } + return firstWidget; +} + +UIWidget* UISceneNode::loadLayoutNodes( pugi::xml_node node, Node* parent ) { + UIWidget* firstWidget = NULL; + + mIsLoading = true; + firstWidget = loadNode( node, parent ); + reloadStyle(); mIsLoading = false; return firstWidget; @@ -381,7 +389,6 @@ void UISceneNode::loadFontFaces( const StyleSheetStyleVector& styles ) { } if ( String::startsWith( path, "file://" ) ) { - std::string filePath( path.substr( 7 ) ); FontTrueType* font = diff --git a/src/eepp/ui/uistyle.cpp b/src/eepp/ui/uistyle.cpp index 3738d146f..5419281cf 100644 --- a/src/eepp/ui/uistyle.cpp +++ b/src/eepp/ui/uistyle.cpp @@ -271,6 +271,9 @@ void UIStyle::onStateChange() { for ( auto& prop : mProperties ) { StyleSheetProperty& property = prop.second; + if ( NULL == property.getPropertyDefinition() ) + continue; + if ( property.getPropertyDefinition()->isIndexed() ) { for ( size_t i = 0; i < property.getPropertyIndexCount(); i++ ) { applyStyleSheetProperty( property.getPropertyIndex( i ), prevProperties ); diff --git a/src/eepp/ui/uiviewpager.cpp b/src/eepp/ui/uiviewpager.cpp index 9f755a498..124d2b166 100644 --- a/src/eepp/ui/uiviewpager.cpp +++ b/src/eepp/ui/uiviewpager.cpp @@ -224,22 +224,22 @@ Uint32 UIViewPager::onCalculateDrag( const Vector2f& position, const Uint32& fla void UIViewPager::onMouseDownEvent() { if ( !mDragging && !getEventDispatcher()->isNodeDragging() ) { mDragging = true; + mMouseDownPos = getEventDispatcher()->getMousePos().asFloat(); mContainer->clearActions(); mInitialDisplacement = mOrientation == UIOrientation::Horizontal ? -mContainer->getPixelsPosition().x : -mContainer->getPixelsPosition().y; + mDisplacement = 0; getEventDispatcher()->setNodeDragging( this ); } } void UIViewPager::onMouseMoveEvent() { if ( mDragging ) { - mDisplacement = - mInitialDisplacement + ( mOrientation == UIOrientation::Horizontal - ? getEventDispatcher()->getMouseDownPos().asFloat().x - - getEventDispatcher()->getMousePos().asFloat().x - : getEventDispatcher()->getMouseDownPos().asFloat().y - - getEventDispatcher()->getMousePos().asFloat().y ); + mDisplacement = mInitialDisplacement + + ( mOrientation == UIOrientation::Horizontal + ? mMouseDownPos.x - getEventDispatcher()->getMousePos().asFloat().x + : mMouseDownPos.y - getEventDispatcher()->getMousePos().asFloat().y ); limitDisplacement(); diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index 4af55022e..abfa19cf7 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -213,6 +213,12 @@ void UIWidget::createTooltip() { mTooltip->setTooltipOf( this ); } +void UIWidget::onChildCountChange( Node* child, const bool& removed ) { + UINode::onChildCountChange( child, removed ); + if ( !isSceneNodeLoading() ) + reloadChildsStyleState(); +} + Uint32 UIWidget::onMouseMove( const Vector2i& Pos, const Uint32& Flags ) { if ( mVisible && NULL != mTooltip && !mTooltip->getText().empty() ) { EventDispatcher* eventDispatcher = getEventDispatcher(); @@ -1073,6 +1079,15 @@ bool UIWidget::checkPropertyDefinition( const StyleSheetProperty& property ) { return true; } +void UIWidget::reloadChildsStyleState() { + Node* childLoop = getFirstChild(); + while ( childLoop != NULL ) { + if ( childLoop->isWidget() ) + childLoop->asType()->reportStyleStateChange(); + childLoop = childLoop->getNextNode(); + } +} + UIWidget* UIWidget::querySelector( const std::string& selector ) { return querySelector( CSS::StyleSheetSelector( selector ) ); } @@ -1246,7 +1261,7 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) { setForegroundDrawable( attribute.getValue(), attribute.getIndex() ); break; case PropertyId::ForegroundRadius: - setForegroundRadius( attribute.asUint() ); + setForegroundRadius( lengthFromValue( attribute ) ); break; case PropertyId::ForegroundSize: setForegroundSize( attribute.value(), attribute.getIndex() ); @@ -1539,7 +1554,8 @@ void UIWidget::loadFromXmlNode( const pugi::xml_node& node ) { for ( pugi::xml_attribute_iterator ait = node.attributes_begin(); ait != node.attributes_end(); ++ait ) { - StyleSheetProperty prop( ait->name(), ait->value() ); + // Create a property without triming its value + StyleSheetProperty prop( ait->name(), ait->value(), false ); if ( prop.getShorthandDefinition() != NULL ) { auto properties = diff --git a/src/eepp/ui/uiwindow.cpp b/src/eepp/ui/uiwindow.cpp index ea276457b..d9dc7be0f 100644 --- a/src/eepp/ui/uiwindow.cpp +++ b/src/eepp/ui/uiwindow.cpp @@ -62,7 +62,7 @@ UIWindow::UIWindow( UIWindow::WindowBaseContainerType type, const StyleConfig& w break; case SIMPLE_LAYOUT: default: - mContainer = UIWidget::New(); + mContainer = UIWidget::NewWithTag( "window::container" ); break; } diff --git a/src/test/eetest.cpp b/src/test/eetest.cpp index 383732676..63a84eeee 100644 --- a/src/test/eetest.cpp +++ b/src/test/eetest.cpp @@ -1000,7 +1000,9 @@ void EETest::createMapEditor() { windowStyleConfig.MinWindowSize = Sizef( 1024, 768 ); tWin->setStyleConfig( windowStyleConfig ); + Clock mapEditorTime; mMapEditor = MapEditor::New( tWin, cb::Make0( this, &EETest::onMapEditorClose ) ); + eePRINTL( "Map Editor created in: %s.", mapEditorTime.getElapsedTime().toString().c_str() ); tWin->center(); tWin->show(); }