Remove unnecessarily exported signals and action names
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / view / view-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 "view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/animation/constraints.h>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/object/type-registry.h>
25
26 // INTERNAL INCLUDES
27
28 namespace Dali
29 {
30
31 namespace Toolkit
32 {
33
34 namespace Internal
35 {
36
37 namespace // to register type
38 {
39
40 // Signals
41
42 const char* const SIGNAL_ORIENTATION_ANIMATION_START = "orientation-animation-start";
43
44 BaseHandle Create()
45 {
46   return Toolkit::View::New();
47 }
48
49 TypeRegistration typeRegistration( typeid( Toolkit::View ), typeid( Toolkit::Control ), Create );
50
51 SignalConnectorType signalConnector1( typeRegistration, SIGNAL_ORIENTATION_ANIMATION_START , &View::DoConnectSignal );
52
53 }
54
55 namespace
56 {
57
58 const float ROTATION_ANIMATION_DURATION = 0.5f;
59
60 }
61
62 Toolkit::View View::New( bool fullscreen )
63 {
64   // Create the implementation, temporarily owned by this handle on stack
65   IntrusivePtr< View > internalView = new View(fullscreen);
66
67   // Pass ownership to CustomActor handle
68   Toolkit::View view( *internalView );
69
70   // Second-phase init of the implementation
71   // This can only be done after the CustomActor connection has been made...
72   internalView->Initialize();
73
74   return view;
75 }
76
77 Layer View::GetContentLayer( unsigned int index ) const
78 {
79   // Returns the layer stored in the layer map.
80   Layer layer;
81
82   LayerConstIt it = mContentLayers.find( index );
83
84   if( it != mContentLayers.end() )
85   {
86     layer = it->second;
87   }
88
89   return layer;
90 }
91
92 unsigned int View::AddContentLayer( Layer layer )
93 {
94   // layer must exist.
95   DALI_ASSERT_ALWAYS( layer );
96
97   unsigned int index = mNextLayerIndex;
98   LayerIt it = FindLayer( layer );
99
100   if( it == mContentLayers.end() )
101   {
102     // Add layer to the custom actor.
103     Self().Add( layer );
104
105     // Store the layer.
106     mContentLayers[mNextLayerIndex] = layer;
107
108     // Increase the index.
109     ++mNextLayerIndex;
110   }
111
112   return index;
113 }
114
115 void View::RemoveContentLayer( Layer layer )
116 {
117   // Check if layer was added in this view.
118   LayerIt it = FindLayer( layer );
119   if( it != mContentLayers.end() )
120   {
121     // Remove layer from custom actor.
122     Self().Remove( layer );
123
124     // Remove layer from layer map.
125     mContentLayers.erase( it );
126   }
127 }
128
129 Layer View::GetBackgroundLayer() const
130 {
131   return mBackgroundLayer;
132 }
133
134 void View::SetBackground( ImageActor backgroundImage )
135 {
136   // Create background layer if doesn't exist.
137
138   if( !mBackgroundLayer )
139   {
140     mBackgroundLayer = Layer::New();
141
142     mBackgroundLayer.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
143     mBackgroundLayer.SetSize( mViewSize );
144
145     // Add background layer to custom actor.
146     Self().Add( mBackgroundLayer );
147
148     // Drop the background layer
149
150     DALI_ASSERT_ALWAYS( mBackgroundLayer.OnStage() ); // We need to be on-stage to drop the layer
151     mBackgroundLayer.LowerToBottom();
152   }
153   else
154   {
155     // It removes the old background
156     if( 0 < mBackgroundLayer.GetChildCount() )
157     {
158       mBackgroundLayer.Remove( mBackgroundLayer.GetChildAt(0) );
159     }
160   }
161
162   backgroundImage.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
163   backgroundImage.SetScale( FillXYKeepAspectRatio( mViewSize, backgroundImage.GetSize() ) );
164   mBackgroundLayer.Add( backgroundImage );
165 }
166
167 void View::SetOrientationFunction( Degree portrait, Degree landscale, Degree portraitInverse, Degree landscapeInverse )
168 {
169   mOrientationFunction[View::PORTRAIT] = portrait;
170   mOrientationFunction[View::LANDSCAPE] = landscale;
171   mOrientationFunction[View::PORTRAIT_INVERSE] = portraitInverse;
172   mOrientationFunction[View::LANDSCAPE_INVERSE] = landscapeInverse;
173 }
174
175 void View::OrientationChanged( Dali::Orientation orientation )
176 {
177   // Nothing to do if orientation doesn't really change.
178   if ( orientation.GetDegrees() == mOrientation || !mAutoRotateEnabled )
179   {
180     return;
181   }
182
183   mOrientation = orientation.GetDegrees();
184
185   // has parent so we expect it to be on stage
186   mRotateAnimation = Animation::New( ROTATION_ANIMATION_DURATION );
187   mRotateAnimation.RotateTo( Self(), Degree( -orientation.GetDegrees() ), Vector3::ZAXIS, AlphaFunctions::EaseOut );
188
189   // Resize the view
190   if( mFullScreen )
191   {
192     const Vector2& stageSize( Stage::GetCurrent().GetSize() );
193     const Vector3& currentSize( Self().GetCurrentSize() );
194
195     float minSize = std::min( stageSize.width, stageSize.height );
196     float maxSize = std::max( stageSize.width, stageSize.height );
197
198     Vector3 targetSize;
199     View::Orientation viewOrientation = DegreeToViewOrientation( Degree( orientation.GetDegrees() ) );
200     switch( viewOrientation )
201     {
202       case View::PORTRAIT:          // Fallthrough
203       case View::PORTRAIT_INVERSE:
204         targetSize = Vector3( minSize, maxSize, currentSize.depth );
205         break;
206       case View::LANDSCAPE:         // Fallthrough
207       case View::LANDSCAPE_INVERSE:
208         targetSize = Vector3( maxSize, minSize, currentSize.depth );
209         break;
210       default:
211         DALI_ASSERT_ALWAYS( false );
212     }
213
214     // if we linearly resize from portrait to landscape halfway through the animation
215     // we get size which is square between the both. This would cause a square image to grow
216     // if it is fitted to be 100% of view size. Therefore we do a nonlinear size animation
217     // where we shrink faster
218     // which one grows
219     if( targetSize.width > currentSize.width )
220     {
221       // width grows, shrink height faster
222       Vector3 shrink( currentSize );shrink.height = targetSize.height;
223       mRotateAnimation.Resize( Self(), shrink, AlphaFunctions::EaseOut, 0.0f, ROTATION_ANIMATION_DURATION * 0.5f );
224       mRotateAnimation.Resize( Self(), targetSize, AlphaFunctions::EaseIn, 0.0f, ROTATION_ANIMATION_DURATION );
225     }
226     else
227     {
228       // height grows, shrink width faster
229       Vector3 shrink( currentSize );shrink.width = targetSize.width;
230       mRotateAnimation.Resize( Self(), shrink, AlphaFunctions::EaseOut, 0.0f, ROTATION_ANIMATION_DURATION * 0.5f );
231       mRotateAnimation.Resize( Self(), targetSize, AlphaFunctions::EaseIn, 0.0f, ROTATION_ANIMATION_DURATION );
232     }
233   }
234
235   Toolkit::View handle( GetOwner() );
236   mOrientationAnimationStartedSignal.Emit( handle, mRotateAnimation, orientation );
237
238   mRotateAnimation.Play();
239 }
240
241 void View::SetAutoRotate( bool enabled )
242 {
243   mAutoRotateEnabled = enabled;
244 }
245
246 Toolkit::View::OrientationAnimationStartedSignalType& View::OrientationAnimationStartedSignal()
247 {
248   return mOrientationAnimationStartedSignal;
249 }
250
251 bool View::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
252 {
253   Dali::BaseHandle handle( object );
254
255   bool connected( true );
256   Toolkit::View view = Toolkit::View::DownCast(handle);
257
258   if( 0 == strcmp( signalName.c_str(), SIGNAL_ORIENTATION_ANIMATION_START ) )
259   {
260     view.OrientationAnimationStartedSignal().Connect( tracker, functor );
261   }
262   else
263   {
264     // signalName does not match any signal
265     connected = false;
266   }
267
268   return connected;
269 }
270
271 View::View(bool fullscreen)
272 : Control( CONTROL_BEHAVIOUR_NONE ),
273   mOrientation( -1 ),
274   mFullScreen(fullscreen),
275   mContentLayers(),
276   mNextLayerIndex( 0 ),
277   mOrientationFunction(),
278   mAutoRotateEnabled( true )
279 {
280   mOrientationFunction[View::PORTRAIT] = 0.f;
281   mOrientationFunction[View::LANDSCAPE] = 90.f;
282   mOrientationFunction[View::PORTRAIT_INVERSE] = 180.f;
283   mOrientationFunction[View::LANDSCAPE_INVERSE] =  270.f;
284 }
285
286 View::~View()
287 {
288 }
289
290 void View::OnInitialize()
291 {
292   Self().SetAnchorPoint( AnchorPoint::CENTER );
293   Self().SetParentOrigin( ParentOrigin::CENTER );
294
295   if( mFullScreen )
296   {
297     Self().SetSize( Stage::GetCurrent().GetSize() );
298   }
299 }
300
301 void View::OnControlSizeSet( const Vector3& targetSize )
302 {
303   mViewSize = targetSize;
304   if( mBackgroundLayer )
305   {
306     mBackgroundLayer.SetSize( mViewSize );
307     if( mBackgroundLayer.GetChildCount() > 0 )
308     {
309       Actor background = mBackgroundLayer.GetChildAt(0);
310       background.SetScale( FillXYKeepAspectRatio( mViewSize, background.GetSize() ) );
311     }
312   }
313 }
314
315 View::Orientation View::DegreeToViewOrientation( Degree degree )
316 {
317   View::Orientation orientation = PORTRAIT;
318
319   if( fabsf( mOrientationFunction[PORTRAIT] - degree ) <= GetRangedEpsilon( mOrientationFunction[PORTRAIT], degree ) )
320   {
321     orientation =  PORTRAIT;
322   }
323   else if( fabsf( mOrientationFunction[LANDSCAPE] - degree ) <= GetRangedEpsilon( mOrientationFunction[LANDSCAPE], degree ) )
324   {
325     orientation = LANDSCAPE;
326   }
327   else if( fabsf( mOrientationFunction[PORTRAIT_INVERSE] - degree ) <= GetRangedEpsilon( mOrientationFunction[PORTRAIT_INVERSE], degree ) )
328   {
329     orientation = PORTRAIT_INVERSE;
330   }
331   else if( fabsf( mOrientationFunction[LANDSCAPE_INVERSE] - degree ) <= GetRangedEpsilon( mOrientationFunction[LANDSCAPE_INVERSE], degree ) )
332   {
333     orientation = LANDSCAPE_INVERSE;
334   }
335
336   return orientation;
337 }
338
339 View::LayerIt View::FindLayer( Layer layer )
340 {
341   for( LayerIt it = mContentLayers.begin(); it != mContentLayers.end(); ++it )
342   {
343     if(layer == it->second)
344     {
345       return it;
346     }
347   }
348
349   return mContentLayers.end();
350 }
351
352 } // namespace Internal
353
354 } // namespace Toolkit
355
356 } // namespace Dali