X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fpage-turn-view%2Fpage-turn-view-impl.cpp;h=df3bf6fc8ae92e0a07f3f4b902abc2cc6f595831;hp=14e84057c850d00231ff9fe3c592aa0853eb48a9;hb=f546dd5d83a968e573f8f053a01ce43df32c71a0;hpb=a56850b33d59c828e3e323670905bd6a29c4abf5 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 14e8405..df3bf6f 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -22,29 +22,43 @@ #include // for strcmp #include #include -#include #include -#include -#include +#include +#include // INTERNAL INCLUDES +#include #include #include +#include +#include +#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); +// 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 -// to bent the page, the minimal horizontal pan start position is pageSize.x * MINIMUM_START_POSITION_RATIO +// 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 viewPageSize.x * MINIMUM_START_POSITION_RATIO const float MINIMUM_START_POSITION_RATIO(0.6f); -// the maximum vertical displacement of pan gesture, if exceed, will reduce it: pageSize.y * MAXIMUM_VERTICAL_MOVEMENT_RATIO +// the maximum vertical displacement of pan gesture, if exceed, will reduce it: viewPageSize.y * MAXIMUM_VERTICAL_MOVEMENT_RATIO const float MAXIMUM_VERTICAL_MOVEMENT_RATIO(0.15f); -// when the x component of pan position reaches pageSize.x * PAGE_TURN_OVER_THRESHOLD_RATIO, page starts to turn over +// when the x component of pan position reaches viewPageSize.x * PAGE_TURN_OVER_THRESHOLD_RATIO, page starts to turn over const float PAGE_TURN_OVER_THRESHOLD_RATIO(0.5f); // duration of animation, shorter for faster speed @@ -162,7 +176,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; @@ -224,52 +238,131 @@ BaseHandle Create() // Setup properties, signals and actions using the type-registry. DALI_TYPE_REGISTRATION_BEGIN( Toolkit::PageTurnView, Toolkit::Control, Create ); -DALI_PROPERTY_REGISTRATION( Toolkit, PageTurnView, "page-size", VECTOR2, PAGE_SIZE ) -DALI_PROPERTY_REGISTRATION( Toolkit, PageTurnView, "current-page-id", INTEGER, CURRENT_PAGE_ID ) -DALI_PROPERTY_REGISTRATION( Toolkit, PageTurnView, "spine-shadow", VECTOR2, SPINE_SHADOW ) +DALI_PROPERTY_REGISTRATION( Toolkit, PageTurnView, "viewPageSize", VECTOR2, VIEW_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, "page-turn-started", SIGNAL_PAGE_TURN_STARTED ) -DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "page-turn-finished", SIGNAL_PAGE_TURN_FINISHED ) -DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "page-pan-started", SIGNAL_PAGE_PAN_STARTED ) -DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "page-pan-finished", SIGNAL_PAGE_PAN_FINISHED ) +DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pageTurnStarted", SIGNAL_PAGE_TURN_STARTED ) +DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pageTurnFinished", SIGNAL_PAGE_TURN_FINISHED ) +DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pagePanStarted", SIGNAL_PAGE_PAN_STARTED ) +DALI_SIGNAL_REGISTRATION( Toolkit, PageTurnView, "pagePanFinished", SIGNAL_PAGE_PAN_FINISHED ) DALI_TYPE_REGISTRATION_END() } // these several constants are also used in the derived classes +const char * const PageTurnView::PROPERTY_TEXTURE_WIDTH( "uTextureWidth" ); // uniform name +const char * const PageTurnView::PROPERTY_ORIGINAL_CENTER( "originalCenter" ); // property used to constrain the uniform +const char * const PageTurnView::PROPERTY_CURRENT_CENTER( "currentCenter" );// property used to constrain the uniform const int PageTurnView::MAXIMUM_TURNING_NUM = 4; const int PageTurnView::NUMBER_OF_CACHED_PAGES_EACH_SIDE = MAXIMUM_TURNING_NUM + 1; const int PageTurnView::NUMBER_OF_CACHED_PAGES = NUMBER_OF_CACHED_PAGES_EACH_SIDE*2; const float PageTurnView::STATIC_PAGE_INTERVAL_DISTANCE = 1.0f; -PageTurnView::PageTurnView( PageFactory& pageFactory, const Vector2& pageSize ) -: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ), - mPageFactory( pageFactory ), - mPageSize( pageSize ), - mTotalPageCount( 0 ), - mPanning( false ), +PageTurnView::Page::Page() +: isTurnBack( false ) +{ + actor = Actor::New(); + actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT ); + actor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER_LEFT ); + actor.SetProperty( Actor::Property::VISIBLE, false ); + + propertyPanDisplacement = actor.RegisterProperty( PROPERTY_PAN_DISPLACEMENT, 0.f ); + propertyPanCenter = actor.RegisterProperty(PROPERTY_PAN_CENTER, Vector2::ZERO); + + propertyOriginalCenter = actor.RegisterProperty(PROPERTY_ORIGINAL_CENTER, Vector2::ZERO); + propertyCurrentCenter = actor.RegisterProperty(PROPERTY_CURRENT_CENTER, Vector2::ZERO); + Matrix zeroMatrix(true); + actor.RegisterProperty(PROPERTY_COMMON_PARAMETERS, zeroMatrix); + propertyTurnDirection = actor.RegisterProperty(PROPERTY_TURN_DIRECTION, -1.f); +} + +void PageTurnView::Page::SetTexture( Texture texture ) +{ + if( !textureSet ) + { + textureSet = TextureSet::New(); + } + textureSet.SetTexture( 0u, texture ); +} + +void PageTurnView::Page::UseEffect(Shader newShader) +{ + shader = newShader; + if( renderer ) + { + renderer.SetShader( shader ); + } +} + +void PageTurnView::Page::UseEffect(Shader newShader, Geometry geometry) +{ + UseEffect( newShader ); + + if( !renderer ) + { + renderer = Renderer::New( geometry, shader ); + + if( !textureSet ) + { + textureSet = TextureSet::New(); + } + + renderer.SetTextures( textureSet ); + renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::ON ); + actor.AddRenderer( renderer ); + } +} + +void PageTurnView::Page::ChangeTurnDirection() +{ + isTurnBack = !isTurnBack; + actor.SetProperty( propertyTurnDirection, isTurnBack ? 1.f : -1.f ); +} + +void PageTurnView::Page::SetPanDisplacement(float value) +{ + actor.SetProperty( propertyPanDisplacement, value ); +} + +void PageTurnView::Page::SetPanCenter( const Vector2& value ) +{ + actor.SetProperty( propertyPanCenter, value ); +} + +void PageTurnView::Page::SetOriginalCenter( const Vector2& value ) +{ + actor.SetProperty( propertyOriginalCenter, value ); +} + +void PageTurnView::Page::SetCurrentCenter( const Vector2& value ) +{ + actor.SetProperty( propertyCurrentCenter, value ); +} + +PageTurnView::PageTurnView( PageFactory& pageFactory, const Vector2& viewPageSize ) +: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), + mPageFactory( &pageFactory ), + mPageSize( viewPageSize ), 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() @@ -278,77 +371,105 @@ 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 = VisualFactoryCache::CreateGridGeometry( Uint16Pair( width, height ) ); + + 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.SetProperty( Actor::Property::SIZE, mPageSize ); + Self().Add( mPages[i].actor ); } + // create the layer for turning pages mTurningPageLayer = Layer::New(); - mTurningPageLayer.SetAnchorPoint( AnchorPoint::CENTER_LEFT ); - mTurningPageLayer.SetBehavior(Layer::LAYER_3D); + mTurningPageLayer.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT ); + mTurningPageLayer.SetProperty( Layer::Property::BEHAVIOR, 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]) + mPages[i].actor.SetProperty( Actor::Property::POSITION_Z, -static_cast( i )*STATIC_PAGE_INTERVAL_DISTANCE ); + } + mPages[0].actor.SetProperty( Actor::Property::VISIBLE,true); + + // enable the pan gesture which is attached to the control + EnableGestureDetection(GestureType::Value(GestureType::PAN)); + + DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) { + return std::unique_ptr< Dali::Accessibility::Accessible >( + new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::PAGE_TAB_LIST ) ); + } ); +} + +Shader PageTurnView::CreateShader( const Property::Map& shaderMap ) +{ + Shader shader; + Property::Value* shaderValue = shaderMap.Find( Toolkit::Visual::Property::SHADER, CUSTOM_SHADER ); + Property::Map shaderSource; + if( shaderValue && shaderValue->Get( shaderSource ) ) + { + std::string vertexShader; + Property::Value* vertexShaderValue = shaderSource.Find( Toolkit::Visual::Shader::Property::VERTEX_SHADER, CUSTOM_VERTEX_SHADER ); + if( !vertexShaderValue || !vertexShaderValue->Get( vertexShader ) ) + { + DALI_LOG_ERROR("PageTurnView::CreateShader failed: vertex shader source is not available.\n"); + } + std::string fragmentShader; + Property::Value* fragmentShaderValue = shaderSource.Find( Toolkit::Visual::Shader::Property::FRAGMENT_SHADER, CUSTOM_FRAGMENT_SHADER ); + if( !fragmentShaderValue || !fragmentShaderValue->Get( fragmentShader ) ) { - mPageActors[i].SetZ( -static_cast( i )*STATIC_PAGE_INTERVAL_DISTANCE ); + 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"); } - mPageActors[0].SetVisible(true); - // enable the pan gesture which is attached to the control - EnableGestureDetection(Gesture::Type(Gesture::Pan)); + return shader; } void PageTurnView::SetupShadowView() { mShadowView = Toolkit::ShadowView::New( 0.25f, 0.25f ); - Vector3 origin = mTurningPageLayer.GetCurrentParentOrigin(); - mShadowView.SetParentOrigin( origin ); - mShadowView.SetAnchorPoint( origin ); + Vector3 origin = mTurningPageLayer.GetCurrentProperty< Vector3 >( Actor::Property::PARENT_ORIGIN ); + mShadowView.SetProperty( Actor::Property::PARENT_ORIGIN, origin ); + mShadowView.SetProperty( Actor::Property::ANCHOR_POINT, origin ); mShadowView.SetPointLightFieldOfView( Math::PI / 2.0f); mShadowView.SetShadowColor(DEFAULT_SHADOW_COLOR); mShadowPlaneBackground = Actor::New(); - mShadowPlaneBackground.SetPositionInheritanceMode( USE_PARENT_POSITION_PLUS_LOCAL_POSITION ); - mShadowPlaneBackground.SetSize( mControlSize ); + mShadowPlaneBackground.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER ); + mShadowPlaneBackground.SetProperty( Actor::Property::SIZE, 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 ); + mPointLight.SetProperty( Actor::Property::ANCHOR_POINT, origin ); + mPointLight.SetProperty( Actor::Property::PARENT_ORIGIN, origin ); + mPointLight.SetProperty( Actor::Property::POSITION, Vector3( 0.f, 0.f, mPageSize.width*POINT_LIGHT_HEIGHT_RATIO )); Self().Add( mPointLight ); mShadowView.SetPointLight( mPointLight ); @@ -356,72 +477,48 @@ void PageTurnView::SetupShadowView() mShadowView.Activate(); } -void PageTurnView::OnStageConnection( int depth ) +void PageTurnView::OnSceneConnection( int depth ) { - Control::OnStageConnection( depth ); - SetupShadowView(); - mTurningPageLayer.Raise(); + + Control::OnSceneConnection( depth ); } -void PageTurnView::OnStageDisconnection() +void PageTurnView::OnSceneDisconnection() { 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; + StopTurning(); - Self().Add(mPanActor); - mIsAnimating[mIndex] = false; - mPanActor.RemoveConstraints(); - mTurnEffect[mIndex].RemoveConstraints(); - mPageUpdated = true; - - SetSpineEffect( mPanActor, mIsTurnBack[mPanActor] ); - } - - Control::OnStageDisconnection(); + Control::OnSceneDisconnection(); } -void PageTurnView::SetPageSize( const Vector2& pageSize ) +void PageTurnView::SetPageSize( const Vector2& viewPageSize ) { - 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 ); - } + mPageSize = viewPageSize; if( mPointLight ) { - mPointLight.SetPosition( 0.f, 0.f, mPageSize.width*POINT_LIGHT_HEIGHT_RATIO ); + mPointLight.SetProperty( Actor::Property::POSITION, Vector3( 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.SetProperty( Actor::Property::SIZE, mPageSize ); } OnPageTurnViewInitialize(); if( mShadowPlaneBackground ) { - mShadowPlaneBackground.SetSize( mControlSize ); + mShadowPlaneBackground.SetProperty( Actor::Property::SIZE, mControlSize ); } } @@ -435,12 +532,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() @@ -457,18 +550,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++ ) @@ -476,10 +563,10 @@ void PageTurnView::GoToPage( unsigned int pageId ) AddPage( i ); } - mPageActors[pageId%NUMBER_OF_CACHED_PAGES].SetVisible(true); + mPages[pageId%NUMBER_OF_CACHED_PAGES].actor.SetProperty( Actor::Property::VISIBLE,true); if( pageId > 0 ) { - mPageActors[(pageId-1)%NUMBER_OF_CACHED_PAGES].SetVisible(true); + mPages[(pageId-1)%NUMBER_OF_CACHED_PAGES].actor.SetProperty( Actor::Property::VISIBLE,true); } // set ordered depth to the stacked pages OrganizePageDepth(); @@ -496,32 +583,26 @@ 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; + Texture newPage; + newPage = mPageFactory->NewPage( pageIndex ); + DALI_ASSERT_ALWAYS( newPage && "must pass in valid texture" ); bool isLeftSide = ( pageIndex < mCurrentPageIndex ); - mIsTurnBack[ newPage ] = isLeftSide; - if( isLeftSide ) + if( mPages[index].isTurnBack != isLeftSide ) { - // new page is added to the left side, so need to rotate it 180 degrees - newPage.RotateBy( Degree(-180.0f ), Vector3::YAXIS ); - } - else - { - newPage.SetShaderEffect(mSpineEffectFront); + mPages[index].ChangeTurnDirection(); } - newPage.SetVisible( false ); + float degree = isLeftSide ? 180.f :0.f; + mPages[index].actor.SetProperty( Actor::Property::ORIENTATION, Quaternion( Degree( degree ), Vector3::YAXIS ) ); + mPages[index].actor.SetProperty( Actor::Property::VISIBLE, false ); + mPages[index].UseEffect( mSpineEffectShader, mGeometry ); + mPages[index].SetTexture( newPage ); // For Portrait, nothing to do - // For Landscape, set spineEffectBack to the new effect if it is in the left side, and set properties to the back image actor if it exists - OnAddPage( newPage, isLeftSide ); + // For Landscape, set the parent origin to CENTER + OnAddPage( mPages[index].actor, isLeftSide ); } } @@ -530,68 +611,47 @@ 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.SetProperty( Actor::Property::VISIBLE,false); } } void PageTurnView::OnPan( const PanGesture& gesture ) { // the pan gesture is attached to control itself instead of each page - switch( gesture.state ) + switch( gesture.GetState() ) { - case Gesture::Started: + case GestureState::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 + const Vector2& position = gesture.GetPosition(); + SetPanActor( position ); // determine which page actor is panned + 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 + PanStarted( SetPanPosition( position ) ); // pass in the pan position in the local page coordinate } else { - mPanActor.Reset(); + mTurningPageIndex = -1; } break; } - case Gesture::Continuing: + case GestureState::CONTINUING: { - PanContinuing( SetPanPosition( gesture.position ) ); // pass in the pan position in the local page coordinate + PanContinuing( SetPanPosition( gesture.GetPosition() ) ); // pass in the pan position in the local page coordinate break; } - case Gesture::Finished: - case Gesture::Cancelled: + case GestureState::FINISHED: + case GestureState::CANCELLED: { - mPanning = false; - PanFinished( SetPanPosition( gesture.position ), gesture.GetSpeed() ); + PanFinished( SetPanPosition( gesture.GetPosition() ), gesture.GetSpeed() ); break; } - case Gesture::Clear: - case Gesture::Possible: + case GestureState::CLEAR: + case GestureState::POSSIBLE: default: { break; @@ -603,13 +663,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; @@ -620,7 +681,7 @@ void PageTurnView::PanStarted( const Vector2& gesturePosition ) void PageTurnView::PanContinuing( const Vector2& gesturePosition ) { - if( !mPanActor ) + if( mTurningPageIndex == -1 ) { return; } @@ -644,31 +705,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.SetProperty( Actor::Property::VISIBLE,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(); } } @@ -708,12 +769,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 @@ -732,41 +793,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 ); } } } @@ -776,25 +834,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 ); @@ -809,30 +867,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 @@ -841,60 +896,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.SetProperty( Actor::Property::ORIENTATION, Quaternion( 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.SetProperty( Actor::Property::VISIBLE,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.SetProperty( Actor::Property::VISIBLE,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() @@ -903,18 +955,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.SetProperty( Actor::Property::POSITION_Z, -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.SetProperty( Actor::Property::POSITION_Z, -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.SetProperty( Actor::Property::ORIENTATION, Quaternion( 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() @@ -979,7 +1051,7 @@ void PageTurnView::SetProperty( BaseObject* object, Property::Index index, const switch( index ) { - case Toolkit::PageTurnView::Property::PAGE_SIZE: + case Toolkit::PageTurnView::Property::VIEW_PAGE_SIZE: { pageTurnViewImpl.SetPageSize( value.Get() ); break; @@ -1010,7 +1082,7 @@ Property::Value PageTurnView::GetProperty( BaseObject* object, Property::Index i switch( index ) { - case Toolkit::PageTurnView::Property::PAGE_SIZE: + case Toolkit::PageTurnView::Property::VIEW_PAGE_SIZE: { value = pageTurnViewImpl.GetPageSize(); break;