Dali 3D User Interface Engine
layer-impl.cpp
Go to the documentation of this file.
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
20 
21 // EXTERNAL INCLUDES
22 
23 // INTERNAL INCLUDES
30 
32 
33 namespace Dali
34 {
35 
36 namespace
37 {
38 
40 
43 DALI_ENUM_TO_STRING_INSIDE_CLASS( Layer, LAYER_3D )
45 
46 } // namespace
47 
48 namespace Internal
49 {
50 
51 namespace
52 {
53 
54 // Properties
55 
56 // Name Type writable animatable constraint-input enum for index-checking
58 DALI_PROPERTY( "clippingEnable", BOOLEAN, true, false, true, Dali::Layer::Property::CLIPPING_ENABLE )
59 DALI_PROPERTY( "clippingBox", RECTANGLE, true, false, true, Dali::Layer::Property::CLIPPING_BOX )
60 DALI_PROPERTY( "behavior", STRING, true, false, false, Dali::Layer::Property::BEHAVIOR )
62 
63 // Actions
64 
65 const char* const ACTION_RAISE = "raise";
66 const char* const ACTION_LOWER = "lower";
67 const char* const ACTION_RAISE_TO_TOP = "raiseToTop";
68 const char* const ACTION_LOWER_TO_BOTTOM = "lowerToBottom";
69 
71 {
72  return Dali::Layer::New();
73 }
74 
75 TypeRegistration mType( typeid( Dali::Layer ), typeid( Dali::Actor ), Create );
76 
81 
82 } // unnamed namespace
83 
84 
86 {
87  LayerPtr layer( new Layer( Actor::LAYER ) );
88 
89  // Second-phase construction
90  layer->Initialize();
91 
92  return layer;
93 }
94 
95 LayerPtr Layer::NewRoot( LayerList& layerList, UpdateManager& manager, bool systemLevel )
96 {
97  LayerPtr root( new Layer( Actor::ROOT_LAYER ) );
98 
99  // Second-phase construction
100  SceneGraph::Layer* layer = static_cast<SceneGraph::Layer*>( root->CreateNode() );
101  InstallRootMessage( manager, *layer, systemLevel ); // Transfer ownership to scene-graph
102 
103  // Keep a raw pointer to the layer node.
104  root->mNode = layer;
105 
106  // root actor is immediately considered to be on-stage
107  root->mIsOnStage = true;
108 
109  // The root actor will not emit a stage connection signal so set the signalled flag here as well
110  root->mOnStageSignalled = true;
111 
112  // layer-list must be set for the root layer
113  root->mLayerList = &layerList;
114  layerList.RegisterLayer( *root );
115 
116  return root;
117 }
118 
120 : Actor( type ),
121  mLayerList(NULL),
122  mClippingBox(0,0,0,0),
123  mSortFunction(Layer::ZValue),
124  mBehavior(Dali::Layer::LAYER_2D),
125  mIsClipping(false),
126  mDepthTestDisabled(false),
127  mTouchConsumed(false),
128  mHoverConsumed(false)
129 {
130 }
131 
133 {
134 }
135 
137 {
138 }
139 
140 unsigned int Layer::GetDepth() const
141 {
142  return mLayerList ? mLayerList->GetDepth( this ) : 0u;
143 }
144 
146 {
147  if ( mLayerList )
148  {
149  mLayerList->RaiseLayer(*this);
150  }
151 }
152 
154 {
155  if ( mLayerList )
156  {
157  mLayerList->LowerLayer(*this);
158  }
159 }
160 
161 void Layer::RaiseAbove( const Internal::Layer& target )
162 {
163  // cannot raise above ourself, both have to be on stage
164  if( ( this != &target ) && OnStage() && target.OnStage() )
165  {
166  // get parameters depth
167  const unsigned int targetDepth = target.GetDepth();
168  if( GetDepth() < targetDepth )
169  {
170  MoveAbove( target );
171  }
172  }
173 }
174 
175 void Layer::LowerBelow( const Internal::Layer& target )
176 {
177  // cannot lower below ourself, both have to be on stage
178  if( ( this != &target ) && OnStage() && target.OnStage() )
179  {
180  // get parameters depth
181  const unsigned int targetDepth = target.GetDepth();
182  if( GetDepth() > targetDepth )
183  {
184  MoveBelow( target );
185  }
186  }
187 }
188 
190 {
191  if ( mLayerList )
192  {
193  mLayerList->RaiseLayerToTop(*this);
194  }
195 }
196 
198 {
199  if ( mLayerList )
200  {
202  }
203 }
204 
205 void Layer::MoveAbove( const Internal::Layer& target )
206 {
207  // cannot raise above ourself, both have to be on stage
208  if( ( this != &target ) && mLayerList && target.OnStage() )
209  {
210  mLayerList->MoveLayerAbove(*this, target );
211  }
212 }
213 
214 void Layer::MoveBelow( const Internal::Layer& target )
215 {
216  // cannot lower below ourself, both have to be on stage
217  if( ( this != &target ) && mLayerList && target.OnStage() )
218  {
219  mLayerList->MoveLayerBelow(*this, target );
220  }
221 }
222 
224 {
225  mBehavior = behavior;
226 
227  // notify update side object
229 }
230 
231 void Layer::SetClipping(bool enabled)
232 {
233  if (enabled != mIsClipping)
234  {
235  mIsClipping = enabled;
236 
237  // layerNode is being used in a separate thread; queue a message to set the value
239  }
240 }
241 
242 void Layer::SetClippingBox(int x, int y, int width, int height)
243 {
244  if( ( x != mClippingBox.x ) ||
245  ( y != mClippingBox.y ) ||
246  ( width != mClippingBox.width ) ||
247  ( height != mClippingBox.height ) )
248  {
249  // Clipping box is not animatable; this is the most up-to-date value
250  mClippingBox.Set(x, y, width, height);
251 
252  // Convert mClippingBox to GL based coordinates (from bottom-left)
253  ClippingBox clippingBox( mClippingBox );
254 
255  StagePtr stage = Stage::GetCurrent();
256  if( stage )
257  {
258  clippingBox.y = stage->GetSize().height - clippingBox.y - clippingBox.height;
259 
260  // layerNode is being used in a separate thread; queue a message to set the value
262  }
263  }
264 }
265 
266 void Layer::SetDepthTestDisabled( bool disable )
267 {
268  if( disable != mDepthTestDisabled )
269  {
270  mDepthTestDisabled = disable;
271 
272  // Send message .....
273  // layerNode is being used in a separate thread; queue a message to set the value
275  }
276 }
277 
279 {
281 }
282 
284 {
285  if( function != mSortFunction )
286  {
287  mSortFunction = function;
288 
289  // layerNode is being used in a separate thread; queue a message to set the value
291  }
292 }
293 
294 void Layer::SetTouchConsumed( bool consume )
295 {
296  mTouchConsumed = consume;
297 }
298 
300 {
301  return mTouchConsumed;
302 }
303 
304 void Layer::SetHoverConsumed( bool consume )
305 {
306  mHoverConsumed = consume;
307 }
308 
310 {
311  return mHoverConsumed;
312 }
313 
315 {
316  return SceneGraph::Layer::New();
317 }
318 
320 {
321  if ( !mIsRoot )
322  {
323  DALI_ASSERT_DEBUG( NULL == mLayerList );
324 
325  // Find the ordered layer-list
326  // This is different for Layers added via Integration::GetSystemOverlay()
327  for ( Actor* parent = mParent; parent != NULL; parent = parent->GetParent() )
328  {
329  if( parent->IsLayer() )
330  {
331  Layer* parentLayer = static_cast< Layer* >( parent ); // cheaper than dynamic_cast
332  mLayerList = parentLayer->mLayerList;
333  }
334  }
335  }
336 
337  DALI_ASSERT_DEBUG( NULL != mLayerList );
338  mLayerList->RegisterLayer( *this );
339 }
340 
342 {
343  mLayerList->UnregisterLayer(*this);
344 
345  // mLayerList is only valid when on-stage
346  mLayerList = NULL;
347 }
348 
350 {
351  DALI_ASSERT_DEBUG( mNode != NULL );
352  return dynamic_cast< const SceneGraph::Layer& >( *mNode );
353 }
354 
355 unsigned int Layer::GetDefaultPropertyCount() const
356 {
357  return Actor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT;
358 }
359 
361 {
362  Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
363  indices.Reserve( indices.Size() + DEFAULT_PROPERTY_COUNT );
364 
366  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
367  {
368  indices.PushBack( index );
369  }
370 }
371 
373 {
375  {
376  return Actor::IsDefaultPropertyWritable( index );
377  }
378 
379  return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].writable;
380 }
381 
383 {
385  {
386  return Actor::IsDefaultPropertyAnimatable( index );
387  }
388 
389  return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].animatable;
390 }
391 
393 {
395  {
397  }
398 
399  return DEFAULT_PROPERTY_DETAILS[ index - DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX ].constraintInput;
400 }
401 
403 {
405  {
406  return Actor::GetDefaultPropertyType( index );
407  }
408 
410 
411  if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
412  {
413  return DEFAULT_PROPERTY_DETAILS[index].type;
414  }
415 
416  // index out-of-bounds
417  return Property::NONE;
418 }
419 
421 {
423  {
424  return Actor::GetDefaultPropertyName( index );
425  }
426 
428  if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
429  {
430  return DEFAULT_PROPERTY_DETAILS[index].name;
431  }
432 
433  return NULL;
434 }
435 
436 Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
437 {
439 
440  // Look for name in current class' default properties
441  for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
442  {
443  const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[i];
444  if( 0 == name.compare( property->name ) ) // dont want to convert rhs to string
445  {
447  break;
448  }
449  }
450  if( Property::INVALID_INDEX == index )
451  {
452  // If not found, check in base class
453  index = Actor::GetDefaultPropertyIndex( name );
454  }
455 
456  return index;
457 }
458 
459 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
460 {
462  {
463  Actor::SetDefaultProperty( index, propertyValue );
464  }
465  else
466  {
467  switch( index )
468  {
470  {
471  SetClipping( propertyValue.Get<bool>() );
472  break;
473  }
475  {
476  Rect<int> clippingBox( propertyValue.Get<Rect<int> >() );
477  SetClippingBox( clippingBox.x, clippingBox.y, clippingBox.width, clippingBox.height );
478  break;
479  }
481  {
482  Behavior behavior(Dali::Layer::LAYER_2D);
483  if( Scripting::GetEnumeration< Behavior >( propertyValue.Get< std::string >().c_str(), BehaviorTable, BehaviorTableCount, behavior ) )
484  {
485  SetBehavior( behavior );
486  }
487  break;
488  }
489  default:
490  {
491  DALI_LOG_WARNING( "Unknown property (%d)\n", index );
492  break;
493  }
494  } // switch(index)
495 
496  } // else
497 }
498 
500 {
501  Property::Value ret;
503  {
504  ret = Actor::GetDefaultProperty( index );
505  }
506  else
507  {
508  switch( index )
509  {
511  {
512  ret = mIsClipping;
513  break;
514  }
516  {
517  ret = mClippingBox;
518  break;
519  }
521  {
522  ret = Scripting::GetLinearEnumerationName< Behavior >( GetBehavior(), BehaviorTable, BehaviorTableCount );
523  break;
524  }
525  default:
526  {
527  DALI_LOG_WARNING( "Unknown property (%d)\n", index );
528  break;
529  }
530  } // switch(index)
531  }
532 
533  return ret;
534 }
535 
536 bool Layer::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /*attributes*/ )
537 {
538  bool done = false;
539  Layer* layer = dynamic_cast<Layer*>( object );
540 
541  if( layer )
542  {
543  if( 0 == actionName.compare( ACTION_RAISE ) )
544  {
545  layer->Raise();
546  done = true;
547  }
548  else if( 0 == actionName.compare( ACTION_LOWER ) )
549  {
550  layer->Lower();
551  done = true;
552  }
553  else if( 0 == actionName.compare( ACTION_RAISE_TO_TOP ) )
554  {
555  layer->RaiseToTop();
556  done = true;
557  }
558  else if( 0 == actionName.compare( ACTION_LOWER_TO_BOTTOM ) )
559  {
560  layer->LowerToBottom();
561  done = true;
562  }
563  }
564 
565  return done;
566 }
567 
568 } // namespace Internal
569 
570 } // namespace Dali
Dali Docs Home
Read more about Dali