Merge "Stop unnecessarily exporting BitmapPackedPixel and BitmapCompressed" into...
[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
23 // INTERNAL INCLUDES
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/internal/event/actors/layer-list.h>
27 #include <dali/internal/event/common/property-helper.h>
28 #include <dali/internal/event/common/stage-impl.h>
29
30 using Dali::Internal::SceneGraph::UpdateManager;
31
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace
39 {
40
41 // Properties
42
43 //              Name                Type      writable animatable constraint-input  enum for index-checking
44 DALI_PROPERTY_TABLE_BEGIN
45 DALI_PROPERTY( "clipping-enable",   BOOLEAN,    true,    false,   true,   Dali::Layer::Property::CLIPPING_ENABLE )
46 DALI_PROPERTY( "clipping-box",      RECTANGLE,  true,    false,   true,   Dali::Layer::Property::CLIPPING_BOX    )
47 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
48
49 // Actions
50
51 const char* const ACTION_RAISE =           "raise";
52 const char* const ACTION_LOWER =           "lower";
53 const char* const ACTION_RAISE_TO_TOP =    "raise-to-top";
54 const char* const ACTION_LOWER_TO_BOTTOM = "lower-to-bottom";
55
56 BaseHandle Create()
57 {
58   return Dali::Layer::New();
59 }
60
61 TypeRegistration mType( typeid( Dali::Layer ), typeid( Dali::Actor ), Create );
62
63 TypeAction a1( mType, ACTION_RAISE, &Layer::DoAction );
64 TypeAction a2( mType, ACTION_LOWER, &Layer::DoAction );
65 TypeAction a3( mType, ACTION_RAISE_TO_TOP, &Layer::DoAction );
66 TypeAction a4( mType, ACTION_LOWER_TO_BOTTOM, &Layer::DoAction );
67
68 } // unnamed namespace
69
70 LayerPtr Layer::New()
71 {
72   LayerPtr layer( new Layer( Actor::LAYER ) );
73
74   // Second-phase construction
75   layer->Initialize();
76
77   return layer;
78 }
79
80 LayerPtr Layer::NewRoot( LayerList& layerList, UpdateManager& manager, bool systemLevel )
81 {
82   LayerPtr root( new Layer( Actor::ROOT_LAYER ) );
83
84   // Second-phase construction
85   SceneGraph::Layer* layer = static_cast<SceneGraph::Layer*>( root->CreateNode() );
86   InstallRootMessage( manager, *layer, systemLevel ); // Transfer ownership to scene-graph
87
88   // Keep a raw pointer to the layer node.
89   root->mNode = layer;
90
91   // root actor is immediately considered to be on-stage
92   root->mIsOnStage = true;
93
94   // The root actor will not emit a stage connection signal so set the signalled flag here as well
95   root->mOnStageSignalled = true;
96
97   // layer-list must be set for the root layer
98   root->mLayerList = &layerList;
99   layerList.RegisterLayer( *root );
100
101   return root;
102 }
103
104 Layer::Layer( Actor::DerivedType type )
105 : Actor( type ),
106   mLayerList(NULL),
107   mClippingBox(0,0,0,0),
108   mSortFunction(Layer::ZValue),
109   mIsClipping(false),
110   mDepthTestDisabled(false),
111   mTouchConsumed(false),
112   mHoverConsumed(false)
113 {
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
231     StagePtr stage = Stage::GetCurrent();
232     if( stage )
233     {
234       clippingBox.y = stage->GetSize().height - clippingBox.y - clippingBox.height;
235
236       // layerNode is being used in a separate thread; queue a message to set the value
237       SetClippingBoxMessage( GetEventThreadServices(), GetSceneLayerOnStage(), clippingBox );
238     }
239   }
240 }
241
242 void Layer::SetDepthTestDisabled( bool disable )
243 {
244   if( disable != mDepthTestDisabled )
245   {
246     mDepthTestDisabled = disable;
247
248     // Send message .....
249     // layerNode is being used in a separate thread; queue a message to set the value
250     SetDepthTestDisabledMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mDepthTestDisabled );
251   }
252 }
253
254 bool Layer::IsDepthTestDisabled() const
255 {
256   return mDepthTestDisabled;
257 }
258
259 void Layer::SetSortFunction(Dali::Layer::SortFunctionType function)
260 {
261   if( function != mSortFunction )
262   {
263     mSortFunction = function;
264
265     // layerNode is being used in a separate thread; queue a message to set the value
266     SetSortFunctionMessage( GetEventThreadServices(), GetSceneLayerOnStage(), mSortFunction );
267   }
268 }
269
270 void Layer::SetTouchConsumed( bool consume )
271 {
272   mTouchConsumed = consume;
273 }
274
275 bool Layer::IsTouchConsumed() const
276 {
277   return mTouchConsumed;
278 }
279
280 void Layer::SetHoverConsumed( bool consume )
281 {
282   mHoverConsumed = consume;
283 }
284
285 bool Layer::IsHoverConsumed() const
286 {
287   return mHoverConsumed;
288 }
289
290 SceneGraph::Node* Layer::CreateNode() const
291 {
292   return SceneGraph::Layer::New();
293 }
294
295 void Layer::OnStageConnectionInternal()
296 {
297   if ( !mIsRoot )
298   {
299     DALI_ASSERT_DEBUG( NULL == mLayerList );
300
301     // Find the ordered layer-list
302     // This is different for Layers added via Integration::GetSystemOverlay()
303     for ( Actor* parent = mParent; parent != NULL; parent = parent->GetParent() )
304     {
305       if( parent->IsLayer() )
306       {
307         Layer* parentLayer = static_cast< Layer* >( parent ); // cheaper than dynamic_cast
308         mLayerList = parentLayer->mLayerList;
309       }
310     }
311   }
312
313   DALI_ASSERT_DEBUG( NULL != mLayerList );
314   mLayerList->RegisterLayer( *this );
315 }
316
317 void Layer::OnStageDisconnectionInternal()
318 {
319   mLayerList->UnregisterLayer(*this);
320
321   // mLayerList is only valid when on-stage
322   mLayerList = NULL;
323 }
324
325 const SceneGraph::Layer& Layer::GetSceneLayerOnStage() const
326 {
327   DALI_ASSERT_DEBUG( mNode != NULL );
328   return dynamic_cast< const SceneGraph::Layer& >( *mNode );
329 }
330
331 unsigned int Layer::GetDefaultPropertyCount() const
332 {
333   return Actor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT;
334 }
335
336 void Layer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
337 {
338   Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
339   indices.Reserve( indices.Size() + DEFAULT_PROPERTY_COUNT );
340
341   int index = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
342   for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
343   {
344     indices.PushBack( index );
345   }
346 }
347
348 bool Layer::IsDefaultPropertyWritable( Property::Index index ) const
349 {
350   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
351   {
352     return Actor::IsDefaultPropertyWritable( index );
353   }
354
355   return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].writable;
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
365   return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].animatable;
366 }
367
368 bool Layer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
369 {
370   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
371   {
372     return Actor::IsDefaultPropertyAConstraintInput( index );
373   }
374
375   return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].constraintInput;
376 }
377
378 Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
379 {
380   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
381   {
382     return Actor::GetDefaultPropertyType( index );
383   }
384
385   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
386
387   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
388   {
389     return DEFAULT_PROPERTY_DETAILS[index].type;
390   }
391
392   // index out-of-bounds
393   return Property::NONE;
394 }
395
396 const char* Layer::GetDefaultPropertyName( Property::Index index ) const
397 {
398   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
399   {
400     return Actor::GetDefaultPropertyName( index );
401   }
402
403   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
404   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
405   {
406     return DEFAULT_PROPERTY_DETAILS[index].name;
407   }
408
409   return NULL;
410 }
411
412 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
413 {
414   Property::Index index = Property::INVALID_INDEX;
415
416   // Look for name in current class' default properties
417   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
418   {
419     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[i];
420     if( 0 == name.compare( property->name ) ) // dont want to convert rhs to string
421     {
422       index = i + DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
423       break;
424     }
425   }
426   if( Property::INVALID_INDEX == index )
427   {
428     // If not found, check in base class
429     index = Actor::GetDefaultPropertyIndex( name );
430   }
431
432   return index;
433 }
434
435 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
436 {
437   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
438   {
439     Actor::SetDefaultProperty( index, propertyValue );
440   }
441   else
442   {
443     switch( index )
444     {
445       case Dali::Layer::Property::CLIPPING_ENABLE:
446       {
447         SetClipping( propertyValue.Get<bool>() );
448         break;
449       }
450       case Dali::Layer::Property::CLIPPING_BOX:
451       {
452         Rect<int> clippingBox( propertyValue.Get<Rect<int> >() );
453         SetClippingBox( clippingBox.x, clippingBox.y, clippingBox.width, clippingBox.height );
454         break;
455       }
456       default:
457       {
458         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
459         break;
460       }
461     } // switch(index)
462
463   } // else
464 }
465
466 Property::Value Layer::GetDefaultProperty( Property::Index index ) const
467 {
468   Property::Value ret;
469   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
470   {
471     ret = Actor::GetDefaultProperty( index );
472   }
473   else
474   {
475     switch( index )
476     {
477       case Dali::Layer::Property::CLIPPING_ENABLE:
478       {
479         ret = mIsClipping;
480         break;
481       }
482       case Dali::Layer::Property::CLIPPING_BOX:
483       {
484         ret = mClippingBox;
485         break;
486       }
487       default:
488       {
489         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
490         break;
491       }
492     } // switch(index)
493   }
494
495   return ret;
496 }
497
498 bool Layer::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /*attributes*/ )
499 {
500   bool done = false;
501   Layer* layer = dynamic_cast<Layer*>( object );
502
503   if( layer )
504   {
505     if( 0 == actionName.compare( ACTION_RAISE ) )
506     {
507       layer->Raise();
508       done = true;
509     }
510     else if( 0 == actionName.compare( ACTION_LOWER ) )
511     {
512       layer->Lower();
513       done = true;
514     }
515     else if( 0 == actionName.compare( ACTION_RAISE_TO_TOP ) )
516     {
517       layer->RaiseToTop();
518       done = true;
519     }
520     else if( 0 == actionName.compare( ACTION_LOWER_TO_BOTTOM ) )
521     {
522       layer->LowerToBottom();
523       done = true;
524     }
525   }
526
527   return done;
528 }
529
530 } // namespace Internal
531
532 } // namespace Dali