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;
182 mIsImageLoading = true;
184 Image image = imageActor.GetImage();
185 mBufferIndex = mBufferIndex^1;
187 //must make sure the image is already loaded before using its attributes
188 if( image.GetLoadingState() == ResourceLoadingSucceeded )
190 OnImageLoaded( image );
194 image.LoadingFinishedSignal().Connect( this, &CubeTransitionEffect::OnImageLoaded );
198 void CubeTransitionEffect::StartTransition( bool toNextImage )
202 StartTransition( Vector2( mViewAreaSize.width, mViewAreaSize.height*0.5f ), Vector2( -10.f, 0.f ) );
206 StartTransition( Vector2( 0, mViewAreaSize.height*0.5f ), Vector2( 10.f, 0.f ));
210 void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement )
212 mRoot.SetVisible( true );
213 mCurrentImage.SetVisible( false );
214 bool toNextImage = ( panDisplacement.x < 0 ) ? true : false;
215 if( mIsToNextImage != toNextImage )
217 mChangeTurningDirection = true;
221 mChangeTurningDirection = false;
223 mIsToNextImage = toNextImage;
239 mAnimation = Animation::New( mAnimationDuration );
240 mAnimation.FinishedSignal().Connect(this, &CubeTransitionEffect::OnTransitionFinished);
242 OnStartTransition( panPosition, panDisplacement );
245 void CubeTransitionEffect::PauseTransition()
247 if( mIsAnimating && !mIsPaused )
254 void CubeTransitionEffect::ResumeTransition()
256 if( mIsAnimating && mIsPaused)
263 void CubeTransitionEffect::StopTransition()
271 //reset the position of the cubes
272 //reset the color of the tiles
273 //all these status should be the same as the final state when the transition animation is finished completely
274 const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f,
275 (-mViewAreaSize.height + mTileSize.height) * 0.5f,
276 -mTileSize.width * 0.5f );
277 unsigned int anotherIndex = mContainerIndex^1;
278 for( unsigned int y = 0; y < mNumRows; y++ )
280 float positionY = y * mTileSize.height + basePosition.y;
281 for( unsigned int x = 0; x < mNumColumns; x++)
283 unsigned int idx = y*mNumColumns + x;
284 mBoxes[idx].SetPosition( x * mTileSize.width + basePosition.x,
287 mTiles[mContainerIndex][idx].SetColor( FULL_BRIGHTNESS );
288 mTiles[anotherIndex][idx].SetColor( HALF_BRIGHTNESS);
292 // reset the rotation of the cubes, which is different process for different derived classes
295 mRoot.SetVisible(false);
296 mCurrentImage.SetVisible(true);
297 mIsAnimating = false;
298 mFirstTransition = false;
302 void CubeTransitionEffect::OnImageLoaded(Image image)
304 // Fit the image to view area, while keeping the aspect; FitKeepAspectRatio(imageSize, viewAreaSize)
305 ImageAttributes attributes( image.GetAttributes() );
306 float scale = std::min( mViewAreaSize.width / attributes.GetWidth(), mViewAreaSize.height / attributes.GetHeight() );
307 Vector2 imageSize(attributes.GetWidth()*scale, attributes.GetHeight()*scale);
309 mFullImageCreator.SetEffectImage(image);
310 mFullImageCreator.SetRegionSize(mViewAreaSize, imageSize);
312 mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]);
313 mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
315 ImageActor::PixelArea pixelArea( 0, 0, mViewAreaSize.x / mNumColumns, mViewAreaSize.y / mNumRows);
317 for( unsigned int y = 0; y < mNumRows; y++ )
319 pixelArea.y = y * pixelArea.height;
320 for( unsigned int x = 0; x < mNumColumns; x++)
322 pixelArea.x = x * pixelArea.width;
323 unsigned int idx = y*mNumColumns + x;
324 mTiles[mContainerIndex][idx].SetImage( mOffScreenBuffer[mBufferIndex]);
325 mTiles[mContainerIndex][idx].SetPixelArea( pixelArea );
328 mIsImageLoading = false;
331 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
333 mRoot.SetVisible(false);
334 mCurrentImage.SetVisible(true);
335 mIsAnimating = false;
336 mFirstTransition = false;
339 Toolkit::CubeTransitionEffect handle( this );
340 mTransitionCompletedSignalV2.Emit( handle, mCurrentImage );
343 Toolkit::CubeTransitionEffect::TransitionCompletedSignalV2& CubeTransitionEffect::TransitionCompletedSignal()
345 return mTransitionCompletedSignalV2;
348 } // namespace Internal
350 } // namespace Toolkit