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=a58f78f8205af9d63f25b1e2d9b59e876b5eef29;hp=17dfff6a8480b1d3acd56e66e6599962f0512789;hb=8a647e87a01c5c78451653c1264a9eea81ac9b20;hpb=4b38b709efae6ba534f7d336b70dabb74c804e03 diff --git a/dali-toolkit/internal/controls/alignment/alignment-impl.cpp b/dali-toolkit/internal/controls/alignment/alignment-impl.cpp index 17dfff6..a58f78f 100644 --- a/dali-toolkit/internal/controls/alignment/alignment-impl.cpp +++ b/dali-toolkit/internal/controls/alignment/alignment-impl.cpp @@ -21,8 +21,11 @@ // EXTERNAL INCLUDES #include #include +#include +#include // INTERNAL INCLUDES +#include namespace Dali { @@ -42,333 +45,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; -}; +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: - { - position.x -= mPadding.right; - break; - } - default: + } + + switch( verticalAlignment ) + { + case Dali::Toolkit::Alignment::VERTICAL_TOP: { - DALI_ASSERT_ALWAYS( !"Wrong horizontal alignment value" ); + position.y += padding.top; break; } - } - - switch( mVerticalAlignment ) - { - case Dali::Toolkit::Alignment::VerticalTop: + case Dali::Toolkit::Alignment::VERTICAL_BOTTOM: { - position.y += mPadding.top; + position.y -= padding.bottom; break; } - case Dali::Toolkit::Alignment::VerticalCenter: + case Dali::Toolkit::Alignment::VERTICAL_CENTER: // FALLTHROUGH + default: // use center as default { - 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 ) @@ -376,7 +116,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 @@ -389,31 +129,31 @@ Toolkit::Alignment Alignment::New( Toolkit::Alignment::Type horizontal, Toolkit: 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(); @@ -450,111 +190,119 @@ 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; anchorPointAndParentOrigin.z = 0.5f; - // anchorPoint.x is initialized to 0.0, which is HorizontalLeft - if( Toolkit::Alignment::HorizontalCenter == mHorizontal ) + // 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 ), +: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), mHorizontal( horizontal ), mVertical( vertical ), - mScaling( Toolkit::Alignment::ScaleNone ), + mScaling( Toolkit::Alignment::SCALE_NONE ), mPadding( 0.f, 0.f, 0.f, 0.f ) { + DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::FILLER ) ); + } ); } Alignment::~Alignment()