X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Falignment%2Falignment-impl.cpp;h=07186e0835df2e0ac4e229db35f1abae509dd5b9;hp=17dfff6a8480b1d3acd56e66e6599962f0512789;hb=5e937a6322849b76d49d5b3f41cb5d91c94acd3e;hpb=4b38b709efae6ba534f7d336b70dabb74c804e03 diff --git a/dali-toolkit/internal/controls/alignment/alignment-impl.cpp b/dali-toolkit/internal/controls/alignment/alignment-impl.cpp index 17dfff6..07186e0 100644 --- a/dali-toolkit/internal/controls/alignment/alignment-impl.cpp +++ b/dali-toolkit/internal/controls/alignment/alignment-impl.cpp @@ -21,8 +21,8 @@ // EXTERNAL INCLUDES #include #include - -// INTERNAL INCLUDES +#include +#include namespace Dali { @@ -42,333 +42,70 @@ BaseHandle Create() return Toolkit::Alignment::New(); } -TypeRegistration mType( typeid(Toolkit::Alignment), typeid(Toolkit::Control), Create ); - -struct ScaleToFillConstraint -{ - /** - * @param padding to be added. - */ - ScaleToFillConstraint( const Toolkit::Alignment::Padding& padding ) - : mPadding( padding ) - {} - - /** - * Called by render thread - */ - Vector3 operator()( const Vector3& currentSize, - const PropertyInput& parentSizeProperty ) - { - const Vector3& parentSize( parentSizeProperty.GetVector3() ); - return GetSize( currentSize, parentSize ); - } - - inline Vector3 GetSize( const Vector3& currentSize, const Vector3& parentSize ) - { - const float parentSizeWidth = parentSize.width - ( mPadding.left + mPadding.right ); - const float parentSizeHeight = parentSize.height - ( mPadding.top + mPadding.bottom ); - - // prevent ridiculous sizes if parent is really small or if we don't have a proper size for the actor - if( ( parentSizeWidth < Math::MACHINE_EPSILON_1000 ) || ( parentSizeHeight < Math::MACHINE_EPSILON_1000 ) ) - { - // no point trying to squeeze actors into this small size - return Vector3::ZERO; - } - return Vector3( parentSizeWidth, parentSizeHeight, parentSize.depth ); - } - - const Toolkit::Alignment::Padding mPadding; -}; - -struct ScaleToFitKeepAspectConstraint -{ - /** - * @param padding to be added. - */ - ScaleToFitKeepAspectConstraint( const Toolkit::Alignment::Padding& padding ) - : mPadding( padding ), - mSizeStored( false ), - mOriginalSize() - {} - - /** - * Called by render thread - */ - Vector3 operator()( const Vector3& currentSize, - const PropertyInput& parentSizeProperty ) - { - const Vector3& parentSize( parentSizeProperty.GetVector3() ); - return GetSize( currentSize, parentSize ); - } - - inline Vector3 GetSize( const Vector3& currentSize, const Vector3& parentSize ) - { - if( ( !mSizeStored ) && ( Vector3::ZERO != currentSize ) ) - { - mOriginalSize = currentSize; - mSizeStored = true; - } - - const float parentSizeWidth = parentSize.width - ( mPadding.left + mPadding.right ); - const float parentSizeHeight = parentSize.height - ( mPadding.top + mPadding.bottom ); - - // prevent ridiculous sizes if parent is really small or if we don't have a proper size for the actor - if( ( parentSizeWidth < Math::MACHINE_EPSILON_1000 ) || ( parentSizeHeight < Math::MACHINE_EPSILON_1000 )|| - ( mOriginalSize.width < Math::MACHINE_EPSILON_1000 ) || ( mOriginalSize.height < Math::MACHINE_EPSILON_1000 ) ) - { - // no point trying to squeeze actors into this small size - return Vector3::ZERO; - } - - return mOriginalSize * std::min( ( parentSizeWidth / mOriginalSize.width ), ( parentSizeHeight / mOriginalSize.height ) ); - } - - const Toolkit::Alignment::Padding mPadding; - bool mSizeStored; - Vector3 mOriginalSize; -}; - -struct ScaleToFillKeepAspectConstraint -{ - /** - * @param padding to be added. - */ - ScaleToFillKeepAspectConstraint( const Toolkit::Alignment::Padding& padding ) - : mPadding( padding ), - mSizeStored( false ), - mOriginalSize() - { } - - /** - * Called by render thread - */ - Vector3 operator()( const Vector3& currentSize, - const PropertyInput& parentSizeProperty ) - { - const Vector3& parentSize( parentSizeProperty.GetVector3() ); - return GetSize( currentSize, parentSize ); - } - - Vector3 GetSize( const Vector3& currentSize, const Vector3& parentSize ) - { - if( ( !mSizeStored ) && ( Vector3::ZERO != currentSize ) ) - { - mOriginalSize = currentSize; - mSizeStored = true; - } - - const float parentSizeWidth = parentSize.width - ( mPadding.left + mPadding.right ); - const float parentSizeHeight = parentSize.height - ( mPadding.top + mPadding.bottom ); - - // prevent ridiculous sizes if parent is really small or if we don't have a proper size for the actor - if( ( parentSizeWidth < Math::MACHINE_EPSILON_1000 ) || ( parentSizeHeight < Math::MACHINE_EPSILON_1000 )|| - ( mOriginalSize.width < Math::MACHINE_EPSILON_1000 ) || ( mOriginalSize.height < Math::MACHINE_EPSILON_1000 ) ) - { - // no point trying to squeeze actors into this small size - return Vector3::ZERO; - } - - return mOriginalSize * std::max( ( parentSizeWidth / mOriginalSize.width ), ( parentSizeHeight / mOriginalSize.height ) ); - } - - const Toolkit::Alignment::Padding mPadding; - bool mSizeStored; - Vector3 mOriginalSize; -}; - -struct ShrinkToFitConstraint -{ - /** - * @param padding to be added. - */ - ShrinkToFitConstraint( const Toolkit::Alignment::Padding& padding ) - : mPadding( padding ), - mSizeStored( false ), - mOriginalSize() - {} - - /** - * Called by render thread - */ - Vector3 operator()( const Vector3& currentSize, - const PropertyInput& parentSizeProperty ) - { - const Vector3& parentSize( parentSizeProperty.GetVector3() ); - return GetSize( currentSize, parentSize ); - } - - Vector3 GetSize( const Vector3& currentSize, const Vector3& parentSize ) - { - if( ( !mSizeStored ) && ( Vector3::ZERO != currentSize ) ) - { - mOriginalSize = currentSize; - mSizeStored = true; - } - - const float parentSizeWidth = parentSize.width - ( mPadding.left + mPadding.right ); - const float parentSizeHeight = parentSize.height - ( mPadding.top + mPadding.bottom ); - - // prevent ridiculous sizes if parent is really small or if we don't have a proper size for the actor - if( ( parentSizeWidth < Math::MACHINE_EPSILON_1000 ) || ( parentSizeHeight < Math::MACHINE_EPSILON_1000 )|| - ( mOriginalSize.width < Math::MACHINE_EPSILON_1000 ) || ( mOriginalSize.height < Math::MACHINE_EPSILON_1000 ) ) - { - // no point trying to squeeze actors into this small size - return Vector3::ZERO; - } - - return Vector3( std::min( parentSizeWidth, mOriginalSize.width ), std::min( parentSizeHeight, mOriginalSize.height ), std::min( parentSize.depth, mOriginalSize.depth ) ); - } - - const Toolkit::Alignment::Padding mPadding; - bool mSizeStored; - Vector3 mOriginalSize; -}; - -/** - * Constraint that uses naturalSize if it fits inside parent and parent size if not. It also adds some padding pixels - */ -struct ShrinkToFitKeepAspectConstraint -{ - /** - * @param padding to be added. - */ - ShrinkToFitKeepAspectConstraint( const Toolkit::Alignment::Padding& padding ) - : mPadding( padding ), - mSizeStored( false ), - mOriginalSize() - {} - - /** - * Called by render thread - */ - Vector3 operator()( const Vector3& currentSize, - const PropertyInput& parentSizeProperty ) - { - const Vector3& parentSize( parentSizeProperty.GetVector3() ); - return GetSize( currentSize, parentSize ); - } - - inline Vector3 GetSize( const Vector3& currentSize, const Vector3& parentSize ) - { - if( ( !mSizeStored ) && ( Vector3::ZERO != currentSize ) ) - { - mOriginalSize = currentSize; - mSizeStored = true; - } - - const float parentSizeWidth = parentSize.width - ( mPadding.left + mPadding.right ); - const float parentSizeHeight = parentSize.height - ( mPadding.top + mPadding.bottom ); - - // prevent ridiculous sizes if parent is really small or if we don't have a proper size for the actor - if( ( parentSizeWidth < Math::MACHINE_EPSILON_1000 ) || ( parentSizeHeight < Math::MACHINE_EPSILON_1000 )|| - ( mOriginalSize.width < Math::MACHINE_EPSILON_1000 ) || ( mOriginalSize.height < Math::MACHINE_EPSILON_1000 ) ) - { - // no point trying to squeeze actors into this small size - return Vector3::ZERO; - } - - return Vector3( ShrinkInside( Vector2( parentSizeWidth, parentSizeHeight ), Vector2( mOriginalSize ) ) ); - } - - const Toolkit::Alignment::Padding mPadding; - bool mSizeStored; - Vector3 mOriginalSize; -}; +DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Alignment, Toolkit::Control, Create ) +DALI_TYPE_REGISTRATION_END() /** - * Constraint that modifies the contained actor taking into account the padding value. + * @param padding The padding value + * @param horizontalAlignment The horizontal alignment. + * @param verticalAlignment The vertical alignment. + * @param currentSize of the object + * @param parentSize */ -struct PositionConstraint +inline Vector3 GetPosition( const Toolkit::Alignment::Padding& padding, Toolkit::Alignment::Type horizontalAlignment, Toolkit::Alignment::Type verticalAlignment, + const Vector2& currentSize, const Vector2& parentSize ) { - /** - * @param padding The padding value - * @param horizontalAlignment The horizontal alignment. - * @param verticalAlignment The vertical alignment. - */ - PositionConstraint( const Toolkit::Alignment::Padding& padding, Toolkit::Alignment::Type horizontalAlignment, Toolkit::Alignment::Type verticalAlignment ) - : mPadding( padding ), - mHorizontalAlignment( horizontalAlignment ), - mVerticalAlignment( verticalAlignment ) - {} - - /** - * Called by render thread. - */ - Vector3 operator()( const Vector3& currentPosition, - const PropertyInput& currentSizeProperty, - const PropertyInput& parentSizeProperty ) - { - const Vector3& currentSize( currentSizeProperty.GetVector3() ); - const Vector3& parentSize( parentSizeProperty.GetVector3() ); - - return GetPosition( currentSize, parentSize ); - } + Vector3 position( 0.f, 0.f, 0.f ); - inline Vector3 GetPosition( const Vector3& currentSize, const Vector3& parentSize ) + switch( horizontalAlignment ) { - Vector3 position( 0.f, 0.f, 0.f ); - - switch( mHorizontalAlignment ) - { case Dali::Toolkit::Alignment::HorizontalLeft: { - position.x += mPadding.left; - break; - } - case Dali::Toolkit::Alignment::HorizontalCenter: - { - if( currentSize.width + mPadding.left + mPadding.right >= parentSize.width ) - { - position.x += 0.5f * ( mPadding.left - mPadding.right ); - } + position.x += padding.left; break; } case Dali::Toolkit::Alignment::HorizontalRight: { - position.x -= mPadding.right; + position.x -= padding.right; break; } - default: + case Dali::Toolkit::Alignment::HorizontalCenter: // FALLTHROUGH + default: // use center as default { - DALI_ASSERT_ALWAYS( !"Wrong horizontal alignment value" ); + if( currentSize.width + padding.left + padding.right >= parentSize.width ) + { + position.x += 0.5f * ( padding.left - padding.right ); + } break; } - } + } - switch( mVerticalAlignment ) - { + switch( verticalAlignment ) + { case Dali::Toolkit::Alignment::VerticalTop: { - position.y += mPadding.top; - break; - } - case Dali::Toolkit::Alignment::VerticalCenter: - { - if( currentSize.height + mPadding.top + mPadding.bottom >= parentSize.height ) - { - position.y += 0.5f * ( mPadding.top - mPadding.bottom ); - } + position.y += padding.top; break; } case Dali::Toolkit::Alignment::VerticalBottom: { - position.y -= mPadding.bottom; + position.y -= padding.bottom; break; } - default: + case Dali::Toolkit::Alignment::VerticalCenter: // FALLTHROUGH + default: // use center as default { - DALI_ASSERT_ALWAYS( !"Wrong vertical alignment value" ); + if( currentSize.height + padding.top + padding.bottom >= parentSize.height ) + { + position.y += 0.5f * ( padding.top - padding.bottom ); + } break; } - } - - return position; } - const Toolkit::Alignment::Padding mPadding; - const Toolkit::Alignment::Type mHorizontalAlignment; - const Toolkit::Alignment::Type mVerticalAlignment; -}; + return position; +} + } // namespace Toolkit::Alignment Alignment::New( Toolkit::Alignment::Type horizontal, Toolkit::Alignment::Type vertical ) @@ -376,7 +113,7 @@ Toolkit::Alignment Alignment::New( Toolkit::Alignment::Type horizontal, Toolkit: // Create the implementation, temporarily owned on stack IntrusivePtr< Alignment > internalAlignment = new Alignment( horizontal, vertical ); - // Pass ownership to Toolkit::View + // Pass ownership to Toolkit::Alignment Toolkit::Alignment alignment( *internalAlignment ); // Second-phase init of the implementation @@ -450,7 +187,7 @@ const Toolkit::Alignment::Padding& Alignment::GetPadding() const return mPadding; } -void Alignment::OnRelayout( const Vector2& size, ActorSizeContainer& container ) +void Alignment::OnRelayout( const Vector2& size, RelayoutContainer& container ) { // lay out the actors Vector3 anchorPointAndParentOrigin = Vector3::ZERO; @@ -474,82 +211,86 @@ void Alignment::OnRelayout( const Vector2& size, ActorSizeContainer& container ) anchorPointAndParentOrigin.y = 1.0f; } - unsigned int childCount = Self().GetChildCount(); - for( unsigned int i=0; i Math::MACHINE_EPSILON_1000 ) && ( newChildSize.height > Math::MACHINE_EPSILON_1000 ) && + ( currentChildSize.width > Math::MACHINE_EPSILON_1000 ) && ( currentChildSize.height > Math::MACHINE_EPSILON_1000 ) ) { - case Toolkit::Alignment::ScaleNone: - { - // Nothing to do but needed just to not to jump to the default. - childSize = actorSize; - break; - } - case Toolkit::Alignment::ScaleToFill: - { - ScaleToFillConstraint constraint( mPadding ); - childSize = constraint.GetSize( actorSize, Vector3(size) ) ; - break; - } - case Toolkit::Alignment::ScaleToFitKeepAspect: - { - ScaleToFitKeepAspectConstraint constraint( mPadding ); - childSize = constraint.GetSize( actorSize, Vector3(size) ) ; - break; - } - case Toolkit::Alignment::ScaleToFillKeepAspect: + // no point trying to squeeze actors into too small size + switch( mScaling ) { - ScaleToFillKeepAspectConstraint constraint( mPadding ); - childSize = constraint.GetSize( actorSize, Vector3(size) ); - break; - } - case Toolkit::Alignment::ShrinkToFit: - { - ShrinkToFitConstraint constraint( mPadding ); - childSize = constraint.GetSize( actorSize, Vector3(size) ); - break; - } - case Toolkit::Alignment::ShrinkToFitKeepAspect: - { - ShrinkToFitKeepAspectConstraint constraint( mPadding ); - childSize = constraint.GetSize( actorSize, Vector3(size) ); - break; - } - default: - { - DALI_ASSERT_ALWAYS( !"Invalid Alignment::mGeometryScaling value" ); - break; + case Toolkit::Alignment::ScaleNone: + { + // Nothing to do + renegotiate = false; + break; + } + case Toolkit::Alignment::ScaleToFill: + { + // Nothing to do, newChildSize is already full size minus padding + break; + } + case Toolkit::Alignment::ScaleToFitKeepAspect: + { + newChildSize = currentChildSize * std::min( ( newChildSize.width / currentChildSize.width ), ( newChildSize.height / currentChildSize.height ) ); + break; + } + case Toolkit::Alignment::ScaleToFillKeepAspect: + { + newChildSize = currentChildSize * std::max( ( newChildSize.width / currentChildSize.width ), ( newChildSize.height / currentChildSize.height ) ); + break; + } + case Toolkit::Alignment::ShrinkToFit: + { + newChildSize = Vector2( std::min( newChildSize.width, currentChildSize.width ), std::min( newChildSize.height, currentChildSize.height ) ); + break; + } + case Toolkit::Alignment::ShrinkToFitKeepAspect: + { + // check source size vs target size to see if we need to shrink + float widthScale = ( newChildSize.width < currentChildSize.width ) ? (newChildSize.width / currentChildSize.width) : 1.f; + float heightScale = ( newChildSize.height < currentChildSize.height ) ? (newChildSize.height / currentChildSize.height) : 1.0f; + // use smaller of the scales + float scale = std::min( widthScale, heightScale ); + // check if we need to scale + if( scale < 1.0f ) + { + // scale natural size to fit inside + newChildSize *= scale; + } + break; + } } } - PositionConstraint positionConstraint(mPadding, mHorizontal, mVertical); - actor.SetPosition( positionConstraint.GetPosition(childSize, actorSize) ); + child.SetPosition( GetPosition( mPadding, mHorizontal, mVertical , newChildSize, currentChildSize ) ); - if( !control ) + if( renegotiate ) { - actor.SetScale(childSize / actorSize); + container.Add( child, newChildSize ); } - - Relayout( actor, Vector2(childSize), container ); } } Alignment::Alignment( Toolkit::Alignment::Type horizontal, Toolkit::Alignment::Type vertical ) -: Control( CONTROL_BEHAVIOUR_NONE ), +: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), mHorizontal( horizontal ), mVertical( vertical ), mScaling( Toolkit::Alignment::ScaleNone ),