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/image-attributes.h>
24 #include <dali/public-api/render-tasks/render-task-list.h>
35 const Vector4 CubeTransitionEffect::FULL_BRIGHTNESS( 1.0f, 1.0f, 1.0f, 1.0f );
36 const Vector4 CubeTransitionEffect::HALF_BRIGHTNESS( 0.5f, 0.5f, 0.5f, 1.0f );
38 CubeTransitionEffect::CubeTransitionEffect( unsigned int numRows, unsigned int numColumns, Size viewAreaSize )
39 : mNumRows( numRows ),
40 mNumColumns( numColumns ),
41 mViewAreaSize( viewAreaSize ),
44 mChangeTurningDirection( false ),
45 mIsToNextImage( true ),
46 mIsImageLoading( false ),
47 mAnimationDuration( 1.f ),
48 mIsAnimating( false ),
50 mCubeDisplacement( 0.f ),
51 mFirstTransition( true ),
56 CubeTransitionEffect::~CubeTransitionEffect()
60 void CubeTransitionEffect::Initialize()
62 //create root actor for the cube transition effect, only visible during the transition
64 mRoot.SetParentOrigin( ParentOrigin::CENTER );
65 mRoot.SetAnchorPoint( AnchorPoint::CENTER );
66 mRoot.SetVisible(false);
68 // create two groups of tiles,
69 // and one group of actors (cubes) serving as parents of every two tiles (one from each image).
70 unsigned int totalNum = mNumColumns* mNumRows;
71 mBoxes.resize( totalNum );
72 mTiles[0].resize( totalNum );
73 mTiles[1].resize( totalNum );
74 mTileSize = Vector2( mViewAreaSize.width / mNumColumns, mViewAreaSize.height / mNumRows );
75 const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f,
76 (-mViewAreaSize.height + mTileSize.height) * 0.5f,
77 -mTileSize.width * 0.5f );
79 Image placeHolder = BitmapImage::WHITE();
80 for( unsigned int y = 0; y < mNumRows; y++ )
82 float positionY = y * mTileSize.height + basePosition.y;
83 for( unsigned int x = 0; x < mNumColumns; x++)
85 unsigned int idx = y*mNumColumns + x;
86 Actor actor( Actor::New() );
88 actor.SetParentOrigin( ParentOrigin::CENTER );
89 actor.SetAnchorPoint( AnchorPoint::CENTER );
90 actor.SetPosition( x * mTileSize.width + basePosition.x,
95 mTiles[ 0 ][idx] = CreateTile( placeHolder, FULL_BRIGHTNESS );
96 actor.Add( mTiles[ 0 ][idx] );
98 mTiles[ 1 ][idx] = CreateTile( placeHolder, HALF_BRIGHTNESS );
99 actor.Add( mTiles[ 1 ][idx] );
103 // helper actor to create a off-screen image using shader effect
104 mEmptyImage = ImageActor::New( placeHolder );
105 mEmptyImage.SetSize(Stage::GetCurrent().GetSize());
106 mEmptyImage.SetParentOrigin( ParentOrigin::CENTER );
107 mEmptyImage.SetAnchorPoint( AnchorPoint::CENTER );
108 mFullImageCreator = FullAreaImageCreator::New();
109 mEmptyImage.SetShaderEffect( mFullImageCreator );
110 Stage::GetCurrent().Add(mEmptyImage);
112 // set up off-screen render task
113 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
114 mOffScreenTask = taskList.CreateTask();
115 mOffScreenTask.SetSourceActor(mEmptyImage);
116 mOffScreenTask.SetExclusive(true);
117 mOffScreenBuffer[0] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y);
118 mOffScreenBuffer[1] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y);
119 mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]);
120 mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
125 ImageActor CubeTransitionEffect::CreateTile( Image image, const Vector4& color )
127 ImageActor tile = ImageActor::New( image );
128 tile.SetParentOrigin( ParentOrigin::CENTER );
129 tile.SetAnchorPoint( AnchorPoint::CENTER );
130 tile.SetSize( mTileSize );
131 tile.SetColorMode( Dali::USE_OWN_COLOR );
132 tile.SetColor( color );
137 void CubeTransitionEffect::SetTransitionDuration( float duration )
139 mAnimationDuration = duration;
142 float CubeTransitionEffect::GetTransitionDuration( ) const
144 return mAnimationDuration;
147 void CubeTransitionEffect::SetCubeDisplacement( float displacement )
149 mCubeDisplacement = displacement;
152 float CubeTransitionEffect::GetCubeDisplacement() const
154 return mCubeDisplacement;
157 Actor CubeTransitionEffect::GetRoot()
162 bool CubeTransitionEffect::IsTransiting()
164 return mIsImageLoading || mIsAnimating;
167 void CubeTransitionEffect::SetCurrentImage( ImageActor imageActor )
169 mContainerIndex = std::abs(mRotateIndex) % 2;
170 SetImage( imageActor );
173 void CubeTransitionEffect::SetTargetImage( ImageActor imageActor )
175 mContainerIndex = std::abs( mRotateIndex+1 ) % 2;
176 SetImage( imageActor );
179 void CubeTransitionEffect::SetImage( ImageActor imageActor )
181 mCurrentImage = imageActor;
183 Image image = imageActor.GetImage();
184 ResourceImage resourceImage = ResourceImage::DownCast( image );
185 mBufferIndex = mBufferIndex^1;
187 //must make sure the image is already loaded before using its attributes
188 if( resourceImage && resourceImage.GetLoadingState() != ResourceLoadingSucceeded )
190 mIsImageLoading = true;
191 resourceImage.LoadingFinishedSignal().Connect( this, &CubeTransitionEffect::OnImageLoaded );
195 mIsImageLoading = false;
196 PrepareTiles( image );
200 void CubeTransitionEffect::StartTransition( bool toNextImage )
204 StartTransition( Vector2( mViewAreaSize.width, mViewAreaSize.height*0.5f ), Vector2( -10.f, 0.f ) );
208 StartTransition( Vector2( 0, mViewAreaSize.height*0.5f ), Vector2( 10.f, 0.f ));
212 void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement )
214 mRoot.SetVisible( true );
215 mCurrentImage.SetVisible( false );
216 bool toNextImage = ( panDisplacement.x < 0 ) ? true : false;
217 if( mIsToNextImage != toNextImage )
219 mChangeTurningDirection = true;
223 mChangeTurningDirection = false;
225 mIsToNextImage = toNextImage;
241 mAnimation = Animation::New( mAnimationDuration );
242 mAnimation.FinishedSignal().Connect(this, &CubeTransitionEffect::OnTransitionFinished);
244 OnStartTransition( panPosition, panDisplacement );
247 void CubeTransitionEffect::PauseTransition()
249 if( mIsAnimating && !mIsPaused )
256 void CubeTransitionEffect::ResumeTransition()
258 if( mIsAnimating && mIsPaused)
265 void CubeTransitionEffect::StopTransition()
273 //reset the position of the cubes
274 //reset the color of the tiles
275 //all these status should be the same as the final state when the transition animation is finished completely
276 const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f,
277 (-mViewAreaSize.height + mTileSize.height) * 0.5f,
278 -mTileSize.width * 0.5f );
279 unsigned int anotherIndex = mContainerIndex^1;
280 for( unsigned int y = 0; y < mNumRows; y++ )
282 float positionY = y * mTileSize.height + basePosition.y;
283 for( unsigned int x = 0; x < mNumColumns; x++)
285 unsigned int idx = y*mNumColumns + x;
286 mBoxes[idx].SetPosition( x * mTileSize.width + basePosition.x,
289 mTiles[mContainerIndex][idx].SetColor( FULL_BRIGHTNESS );
290 mTiles[anotherIndex][idx].SetColor( HALF_BRIGHTNESS);
294 // reset the rotation of the cubes, which is different process for different derived classes
297 mRoot.SetVisible(false);
298 mCurrentImage.SetVisible(true);
299 mIsAnimating = false;
300 mFirstTransition = false;
304 void CubeTransitionEffect::OnImageLoaded(ResourceImage image)
306 mIsImageLoading = false;
307 PrepareTiles( image );
311 * Set sub-image to each tile.
312 * @param[in] image The image content of the imageActor for transition
314 void CubeTransitionEffect::PrepareTiles( Image image )
316 // Fit the image to view area, while keeping the aspect; FitKeepAspectRatio(imageSize, viewAreaSize)
317 float scale = std::min( mViewAreaSize.width / image.GetWidth(), mViewAreaSize.height / image.GetHeight() );
318 Vector2 imageSize(image.GetWidth()*scale, image.GetHeight()*scale);
320 mFullImageCreator.SetEffectImage(image);
321 mFullImageCreator.SetRegionSize(mViewAreaSize, imageSize);
323 mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]);
324 mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
326 ImageActor::PixelArea pixelArea( 0, 0, mViewAreaSize.x / mNumColumns, mViewAreaSize.y / mNumRows);
328 for( unsigned int y = 0; y < mNumRows; y++ )
330 pixelArea.y = y * pixelArea.height;
331 for( unsigned int x = 0; x < mNumColumns; x++)
333 pixelArea.x = x * pixelArea.width;
334 unsigned int idx = y*mNumColumns + x;
335 mTiles[mContainerIndex][idx].SetImage( mOffScreenBuffer[mBufferIndex]);
336 mTiles[mContainerIndex][idx].SetPixelArea( pixelArea );
342 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
344 mRoot.SetVisible(false);
345 mCurrentImage.SetVisible(true);
346 mIsAnimating = false;
347 mFirstTransition = false;
350 Toolkit::CubeTransitionEffect handle( this );
351 mTransitionCompletedSignal.Emit( handle, mCurrentImage );
354 Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()
356 return mTransitionCompletedSignal;
359 } // namespace Internal
361 } // namespace Toolkit