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