/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h>
// EXTERNAL INCLUDES
+#include <cstring> // for strcmp
#include <dali/public-api/animation/animation.h>
-#include <dali/public-api/animation/active-constraint.h>
#include <dali/public-api/animation/constraint.h>
-#include <dali/public-api/events/hit-test-algorithm.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/object/type-registry-helper.h>
-#include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/integration-api/debug.h>
// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h>
+#include <dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h>
+#include <dali-toolkit/internal/visuals/visual-factory-cache.h>
+#include <dali-toolkit/internal/visuals/visual-string-constants.h>
using namespace Dali;
namespace //Unnamed namespace
{
-// To register type
+// properties set on shader, these properties have the constant value in regardless of the page status
+const char * const PROPERTY_SPINE_SHADOW ( "uSpineShadowParameter" ); // uniform for both spine and turn effect
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::PageTurnView, Toolkit::Control, NULL )
-DALI_TYPE_REGISTRATION_END()
+// properties set on actor, the value of these properties varies depending on the page status
+// properties used in turn effect
+const char * const PROPERTY_TURN_DIRECTION( "uIsTurningBack" ); // uniform
+const char * const PROPERTY_COMMON_PARAMETERS( "uCommonParameters" ); //uniform
+
+const char * const PROPERTY_PAN_DISPLACEMENT( "panDisplacement" );// property used to constrain the uniforms
+const char * const PROPERTY_PAN_CENTER( "panCenter" );// property used to constrain the uniforms
-// default grid density for page turn effect, 10 pixels by 10 pixels
-const float DEFAULT_GRID_DENSITY(10.0f);
+// default grid density for page turn effect, 20 pixels by 20 pixels
+const float DEFAULT_GRID_DENSITY(20.0f);
// to bent the page, the minimal horizontal pan start position is pageSize.x * MINIMUM_START_POSITION_RATIO
const float MINIMUM_START_POSITION_RATIO(0.6f);
mDirection = offset / mDistance;
}
- Vector2 operator()(const Vector2& current, const PropertyInput& panDisplacement)
+ void operator()( Vector2& current, const PropertyInputContainer& inputs )
{
- float displacement = panDisplacement.GetFloat();
+ float displacement = inputs[0]->GetFloat();
if( displacement < mDistance )
{
- return mOldCenter + mDirection * displacement;
+ current = mOldCenter + mDirection * displacement;
}
else
{
- return mNewCenter + Vector2(0.25f*(displacement-mDistance), 0.f);
+ current = mNewCenter + Vector2(0.25f*(displacement-mDistance), 0.f);
}
}
mStep = 1.f / pageWidth;
mSign = isTurnBack ? -1.0f : 1.0f;
mConst = isTurnBack ? -1.0f : 0.f;
- mRotation = isTurnBack ? Quaternion( -Math::PI, Vector3::YAXIS ) : Quaternion( 0.f, Vector3::YAXIS );
+ mRotation = isTurnBack ? Quaternion( Radian( -Math::PI ), Vector3::YAXIS ) : Quaternion( Radian(0.f), Vector3::YAXIS );
}
- Quaternion operator()( const Quaternion& current, const PropertyInput& panDisplacement )
+ void operator()( Quaternion& current, const PropertyInputContainer& inputs )
{
- float displacement = panDisplacement.GetFloat();
- float angle;
+ float displacement = inputs[0]->GetFloat();
if( displacement < mDistance)
{
- return mRotation;
+ current = mRotation;
}
else
{
float coef = std::max(-1.0f, mStep*(mDistance-displacement));
- angle = Math::PI*( mConst + mSign*coef );
- return Quaternion( angle, Vector3::YAXIS );
+ float angle = Math::PI * ( mConst + mSign * coef );
+ current = Quaternion( Radian( angle ), Vector3::YAXIS );
}
}
*/
struct CurrentCenterConstraint
{
- CurrentCenterConstraint( float pageWidth)
+ CurrentCenterConstraint( float pageWidth )
: mPageWidth( pageWidth )
{
mThres = pageWidth * PAGE_TURN_OVER_THRESHOLD_RATIO * 0.5f;
}
- Vector2 operator()( const Vector2& current, const PropertyInput& center, const PropertyInput& originalCenter )
+ void operator()( Vector2& current, const PropertyInputContainer& inputs )
{
- Vector2 centerPosition = center.GetVector2();
+ const Vector2& centerPosition = inputs[0]->GetVector2();
if( centerPosition.x > 0.f )
{
- return Vector2( mThres+centerPosition.x*0.5f , centerPosition.y);
+ current.x = mThres+centerPosition.x * 0.5f;
+ current.y = centerPosition.y;
}
else
{
- Vector2 centerOrigin = originalCenter.GetVector2();
+ const Vector2& centerOrigin = inputs[1]->GetVector2();
Vector2 direction = centerOrigin - Vector2(mThres, centerPosition.y);
float coef = 1.f+(centerPosition.x*2.f / mPageWidth);
- // Todo: when coef <= 0, the page is flat, slow down the last moment of the page stretch by 10 times to avoid a small bounce
+ // when coef <= 0, the page is flat, slow down the last moment of the page stretch by 10 times to avoid a small bounce
if(coef < 0.025f)
{
coef = (coef+0.225f)/10.0f;
}
- return centerOrigin - direction * coef;
+ current = centerOrigin - direction * coef;
}
}
: mThres( thres )
{}
- float operator()( const float current, const PropertyInput& currentCenter, const PropertyInput& originalCenter, const PropertyInput& panDisplacement)
+ void operator()( float& blurStrength, const PropertyInputContainer& inputs )
{
- float displacement = panDisplacement.GetFloat();
- float blurStrength;
+ float displacement = inputs[2]->GetFloat();
if( EqualsZero(displacement))
{
- Vector2 cur = currentCenter.GetVector2();
- Vector2 ori = originalCenter.GetVector2();
+ const Vector2& cur = inputs[0]->GetVector2();
+ const Vector2& ori = inputs[1]->GetVector2();
blurStrength = 5.f*(ori-cur).Length() / mThres;
}
else
}
blurStrength = blurStrength > 1.f ? 1.f : ( blurStrength < 0.f ? 0.f : blurStrength );
- return blurStrength;
}
float mThres;
};
-bool IsActorHittableFunction( Actor actor, Dali::HitTestAlgorithm::TraverseType type )
-{
- bool hittable = false;
-
- switch (type)
- {
- case Dali::HitTestAlgorithm::CHECK_ACTOR:
- {
- // Check whether the actor is visible and not fully transparent.
- Property::Index propertyActorHittable = actor.GetPropertyIndex(Toolkit::PageFactory::ACTOR_HITTABLE);
- if( actor.IsSensitive()
- && actor.IsVisible()
- && actor.GetCurrentWorldColor().a > 0.01f// not FULLY_TRANSPARENT
- && ( propertyActorHittable != Property::INVALID_INDEX &&
- actor.GetProperty<bool>( propertyActorHittable ) ) )
- {
- hittable = true;
- }
- break;
- }
- case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
- {
- if( actor.IsSensitive() && actor.IsVisible() ) // Actor is visible, if not visible then none of its children are visible.
- {
- hittable = true;
- }
- break;
- }
- default:
- {
- break;
- }
- }
-
- return hittable;
-}
-
} //unnamed namespace
namespace Dali
namespace Internal
{
+namespace
+{
+
+BaseHandle Create()
+{
+ // empty handle as we cannot create PageTurnView(but type registered for page turn signal)
+ return BaseHandle();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::PageTurnView, Toolkit::Control, Create );
+
+DALI_PROPERTY_REGISTRATION( Toolkit, PageTurnView, "pageSize", VECTOR2, PAGE_SIZE )
+DALI_PROPERTY_REGISTRATION( Toolkit, PageTurnView, "currentPageId", INTEGER, CURRENT_PAGE_ID )
+DALI_PROPERTY_REGISTRATION( Toolkit, PageTurnView, "spineShadow", VECTOR2, SPINE_SHADOW )
+
+DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pageTurnStarted", SIGNAL_PAGE_TURN_STARTED )
+DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pageTurnFinished", SIGNAL_PAGE_TURN_FINISHED )
+DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pagePanStarted", SIGNAL_PAGE_PAN_STARTED )
+DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pagePanFinished", SIGNAL_PAGE_PAN_FINISHED )
+
+DALI_TYPE_REGISTRATION_END()
+
+}
+
// these several constants are also used in the derived classes
+const char * const PageTurnView::PROPERTY_TEXTURE_WIDTH( "uTextureWidth" ); // uniform name
+const char * const PageTurnView::PROPERTY_ORIGINAL_CENTER( "originalCenter" ); // property used to constrain the uniform
+const char * const PageTurnView::PROPERTY_CURRENT_CENTER( "currentCenter" );// property used to constrain the uniform
const int PageTurnView::MAXIMUM_TURNING_NUM = 4;
const int PageTurnView::NUMBER_OF_CACHED_PAGES_EACH_SIDE = MAXIMUM_TURNING_NUM + 1;
const int PageTurnView::NUMBER_OF_CACHED_PAGES = NUMBER_OF_CACHED_PAGES_EACH_SIDE*2;
const float PageTurnView::STATIC_PAGE_INTERVAL_DISTANCE = 1.0f;
+PageTurnView::Page::Page()
+: isTurnBack( false )
+{
+ actor = Actor::New();
+ actor.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+ actor.SetVisible( false );
+
+ propertyPanDisplacement = actor.RegisterProperty( PROPERTY_PAN_DISPLACEMENT, 0.f );
+ propertyPanCenter = actor.RegisterProperty(PROPERTY_PAN_CENTER, Vector2::ZERO);
+
+ propertyOriginalCenter = actor.RegisterProperty(PROPERTY_ORIGINAL_CENTER, Vector2::ZERO);
+ propertyCurrentCenter = actor.RegisterProperty(PROPERTY_CURRENT_CENTER, Vector2::ZERO);
+ Matrix zeroMatrix(true);
+ actor.RegisterProperty(PROPERTY_COMMON_PARAMETERS, zeroMatrix);
+ propertyTurnDirection = actor.RegisterProperty(PROPERTY_TURN_DIRECTION, -1.f);
+}
+
+void PageTurnView::Page::SetTexture( Texture texture )
+{
+ if( !textureSet )
+ {
+ textureSet = TextureSet::New();
+ }
+ textureSet.SetTexture( 0u, texture );
+}
+
+void PageTurnView::Page::UseEffect(Shader newShader)
+{
+ shader = newShader;
+ if( renderer )
+ {
+ renderer.SetShader( shader );
+ }
+}
+
+void PageTurnView::Page::UseEffect(Shader newShader, Geometry geometry)
+{
+ UseEffect( newShader );
+
+ if( !renderer )
+ {
+ renderer = Renderer::New( geometry, shader );
+
+ if( !textureSet )
+ {
+ textureSet = TextureSet::New();
+ }
+
+ renderer.SetTextures( textureSet );
+ renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON );
+ actor.AddRenderer( renderer );
+ }
+}
+
+void PageTurnView::Page::ChangeTurnDirection()
+{
+ isTurnBack = !isTurnBack;
+ actor.SetProperty( propertyTurnDirection, isTurnBack ? 1.f : -1.f );
+}
+
+void PageTurnView::Page::SetPanDisplacement(float value)
+{
+ actor.SetProperty( propertyPanDisplacement, value );
+}
+
+void PageTurnView::Page::SetPanCenter( const Vector2& value )
+{
+ actor.SetProperty( propertyPanCenter, value );
+}
+
+void PageTurnView::Page::SetOriginalCenter( const Vector2& value )
+{
+ actor.SetProperty( propertyOriginalCenter, value );
+}
+
+void PageTurnView::Page::SetCurrentCenter( const Vector2& value )
+{
+ actor.SetProperty( propertyCurrentCenter, value );
+}
+
PageTurnView::PageTurnView( PageFactory& pageFactory, const Vector2& pageSize )
-: Control( REQUIRES_TOUCH_EVENTS ),
- mPageFactory( pageFactory ),
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
+ mPageFactory( &pageFactory ),
mPageSize( pageSize ),
- mTotalPageCount( 0 ),
- mIsEditMode( false ),
- mNeedOffscreenRendering( false ),
- mPanning( false ),
mSpineShadowParameter( DEFAULT_SPINE_SHADOW_PARAMETER ),
- mCurrentPageIndex( 0 ),
- mIndex( 0 ),
- mPress( false ),
- mPageUpdated( true ),
mDistanceUpCorner( 0.f ),
mDistanceBottomCorner( 0.f ),
mPanDisplacement( 0.f ),
+ mTotalPageCount( 0 ),
+ mCurrentPageIndex( 0 ),
+ mTurningPageIndex( 0 ),
+ mIndex( 0 ),
+ mSlidingCount( 0 ),
+ mAnimatingCount( 0 ),
mConstraints( false ),
+ mPress( false ),
+ mPageUpdated( true ),
mPageTurnStartedSignal(),
mPageTurnFinishedSignal(),
mPagePanStartedSignal(),
mPagePanFinishedSignal()
{
- mPageActors.resize( NUMBER_OF_CACHED_PAGES );
- mIsAnimating.resize( MAXIMUM_TURNING_NUM );
- mIsSliding.resize( MAXIMUM_TURNING_NUM );
- mTurnEffect.resize( MAXIMUM_TURNING_NUM );
- mPropertyPanDisplacement.resize( MAXIMUM_TURNING_NUM );
- mPropertyCurrentCenter.resize( MAXIMUM_TURNING_NUM );
}
PageTurnView::~PageTurnView()
void PageTurnView::OnInitialize()
{
- // create the two book spine effect for static images, left and right side pages respectively
- mSpineEffectFront = PageTurnBookSpineEffect::New();
- mSpineEffectFront.SetIsBackImageVisible( false );
- mSpineEffectFront.SetPageWidth( mPageSize.width );
- mSpineEffectFront.SetShadowWidth( 0.f );
- mSpineEffectFront.SetSpineShadowParameter( mSpineShadowParameter );
-
- mSpineEffectBack = PageTurnBookSpineEffect::New();
- mSpineEffectBack.SetIsBackImageVisible( true );
- mSpineEffectBack.SetPageWidth( mPageSize.width );
- mSpineEffectBack.SetShadowWidth( 0.f );
- mSpineEffectBack.SetSpineShadowParameter( mSpineShadowParameter );
-
- // create the page turn effect objects
- for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
+ // create the book spine effect for static pages
+ Property::Map spineEffectMap = CreatePageTurnBookSpineEffect();
+ mSpineEffectShader = CreateShader( spineEffectMap );
+ mSpineEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
+ // create the turn effect for turning pages
+ Property::Map turnEffectMap = CreatePageTurnEffect();
+ mTurnEffectShader = CreateShader( turnEffectMap );
+ mTurnEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
+
+ // create the grid geometry for pages
+ uint16_t width = static_cast<uint16_t>(mPageSize.width / DEFAULT_GRID_DENSITY + 0.5f);
+ uint16_t height = static_cast<uint16_t>(mPageSize.height / DEFAULT_GRID_DENSITY + 0.5f);
+ mGeometry = VisualFactoryCache::CreateGridGeometry( Uint16Pair( width, height ) );
+
+ mPages.reserve( NUMBER_OF_CACHED_PAGES );
+ for( int i = 0; i < NUMBER_OF_CACHED_PAGES; i++ )
{
- mTurnEffect[i] = Toolkit::PageTurnEffect::New( false );
- mTurnEffect[i].SetProperty( ShaderEffect::Property::GRID_DENSITY, Property::Value( DEFAULT_GRID_DENSITY ) );
- mTurnEffect[i].SetPageSize( mPageSize );
- mTurnEffect[i].SetShadowWidth(0.f);
- mTurnEffect[i].SetSpineShadowParameter( mSpineShadowParameter );
- mIsAnimating[i] = false;
- mIsSliding[i] = false;
- mPropertyPanDisplacement[i] = Self().RegisterProperty("PAN_DISPLACEMENT_PROPERTY_"+i, 0.0f);
- mPropertyCurrentCenter[i] = Self().RegisterProperty("CURRENT_CENTER_PROPERTY_"+i, Vector2(0.0f,0.0f));
+ mPages.push_back( Page() );
+ mPages[i].actor.SetSize( mPageSize );
+ Self().Add( mPages[i].actor );
}
+ // create the layer for turning pages
mTurningPageLayer = Layer::New();
mTurningPageLayer.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
- // Set control size and the parent origin of turningPageLayer
+ mTurningPageLayer.SetBehavior(Layer::LAYER_3D);
+ mTurningPageLayer.Raise();
+
+ // Set control size and the parent origin of page layers
OnPageTurnViewInitialize();
- mRootOnScreen = Actor::New();
- mRootOnScreen.SetPositionInheritanceMode( USE_PARENT_POSITION );
- mRootOnScreen.SetSize( mControlSize );
- Self().Add( mRootOnScreen );
- mRootOnScreen.Add(mTurningPageLayer);
-
- mTotalPageCount = static_cast<int>( mPageFactory.GetNumberOfPages() );
- mNeedOffscreenRendering = mPageFactory.IsOffscreenRenderingNeeded();
- if( mNeedOffscreenRendering )
- {
- SetupRenderTasks();
- }
+ Self().Add(mTurningPageLayer);
+ mTotalPageCount = static_cast<int>( mPageFactory->GetNumberOfPages() );
// add pages to the scene, and set depth for the stacked pages
for( int i = 0; i < NUMBER_OF_CACHED_PAGES_EACH_SIDE; i++ )
{
AddPage( i );
- if(mPageActors[i])
- {
- mPageActors[i].SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
- }
+ mPages[i].actor.SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
}
+ mPages[0].actor.SetVisible(true);
// enable the pan gesture which is attached to the control
EnableGestureDetection(Gesture::Type(Gesture::Pan));
-
- mPageFactory.PageRefreshSignal().Connect(this, &PageTurnView::RenderPage);
}
-void PageTurnView::SetupRenderTasks()
+Shader PageTurnView::CreateShader( const Property::Map& shaderMap )
{
- mPageSourceActor.resize( NUMBER_OF_CACHED_PAGES );
- mOffscreenTask.resize( NUMBER_OF_CACHED_PAGES );
- mRenderedPage.resize( NUMBER_OF_CACHED_PAGES );
-
- mCameraActor = CameraActor::New(mControlSize);
- mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
- mCameraActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
- mCameraActor.SetInheritScale( false );
- Self().Add(mCameraActor);
-
- RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
- for(int i=0; i<NUMBER_OF_CACHED_PAGES; i++)
+ Shader shader;
+ Property::Value* shaderValue = shaderMap.Find( Toolkit::Visual::Property::SHADER, CUSTOM_SHADER );
+ Property::Map shaderSource;
+ if( shaderValue && shaderValue->Get( shaderSource ) )
{
- mPageSourceActor[i] = Actor::New();
- mPageSourceActor[i].SetParentOrigin(ParentOrigin::CENTER);
- mPageSourceActor[i].SetColorMode( USE_OWN_COLOR );
- mPageSourceActor[i].SetPositionInheritanceMode( DONT_INHERIT_POSITION );
- mPageSourceActor[i].SetInheritScale( false );
- Self().Add( mPageSourceActor[i] );
- mPageSourceActor[i].SetSensitive( false );
-
- mRenderedPage[i] = FrameBufferImage::New( mControlSize.width, mControlSize.height, Pixel::RGB8888, Image::UNUSED );
- mOffscreenTask[i] = taskList.CreateTask();
- mOffscreenTask[i].SetRefreshRate( RenderTask::REFRESH_ONCE );
- mOffscreenTask[i].SetCameraActor(mCameraActor);
- mOffscreenTask[i].SetSourceActor( mPageSourceActor[i] );
- mOffscreenTask[i].SetExclusive(true);
- mOffscreenTask[i].SetInputEnabled( false );
- mOffscreenTask[i].SetClearEnabled( true );
- mOffscreenTask[i].SetClearColor( Vector4(0.f,0.f,0.f,0.f) );
- mOffscreenTask[i].SetTargetFrameBuffer( mRenderedPage[i] );
- mOffscreenTask[i].SetScreenToFrameBufferMappingActor( Self() );
- }
+ std::string vertexShader;
+ Property::Value* vertexShaderValue = shaderSource.Find( Toolkit::Visual::Shader::Property::VERTEX_SHADER, CUSTOM_VERTEX_SHADER );
+ if( !vertexShaderValue || !vertexShaderValue->Get( vertexShader ) )
+ {
+ DALI_LOG_ERROR("PageTurnView::CreateShader failed: vertex shader source is not available.\n");
+ }
+ std::string fragmentShader;
+ Property::Value* fragmentShaderValue = shaderSource.Find( Toolkit::Visual::Shader::Property::FRAGMENT_SHADER, CUSTOM_FRAGMENT_SHADER );
+ if( !fragmentShaderValue || !fragmentShaderValue->Get( fragmentShader ) )
+ {
+ DALI_LOG_ERROR("PageTurnView::CreateShader failed: fragment shader source is not available.\n");
+ }
+ shader = Shader::New( vertexShader, fragmentShader );
+ }
+ else
+ {
+ DALI_LOG_ERROR("PageTurnView::CreateShader failed: shader source is not available.\n");
+ }
+
+ return shader;
}
void PageTurnView::SetupShadowView()
mShadowView.SetPointLightFieldOfView( Math::PI / 2.0f);
mShadowView.SetShadowColor(DEFAULT_SHADOW_COLOR);
- mShadowLayer = Layer::New();
- mShadowLayer.SetPositionInheritanceMode( USE_PARENT_POSITION );
- mRootOnScreen.Add(mShadowLayer);
- mShadowLayer.Raise();
-
- mShadowPlane = CreateSolidColorActor( Vector4 (0.0f, 0.0f, 0.0f, 0.0f) );
- mShadowPlane.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
- mShadowPlane.SetSize( mControlSize );
- mShadowLayer.Add( mShadowPlane );
- mShadowView.SetShadowPlane( mShadowPlane );
+ mShadowPlaneBackground = Actor::New();
+ mShadowPlaneBackground.SetParentOrigin( ParentOrigin::CENTER );
+ mShadowPlaneBackground.SetSize( mControlSize );
+ Self().Add( mShadowPlaneBackground );
+ mShadowView.SetShadowPlaneBackground( mShadowPlaneBackground );
mPointLight = Actor::New();
mPointLight.SetAnchorPoint( origin );
mPointLight.SetParentOrigin( origin );
mPointLight.SetPosition( 0.f, 0.f, mPageSize.width*POINT_LIGHT_HEIGHT_RATIO );
- mRootOnScreen.Add( mPointLight );
+ Self().Add( mPointLight );
mShadowView.SetPointLight( mPointLight );
mTurningPageLayer.Add( mShadowView );
mShadowView.Activate();
}
-void PageTurnView::OnControlStageConnection()
+void PageTurnView::OnStageConnection( int depth )
{
SetupShadowView();
- mTurningPageLayer.RaiseToTop();
+
+ Control::OnStageConnection( depth );
}
-void PageTurnView::OnControlStageDisconnection()
+void PageTurnView::OnStageDisconnection()
{
if(mShadowView)
{
- Self().Remove(mPointLight);
- Self().Remove(mShadowLayer);
- mTurningPageLayer.Remove( mShadowView );
+ mShadowView.RemoveConstraints();
+ mPointLight.Unparent();
+ mShadowPlaneBackground.Unparent();
+ mShadowView.Unparent();
}
// make sure the status of the control is updated correctly when the pan gesture is interrupted
- if(mPanning)
+ StopTurning();
+
+ Control::OnStageDisconnection();
+}
+
+void PageTurnView::SetPageSize( const Vector2& pageSize )
+{
+ mPageSize = pageSize;
+
+ if( mPointLight )
{
- mPanning = false;
+ mPointLight.SetPosition( 0.f, 0.f, mPageSize.width*POINT_LIGHT_HEIGHT_RATIO );
+ }
- mRootOnScreen.Add(mPanActor);
- mIsAnimating[mIndex] = false;
- mPanActor.RemoveConstraints();
- mTurnEffect[mIndex].RemoveConstraints();
- mPageUpdated = true;
+ for( size_t i=0; i<mPages.size(); i++ )
+ {
+ mPages[i].actor.SetSize( mPageSize );
+ }
- SetSpineEffect( mPanActor, mIsTurnBack[mPanActor] );
+ OnPageTurnViewInitialize();
+
+ if( mShadowPlaneBackground )
+ {
+ mShadowPlaneBackground.SetSize( mControlSize );
}
}
-void PageTurnView::OnControlSizeSet( const Vector3& size )
+Vector2 PageTurnView::GetPageSize()
{
- // disable the SetSize of the control from the application
- Self().SetSize( mControlSize );
+ return mPageSize;
}
void PageTurnView::SetSpineShadowParameter( const Vector2& spineShadowParameter )
mSpineShadowParameter = spineShadowParameter;
// set spine shadow parameter to all the shader effects
- mSpineEffectFront.SetSpineShadowParameter( mSpineShadowParameter );
- mSpineEffectBack.SetSpineShadowParameter( mSpineShadowParameter );
- for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
- {
- mTurnEffect[i].SetSpineShadowParameter( mSpineShadowParameter );
- }
+ mSpineEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
+ mTurnEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
}
Vector2 PageTurnView::GetSpineShadowParameter()
void PageTurnView::GoToPage( unsigned int pageId )
{
- int pageIdx = static_cast<int>(pageId);
- // record the new current page index
- mCurrentPageIndex = pageIdx;
+ int pageIdx = Clamp( static_cast<int>(pageId), 0, mTotalPageCount-1);
- // clear the old pages
- for(int i = 0; i < NUMBER_OF_CACHED_PAGES; i++ )
+ if( mCurrentPageIndex == pageIdx )
{
- if( mPageActors[i] )
- {
- mPageActors[i].Unparent();
- mPageActors[i].Reset();
- }
+ return;
}
+ // if any animation ongoing, stop it.
+ StopTurning();
+
+ // record the new current page index
+ mCurrentPageIndex = pageIdx;
+
+
// add the current page and the pages right before and after it
for( int i = pageIdx - NUMBER_OF_CACHED_PAGES_EACH_SIDE; i < pageIdx + NUMBER_OF_CACHED_PAGES_EACH_SIDE; i++ )
{
AddPage( i );
}
+
+ mPages[pageId%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true);
+ if( pageId > 0 )
+ {
+ mPages[(pageId-1)%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true);
+ }
// set ordered depth to the stacked pages
OrganizePageDepth();
}
return static_cast< unsigned int >( mCurrentPageIndex );
}
-Actor PageTurnView::EnterEditMode()
-{
- if( mNeedOffscreenRendering )
- {
- DALI_ASSERT_ALWAYS( mCurrentPageIndex >= 0 );
-
- mIsEditMode = true;
-
- int index = mCurrentPageIndex % NUMBER_OF_CACHED_PAGES;
- mOffscreenTask[index].SetInputEnabled( true );
- mPageSourceActor[index].SetSensitive( true );
- mOffscreenTask[index].SetRefreshRate( RenderTask::REFRESH_ALWAYS );
-
- mRootOnScreen.SetSensitive(false);
-
- return mPageSourceActor[index].GetChildAt( 0 );
- }
- else
- {
- return Actor();
- }
-}
-
-void PageTurnView::LeaveEditMode()
-{
- if( mNeedOffscreenRendering )
- {
- DALI_ASSERT_ALWAYS( mCurrentPageIndex >= 0 );
-
- mIsEditMode = false;
-
- int index = mCurrentPageIndex % NUMBER_OF_CACHED_PAGES;
- mOffscreenTask[index].SetInputEnabled( false );
- mPageSourceActor[index].SetSensitive( false );
- mOffscreenTask[index].SetRefreshRate( RenderTask::REFRESH_ONCE );
-
- mRootOnScreen.SetSensitive(true);
- }
-}
-
-Actor PageTurnView::GetHitActor( Vector2& screenCoordinates, Vector2& actorCoordinates )
-{
- if( mNeedOffscreenRendering && mCurrentPageIndex < mTotalPageCount)
- {
- int index = mCurrentPageIndex % NUMBER_OF_CACHED_PAGES;
-
- Dali::HitTestAlgorithm::Results results;
- if( !mOffscreenTask[index].GetInputEnabled() )
- {
- mOffscreenTask[index].SetInputEnabled( true );
- mPageSourceActor[index].SetSensitive( true );
- Dali::HitTestAlgorithm::HitTest( mOffscreenTask[index], screenCoordinates, results, IsActorHittableFunction );
- mOffscreenTask[index].SetInputEnabled( false );
- mPageSourceActor[index].SetSensitive( false );
- }
- else
- {
- Dali::HitTestAlgorithm::HitTest( mOffscreenTask[index], screenCoordinates, results, IsActorHittableFunction );
- }
- actorCoordinates = results.actorCoordinates;
- return results.actor;
- }
- else
- {
- return Actor();
- }
-}
-
void PageTurnView::AddPage( int pageIndex )
{
if(pageIndex > -1 && pageIndex < mTotalPageCount) // whether the page is available from the page factory
{
int index = pageIndex % NUMBER_OF_CACHED_PAGES;
- ImageActor newPage;
- if( mNeedOffscreenRendering )
- {
- Actor source = mPageFactory.NewPage( pageIndex );
- if( mPageSourceActor[index].GetChildCount() > 0 )
- {
- mPageSourceActor[index].Remove( mPageSourceActor[index].GetChildAt( 0 ) );
- }
- mPageSourceActor[index].Add( source );
- mOffscreenTask[index].SetRefreshRate( RenderTask::REFRESH_ONCE );
- newPage = NewPageFromRenderBuffer( pageIndex );
- }
- else
- {
- newPage= ImageActor::DownCast( mPageFactory.NewPage( pageIndex ) );
- DALI_ASSERT_ALWAYS( newPage );
- }
- newPage.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
- newPage.SetParentOrigin( ParentOrigin::CENTER_LEFT );
- newPage.SetSize( mPageSize );
- mRootOnScreen.Add( newPage );
- mPageActors[index] = newPage;
+
+ Texture newPage;
+ newPage = mPageFactory->NewPage( pageIndex );
+ DALI_ASSERT_ALWAYS( newPage && "must pass in valid texture" );
bool isLeftSide = ( pageIndex < mCurrentPageIndex );
- mIsTurnBack[ newPage ] = isLeftSide;
- if( isLeftSide )
+ if( mPages[index].isTurnBack != isLeftSide )
{
- // new page is added to the left side, so need to rotate it 180 degrees
- newPage.RotateBy( Degree(-180.0f ), Vector3::YAXIS );
- }
- else
- {
- SetShaderEffect( newPage, mSpineEffectFront);
+ mPages[index].ChangeTurnDirection();
}
+ float degree = isLeftSide ? 180.f :0.f;
+ mPages[index].actor.SetOrientation( Degree( degree ), Vector3::YAXIS );
+ mPages[index].actor.SetVisible( false );
+ mPages[index].UseEffect( mSpineEffectShader, mGeometry );
+ mPages[index].SetTexture( newPage );
+
// For Portrait, nothing to do
- // For Landscape, set spineEffectBack to the new effect if it is in the left side, and set properties to the back image actor if it exists
- OnAddPage( newPage, isLeftSide );
+ // For Landscape, set the parent origin to CENTER
+ OnAddPage( mPages[index].actor, isLeftSide );
}
}
if( pageIndex > -1 && pageIndex < mTotalPageCount)
{
int index = pageIndex % NUMBER_OF_CACHED_PAGES;
- mPageActors[index].Unparent();
- mIsTurnBack.erase( mPageActors[index] );
- mPageActors[index].Reset();
- if( mNeedOffscreenRendering )
- {
- mPageSourceActor[index].Remove( mPageSourceActor[index].GetChildAt( 0 ) );
- }
- }
-}
-
-void PageTurnView::RenderPage( int pageIndex )
-{
- if( pageIndex > std::max(-1, mCurrentPageIndex - NUMBER_OF_CACHED_PAGES_EACH_SIDE -1)
- && pageIndex < std::min(mTotalPageCount, mCurrentPageIndex + NUMBER_OF_CACHED_PAGES_EACH_SIDE))
- {
- int index = pageIndex % NUMBER_OF_CACHED_PAGES;
- mOffscreenTask[index].SetRefreshRate( RenderTask::REFRESH_ONCE );
- }
-}
-
-void PageTurnView::RefreshAll()
-{
- mTotalPageCount = static_cast<int>( mPageFactory.GetNumberOfPages() );
- if( mTotalPageCount > 0 )
- {
- if(mCurrentPageIndex < mTotalPageCount)
- {
- GoToPage( mCurrentPageIndex );
- }
- else
- {
- GoToPage( mCurrentPageIndex-- );
- }
+ mPages[index].actor.SetVisible(false);
}
}
-void PageTurnView::RefreshCurrentPage()
-{
- RenderPage( mCurrentPageIndex );
-}
-
void PageTurnView::OnPan( const PanGesture& gesture )
{
- if( mIsEditMode )
- {
- // when interrupted by the call of DisplayCurrentPageSourceActor(),
- // make sure the panFinished is always called before stopping to responding the gesture
- // so the status of the control is updated correctly
- if(mPanning)
- {
- mPanning = false;
- PanFinished( SetPanPosition( gesture.position ), gesture.GetSpeed() );
- }
-
- return;
- }
// the pan gesture is attached to control itself instead of each page
switch( gesture.state )
{
case Gesture::Started:
{
- mPanning = true;
- // to find out whether the undergoing turning page number already reaches the maximum allowed
- // and get one idle index when it is animatable
- bool animatable = false;
- for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
- {
- if( !mIsAnimating[mIndex] )
- {
- animatable = true;
- break;
- }
- if( mIsSliding[mIndex] )
- {
- animatable = false;
- break;
- }
- mIndex++;
- mIndex = mIndex % MAXIMUM_TURNING_NUM;
- }
-
- if( mPageUpdated && animatable )
+ // check whether the undergoing turning page number already reaches the maximum allowed
+ if( mPageUpdated && mAnimatingCount< MAXIMUM_TURNING_NUM && mSlidingCount < 1 )
{
SetPanActor( gesture.position ); // determine which page actor is panned
- if(mPanActor && mPanActor.GetParent() != mRootOnScreen) // if the page is added to turning layer,it is undergoing an animation currently
+ if( mTurningPageIndex != -1 && mPages[mTurningPageIndex % NUMBER_OF_CACHED_PAGES].actor.GetParent() != Self()) // if the page is added to turning layer,it is undergoing an animation currently
{
- mPanActor.Reset();
+ mTurningPageIndex = -1;
}
PanStarted( SetPanPosition( gesture.position ) ); // pass in the pan position in the local page coordinate
}
else
{
- mPanActor.Reset();
+ mTurningPageIndex = -1;
}
break;
}
case Gesture::Finished:
case Gesture::Cancelled:
{
- mPanning = false;
PanFinished( SetPanPosition( gesture.position ), gesture.GetSpeed() );
break;
}
{
mPressDownPosition = gesturePosition;
- if( !mPanActor )
+ if( mTurningPageIndex == -1 )
{
return;
}
+ mIndex = mTurningPageIndex % NUMBER_OF_CACHED_PAGES;
+
mOriginalCenter = gesturePosition;
- mTurnEffect[mIndex].SetIsTurningBack( mIsTurnBack[ mPanActor] );
mPress = false;
mPageUpdated = false;
void PageTurnView::PanContinuing( const Vector2& gesturePosition )
{
- if( !mPanActor )
+ if( mTurningPageIndex == -1 )
{
return;
}
{
mDistanceUpCorner = mOriginalCenter.Length();
mDistanceBottomCorner = ( mOriginalCenter - Vector2( 0.0f, mPageSize.height ) ).Length();
- mShadowView.Add( mPanActor );
- SetShaderEffect( mPanActor, mTurnEffect[mIndex] );
- mTurnEffect[mIndex].SetOriginalCenter( mOriginalCenter );
+ mShadowView.Add( mPages[mIndex].actor );
+ mPages[mIndex].UseEffect( mTurnEffectShader );
+ mPages[mIndex].SetOriginalCenter( mOriginalCenter );
mCurrentCenter = mOriginalCenter;
- mTurnEffect[mIndex].SetCurrentCenter( mCurrentCenter );
+ mPages[mIndex].SetCurrentCenter( mCurrentCenter );
mPanDisplacement = 0.f;
- mConstraints = true;
+ mConstraints = false;
mPress = true;
- mIsAnimating[mIndex] = true;
+ mAnimatingCount++;
- mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mCurrentPageIndex + ( ( mIsTurnBack[mPanActor] ) ? -1 : 0 ) ), !mIsTurnBack[mPanActor] );
+ mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mTurningPageIndex), !mPages[mIndex].isTurnBack );
+ int id = mTurningPageIndex + (mPages[mIndex].isTurnBack ? -1 : 1);
+ if( id >=0 && id < mTotalPageCount )
+ {
+ mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true);
+ }
mShadowView.RemoveConstraints();
Actor self = Self();
- self.SetProperty( mPropertyPanDisplacement[mIndex], 0.f );
- Constraint shadowBlurStrengthConstraint = Constraint::New<float>( mShadowView.GetBlurStrengthPropertyIndex(),
- Source(mTurnEffect[mIndex], mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetCurrentCenterPropertyName())),
- Source(mTurnEffect[mIndex], mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetOriginalCenterPropertyName())),
- Source( self, mPropertyPanDisplacement[mIndex] ),
- ShadowBlurStrengthConstraint( mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO ) );
- mShadowView.ApplyConstraint( shadowBlurStrengthConstraint );
+ mPages[mIndex].SetPanDisplacement( 0.f );
+
+ Constraint shadowBlurStrengthConstraint = Constraint::New<float>( mShadowView, mShadowView.GetBlurStrengthPropertyIndex(), ShadowBlurStrengthConstraint( mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO ) );
+ shadowBlurStrengthConstraint.AddSource( Source(mPages[mIndex].actor, mPages[mIndex].propertyCurrentCenter) );
+ shadowBlurStrengthConstraint.AddSource( Source(mPages[mIndex].actor, mPages[mIndex].propertyOriginalCenter) );
+ shadowBlurStrengthConstraint.AddSource( Source(mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement) );
+ shadowBlurStrengthConstraint.Apply();
}
}
else
{
// set the property values used by the constraints
mPanDisplacement = mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO - currentCenter.x;
- Self().SetProperty( mPropertyPanDisplacement[mIndex], mPanDisplacement );
- Self().SetProperty( mPropertyCurrentCenter[mIndex], currentCenter );
+ mPages[mIndex].SetPanDisplacement( mPanDisplacement );
+ mPages[mIndex].SetPanCenter( currentCenter );
// set up the OriginalCenterConstraint and CurrentCebterConstraint to the PageTurnEdffect
// also set up the RotationConstraint to the page actor
- if( mConstraints )
+ if( !mConstraints )
{
Vector2 corner;
// the corner position need to be a little far away from the page edge to ensure the whole page is lift up
/( offset.x*offset.x + offset.y*offset.y );
offset *= k;
Actor self = Self();
- Source source(self, mPropertyPanDisplacement[mIndex]);
- Property::Index shaderOriginalCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetOriginalCenterPropertyName());
- Constraint originalCenterConstraint = Constraint::New<Vector2>( shaderOriginalCenterPropertyIndex ,
- source,
- OriginalCenterConstraint( mOriginalCenter, offset ));
- mTurnEffect[mIndex].ApplyConstraint( originalCenterConstraint );
+ Constraint originalCenterConstraint = Constraint::New<Vector2>( mPages[mIndex].actor, mPages[mIndex].propertyOriginalCenter, OriginalCenterConstraint( mOriginalCenter, offset ));
+ originalCenterConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement ) );
+ originalCenterConstraint.Apply();
- Property::Index shaderCurrentCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex(mTurnEffect[mIndex].PageTurnEffect::GetCurrentCenterPropertyName());
- Constraint currentCenterConstraint = Constraint::New<Vector2>( shaderCurrentCenterPropertyIndex,
- Source(self, mPropertyCurrentCenter[mIndex]),
- Source(mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex),
- CurrentCenterConstraint(mPageSize.width));
- mTurnEffect[mIndex].ApplyConstraint( currentCenterConstraint );
+ Constraint currentCenterConstraint = Constraint::New<Vector2>( mPages[mIndex].actor, mPages[mIndex].propertyCurrentCenter, CurrentCenterConstraint(mPageSize.width));
+ currentCenterConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyPanCenter ) );
+ currentCenterConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyOriginalCenter ) );
+ currentCenterConstraint.Apply();
- GetImpl( mTurnEffect[mIndex] ).ApplyInternalConstraint();
+ PageTurnApplyInternalConstraint( mPages[mIndex].actor, mPageSize.height );
float distance = offset.Length();
- Constraint rotationConstraint = Constraint::New<Quaternion>( Actor::Property::ORIENTATION,
- Source( self, mPropertyPanDisplacement[mIndex] ),
- RotationConstraint(distance, mPageSize.width, mIsTurnBack[mPanActor]));
- mPanActor.ApplyConstraint( rotationConstraint );
+ Constraint rotationConstraint = Constraint::New<Quaternion>( mPages[mIndex].actor, Actor::Property::ORIENTATION, RotationConstraint(distance, mPageSize.width, mPages[mIndex].isTurnBack));
+ rotationConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement ) );
+ rotationConstraint.Apply();
- mConstraints = false;
+ mConstraints = true;
}
}
else
{
- if(!mConstraints) // remove the constraint is the pan position move back to far away from the spine
+ if(mConstraints) // remove the constraint is the pan position move back to far away from the spine
{
- mPanActor.RemoveConstraints();
- mTurnEffect[mIndex].RemoveConstraints();
- mTurnEffect[mIndex].SetOriginalCenter( mOriginalCenter );
- mConstraints = true;
+ mPages[mIndex].actor.RemoveConstraints();
+ mPages[mIndex].SetOriginalCenter(mOriginalCenter );
+ mConstraints = false;
mPanDisplacement = 0.f;
}
- mTurnEffect[mIndex].SetCurrentCenter( currentCenter );
+ mPages[mIndex].SetCurrentCenter( currentCenter );
mCurrentCenter = currentCenter;
- GetImpl( mTurnEffect[mIndex] ).ApplyInternalConstraint();
+ PageTurnApplyInternalConstraint(mPages[mIndex].actor, mPageSize.height );
}
}
}
// Guard against destruction during signal emission
Toolkit::PageTurnView handle( GetOwner() );
- if( !mPanActor )
+ if( mTurningPageIndex == -1 )
{
- if(!mIsAnimating[mIndex])
+ if( mAnimatingCount< MAXIMUM_TURNING_NUM && mSlidingCount < 1)
{
OnPossibleOutwardsFlick( gesturePosition, gestureSpeed );
}
+
return;
}
mPagePanFinishedSignal.Emit( handle );
- ImageActor actor = mPanActor;
if(mPress)
{
- if(!mConstraints) // if with constraints, the pan finished position is near spine, set up an animation to turn the page over
+ if(mConstraints) // if with constraints, the pan finished position is near spine, set up an animation to turn the page over
{
// update the pages here instead of in the TurnedOver callback function
// as new page is allowed to respond to the pan gesture before other pages finishing animation
- if(mIsTurnBack[actor])
+ if(mPages[mIndex].isTurnBack)
{
mCurrentPageIndex--;
RemovePage( mCurrentPageIndex+NUMBER_OF_CACHED_PAGES_EACH_SIDE );
OrganizePageDepth();
// set up an animation to turn the page over
- Actor self = Self();
float width = mPageSize.width*(1.f+PAGE_TURN_OVER_THRESHOLD_RATIO);
Animation animation = Animation::New( std::max(0.1f,PAGE_TURN_OVER_ANIMATION_DURATION * (1.0f - mPanDisplacement / width)) );
- animation.AnimateTo( Property(self, mPropertyPanDisplacement[mIndex]),
- width,AlphaFunctions::EaseOutSine33);
- animation.AnimateTo( Property(self, mPropertyCurrentCenter[mIndex]),
- Vector2(-mPageSize.width, 0.5f*mPageSize.height), AlphaFunctions::EaseOutSine33);
- mAnimationActorPair[animation] = actor;
- mAnimationIndexPair[animation] = mIndex;
+ animation.AnimateTo( Property(mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement),
+ width,AlphaFunction::EASE_OUT_SINE);
+ animation.AnimateTo( Property(mPages[mIndex].actor, mPages[mIndex].propertyPanCenter),
+ Vector2(-mPageSize.width*1.1f, 0.5f*mPageSize.height), AlphaFunction::EASE_OUT_SINE);
+ mAnimationPageIdPair[animation] = mTurningPageIndex;
animation.Play();
animation.FinishedSignal().Connect( this, &PageTurnView::TurnedOver );
}
else // the pan finished position is far away from the spine, set up an animation to slide the page back instead of turning over
{
Animation animation= Animation::New( PAGE_SLIDE_BACK_ANIMATION_DURATION * (mOriginalCenter.x - mCurrentCenter.x) / mPageSize.width / PAGE_TURN_OVER_THRESHOLD_RATIO );
- animation.AnimateTo( Property( mTurnEffect[mIndex], mTurnEffect[mIndex].PageTurnEffect::GetCurrentCenterPropertyName() ),
- mOriginalCenter, AlphaFunctions::Linear );
- mAnimationActorPair[animation] = actor;
- mAnimationIndexPair[animation] = mIndex;
+ animation.AnimateTo( Property( mPages[mIndex].actor, mPages[mIndex].propertyCurrentCenter ),
+ mOriginalCenter, AlphaFunction::LINEAR );
+ mAnimationPageIdPair[animation] = mTurningPageIndex;
animation.Play();
- mIsSliding[mIndex] = true;
+ mSlidingCount++;
animation.FinishedSignal().Connect( this, &PageTurnView::SliddenBack );
- mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>( mCurrentPageIndex + ( ( mIsTurnBack[mPanActor] ) ? -1 : 0 ) ), mIsTurnBack[mPanActor] );
+ mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mTurningPageIndex), mPages[mIndex].isTurnBack );
}
}
else
// In landscape view, nothing to do
OnPossibleOutwardsFlick( gesturePosition, gestureSpeed );
}
-
mPageUpdated = true;
}
void PageTurnView::TurnedOver( Animation& animation )
{
- ImageActor actor = mAnimationActorPair[animation];
- mIsTurnBack[actor] = !mIsTurnBack[actor];
- actor.RemoveConstraints();
- mRootOnScreen.Add(actor);
- int index = mAnimationIndexPair[animation];
- mIsAnimating[index] = false;
- mTurnEffect[index].RemoveConstraints();
- mAnimationIndexPair.erase( animation );
- mAnimationActorPair.erase( animation );
-
- SetSpineEffect( actor, mIsTurnBack[actor] );
+ int pageId = mAnimationPageIdPair[animation];
+ int index = pageId%NUMBER_OF_CACHED_PAGES;
+
+ mPages[index].ChangeTurnDirection();
+ mPages[index].actor.RemoveConstraints();
+ Self().Add(mPages[index].actor);
+ mAnimatingCount--;
+ mAnimationPageIdPair.erase( animation );
+
+ float degree = mPages[index].isTurnBack ? 180.f : 0.f;
+ mPages[index].actor.SetOrientation( Degree(degree), Vector3::YAXIS );
+ mPages[index].UseEffect( mSpineEffectShader );
+
+ int id = pageId + (mPages[index].isTurnBack ? -1 : 1);
+ if( id >=0 && id < mTotalPageCount )
+ {
+ mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(false);
+ }
+
+ OnTurnedOver( mPages[index].actor, mPages[index].isTurnBack );
// Guard against destruction during signal emission
Toolkit::PageTurnView handle( GetOwner() );
- mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>( mCurrentPageIndex + ( ( mIsTurnBack[actor] ) ? -1 : 0 ) ), mIsTurnBack[actor] );
+ mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>(pageId), mPages[index].isTurnBack );
}
void PageTurnView::SliddenBack( Animation& animation )
{
- ImageActor actor = mAnimationActorPair[animation];
- mRootOnScreen.Add(actor);
- int index = mAnimationIndexPair[animation];
- mIsSliding[index] = false;
- mIsAnimating[index] = false;
- mAnimationIndexPair.erase( animation );
- mAnimationActorPair.erase( animation );
+ int pageId = mAnimationPageIdPair[animation];
+ int index = pageId%NUMBER_OF_CACHED_PAGES;
+ Self().Add(mPages[index].actor);
+ mSlidingCount--;
+ mAnimatingCount--;
+ mAnimationPageIdPair.erase( animation );
+
+ mPages[index].UseEffect( mSpineEffectShader );
- SetSpineEffect( actor, mIsTurnBack[actor] );
+ int id = pageId + (mPages[index].isTurnBack ? -1 : 1);
+ if( id >=0 && id < mTotalPageCount )
+ {
+ mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(false);
+ }
// Guard against destruction during signal emission
Toolkit::PageTurnView handle( GetOwner() );
- mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>( mCurrentPageIndex + ( ( mIsTurnBack[mPanActor] ) ? -1 : 0 ) ), mIsTurnBack[actor] );
+ mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>(pageId), mPages[index].isTurnBack );
}
void PageTurnView::OrganizePageDepth()
{
if(mCurrentPageIndex+i < mTotalPageCount)
{
- mPageActors[( mCurrentPageIndex+i )%NUMBER_OF_CACHED_PAGES].SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
+ mPages[( mCurrentPageIndex+i )%NUMBER_OF_CACHED_PAGES].actor.SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
}
if( mCurrentPageIndex >= i + 1 )
{
- mPageActors[( mCurrentPageIndex-i-1 )%NUMBER_OF_CACHED_PAGES].SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
+ mPages[( mCurrentPageIndex-i-1 )%NUMBER_OF_CACHED_PAGES].actor.SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
}
}
}
-void PageTurnView::SetShaderEffect( ImageActor actor, ShaderEffect shaderEffect )
+void PageTurnView::StopTurning()
{
- SetShaderEffectRecursively( actor, shaderEffect );
+ mAnimatingCount = 0;
+ mSlidingCount = 0;
+
+ if( !mPageUpdated )
+ {
+ int index = mTurningPageIndex % NUMBER_OF_CACHED_PAGES;
+ Self().Add( mPages[ index ].actor );
+ mPages[ index ].actor.RemoveConstraints();
+ mPages[ index ].UseEffect( mSpineEffectShader );
+ float degree = mTurningPageIndex==mCurrentPageIndex ? 0.f :180.f;
+ mPages[index].actor.SetOrientation( Degree(degree), Vector3::YAXIS );
+ mPageUpdated = true;
+ }
+
+ if( !mAnimationPageIdPair.empty() )
+ {
+ for (std::map<Animation,int>::iterator it=mAnimationPageIdPair.begin(); it!=mAnimationPageIdPair.end(); ++it)
+ {
+ static_cast<Animation>(it->first).SetCurrentProgress( 1.f );
+ }
+ }
}
Toolkit::PageTurnView::PageTurnSignal& PageTurnView::PageTurnStartedSignal()
return mPagePanFinishedSignal;
}
+bool PageTurnView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+{
+ Dali::BaseHandle handle( object );
+
+ bool connected( true );
+ Toolkit::PageTurnView pageTurnView = Toolkit::PageTurnView::DownCast( handle );
+
+ if( 0 == strcmp( signalName.c_str(), SIGNAL_PAGE_TURN_STARTED ) )
+ {
+ pageTurnView.PageTurnStartedSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_PAGE_TURN_FINISHED ) )
+ {
+ pageTurnView.PageTurnFinishedSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_PAGE_PAN_STARTED ) )
+ {
+ pageTurnView.PagePanStartedSignal().Connect( tracker, functor );
+ }
+ else if( 0 == strcmp( signalName.c_str(), SIGNAL_PAGE_PAN_FINISHED ) )
+ {
+ pageTurnView.PagePanFinishedSignal().Connect( tracker, functor );
+ }
+ else
+ {
+ // signalName does not match any signal
+ connected = false;
+ }
+
+ return connected;
+}
+
+void PageTurnView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::PageTurnView pageTurnView = Toolkit::PageTurnView::DownCast( Dali::BaseHandle( object ) );
+
+ if( pageTurnView )
+ {
+ PageTurnView& pageTurnViewImpl( GetImplementation( pageTurnView ) );
+
+ switch( index )
+ {
+ case Toolkit::PageTurnView::Property::PAGE_SIZE:
+ {
+ pageTurnViewImpl.SetPageSize( value.Get<Vector2>() );
+ break;
+ }
+ case Toolkit::PageTurnView::Property::CURRENT_PAGE_ID:
+ {
+ pageTurnViewImpl.GoToPage( value.Get<int>() );
+ break;
+ }
+ case Toolkit::PageTurnView::Property::SPINE_SHADOW:
+ {
+ pageTurnViewImpl.SetSpineShadowParameter( value.Get<Vector2>() );
+ break;
+ }
+ }
+ }
+}
+
+Property::Value PageTurnView::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::PageTurnView pageTurnView = Toolkit::PageTurnView::DownCast( Dali::BaseHandle( object ) );
+
+ if( pageTurnView )
+ {
+ PageTurnView& pageTurnViewImpl( GetImplementation( pageTurnView ) );
+
+ switch( index )
+ {
+ case Toolkit::PageTurnView::Property::PAGE_SIZE:
+ {
+ value = pageTurnViewImpl.GetPageSize();
+ break;
+ }
+ case Toolkit::PageTurnView::Property::CURRENT_PAGE_ID:
+ {
+ value = static_cast<int>( pageTurnViewImpl.GetCurrentPage() );
+ break;
+ }
+ case Toolkit::PageTurnView::Property::SPINE_SHADOW:
+ {
+ value = pageTurnViewImpl.GetSpineShadowParameter();
+ break;
+ }
+ }
+ }
+ return value;
+}
+
} // namespace Internal
} // namespace Toolkit