Merge "Add cmake to the required system packages list in dali_env" into tizen
[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 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/object/type-registry.h>
27 #include <dali/internal/event/actors/layer-list.h>
28 #include <dali/internal/event/common/property-helper.h>
29 #include <dali/internal/event/common/stage-impl.h>
30
31 using Dali::Internal::SceneGraph::UpdateManager;
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38
39 namespace
40 {
41
42 // Properties
43
44 //              Name                Type      writable animatable constraint-input  enum for index-checking
45 DALI_PROPERTY_TABLE_BEGIN
46 DALI_PROPERTY( "clipping-enable",   BOOLEAN,    true,    false,   true,   Dali::Layer::Property::CLIPPING_ENABLE )
47 DALI_PROPERTY( "clipping-box",      RECTANGLE,  true,    false,   true,   Dali::Layer::Property::CLIPPING_BOX    )
48 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
49
50 // Actions
51
52 const char* const ACTION_RAISE =           "raise";
53 const char* const ACTION_LOWER =           "lower";
54 const char* const ACTION_RAISE_TO_TOP =    "raise-to-top";
55 const char* const ACTION_LOWER_TO_BOTTOM = "lower-to-bottom";
56
57 BaseHandle Create()
58 {
59   return Dali::Layer::New();
60 }
61
62 TypeRegistration mType( typeid( Dali::Layer ), typeid( Dali::Actor ), Create );
63
64 TypeAction a1( mType, ACTION_RAISE, &Layer::DoAction );
65 TypeAction a2( mType, ACTION_LOWER, &Layer::DoAction );
66 TypeAction a3( mType, ACTION_RAISE_TO_TOP, &Layer::DoAction );
67 TypeAction a4( mType, ACTION_LOWER_TO_BOTTOM, &Layer::DoAction );
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( 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   // root actor is immediately considered to be on-stage
93   root->mIsOnStage = true;
94
95   // The root actor will not emit a stage connection signal so set the signalled flag here as well
96   root->mOnStageSignalled = true;
97
98   // layer-list must be set for the root layer
99   root->mLayerList = &layerList;
100   layerList.RegisterLayer( *root );
101
102   return root;
103 }
104
105 Layer::Layer( Actor::DerivedType type )
106 : Actor( type ),
107   mLayerList(NULL),
108   mClippingBox(0,0,0,0),
109   mSortFunction(Dali::Layer::ZValue),
110   mIsClipping(false),
111   mDepthTestDisabled(false),
112   mTouchConsumed(false),
113   mHoverConsumed(false)
114 {
115   // Size negotiate disabled by default, so turn it on for this actor
116   SetRelayoutEnabled( true );
117 }
118
119 void Layer::OnInitialize()
120 {
121 }
122
123 Layer::~Layer()
124 {
125 }
126
127 unsigned int Layer::GetDepth() const
128 {
129   return mLayerList ? mLayerList->GetDepth( this ) : 0u;
130 }
131
132 void Layer::Raise()
133 {
134   if ( mLayerList )
135   {
136     mLayerList->RaiseLayer(*this);
137   }
138 }
139
140 void Layer::Lower()
141 {
142   if ( mLayerList )
143   {
144     mLayerList->LowerLayer(*this);
145   }
146 }
147
148 void Layer::RaiseAbove( const Internal::Layer& target )
149 {
150   // cannot raise above ourself, both have to be on stage
151   if( ( this != &target ) && OnStage() && target.OnStage() )
152   {
153     // get parameters depth
154     const unsigned int targetDepth = target.GetDepth();
155     if( GetDepth() < targetDepth )
156     {
157       MoveAbove( target );
158     }
159   }
160 }
161
162 void Layer::LowerBelow( const Internal::Layer& target )
163 {
164   // cannot lower below ourself, both have to be on stage
165   if( ( this != &target ) && OnStage() && target.OnStage() )
166   {
167     // get parameters depth
168     const unsigned int targetDepth = target.GetDepth();
169     if( GetDepth() > targetDepth )
170     {
171       MoveBelow( target );
172     }
173   }
174 }
175
176 void Layer::RaiseToTop()
177 {
178   if ( mLayerList )
179   {
180     mLayerList->RaiseLayerToTop(*this);
181   }
182 }
183
184 void Layer::LowerToBottom()
185 {
186   if ( mLayerList )
187   {
188     mLayerList->LowerLayerToBottom(*this);
189   }
190 }
191
192 void Layer::MoveAbove( const Internal::Layer& target )
193 {
194   // cannot raise above ourself, both have to be on stage
195   if( ( this != &target ) && mLayerList && target.OnStage() )
196   {
197     mLayerList->MoveLayerAbove(*this, target );
198   }
199 }
200
201 void Layer::MoveBelow( const Internal::Layer& target )
202 {
203   // cannot lower below ourself, both have to be on stage
204   if( ( this != &target ) && mLayerList && target.OnStage() )
205   {
206     mLayerList->MoveLayerBelow(*this, target );
207   }
208 }
209
210 void Layer::SetClipping(bool enabled)
211 {
212   if (enabled != mIsClipping)
213   {
214     mIsClipping = enabled;
215
216     // layerNode is being used in a separate thread; queue a message to set the value
217     SetClippingMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mIsClipping );
218   }
219 }
220
221 void Layer::SetClippingBox(int x, int y, int width, int height)
222 {
223   if( ( x != mClippingBox.x ) ||
224       ( y != mClippingBox.y ) ||
225       ( width != mClippingBox.width ) ||
226       ( height != mClippingBox.height ) )
227   {
228     // Clipping box is not animatable; this is the most up-to-date value
229     mClippingBox.Set(x, y, width, height);
230
231     // Convert mClippingBox to GL based coordinates (from bottom-left)
232     ClippingBox clippingBox( mClippingBox );
233     clippingBox.y = Stage::GetCurrent()->GetSize().height - clippingBox.y - clippingBox.height;
234
235     // layerNode is being used in a separate thread; queue a message to set the value
236     SetClippingBoxMessage( GetEventThreadServices(), GetSceneLayerOnStage(), clippingBox );
237   }
238 }
239
240 void Layer::SetDepthTestDisabled( bool disable )
241 {
242   if( disable != mDepthTestDisabled )
243   {
244     mDepthTestDisabled = disable;
245
246     // Send message .....
247     // layerNode is being used in a separate thread; queue a message to set the value
248     SetDepthTestDisabledMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mDepthTestDisabled );
249   }
250 }
251
252 bool Layer::IsDepthTestDisabled() const
253 {
254   return mDepthTestDisabled;
255 }
256
257 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
258 {
259   if( function != mSortFunction )
260   {
261     mSortFunction = function;
262
263     // layerNode is being used in a separate thread; queue a message to set the value
264     SetSortFunctionMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mSortFunction );
265   }
266 }
267
268 void Layer::SetTouchConsumed( bool consume )
269 {
270   mTouchConsumed = consume;
271 }
272
273 bool Layer::IsTouchConsumed() const
274 {
275   return mTouchConsumed;
276 }
277
278 void Layer::SetHoverConsumed( bool consume )
279 {
280   mHoverConsumed = consume;
281 }
282
283 bool Layer::IsHoverConsumed() const
284 {
285   return mHoverConsumed;
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_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_PROPERTY_COUNT );
338
339   int index = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
340   for ( int i = 0; i < DEFAULT_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
353   return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].writable;
354 }
355
356 bool Layer::IsDefaultPropertyAnimatable( Property::Index index ) const
357 {
358   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
359   {
360     return Actor::IsDefaultPropertyAnimatable( index );
361   }
362
363   return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].animatable;
364 }
365
366 bool Layer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
367 {
368   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
369   {
370     return Actor::IsDefaultPropertyAConstraintInput( index );
371   }
372
373   return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].constraintInput;
374 }
375
376 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
377 {
378   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
379   {
380     return Actor::GetDefaultPropertyType( index );
381   }
382
383   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
384
385   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
386   {
387     return DEFAULT_PROPERTY_DETAILS[index].type;
388   }
389
390   // index out-of-bounds
391   return Property::NONE;
392 }
393
394 const char* Layer::GetDefaultPropertyName( Property::Index index ) const
395 {
396   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
397   {
398     return Actor::GetDefaultPropertyName( index );
399   }
400
401   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
402   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
403   {
404     return DEFAULT_PROPERTY_DETAILS[index].name;
405   }
406
407   return NULL;
408 }
409
410 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
411 {
412   Property::Index index = Property::INVALID_INDEX;
413
414   // Look for name in current class' default properties
415   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
416   {
417     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[i];
418     if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
419     {
420       index = i + DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
421       break;
422     }
423   }
424   if( Property::INVALID_INDEX == index )
425   {
426     // If not found, check in base class
427     index = Actor::GetDefaultPropertyIndex( name );
428   }
429
430   return index;
431 }
432
433 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
434 {
435   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
436   {
437     Actor::SetDefaultProperty( index, propertyValue );
438   }
439   else
440   {
441     switch( index )
442     {
443       case Dali::Layer::Property::CLIPPING_ENABLE:
444       {
445         SetClipping( propertyValue.Get<bool>() );
446         break;
447       }
448       case Dali::Layer::Property::CLIPPING_BOX:
449       {
450         Rect<int> clippingBox( propertyValue.Get<Rect<int> >() );
451         SetClippingBox( clippingBox.x, clippingBox.y, clippingBox.width, clippingBox.height );
452         break;
453       }
454       default:
455       {
456         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
457         break;
458       }
459     } // switch(index)
460
461   } // else
462 }
463
464 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
465 {
466   Property::Value ret;
467   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
468   {
469     ret = Actor::GetDefaultProperty( index );
470   }
471   else
472   {
473     switch( index )
474     {
475       case Dali::Layer::Property::CLIPPING_ENABLE:
476       {
477         ret = mIsClipping;
478         break;
479       }
480       case Dali::Layer::Property::CLIPPING_BOX:
481       {
482         ret = mClippingBox;
483         break;
484       }
485       default:
486       {
487         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
488         break;
489       }
490     } // switch(index)
491   }
492
493   return ret;
494 }
495
496 bool Layer::DoAction( BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes )
497 {
498   bool done = false;
499   Layer* layer = dynamic_cast<Layer*>( object );
500
501   if( layer )
502   {
503     if( 0 == strcmp( actionName.c_str(), ACTION_RAISE ) )
504     {
505       layer->Raise();
506       done = true;
507     }
508     else if( 0 == strcmp( actionName.c_str(), ACTION_LOWER ) )
509     {
510       layer->Lower();
511       done = true;
512     }
513     else if( 0 == strcmp( actionName.c_str(), ACTION_RAISE_TO_TOP ) )
514     {
515       layer->RaiseToTop();
516       done = true;
517     }
518     else if( 0 == strcmp( actionName.c_str(), ACTION_LOWER_TO_BOTTOM ) )
519     {
520       layer->LowerToBottom();
521       done = true;
522     }
523   }
524
525   return done;
526 }
527
528 } // namespace Internal
529
530 } // namespace Dali