Changed all property & signal names to lowerCamelCase
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / page-turn-view / page-turn-view-impl.cpp
index e08a223..f3e2ed1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2015 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/devel-api/events/hit-test-algorithm.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/object/type-registry-helper.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.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>
 
 using namespace Dali;
 
-namespace //unnamed namespace
+namespace //Unnamed namespace
 {
-// To register type
-TypeRegistration mType( typeid(Toolkit::PageTurnView), typeid(Toolkit::Control), NULL );
-
 // default grid density for page turn effect, 10 pixels by 10 pixels
 const float DEFAULT_GRID_DENSITY(10.0f);
 
@@ -77,17 +76,17 @@ struct OriginalCenterConstraint
     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);
     }
   }
 
@@ -111,22 +110,21 @@ struct RotationConstraint
     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 );
     }
   }
 
@@ -145,22 +143,23 @@ struct RotationConstraint
  */
 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
@@ -168,7 +167,7 @@ struct CurrentCenterConstraint
       {
         coef = (coef+0.225f)/10.0f;
       }
-      return centerOrigin - direction * coef;
+      current = centerOrigin - direction * coef;
     }
   }
 
@@ -182,14 +181,13 @@ struct ShadowBlurStrengthConstraint
   : 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
@@ -198,49 +196,11 @@ struct ShadowBlurStrengthConstraint
     }
 
     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
@@ -252,6 +212,31 @@ namespace Toolkit
 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 int PageTurnView::MAXIMUM_TURNING_NUM = 4;
 const int PageTurnView::NUMBER_OF_CACHED_PAGES_EACH_SIDE = MAXIMUM_TURNING_NUM + 1;
@@ -259,15 +244,14 @@ const int PageTurnView::NUMBER_OF_CACHED_PAGES = NUMBER_OF_CACHED_PAGES_EACH_SID
 const float PageTurnView::STATIC_PAGE_INTERVAL_DISTANCE = 1.0f;
 
 PageTurnView::PageTurnView( PageFactory& pageFactory, const Vector2& pageSize )
-: Control( REQUIRES_TOUCH_EVENTS ),
+: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
   mPageFactory( pageFactory ),
   mPageSize( pageSize ),
   mTotalPageCount( 0 ),
-  mIsEditMode( false ),
-  mNeedOffscreenRendering( false ),
   mPanning( false ),
   mSpineShadowParameter( DEFAULT_SPINE_SHADOW_PARAMETER ),
   mCurrentPageIndex( 0 ),
+  mTurningPageIndex( 0 ),
   mIndex( 0 ),
   mPress( false ),
   mPageUpdated( true ),
@@ -295,26 +279,26 @@ 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 );
+  mSpineEffectFront = CreatePageTurnBookSpineEffect();
+  mSpineEffectFront.SetUniform("uIsBackImageVisible", -1.f );
+  mSpineEffectFront.SetUniform("uPageWidth", mPageSize.width );
+  mSpineEffectFront.SetUniform("uShadowWidth", 0.f );
+  mSpineEffectFront.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
+
+  mSpineEffectBack = CreatePageTurnBookSpineEffect();
+  mSpineEffectBack.SetUniform("uIsBackImageVisible", 1.f );
+  mSpineEffectBack.SetUniform("uPageWidth", mPageSize.width );
+  mSpineEffectBack.SetUniform("uShadowWidth", 0.f );
+  mSpineEffectBack.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
 
   // create the page turn effect objects
   for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
   {
-    mTurnEffect[i] = Toolkit::PageTurnEffect::New( false );
-    mTurnEffect[i].SetProperty( ShaderEffect::GRID_DENSITY, Property::Value( DEFAULT_GRID_DENSITY ) );
-    mTurnEffect[i].SetPageSize( mPageSize );
-    mTurnEffect[i].SetShadowWidth(0.f);
-    mTurnEffect[i].SetSpineShadowParameter( mSpineShadowParameter );
+    mTurnEffect[i] = CreatePageTurnEffect();
+    mTurnEffect[i].SetProperty( ShaderEffect::Property::GRID_DENSITY, Property::Value( DEFAULT_GRID_DENSITY ) );
+    mTurnEffect[i].SetUniform( "uPageSize", mPageSize );
+    mTurnEffect[i].SetUniform( "uShadowWidth", 0.f);
+    mTurnEffect[i].SetUniform( "uSpineShadowParameter", mSpineShadowParameter );
     mIsAnimating[i] = false;
     mIsSliding[i] = false;
     mPropertyPanDisplacement[i] = Self().RegisterProperty("PAN_DISPLACEMENT_PROPERTY_"+i, 0.0f);
@@ -323,22 +307,14 @@ void PageTurnView::OnInitialize()
 
   mTurningPageLayer = Layer::New();
   mTurningPageLayer.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
-  // Set control size and the parent origin of turningPageLayer
+  mTurningPageLayer.SetBehavior(Layer::LAYER_3D);
+
+  // 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);
+  Self().Add(mTurningPageLayer);
 
   mTotalPageCount = static_cast<int>( mPageFactory.GetNumberOfPages() );
-  mNeedOffscreenRendering = mPageFactory.IsOffscreenRenderingNeeded();
-  if( mNeedOffscreenRendering )
-  {
-    SetupRenderTasks();
-  }
-
   // add pages to the scene, and set depth for the stacked pages
   for( int i = 0; i < NUMBER_OF_CACHED_PAGES_EACH_SIDE; i++ )
   {
@@ -348,48 +324,10 @@ void PageTurnView::OnInitialize()
       mPageActors[i].SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
     }
   }
+  mPageActors[0].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()
-{
-  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++)
-  {
-    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() );
-   }
 }
 
 void PageTurnView::SetupShadowView()
@@ -401,41 +339,38 @@ 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.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION );
+  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 )
 {
+  Control::OnStageConnection( depth );
+
   SetupShadowView();
-  mTurningPageLayer.RaiseToTop();
+  mTurningPageLayer.Raise();
 }
 
-void PageTurnView::OnControlStageDisconnection()
+void PageTurnView::OnStageDisconnection()
 {
   if(mShadowView)
   {
-    Self().Remove(mPointLight);
-    Self().Remove(mShadowLayer);
-    mTurningPageLayer.Remove( mShadowView );
+    mPointLight.Unparent();
+    mShadowPlaneBackground.Unparent();
+    mShadowView.Unparent();
   }
 
   // make sure the status of the control is updated correctly when the pan gesture is interrupted
@@ -443,7 +378,7 @@ void PageTurnView::OnControlStageDisconnection()
   {
     mPanning = false;
 
-    mRootOnScreen.Add(mPanActor);
+    Self().Add(mPanActor);
     mIsAnimating[mIndex] = false;
     mPanActor.RemoveConstraints();
     mTurnEffect[mIndex].RemoveConstraints();
@@ -451,12 +386,48 @@ void PageTurnView::OnControlStageDisconnection()
 
     SetSpineEffect( mPanActor, mIsTurnBack[mPanActor] );
   }
+
+  Control::OnStageDisconnection();
 }
 
-void PageTurnView::OnControlSizeSet( const Vector3& size )
+void PageTurnView::SetPageSize( const Vector2& pageSize )
 {
-  // disable the SetSize of the control from the application
-  Self().SetSize( mControlSize );
+  mPageSize = pageSize;
+  mSpineEffectFront.SetUniform("uPageWidth", mPageSize.width );
+  mSpineEffectBack.SetUniform("uPageWidth", mPageSize.width );
+  for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
+  {
+    mTurnEffect[i].SetUniform( "uPageSize", mPageSize );
+  }
+
+  if( mPointLight )
+  {
+    mPointLight.SetPosition( 0.f, 0.f, mPageSize.width*POINT_LIGHT_HEIGHT_RATIO );
+  }
+
+  for( size_t i=0; i<mPageActors.size(); i++ )
+  {
+    if( mPageActors[i] )
+    {
+      mPageActors[i].SetSize( mPageSize );
+      if( mPageActors[i].GetChildCount()>0 )
+      {
+        mPageActors[i].GetChildAt(0).SetSize( mPageSize );
+      }
+    }
+  }
+
+  OnPageTurnViewInitialize();
+
+  if( mShadowPlaneBackground )
+  {
+    mShadowPlaneBackground.SetSize( mControlSize );
+  }
+}
+
+Vector2 PageTurnView::GetPageSize()
+{
+  return mPageSize;
 }
 
 void PageTurnView::SetSpineShadowParameter( const Vector2& spineShadowParameter )
@@ -464,11 +435,11 @@ void PageTurnView::SetSpineShadowParameter( const Vector2& spineShadowParameter
   mSpineShadowParameter = spineShadowParameter;
 
   // set spine shadow parameter to all the shader effects
-  mSpineEffectFront.SetSpineShadowParameter( mSpineShadowParameter );
-  mSpineEffectBack.SetSpineShadowParameter( mSpineShadowParameter );
+  mSpineEffectFront.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
+  mSpineEffectBack.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
   for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
   {
-    mTurnEffect[i].SetSpineShadowParameter( mSpineShadowParameter );
+    mTurnEffect[i].SetUniform("uSpineShadowParameter", mSpineShadowParameter );
   }
 }
 
@@ -479,7 +450,13 @@ Vector2 PageTurnView::GetSpineShadowParameter()
 
 void PageTurnView::GoToPage( unsigned int pageId )
 {
-  int pageIdx = static_cast<int>(pageId);
+  int pageIdx = Clamp( static_cast<int>(pageId), 0, mTotalPageCount-1);
+
+  if( mCurrentPageIndex == pageIdx  )
+  {
+    return;
+  }
+
   // record the new current page index
   mCurrentPageIndex = pageIdx;
 
@@ -498,6 +475,12 @@ void PageTurnView::GoToPage( unsigned int pageId )
   {
     AddPage( i );
   }
+
+  mPageActors[pageId%NUMBER_OF_CACHED_PAGES].SetVisible(true);
+  if( pageId > 0 )
+  {
+    mPageActors[(pageId-1)%NUMBER_OF_CACHED_PAGES].SetVisible(true);
+  }
   // set ordered depth to the stacked pages
   OrganizePageDepth();
 }
@@ -508,100 +491,18 @@ unsigned int PageTurnView::GetCurrentPage()
   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 );
-    }
+    ImageActor 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 );
+    Self().Add( newPage );
     mPageActors[index] = newPage;
 
     bool isLeftSide = ( pageIndex < mCurrentPageIndex );
@@ -613,9 +514,11 @@ void PageTurnView::AddPage( int pageIndex )
     }
     else
     {
-      SetShaderEffect( newPage, mSpineEffectFront);
+      newPage.SetShaderEffect(mSpineEffectFront);
     }
 
+    newPage.SetVisible( false );
+
     // 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 );
@@ -630,59 +533,11 @@ void PageTurnView::RemovePage( int pageIndex )
     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-- );
-    }
   }
 }
 
-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 )
   {
@@ -711,7 +566,7 @@ void PageTurnView::OnPan( const PanGesture& gesture )
       if( mPageUpdated && animatable )
       {
         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(mPanActor && mPanActor.GetParent() != Self()) // if the page is added to turning layer,it is undergoing an animation currently
         {
           mPanActor.Reset();
         }
@@ -754,7 +609,7 @@ void PageTurnView::PanStarted( const Vector2& gesturePosition )
   }
 
   mOriginalCenter = gesturePosition;
-  mTurnEffect[mIndex].SetIsTurningBack( mIsTurnBack[ mPanActor] );
+  mTurnEffect[mIndex].SetUniform("uIsTurningBack", mIsTurnBack[ mPanActor] ? 1.f : -1.f);
   mPress = false;
   mPageUpdated = false;
 
@@ -791,25 +646,30 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition )
       mDistanceBottomCorner = ( mOriginalCenter - Vector2( 0.0f, mPageSize.height ) ).Length();
       mShadowView.Add( mPanActor );
       SetShaderEffect( mPanActor, mTurnEffect[mIndex] );
-      mTurnEffect[mIndex].SetOriginalCenter( mOriginalCenter );
+      mTurnEffect[mIndex].SetUniform("uOriginalCenter", mOriginalCenter );
       mCurrentCenter = mOriginalCenter;
-      mTurnEffect[mIndex].SetCurrentCenter( mCurrentCenter );
+      mTurnEffect[mIndex].SetUniform("uCurrentCenter", mCurrentCenter );
       mPanDisplacement = 0.f;
       mConstraints = true;
       mPress = true;
       mIsAnimating[mIndex] = true;
 
-      mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mCurrentPageIndex + ( ( mIsTurnBack[mPanActor] ) ? -1 : 0 ) ), !mIsTurnBack[mPanActor] );
+      mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mTurningPageIndex), !mIsTurnBack[mPanActor] );
+      int id = mTurningPageIndex + (mIsTurnBack[mPanActor]? -1 : 1);
+      if( id >=0 && id < mTotalPageCount )
+      {
+        mPageActors[id%NUMBER_OF_CACHED_PAGES].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  );
+
+      Constraint shadowBlurStrengthConstraint = Constraint::New<float>( mShadowView, mShadowView.GetBlurStrengthPropertyIndex(), ShadowBlurStrengthConstraint( mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO ) );
+      shadowBlurStrengthConstraint.AddSource( Source(mTurnEffect[mIndex],  mTurnEffect[mIndex].GetPropertyIndex("uCurrentCenter")) );
+      shadowBlurStrengthConstraint.AddSource( Source(mTurnEffect[mIndex],  mTurnEffect[mIndex].GetPropertyIndex("uOriginalCenter")) );
+      shadowBlurStrengthConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+      shadowBlurStrengthConstraint.Apply();
     }
   }
   else
@@ -871,28 +731,24 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition )
                    /( 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 );
+        Property::Index shaderOriginalCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex("uOriginalCenter");
+        Constraint originalCenterConstraint = Constraint::New<Vector2>( mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex, OriginalCenterConstraint( mOriginalCenter, offset ));
+        originalCenterConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+        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 );
+        Property::Index shaderCurrentCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex("uCurrentCenter");
+        Constraint currentCenterConstraint = Constraint::New<Vector2>( mTurnEffect[mIndex], shaderCurrentCenterPropertyIndex, CurrentCenterConstraint(mPageSize.width));
+        currentCenterConstraint.AddSource( Source(self, mPropertyCurrentCenter[mIndex]) );
+        currentCenterConstraint.AddSource( Source(mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex) );
+        currentCenterConstraint.Apply();
 
-        GetImpl( mTurnEffect[mIndex] ).ApplyInternalConstraint();
+        PageTurnApplyInternalConstraint(mTurnEffect[mIndex]);
 
         float distance = offset.Length();
-        Constraint rotationConstraint = Constraint::New<Quaternion>( Actor::ROTATION,
-                                                                     Source( self, mPropertyPanDisplacement[mIndex] ),
-                                                                     RotationConstraint(distance, mPageSize.width, mIsTurnBack[mPanActor]));
-        mPanActor.ApplyConstraint( rotationConstraint );
+        Constraint rotationConstraint = Constraint::New<Quaternion>( mPanActor, Actor::Property::ORIENTATION, RotationConstraint(distance, mPageSize.width, mIsTurnBack[mPanActor]));
+        rotationConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+        rotationConstraint.Apply();
 
         mConstraints = false;
       }
@@ -903,14 +759,14 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition )
       {
         mPanActor.RemoveConstraints();
         mTurnEffect[mIndex].RemoveConstraints();
-        mTurnEffect[mIndex].SetOriginalCenter( mOriginalCenter );
+        mTurnEffect[mIndex].SetUniform("uOriginalCenter",mOriginalCenter );
         mConstraints = true;
         mPanDisplacement = 0.f;
       }
 
-      mTurnEffect[mIndex].SetCurrentCenter( currentCenter );
+      mTurnEffect[mIndex].SetUniform("uCurrentCenter", currentCenter );
       mCurrentCenter = currentCenter;
-      GetImpl( mTurnEffect[mIndex] ).ApplyInternalConstraint();
+      PageTurnApplyInternalConstraint(mTurnEffect[mIndex]);
     }
   }
 }
@@ -957,10 +813,10 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe
       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);
+                           width,AlphaFunction::EASE_OUT_SINE);
       animation.AnimateTo( Property(self, mPropertyCurrentCenter[mIndex]),
-                           Vector2(-mPageSize.width, 0.5f*mPageSize.height), AlphaFunctions::EaseOutSine33);
-      mAnimationActorPair[animation] = actor;
+                           Vector2(-mPageSize.width*1.1f, 0.5f*mPageSize.height), AlphaFunction::EASE_OUT_SINE);
+      mAnimationPageIdPair[animation] = mTurningPageIndex;
       mAnimationIndexPair[animation] = mIndex;
       animation.Play();
       animation.FinishedSignal().Connect( this, &PageTurnView::TurnedOver );
@@ -968,15 +824,15 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe
     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;
+      animation.AnimateTo( Property( mTurnEffect[mIndex], "uCurrentCenter" ),
+                           mOriginalCenter, AlphaFunction::LINEAR );
+      mAnimationPageIdPair[animation] = mTurningPageIndex;
       mAnimationIndexPair[animation] = mIndex;
       animation.Play();
       mIsSliding[mIndex] = true;
       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), mIsTurnBack[actor] );
     }
   }
   else
@@ -991,38 +847,54 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe
 
 void PageTurnView::TurnedOver( Animation& animation )
 {
-  ImageActor actor = mAnimationActorPair[animation];
+  int pageId = mAnimationPageIdPair[animation];
+  ImageActor actor = mPageActors[pageId % NUMBER_OF_CACHED_PAGES];
   mIsTurnBack[actor] = !mIsTurnBack[actor];
   actor.RemoveConstraints();
-  mRootOnScreen.Add(actor);
+  Self().Add(actor);
   int index = mAnimationIndexPair[animation];
   mIsAnimating[index] = false;
   mTurnEffect[index].RemoveConstraints();
   mAnimationIndexPair.erase( animation );
-  mAnimationActorPair.erase( animation );
+  mAnimationPageIdPair.erase( animation );
 
   SetSpineEffect( actor, mIsTurnBack[actor] );
 
+  int id = pageId + (mIsTurnBack[actor]? -1 : 1);
+  if( id >=0 && id < mTotalPageCount )
+  {
+    mPageActors[id%NUMBER_OF_CACHED_PAGES].SetVisible(false);
+  }
+
+  OnTurnedOver( actor, mIsTurnBack[actor] );
+
   // 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), mIsTurnBack[actor] );
 }
 
 void PageTurnView::SliddenBack( Animation& animation )
 {
-  ImageActor actor = mAnimationActorPair[animation];
-  mRootOnScreen.Add(actor);
+  int pageId = mAnimationPageIdPair[animation];
+  ImageActor actor = mPageActors[pageId % NUMBER_OF_CACHED_PAGES];
+  Self().Add(actor);
   int index = mAnimationIndexPair[animation];
   mIsSliding[index] = false;
   mIsAnimating[index] = false;
   mAnimationIndexPair.erase( animation );
-  mAnimationActorPair.erase( animation );
+  mAnimationPageIdPair.erase( animation );
 
   SetSpineEffect( actor, mIsTurnBack[actor] );
 
+  int id = pageId + (mIsTurnBack[actor]? -1 : 1);
+  if( id >=0 && id < mTotalPageCount )
+  {
+    mPageActors[id%NUMBER_OF_CACHED_PAGES].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), mIsTurnBack[actor] );
 }
 
 void PageTurnView::OrganizePageDepth()
@@ -1065,6 +937,99 @@ Toolkit::PageTurnView::PagePanSignal& PageTurnView::PagePanFinishedSignal()
   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