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.
20 #include "view-impl.h"
35 namespace // to register type
40 return Toolkit::View::New();
43 TypeRegistration typeRegistration( typeid(Toolkit::View), typeid(Toolkit::Control), Create );
45 SignalConnectorType signalConnector1( typeRegistration, Toolkit::View::SIGNAL_ORIENTATION_ANIMATION_START , &View::DoConnectSignal );
52 const float ROTATION_ANIMATION_DURATION = 0.5f;
56 Toolkit::View View::New( bool fullscreen )
58 // Create the implementation, temporarily owned by this handle on stack
59 IntrusivePtr< View > internalView = new View(fullscreen);
61 // Pass ownership to CustomActor handle
62 Toolkit::View view( *internalView );
64 // Second-phase init of the implementation
65 // This can only be done after the CustomActor connection has been made...
66 internalView->Initialize();
71 Layer View::GetContentLayer( unsigned int index ) const
73 // Returns the layer stored in the layer map.
76 LayerConstIt it = mContentLayers.find( index );
78 if( it != mContentLayers.end() )
86 unsigned int View::AddContentLayer( Layer layer )
89 DALI_ASSERT_ALWAYS( layer );
91 unsigned int index = mNextLayerIndex;
92 LayerIt it = FindLayer( layer );
94 if( it == mContentLayers.end() )
96 // Add layer to the custom actor.
100 mContentLayers[mNextLayerIndex] = layer;
102 // Increase the index.
109 void View::RemoveContentLayer( Layer layer )
111 // Check if layer was added in this view.
112 LayerIt it = FindLayer( layer );
113 if( it != mContentLayers.end() )
115 // Remove layer from custom actor.
116 Self().Remove( layer );
118 // Remove layer from layer map.
119 mContentLayers.erase( it );
123 Layer View::GetBackgroundLayer() const
125 return mBackgroundLayer;
128 void View::SetBackground( ImageActor backgroundImage )
130 // Create background layer if doesn't exist.
132 if( !mBackgroundLayer )
134 mBackgroundLayer = Layer::New();
136 mBackgroundLayer.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
137 mBackgroundLayer.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
139 // Add background layer to custom actor.
140 Self().Add( mBackgroundLayer );
142 // Drop the background layer
144 DALI_ASSERT_ALWAYS( mBackgroundLayer.OnStage() ); // We need to be on-stage to drop the layer
145 mBackgroundLayer.LowerToBottom();
149 // It removes the old background
150 if( 0 < mBackgroundLayer.GetChildCount() )
152 mBackgroundLayer.Remove( mBackgroundLayer.GetChildAt(0) );
156 backgroundImage.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
157 Constraint constraint = Constraint::New<Vector3>(
159 LocalSource( Actor::SIZE ),
160 ParentSource( Actor::SIZE ),
161 ScaleToFillXYKeepAspectRatioConstraint() );
162 backgroundImage.ApplyConstraint( constraint );
163 mBackgroundLayer.Add( backgroundImage );
166 void View::SetOrientationFunction( Degree portrait, Degree landscale, Degree portraitInverse, Degree landscapeInverse )
168 mOrientationFunction[View::PORTRAIT] = portrait;
169 mOrientationFunction[View::LANDSCAPE] = landscale;
170 mOrientationFunction[View::PORTRAIT_INVERSE] = portraitInverse;
171 mOrientationFunction[View::LANDSCAPE_INVERSE] = landscapeInverse;
174 void View::OrientationChanged( Dali::Orientation orientation )
176 // Nothing to do if orientation doesn't really change.
177 if ( orientation.GetDegrees() == mOrientation || !mAutoRotateEnabled )
182 mOrientation = orientation.GetDegrees();
184 // has parent so we expect it to be on stage
185 mRotateAnimation = Animation::New( ROTATION_ANIMATION_DURATION );
186 mRotateAnimation.RotateTo( Self(), Degree( -orientation.GetDegrees() ), Vector3::ZAXIS, AlphaFunctions::EaseOut );
191 const Vector2& stageSize( Stage::GetCurrent().GetSize() );
192 const Vector3& currentSize( Self().GetCurrentSize() );
194 float minSize = std::min( stageSize.width, stageSize.height );
195 float maxSize = std::max( stageSize.width, stageSize.height );
198 View::Orientation viewOrientation = DegreeToViewOrientation( Degree( orientation.GetDegrees() ) );
199 switch( viewOrientation )
201 case View::PORTRAIT: // Fallthrough
202 case View::PORTRAIT_INVERSE:
203 targetSize = Vector3( minSize, maxSize, currentSize.depth );
205 case View::LANDSCAPE: // Fallthrough
206 case View::LANDSCAPE_INVERSE:
207 targetSize = Vector3( maxSize, minSize, currentSize.depth );
210 DALI_ASSERT_ALWAYS( false );
213 // if we linearly resize from portrait to landscape halfway through the animation
214 // we get size which is square between the both. This would cause a square image to grow
215 // if it is fitted to be 100% of view size. Therefore we do a nonlinear size animation
216 // where we shrink faster
218 if( targetSize.width > currentSize.width )
220 // width grows, shrink height faster
221 Vector3 shrink( currentSize );shrink.height = targetSize.height;
222 mRotateAnimation.Resize( Self(), shrink, AlphaFunctions::EaseOut, 0.0f, ROTATION_ANIMATION_DURATION * 0.5f );
223 mRotateAnimation.Resize( Self(), targetSize, AlphaFunctions::EaseIn, 0.0f, ROTATION_ANIMATION_DURATION );
227 // height grows, shrink width faster
228 Vector3 shrink( currentSize );shrink.width = targetSize.width;
229 mRotateAnimation.Resize( Self(), shrink, AlphaFunctions::EaseOut, 0.0f, ROTATION_ANIMATION_DURATION * 0.5f );
230 mRotateAnimation.Resize( Self(), targetSize, AlphaFunctions::EaseIn, 0.0f, ROTATION_ANIMATION_DURATION );
234 mRotateAnimation.SetDestroyAction( Animation::Bake );
236 Toolkit::View handle( GetOwner() );
237 mOrientationAnimationStartedSignalV2.Emit( handle, mRotateAnimation, orientation );
239 mRotateAnimation.Play();
242 void View::SetAutoRotate( bool enabled )
244 mAutoRotateEnabled = enabled;
247 Toolkit::View::OrientationAnimationStartedSignalV2& View::OrientationAnimationStartedSignal()
249 return mOrientationAnimationStartedSignalV2;
252 bool View::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
254 Dali::BaseHandle handle( object );
256 bool connected( true );
257 Toolkit::View view = Toolkit::View::DownCast(handle);
259 if( Toolkit::View::SIGNAL_ORIENTATION_ANIMATION_START == signalName )
261 view.OrientationAnimationStartedSignal().Connect( tracker, functor );
265 // signalName does not match any signal
272 View::View(bool fullscreen)
273 : ControlImpl( false ), // doesn't require touch events
275 mFullScreen(fullscreen),
277 mNextLayerIndex( 0 ),
278 mOrientationFunction(),
279 mAutoRotateEnabled( true )
281 mOrientationFunction[View::PORTRAIT] = 0.f;
282 mOrientationFunction[View::LANDSCAPE] = 90.f;
283 mOrientationFunction[View::PORTRAIT_INVERSE] = 180.f;
284 mOrientationFunction[View::LANDSCAPE_INVERSE] = 270.f;
291 void View::OnInitialize()
293 Self().SetAnchorPoint( AnchorPoint::CENTER );
294 Self().SetParentOrigin( ParentOrigin::CENTER );
298 Self().SetSize( Stage::GetCurrent().GetSize() );
302 View::Orientation View::DegreeToViewOrientation( Degree degree )
304 View::Orientation orientation = PORTRAIT;
306 if( fabsf( mOrientationFunction[PORTRAIT] - degree ) <= GetRangedEpsilon( mOrientationFunction[PORTRAIT], degree ) )
308 orientation = PORTRAIT;
310 else if( fabsf( mOrientationFunction[LANDSCAPE] - degree ) <= GetRangedEpsilon( mOrientationFunction[LANDSCAPE], degree ) )
312 orientation = LANDSCAPE;
314 else if( fabsf( mOrientationFunction[PORTRAIT_INVERSE] - degree ) <= GetRangedEpsilon( mOrientationFunction[PORTRAIT_INVERSE], degree ) )
316 orientation = PORTRAIT_INVERSE;
318 else if( fabsf( mOrientationFunction[LANDSCAPE_INVERSE] - degree ) <= GetRangedEpsilon( mOrientationFunction[LANDSCAPE_INVERSE], degree ) )
320 orientation = LANDSCAPE_INVERSE;
326 View::LayerIt View::FindLayer( Layer layer )
328 for( LayerIt it = mContentLayers.begin(); it != mContentLayers.end(); ++it )
330 if(layer == it->second)
336 return mContentLayers.end();
339 } // namespace Internal
341 } // namespace Toolkit