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 <dali/internal/event/actors/layer-impl.h>
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/internal/event/actors/layer-list.h>
25 #include <dali/internal/event/common/property-helper.h>
26 #include <dali/internal/event/common/stage-impl.h>
28 using Dali::Internal::SceneGraph::UpdateManager;
41 // Name Type writable animatable constraint-input enum for index-checking
42 DALI_PROPERTY_TABLE_BEGIN
43 DALI_PROPERTY( "clipping-enable", BOOLEAN, true, false, true, Dali::Layer::Property::CLIPPING_ENABLE )
44 DALI_PROPERTY( "clipping-box", RECTANGLE, true, false, true, Dali::Layer::Property::CLIPPING_BOX )
45 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
49 const char* const ACTION_RAISE = "raise";
50 const char* const ACTION_LOWER = "lower";
51 const char* const ACTION_RAISE_TO_TOP = "raise-to-top";
52 const char* const ACTION_LOWER_TO_BOTTOM = "lower-to-bottom";
56 return Dali::Layer::New();
59 TypeRegistration mType( typeid( Dali::Layer ), typeid( Dali::Actor ), Create );
61 TypeAction a1( mType, ACTION_RAISE, &Layer::DoAction );
62 TypeAction a2( mType, ACTION_LOWER, &Layer::DoAction );
63 TypeAction a3( mType, ACTION_RAISE_TO_TOP, &Layer::DoAction );
64 TypeAction a4( mType, ACTION_LOWER_TO_BOTTOM, &Layer::DoAction );
66 } // unnamed namespace
70 LayerPtr layer( new Layer( Actor::LAYER ) );
72 // Second-phase construction
78 LayerPtr Layer::NewRoot( LayerList& layerList, UpdateManager& manager, bool systemLevel )
80 LayerPtr root( new Layer( Actor::ROOT_LAYER ) );
82 // Second-phase construction
83 SceneGraph::Layer* layer = static_cast<SceneGraph::Layer*>( root->CreateNode() );
84 InstallRootMessage( manager, *layer, systemLevel ); // Transfer ownership to scene-graph
86 // Keep a raw pointer to the layer node.
89 // root actor is immediately considered to be on-stage
90 root->mIsOnStage = true;
92 // The root actor will not emit a stage connection signal so set the signalled flag here as well
93 root->mOnStageSignalled = true;
95 // layer-list must be set for the root layer
96 root->mLayerList = &layerList;
97 layerList.RegisterLayer( *root );
102 Layer::Layer( Actor::DerivedType type )
105 mClippingBox(0,0,0,0),
106 mSortFunction(Dali::Layer::ZValue),
108 mDepthTestDisabled(false),
109 mTouchConsumed(false),
110 mHoverConsumed(false)
114 void Layer::OnInitialize()
122 unsigned int Layer::GetDepth() const
124 return mLayerList ? mLayerList->GetDepth( this ) : 0u;
131 mLayerList->RaiseLayer(*this);
139 mLayerList->LowerLayer(*this);
143 void Layer::RaiseAbove( const Internal::Layer& target )
145 // cannot raise above ourself, both have to be on stage
146 if( ( this != &target ) && OnStage() && target.OnStage() )
148 // get parameters depth
149 const unsigned int targetDepth = target.GetDepth();
150 if( GetDepth() < targetDepth )
157 void Layer::LowerBelow( const Internal::Layer& target )
159 // cannot lower below ourself, both have to be on stage
160 if( ( this != &target ) && OnStage() && target.OnStage() )
162 // get parameters depth
163 const unsigned int targetDepth = target.GetDepth();
164 if( GetDepth() > targetDepth )
171 void Layer::RaiseToTop()
175 mLayerList->RaiseLayerToTop(*this);
179 void Layer::LowerToBottom()
183 mLayerList->LowerLayerToBottom(*this);
187 void Layer::MoveAbove( const Internal::Layer& target )
189 // cannot raise above ourself, both have to be on stage
190 if( ( this != &target ) && mLayerList && target.OnStage() )
192 mLayerList->MoveLayerAbove(*this, target );
196 void Layer::MoveBelow( const Internal::Layer& target )
198 // cannot lower below ourself, both have to be on stage
199 if( ( this != &target ) && mLayerList && target.OnStage() )
201 mLayerList->MoveLayerBelow(*this, target );
205 void Layer::SetClipping(bool enabled)
207 if (enabled != mIsClipping)
209 mIsClipping = enabled;
211 // layerNode is being used in a separate thread; queue a message to set the value
212 SetClippingMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mIsClipping );
216 void Layer::SetClippingBox(int x, int y, int width, int height)
218 if( ( x != mClippingBox.x ) ||
219 ( y != mClippingBox.y ) ||
220 ( width != mClippingBox.width ) ||
221 ( height != mClippingBox.height ) )
223 // Clipping box is not animatable; this is the most up-to-date value
224 mClippingBox.Set(x, y, width, height);
226 // Convert mClippingBox to GL based coordinates (from bottom-left)
227 ClippingBox clippingBox( mClippingBox );
228 clippingBox.y = Stage::GetCurrent()->GetSize().height - clippingBox.y - clippingBox.height;
230 // layerNode is being used in a separate thread; queue a message to set the value
231 SetClippingBoxMessage( GetEventThreadServices(), GetSceneLayerOnStage(), clippingBox );
235 void Layer::SetDepthTestDisabled( bool disable )
237 if( disable != mDepthTestDisabled )
239 mDepthTestDisabled = disable;
241 // Send message .....
242 // layerNode is being used in a separate thread; queue a message to set the value
243 SetDepthTestDisabledMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mDepthTestDisabled );
247 bool Layer::IsDepthTestDisabled() const
249 return mDepthTestDisabled;
252 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
254 if( function != mSortFunction )
256 mSortFunction = function;
258 // layerNode is being used in a separate thread; queue a message to set the value
259 SetSortFunctionMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mSortFunction );
263 void Layer::SetTouchConsumed( bool consume )
265 mTouchConsumed = consume;
268 bool Layer::IsTouchConsumed() const
270 return mTouchConsumed;
273 void Layer::SetHoverConsumed( bool consume )
275 mHoverConsumed = consume;
278 bool Layer::IsHoverConsumed() const
280 return mHoverConsumed;
283 SceneGraph::Node* Layer::CreateNode() const
285 return SceneGraph::Layer::New();
288 void Layer::OnStageConnectionInternal()
292 DALI_ASSERT_DEBUG( NULL == mLayerList );
294 // Find the ordered layer-list
295 // This is different for Layers added via Integration::GetSystemOverlay()
296 for ( Actor* parent = mParent; parent != NULL; parent = parent->GetParent() )
298 if( parent->IsLayer() )
300 Layer* parentLayer = static_cast< Layer* >( parent ); // cheaper than dynamic_cast
301 mLayerList = parentLayer->mLayerList;
306 DALI_ASSERT_DEBUG( NULL != mLayerList );
307 mLayerList->RegisterLayer( *this );
310 void Layer::OnStageDisconnectionInternal()
312 mLayerList->UnregisterLayer(*this);
314 // mLayerList is only valid when on-stage
318 const SceneGraph::Layer& Layer::GetSceneLayerOnStage() const
320 DALI_ASSERT_DEBUG( mNode != NULL );
321 return dynamic_cast< const SceneGraph::Layer& >( *mNode );
324 unsigned int Layer::GetDefaultPropertyCount() const
326 return Actor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT;
329 void Layer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
331 Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
332 indices.reserve( indices.size() + DEFAULT_PROPERTY_COUNT );
334 int index = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
335 for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
337 indices.push_back( index );
341 bool Layer::IsDefaultPropertyWritable( Property::Index index ) const
343 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
345 return Actor::IsDefaultPropertyWritable( index );
348 return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].writable;
351 bool Layer::IsDefaultPropertyAnimatable( Property::Index index ) const
353 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
355 return Actor::IsDefaultPropertyAnimatable( index );
358 return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].animatable;
361 bool Layer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
363 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
365 return Actor::IsDefaultPropertyAConstraintInput( index );
368 return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].constraintInput;
371 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
373 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
375 return Actor::GetDefaultPropertyType( index );
378 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
380 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
382 return DEFAULT_PROPERTY_DETAILS[index].type;
385 // index out-of-bounds
386 return Property::NONE;
389 const char* Layer::GetDefaultPropertyName( Property::Index index ) const
391 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
393 return Actor::GetDefaultPropertyName( index );
396 index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
397 if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
399 return DEFAULT_PROPERTY_DETAILS[index].name;
405 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
407 Property::Index index = Property::INVALID_INDEX;
409 // Look for name in current class' default properties
410 for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
412 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[i];
413 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
415 index = i + DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
419 if( Property::INVALID_INDEX == index )
421 // If not found, check in base class
422 index = Actor::GetDefaultPropertyIndex( name );
428 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
430 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
432 Actor::SetDefaultProperty( index, propertyValue );
438 case Dali::Layer::Property::CLIPPING_ENABLE:
440 SetClipping( propertyValue.Get<bool>() );
443 case Dali::Layer::Property::CLIPPING_BOX:
445 Rect<int> clippingBox( propertyValue.Get<Rect<int> >() );
446 SetClippingBox( clippingBox.x, clippingBox.y, clippingBox.width, clippingBox.height );
451 DALI_LOG_WARNING( "Unknown property (%d)\n", index );
459 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
462 if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
464 ret = Actor::GetDefaultProperty( index );
470 case Dali::Layer::Property::CLIPPING_ENABLE:
475 case Dali::Layer::Property::CLIPPING_BOX:
482 DALI_LOG_WARNING( "Unknown property (%d)\n", index );
491 bool Layer::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
494 Layer* layer = dynamic_cast<Layer*>( object );
498 if( 0 == strcmp( actionName.c_str(), ACTION_RAISE ) )
503 else if( 0 == strcmp( actionName.c_str(), ACTION_LOWER ) )
508 else if( 0 == strcmp( actionName.c_str(), ACTION_RAISE_TO_TOP ) )
513 else if( 0 == strcmp( actionName.c_str(), ACTION_LOWER_TO_BOTTOM ) )
515 layer->LowerToBottom();
523 } // namespace Internal