License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / layer-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 <dali/internal/event/actors/layer-impl.h>
20
21 // INTERNAL INCLUDES
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>
27
28 using Dali::Internal::SceneGraph::UpdateManager;
29
30 namespace Dali
31 {
32
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;
35
36 namespace Internal
37 {
38 bool Layer::mFirstInstance = true;
39 Actor::DefaultPropertyLookup* Layer::mDefaultLayerPropertyLookup = NULL;
40
41 namespace
42 {
43
44 BaseHandle Create()
45 {
46   return Dali::Layer::New();
47 }
48
49 TypeRegistration mType( typeid(Dali::Layer), typeid(Dali::Actor), Create );
50
51 TypeAction a1(mType, Dali::Layer::ACTION_RAISE, &Layer::DoAction);
52 TypeAction a2(mType, Dali::Layer::ACTION_LOWER, &Layer::DoAction);
53 TypeAction a3(mType, Dali::Layer::ACTION_RAISE_TO_TOP, &Layer::DoAction);
54 TypeAction a4(mType, Dali::Layer::ACTION_LOWER_TO_BOTTOM, &Layer::DoAction);
55
56 const std::string DEFAULT_LAYER_PROPERTY_NAMES[] =
57 {
58   "clipping-enable",
59   "clipping-box"
60 };
61 const int DEFAULT_LAYER_PROPERTY_COUNT = sizeof( DEFAULT_LAYER_PROPERTY_NAMES ) / sizeof( std::string );
62
63 const Property::Type DEFAULT_LAYER_PROPERTY_TYPES[DEFAULT_LAYER_PROPERTY_COUNT] =
64 {
65   Property::BOOLEAN,    // "clipping-enable",
66   Property::RECTANGLE,  // "clipping-box",
67 };
68
69 } // unnamed namespace
70
71 LayerPtr Layer::New()
72 {
73   LayerPtr layer( new Layer( Actor::LAYER ) );
74
75   // Second-phase construction
76   layer->Initialize();
77
78   return layer;
79 }
80
81 LayerPtr Layer::NewRoot( Stage& stage, LayerList& layerList, UpdateManager& manager, bool systemLevel )
82 {
83   LayerPtr root( new Layer( Actor::ROOT_LAYER ) );
84
85   // Second-phase construction
86   SceneGraph::Layer* layer = static_cast<SceneGraph::Layer*>( root->CreateNode() );
87   InstallRootMessage( manager, *layer, systemLevel ); // Transfer ownership to scene-graph
88
89   // Keep a raw pointer to the layer node.
90   root->mNode = layer;
91
92   // stage must be set for the root layer
93   root->mStage = &stage;
94
95   // root actor is immediately considered to be on-stage
96   root->mIsOnStage = true;
97
98   // The root actor will not emit a stage connection signal so set the signalled flag here as well
99   root->mOnStageSignalled = true;
100
101   // layer-list must be set for the root layer
102   root->mLayerList = &layerList;
103   layerList.RegisterLayer( *root );
104
105   return root;
106 }
107
108 Layer::Layer( Actor::DerivedType type )
109 : Actor( type ),
110   mLayerList(NULL),
111   mClippingBox(0,0,0,0),
112   mSortFunction(Dali::Layer::ZValue),
113   mIsClipping(false),
114   mDepthTestDisabled(false)
115 {
116 }
117
118 void Layer::OnInitialize()
119 {
120   if(Layer::mFirstInstance)
121   {
122     mDefaultLayerPropertyLookup = new DefaultPropertyLookup();
123     const int start = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
124     for ( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i )
125     {
126       (*mDefaultLayerPropertyLookup)[DEFAULT_LAYER_PROPERTY_NAMES[i]] = i + start;
127     }
128     Layer::mFirstInstance = false;
129   }
130 }
131
132 Layer::~Layer()
133 {
134 }
135
136 unsigned int Layer::GetDepth() const
137 {
138   return mLayerList ? mLayerList->GetDepth( this ) : 0u;
139 }
140
141 void Layer::Raise()
142 {
143   if ( mLayerList )
144   {
145     mLayerList->RaiseLayer(*this);
146   }
147 }
148
149 void Layer::Lower()
150 {
151   if ( mLayerList )
152   {
153     mLayerList->LowerLayer(*this);
154   }
155 }
156
157 void Layer::RaiseAbove( const Internal::Layer& target )
158 {
159   // cannot raise above ourself, both have to be on stage
160   if( ( this != &target ) && OnStage() && target.OnStage() )
161   {
162     // get parameters depth
163     const unsigned int targetDepth = target.GetDepth();
164     if( GetDepth() < targetDepth )
165     {
166       MoveAbove( target );
167     }
168   }
169 }
170
171 void Layer::LowerBelow( const Internal::Layer& target )
172 {
173   // cannot lower below ourself, both have to be on stage
174   if( ( this != &target ) && OnStage() && target.OnStage() )
175   {
176     // get parameters depth
177     const unsigned int targetDepth = target.GetDepth();
178     if( GetDepth() > targetDepth )
179     {
180       MoveBelow( target );
181     }
182   }
183 }
184
185 void Layer::RaiseToTop()
186 {
187   if ( mLayerList )
188   {
189     mLayerList->RaiseLayerToTop(*this);
190   }
191 }
192
193 void Layer::LowerToBottom()
194 {
195   if ( mLayerList )
196   {
197     mLayerList->LowerLayerToBottom(*this);
198   }
199 }
200
201 void Layer::MoveAbove( const Internal::Layer& target )
202 {
203   // cannot raise above ourself, both have to be on stage
204   if( ( this != &target ) && mLayerList && target.OnStage() )
205   {
206     mLayerList->MoveLayerAbove(*this, target );
207   }
208 }
209
210 void Layer::MoveBelow( const Internal::Layer& target )
211 {
212   // cannot lower below ourself, both have to be on stage
213   if( ( this != &target ) && mLayerList && target.OnStage() )
214   {
215     mLayerList->MoveLayerBelow(*this, target );
216   }
217 }
218
219 void Layer::SetClipping(bool enabled)
220 {
221   if (enabled != mIsClipping)
222   {
223     mIsClipping = enabled;
224
225     // layerNode is being used in a separate thread; queue a message to set the value
226     SetClippingMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mIsClipping );
227   }
228 }
229
230 void Layer::SetClippingBox(int x, int y, int width, int height)
231 {
232   if( ( x != mClippingBox.x ) ||
233       ( y != mClippingBox.y ) ||
234       ( width != mClippingBox.width ) ||
235       ( height != mClippingBox.height ) )
236   {
237     // Clipping box is not animatable; this is the most up-to-date value
238     mClippingBox.Set(x, y, width, height);
239
240     // layerNode is being used in a separate thread; queue a message to set the value
241     SetClippingBoxMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mClippingBox );
242   }
243 }
244
245 void Layer::SetDepthTestDisabled( bool disable )
246 {
247   if( disable != mDepthTestDisabled )
248   {
249     mDepthTestDisabled = disable;
250
251     // Send message .....
252     // layerNode is being used in a separate thread; queue a message to set the value
253     SetDepthTestDisabledMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mDepthTestDisabled );
254   }
255 }
256
257 bool Layer::IsDepthTestDisabled() const
258 {
259   return mDepthTestDisabled;
260 }
261
262 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
263 {
264   if( function != mSortFunction )
265   {
266     mSortFunction = function;
267
268     // layerNode is being used in a separate thread; queue a message to set the value
269     SetSortFunctionMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mSortFunction );
270   }
271 }
272
273 SceneGraph::Node* Layer::CreateNode() const
274 {
275   return SceneGraph::Layer::New();
276 }
277
278 void Layer::OnStageConnectionInternal()
279 {
280   if ( !mIsRoot )
281   {
282     DALI_ASSERT_DEBUG( NULL == mLayerList );
283
284     // Find the ordered layer-list
285     // This is different for Layers added via Integration::GetSystemOverlay()
286     for ( Actor* parent = mParent; parent != NULL; parent = parent->GetParent() )
287     {
288       if( parent->IsLayer() )
289       {
290         Layer* parentLayer = static_cast< Layer* >( parent ); // cheaper than dynamic_cast
291         mLayerList = parentLayer->mLayerList;
292       }
293     }
294   }
295
296   DALI_ASSERT_DEBUG( NULL != mLayerList );
297   mLayerList->RegisterLayer( *this );
298 }
299
300 void Layer::OnStageDisconnectionInternal()
301 {
302   mLayerList->UnregisterLayer(*this);
303
304   // mLayerList is only valid when on-stage
305   mLayerList = NULL;
306 }
307
308 const SceneGraph::Layer& Layer::GetSceneLayerOnStage() const
309 {
310   DALI_ASSERT_DEBUG( mNode != NULL );
311   return dynamic_cast< const SceneGraph::Layer& >( *mNode );
312 }
313
314 unsigned int Layer::GetDefaultPropertyCount() const
315 {
316   return Actor::GetDefaultPropertyCount() + DEFAULT_LAYER_PROPERTY_COUNT;
317 }
318
319 void Layer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
320 {
321   Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
322   indices.reserve( indices.size() + DEFAULT_LAYER_PROPERTY_COUNT );
323
324   int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
325   for ( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i, ++index )
326   {
327     indices.push_back( index );
328   }
329 }
330
331 bool Layer::IsDefaultPropertyWritable( Property::Index index ) const
332 {
333   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
334   {
335     return Actor::IsDefaultPropertyWritable(index);
336   }
337   else
338   {
339     return true;
340   }
341 }
342
343 bool Layer::IsDefaultPropertyAnimatable( Property::Index index ) const
344 {
345   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
346   {
347     return Actor::IsDefaultPropertyAnimatable(index);
348   }
349   else
350   {
351     return false;
352   }
353 }
354
355 bool Layer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
356 {
357   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
358   {
359     return Actor::IsDefaultPropertyAConstraintInput(index);
360   }
361   return true; // our properties can be used as an input to a constraint
362 }
363
364 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
365 {
366   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
367   {
368     return Actor::GetDefaultPropertyType(index);
369   }
370   else
371   {
372     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
373
374     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
375     {
376       return DEFAULT_LAYER_PROPERTY_TYPES[index];
377     }
378     else
379     {
380       // index out-of-bounds
381       return Property::NONE;
382     }
383   }
384 }
385
386
387 const std::string& Layer::GetDefaultPropertyName( Property::Index index ) const
388 {
389   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
390   {
391     return Actor::GetDefaultPropertyName(index);
392   }
393   else
394   {
395     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
396
397     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
398     {
399       return DEFAULT_LAYER_PROPERTY_NAMES[index];
400     }
401     else
402     {
403       // index out-of-bounds
404       static const std::string INVALID_PROPERTY_NAME;
405       return INVALID_PROPERTY_NAME;
406     }
407   }
408 }
409
410 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
411 {
412   Property::Index index = Property::INVALID_INDEX;
413
414   DALI_ASSERT_DEBUG( NULL != mDefaultLayerPropertyLookup );
415
416   // Look for name in current class' default properties
417   DefaultPropertyLookup::const_iterator result = mDefaultLayerPropertyLookup->find( name );
418   if ( mDefaultLayerPropertyLookup->end() != result )
419   {
420     index = result->second;
421   }
422   else
423   {
424     // If not found, check in base class
425     index = Actor::GetDefaultPropertyIndex( name );
426   }
427
428   return index;
429 }
430
431 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
432 {
433   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
434   {
435     Actor::SetDefaultProperty(index, propertyValue);
436   }
437   else
438   {
439     switch(index)
440     {
441       case Dali::Layer::CLIPPING_ENABLE:
442       {
443         mIsClipping = propertyValue.Get<bool>();
444         break;
445       }
446       case Dali::Layer::CLIPPING_BOX:
447       {
448         mClippingBox = propertyValue.Get<Rect<int> >();
449         break;
450       }
451       default:
452       {
453         DALI_LOG_WARNING("Unknown property (%d)\n", index);
454         break;
455       }
456     } // switch(index)
457
458   } // else
459 }
460
461 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
462 {
463   Property::Value ret;
464   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
465   {
466     ret = Actor::GetDefaultProperty(index);
467   }
468   else
469   {
470     switch(index)
471     {
472       case Dali::Layer::CLIPPING_ENABLE:
473       {
474         ret = mIsClipping;
475         break;
476       }
477       case Dali::Layer::CLIPPING_BOX:
478       {
479         ret = mClippingBox;
480         break;
481       }
482       default:
483       {
484         DALI_LOG_WARNING("Unknown property (%d)\n", index);
485         break;
486       }
487     } // switch(index)
488   }
489
490   return ret;
491 }
492
493 bool Layer::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
494 {
495   bool done = false;
496   Layer* layer = dynamic_cast<Layer*>(object);
497
498   if(layer)
499   {
500     if(Dali::Layer::ACTION_RAISE == actionName)
501     {
502       layer->Raise();
503       done = true;
504     }
505     else if(Dali::Layer::ACTION_LOWER == actionName)
506     {
507       layer->Lower();
508       done = true;
509     }
510     else if(Dali::Layer::ACTION_RAISE_TO_TOP == actionName)
511     {
512       layer->RaiseToTop();
513       done = true;
514     }
515     else if(Dali::Layer::ACTION_LOWER_TO_BOTTOM == actionName)
516     {
517       layer->LowerToBottom();
518       done = true;
519     }
520   }
521
522   return done;
523 }
524
525 } // namespace Internal
526
527 } // namespace Dali
528