(Properties) Added ability to add non-animatable event-thread only properties via...
[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 Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/event/actors/layer-impl.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/public-api/common/dali-common.h>
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/internal/event/common/property-index-ranges.h>
24 #include <dali/internal/event/common/stage-impl.h>
25 #include <dali/internal/event/actors/layer-list.h>
26
27 using Dali::Internal::SceneGraph::UpdateManager;
28
29 namespace Dali
30 {
31
32 const Property::Index Layer::CLIPPING_ENABLE = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
33 const Property::Index Layer::CLIPPING_BOX    = DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 1;
34
35 namespace Internal
36 {
37 bool Layer::mFirstInstance = true;
38 Actor::DefaultPropertyLookup* Layer::mDefaultLayerPropertyLookup = NULL;
39
40 namespace
41 {
42
43 BaseHandle Create()
44 {
45   return Dali::Layer::New();
46 }
47
48 TypeRegistration mType( typeid(Dali::Layer), typeid(Dali::Actor), Create );
49
50 TypeAction a1(mType, Dali::Layer::ACTION_RAISE, &Layer::DoAction);
51 TypeAction a2(mType, Dali::Layer::ACTION_LOWER, &Layer::DoAction);
52 TypeAction a3(mType, Dali::Layer::ACTION_RAISE_TO_TOP, &Layer::DoAction);
53 TypeAction a4(mType, Dali::Layer::ACTION_LOWER_TO_BOTTOM, &Layer::DoAction);
54
55 const std::string DEFAULT_LAYER_PROPERTY_NAMES[] =
56 {
57   "clipping-enable",
58   "clipping-box"
59 };
60 const int DEFAULT_LAYER_PROPERTY_COUNT = sizeof( DEFAULT_LAYER_PROPERTY_NAMES ) / sizeof( std::string );
61
62 const Property::Type DEFAULT_LAYER_PROPERTY_TYPES[DEFAULT_LAYER_PROPERTY_COUNT] =
63 {
64   Property::BOOLEAN,    // "clipping-enable",
65   Property::RECTANGLE,  // "clipping-box",
66 };
67
68 } // unnamed namespace
69
70 LayerPtr Layer::New()
71 {
72   LayerPtr layer( new Layer( Actor::LAYER ) );
73
74   // Second-phase construction
75   layer->Initialize();
76
77   return layer;
78 }
79
80 LayerPtr Layer::NewRoot( Stage& stage, LayerList& layerList, UpdateManager& manager, bool systemLevel )
81 {
82   LayerPtr root( new Layer( Actor::ROOT_LAYER ) );
83
84   // Second-phase construction
85   SceneGraph::Layer* layer = static_cast<SceneGraph::Layer*>( root->CreateNode() );
86   InstallRootMessage( manager, *layer, systemLevel ); // Transfer ownership to scene-graph
87
88   // Keep a raw pointer to the layer node.
89   root->mNode = layer;
90
91   // stage must be set for the root layer
92   root->mStage = &stage;
93
94   // root actor is immediately considered to be on-stage
95   root->mIsOnStage = true;
96
97   // The root actor will not emit a stage connection signal so set the signalled flag here as well
98   root->mOnStageSignalled = true;
99
100   // layer-list must be set for the root layer
101   root->mLayerList = &layerList;
102   layerList.RegisterLayer( *root );
103
104   return root;
105 }
106
107 Layer::Layer( Actor::DerivedType type )
108 : Actor( type ),
109   mLayerList(NULL),
110   mClippingBox(0,0,0,0),
111   mSortFunction(Dali::Layer::ZValue),
112   mRenderOffscreen(false),
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 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
356 {
357   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
358   {
359     return Actor::GetDefaultPropertyType(index);
360   }
361   else
362   {
363     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
364
365     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
366     {
367       return DEFAULT_LAYER_PROPERTY_TYPES[index];
368     }
369     else
370     {
371       // index out-of-bounds
372       return Property::NONE;
373     }
374   }
375 }
376
377
378 const std::string& Layer::GetDefaultPropertyName( Property::Index index ) const
379 {
380   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
381   {
382     return Actor::GetDefaultPropertyName(index);
383   }
384   else
385   {
386     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
387
388     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
389     {
390       return DEFAULT_LAYER_PROPERTY_NAMES[index];
391     }
392     else
393     {
394       // index out-of-bounds
395       static const std::string INVALID_PROPERTY_NAME;
396       return INVALID_PROPERTY_NAME;
397     }
398   }
399 }
400
401 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
402 {
403   Property::Index index = Property::INVALID_INDEX;
404
405   DALI_ASSERT_DEBUG( NULL != mDefaultLayerPropertyLookup );
406
407   // Look for name in current class' default properties
408   DefaultPropertyLookup::const_iterator result = mDefaultLayerPropertyLookup->find( name );
409   if ( mDefaultLayerPropertyLookup->end() != result )
410   {
411     index = result->second;
412   }
413   else
414   {
415     // If not found, check in base class
416     index = Actor::GetDefaultPropertyIndex( name );
417   }
418
419   return index;
420 }
421
422 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
423 {
424   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
425   {
426     Actor::SetDefaultProperty(index, propertyValue);
427   }
428   else
429   {
430     switch(index)
431     {
432       case Dali::Layer::CLIPPING_ENABLE:
433       {
434         mIsClipping = propertyValue.Get<bool>();
435         break;
436       }
437       case Dali::Layer::CLIPPING_BOX:
438       {
439         mClippingBox = propertyValue.Get<Rect<int> >();
440         break;
441       }
442       default:
443       {
444         DALI_LOG_WARNING("Unknown property (%d)\n", index);
445         break;
446       }
447     } // switch(index)
448
449   } // else
450 }
451
452 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
453 {
454   Property::Value ret;
455   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
456   {
457     ret = Actor::GetDefaultProperty(index);
458   }
459   else
460   {
461     switch(index)
462     {
463       case Dali::Layer::CLIPPING_ENABLE:
464       {
465         ret = mIsClipping;
466         break;
467       }
468       case Dali::Layer::CLIPPING_BOX:
469       {
470         ret = mClippingBox;
471         break;
472       }
473       default:
474       {
475         DALI_LOG_WARNING("Unknown property (%d)\n", index);
476         break;
477       }
478     } // switch(index)
479   }
480
481   return ret;
482 }
483
484 bool Layer::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
485 {
486   bool done = false;
487   Layer* layer = dynamic_cast<Layer*>(object);
488
489   if(layer)
490   {
491     if(Dali::Layer::ACTION_RAISE == actionName)
492     {
493       layer->Raise();
494       done = true;
495     }
496     else if(Dali::Layer::ACTION_LOWER == actionName)
497     {
498       layer->Lower();
499       done = true;
500     }
501     else if(Dali::Layer::ACTION_RAISE_TO_TOP == actionName)
502     {
503       layer->RaiseToTop();
504       done = true;
505     }
506     else if(Dali::Layer::ACTION_LOWER_TO_BOTTOM == actionName)
507     {
508       layer->LowerToBottom();
509       done = true;
510     }
511   }
512
513   return done;
514 }
515
516 } // namespace Internal
517
518 } // namespace Dali
519