Add GetNaturalSize to Actor and deriving classes.
[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   mTouchConsumed(false)
116 {
117 }
118
119 void Layer::OnInitialize()
120 {
121   if(Layer::mFirstInstance)
122   {
123     mDefaultLayerPropertyLookup = new DefaultPropertyLookup();
124     const int start = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
125     for ( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i )
126     {
127       (*mDefaultLayerPropertyLookup)[DEFAULT_LAYER_PROPERTY_NAMES[i]] = i + start;
128     }
129     Layer::mFirstInstance = false;
130   }
131 }
132
133 Layer::~Layer()
134 {
135 }
136
137 unsigned int Layer::GetDepth() const
138 {
139   return mLayerList ? mLayerList->GetDepth( this ) : 0u;
140 }
141
142 void Layer::Raise()
143 {
144   if ( mLayerList )
145   {
146     mLayerList->RaiseLayer(*this);
147   }
148 }
149
150 void Layer::Lower()
151 {
152   if ( mLayerList )
153   {
154     mLayerList->LowerLayer(*this);
155   }
156 }
157
158 void Layer::RaiseAbove( const Internal::Layer& target )
159 {
160   // cannot raise above ourself, both have to be on stage
161   if( ( this != &target ) && OnStage() && target.OnStage() )
162   {
163     // get parameters depth
164     const unsigned int targetDepth = target.GetDepth();
165     if( GetDepth() < targetDepth )
166     {
167       MoveAbove( target );
168     }
169   }
170 }
171
172 void Layer::LowerBelow( const Internal::Layer& target )
173 {
174   // cannot lower below ourself, both have to be on stage
175   if( ( this != &target ) && OnStage() && target.OnStage() )
176   {
177     // get parameters depth
178     const unsigned int targetDepth = target.GetDepth();
179     if( GetDepth() > targetDepth )
180     {
181       MoveBelow( target );
182     }
183   }
184 }
185
186 void Layer::RaiseToTop()
187 {
188   if ( mLayerList )
189   {
190     mLayerList->RaiseLayerToTop(*this);
191   }
192 }
193
194 void Layer::LowerToBottom()
195 {
196   if ( mLayerList )
197   {
198     mLayerList->LowerLayerToBottom(*this);
199   }
200 }
201
202 void Layer::MoveAbove( const Internal::Layer& target )
203 {
204   // cannot raise above ourself, both have to be on stage
205   if( ( this != &target ) && mLayerList && target.OnStage() )
206   {
207     mLayerList->MoveLayerAbove(*this, target );
208   }
209 }
210
211 void Layer::MoveBelow( const Internal::Layer& target )
212 {
213   // cannot lower below ourself, both have to be on stage
214   if( ( this != &target ) && mLayerList && target.OnStage() )
215   {
216     mLayerList->MoveLayerBelow(*this, target );
217   }
218 }
219
220 void Layer::SetClipping(bool enabled)
221 {
222   if (enabled != mIsClipping)
223   {
224     mIsClipping = enabled;
225
226     // layerNode is being used in a separate thread; queue a message to set the value
227     SetClippingMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mIsClipping );
228   }
229 }
230
231 void Layer::SetClippingBox(int x, int y, int width, int height)
232 {
233   if( ( x != mClippingBox.x ) ||
234       ( y != mClippingBox.y ) ||
235       ( width != mClippingBox.width ) ||
236       ( height != mClippingBox.height ) )
237   {
238     // Clipping box is not animatable; this is the most up-to-date value
239     mClippingBox.Set(x, y, width, height);
240
241     // Convert mClippingBox to GL based coordinates (from bottom-left)
242     ClippingBox clippingBox( mClippingBox );
243     clippingBox.y = mStage->GetSize().height - clippingBox.y - clippingBox.height;
244
245     // layerNode is being used in a separate thread; queue a message to set the value
246     SetClippingBoxMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), clippingBox );
247   }
248 }
249
250 void Layer::SetDepthTestDisabled( bool disable )
251 {
252   if( disable != mDepthTestDisabled )
253   {
254     mDepthTestDisabled = disable;
255
256     // Send message .....
257     // layerNode is being used in a separate thread; queue a message to set the value
258     SetDepthTestDisabledMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mDepthTestDisabled );
259   }
260 }
261
262 bool Layer::IsDepthTestDisabled() const
263 {
264   return mDepthTestDisabled;
265 }
266
267 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
268 {
269   if( function != mSortFunction )
270   {
271     mSortFunction = function;
272
273     // layerNode is being used in a separate thread; queue a message to set the value
274     SetSortFunctionMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mSortFunction );
275   }
276 }
277
278 void Layer::SetTouchConsumed( bool consume )
279 {
280   mTouchConsumed = consume;
281 }
282
283 bool Layer::IsTouchConsumed() const
284 {
285   return mTouchConsumed;
286 }
287
288 SceneGraph::Node* Layer::CreateNode() const
289 {
290   return SceneGraph::Layer::New();
291 }
292
293 void Layer::OnStageConnectionInternal()
294 {
295   if ( !mIsRoot )
296   {
297     DALI_ASSERT_DEBUG( NULL == mLayerList );
298
299     // Find the ordered layer-list
300     // This is different for Layers added via Integration::GetSystemOverlay()
301     for ( Actor* parent = mParent; parent != NULL; parent = parent->GetParent() )
302     {
303       if( parent->IsLayer() )
304       {
305         Layer* parentLayer = static_cast< Layer* >( parent ); // cheaper than dynamic_cast
306         mLayerList = parentLayer->mLayerList;
307       }
308     }
309   }
310
311   DALI_ASSERT_DEBUG( NULL != mLayerList );
312   mLayerList->RegisterLayer( *this );
313 }
314
315 void Layer::OnStageDisconnectionInternal()
316 {
317   mLayerList->UnregisterLayer(*this);
318
319   // mLayerList is only valid when on-stage
320   mLayerList = NULL;
321 }
322
323 const SceneGraph::Layer& Layer::GetSceneLayerOnStage() const
324 {
325   DALI_ASSERT_DEBUG( mNode != NULL );
326   return dynamic_cast< const SceneGraph::Layer& >( *mNode );
327 }
328
329 unsigned int Layer::GetDefaultPropertyCount() const
330 {
331   return Actor::GetDefaultPropertyCount() + DEFAULT_LAYER_PROPERTY_COUNT;
332 }
333
334 void Layer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
335 {
336   Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
337   indices.reserve( indices.size() + DEFAULT_LAYER_PROPERTY_COUNT );
338
339   int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
340   for ( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i, ++index )
341   {
342     indices.push_back( index );
343   }
344 }
345
346 bool Layer::IsDefaultPropertyWritable( Property::Index index ) const
347 {
348   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
349   {
350     return Actor::IsDefaultPropertyWritable(index);
351   }
352   else
353   {
354     return true;
355   }
356 }
357
358 bool Layer::IsDefaultPropertyAnimatable( Property::Index index ) const
359 {
360   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
361   {
362     return Actor::IsDefaultPropertyAnimatable(index);
363   }
364   else
365   {
366     return false;
367   }
368 }
369
370 bool Layer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
371 {
372   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
373   {
374     return Actor::IsDefaultPropertyAConstraintInput(index);
375   }
376   return true; // our properties can be used as an input to a constraint
377 }
378
379 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
380 {
381   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
382   {
383     return Actor::GetDefaultPropertyType(index);
384   }
385   else
386   {
387     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
388
389     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
390     {
391       return DEFAULT_LAYER_PROPERTY_TYPES[index];
392     }
393     else
394     {
395       // index out-of-bounds
396       return Property::NONE;
397     }
398   }
399 }
400
401
402 const std::string& Layer::GetDefaultPropertyName( Property::Index index ) const
403 {
404   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
405   {
406     return Actor::GetDefaultPropertyName(index);
407   }
408   else
409   {
410     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
411
412     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
413     {
414       return DEFAULT_LAYER_PROPERTY_NAMES[index];
415     }
416     else
417     {
418       // index out-of-bounds
419       static const std::string INVALID_PROPERTY_NAME;
420       return INVALID_PROPERTY_NAME;
421     }
422   }
423 }
424
425 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
426 {
427   Property::Index index = Property::INVALID_INDEX;
428
429   DALI_ASSERT_DEBUG( NULL != mDefaultLayerPropertyLookup );
430
431   // Look for name in current class' default properties
432   DefaultPropertyLookup::const_iterator result = mDefaultLayerPropertyLookup->find( name );
433   if ( mDefaultLayerPropertyLookup->end() != result )
434   {
435     index = result->second;
436   }
437   else
438   {
439     // If not found, check in base class
440     index = Actor::GetDefaultPropertyIndex( name );
441   }
442
443   return index;
444 }
445
446 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
447 {
448   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
449   {
450     Actor::SetDefaultProperty(index, propertyValue);
451   }
452   else
453   {
454     switch(index)
455     {
456       case Dali::Layer::CLIPPING_ENABLE:
457       {
458         SetClipping( propertyValue.Get<bool>() );
459         break;
460       }
461       case Dali::Layer::CLIPPING_BOX:
462       {
463         Rect<int> clippingBox( propertyValue.Get<Rect<int> >() );
464         SetClippingBox( clippingBox.x, clippingBox.y, clippingBox.width, clippingBox.height );
465         break;
466       }
467       default:
468       {
469         DALI_LOG_WARNING("Unknown property (%d)\n", index);
470         break;
471       }
472     } // switch(index)
473
474   } // else
475 }
476
477 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
478 {
479   Property::Value ret;
480   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
481   {
482     ret = Actor::GetDefaultProperty(index);
483   }
484   else
485   {
486     switch(index)
487     {
488       case Dali::Layer::CLIPPING_ENABLE:
489       {
490         ret = mIsClipping;
491         break;
492       }
493       case Dali::Layer::CLIPPING_BOX:
494       {
495         ret = mClippingBox;
496         break;
497       }
498       default:
499       {
500         DALI_LOG_WARNING("Unknown property (%d)\n", index);
501         break;
502       }
503     } // switch(index)
504   }
505
506   return ret;
507 }
508
509 bool Layer::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
510 {
511   bool done = false;
512   Layer* layer = dynamic_cast<Layer*>(object);
513
514   if(layer)
515   {
516     if(Dali::Layer::ACTION_RAISE == actionName)
517     {
518       layer->Raise();
519       done = true;
520     }
521     else if(Dali::Layer::ACTION_LOWER == actionName)
522     {
523       layer->Lower();
524       done = true;
525     }
526     else if(Dali::Layer::ACTION_RAISE_TO_TOP == actionName)
527     {
528       layer->RaiseToTop();
529       done = true;
530     }
531     else if(Dali::Layer::ACTION_LOWER_TO_BOTTOM == actionName)
532     {
533       layer->LowerToBottom();
534       done = true;
535     }
536   }
537
538   return done;
539 }
540
541 } // namespace Internal
542
543 } // namespace Dali
544