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 <dali/public-api/common/stage.h>
23 #include <dali/public-api/images/buffer-image.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/object/type-registry-helper.h>
26 #include <dali/public-api/render-tasks/render-task-list.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( CubeTransitionEffect, "transition-completed", SIGNAL_TRANSITION_COMPLETED )
45 DALI_TYPE_REGISTRATION_END()
49 const Vector4 CubeTransitionEffect::FULL_BRIGHTNESS( 1.0f, 1.0f, 1.0f, 1.0f );
50 const Vector4 CubeTransitionEffect::HALF_BRIGHTNESS( 0.5f, 0.5f, 0.5f, 1.0f );
52 CubeTransitionEffect::CubeTransitionEffect( unsigned int numRows, unsigned int numColumns, Size viewAreaSize )
53 : mNumRows( numRows ),
54 mNumColumns( numColumns ),
55 mViewAreaSize( viewAreaSize ),
58 mChangeTurningDirection( false ),
59 mIsToNextImage( true ),
60 mIsImageLoading( false ),
61 mAnimationDuration( 1.f ),
62 mIsAnimating( false ),
64 mCubeDisplacement( 0.f ),
65 mFirstTransition( true ),
70 CubeTransitionEffect::~CubeTransitionEffect()
74 void CubeTransitionEffect::Initialize()
76 //create root actor for the cube transition effect, only visible during the transition
78 mRoot.SetParentOrigin( ParentOrigin::CENTER );
79 mRoot.SetAnchorPoint( AnchorPoint::CENTER );
80 mRoot.SetVisible(false);
82 // create two groups of tiles,
83 // and one group of actors (cubes) serving as parents of every two tiles (one from each image).
84 unsigned int totalNum = mNumColumns* mNumRows;
85 mBoxes.resize( totalNum );
86 mTiles[0].resize( totalNum );
87 mTiles[1].resize( totalNum );
88 mTileSize = Vector2( mViewAreaSize.width / mNumColumns, mViewAreaSize.height / mNumRows );
89 const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f,
90 (-mViewAreaSize.height + mTileSize.height) * 0.5f,
91 -mTileSize.width * 0.5f );
93 Image placeHolder = BufferImage::WHITE();
94 for( unsigned int y = 0; y < mNumRows; y++ )
96 float positionY = y * mTileSize.height + basePosition.y;
97 for( unsigned int x = 0; x < mNumColumns; x++)
99 unsigned int idx = y*mNumColumns + x;
100 Actor actor( Actor::New() );
102 actor.SetParentOrigin( ParentOrigin::CENTER );
103 actor.SetAnchorPoint( AnchorPoint::CENTER );
104 actor.SetPosition( x * mTileSize.width + basePosition.x,
109 mTiles[ 0 ][idx] = CreateTile( placeHolder, FULL_BRIGHTNESS );
110 actor.Add( mTiles[ 0 ][idx] );
112 mTiles[ 1 ][idx] = CreateTile( placeHolder, HALF_BRIGHTNESS );
113 actor.Add( mTiles[ 1 ][idx] );
117 // helper actor to create a off-screen image using shader effect
118 mEmptyImage = ImageActor::New( placeHolder );
119 mEmptyImage.SetSize(Stage::GetCurrent().GetSize());
120 mEmptyImage.SetParentOrigin( ParentOrigin::CENTER );
121 mEmptyImage.SetAnchorPoint( AnchorPoint::CENTER );
122 mFullImageCreator = FullAreaImageCreator::New();
123 mEmptyImage.SetShaderEffect( mFullImageCreator );
124 Stage::GetCurrent().Add(mEmptyImage);
126 // set up off-screen render task
127 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
128 mOffScreenTask = taskList.CreateTask();
129 mOffScreenTask.SetSourceActor(mEmptyImage);
130 mOffScreenTask.SetExclusive(true);
131 mOffScreenBuffer[0] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y);
132 mOffScreenBuffer[1] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y);
133 mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]);
134 mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
139 ImageActor CubeTransitionEffect::CreateTile( Image image, const Vector4& color )
141 ImageActor tile = ImageActor::New( image );
142 tile.SetParentOrigin( ParentOrigin::CENTER );
143 tile.SetAnchorPoint( AnchorPoint::CENTER );
144 tile.SetSize( mTileSize );
145 tile.SetColorMode( Dali::USE_OWN_COLOR );
146 tile.SetColor( color );
151 void CubeTransitionEffect::SetTransitionDuration( float duration )
153 mAnimationDuration = duration;
156 float CubeTransitionEffect::GetTransitionDuration( ) const
158 return mAnimationDuration;
161 void CubeTransitionEffect::SetCubeDisplacement( float displacement )
163 mCubeDisplacement = displacement;
166 float CubeTransitionEffect::GetCubeDisplacement() const
168 return mCubeDisplacement;
171 Actor CubeTransitionEffect::GetRoot()
176 bool CubeTransitionEffect::IsTransiting()
178 return mIsImageLoading || mIsAnimating;
181 void CubeTransitionEffect::SetCurrentImage( ImageActor imageActor )
183 mContainerIndex = std::abs(mRotateIndex) % 2;
184 SetImage( imageActor );
187 void CubeTransitionEffect::SetTargetImage( ImageActor imageActor )
189 mContainerIndex = std::abs( mRotateIndex+1 ) % 2;
190 SetImage( imageActor );
193 void CubeTransitionEffect::SetImage( ImageActor imageActor )
195 mCurrentImage = imageActor;
197 Image image = imageActor.GetImage();
198 ResourceImage resourceImage = ResourceImage::DownCast( image );
199 mBufferIndex = mBufferIndex^1;
201 //must make sure the image is already loaded before using its attributes
202 if( resourceImage && resourceImage.GetLoadingState() != ResourceLoadingSucceeded )
204 mIsImageLoading = true;
205 resourceImage.LoadingFinishedSignal().Connect( this, &CubeTransitionEffect::OnImageLoaded );
209 mIsImageLoading = false;
210 PrepareTiles( image );
214 void CubeTransitionEffect::StartTransition( bool toNextImage )
218 StartTransition( Vector2( mViewAreaSize.width, mViewAreaSize.height*0.5f ), Vector2( -10.f, 0.f ) );
222 StartTransition( Vector2( 0, mViewAreaSize.height*0.5f ), Vector2( 10.f, 0.f ));
226 void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement )
228 mRoot.SetVisible( true );
229 mCurrentImage.SetVisible( false );
230 bool toNextImage = ( panDisplacement.x < 0 ) ? true : false;
231 if( mIsToNextImage != toNextImage )
233 mChangeTurningDirection = true;
237 mChangeTurningDirection = false;
239 mIsToNextImage = toNextImage;
255 mAnimation = Animation::New( mAnimationDuration );
256 mAnimation.FinishedSignal().Connect(this, &CubeTransitionEffect::OnTransitionFinished);
258 OnStartTransition( panPosition, panDisplacement );
261 void CubeTransitionEffect::PauseTransition()
263 if( mIsAnimating && !mIsPaused )
270 void CubeTransitionEffect::ResumeTransition()
272 if( mIsAnimating && mIsPaused)
279 void CubeTransitionEffect::StopTransition()
287 //reset the position of the cubes
288 //reset the color of the tiles
289 //all these status should be the same as the final state when the transition animation is finished completely
290 const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f,
291 (-mViewAreaSize.height + mTileSize.height) * 0.5f,
292 -mTileSize.width * 0.5f );
293 unsigned int anotherIndex = mContainerIndex^1;
294 for( unsigned int y = 0; y < mNumRows; y++ )
296 float positionY = y * mTileSize.height + basePosition.y;
297 for( unsigned int x = 0; x < mNumColumns; x++)
299 unsigned int idx = y*mNumColumns + x;
300 mBoxes[idx].SetPosition( x * mTileSize.width + basePosition.x,
303 mTiles[mContainerIndex][idx].SetColor( FULL_BRIGHTNESS );
304 mTiles[anotherIndex][idx].SetColor( HALF_BRIGHTNESS);
308 // reset the rotation of the cubes, which is different process for different derived classes
311 mRoot.SetVisible(false);
312 mCurrentImage.SetVisible(true);
313 mIsAnimating = false;
314 mFirstTransition = false;
318 void CubeTransitionEffect::OnImageLoaded(ResourceImage image)
320 mIsImageLoading = false;
321 PrepareTiles( image );
325 * Set sub-image to each tile.
326 * @param[in] image The image content of the imageActor for transition
328 void CubeTransitionEffect::PrepareTiles( Image image )
330 // Fit the image to view area, while keeping the aspect; FitKeepAspectRatio(imageSize, viewAreaSize)
331 float scale = std::min( mViewAreaSize.width / image.GetWidth(), mViewAreaSize.height / image.GetHeight() );
332 Vector2 imageSize(image.GetWidth()*scale, image.GetHeight()*scale);
334 mFullImageCreator.SetEffectImage(image);
335 mFullImageCreator.SetRegionSize(mViewAreaSize, imageSize);
337 mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]);
338 mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
340 ImageActor::PixelArea pixelArea( 0, 0, mViewAreaSize.x / mNumColumns, mViewAreaSize.y / mNumRows);
342 for( unsigned int y = 0; y < mNumRows; y++ )
344 pixelArea.y = y * pixelArea.height;
345 for( unsigned int x = 0; x < mNumColumns; x++)
347 pixelArea.x = x * pixelArea.width;
348 unsigned int idx = y*mNumColumns + x;
349 mTiles[mContainerIndex][idx].SetImage( mOffScreenBuffer[mBufferIndex]);
350 mTiles[mContainerIndex][idx].SetPixelArea( pixelArea );
356 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
358 mRoot.SetVisible(false);
359 mCurrentImage.SetVisible(true);
360 mIsAnimating = false;
361 mFirstTransition = false;
364 Toolkit::CubeTransitionEffect handle( this );
365 mTransitionCompletedSignal.Emit( handle, mCurrentImage );
368 Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()
370 return mTransitionCompletedSignal;
373 bool CubeTransitionEffect::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
375 Dali::BaseHandle handle( object );
377 bool connected( true );
378 Toolkit::CubeTransitionEffect cubeTransitionEffect = Toolkit::CubeTransitionEffect::DownCast( handle );
380 if( 0 == strcmp( signalName.c_str(), SIGNAL_TRANSITION_COMPLETED ) )
382 cubeTransitionEffect.TransitionCompletedSignal().Connect( tracker, functor );
386 // signalName does not match any signal
393 } // namespace Internal
395 } // namespace Toolkit