2 * Copyright (c) 2017 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/integration-api/debug.h>
28 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
29 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
30 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
44 // Setup properties, signals and actions using the type-registry.
45 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::CubeTransitionEffect, Dali::BaseHandle, NULL );
47 DALI_SIGNAL_REGISTRATION( Toolkit, CubeTransitionEffect, "transitionCompleted", SIGNAL_TRANSITION_COMPLETED )
49 DALI_TYPE_REGISTRATION_END()
51 Actor CreateTile( const Vector4& samplerRect )
53 Actor tile = Actor::New();
54 tile.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
55 tile.RegisterProperty( "uTextureRect", samplerRect );
61 const Vector4 CubeTransitionEffect::FULL_BRIGHTNESS( 1.0f, 1.0f, 1.0f, 1.0f );
62 const Vector4 CubeTransitionEffect::HALF_BRIGHTNESS( 0.5f, 0.5f, 0.5f, 1.0f );
64 CubeTransitionEffect::CubeTransitionEffect( unsigned int rows, unsigned int columns )
65 : Control( ControlBehaviour( DISABLE_STYLE_CHANGE_SIGNALS ) ),
68 mIsAnimating( false ),
70 mAnimationDuration( 1.f ),
71 mCubeDisplacement( 0.f )
75 CubeTransitionEffect::~CubeTransitionEffect()
79 void CubeTransitionEffect::SetTargetRight( unsigned int idx )
81 mBoxType[ idx ] = RIGHT;
83 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f );
85 mTargetTiles[ idx ].SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 1.f, 0.5f, 0.5f) );
86 mTargetTiles[ idx ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Degree( 90.f ), Vector3::YAXIS ) );
89 void CubeTransitionEffect::SetTargetLeft( unsigned int idx )
91 mBoxType[ idx ] = LEFT;
93 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f );
95 mTargetTiles[ idx ].SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.f, 0.5f, 0.5f) );
96 mTargetTiles[ idx ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Degree( -90.f ), Vector3::YAXIS ) );
99 void CubeTransitionEffect::SetTargetBottom( unsigned int idx )
101 mBoxType[ idx ] = BOTTOM;
103 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f );
105 mTargetTiles[ idx ].SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, 0.f, 0.5f) );
106 mTargetTiles[ idx ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Degree( 90.f ), Vector3::XAXIS ) );
109 void CubeTransitionEffect::SetTargetTop( unsigned int idx )
111 mBoxType[ idx ] = TOP;
113 mBoxes[ idx ].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f );
115 mTargetTiles[ idx ].SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, 1.f, 0.5f) );
116 mTargetTiles[ idx ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Degree( -90.f ), Vector3::XAXIS ) );
119 void CubeTransitionEffect::OnRelayout( const Vector2& size, RelayoutContainer& container )
121 mTileSize = Vector2( size.x / mColumns, size.y / mRows );
123 mBoxRoot.SetProperty( Actor::Property::SIZE_WIDTH, size.x );
124 mBoxRoot.SetProperty( Actor::Property::SIZE_HEIGHT, size.y );
125 mBoxRoot.SetProperty( Actor::Property::SIZE_DEPTH, 1.0f );
127 for( size_t i = 0; i < mBoxes.size(); ++i )
129 mBoxes[ i ].SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x );
130 mBoxes[ i ].SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y );
132 switch( mBoxType[i] )
137 mBoxes[ i ].SetProperty( Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f );
138 mBoxes[ i ].SetProperty( Actor::Property::SIZE_DEPTH, mTileSize.x );
144 mBoxes[ i ].SetProperty( Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f );
145 mBoxes[ i ].SetProperty( Actor::Property::SIZE_DEPTH, mTileSize.y );
151 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
153 it->SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x );
154 it->SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y );
156 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
158 it->SetProperty( Actor::Property::SIZE_WIDTH, mTileSize.x );
159 it->SetProperty( Actor::Property::SIZE_HEIGHT, mTileSize.y );
163 void CubeTransitionEffect::Initialize()
165 Self().RegisterProperty( "uTextureRect", Vector4( 0.0f, 0.0f, 1.0f, 1.0f ) );
167 mBoxType.Resize(mColumns * mRows);
169 //create the box parents
170 mBoxRoot = Actor::New();
171 mBoxRoot.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
172 mBoxRoot.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
174 mCurrentTiles.clear();
175 mTargetTiles.clear();
177 mCurrentTiles.reserve( mColumns * mRows );
178 mTargetTiles.reserve( mColumns * mRows );
180 Vector2 gridSizeInv( 1.0f / mColumns, 1.0f / mRows );
181 Vector3 offset( 0.5f * gridSizeInv.x, 0.5f * gridSizeInv.y, 0.0f );
184 for( unsigned int y = 0; y < mRows; ++y, anchor.y += 1.0f / mRows )
187 for( unsigned int x = 0; x <mColumns; ++x, anchor.x += 1.0f / mColumns )
189 Vector4 textureRect( anchor.x, anchor.y, anchor.x + gridSizeInv.x, anchor.y + gridSizeInv.y );
191 Actor currentTile = CreateTile( textureRect );
192 currentTile.SetProperty( Actor::Property::COLOR, FULL_BRIGHTNESS );
193 currentTile.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
194 mCurrentTiles.push_back( currentTile );
196 Actor targetTile = CreateTile( textureRect );
197 targetTile.SetProperty( Actor::Property::COLOR, HALF_BRIGHTNESS );
198 mTargetTiles.push_back( targetTile );
200 Actor box = Actor::New();
201 box.SetProperty( Actor::Property::PARENT_ORIGIN, anchor + offset );
202 box.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
204 box.Add( currentTile );
205 box.Add( targetTile );
209 mBoxes.push_back( box );
216 void CubeTransitionEffect::OnSceneConnection( int depth )
218 Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
219 Shader shader = Shader::New( SHADER_CUBE_TRANSITION_EFFECT_VERT, SHADER_CUBE_TRANSITION_EFFECT_FRAG );
221 TextureSet textureSet = TextureSet::New();
223 if( mCurrentTexture )
225 textureSet.SetTexture( 0u, mCurrentTexture );
227 mCurrentRenderer = Renderer::New( geometry, shader );
228 mCurrentRenderer.SetTextures( textureSet );
230 mCurrentRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depth );
231 Self().AddRenderer( mCurrentRenderer );
233 Control::OnSceneConnection( depth );
236 void CubeTransitionEffect::OnSceneDisconnection()
238 if( mCurrentRenderer )
240 Self().RemoveRenderer( mCurrentRenderer );
242 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
244 it->RemoveRenderer( mCurrentRenderer );
246 mCurrentRenderer.Reset();
249 if( mTargetRenderer )
251 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
253 it->RemoveRenderer( mTargetRenderer );
255 mTargetRenderer.Reset();
258 Control::OnSceneDisconnection();
261 void CubeTransitionEffect::SetTransitionDuration( float duration )
263 mAnimationDuration = duration;
266 float CubeTransitionEffect::GetTransitionDuration( ) const
268 return mAnimationDuration;
271 void CubeTransitionEffect::SetCubeDisplacement( float displacement )
273 mCubeDisplacement = displacement;
276 float CubeTransitionEffect::GetCubeDisplacement() const
278 return mCubeDisplacement;
281 bool CubeTransitionEffect::IsTransitioning()
286 void CubeTransitionEffect::SetCurrentTexture( Texture texture )
288 mCurrentTexture = texture;
290 if( mCurrentRenderer )
292 TextureSet textureSet = mCurrentRenderer.GetTextures();
293 textureSet.SetTexture( 0u, mCurrentTexture);
297 void CubeTransitionEffect::SetTargetTexture( Texture texture )
299 mTargetTexture = texture;
301 if( mTargetRenderer )
303 TextureSet textureSet = mTargetRenderer.GetTextures();
304 textureSet.SetTexture( 0u, mTargetTexture );
308 void CubeTransitionEffect::StartTransition( bool toNextImage )
310 Vector3 size = Self().GetCurrentProperty< Vector3 >( Actor::Property::SIZE );
313 StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( -10.f, 0.f ) );
317 StartTransition( Vector2(size.x* 0.5f, size.y*0.5f), Vector2( 10.f, 0.f ));
321 void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement )
323 if( !mCurrentRenderer )
325 DALI_LOG_ERROR( "Trying to transition a cube transition without an image set\n" );
329 //create the target renderer
330 TextureSet textureSet = TextureSet::New();
333 textureSet.SetTexture( 0u, mTargetTexture );
335 Geometry geometry = mCurrentRenderer.GetGeometry();
336 Shader shader( mCurrentRenderer.GetShader() );
337 mTargetRenderer = Renderer::New( geometry, shader );
338 mTargetRenderer.SetTextures( textureSet );
340 int depthIndex = mCurrentRenderer.GetProperty<int>(Renderer::Property::DEPTH_INDEX);
341 mTargetRenderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex );
343 for( size_t i = 0; i < mBoxes.size(); ++i )
345 mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
348 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
350 it->SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, 0.5f, 1.0f) );
351 it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
352 it->AddRenderer( mCurrentRenderer );
354 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
356 it->AddRenderer( mTargetRenderer );
359 Self().RemoveRenderer( mCurrentRenderer );
360 Self().Add( mBoxRoot );
368 mAnimation = Animation::New( mAnimationDuration );
369 mAnimation.FinishedSignal().Connect( this, &CubeTransitionEffect::OnTransitionFinished );
371 OnStartTransition( panPosition, panDisplacement );
374 void CubeTransitionEffect::PauseTransition()
376 if( mIsAnimating && !mIsPaused )
383 void CubeTransitionEffect::ResumeTransition()
385 if( mIsAnimating && mIsPaused)
392 void CubeTransitionEffect::StopTransition()
394 ResetToInitialState();
397 void CubeTransitionEffect::ResetToInitialState()
401 mIsAnimating = false;
403 Self().Remove( mBoxRoot );
405 for( size_t i = 0; i < mBoxes.size(); ++i )
407 mBoxes[ i ].SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
410 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
412 it->SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( 0.5f, 0.5f, 1.0f) );
413 it->SetProperty( Actor::Property::ORIENTATION, Quaternion( Radian( 0.0f ), Vector3::XAXIS ) );
414 it->SetProperty( Actor::Property::COLOR, FULL_BRIGHTNESS );
416 if( mCurrentRenderer )
418 for( ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it )
420 it->RemoveRenderer( mCurrentRenderer );
422 Self().AddRenderer( mCurrentRenderer );
425 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
427 it->SetProperty( Actor::Property::COLOR, HALF_BRIGHTNESS );
429 if( mTargetRenderer )
431 for( ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it )
433 it->RemoveRenderer( mTargetRenderer );
438 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
441 std::swap( mCurrentTiles, mTargetTiles );
442 std::swap( mCurrentRenderer, mTargetRenderer );
443 std::swap( mCurrentTexture, mTargetTexture );
445 ResetToInitialState();
448 Toolkit::CubeTransitionEffect handle( GetOwner() );
449 mTransitionCompletedSignal.Emit( handle, mCurrentTexture );
452 Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()
454 return mTransitionCompletedSignal;
457 bool CubeTransitionEffect::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
459 Dali::BaseHandle handle( object );
461 bool connected( true );
462 Toolkit::CubeTransitionEffect cubeTransitionEffect = Toolkit::CubeTransitionEffect::DownCast( handle );
464 if( 0 == strcmp( signalName.c_str(), SIGNAL_TRANSITION_COMPLETED ) )
466 cubeTransitionEffect.TransitionCompletedSignal().Connect( tracker, functor );
470 // signalName does not match any signal
477 } // namespace Internal
479 } // namespace Toolkit