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();
255 textureSet.SetImage( 0u, mCurrentImage );
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::SetCurrentImage( Image image )
316 mCurrentImage = image;
317 if( mCurrentRenderer )
319 TextureSet textureSet = mCurrentRenderer.GetTextures();
320 textureSet.SetImage( 0u, mCurrentImage );
324 void CubeTransitionEffect::SetTargetImage( Image image )
326 mTargetImage = image;
328 if( mTargetRenderer )
330 TextureSet textureSet = mTargetRenderer.GetTextures();
331 textureSet.SetImage( 0u, mTargetImage );
335 void CubeTransitionEffect::StartTransition( bool toNextImage )
337 Vector3 size = Self().GetCurrentSize();
340 StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( -10.f, 0.f ) );
344 StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( 10.f, 0.f ));
348 void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement )
350 if( !mCurrentRenderer )
352 DALI_LOG_ERROR( "Trying to transition a cube transition without an image set" );
356 //create the target renderer
357 TextureSet textureSet = TextureSet::New();
360 textureSet.SetImage( 0u, mTargetImage );
362 Geometry geometry = mCurrentRenderer.GetGeometry();
363 Shader shader( mCurrentRenderer.GetShader() );
364 mTargetRenderer = Renderer::New( geometry, shader );
365 mTargetRenderer.SetTextures( textureSet );
367 int depthIndex = mCurrentRenderer.GetProperty<int>(Renderer::Property::DEPTH_INDEX);
368 mTargetRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex );
370 for( size_t i = 0; i < mBoxes.size(); ++i )
372 mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
375 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
377 it->SetParentOrigin( Vector3( 0.5f, 0.5f, 1.0f) );
378 it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
379 it->AddRenderer( mCurrentRenderer );
381 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
383 it->AddRenderer( mTargetRenderer );
386 Self().RemoveRenderer( mCurrentRenderer );
387 Self().Add( mBoxRoot );
395 mAnimation = Animation::New( mAnimationDuration );
396 mAnimation.FinishedSignal().Connect( this, &CubeTransitionEffect::OnTransitionFinished );
398 OnStartTransition( panPosition, panDisplacement );
401 void CubeTransitionEffect::PauseTransition()
403 if( mIsAnimating && !mIsPaused )
410 void CubeTransitionEffect::ResumeTransition()
412 if( mIsAnimating && mIsPaused)
419 void CubeTransitionEffect::StopTransition()
421 ResetToInitialState();
424 void CubeTransitionEffect::ResetToInitialState()
428 mIsAnimating = false;
430 Self().Remove( mBoxRoot );
432 for( size_t i = 0; i < mBoxes.size(); ++i )
434 mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
437 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
439 it->SetParentOrigin( Vector3( 0.5f, 0.5f, 1.0f) );
440 it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
441 it->SetProperty( Actor::Property::COLOR, FULL_BRIGHTNESS );
443 if( mCurrentRenderer )
445 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
447 it->RemoveRenderer( mCurrentRenderer );
449 Self().AddRenderer( mCurrentRenderer );
452 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
454 it->SetProperty( Actor::Property::COLOR, HALF_BRIGHTNESS );
456 if( mTargetRenderer )
458 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
460 it->RemoveRenderer( mTargetRenderer );
465 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
468 std::swap( mCurrentTiles, mTargetTiles );
469 std::swap( mCurrentRenderer, mTargetRenderer );
470 std::swap( mCurrentImage, mTargetImage );
472 ResetToInitialState();
475 Toolkit::CubeTransitionEffect handle( GetOwner() );
476 mTransitionCompletedSignal.Emit( handle, mCurrentImage );
479 Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()
481 return mTransitionCompletedSignal;
484 bool CubeTransitionEffect::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
486 Dali::BaseHandle handle( object );
488 bool connected( true );
489 Toolkit::CubeTransitionEffect cubeTransitionEffect = Toolkit::CubeTransitionEffect::DownCast( handle );
491 if( 0 == strcmp( signalName.c_str(), SIGNAL_TRANSITION_COMPLETED ) )
493 cubeTransitionEffect.TransitionCompletedSignal().Connect( tracker, functor );
497 // signalName does not match any signal
504 } // namespace Internal
506 } // namespace Toolkit