From 322ff9dad8e2227d2df555a2b36242ba4bf287ca Mon Sep 17 00:00:00 2001 From: Xiangyin Ma Date: Wed, 25 Nov 2015 18:15:05 +0000 Subject: [PATCH] Stop using ImageActor in PageTurnView Change-Id: Id919c0ec67faf0afcabd0dbc4ff895cdab4ff52f --- .../src/dali-toolkit/utc-Dali-PageTurnView.cpp | 41 +- .../page-turn-view/page-turn-book-spine-effect.h | 73 +-- .../controls/page-turn-view/page-turn-effect.cpp | 239 +++++----- .../controls/page-turn-view/page-turn-effect.h | 48 +- .../page-turn-landscape-view-impl.cpp | 40 +- .../page-turn-view/page-turn-landscape-view-impl.h | 14 +- .../page-turn-portrait-view-impl.cpp | 53 +-- .../page-turn-view/page-turn-portrait-view-impl.h | 15 +- .../page-turn-view/page-turn-view-impl.cpp | 514 ++++++++++++--------- .../controls/page-turn-view/page-turn-view-impl.h | 159 +++++-- .../controls/renderers/image/image-renderer.cpp | 73 +-- .../controls/renderers/renderer-factory-cache.cpp | 70 ++- .../controls/renderers/renderer-factory-cache.h | 8 + .../controls/page-turn-view/page-factory.h | 25 +- 14 files changed, 759 insertions(+), 613 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-PageTurnView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-PageTurnView.cpp index cb6eefa..1142c4c 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-PageTurnView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-PageTurnView.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -193,7 +194,6 @@ public: TestPageFactory(ToolkitTestApplication& application) : mApplication( application ) { - mSourceActors.resize(TOTAL_PAGE_NUMBER); mTotalPageNumber = TOTAL_PAGE_NUMBER; } @@ -207,40 +207,17 @@ public: } /** - * Create an image actor to represent a page. + * Create an image to represent a page content. * @param[in] pageId The ID of the page to create. - * @return An image actor, or an uninitialized pointer if the ID is out of range. + * @return An image, or an empty handle if the ID is out of range. */ - virtual Actor NewPage( unsigned int pageId ) + virtual Image NewPage( unsigned int pageId ) { - if(!mSourceActors[pageId]) - { - Actor actor = CreateSolidColorImageActor(mApplication, Color::BLUE,IMAGE_WIDTH,IMAGE_HEIGHT); - actor.SetName( static_cast( &(std::ostringstream() << pageId) )->str() ); - - actor.SetParentOrigin( ParentOrigin::CENTER ); - actor.SetAnchorPoint( AnchorPoint::CENTER ); - - ImageActor backPageActor = CreateSolidColorImageActor(mApplication, Color::BLUE,IMAGE_WIDTH,IMAGE_HEIGHT); - backPageActor.SetParentOrigin( ParentOrigin::CENTER ); - backPageActor.SetAnchorPoint( AnchorPoint::CENTER ); - actor.Add( backPageActor ); - - mSourceActors[pageId] = actor; - } - - return mSourceActors[pageId]; - } - - void DeletePage( unsigned int pageId ) - { - mSourceActors.erase( mSourceActors.begin() + pageId ); - mTotalPageNumber--; + return BufferImage::WHITE(); } private: ToolkitTestApplication& mApplication; - std::vector mSourceActors; unsigned int mTotalPageNumber; }; @@ -706,3 +683,11 @@ int UtcDaliPageTurnLanscapeViewSignals(void) DALI_TEST_EQUALS( landscapeView.GetProperty(PageTurnView::Property::CURRENT_PAGE_ID).Get(), 0, TEST_LOCATION ); END_TEST; } + +int UtcDaliPageImageFactoryGetExtention(void) +{ + ToolkitTestApplication application; + TestPageFactory factory(application); + DALI_TEST_CHECK( factory.GetExtension() == NULL ); + END_TEST; +} diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h b/dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h index efe112c..f9e87fb 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h @@ -18,8 +18,7 @@ * */ -// EXTERNAL INCLUDES -#include +#define DALI_COMPOSE_SHADER(STR) #STR namespace Dali { @@ -42,50 +41,68 @@ namespace Internal * * Animatable/Constrainable uniforms: * "uSpineShadowParameter" - The two parameters are the major&minor radius (in pixels) to form an ellipse shape. The top-left - * quarter of this ellipse is used to calculate spine normal for simulating shadow - * "uIsBackImageVisible" - Set whether the current page is with its backside visible. Need to pass the parameter as true for - * the page which is turned over but still visible in Landscape - * "uPageWidth" - The page width of the PageTurnBookSpineEffect + * quarter of this ellipse is used to calculate spine normal for simulating shadow * + * "uTextureWidth" - 1.0 for single sided page, + * 2.0 for double sided image which has left half part as page front side and right half part as page back side. * - * @return A handle to a newly allocated ShaderEffect + * @return The newly created Property::Map with the page turn book spine effect **/ -inline ShaderEffect CreatePageTurnBookSpineEffect() +inline Property::Map CreatePageTurnBookSpineEffect() { + const char* vertexSource = DALI_COMPOSE_SHADER( + precision mediump float;\n + attribute mediump vec2 aPosition;\n + uniform mediump mat4 uMvpMatrix;\n + uniform vec3 uSize;\n + uniform float uTextureWidth;\n + varying vec2 vTexCoord;\n + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition*uSize.xy, 0.0, 1.0);\n + gl_Position = uMvpMatrix * vertexPosition;\n + vTexCoord = aPosition + vec2(0.5);\n + vTexCoord.x /= uTextureWidth; + }\n); + // the simplified version of the fragment shader of page turn effect - std::string fragmentSource = DALI_COMPOSE_SHADER( + const char* fragmentSource = DALI_COMPOSE_SHADER( precision mediump float;\n - uniform float uIsBackImageVisible;\n - uniform float uPageWidth;\n + varying mediump vec2 vTexCoord;\n + uniform vec3 uSize;\n uniform vec2 uSpineShadowParameter;\n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + void main()\n {\n - // flip the image horizontally by changing the x component of the texture coordinate - if( uIsBackImageVisible == 1.0 )\n - gl_FragColor = texture2D( sTexture, vec2( sTextureRect.p+sTextureRect.s-vTexCoord.x, vTexCoord.y ) ) * uColor; \n - else\n - gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n - // display book spine, a stripe of shadowed texture - float pixelPos = (vTexCoord.x-sTextureRect.s)*uPageWidth; \n - if(pixelPos < uSpineShadowParameter.x) \n + if( gl_FrontFacing )\n // display front side + {\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n + }\n + else\n // display back side, flip the image horizontally by changing the x component of the texture coordinate + {\n + gl_FragColor = texture2D( sTexture, vec2( 1.0 - vTexCoord.x, vTexCoord.y ) ) * uColor;\n + }\n + // display book spine, a stripe of shadowed texture + float pixelPos = vTexCoord.x * uSize.x;\n + if( pixelPos < uSpineShadowParameter.x )\n {\n float x = pixelPos - uSpineShadowParameter.x;\n float y = sqrt( uSpineShadowParameter.x*uSpineShadowParameter.x - x*x );\n vec2 spineNormal = normalize(vec2(uSpineShadowParameter.y*x/uSpineShadowParameter.x, y));\n gl_FragColor.rgb *= spineNormal.y; \n - } + }\n } ); - const Vector2 DEFAULT_SPINE_SHADOW_PARAMETER(50.0f, 20.0f); - - ShaderEffect shaderEffect = ShaderEffect::New( "", fragmentSource ); + Property::Map map; - shaderEffect.SetUniform( "uIsBackImageVisible", -1.f ); - shaderEffect.SetUniform( "uSpineShadowParameter", DEFAULT_SPINE_SHADOW_PARAMETER ); + Property::Map customShader; - float defaultPageWidth = Dali::Stage::GetCurrent().GetSize().x; - shaderEffect.SetUniform( "uPageWidth", defaultPageWidth ); + customShader[ "vertexShader" ] = vertexSource; + customShader[ "fragmentShader" ] = fragmentSource; - return shaderEffect; + map[ "shader" ] = customShader; + return map; } } //namespace Internal diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.cpp b/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.cpp index f4ada4f..f4d1126 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.cpp +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.cpp @@ -15,90 +15,115 @@ * */ +//EXTERNAL INCLUDES +#include +#include +#include +#include + +//INTERNAL INCLUDES #include -#include using namespace Dali; using namespace Dali::Toolkit; -void CommonParametersConstraint( Dali::Matrix& current, const PropertyInputContainer& inputs ) +namespace { - const Vector2& originalCenter = inputs[0]->GetVector2(); - Vector2 currentCenter = inputs[1]->GetVector2(); - const Vector2& pageSize = inputs[2]->GetVector2(); +#define DALI_COMPOSE_SHADER(STR) #STR +const char * const PROPERTY_COMMON_PARAMETERS( "uCommonParameters" ); +const char * const PROPERTY_ORIGINAL_CENTER( "originalCenter" ); +const char * const PROPERTY_CURRENT_CENTER( "currentCenter" ); +} - // calculate the curve direction and the vanishing point - // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction - Vector2 curveDirection( currentCenter - originalCenter ); - curveDirection.Normalize(); - if( fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step - { - curveDirection.y = 0.01f; - } - float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y; +/** + * This constraint updates the common parameter values used by every vertex. + * By using constraint, they are calculate once in CPU then pass into the vertex shader as uniforms + */ +struct CommonParametersConstraint +{ + CommonParametersConstraint( float pageHeight ) + : mPageHeight( pageHeight ) + {} - float curveEndY, cosTheta ,sinTheta ,translateX, translateY; - // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally - const float THRESHOLD(20.0); - if( fabs(vanishingPointY-pageSize.y*0.5f) >= pageSize.y*THRESHOLD ) + void operator()( Dali::Matrix& current, const PropertyInputContainer& inputs ) { - curveDirection = Vector2(-1.f,0.f); - currentCenter.y = originalCenter.y; + const Vector2& originalCenter = inputs[0]->GetVector2(); + Vector2 currentCenter = inputs[1]->GetVector2(); - curveEndY = originalCenter.y; - cosTheta = 1.f; - sinTheta = 0.f; - translateX = currentCenter.x - originalCenter.x; - translateY = vanishingPointY; - } - else - { - curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x/curveDirection.x) ; - Vector2 v1( currentCenter.x, currentCenter.y - vanishingPointY ); - v1.Normalize(); - Vector2 v2( originalCenter.x, originalCenter.y - vanishingPointY ); - v2.Normalize(); - cosTheta = v1.x*v2.x + v1.y*v2.y; - sinTheta = ( vanishingPointY > pageSize.y*0.5f ) ? sqrt(1.0-cosTheta*cosTheta) : -sqrt(1.0-cosTheta*cosTheta); - translateX = currentCenter.x - cosTheta*originalCenter.x - sinTheta*( originalCenter.y-vanishingPointY ); - translateY = currentCenter.y + sinTheta*originalCenter.x - cosTheta*( originalCenter.y-vanishingPointY ); - } + // calculate the curve direction and the vanishing point + // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction + Vector2 curveDirection( currentCenter - originalCenter ); + curveDirection.Normalize(); + if( fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step + { + curveDirection.y = 0.01f; + } + float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y; - float originalLength = fabs(originalCenter.x/curveDirection.x); - float currentLength = fabs(currentCenter.x/curveDirection.x); - float curveHeight = 0.45f*sqrt(originalLength*originalLength - currentLength*currentLength); + float curveEndY, cosTheta ,sinTheta ,translateX, translateY; + // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally + const float THRESHOLD(20.0); + if( fabs(vanishingPointY-mPageHeight*0.5f) >= mPageHeight*THRESHOLD ) + { + curveDirection = Vector2(-1.f,0.f); + currentCenter.y = originalCenter.y; - float* parameterArray = current.AsFloat(); - parameterArray[0] = cosTheta; - parameterArray[1] = -sinTheta; - parameterArray[2] = originalCenter.x; - parameterArray[3] = originalCenter.y; - parameterArray[4] = sinTheta; - parameterArray[5] = cosTheta; - parameterArray[6] = currentCenter.x; - parameterArray[7] = currentCenter.y; - parameterArray[8] = translateX; - parameterArray[9] = translateY; - parameterArray[10] = vanishingPointY; - parameterArray[11] = curveEndY; - parameterArray[12] = curveDirection.x; - parameterArray[13] = curveDirection.y; - parameterArray[14] = curveHeight; - parameterArray[15] = currentLength; -} + curveEndY = originalCenter.y; + cosTheta = 1.f; + sinTheta = 0.f; + translateX = currentCenter.x - originalCenter.x; + translateY = vanishingPointY; + } + else + { + curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x/curveDirection.x) ; + Vector2 v1( currentCenter.x, currentCenter.y - vanishingPointY ); + v1.Normalize(); + Vector2 v2( originalCenter.x, originalCenter.y - vanishingPointY ); + v2.Normalize(); + cosTheta = v1.x*v2.x + v1.y*v2.y; + sinTheta = ( vanishingPointY > mPageHeight*0.5f ) ? sqrt(1.0-cosTheta*cosTheta) : -sqrt(1.0-cosTheta*cosTheta); + translateX = currentCenter.x - cosTheta*originalCenter.x - sinTheta*( originalCenter.y-vanishingPointY ); + translateY = currentCenter.y + sinTheta*originalCenter.x - cosTheta*( originalCenter.y-vanishingPointY ); + } + + float originalLength = fabs(originalCenter.x/curveDirection.x); + float currentLength = fabs(currentCenter.x/curveDirection.x); + float curveHeight = 0.45f*sqrt(originalLength*originalLength - currentLength*currentLength); + + float* parameterArray = current.AsFloat(); + parameterArray[0] = cosTheta; + parameterArray[1] = -sinTheta; + parameterArray[2] = originalCenter.x; + parameterArray[3] = originalCenter.y; + parameterArray[4] = sinTheta; + parameterArray[5] = cosTheta; + parameterArray[6] = currentCenter.x; + parameterArray[7] = currentCenter.y; + parameterArray[8] = translateX; + parameterArray[9] = translateY; + parameterArray[10] = vanishingPointY; + parameterArray[11] = curveEndY; + parameterArray[12] = curveDirection.x; + parameterArray[13] = curveDirection.y; + parameterArray[14] = curveHeight; + parameterArray[15] = currentLength; + } + + float mPageHeight; +}; -void Dali::Toolkit::Internal::PageTurnApplyInternalConstraint( ShaderEffect& shaderEffect) +void Dali::Toolkit::Internal::PageTurnApplyInternalConstraint( Actor& actor, float pageHeight ) { - Constraint constraint = Constraint::New( shaderEffect, shaderEffect.GetPropertyIndex( "uCommonParameters" ), CommonParametersConstraint ); - constraint.AddSource( LocalSource( shaderEffect.GetPropertyIndex( "uOriginalCenter" ) ) ); - constraint.AddSource( LocalSource( shaderEffect.GetPropertyIndex( "uCurrentCenter" ) ) ); - constraint.AddSource( LocalSource( shaderEffect.GetPropertyIndex( "uPageSize" ) ) ); + Constraint constraint = Constraint::New( actor, actor.GetPropertyIndex( PROPERTY_COMMON_PARAMETERS ) , CommonParametersConstraint( pageHeight ) ); + constraint.AddSource( LocalSource( actor.GetPropertyIndex( PROPERTY_ORIGINAL_CENTER ) ) ); + constraint.AddSource( LocalSource( actor.GetPropertyIndex( PROPERTY_CURRENT_CENTER ) ) ); constraint.Apply(); } -ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect() +Property::Map Dali::Toolkit::Internal::CreatePageTurnEffect() { - std::string vertexShader = DALI_COMPOSE_SHADER( + const char* vertexShader = DALI_COMPOSE_SHADER( /* * The common parameters for all the vertices, calculate in CPU then pass into the shader as uniforms * @@ -117,17 +142,25 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect() * ([3][3]) float currentLength: The length from the current center to the curveEnd. */ precision mediump float;\n + \n + attribute mediump vec2 aPosition;\n + \n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump mat3 uNormalMatrix;\n + uniform mediump mat4 uModelView;\n + \n uniform mat4 uCommonParameters;\n \n - uniform vec2 uPageSize;\n + uniform vec3 uSize;\n uniform float uIsTurningBack;\n + uniform float uTextureWidth;\n varying vec3 vNormal;\n varying vec4 vPosition;\n - varying float vEdgeShadow;\n + varying mediump vec2 vTexCoord;\n \n void main()\n {\n - vec4 position = vec4( aPosition, 1.0);\n + vec4 position = vec4( aPosition*uSize.xy, 0.0, 1.0);\n vec2 currentCenter = vec2( uCommonParameters[1][2], uCommonParameters[1][3]);\n vec2 originalCenter = vec2( uCommonParameters[0][2], uCommonParameters[0][3]);\n vec3 normal = vec3(0.0,0.0,1.0);\n @@ -135,7 +168,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect() if(currentCenter.x < originalCenter.x)\n {\n // change the coordinate origin from the center of the page to its top-left - position.xy += uPageSize * 0.5;\n + position.xy += uSize.xy * 0.5;\n vec2 curveDirection = vec2( uCommonParameters[3]);\n vec3 vanishingPoint = vec3(0.0, uCommonParameters[2][2], 0.0);\n // first part of the page, (outside the the line passing through original center and vertical to curve direction) @@ -164,7 +197,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect() }\n \n // define the control points of hermite curve, composed with two segments - // calulation is carried out on the 2D plane which is passing through both current and original center and vertical to the image plane + // calculation is carried out on the 2D plane which is passing through both current and original center and vertical to the image plane float currentLength = uCommonParameters[3][3];\n float originalLength = abs(originalCenter.x/curveDirection.x);\n float height = uCommonParameters[3][2];\n @@ -178,7 +211,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect() vec2 SegmentTwoTangentVector0 = SegmentOneTangentVector1;\n vec2 SegmentTwoTangentVector1 = SegmentOneTangentVector1;\n \n - // calulate the corresponding curve point position and its tangent vector + // calculate the corresponding curve point position and its tangent vector // it is a linear mapping onto nonlinear curves, might cause some unwanted deformation // but as there are no analytical method to calculate the curve length on arbitrary segment // no efficient way to solve this nonlinear mapping, Numerical approximation would cost too much computation in shader @@ -207,7 +240,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect() // a trick to eliminate some optical illusion caused by the gradient matter of normal in per-fragment shading // which is caused by linear interpolation of normal vs. nonlinear lighting // will notice some artifact in the areas with dramatically normal changes, so compress the normal differences here - tangent.y *= min(1.0, length(position.xyz - vanishingPoint) / uPageSize.y ); \n + tangent.y *= min(1.0, length(position.xyz - vanishingPoint) / uSize.y ); \n }\n vec3 curvePoint = vec3(curveEnd - curvePoint2D.x*curveDirection,max(0.0,curvePoint2D.y));\n vec3 tangentVector = vec3(-tangent.x*curveDirection,tangent.y);\n @@ -244,69 +277,67 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect() normal.xy *= -uIsTurningBack;\n }\n // change the coordinate origin from the top-left of the page to its center - position.xy -= uPageSize * 0.5; \n + position.xy -= uSize.xy * 0.5; \n }\n - gl_Position = uMvpMatrix * position;\n + vNormal = uNormalMatrix * normal;\n + gl_Position = uMvpMatrix * position; // varying parameters for fragment shader - vTexCoord = mix( sTextureRect.xy, sTextureRect.zw, aTexCoord );\n; - vNormal = uNormalMatrix*normal;\n + vTexCoord = aPosition + vec2(0.5);\n + vTexCoord.x /= uTextureWidth; vPosition = uModelView * position;\n }\n ); - std::string fragmentShader = DALI_COMPOSE_SHADER( + const char* fragmentShader = DALI_COMPOSE_SHADER( precision mediump float;\n - uniform vec2 uPageSize;\n + \n + varying mediump vec2 vTexCoord;\n + \n + uniform sampler2D sTexture;\n + uniform lowp vec4 uColor;\n + uniform vec3 uSize;\n uniform vec2 uSpineShadowParameter;\n varying vec3 vNormal;\n varying vec4 vPosition;\n - varying float vEdgeShadow;\n \n void main()\n {\n // need to re-normalize the interpolated normal - vec3 normal = normalize(vNormal);\n - vec4 texel;\n - float spineShadowCoef = 1.0; \n + vec3 normal = normalize( vNormal );\n // display page content + vec4 texel; // display back image of the page, flip the texture - if( dot(vPosition.xyz, normal) > 0.0 ) texel = texture2D( sTexture, vec2( sTextureRect.p+sTextureRect.s-vTexCoord.x, vTexCoord.y ) );\n + if( dot(vPosition.xyz, normal) > 0.0 ) texel = texture2D( sTexture, vec2( 1.0 - vTexCoord.x, vTexCoord.y ) );\n // display front image of the page else texel = texture2D( sTexture, vTexCoord );\n + // display book spine, a stripe of shadowed texture - float pixelPos = (vTexCoord.x-sTextureRect.s)*uPageSize.x; \n - if(pixelPos < uSpineShadowParameter.x) \n + float pixelPos = vTexCoord.x * uSize.x; \n + float spineShadowCoef = 1.0; \n + if( pixelPos < uSpineShadowParameter.x ) \n {\n float x = pixelPos - uSpineShadowParameter.x;\n - float y = sqrt( uSpineShadowParameter.x*uSpineShadowParameter.x - x*x);\n + float y = sqrt( uSpineShadowParameter.x*uSpineShadowParameter.x - x*x );\n spineShadowCoef = normalize( vec2( uSpineShadowParameter.y*x/uSpineShadowParameter.x, y ) ).y;\n }\n // calculate the lighting // set the ambient color as vec3(0.4); float lightColor = abs( normal.z ) * 0.6 + 0.4;\n - gl_FragColor = vec4( ( spineShadowCoef* lightColor)* texel.rgb , texel.a ) * uColor;\n + gl_FragColor = vec4( ( spineShadowCoef * lightColor ) * texel.rgb , texel.a ) * uColor;\n } ); - // Create the implementation, temporarily owned on stack, - Dali::ShaderEffect shaderEffectCustom = Dali::ShaderEffect::New( vertexShader, fragmentShader,ShaderEffect::HINT_GRID ); - - static const Vector2 DEFAULT_SPINE_SHADOW_PARAMETER(50.0f, 20.0f); - - Vector2 defaultPageSize = Dali::Stage::GetCurrent().GetSize(); - Dali::Matrix zeroMatrix(true); - shaderEffectCustom.SetUniform( "uCommonParameters", zeroMatrix ); - shaderEffectCustom.SetUniform( "uPageSize", defaultPageSize ); - shaderEffectCustom.SetUniform( "uSpineShadowParameter", DEFAULT_SPINE_SHADOW_PARAMETER ); + Property::Map map; - shaderEffectCustom.RegisterProperty( "uOriginalCenter", Vector2( defaultPageSize[0], defaultPageSize[1]*0.5f ) ); - shaderEffectCustom.RegisterProperty( "uCurrentCenter", Vector2( defaultPageSize[0], defaultPageSize[1]*0.5f ) ); + Property::Map customShader; - PageTurnApplyInternalConstraint(shaderEffectCustom); + customShader[ "vertexShader" ] = vertexShader; + customShader[ "fragmentShader" ] = fragmentShader; + customShader[ "subdivideGridX" ] = 20; + customShader[ "subdivideGridY" ] = 20; - // setting isTurningBack to -1.0f here means turning page forward - shaderEffectCustom.SetUniform( "uIsTurningBack", -1.0f ); + map[ "shader" ] = customShader; + return map; - return shaderEffectCustom; } diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h b/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h index 59a4603..1025d2d 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h @@ -19,11 +19,6 @@ */ // EXTERNAL INCLUDES -#include -#include -#include -#include -#include namespace Dali { @@ -37,15 +32,16 @@ namespace Internal /** * @brief Re-applies PageTurnEffect internal constraints - * The internal constraint uses the OriginalCenter property and the CurrentCenter Property + * The internal constraint uses the OriginalCenter property and the CURRENT_CENTER Property * to update the variety of common parameters which are with the same value for all the vertices. * Note: For each actor, the constraints are applied in the same order as the calls to Actor::ApplyConstraint(). - * So if there are other contraints applied to the OriginalCenter or CurrentCenter while when using this effect, + * So if there are other contraints applied to the ORIGINAL_CENTER or CURRENT_CENTER while when using this effect, * call this method to get the internal constraints and re-apply it afterwards. * - * @param[in] shaderEffect The page turn effect to which internal constraints should be re-applied + * @param[in] actor The page turn actor to which internal constraints should be re-applied + * @param[in] pageHeight The page height. */ -void PageTurnApplyInternalConstraint( ShaderEffect& shaderEffect); +void PageTurnApplyInternalConstraint( Actor& actor, float pageHeight ); /** * @brief Create a new PageTurnEffect @@ -54,33 +50,33 @@ void PageTurnApplyInternalConstraint( ShaderEffect& shaderEffect); * Usage example:- * * // create shader used for doing page-turn effect\n - * ShaderEffect pageTurnEffect = CreatePageTurnEffect(); + * Property::Map pageTurnEffect = CreatePageTurnEffect(); * - * // set image actor shader to the page-turn one\n + * // set image view custom shader to the page-turn one\n * // for portrait view, one image actor for each page\n * // for landscape view, the page turned over is still visible, so back image is needed \n * // in this case, create another image Actor using the back image and added to the page actor \n - * ImageActor pageActor = ImageActor::New(....); \n - * ImageActor backImageActor = ImageActor::New(....); \n - * pageActor.Add(backPageActor);\n - * pageActor.SetShaderEffect ( pageTurnEffect ); \n + * ImageView page = ImageView::New(....); \n + * page.SetProperty ( ImageView::Property::IMAGE, pageTurnEffect ); \n * * //set initial values - * pageTurnEffect.SetUniform("uPageSize", Vector2);\n - * pageTurnEffect.SetUniform("uOriginalCenter", Vector2);\n - * pageTurnEffect.SetUniform("uIsTurningBack", bool);\n - * pageTurnEffect.SetUniform("uCurrentCenter",Vector2);\n + * page.SetProperty( page.GetPropertyIndex("uIsTurningBack",) bool );\n + * page.SetProperty( page.GetPropertyIndex("uSpineShadowParameter",) Vector2 );\n + * page.SetProperty( page.GetPropertyIndex("ORIGINAL_CENTER"), Vector2 );\n + * page.SetProperty( page.GetPropertyIndex("CURRENT_CENTER"), Vector2 );\n + * page.SetProperty( page.GetPropertyIndex("uCommonParameters"), Matrix );\n + * page.SetProperty( page.GetPropertyIndex("uTextureWidth"), float ); // Set to 1.0 for single-sided or 2.0 for double-sided \n + * PageTurnApplyInternalConstraint( page );\n * * //Animate it with the current center property\n - * Animation animation[mAnimationIndex] = Animation::New( ... );\n - * animation.AnimateTo(Property( pageTurnEffect, "uCurrentCenter" ), - * currentCenter, - * AlphaFunction::...);\n - * animation[mAnimationIndex].Play(); \n + * Animation animation = Animation::New( ... );\n + * animation.AnimateTo(Property( page, "CURRENT_CENTER" ), + * currentCenter, + * AlphaFunction::...);\n + * animation.Play(); \n * - * Animatable/Constrainable uniforms: */ -ShaderEffect CreatePageTurnEffect(); +Property::Map CreatePageTurnEffect(); } // namespace Internal diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.cpp b/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.cpp index df0db93..bbaf508 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.cpp +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.cpp @@ -34,7 +34,6 @@ namespace Internal namespace { -using namespace Dali; DALI_TYPE_REGISTRATION_BEGIN( Toolkit::PageTurnLandscapeView, Toolkit::PageTurnView, NULL ) DALI_TYPE_REGISTRATION_END() @@ -66,33 +65,22 @@ Toolkit::PageTurnLandscapeView PageTurnLandscapeView::New( PageFactory& pageFact void PageTurnLandscapeView::OnPageTurnViewInitialize() { + mTurnEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 2.f ); + mSpineEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 2.f ); + mControlSize = Vector2( mPageSize.width * 2.f, mPageSize.height ); Self().SetSize( mControlSize ); mTurningPageLayer.SetParentOrigin( ParentOrigin::CENTER ); } -void PageTurnLandscapeView::OnAddPage( ImageActor newPage, bool isLeftSide ) +void PageTurnLandscapeView::OnAddPage( Actor newPage, bool isLeftSide ) { newPage.SetParentOrigin( ParentOrigin::CENTER ); - SetCullFace( newPage, CullBack ); - - if( 0 < newPage.GetChildCount() ) - { - ImageActor backImage = ImageActor::DownCast( newPage.GetChildAt( 0 ) ); - backImage.SetParentOrigin( ParentOrigin::CENTER ); - backImage.SetSize( mPageSize ); - SetCullFace( backImage, CullFront ); - backImage.SetZ( 0.25f * STATIC_PAGE_INTERVAL_DISTANCE ); - } - if( isLeftSide ) - { - SetShaderEffect( newPage, mSpineEffectBack ); - } } Vector2 PageTurnLandscapeView::SetPanPosition( const Vector2& gesturePosition ) { - if( mIsTurnBack[mPanActor] ) + if( mPages[mIndex].isTurnBack ) { return Vector2( mPageSize.width - gesturePosition.x, gesturePosition.y ); } @@ -104,31 +92,17 @@ Vector2 PageTurnLandscapeView::SetPanPosition( const Vector2& gesturePosition ) void PageTurnLandscapeView::SetPanActor( const Vector2& panPosition ) { - if( panPosition.x > mPageSize.width && mCurrentPageIndex < mTotalPageCount-1 ) + if( panPosition.x > mPageSize.width && mCurrentPageIndex < mTotalPageCount ) { - mPanActor = mPageActors[mCurrentPageIndex%NUMBER_OF_CACHED_PAGES]; // right side page mTurningPageIndex = mCurrentPageIndex; } else if( panPosition.x <= mPageSize.width && mCurrentPageIndex > 0 ) { - mPanActor = mPageActors[ (mCurrentPageIndex-1)%NUMBER_OF_CACHED_PAGES ]; // left side page mTurningPageIndex = mCurrentPageIndex - 1; } else { - mPanActor.Reset(); - } -} - -void PageTurnLandscapeView::SetSpineEffect(ImageActor actor, bool isLeftSide) -{ - if(isLeftSide) - { - SetShaderEffect( actor, mSpineEffectBack ); - } - else - { - SetShaderEffect( actor, mSpineEffectFront ); + mTurningPageIndex = -1; } } diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.h b/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.h index 2033649..6f29d67 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.h +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.h @@ -36,15 +36,16 @@ class PageTurnLandscapeView : public PageTurnView public: /** - * Create a new PageTurnLandscapeView - * @return A handle to the newly allocated PageTurnLandscapeView + * @copydoc Toolkit::PageTurnLandscapeView::New( PageFactory&, const Vector2& ) */ static Toolkit::PageTurnLandscapeView New( PageFactory& pageFactory, const Vector2& pageSize ); protected: /** * Constructor. - * It initializes the PageTurnLandscapeView members + * It initializes the PageTurnPortraitView members + * @param[in] pageFactory The factory which provides image actors to PageTurnView as the page content. + * @param[in] pageSize The size of the page */ PageTurnLandscapeView( PageFactory& pageFactory, const Vector2& pageSize ); @@ -63,7 +64,7 @@ protected: // From PageTurnView /** * @copydoc PageTurnView::OnAddPage */ - virtual void OnAddPage( ImageActor newPage, bool isLeftSide ); + virtual void OnAddPage( Actor newPage, bool isLeftSide ); /** * @copydoc PageTurnView::SetPanPosition @@ -75,11 +76,6 @@ protected: // From PageTurnView */ virtual void SetPanActor( const Vector2& panPosition ); - /** - * @copydoc PageTurnView::SetSpineEffect - */ - virtual void SetSpineEffect(ImageActor actor, bool isLeftSide); - private: //Undefined diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.cpp b/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.cpp index 9fe3a00..45d3d98 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.cpp +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.cpp @@ -38,8 +38,6 @@ namespace Internal namespace { -using namespace Dali; - DALI_TYPE_REGISTRATION_BEGIN( Toolkit::PageTurnPortraitView, Toolkit::PageTurnView, NULL ) DALI_TYPE_REGISTRATION_END() @@ -54,7 +52,6 @@ const float PAGE_TURN_OVER_ANIMATION_DURATION(0.5f); PageTurnPortraitView::PageTurnPortraitView( PageFactory& pageFactory, const Vector2& pageSize ) : PageTurnView( pageFactory, pageSize ) { - } PageTurnPortraitView::~PageTurnPortraitView() @@ -78,6 +75,9 @@ Toolkit::PageTurnPortraitView PageTurnPortraitView::New( PageFactory& pageFactor void PageTurnPortraitView::OnPageTurnViewInitialize() { + mTurnEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 1.f ); + mSpineEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 1.f ); + mControlSize = mPageSize; Self().SetSize( mPageSize ); mTurningPageLayer.SetParentOrigin( ParentOrigin::CENTER_LEFT ); @@ -92,24 +92,11 @@ void PageTurnPortraitView::SetPanActor( const Vector2& panPosition ) { if( mCurrentPageIndex < mTotalPageCount ) { - mPanActor = mPageActors[mCurrentPageIndex%NUMBER_OF_CACHED_PAGES]; mTurningPageIndex = mCurrentPageIndex; } else { - mPanActor.Reset(); - } -} - -void PageTurnPortraitView::SetSpineEffect(ImageActor actor, bool isLeftSide) -{ - if(isLeftSide) - { - actor.RemoveShaderEffect(); - } - else - { - actor.SetShaderEffect( mSpineEffectFront ); + mTurningPageIndex = -1; } } @@ -119,7 +106,8 @@ void PageTurnPortraitView::OnPossibleOutwardsFlick( const Vector2& panPosition, // There is previous page and an outwards flick is detected if( mCurrentPageIndex > 0 && gestureSpeed > GESTURE_SPEED_THRESHOLD && offset.x > fabs( offset.y )) { - ImageActor actor = mPageActors[ (mCurrentPageIndex-1) % NUMBER_OF_CACHED_PAGES ]; + int actorIndex = (mCurrentPageIndex-1) % NUMBER_OF_CACHED_PAGES; + Actor actor = mPages[ actorIndex ].actor; if(actor.GetParent() != Self()) { return; @@ -136,40 +124,34 @@ void PageTurnPortraitView::OnPossibleOutwardsFlick( const Vector2& panPosition, RemovePage( mCurrentPageIndex+NUMBER_OF_CACHED_PAGES_EACH_SIDE ); AddPage( mCurrentPageIndex-NUMBER_OF_CACHED_PAGES_EACH_SIDE ); OrganizePageDepth(); + mPageUpdated = true; - mPageActors[mTurningPageIndex%NUMBER_OF_CACHED_PAGES].SetVisible(true); + actor.SetVisible(true); // Add the page to tuning page layer and set up PageTurnEffect mShadowView.Add( actor ); - actor.SetShaderEffect( mTurnEffect[mIndex] ); - PageTurnApplyInternalConstraint(mTurnEffect[mIndex]); - mIsAnimating[mIndex] = true; - mTurnEffect[mIndex].SetUniform("uIsTurningBack", 1.f ); + mPages[actorIndex].UseEffect( mTurnEffectShader ); + mAnimatingCount++; Vector2 originalCenter( mPageSize.width*1.5f, 0.5f*mPageSize.height ); - mTurnEffect[mIndex].SetUniform("uOriginalCenter", originalCenter ); - mTurnEffect[mIndex].SetUniform("uCurrentCenter", Vector2( mPageSize.width*0.5f, mPageSize.height*0.5f ) ); + mPages[actorIndex].SetOriginalCenter( originalCenter ); + mPages[actorIndex].SetCurrentCenter( Vector2( mPageSize.width*0.5f, mPageSize.height*0.5f ) ); + PageTurnApplyInternalConstraint(actor, mPageSize.height); // Start an animation to turn the previous page back Animation animation = Animation::New( PAGE_TURN_OVER_ANIMATION_DURATION ); mAnimationPageIdPair[animation] = mCurrentPageIndex; - mAnimationIndexPair[animation] = mIndex; - animation.AnimateTo( Property( mTurnEffect[mIndex], "uCurrentCenter" ), + animation.AnimateTo( Property( actor, mPages[actorIndex].propertyCurrentCenter ), originalCenter, AlphaFunction::EASE_OUT, TimePeriod(PAGE_TURN_OVER_ANIMATION_DURATION*0.75f) ); animation.AnimateBy( Property( actor, Actor::Property::ORIENTATION ), AngleAxis( Degree( 180.0f ), Vector3::YAXIS ) ,AlphaFunction::EASE_OUT ); animation.Play(); - ImageActor imageActor = ImageActor::DownCast(actor); - if( imageActor ) - { - SetCullFace( imageActor, CullBack ); - } animation.FinishedSignal().Connect( this, &PageTurnPortraitView::TurnedOverBackwards ); } } -void PageTurnPortraitView::OnTurnedOver( ImageActor actor, bool isLeftSide ) +void PageTurnPortraitView::OnTurnedOver( Actor actor, bool isLeftSide ) { if( isLeftSide ) { @@ -179,11 +161,6 @@ void PageTurnPortraitView::OnTurnedOver( ImageActor actor, bool isLeftSide ) void PageTurnPortraitView::TurnedOverBackwards( Animation& animation ) { - ImageActor imageActor = mPageActors[mAnimationPageIdPair[animation] % NUMBER_OF_CACHED_PAGES]; - if( imageActor ) - { - SetCullFace( imageActor, CullNone ); - } TurnedOver( animation ); } diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.h b/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.h index 0adb4e5..6fb4c62 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.h +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.h @@ -39,8 +39,7 @@ class PageTurnPortraitView : public PageTurnView public: /** - * Create a new PageTurnPortraitView - * @return A handle to the newly allocated PageTurnPortraitView + * @copydoc Toolkit::PageTurnPortraitView::New( PageFactory&, const Vector2& ) */ static Toolkit::PageTurnPortraitView New( PageFactory& pageFactory, const Vector2& pageSize ); @@ -49,6 +48,8 @@ protected: /** * Constructor. * It initializes the PageTurnPortraitView members + * @param[in] pageFactory The factory which provides image actors to PageTurnView as the page content. + * @param[in] pageSize The size of the page */ PageTurnPortraitView( PageFactory& pageFactory, const Vector2& pageSize ); @@ -75,16 +76,14 @@ protected: // From PageTurnView virtual void SetPanActor( const Vector2& panPosition ); /** - * @copydoc PageTurnView::SetSpineEffect - */ - virtual void SetSpineEffect(ImageActor actor, bool isLeftSide); - - /** * @copydoc PageTurnView::OnPossibleOutwardsFlick */ virtual void OnPossibleOutwardsFlick( const Vector2& panPosition, float gestureSpeed ); - virtual void OnTurnedOver( ImageActor actor, bool isLeftSide ); + /** + * @copydoc PageTurnView::OnTurnedOver + */ + virtual void OnTurnedOver( Actor actor, bool isLeftSide ); private: diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp index 6db3956..19e8421 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp @@ -22,22 +22,47 @@ #include // for strcmp #include #include -#include +#include #include #include -#include -#include +#include // INTERNAL INCLUDES #include #include +#include + +// headers needed for backward compatibility of PageFactory::NewPage(pageId) API +#include using namespace Dali; namespace //Unnamed namespace { -// default grid density for page turn effect, 10 pixels by 10 pixels -const float DEFAULT_GRID_DENSITY(10.0f); +// broken image is loaded if there is no valid image provided for the page +const char * const BROKEN_IMAGE_URL( DALI_IMAGE_DIR "broken.png"); + +// names of shader property map +const char * const CUSTOM_SHADER( "shader" ); +const char * const CUSTOM_VERTEX_SHADER( "vertexShader" ); +const char * const CUSTOM_FRAGMENT_SHADER( "fragmentShader" ); + +// name of the texture in material +const char * const TEXTURE_NAME( "sTexture" ); + +// 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 + +// 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, 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); @@ -163,7 +188,7 @@ struct CurrentCenterConstraint 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; @@ -239,38 +264,115 @@ 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::SetImage( Image image ) +{ + if( material.GetNumberOfTextures() > 0 ) + { + material.SetTextureImage( 0u, image ); + } + else + { + material.AddTexture(image, TEXTURE_NAME); + } +} + +void PageTurnView::Page::UseEffect(Shader shader) +{ + if( material ) + { + material.SetShader( shader ); + } + else + { + material = Material::New( shader ); + } +} + +void PageTurnView::Page::UseEffect(Shader shader, Geometry geometry) +{ + UseEffect( shader ); + + if( !renderer ) + { + renderer = Renderer::New( geometry, material ); + 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( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ), - mPageFactory( pageFactory ), + mPageFactory( &pageFactory ), mPageSize( pageSize ), - mTotalPageCount( 0 ), - mPanning( false ), mSpineShadowParameter( DEFAULT_SPINE_SHADOW_PARAMETER ), + 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 ), - mDistanceUpCorner( 0.f ), - mDistanceBottomCorner( 0.f ), - mPanDisplacement( 0.f ), - mConstraints( false ), 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() @@ -279,58 +381,82 @@ PageTurnView::~PageTurnView() void PageTurnView::OnInitialize() { - // create the two book spine effect for static images, left and right side pages respectively - 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++ ) + // 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(mPageSize.width / DEFAULT_GRID_DENSITY + 0.5f); + uint16_t height = static_cast(mPageSize.height / DEFAULT_GRID_DENSITY + 0.5f); + mGeometry = RendererFactoryCache::CreateGridGeometry( Uint16Pair( width, height ) ); + mGeometry.SetRequiresDepthTesting( true ); + + mPages.reserve( NUMBER_OF_CACHED_PAGES ); + for( int i = 0; i < NUMBER_OF_CACHED_PAGES; i++ ) { - 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); - 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 images mTurningPageLayer = Layer::New(); mTurningPageLayer.SetAnchorPoint( AnchorPoint::CENTER_LEFT ); mTurningPageLayer.SetBehavior(Layer::LAYER_3D); + mTurningPageLayer.Raise(); // Set control size and the parent origin of page layers OnPageTurnViewInitialize(); Self().Add(mTurningPageLayer); - mTotalPageCount = static_cast( mPageFactory.GetNumberOfPages() ); + mTotalPageCount = static_cast( 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( i )*STATIC_PAGE_INTERVAL_DISTANCE ); - } + mPages[i].actor.SetZ( -static_cast( i )*STATIC_PAGE_INTERVAL_DISTANCE ); } - mPageActors[0].SetVisible(true); + mPages[0].actor.SetVisible(true); // enable the pan gesture which is attached to the control EnableGestureDetection(Gesture::Type(Gesture::Pan)); } +Shader PageTurnView::CreateShader( const Property::Map& shaderMap ) +{ + Shader shader; + Property::Value* shaderValue = shaderMap.Find( CUSTOM_SHADER ); + Property::Map shaderSource; + if( shaderValue && shaderValue->Get( shaderSource ) ) + { + std::string vertexShader; + Property::Value* vertexShaderValue = shaderSource.Find( 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( 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 = Toolkit::ShadowView::New( 0.25f, 0.25f ); @@ -362,31 +488,20 @@ void PageTurnView::OnStageConnection( int depth ) Control::OnStageConnection( depth ); SetupShadowView(); - mTurningPageLayer.Raise(); } void PageTurnView::OnStageDisconnection() { if(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) - { - mPanning = false; - - Self().Add(mPanActor); - mIsAnimating[mIndex] = false; - mPanActor.RemoveConstraints(); - mTurnEffect[mIndex].RemoveConstraints(); - mPageUpdated = true; - - SetSpineEffect( mPanActor, mIsTurnBack[mPanActor] ); - } + StopTurning(); Control::OnStageDisconnection(); } @@ -394,28 +509,15 @@ void PageTurnView::OnStageDisconnection() void PageTurnView::SetPageSize( const Vector2& pageSize ) { 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; i0 ) - { - mPageActors[i].GetChildAt(0).SetSize( mPageSize ); - } - } + mPages[i].actor.SetSize( mPageSize ); } OnPageTurnViewInitialize(); @@ -436,12 +538,8 @@ void PageTurnView::SetSpineShadowParameter( const Vector2& spineShadowParameter mSpineShadowParameter = spineShadowParameter; // set spine shadow parameter to all the shader effects - mSpineEffectFront.SetUniform("uSpineShadowParameter", mSpineShadowParameter ); - mSpineEffectBack.SetUniform("uSpineShadowParameter", mSpineShadowParameter ); - for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ ) - { - mTurnEffect[i].SetUniform("uSpineShadowParameter", mSpineShadowParameter ); - } + mSpineEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter ); + mTurnEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter ); } Vector2 PageTurnView::GetSpineShadowParameter() @@ -458,18 +556,12 @@ void PageTurnView::GoToPage( unsigned int pageId ) return; } + // if any animation ongoing, stop it. + StopTurning(); + // record the new current page index mCurrentPageIndex = pageIdx; - // clear the old pages - for(int i = 0; i < NUMBER_OF_CACHED_PAGES; i++ ) - { - if( mPageActors[i] ) - { - mPageActors[i].Unparent(); - mPageActors[i].Reset(); - } - } // 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++ ) @@ -477,10 +569,10 @@ void PageTurnView::GoToPage( unsigned int pageId ) AddPage( i ); } - mPageActors[pageId%NUMBER_OF_CACHED_PAGES].SetVisible(true); + mPages[pageId%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true); if( pageId > 0 ) { - mPageActors[(pageId-1)%NUMBER_OF_CACHED_PAGES].SetVisible(true); + mPages[(pageId-1)%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true); } // set ordered depth to the stacked pages OrganizePageDepth(); @@ -497,32 +589,30 @@ 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= ImageActor::DownCast( mPageFactory.NewPage( pageIndex ) ); - DALI_ASSERT_ALWAYS( newPage ); - newPage.SetAnchorPoint( AnchorPoint::CENTER_LEFT ); - newPage.SetParentOrigin( ParentOrigin::CENTER_LEFT ); - newPage.SetSize( mPageSize ); - Self().Add( newPage ); - mPageActors[index] = newPage; + Image newPageImage; + newPageImage = mPageFactory->NewPage( pageIndex ); - bool isLeftSide = ( pageIndex < mCurrentPageIndex ); - mIsTurnBack[ newPage ] = isLeftSide; - if( isLeftSide ) + if( !newPageImage ) // load the broken image { - // new page is added to the left side, so need to rotate it 180 degrees - newPage.RotateBy( Degree(-180.0f ), Vector3::YAXIS ); + newPageImage = ResourceImage::New( BROKEN_IMAGE_URL ); } - else + + bool isLeftSide = ( pageIndex < mCurrentPageIndex ); + if( mPages[index].isTurnBack != isLeftSide ) { - newPage.SetShaderEffect(mSpineEffectFront); + mPages[index].ChangeTurnDirection(); } - newPage.SetVisible( false ); + 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].SetImage( newPageImage ); // 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 ); } } @@ -531,9 +621,7 @@ void PageTurnView::RemovePage( int pageIndex ) if( pageIndex > -1 && pageIndex < mTotalPageCount) { int index = pageIndex % NUMBER_OF_CACHED_PAGES; - mPageActors[index].Unparent(); - mIsTurnBack.erase( mPageActors[index] ); - mPageActors[index].Reset(); + mPages[index].actor.SetVisible(false); } } @@ -544,38 +632,19 @@ void PageTurnView::OnPan( const PanGesture& gesture ) { 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() != Self()) // 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; } @@ -587,7 +656,6 @@ void PageTurnView::OnPan( const PanGesture& gesture ) case Gesture::Finished: case Gesture::Cancelled: { - mPanning = false; PanFinished( SetPanPosition( gesture.position ), gesture.GetSpeed() ); break; } @@ -604,13 +672,14 @@ void PageTurnView::PanStarted( const Vector2& gesturePosition ) { mPressDownPosition = gesturePosition; - if( !mPanActor ) + if( mTurningPageIndex == -1 ) { return; } + mIndex = mTurningPageIndex % NUMBER_OF_CACHED_PAGES; + mOriginalCenter = gesturePosition; - mTurnEffect[mIndex].SetUniform("uIsTurningBack", mIsTurnBack[ mPanActor] ? 1.f : -1.f); mPress = false; mPageUpdated = false; @@ -621,7 +690,7 @@ void PageTurnView::PanStarted( const Vector2& gesturePosition ) void PageTurnView::PanContinuing( const Vector2& gesturePosition ) { - if( !mPanActor ) + if( mTurningPageIndex == -1 ) { return; } @@ -645,31 +714,31 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition ) { mDistanceUpCorner = mOriginalCenter.Length(); mDistanceBottomCorner = ( mOriginalCenter - Vector2( 0.0f, mPageSize.height ) ).Length(); - mShadowView.Add( mPanActor ); - SetShaderEffect( mPanActor, mTurnEffect[mIndex] ); - mTurnEffect[mIndex].SetUniform("uOriginalCenter", mOriginalCenter ); + mShadowView.Add( mPages[mIndex].actor ); + mPages[mIndex].UseEffect( mTurnEffectShader ); + mPages[mIndex].SetOriginalCenter( mOriginalCenter ); mCurrentCenter = mOriginalCenter; - mTurnEffect[mIndex].SetUniform("uCurrentCenter", mCurrentCenter ); + mPages[mIndex].SetCurrentCenter( mCurrentCenter ); mPanDisplacement = 0.f; - mConstraints = true; + mConstraints = false; mPress = true; - mIsAnimating[mIndex] = true; + mAnimatingCount++; - mPageTurnStartedSignal.Emit( handle, static_cast(mTurningPageIndex), !mIsTurnBack[mPanActor] ); - int id = mTurningPageIndex + (mIsTurnBack[mPanActor]? -1 : 1); + mPageTurnStartedSignal.Emit( handle, static_cast(mTurningPageIndex), !mPages[mIndex].isTurnBack ); + int id = mTurningPageIndex + (mPages[mIndex].isTurnBack ? -1 : 1); if( id >=0 && id < mTotalPageCount ) { - mPageActors[id%NUMBER_OF_CACHED_PAGES].SetVisible(true); + mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true); } mShadowView.RemoveConstraints(); Actor self = Self(); - self.SetProperty( mPropertyPanDisplacement[mIndex], 0.f ); + mPages[mIndex].SetPanDisplacement( 0.f ); Constraint shadowBlurStrengthConstraint = Constraint::New( 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.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(); } } @@ -709,12 +778,12 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition ) { // 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 @@ -733,41 +802,38 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition ) offset *= k; Actor self = Self(); - Property::Index shaderOriginalCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex("uOriginalCenter"); - Constraint originalCenterConstraint = Constraint::New( mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex, OriginalCenterConstraint( mOriginalCenter, offset )); - originalCenterConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) ); + Constraint originalCenterConstraint = Constraint::New( 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("uCurrentCenter"); - Constraint currentCenterConstraint = Constraint::New( mTurnEffect[mIndex], shaderCurrentCenterPropertyIndex, CurrentCenterConstraint(mPageSize.width)); - currentCenterConstraint.AddSource( Source(self, mPropertyCurrentCenter[mIndex]) ); - currentCenterConstraint.AddSource( Source(mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex) ); + Constraint currentCenterConstraint = Constraint::New( 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(); - PageTurnApplyInternalConstraint(mTurnEffect[mIndex]); + PageTurnApplyInternalConstraint( mPages[mIndex].actor, mPageSize.height ); float distance = offset.Length(); - Constraint rotationConstraint = Constraint::New( mPanActor, Actor::Property::ORIENTATION, RotationConstraint(distance, mPageSize.width, mIsTurnBack[mPanActor])); - rotationConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) ); + Constraint rotationConstraint = Constraint::New( 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].SetUniform("uOriginalCenter",mOriginalCenter ); - mConstraints = true; + mPages[mIndex].actor.RemoveConstraints(); + mPages[mIndex].SetOriginalCenter(mOriginalCenter ); + mConstraints = false; mPanDisplacement = 0.f; } - mTurnEffect[mIndex].SetUniform("uCurrentCenter", currentCenter ); + mPages[mIndex].SetCurrentCenter( currentCenter ); mCurrentCenter = currentCenter; - PageTurnApplyInternalConstraint(mTurnEffect[mIndex]); + PageTurnApplyInternalConstraint(mPages[mIndex].actor, mPageSize.height ); } } } @@ -777,25 +843,25 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe // 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 ); @@ -810,30 +876,27 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe 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]), + animation.AnimateTo( Property(mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement), width,AlphaFunction::EASE_OUT_SINE); - animation.AnimateTo( Property(self, mPropertyCurrentCenter[mIndex]), + 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; - mAnimationIndexPair[animation] = mIndex; 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], "uCurrentCenter" ), + animation.AnimateTo( Property( mPages[mIndex].actor, mPages[mIndex].propertyCurrentCenter ), mOriginalCenter, AlphaFunction::LINEAR ); mAnimationPageIdPair[animation] = mTurningPageIndex; - mAnimationIndexPair[animation] = mIndex; animation.Play(); - mIsSliding[mIndex] = true; + mSlidingCount++; animation.FinishedSignal().Connect( this, &PageTurnView::SliddenBack ); - mPageTurnStartedSignal.Emit( handle, static_cast(mTurningPageIndex), mIsTurnBack[actor] ); + mPageTurnStartedSignal.Emit( handle, static_cast(mTurningPageIndex), mPages[mIndex].isTurnBack ); } } else @@ -842,60 +905,57 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe // In landscape view, nothing to do OnPossibleOutwardsFlick( gesturePosition, gestureSpeed ); } - mPageUpdated = true; } void PageTurnView::TurnedOver( Animation& animation ) { int pageId = mAnimationPageIdPair[animation]; - ImageActor actor = mPageActors[pageId % NUMBER_OF_CACHED_PAGES]; - mIsTurnBack[actor] = !mIsTurnBack[actor]; - actor.RemoveConstraints(); - Self().Add(actor); - int index = mAnimationIndexPair[animation]; - mIsAnimating[index] = false; - mTurnEffect[index].RemoveConstraints(); - mAnimationIndexPair.erase( animation ); + int index = pageId%NUMBER_OF_CACHED_PAGES; + + mPages[index].ChangeTurnDirection(); + mPages[index].actor.RemoveConstraints(); + Self().Add(mPages[index].actor); + mAnimatingCount--; mAnimationPageIdPair.erase( animation ); - SetSpineEffect( actor, mIsTurnBack[actor] ); + float degree = mPages[index].isTurnBack ? 180.f : 0.f; + mPages[index].actor.SetOrientation( Degree(degree), Vector3::YAXIS ); + mPages[index].UseEffect( mSpineEffectShader ); - int id = pageId + (mIsTurnBack[actor]? -1 : 1); + int id = pageId + (mPages[index].isTurnBack ? -1 : 1); if( id >=0 && id < mTotalPageCount ) { - mPageActors[id%NUMBER_OF_CACHED_PAGES].SetVisible(false); + mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(false); } - OnTurnedOver( actor, mIsTurnBack[actor] ); + OnTurnedOver( mPages[index].actor, mPages[index].isTurnBack ); // Guard against destruction during signal emission Toolkit::PageTurnView handle( GetOwner() ); - mPageTurnFinishedSignal.Emit( handle, static_cast(pageId), mIsTurnBack[actor] ); + mPageTurnFinishedSignal.Emit( handle, static_cast(pageId), mPages[index].isTurnBack ); } void PageTurnView::SliddenBack( Animation& animation ) { 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 ); + int index = pageId%NUMBER_OF_CACHED_PAGES; + Self().Add(mPages[index].actor); + mSlidingCount--; + mAnimatingCount--; mAnimationPageIdPair.erase( animation ); - SetSpineEffect( actor, mIsTurnBack[actor] ); + mPages[index].UseEffect( mSpineEffectShader ); - int id = pageId + (mIsTurnBack[actor]? -1 : 1); + int id = pageId + (mPages[index].isTurnBack ? -1 : 1); if( id >=0 && id < mTotalPageCount ) { - mPageActors[id%NUMBER_OF_CACHED_PAGES].SetVisible(false); + mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(false); } // Guard against destruction during signal emission Toolkit::PageTurnView handle( GetOwner() ); - mPageTurnFinishedSignal.Emit( handle, static_cast(pageId), mIsTurnBack[actor] ); + mPageTurnFinishedSignal.Emit( handle, static_cast(pageId), mPages[index].isTurnBack ); } void PageTurnView::OrganizePageDepth() @@ -904,18 +964,38 @@ void PageTurnView::OrganizePageDepth() { if(mCurrentPageIndex+i < mTotalPageCount) { - mPageActors[( mCurrentPageIndex+i )%NUMBER_OF_CACHED_PAGES].SetZ( -static_cast( i )*STATIC_PAGE_INTERVAL_DISTANCE ); + mPages[( mCurrentPageIndex+i )%NUMBER_OF_CACHED_PAGES].actor.SetZ( -static_cast( i )*STATIC_PAGE_INTERVAL_DISTANCE ); } if( mCurrentPageIndex >= i + 1 ) { - mPageActors[( mCurrentPageIndex-i-1 )%NUMBER_OF_CACHED_PAGES].SetZ( -static_cast( i )*STATIC_PAGE_INTERVAL_DISTANCE ); + mPages[( mCurrentPageIndex-i-1 )%NUMBER_OF_CACHED_PAGES].actor.SetZ( -static_cast( 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::iterator it=mAnimationPageIdPair.begin(); it!=mAnimationPageIdPair.end(); ++it) + { + static_cast(it->first).SetCurrentProgress( 1.f ); + } + } } Toolkit::PageTurnView::PageTurnSignal& PageTurnView::PageTurnStartedSignal() diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h index 91a714f..e17f2a0 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h @@ -21,10 +21,7 @@ // EXTERNAL INCLUDES #include #include -#include -#include -#include -#include +#include // INTERNAL INCLUDES #include @@ -46,6 +43,82 @@ class PageTurnView : public Control protected: /** + * The book page class + */ + struct Page + { + /** + * Constructor + */ + Page(); + /** + * Destructor + */ + ~Page(){}; + + /** + * Set the page image content + * @param[in] image The content of the page. + */ + void SetImage( Image image ); + + /** + * Apply an effect onto the page actor. + * @param[in] shader The shader for rendering effect. + */ + void UseEffect(Shader shader); + + /** + * Apply an effect onto the page actor. + * @param[in] shader The shader for rendering effect. + * @param[in] geometry The geometry for rendering effect. + */ + void UseEffect(Shader shader, Geometry geometry); + + /** + * Change the page turning direction. + */ + void ChangeTurnDirection(); + + /** + * Set the pan displacement property + * @param[in] value The property value + */ + void SetPanDisplacement(float value); + + /** + * Set the pan center property + * @param[in] value The property value + */ + void SetPanCenter( const Vector2& value ); + + /** + * Set the original center property to be used by shader + * @param[in] value The property value + */ + void SetOriginalCenter( const Vector2& value ); + + /** + * Set the current center property to be used by shader + * @param[in] value The property value + */ + void SetCurrentCenter( const Vector2& value ); + + Actor actor; ///< The page actor + Material material; ///< The material of the actor + Renderer renderer; ///< The renderer of the actor + bool isTurnBack; ///< The turning direction + Property::Index propertyPanDisplacement; ///< The horizontal displacement of the pan + Property::Index propertyPanCenter; ///< The current pan position + Property::Index propertyOriginalCenter; ///< The original center to be used by the shader + Property::Index propertyCurrentCenter; ///< The current center to be used by the shader + Property::Index propertyTurnDirection; ///< The turning direction property + }; + + +protected: + + /** * Constructor. * It initializes the PageTurnView members */ @@ -125,15 +198,14 @@ protected: */ void OrganizePageDepth(); +private: + /** - * Set shader Effect to the actor. - * If the actor has children, the shader effect is also applied to its first child - * @param[in] actor The actor which the shader effect would be applied onto - * @param[in] shaderEffect The shader effect to be set to the actor + * Create shader from a property map. + * @param[in] shaderMap The shader property map; + * @return The created shader. */ - void SetShaderEffect( ImageActor actor, ShaderEffect shaderEffect ); - -private: + Shader CreateShader( const Property::Map& shaderMap ); /** * Set up the shadow view control to cast shadow @@ -166,6 +238,11 @@ private: */ void SliddenBack( Animation& animation ); + /** + * Stop the page turning animation and contraint. + * This method should be called when taking off stage or jump to a specified page. + */ + void StopTurning(); private: // from Control @@ -204,7 +281,7 @@ private: // implemented differently by PageTurnLandscapeView and PageTurnPortrai * @param[in] newPage The added page actor * @param[in] isLeftSide Which side the new page is added to */ - virtual void OnAddPage( ImageActor newPage, bool isLeftSide ) { } + virtual void OnAddPage( Actor newPage, bool isLeftSide ) { } /** * This method is called when pan started or continuing @@ -223,15 +300,6 @@ private: // implemented differently by PageTurnLandscapeView and PageTurnPortrai virtual void SetPanActor( const Vector2& panPosition ) = 0; /** - * This method is called when a page is turned over or slidden back - * Remove PageTurnEffect and use a proper PageTurnBookSpineEffect - * Implemented in subclasses to provide specific behaviour. - * @param[in] actor The current page actor - * @param[in] isLeftSide Which side the current page is located - */ - virtual void SetSpineEffect(ImageActor actor, bool isLeftSide) = 0; - - /** * This method is called when pan finished to detect outwards flick * In portrait view, start an animation of turning previous page back when outwards flick is detected * In landscape view, nothing to do @@ -246,7 +314,7 @@ private: // implemented differently by PageTurnLandscapeView and PageTurnPortrai * @param[in] actor The page actor * @param[in] isLeftSide Which side the page is turned to */ - virtual void OnTurnedOver( ImageActor actor, bool isLeftSide ) { } + virtual void OnTurnedOver( Actor actor, bool isLeftSide ) { } public: //signal and property @@ -309,53 +377,50 @@ private: protected: - Vector2 mControlSize; ///< The size of the control, it is decided by the page size, the SetSize from application can not change it Layer mTurningPageLayer; ///< The layer for the turning page, to avoid possible depth conflict Toolkit::ShadowView mShadowView; ///< The shadow view control for shadow casting Actor mShadowPlaneBackground; ///< The plane for the shadow to cast on Actor mPointLight; ///< The point light used for shadow casting - PageFactory& mPageFactory; ///< The page factory which provides the page actors - Vector2 mPageSize; ///< The page size - int mTotalPageCount; ///< The total number of pages provided by the page factory + PageFactory* const mPageFactory; ///< The factory which provides the page actors + Shader mTurnEffectShader; ///< The group of PageTurnEffects + Shader mSpineEffectShader; ///< The book spine shader effect + Geometry mGeometry; ///< The grid geometry for pages - bool mPanning; ///< The boolean to indicate whether the pan gesture is continuing + std::vector mPages; ///< The vector of pages on stage + std::map mAnimationPageIdPair; ///< The map to keep track which page actor is the animation act on - std::vector mTurnEffect; ///< The group of PageTurnEffects - ShaderEffect mSpineEffectFront; ///< The book spine shader effect without flipping image content - ShaderEffect mSpineEffectBack; ///< The book spine shader effect with image content flipped + Vector2 mPageSize; ///< The page size + Vector2 mControlSize; ///< The size of the control, it is decided by the page size, the SetSize from application can not change it Vector2 mSpineShadowParameter; ///< The spine shadow parameter for all the above shader effects Vector2 mOriginalCenter; ///< The original center set to the PageTurnEffect Vector2 mCurrentCenter; ///< The current center set to the PageTurnEffect - - std::vector mPageActors; ///< The vector of pages on stage - int mCurrentPageIndex; ///< The index of the current page, between 0 ~ mTotalPageCount-1 - int mTurningPageIndex; ///< The index of the turning page - std::map mIsTurnBack; ///< The map to keep track the page actor's turning direction - std::map mAnimationPageIdPair; ///< The map to keep track which page actor is the animation act on - std::map mAnimationIndexPair; ///< The map to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is used for the animation - int mIndex; ///< The index to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is used for the current panning page - std::vector mIsAnimating; ///< The boolean vector to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is available for using - std::vector mIsSliding; ///< The boolean vector to keep track whether there are animating pages sliding back - - ImageActor mPanActor; ///< The page being panned by the pan gesture Vector2 mPressDownPosition; ///< The first press down position of the pan gesture - bool mPress; ///< The boolean to keep track the state of the pageTurnEffect is activated or not - bool mPageUpdated; ///< The boolean to keep track whether is page is updated after any turning activity float mDistanceUpCorner; ///< The distance between the original center of PageTurnEffect and the top-left corner of the page float mDistanceBottomCorner; ///< The distance between the original center of PageTurnEffect and the bottom-left corner of the page - - std::vector mPropertyPanDisplacement; ///< The pan displacement property group - std::vector mPropertyCurrentCenter; ///< The current center property group float mPanDisplacement; ///< The displacement of the pan after the constrains are applied + + int mTotalPageCount; ///< The total number of pages provided by the page factory + int mCurrentPageIndex; ///< The index of the current page, between 0 ~ mTotalPageCount-1 + int mTurningPageIndex; ///< The index of the turning page + int mIndex; ///< The index to keep track which PanDisplacementProperty, CurrentCenterProperty is used for the current panning page + int mSlidingCount; ///< The boolean vector to keep track whether there are animating pages sliding back + int mAnimatingCount; ///< The boolean vector to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is available for using + bool mConstraints; ///< The boolean to keep track the constrains are applied or not + bool mPress; ///< The boolean to keep track the state of the pageTurnEffect is activated or not + bool mPageUpdated; ///< The boolean to keep track whether is page is updated after any turning activity Toolkit::PageTurnView::PageTurnSignal mPageTurnStartedSignal; ///< The signal to notify that a page has started turning Toolkit::PageTurnView::PageTurnSignal mPageTurnFinishedSignal; ///< The signal to notify that a page has finished turning Toolkit::PageTurnView::PagePanSignal mPagePanStartedSignal; ///< The signal to notify that a page has started panning Toolkit::PageTurnView::PagePanSignal mPagePanFinishedSignal; ///< The signal to notify that a page has finished panning + static const char * const PROPERTY_TEXTURE_WIDTH; ///< The uniform name of texture width + static const char * const PROPERTY_ORIGINAL_CENTER; ///< The property name of original center, which is used to constrain the uniforms + static const char * const PROPERTY_CURRENT_CENTER; ///< The property name of current center, which is used to constrain the uniforms + static const int MAXIMUM_TURNING_NUM; ///< How many pages are allowed to animating in the same time static const int NUMBER_OF_CACHED_PAGES_EACH_SIDE; ///< The maximum number of pages kept, (MAXIMUM_ANIMATION_NUM+1) pages for each side static const int NUMBER_OF_CACHED_PAGES; ///< The maximum number of pages kept, (MAXIMUM_ANIMATION_NUM+1)*2 pages in total diff --git a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp index b8c6343..17eae58 100644 --- a/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp +++ b/dali-toolkit/internal/controls/renderers/image/image-renderer.cpp @@ -109,34 +109,6 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( }\n ); - -Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned int >& indices ) -{ - Property::Map vertexFormat; - vertexFormat[ "aPosition" ] = Property::VECTOR2; - PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat ); - if( vertices.Size() > 0 ) - { - vertexPropertyBuffer.SetData( &vertices[ 0 ], vertices.Size() ); - } - - Property::Map indexFormat; - indexFormat[ "indices" ] = Property::INTEGER; - PropertyBuffer indexPropertyBuffer = PropertyBuffer::New( indexFormat ); - if( indices.Size() > 0 ) - { - indexPropertyBuffer.SetData( &indices[ 0 ], indices.Size() ); - } - - // Create the geometry object - Geometry geometry = Geometry::New(); - geometry.AddVertexBuffer( vertexPropertyBuffer ); - geometry.SetIndexBuffer( indexPropertyBuffer ); - geometry.SetGeometryType( Geometry::TRIANGLE_STRIP ); - - return geometry; -} - Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gridSize ) { Geometry geometry; @@ -146,54 +118,13 @@ Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gri geometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY ); if( !geometry ) { - geometry = factoryCache.CreateQuadGeometry(); + geometry = RendererFactoryCache::CreateQuadGeometry(); factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, geometry ); } } else { - uint16_t gridWidth = gridSize.GetWidth(); - uint16_t gridHeight = gridSize.GetHeight(); - - // Create vertices - Vector< Vector2 > vertices; - vertices.Reserve( ( gridWidth + 1 ) * ( gridHeight + 1 ) ); - - for( int y = 0; y < gridHeight + 1; ++y ) - { - for( int x = 0; x < gridWidth + 1; ++x ) - { - vertices.PushBack( Vector2( (float)x/gridWidth - 0.5f, (float)y/gridHeight - 0.5f) ); - } - } - - // Create indices - Vector< unsigned int > indices; - indices.Reserve( (gridWidth+2)*gridHeight*2 - 2); - - for( unsigned int row = 0u; row < gridHeight; ++row ) - { - unsigned int rowStartIndex = row*(gridWidth+1u); - unsigned int nextRowStartIndex = rowStartIndex + gridWidth +1u; - - if( row != 0u ) // degenerate index on non-first row - { - indices.PushBack( rowStartIndex ); - } - - for( unsigned int column = 0u; column < gridWidth+1u; column++) // main strip - { - indices.PushBack( rowStartIndex + column); - indices.PushBack( nextRowStartIndex + column); - } - - if( row != gridHeight-1u ) // degenerate index on non-last row - { - indices.PushBack( nextRowStartIndex + gridWidth ); - } - } - - return GenerateGeometry( vertices, indices ); + geometry = RendererFactoryCache::CreateGridGeometry( gridSize ); } return geometry; diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp index ecfc6b5..3a6b79f 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp @@ -161,8 +161,8 @@ Geometry RendererFactoryCache::CreateQuadGeometry() QuadVertex quadVertexData[4] = { { Vector2(-halfWidth, -halfHeight) }, - { Vector2( halfWidth, -halfHeight) }, { Vector2(-halfWidth, halfHeight) }, + { Vector2( halfWidth, -halfHeight) }, { Vector2( halfWidth, halfHeight) } }; @@ -197,6 +197,74 @@ void RendererFactoryCache::ApplyRasterizedSVGToSampler() } } +Geometry RendererFactoryCache::CreateGridGeometry( Uint16Pair gridSize ) +{ + uint16_t gridWidth = gridSize.GetWidth(); + uint16_t gridHeight = gridSize.GetHeight(); + + // Create vertices + Vector< Vector2 > vertices; + vertices.Reserve( ( gridWidth + 1 ) * ( gridHeight + 1 ) ); + + for( int y = 0; y < gridHeight + 1; ++y ) + { + for( int x = 0; x < gridWidth + 1; ++x ) + { + vertices.PushBack( Vector2( (float)x/gridWidth - 0.5f, (float)y/gridHeight - 0.5f) ); + } + } + + // Create indices + Vector< unsigned int > indices; + indices.Reserve( (gridWidth+2)*gridHeight*2 - 2); + + for( unsigned int row = 0u; row < gridHeight; ++row ) + { + unsigned int rowStartIndex = row*(gridWidth+1u); + unsigned int nextRowStartIndex = rowStartIndex + gridWidth +1u; + + if( row != 0u ) // degenerate index on non-first row + { + indices.PushBack( rowStartIndex ); + } + + for( unsigned int column = 0u; column < gridWidth+1u; column++) // main strip + { + indices.PushBack( rowStartIndex + column); + indices.PushBack( nextRowStartIndex + column); + } + + if( row != gridHeight-1u ) // degenerate index on non-last row + { + indices.PushBack( nextRowStartIndex + gridWidth ); + } + } + + Property::Map vertexFormat; + vertexFormat[ "aPosition" ] = Property::VECTOR2; + PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat ); + if( vertices.Size() > 0 ) + { + vertexPropertyBuffer.SetData( &vertices[ 0 ], vertices.Size() ); + } + + Property::Map indexFormat; + indexFormat[ "indices" ] = Property::INTEGER; + PropertyBuffer indexPropertyBuffer = PropertyBuffer::New( indexFormat ); + if( indices.Size() > 0 ) + { + indexPropertyBuffer.SetData( &indices[ 0 ], indices.Size() ); + } + + // Create the geometry object + Geometry geometry = Geometry::New(); + geometry.AddVertexBuffer( vertexPropertyBuffer ); + geometry.SetIndexBuffer( indexPropertyBuffer ); + geometry.SetGeometryType( Geometry::TRIANGLE_STRIP ); + + return geometry; +} + } // namespace Internal } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h index 89334c5..f6fd573 100644 --- a/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h +++ b/dali-toolkit/internal/controls/renderers/renderer-factory-cache.h @@ -21,6 +21,7 @@ #include "svg/svg-rasterize-thread.h" // EXTERNAL INCLUDES +#include #include #include #include @@ -114,6 +115,13 @@ public: */ static Geometry CreateQuadGeometry(); + /** + * Create the grid geometry. + * @param[in] gridSize The size of the grid. + * @return The created grid geometry. + */ + static Geometry CreateGridGeometry( Uint16Pair gridSize ); + public: /** diff --git a/dali-toolkit/public-api/controls/page-turn-view/page-factory.h b/dali-toolkit/public-api/controls/page-turn-view/page-factory.h index 99d036a..16bfdca 100644 --- a/dali-toolkit/public-api/controls/page-turn-view/page-factory.h +++ b/dali-toolkit/public-api/controls/page-turn-view/page-factory.h @@ -29,7 +29,7 @@ namespace Toolkit /** * @brief PageFactory is an abstract interface for providing image actors to PageTurnView - * Each image actor is identified by a unique ID, and has a linear order from 0 to GetNumberOfPages()-1 + * Each page is identified by a unique ID, and has a linear order from 0 to GetNumberOfPages()-1 * * @SINCE_1_1.4 */ @@ -37,6 +37,8 @@ class DALI_IMPORT_API PageFactory { public: + class Extension; ///< Forward declare future extension interface + /** * @brief Virtual destructor * @SINCE_1_1.4 @@ -45,18 +47,35 @@ public: /** * @brief Query the number of pages available from the factory. + * * The maximum available page has an ID of GetNumberOfPages()-1. * @SINCE_1_1.4 + * @return The page count. */ virtual unsigned int GetNumberOfPages() = 0; /** * @brief Create an actor to represent the page content. - * @SINCE_1_1.4 + * @SINCE_1_1.30 + * + * If no valid image provided, a broken image is displayed. + * For double-sided page( PageTurnLandscapeView ), the left half of image is used as page front side, and the right half as page back side. + * * @param[in] pageId The ID of the page to create. * @return An actor, or an uninitialized pointer if the ID is out of range. */ - virtual Actor NewPage( unsigned int pageId ) = 0; + virtual Image NewPage( unsigned int pageId ) = 0; + + /** + * @brief Retrieve the extension for this factory + * @SINCE_1_1.30 + * + * @return The extension if available, NULL otherwise. + */ + virtual Extension* GetExtension() + { + return NULL; + } }; } // namespace Toolkit -- 2.7.4