(HitTest) Added API to layer so that it can consume all touch if required
[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     // layerNode is being used in a separate thread; queue a message to set the value
242     SetClippingBoxMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mClippingBox );
243   }
244 }
245
246 void Layer::SetDepthTestDisabled( bool disable )
247 {
248   if( disable != mDepthTestDisabled )
249   {
250     mDepthTestDisabled = disable;
251
252     // Send message .....
253     // layerNode is being used in a separate thread; queue a message to set the value
254     SetDepthTestDisabledMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mDepthTestDisabled );
255   }
256 }
257
258 bool Layer::IsDepthTestDisabled() const
259 {
260   return mDepthTestDisabled;
261 }
262
263 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
264 {
265   if( function != mSortFunction )
266   {
267     mSortFunction = function;
268
269     // layerNode is being used in a separate thread; queue a message to set the value
270     SetSortFunctionMessage( mStage->GetUpdateInterface(), GetSceneLayerOnStage(), mSortFunction );
271   }
272 }
273
274 void Layer::SetTouchConsumed( bool consume )
275 {
276   mTouchConsumed = consume;
277 }
278
279 bool Layer::IsTouchConsumed() const
280 {
281   return mTouchConsumed;
282 }
283
284 SceneGraph::Node* Layer::CreateNode() const
285 {
286   return SceneGraph::Layer::New();
287 }
288
289 void Layer::OnStageConnectionInternal()
290 {
291   if ( !mIsRoot )
292   {
293     DALI_ASSERT_DEBUG( NULL == mLayerList );
294
295     // Find the ordered layer-list
296     // This is different for Layers added via Integration::GetSystemOverlay()
297     for ( Actor* parent = mParent; parent != NULL; parent = parent->GetParent() )
298     {
299       if( parent->IsLayer() )
300       {
301         Layer* parentLayer = static_cast< Layer* >( parent ); // cheaper than dynamic_cast
302         mLayerList = parentLayer->mLayerList;
303       }
304     }
305   }
306
307   DALI_ASSERT_DEBUG( NULL != mLayerList );
308   mLayerList->RegisterLayer( *this );
309 }
310
311 void Layer::OnStageDisconnectionInternal()
312 {
313   mLayerList->UnregisterLayer(*this);
314
315   // mLayerList is only valid when on-stage
316   mLayerList = NULL;
317 }
318
319 const SceneGraph::Layer& Layer::GetSceneLayerOnStage() const
320 {
321   DALI_ASSERT_DEBUG( mNode != NULL );
322   return dynamic_cast< const SceneGraph::Layer& >( *mNode );
323 }
324
325 unsigned int Layer::GetDefaultPropertyCount() const
326 {
327   return Actor::GetDefaultPropertyCount() + DEFAULT_LAYER_PROPERTY_COUNT;
328 }
329
330 void Layer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
331 {
332   Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
333   indices.reserve( indices.size() + DEFAULT_LAYER_PROPERTY_COUNT );
334
335   int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
336   for ( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i, ++index )
337   {
338     indices.push_back( index );
339   }
340 }
341
342 bool Layer::IsDefaultPropertyWritable( Property::Index index ) const
343 {
344   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
345   {
346     return Actor::IsDefaultPropertyWritable(index);
347   }
348   else
349   {
350     return true;
351   }
352 }
353
354 bool Layer::IsDefaultPropertyAnimatable( Property::Index index ) const
355 {
356   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
357   {
358     return Actor::IsDefaultPropertyAnimatable(index);
359   }
360   else
361   {
362     return false;
363   }
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   return true; // our properties can be used as an input to a constraint
373 }
374
375 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
376 {
377   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
378   {
379     return Actor::GetDefaultPropertyType(index);
380   }
381   else
382   {
383     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
384
385     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
386     {
387       return DEFAULT_LAYER_PROPERTY_TYPES[index];
388     }
389     else
390     {
391       // index out-of-bounds
392       return Property::NONE;
393     }
394   }
395 }
396
397
398 const std::string& Layer::GetDefaultPropertyName( Property::Index index ) const
399 {
400   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
401   {
402     return Actor::GetDefaultPropertyName(index);
403   }
404   else
405   {
406     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
407
408     if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
409     {
410       return DEFAULT_LAYER_PROPERTY_NAMES[index];
411     }
412     else
413     {
414       // index out-of-bounds
415       static const std::string INVALID_PROPERTY_NAME;
416       return INVALID_PROPERTY_NAME;
417     }
418   }
419 }
420
421 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
422 {
423   Property::Index index = Property::INVALID_INDEX;
424
425   DALI_ASSERT_DEBUG( NULL != mDefaultLayerPropertyLookup );
426
427   // Look for name in current class' default properties
428   DefaultPropertyLookup::const_iterator result = mDefaultLayerPropertyLookup->find( name );
429   if ( mDefaultLayerPropertyLookup->end() != result )
430   {
431     index = result->second;
432   }
433   else
434   {
435     // If not found, check in base class
436     index = Actor::GetDefaultPropertyIndex( name );
437   }
438
439   return index;
440 }
441
442 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
443 {
444   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
445   {
446     Actor::SetDefaultProperty(index, propertyValue);
447   }
448   else
449   {
450     switch(index)
451     {
452       case Dali::Layer::CLIPPING_ENABLE:
453       {
454         mIsClipping = propertyValue.Get<bool>();
455         break;
456       }
457       case Dali::Layer::CLIPPING_BOX:
458       {
459         mClippingBox = propertyValue.Get<Rect<int> >();
460         break;
461       }
462       default:
463       {
464         DALI_LOG_WARNING("Unknown property (%d)\n", index);
465         break;
466       }
467     } // switch(index)
468
469   } // else
470 }
471
472 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
473 {
474   Property::Value ret;
475   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
476   {
477     ret = Actor::GetDefaultProperty(index);
478   }
479   else
480   {
481     switch(index)
482     {
483       case Dali::Layer::CLIPPING_ENABLE:
484       {
485         ret = mIsClipping;
486         break;
487       }
488       case Dali::Layer::CLIPPING_BOX:
489       {
490         ret = mClippingBox;
491         break;
492       }
493       default:
494       {
495         DALI_LOG_WARNING("Unknown property (%d)\n", index);
496         break;
497       }
498     } // switch(index)
499   }
500
501   return ret;
502 }
503
504 bool Layer::DoAction(BaseObject* object, const std::string& actionName, const std::vector<Property::Value>& attributes)
505 {
506   bool done = false;
507   Layer* layer = dynamic_cast<Layer*>(object);
508
509   if(layer)
510   {
511     if(Dali::Layer::ACTION_RAISE == actionName)
512     {
513       layer->Raise();
514       done = true;
515     }
516     else if(Dali::Layer::ACTION_LOWER == actionName)
517     {
518       layer->Lower();
519       done = true;
520     }
521     else if(Dali::Layer::ACTION_RAISE_TO_TOP == actionName)
522     {
523       layer->RaiseToTop();
524       done = true;
525     }
526     else if(Dali::Layer::ACTION_LOWER_TO_BOTTOM == actionName)
527     {
528       layer->LowerToBottom();
529       done = true;
530     }
531   }
532
533   return done;
534 }
535
536 } // namespace Internal
537
538 } // namespace Dali
539