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=d9b3b4dbcc57d175582ed90479cf361a3b907263;hp=97b6f64d69d1cf28d4f9566a8ffa252f0f069283;hb=9a5ce98a301f74f8df8a3be6d223b525c8839b0b;hpb=306d2f61a1b64179e801fa8a0bb2bd7b4e9dd682 diff --git a/dali-toolkit/internal/controls/alignment/alignment-impl.cpp b/dali-toolkit/internal/controls/alignment/alignment-impl.cpp index 97b6f64..d9b3b4d 100644 --- a/dali-toolkit/internal/controls/alignment/alignment-impl.cpp +++ b/dali-toolkit/internal/controls/alignment/alignment-impl.cpp @@ -16,368 +16,103 @@ */ // CLASS HEADER - #include "alignment-impl.h" // EXTERNAL INCLUDES +#include +#include #include +#include // INTERNAL INCLUDES +#include namespace Dali { - namespace Toolkit { - namespace Internal { - namespace { - //Type Registration 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; -}; +DALI_TYPE_REGISTRATION_BEGIN(Toolkit::Alignment, Toolkit::Control, Create) +DALI_TYPE_REGISTRATION_END() /** - * Constraint that uses naturalSize if it fits inside parent and parent size if not. It also adds some padding pixels + * @param padding The padding value + * @param horizontalAlignment The horizontal alignment. + * @param verticalAlignment The vertical alignment. + * @param currentSize of the object + * @param parentSize */ -struct ShrinkToFitKeepAspectConstraint +inline Vector3 GetPosition(const Toolkit::Alignment::Padding& padding, Toolkit::Alignment::Type horizontalAlignment, Toolkit::Alignment::Type verticalAlignment, const Vector2& currentSize, const Vector2& parentSize) { - /** - * @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 ); - } + Vector3 position(0.f, 0.f, 0.f); - inline Vector3 GetSize( const Vector3& currentSize, const Vector3& parentSize ) + switch(horizontalAlignment) { - if( ( !mSizeStored ) && ( Vector3::ZERO != currentSize ) ) + case Dali::Toolkit::Alignment::HORIZONTAL_LEFT: { - mOriginalSize = currentSize; - mSizeStored = true; + position.x += padding.left; + break; } - - 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 ) ) + case Dali::Toolkit::Alignment::HORIZONTAL_RIGHT: { - // 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; -}; - -/** - * Constraint that modifies the contained actor taking into account the padding value. - */ -struct PositionConstraint -{ - /** - * @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 ); - } - - inline Vector3 GetPosition( const Vector3& currentSize, const Vector3& parentSize ) - { - Vector3 position( 0.f, 0.f, 0.f ); - - switch( mHorizontalAlignment ) - { - case Dali::Toolkit::Alignment::HorizontalLeft: - { - position.x += mPadding.left; + position.x -= padding.right; break; } - case Dali::Toolkit::Alignment::HorizontalCenter: + case Dali::Toolkit::Alignment::HORIZONTAL_CENTER: // FALLTHROUGH + default: // use center as default { - if( currentSize.width + mPadding.left + mPadding.right >= parentSize.width ) + if(currentSize.width + padding.left + padding.right >= parentSize.width) { - position.x += 0.5f * ( mPadding.left - mPadding.right ); + position.x += 0.5f * (padding.left - padding.right); } break; } - case Dali::Toolkit::Alignment::HorizontalRight: + } + + switch(verticalAlignment) + { + case Dali::Toolkit::Alignment::VERTICAL_TOP: { - position.x -= mPadding.right; + position.y += padding.top; break; } - default: + case Dali::Toolkit::Alignment::VERTICAL_BOTTOM: { - DALI_ASSERT_ALWAYS( !"Wrong horizontal alignment value" ); + position.y -= padding.bottom; break; } - } - - switch( mVerticalAlignment ) - { - case Dali::Toolkit::Alignment::VerticalTop: + case Dali::Toolkit::Alignment::VERTICAL_CENTER: // FALLTHROUGH + default: // use center as default { - position.y += mPadding.top; - break; - } - case Dali::Toolkit::Alignment::VerticalCenter: - { - if( currentSize.height + mPadding.top + mPadding.bottom >= parentSize.height ) + if(currentSize.height + padding.top + padding.bottom >= parentSize.height) { - position.y += 0.5f * ( mPadding.top - mPadding.bottom ); + position.y += 0.5f * (padding.top - padding.bottom); } break; } - case Dali::Toolkit::Alignment::VerticalBottom: - { - position.y -= mPadding.bottom; - break; - } - default: - { - DALI_ASSERT_ALWAYS( !"Wrong vertical alignment value" ); - 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 ) +Toolkit::Alignment Alignment::New(Toolkit::Alignment::Type horizontal, Toolkit::Alignment::Type vertical) { // Create the implementation, temporarily owned on stack - IntrusivePtr< Alignment > internalAlignment = new Alignment( horizontal, vertical ); + IntrusivePtr internalAlignment = new Alignment(horizontal, vertical); - // Pass ownership to Toolkit::View - Toolkit::Alignment alignment( *internalAlignment ); + // Pass ownership to Toolkit::Alignment + Toolkit::Alignment alignment(*internalAlignment); // Second-phase init of the implementation // This can only be done after the CustomActor connection has been made... @@ -386,34 +121,34 @@ Toolkit::Alignment Alignment::New( Toolkit::Alignment::Type horizontal, Toolkit: return alignment; } -void Alignment::SetAlignmentType( Toolkit::Alignment::Type type ) +void Alignment::SetAlignmentType(Toolkit::Alignment::Type type) { // Horizontal Alignment - if( type & Toolkit::Alignment::HorizontalRight ) + if(type & Toolkit::Alignment::HORIZONTAL_RIGHT) { - mHorizontal = Toolkit::Alignment::HorizontalRight; + mHorizontal = Toolkit::Alignment::HORIZONTAL_RIGHT; } - if( type & Toolkit::Alignment::HorizontalLeft ) + if(type & Toolkit::Alignment::HORIZONTAL_LEFT) { - mHorizontal = Toolkit::Alignment::HorizontalLeft; + mHorizontal = Toolkit::Alignment::HORIZONTAL_LEFT; } - if( type & Toolkit::Alignment::HorizontalCenter ) + if(type & Toolkit::Alignment::HORIZONTAL_CENTER) { - mHorizontal = Toolkit::Alignment::HorizontalCenter; + mHorizontal = Toolkit::Alignment::HORIZONTAL_CENTER; } // Vertical Alignment - if( type & Toolkit::Alignment::VerticalBottom ) + if(type & Toolkit::Alignment::VERTICAL_BOTTOM) { - mVertical = Toolkit::Alignment::VerticalBottom; + mVertical = Toolkit::Alignment::VERTICAL_BOTTOM; } - if( type & Toolkit::Alignment::VerticalTop ) + if(type & Toolkit::Alignment::VERTICAL_TOP) { - mVertical = Toolkit::Alignment::VerticalTop; + mVertical = Toolkit::Alignment::VERTICAL_TOP; } - if( type & Toolkit::Alignment::VerticalCenter ) + if(type & Toolkit::Alignment::VERTICAL_CENTER) { - mVertical = Toolkit::Alignment::VerticalCenter; + mVertical = Toolkit::Alignment::VERTICAL_CENTER; } RelayoutRequest(); @@ -421,10 +156,10 @@ void Alignment::SetAlignmentType( Toolkit::Alignment::Type type ) Toolkit::Alignment::Type Alignment::GetAlignmentType() const { - return Toolkit::Alignment::Type( mHorizontal | mVertical ); + return Toolkit::Alignment::Type(mHorizontal | mVertical); } -void Alignment::SetScaling( Toolkit::Alignment::Scaling scaling ) +void Alignment::SetScaling(Toolkit::Alignment::Scaling scaling) { mScaling = scaling; @@ -436,9 +171,9 @@ Toolkit::Alignment::Scaling Alignment::GetScaling() const return mScaling; } -void Alignment::SetPadding( const Toolkit::Alignment::Padding& padding ) +void Alignment::SetPadding(const Toolkit::Alignment::Padding& padding) { - DALI_ASSERT_ALWAYS( ( padding.left >= 0.f ) && ( padding.top >= 0.f ) && ( padding.right >= 0.f ) && ( padding.bottom >= 0.f ) ); + DALI_ASSERT_ALWAYS((padding.left >= 0.f) && (padding.top >= 0.f) && (padding.right >= 0.f) && (padding.bottom >= 0.f)); mPadding = padding; @@ -450,110 +185,122 @@ const Toolkit::Alignment::Padding& Alignment::GetPadding() const return mPadding; } -void Alignment::OnRelayout( const Vector2& size, ActorSizeContainer& container ) +void Alignment::OnInitialize() +{ + DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) { + return std::unique_ptr( + new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::FILLER)); + }); +} + +void Alignment::OnRelayout(const Vector2& size, RelayoutContainer& container) { // lay out the actors - Vector3 anchorPointAndParentOrigin = Vector3::ZERO; - anchorPointAndParentOrigin.z = 0.5f; - // anchorPoint.x is initialized to 0.0, which is HorizontalLeft - if( Toolkit::Alignment::HorizontalCenter == mHorizontal ) + Vector3 anchorPointAndParentOrigin = Vector3::ZERO; + anchorPointAndParentOrigin.z = 0.5f; + // anchorPoint.x is initialized to 0.0, which is HORIZONTAL_LEFT + if(Toolkit::Alignment::HORIZONTAL_CENTER == mHorizontal) { anchorPointAndParentOrigin.x = 0.5f; } - else if( Toolkit::Alignment::HorizontalRight == mHorizontal ) + else if(Toolkit::Alignment::HORIZONTAL_RIGHT == mHorizontal) { anchorPointAndParentOrigin.x = 1.0f; } - // anchorPoint.y is initialized to 0.0, which is VerticalTop - if( Toolkit::Alignment::VerticalCenter == mVertical ) + // anchorPoint.y is initialized to 0.0, which is VERTICAL_TOP + if(Toolkit::Alignment::VERTICAL_CENTER == mVertical) { anchorPointAndParentOrigin.y = 0.5f; } - else if( Toolkit::Alignment::VerticalBottom == mVertical ) + else if(Toolkit::Alignment::VERTICAL_BOTTOM == mVertical) { 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::SCALE_NONE: + { + // Nothing to do + renegotiate = false; + break; + } + case Toolkit::Alignment::SCALE_TO_FILL: + { + // Nothing to do, newChildSize is already full size minus padding + break; + } + case Toolkit::Alignment::SCALE_TO_FIT_KEEP_ASPECT: + { + newChildSize = currentChildSize * std::min((newChildSize.width / currentChildSize.width), (newChildSize.height / currentChildSize.height)); + break; + } + case Toolkit::Alignment::SCALE_TO_FILL_KEEP_ASPECT: + { + newChildSize = currentChildSize * std::max((newChildSize.width / currentChildSize.width), (newChildSize.height / currentChildSize.height)); + break; + } + case Toolkit::Alignment::SHRINK_TO_FIT: + { + newChildSize = Vector2(std::min(newChildSize.width, currentChildSize.width), std::min(newChildSize.height, currentChildSize.height)); + break; + } + case Toolkit::Alignment::SHRINK_TO_FIT_KEEP_ASPECT: + { + // 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.SetProperty(Actor::Property::POSITION, 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 ), - mHorizontal( horizontal ), - mVertical( vertical ), - mScaling( Toolkit::Alignment::ScaleNone ), - mPadding( 0.f, 0.f, 0.f, 0.f ) +Alignment::Alignment(Toolkit::Alignment::Type horizontal, Toolkit::Alignment::Type vertical) +: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)), + mHorizontal(horizontal), + mVertical(vertical), + mScaling(Toolkit::Alignment::SCALE_NONE), + mPadding(0.f, 0.f, 0.f, 0.f) { }