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 "view-impl.h"
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 #include <dali/public-api/object/type-registry-helper.h>
41 return Toolkit::View::New();
44 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::View, Toolkit::Control, Create )
46 DALI_SIGNAL_REGISTRATION( View, "orientation-animation-start", SIGNAL_ORIENTATION_ANIMATION_START )
48 DALI_TYPE_REGISTRATION_END()
50 const float ROTATION_ANIMATION_DURATION = 0.5f;
54 Toolkit::View View::New( bool fullscreen )
56 // Create the implementation, temporarily owned by this handle on stack
57 IntrusivePtr< View > internalView = new View(fullscreen);
59 // Pass ownership to CustomActor handle
60 Toolkit::View view( *internalView );
62 // Second-phase init of the implementation
63 // This can only be done after the CustomActor connection has been made...
64 internalView->Initialize();
69 Layer View::GetContentLayer( unsigned int index ) const
71 // Returns the layer stored in the layer map.
74 LayerConstIt it = mContentLayers.find( index );
76 if( it != mContentLayers.end() )
84 unsigned int View::AddContentLayer( Layer layer )
87 DALI_ASSERT_ALWAYS( layer );
89 unsigned int index = mNextLayerIndex;
90 LayerIt it = FindLayer( layer );
92 if( it == mContentLayers.end() )
94 // Add layer to the custom actor.
98 mContentLayers[mNextLayerIndex] = layer;
100 // Increase the index.
107 void View::RemoveContentLayer( Layer layer )
109 // Check if layer was added in this view.
110 LayerIt it = FindLayer( layer );
111 if( it != mContentLayers.end() )
113 // Remove layer from custom actor.
114 Self().Remove( layer );
116 // Remove layer from layer map.
117 mContentLayers.erase( it );
121 Layer View::GetBackgroundLayer() const
123 return mBackgroundLayer;
126 void View::SetBackground( ImageActor backgroundImage )
128 // Create background layer if doesn't exist.
130 if( !mBackgroundLayer )
132 mBackgroundLayer = Layer::New();
134 mBackgroundLayer.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
135 mBackgroundLayer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
137 // Add background layer to custom actor.
138 Self().Add( mBackgroundLayer );
140 // Drop the background layer
142 DALI_ASSERT_ALWAYS( mBackgroundLayer.OnStage() ); // We need to be on-stage to drop the layer
143 mBackgroundLayer.LowerToBottom();
147 // It removes the old background
148 if( 0 < mBackgroundLayer.GetChildCount() )
150 mBackgroundLayer.Remove( mBackgroundLayer.GetChildAt(0) );
154 backgroundImage.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
155 backgroundImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
156 backgroundImage.SetSizeScalePolicy( SizeScalePolicy::FILL_WITH_ASPECT_RATIO );
157 mBackgroundLayer.Add( backgroundImage );
162 void View::SetOrientationFunction( Degree portrait, Degree landscale, Degree portraitInverse, Degree landscapeInverse )
164 mOrientationFunction[View::PORTRAIT] = portrait;
165 mOrientationFunction[View::LANDSCAPE] = landscale;
166 mOrientationFunction[View::PORTRAIT_INVERSE] = portraitInverse;
167 mOrientationFunction[View::LANDSCAPE_INVERSE] = landscapeInverse;
170 void View::OrientationChanged( Dali::Orientation orientation )
174 // Nothing to do if orientation doesn't really change.
175 if ( orientation.GetDegrees() == mOrientation || !mAutoRotateEnabled )
180 mOrientation = orientation.GetDegrees();
182 // has parent so we expect it to be on stage
183 mRotateAnimation = Animation::New( ROTATION_ANIMATION_DURATION );
184 mRotateAnimation.AnimateTo( Property( self, Actor::Property::ORIENTATION ), Quaternion( -orientation.GetRadians(), Vector3::ZAXIS ), AlphaFunctions::EaseOut );
189 const Vector2& stageSize( Stage::GetCurrent().GetSize() );
190 const Vector3& currentSize( self.GetCurrentSize() );
192 float minSize = std::min( stageSize.width, stageSize.height );
193 float maxSize = std::max( stageSize.width, stageSize.height );
196 View::Orientation viewOrientation = DegreeToViewOrientation( Degree( orientation.GetDegrees() ) );
197 switch( viewOrientation )
199 case View::PORTRAIT: // Fallthrough
200 case View::PORTRAIT_INVERSE:
201 targetSize = Vector3( minSize, maxSize, currentSize.depth );
203 case View::LANDSCAPE: // Fallthrough
204 case View::LANDSCAPE_INVERSE:
205 targetSize = Vector3( maxSize, minSize, currentSize.depth );
208 DALI_ASSERT_ALWAYS( false );
211 // if we linearly resize from portrait to landscape halfway through the animation
212 // we get size which is square between the both. This would cause a square image to grow
213 // if it is fitted to be 100% of view size. Therefore we do a nonlinear size animation
214 // where we shrink faster
216 if( targetSize.width > currentSize.width )
218 // width grows, shrink height faster
219 Vector3 shrink( currentSize );shrink.height = targetSize.height;
220 mRotateAnimation.AnimateTo( Property( self, Actor::Property::SIZE ), shrink, AlphaFunctions::EaseOut, TimePeriod( 0.0f, ROTATION_ANIMATION_DURATION * 0.5f ) );
221 mRotateAnimation.AnimateTo( Property( self, Actor::Property::SIZE ), targetSize, AlphaFunctions::EaseIn, TimePeriod( 0.0f, ROTATION_ANIMATION_DURATION ) );
225 // height grows, shrink width faster
226 Vector3 shrink( currentSize );shrink.width = targetSize.width;
227 mRotateAnimation.AnimateTo( Property( self, Actor::Property::SIZE ), shrink, AlphaFunctions::EaseOut, TimePeriod( 0.0f, ROTATION_ANIMATION_DURATION * 0.5f ) );
228 mRotateAnimation.AnimateTo( Property( self, Actor::Property::SIZE ), targetSize, AlphaFunctions::EaseIn, TimePeriod( 0.0f, ROTATION_ANIMATION_DURATION ) );
232 Toolkit::View handle( GetOwner() );
233 mOrientationAnimationStartedSignal.Emit( handle, mRotateAnimation, orientation );
235 mRotateAnimation.Play();
238 void View::SetAutoRotate( bool enabled )
240 mAutoRotateEnabled = enabled;
243 Toolkit::View::OrientationAnimationStartedSignalType& View::OrientationAnimationStartedSignal()
245 return mOrientationAnimationStartedSignal;
248 bool View::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
250 Dali::BaseHandle handle( object );
252 bool connected( true );
253 Toolkit::View view = Toolkit::View::DownCast(handle);
255 if( 0 == strcmp( signalName.c_str(), SIGNAL_ORIENTATION_ANIMATION_START ) )
257 view.OrientationAnimationStartedSignal().Connect( tracker, functor );
261 // signalName does not match any signal
268 View::View(bool fullscreen)
269 : Control( CONTROL_BEHAVIOUR_NONE ),
271 mFullScreen(fullscreen),
273 mNextLayerIndex( 0 ),
274 mOrientationFunction(),
275 mAutoRotateEnabled( true )
277 mOrientationFunction[View::PORTRAIT] = 0.f;
278 mOrientationFunction[View::LANDSCAPE] = 90.f;
279 mOrientationFunction[View::PORTRAIT_INVERSE] = 180.f;
280 mOrientationFunction[View::LANDSCAPE_INVERSE] = 270.f;
287 void View::OnInitialize()
289 Self().SetAnchorPoint( AnchorPoint::CENTER );
290 Self().SetParentOrigin( ParentOrigin::CENTER );
294 Self().SetSize( Stage::GetCurrent().GetSize() );
298 View::Orientation View::DegreeToViewOrientation( Degree degree )
300 View::Orientation orientation = PORTRAIT;
302 if( fabsf( mOrientationFunction[PORTRAIT] - degree ) <= GetRangedEpsilon( mOrientationFunction[PORTRAIT], degree ) )
304 orientation = PORTRAIT;
306 else if( fabsf( mOrientationFunction[LANDSCAPE] - degree ) <= GetRangedEpsilon( mOrientationFunction[LANDSCAPE], degree ) )
308 orientation = LANDSCAPE;
310 else if( fabsf( mOrientationFunction[PORTRAIT_INVERSE] - degree ) <= GetRangedEpsilon( mOrientationFunction[PORTRAIT_INVERSE], degree ) )
312 orientation = PORTRAIT_INVERSE;
314 else if( fabsf( mOrientationFunction[LANDSCAPE_INVERSE] - degree ) <= GetRangedEpsilon( mOrientationFunction[LANDSCAPE_INVERSE], degree ) )
316 orientation = LANDSCAPE_INVERSE;
322 View::LayerIt View::FindLayer( Layer layer )
324 for( LayerIt it = mContentLayers.begin(); it != mContentLayers.end(); ++it )
326 if(layer == it->second)
332 return mContentLayers.end();
335 } // namespace Internal
337 } // namespace Toolkit