2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "cube-transition-effect-impl.h"
22 #include <cstring> // for strcmp
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/object/type-registry-helper.h>
25 #include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
26 #include <dali/integration-api/debug.h>
40 // Setup properties, signals and actions using the type-registry.
41 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::CubeTransitionEffect, Dali::BaseHandle, NULL );
43 DALI_SIGNAL_REGISTRATION( Toolkit, CubeTransitionEffect, "transitionCompleted", SIGNAL_TRANSITION_COMPLETED )
45 DALI_TYPE_REGISTRATION_END()
47 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
48 attribute mediump vec2 aPosition;\n
49 varying mediump vec2 vTexCoord;\n
50 uniform mediump mat4 uMvpMatrix;\n
51 uniform mediump vec3 uSize;\n
52 uniform mediump vec4 uTextureRect;\n
56 mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
57 vertexPosition.xyz *= uSize;\n
58 vertexPosition = uMvpMatrix * vertexPosition;\n
60 vTexCoord = aPosition + vec2(0.5);\n
61 vTexCoord = mix(uTextureRect.xy, uTextureRect.zw, vTexCoord);\n
63 gl_Position = vertexPosition;\n
67 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
68 varying mediump vec2 vTexCoord;\n
69 uniform sampler2D sTexture;\n
70 uniform lowp vec4 uColor;\n
71 uniform lowp vec4 uSamplerRect;
75 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
79 Actor CreateTile( const Vector4& samplerRect )
81 Actor tile = Actor::New();
82 tile.SetAnchorPoint( AnchorPoint::CENTER );
83 tile.RegisterProperty( "uTextureRect", samplerRect );
89 const Vector4 CubeTransitionEffect::FULL_BRIGHTNESS( 1.0f, 1.0f, 1.0f, 1.0f );
90 const Vector4 CubeTransitionEffect::HALF_BRIGHTNESS( 0.5f, 0.5f, 0.5f, 1.0f );
92 CubeTransitionEffect::CubeTransitionEffect( unsigned int rows, unsigned int columns )
93 : Control( ControlBehaviour( 0 ) ),
96 mIsAnimating( false ),
98 mAnimationDuration( 1.f ),
99 mCubeDisplacement( 0.f )
103 CubeTransitionEffect::~CubeTransitionEffect()
107 void CubeTransitionEffect::SetTargetRight( unsigned int idx )
109 mBoxType[ idx ] = RIGHT;
111 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f );
113 mTargetTiles[ idx ].SetParentOrigin( Vector3( 1.f, 0.5f, 0.5f) );
114 mTargetTiles[ idx ].SetOrientation( Degree( 90.f ), Vector3::YAXIS );
117 void CubeTransitionEffect::SetTargetLeft( unsigned int idx )
119 mBoxType[ idx ] = LEFT;
121 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f );
123 mTargetTiles[ idx ].SetParentOrigin( Vector3( 0.f, 0.5f, 0.5f) );
124 mTargetTiles[ idx ].SetOrientation( Degree( -90.f ), Vector3::YAXIS );
127 void CubeTransitionEffect::SetTargetBottom( unsigned int idx )
129 mBoxType[ idx ] = BOTTOM;
131 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f );
133 mTargetTiles[ idx ].SetParentOrigin( Vector3( 0.5f, 0.f, 0.5f) );
134 mTargetTiles[ idx ].SetOrientation( Degree( 90.f ), Vector3::XAXIS );
137 void CubeTransitionEffect::SetTargetTop( unsigned int idx )
139 mBoxType[ idx ] = TOP;
141 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f );
143 mTargetTiles[ idx ].SetParentOrigin( Vector3( 0.5f, 1.f, 0.5f) );
144 mTargetTiles[ idx ].SetOrientation( Degree( -90.f ), Vector3::XAXIS );
147 void CubeTransitionEffect::OnRelayout( const Vector2& size, RelayoutContainer& container )
149 mTileSize = Vector2( size.x / mColumns, size.y / mRows );
151 mBoxRoot.SetProperty( Actor::Property::SIZE_WIDTH, size.x );
152 mBoxRoot.SetProperty( Actor::Property::SIZE_HEIGHT, size.y );
153 mBoxRoot.SetProperty( Actor::Property::SIZE_DEPTH, 1.0f );
155 for( size_t i = 0; i < mBoxes.size(); ++i )
157 mBoxes[ i ].SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x );
158 mBoxes[ i ].SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y );
160 switch( mBoxType[i] )
165 mBoxes[ i ].SetProperty( Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f );
166 mBoxes[ i ].SetProperty( Actor::Property::SIZE_DEPTH, mTileSize.x );
172 mBoxes[ i ].SetProperty( Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f );
173 mBoxes[ i ].SetProperty( Actor::Property::SIZE_DEPTH, mTileSize.y );
179 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
181 it->SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x );
182 it->SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y );
184 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
186 it->SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x );
187 it->SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y );
191 void CubeTransitionEffect::Initialize()
193 Self().RegisterProperty( "uTextureRect", Vector4( 0.0f, 0.0f, 1.0f, 1.0f ) );
195 mBoxType.Resize(mColumns * mRows);
197 //create the box parents
198 mBoxRoot = Actor::New();
199 mBoxRoot.SetParentOrigin( ParentOrigin::CENTER );
200 mBoxRoot.SetAnchorPoint( AnchorPoint::CENTER );
202 mCurrentTiles.clear();
203 mTargetTiles.clear();
205 mCurrentTiles.reserve( mColumns * mRows );
206 mTargetTiles.reserve( mColumns * mRows );
208 Vector2 gridSizeInv( 1.0f / mColumns, 1.0f / mRows );
209 Vector3 offset( 0.5f * gridSizeInv.x, 0.5f * gridSizeInv.y, 0.0f );
212 for( unsigned int y = 0; y < mRows; ++y, anchor.y += 1.0f / mRows )
215 for( unsigned int x = 0; x <mColumns; ++x, anchor.x += 1.0f / mColumns )
217 Vector4 textureRect( anchor.x, anchor.y, anchor.x + gridSizeInv.x, anchor.y + gridSizeInv.y );
219 Actor currentTile = CreateTile( textureRect );
220 currentTile.SetProperty( Actor::Property::COLOR, FULL_BRIGHTNESS );
221 currentTile.SetParentOrigin( ParentOrigin::CENTER );
222 mCurrentTiles.push_back( currentTile );
224 Actor targetTile = CreateTile( textureRect );
225 targetTile.SetProperty( Actor::Property::COLOR, HALF_BRIGHTNESS );
226 mTargetTiles.push_back( targetTile );
228 Actor box = Actor::New();
229 box.SetParentOrigin( anchor + offset );
230 box.SetAnchorPoint( AnchorPoint::CENTER );
232 box.Add( currentTile );
233 box.Add( targetTile );
237 mBoxes.push_back( box );
244 void CubeTransitionEffect::OnStageConnection( int depth )
246 Control::OnStageConnection( depth );
248 Geometry geometry = Geometry::QUAD();
249 Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
251 TextureSet textureSet = TextureSet::New();
253 if( mCurrentTexture )
255 textureSet.SetTexture( 0u, mCurrentTexture );
257 mCurrentRenderer = Renderer::New( geometry, shader );
258 mCurrentRenderer.SetTextures( textureSet );
260 mCurrentRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depth );
261 Self().AddRenderer( mCurrentRenderer );
264 void CubeTransitionEffect::OnStageDisconnection()
266 if( mCurrentRenderer )
268 Self().RemoveRenderer( mCurrentRenderer );
270 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
272 it->RemoveRenderer( mCurrentRenderer );
274 mCurrentRenderer.Reset();
277 if( mTargetRenderer )
279 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
281 it->RemoveRenderer( mTargetRenderer );
283 mTargetRenderer.Reset();
286 Control::OnStageDisconnection();
289 void CubeTransitionEffect::SetTransitionDuration( float duration )
291 mAnimationDuration = duration;
294 float CubeTransitionEffect::GetTransitionDuration( ) const
296 return mAnimationDuration;
299 void CubeTransitionEffect::SetCubeDisplacement( float displacement )
301 mCubeDisplacement = displacement;
304 float CubeTransitionEffect::GetCubeDisplacement() const
306 return mCubeDisplacement;
309 bool CubeTransitionEffect::IsTransitioning()
314 void CubeTransitionEffect::SetCurrentTexture( Texture texture )
316 mCurrentTexture = texture;
318 if( mCurrentRenderer )
320 TextureSet textureSet = mCurrentRenderer.GetTextures();
321 textureSet.SetTexture( 0u, mCurrentTexture);
325 void CubeTransitionEffect::SetTargetTexture( Texture texture )
327 mTargetTexture = texture;
329 if( mTargetRenderer )
331 TextureSet textureSet = mTargetRenderer.GetTextures();
332 textureSet.SetTexture( 0u, mTargetTexture );
336 void CubeTransitionEffect::StartTransition( bool toNextImage )
338 Vector3 size = Self().GetCurrentSize();
341 StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( -10.f, 0.f ) );
345 StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( 10.f, 0.f ));
349 void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement )
351 if( !mCurrentRenderer )
353 DALI_LOG_ERROR( "Trying to transition a cube transition without an image set" );
357 //create the target renderer
358 TextureSet textureSet = TextureSet::New();
361 textureSet.SetTexture( 0u, mTargetTexture );
363 Geometry geometry = mCurrentRenderer.GetGeometry();
364 Shader shader( mCurrentRenderer.GetShader() );
365 mTargetRenderer = Renderer::New( geometry, shader );
366 mTargetRenderer.SetTextures( textureSet );
368 int depthIndex = mCurrentRenderer.GetProperty<int>(Renderer::Property::DEPTH_INDEX);
369 mTargetRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex );
371 for( size_t i = 0; i < mBoxes.size(); ++i )
373 mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
376 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
378 it->SetParentOrigin( Vector3( 0.5f, 0.5f, 1.0f) );
379 it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
380 it->AddRenderer( mCurrentRenderer );
382 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
384 it->AddRenderer( mTargetRenderer );
387 Self().RemoveRenderer( mCurrentRenderer );
388 Self().Add( mBoxRoot );
396 mAnimation = Animation::New( mAnimationDuration );
397 mAnimation.FinishedSignal().Connect( this, &CubeTransitionEffect::OnTransitionFinished );
399 OnStartTransition( panPosition, panDisplacement );
402 void CubeTransitionEffect::PauseTransition()
404 if( mIsAnimating && !mIsPaused )
411 void CubeTransitionEffect::ResumeTransition()
413 if( mIsAnimating && mIsPaused)
420 void CubeTransitionEffect::StopTransition()
422 ResetToInitialState();
425 void CubeTransitionEffect::ResetToInitialState()
429 mIsAnimating = false;
431 Self().Remove( mBoxRoot );
433 for( size_t i = 0; i < mBoxes.size(); ++i )
435 mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
438 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
440 it->SetParentOrigin( Vector3( 0.5f, 0.5f, 1.0f) );
441 it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
442 it->SetProperty( Actor::Property::COLOR, FULL_BRIGHTNESS );
444 if( mCurrentRenderer )
446 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
448 it->RemoveRenderer( mCurrentRenderer );
450 Self().AddRenderer( mCurrentRenderer );
453 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
455 it->SetProperty( Actor::Property::COLOR, HALF_BRIGHTNESS );
457 if( mTargetRenderer )
459 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
461 it->RemoveRenderer( mTargetRenderer );
466 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
469 std::swap( mCurrentTiles, mTargetTiles );
470 std::swap( mCurrentRenderer, mTargetRenderer );
471 std::swap( mCurrentTexture, mTargetTexture );
473 ResetToInitialState();
476 Toolkit::CubeTransitionEffect handle( GetOwner() );
477 mTransitionCompletedSignal.Emit( handle, mCurrentTexture );
480 Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()
482 return mTransitionCompletedSignal;
485 bool CubeTransitionEffect::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
487 Dali::BaseHandle handle( object );
489 bool connected( true );
490 Toolkit::CubeTransitionEffect cubeTransitionEffect = Toolkit::CubeTransitionEffect::DownCast( handle );
492 if( 0 == strcmp( signalName.c_str(), SIGNAL_TRANSITION_COMPLETED ) )
494 cubeTransitionEffect.TransitionCompletedSignal().Connect( tracker, functor );
498 // signalName does not match any signal
505 } // namespace Internal
507 } // namespace Toolkit