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