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/common/property-index-ranges.h>
25 #include <dali/internal/event/common/stage-impl.h>
26 #include <dali/internal/event/actors/layer-list.h>
28 using Dali::Internal::SceneGraph::UpdateManager;
33 const Property::Index Layer::CLIPPING_ENABLE = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
34 const Property::Index Layer::CLIPPING_BOX = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 1;
44 const char* const ACTION_RAISE = "raise";
45 const char* const ACTION_LOWER = "lower";
46 const char* const ACTION_RAISE_TO_TOP = "raise-to-top";
47 const char* const ACTION_LOWER_TO_BOTTOM = "lower-to-bottom";
51 return Dali::Layer::New();
54 TypeRegistration mType( typeid( Dali::Layer ), typeid( Dali::Actor ), Create );
56 TypeAction a1( mType, ACTION_RAISE, &Layer::DoAction );
57 TypeAction a2( mType, ACTION_LOWER, &Layer::DoAction );
58 TypeAction a3( mType, ACTION_RAISE_TO_TOP, &Layer::DoAction );
59 TypeAction a4( mType, ACTION_LOWER_TO_BOTTOM, &Layer::DoAction );
61 const PropertyDetails DEFAULT_PROPERTY_DETAILS[] =
63 // Name Type writable animatable constraint-input
64 { "clipping-enable", Property::BOOLEAN, true, false, true }, // CLIPPING_ENABLE
65 { "clipping-box", Property::RECTANGLE, true, false, true }, // CLIPPING_BOX
67 const int DEFAULT_LAYER_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( DEFAULT_PROPERTY_DETAILS[0] );
69 } // unnamed namespace
73 LayerPtr layer( new Layer( Actor::LAYER ) );
75 // Second-phase construction
81 LayerPtr Layer::NewRoot( Stage& stage, LayerList& layerList, UpdateManager& manager, bool systemLevel )
83 LayerPtr root( new Layer( Actor::ROOT_LAYER ) );
85 // Second-phase construction
86 SceneGraph::Layer* layer = static_cast<SceneGraph::Layer*>( root->CreateNode() );
87 InstallRootMessage( manager, *layer, systemLevel ); // Transfer ownership to scene-graph
89 // Keep a raw pointer to the layer node.
92 // stage must be set for the root layer
93 root->mStage = &stage;
95 // root actor is immediately considered to be on-stage
96 root->mIsOnStage = true;
98 // The root actor will not emit a stage connection signal so set the signalled flag here as well
99 root->mOnStageSignalled = true;
101 // layer-list must be set for the root layer
102 root->mLayerList = &layerList;
103 layerList.RegisterLayer( *root );
108 Layer::Layer( Actor::DerivedType type )
111 mClippingBox(0,0,0,0),
112 mSortFunction(Dali::Layer::ZValue),
114 mDepthTestDisabled(false),
115 mTouchConsumed(false),
116 mHoverConsumed(false)
120 void Layer::OnInitialize()
128 unsigned int Layer::GetDepth() const
130 return mLayerList ? mLayerList->GetDepth( this ) : 0u;
137 mLayerList->RaiseLayer(*this);
145 mLayerList->LowerLayer(*this);
149 void Layer::RaiseAbove( const Internal::Layer& target )
151 // cannot raise above ourself, both have to be on stage
152 if( ( this != &target ) && OnStage() && target.OnStage() )
154 // get parameters depth
155 const unsigned int targetDepth = target.GetDepth();
156 if( GetDepth() < targetDepth )
163 void Layer::LowerBelow( const Internal::Layer& target )
165 // cannot lower below ourself, both have to be on stage
166 if( ( this != &target ) && OnStage() && target.OnStage() )
168 // get parameters depth
169 const unsigned int targetDepth = target.GetDepth();
170 if( GetDepth() > targetDepth )
177 void Layer::RaiseToTop()
181 mLayerList->RaiseLayerToTop(*this);
185 void Layer::LowerToBottom()
189 mLayerList->LowerLayerToBottom(*this);
193 void Layer::MoveAbove( const Internal::Layer& target )
195 // cannot raise above ourself, both have to be on stage
196 if( ( this != &target ) && mLayerList && target.OnStage() )
198 mLayerList->MoveLayerAbove(*this, target );
202 void Layer::MoveBelow( const Internal::Layer& target )
204 // cannot lower below ourself, both have to be on stage
205 if( ( this != &target ) && mLayerList && target.OnStage() )
207 mLayerList->MoveLayerBelow(*this, target );
211 void Layer::SetClipping(bool enabled)
213 if (enabled != mIsClipping)
215 mIsClipping = enabled;
217 // layerNode is being used in a separate thread; queue a message to set the value
218 SetClippingMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mIsClipping );
222 void Layer::SetClippingBox(int x, int y, int width, int height)
224 if( ( x != mClippingBox.x ) ||
225 ( y != mClippingBox.y ) ||
226 ( width != mClippingBox.width ) ||
227 ( height != mClippingBox.height ) )
229 // Clipping box is not animatable; this is the most up-to-date value
230 mClippingBox.Set(x, y, width, height);
232 // Convert mClippingBox to GL based coordinates (from bottom-left)
233 ClippingBox clippingBox( mClippingBox );
234 clippingBox.y = mStage->GetSize().height - clippingBox.y - clippingBox.height;
236 // layerNode is being used in a separate thread; queue a message to set the value
237 SetClippingBoxMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), clippingBox );
241 void Layer::SetDepthTestDisabled( bool disable )
243 if( disable != mDepthTestDisabled )
245 mDepthTestDisabled = disable;
247 // Send message .....
248 // layerNode is being used in a separate thread; queue a message to set the value
249 SetDepthTestDisabledMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mDepthTestDisabled );
253 bool Layer::IsDepthTestDisabled() const
255 return mDepthTestDisabled;
258 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
260 if( function != mSortFunction )
262 mSortFunction = function;
264 // layerNode is being used in a separate thread; queue a message to set the value
265 SetSortFunctionMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mSortFunction );
269 void Layer::SetTouchConsumed( bool consume )
271 mTouchConsumed = consume;
274 bool Layer::IsTouchConsumed() const
276 return mTouchConsumed;
279 void Layer::SetHoverConsumed( bool consume )
281 mHoverConsumed = consume;
284 bool Layer::IsHoverConsumed() const
286 return mHoverConsumed;
289 SceneGraph::Node* Layer::CreateNode() const
291 return SceneGraph::Layer::New();
294 void Layer::OnStageConnectionInternal()
298 DALI_ASSERT_DEBUG( NULL == mLayerList );
300 // Find the ordered layer-list
301 // This is different for Layers added via Integration::GetSystemOverlay()
302 for ( Actor* parent = mParent; parent != NULL; parent = parent->GetParent() )
304 if( parent->IsLayer() )
306 Layer* parentLayer = static_cast< Layer* >( parent ); // cheaper than dynamic_cast
307 mLayerList = parentLayer->mLayerList;
312 DALI_ASSERT_DEBUG( NULL != mLayerList );
313 mLayerList->RegisterLayer( *this );
316 void Layer::OnStageDisconnectionInternal()
318 mLayerList->UnregisterLayer(*this);
320 // mLayerList is only valid when on-stage
324 const SceneGraph::Layer& Layer::GetSceneLayerOnStage() const
326 DALI_ASSERT_DEBUG( mNode != NULL );
327 return dynamic_cast< const SceneGraph::Layer& >( *mNode );
330 unsigned int Layer::GetDefaultPropertyCount() const
332 return Actor::GetDefaultPropertyCount() + DEFAULT_LAYER_PROPERTY_COUNT;
335 void Layer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
337 Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
338 indices.reserve( indices.size() + DEFAULT_LAYER_PROPERTY_COUNT );
340 int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
341 for ( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i, ++index )
343 indices.push_back( index );
347 bool Layer::IsDefaultPropertyWritable( Property::Index index ) const
349 if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
351 return Actor::IsDefaultPropertyWritable(index);
355 return true; // all properties writable, no need to lookup the table
359 bool Layer::IsDefaultPropertyAnimatable( Property::Index index ) const
361 if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
363 return Actor::IsDefaultPropertyAnimatable(index);
367 return false; // all properties non animateable, no need to lookup the table
371 bool Layer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
373 if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
375 return Actor::IsDefaultPropertyAConstraintInput(index);
377 return true; // our properties can be used as an input to a constraint, no need to lookup the table
380 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
382 if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
384 return Actor::GetDefaultPropertyType(index);
388 index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
390 if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
392 return DEFAULT_PROPERTY_DETAILS[index].type;
396 // index out-of-bounds
397 return Property::NONE;
402 const char* Layer::GetDefaultPropertyName( Property::Index index ) const
404 if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
406 return Actor::GetDefaultPropertyName(index);
410 index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
412 if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
414 return DEFAULT_PROPERTY_DETAILS[index].name;
423 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
425 Property::Index index = Property::INVALID_INDEX;
427 // Look for name in current class' default properties
428 for( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i )
430 const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
431 if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
433 index = i + DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
437 if( Property::INVALID_INDEX == index )
439 // If not found, check in base class
440 index = Actor::GetDefaultPropertyIndex( name );
446 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
448 if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
450 Actor::SetDefaultProperty(index, propertyValue);
456 case Dali::Layer::CLIPPING_ENABLE:
458 SetClipping( propertyValue.Get<bool>() );
461 case Dali::Layer::CLIPPING_BOX:
463 Rect<int> clippingBox( propertyValue.Get<Rect<int> >() );
464 SetClippingBox( clippingBox.x, clippingBox.y, clippingBox.width, clippingBox.height );
469 DALI_LOG_WARNING("Unknown property (%d)\n", index);
477 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
480 if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
482 ret = Actor::GetDefaultProperty(index);
488 case Dali::Layer::CLIPPING_ENABLE:
493 case Dali::Layer::CLIPPING_BOX:
500 DALI_LOG_WARNING("Unknown property (%d)\n", index);
509 bool Layer::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
512 Layer* layer = dynamic_cast<Layer*>( object );
516 if( 0 == strcmp( actionName.c_str(), ACTION_RAISE ) )
521 else if( 0 == strcmp( actionName.c_str(), ACTION_LOWER ) )
526 else if( 0 == strcmp( actionName.c_str(), ACTION_RAISE_TO_TOP ) )
531 else if( 0 == strcmp( actionName.c_str(), ACTION_LOWER_TO_BOTTOM ) )
533 layer->LowerToBottom();
541 } // namespace Internal