Merge "Empty Implementation for INPUT_METHOD_SETTINGS property" into tizen
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / transition-effects / cube-transition-effect-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "cube-transition-effect-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/images/buffer-image.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/devel-api/object/type-registry-helper.h>
27 #include <dali/public-api/render-tasks/render-task-list.h>
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal
36 {
37
38 namespace
39 {
40
41 // Setup properties, signals and actions using the type-registry.
42 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::CubeTransitionEffect, Dali::BaseHandle, NULL );
43
44 DALI_SIGNAL_REGISTRATION( Toolkit, CubeTransitionEffect, "transition-completed", SIGNAL_TRANSITION_COMPLETED )
45
46 DALI_TYPE_REGISTRATION_END()
47
48 }
49
50 const Vector4 CubeTransitionEffect::FULL_BRIGHTNESS( 1.0f, 1.0f, 1.0f, 1.0f );
51 const Vector4 CubeTransitionEffect::HALF_BRIGHTNESS( 0.5f, 0.5f, 0.5f, 1.0f );
52
53 CubeTransitionEffect::CubeTransitionEffect( unsigned int numRows, unsigned int numColumns, Size viewAreaSize )
54 : mNumRows( numRows ),
55   mNumColumns( numColumns ),
56   mViewAreaSize( viewAreaSize ),
57   mRotateIndex( 0 ),
58   mContainerIndex( 0 ),
59   mChangeTurningDirection( false ),
60   mIsToNextImage( true ),
61   mIsImageLoading( false ),
62   mAnimationDuration( 1.f ),
63   mIsAnimating( false ),
64   mIsPaused( false ),
65   mCubeDisplacement( 0.f ),
66   mFirstTransition( true ),
67   mBufferIndex( 0 )
68 {
69 }
70
71 CubeTransitionEffect::~CubeTransitionEffect()
72 {
73 }
74
75 void CubeTransitionEffect::Initialize()
76 {
77   //create root actor for the cube transition effect, only visible during the transition
78   mRoot = Actor::New();
79   mRoot.SetParentOrigin( ParentOrigin::CENTER );
80   mRoot.SetAnchorPoint( AnchorPoint::CENTER );
81   mRoot.SetVisible(false);
82
83   // create two groups of tiles,
84   // and one group of actors (cubes) serving as parents of every two tiles (one from each image).
85   unsigned int totalNum = mNumColumns* mNumRows;
86   mBoxes.resize( totalNum );
87   mTiles[0].resize( totalNum );
88   mTiles[1].resize( totalNum );
89   mTileSize = Vector2( mViewAreaSize.width / mNumColumns, mViewAreaSize.height / mNumRows );
90   const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f,
91                               (-mViewAreaSize.height + mTileSize.height) * 0.5f,
92                               -mTileSize.width * 0.5f );
93
94   Image placeHolder = BufferImage::WHITE();
95   for( unsigned int y = 0; y < mNumRows; y++ )
96   {
97     float positionY = y * mTileSize.height + basePosition.y;
98     for( unsigned int x = 0; x < mNumColumns; x++)
99     {
100       unsigned int idx = y*mNumColumns + x;
101       Actor actor( Actor::New() );
102       mBoxes[idx] = actor;
103       actor.SetParentOrigin( ParentOrigin::CENTER );
104       actor.SetAnchorPoint( AnchorPoint::CENTER );
105       actor.SetPosition( x * mTileSize.width + basePosition.x,
106                          positionY,
107                          basePosition.z );
108       mRoot.Add( actor );
109
110       mTiles[ 0 ][idx] = CreateTile( placeHolder, FULL_BRIGHTNESS );
111       actor.Add( mTiles[ 0 ][idx] );
112
113       mTiles[ 1 ][idx] = CreateTile( placeHolder, HALF_BRIGHTNESS );
114       actor.Add( mTiles[ 1 ][idx] );
115     }
116   }
117
118   // helper actor to create a off-screen image using shader effect
119   mEmptyImage = ImageActor::New( placeHolder );
120   mEmptyImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
121   mEmptyImage.SetParentOrigin( ParentOrigin::CENTER );
122   mEmptyImage.SetAnchorPoint( AnchorPoint::CENTER );
123   mFullImageCreator = FullAreaImageCreator::New();
124   mEmptyImage.SetShaderEffect( mFullImageCreator );
125   Stage::GetCurrent().Add(mEmptyImage);
126
127   // set up off-screen render task
128   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
129   mOffScreenTask = taskList.CreateTask();
130   mOffScreenTask.SetSourceActor(mEmptyImage);
131   mOffScreenTask.SetExclusive(true);
132   mOffScreenBuffer[0] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y);
133   mOffScreenBuffer[1] = FrameBufferImage::New(mViewAreaSize.x, mViewAreaSize.y);
134   mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]);
135   mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
136
137   OnInitialize();
138 }
139
140 ImageActor CubeTransitionEffect::CreateTile( Image image, const Vector4& color )
141 {
142   ImageActor tile = ImageActor::New( image );
143   tile.SetParentOrigin( ParentOrigin::CENTER );
144   tile.SetAnchorPoint( AnchorPoint::CENTER );
145   tile.SetSize( mTileSize );
146   tile.SetColorMode( Dali::USE_OWN_COLOR );
147   tile.SetColor( color );
148
149   return tile;
150 }
151
152 void CubeTransitionEffect::SetTransitionDuration( float duration )
153 {
154   mAnimationDuration = duration;
155 }
156
157 float CubeTransitionEffect::GetTransitionDuration( ) const
158 {
159   return mAnimationDuration;
160 }
161
162 void CubeTransitionEffect::SetCubeDisplacement( float displacement )
163 {
164   mCubeDisplacement = displacement;
165 }
166
167 float CubeTransitionEffect::GetCubeDisplacement() const
168 {
169   return mCubeDisplacement;
170 }
171
172 Actor CubeTransitionEffect::GetRoot()
173 {
174   return mRoot;
175 }
176
177 bool CubeTransitionEffect::IsTransiting()
178 {
179   return mIsImageLoading || mIsAnimating;
180 }
181
182 void CubeTransitionEffect::SetCurrentImage( ImageActor imageActor )
183 {
184   mContainerIndex = std::abs(mRotateIndex) % 2;
185   SetImage( imageActor );
186 }
187
188 void CubeTransitionEffect::SetTargetImage( ImageActor imageActor )
189 {
190   mContainerIndex = std::abs( mRotateIndex+1 ) % 2;
191   SetImage( imageActor );
192 }
193
194 void CubeTransitionEffect::SetImage( ImageActor imageActor )
195 {
196   mCurrentImage = imageActor;
197
198   Image image = imageActor.GetImage();
199   ResourceImage resourceImage = ResourceImage::DownCast( image );
200   mBufferIndex = mBufferIndex^1;
201
202   //must make sure the image is already loaded before using its attributes
203   if( resourceImage && resourceImage.GetLoadingState() != ResourceLoadingSucceeded )
204   {
205     mIsImageLoading = true;
206     resourceImage.LoadingFinishedSignal().Connect( this, &CubeTransitionEffect::OnImageLoaded );
207   }
208   else
209   {
210     mIsImageLoading = false;
211     PrepareTiles( image );
212   }
213 }
214
215 void CubeTransitionEffect::StartTransition( bool toNextImage )
216 {
217   if( toNextImage )
218   {
219     StartTransition( Vector2( mViewAreaSize.width, mViewAreaSize.height*0.5f ), Vector2( -10.f, 0.f ) );
220   }
221   else
222   {
223     StartTransition( Vector2( 0, mViewAreaSize.height*0.5f ), Vector2( 10.f, 0.f ));
224   }
225 }
226
227 void CubeTransitionEffect::StartTransition( Vector2 panPosition, Vector2 panDisplacement )
228 {
229   mRoot.SetVisible( true );
230   mCurrentImage.SetVisible( false );
231   bool toNextImage = ( panDisplacement.x < 0 ) ? true : false;
232   if( mIsToNextImage != toNextImage )
233   {
234     mChangeTurningDirection = true;
235   }
236   else
237   {
238     mChangeTurningDirection = false;
239   }
240   mIsToNextImage = toNextImage;
241
242   if( mIsToNextImage )
243   {
244     mRotateIndex += 1.f;
245   }
246   else
247   {
248     mRotateIndex -= 1.f;
249   }
250
251   if(mAnimation)
252   {
253     mAnimation.Clear();
254     mAnimation.Reset();
255   }
256   mAnimation = Animation::New( mAnimationDuration );
257   mAnimation.FinishedSignal().Connect(this, &CubeTransitionEffect::OnTransitionFinished);
258
259   OnStartTransition( panPosition, panDisplacement );
260 }
261
262 void CubeTransitionEffect::PauseTransition()
263 {
264   if( mIsAnimating && !mIsPaused )
265   {
266     mAnimation.Pause();
267     mIsPaused = true;
268   }
269 }
270
271 void CubeTransitionEffect::ResumeTransition()
272 {
273   if( mIsAnimating && mIsPaused)
274   {
275     mAnimation.Play();
276     mIsPaused = false;
277   }
278 }
279
280 void CubeTransitionEffect::StopTransition()
281 {
282   if( mIsAnimating )
283   {
284     mAnimation.Clear();
285     mAnimation.Reset();
286     mIsPaused = false;
287
288     //reset the position of the cubes
289     //reset the color of the tiles
290     //all these status should be the same as the final state when the transition animation is finished completely
291     const Vector3 basePosition( (-mViewAreaSize.width + mTileSize.width) * 0.5f,
292                                 (-mViewAreaSize.height + mTileSize.height) * 0.5f,
293                                  -mTileSize.width * 0.5f );
294     unsigned int anotherIndex = mContainerIndex^1;
295     for( unsigned int y = 0; y < mNumRows; y++ )
296     {
297       float positionY = y * mTileSize.height + basePosition.y;
298       for( unsigned int x = 0; x < mNumColumns; x++)
299       {
300         unsigned int idx = y*mNumColumns + x;
301         mBoxes[idx].SetPosition( x * mTileSize.width + basePosition.x,
302                                  positionY,
303                                  basePosition.z );
304         mTiles[mContainerIndex][idx].SetColor( FULL_BRIGHTNESS );
305         mTiles[anotherIndex][idx].SetColor( HALF_BRIGHTNESS);
306       }
307     }
308
309     // reset the rotation of the cubes, which is different process for different derived classes
310     OnStopTransition();
311
312     mRoot.SetVisible(false);
313     mCurrentImage.SetVisible(true);
314     mIsAnimating = false;
315     mFirstTransition = false;
316   }
317 }
318
319 void CubeTransitionEffect::OnImageLoaded(ResourceImage image)
320 {
321   mIsImageLoading = false;
322   PrepareTiles( image );
323 }
324
325 /**
326  * Set sub-image to each tile.
327  * @param[in] image The image content of the imageActor for transition
328  */
329 void CubeTransitionEffect::PrepareTiles( Image image )
330 {
331   // Fit the image to view area, while keeping the aspect; FitKeepAspectRatio(imageSize, viewAreaSize)
332   float scale = std::min(  mViewAreaSize.width / image.GetWidth(), mViewAreaSize.height / image.GetHeight() );
333   Vector2 imageSize(image.GetWidth()*scale, image.GetHeight()*scale);
334
335   mFullImageCreator.SetEffectImage(image);
336   mFullImageCreator.SetRegionSize(mViewAreaSize, imageSize);
337
338   mOffScreenTask.SetTargetFrameBuffer(mOffScreenBuffer[mBufferIndex]);
339   mOffScreenTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
340
341   ImageActor::PixelArea pixelArea( 0, 0, mViewAreaSize.x / mNumColumns, mViewAreaSize.y / mNumRows);
342
343   for( unsigned int y = 0; y < mNumRows; y++ )
344   {
345     pixelArea.y = y * pixelArea.height;
346     for( unsigned int x = 0; x < mNumColumns; x++)
347     {
348       pixelArea.x = x * pixelArea.width;
349       unsigned int idx = y*mNumColumns + x;
350       mTiles[mContainerIndex][idx].SetImage( mOffScreenBuffer[mBufferIndex]);
351       mTiles[mContainerIndex][idx].SetPixelArea( pixelArea );
352     }
353   }
354 }
355
356
357 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
358 {
359   mRoot.SetVisible(false);
360   mCurrentImage.SetVisible(true);
361   mIsAnimating = false;
362   mFirstTransition = false;
363
364   //Emit signal
365   Toolkit::CubeTransitionEffect handle( this );
366   mTransitionCompletedSignal.Emit( handle, mCurrentImage );
367 }
368
369 Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()
370 {
371   return mTransitionCompletedSignal;
372 }
373
374 bool CubeTransitionEffect::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
375 {
376   Dali::BaseHandle handle( object );
377
378   bool connected( true );
379   Toolkit::CubeTransitionEffect cubeTransitionEffect = Toolkit::CubeTransitionEffect::DownCast( handle );
380
381   if( 0 == strcmp( signalName.c_str(), SIGNAL_TRANSITION_COMPLETED ) )
382   {
383     cubeTransitionEffect.TransitionCompletedSignal().Connect( tracker, functor );
384   }
385   else
386   {
387     // signalName does not match any signal
388     connected = false;
389   }
390
391   return connected;
392 }
393
394 } // namespace Internal
395
396 } // namespace Toolkit
397
398 } // namespace Dali