Add GetNaturalSize to Actor and deriving classes.
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / light-actor-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/light-actor-impl.h>
20
21 // INTERNAL HEADER
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/internal/event/common/property-index-ranges.h>
25
26 namespace Dali
27 {
28
29 const Property::Index LightActor::LIGHT_TYPE              = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
30 const Property::Index LightActor::ENABLE                  = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 1;
31 const Property::Index LightActor::FALL_OFF                = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 2;
32 const Property::Index LightActor::SPOT_ANGLE              = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 3;
33 const Property::Index LightActor::AMBIENT_COLOR           = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 4;
34 const Property::Index LightActor::DIFFUSE_COLOR           = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 5;
35 const Property::Index LightActor::SPECULAR_COLOR          = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 6;
36 const Property::Index LightActor::DIRECTION               = Internal::DEFAULT_ACTOR_PROPERTY_MAX_COUNT + 7;
37
38 namespace Internal
39 {
40 bool LightActor::mFirstInstance = true ;
41 Actor::DefaultPropertyLookup* LightActor::mDefaultLightActorPropertyLookup = NULL;
42
43 namespace
44 {
45
46 BaseHandle Create()
47 {
48   return Dali::LightActor::New();
49 }
50
51 TypeRegistration mType( typeid(Dali::LightActor), typeid(Dali::Actor), Create );
52
53 const Internal::PropertyDetails DEFAULT_LIGHT_ACTOR_PROPERTY_DETAILS[] =
54 {
55   // Name             Type              writable animatable constraint-input
56   { "light-type",     Property::STRING,   true,    false,   true },  // LIGHT_TYPE
57   { "enable",         Property::BOOLEAN,  true,    false,   true },  // ENABLE
58   { "fall-off",       Property::VECTOR2,  true,    false,   true },  // FALL_OFF
59   { "spot-angle",     Property::VECTOR2,  true,    false,   true },  // SPOT_ANGLE
60   { "ambient-color",  Property::VECTOR3,  true,    false,   true },  // AMBIENT_COLOR
61   { "diffuse-color",  Property::VECTOR3,  true,    false,   true },  // DIFFUSE_COLOR
62   { "specular-color", Property::VECTOR3,  true,    false,   true },  // SPECULAR_COLOR
63   { "direction",      Property::VECTOR3,  true,    false,   true },  // DIRECTION
64 };
65 const int DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT = sizeof( DEFAULT_LIGHT_ACTOR_PROPERTY_DETAILS ) / sizeof( Internal::PropertyDetails );
66
67 LightType LightTypeEnum(const std::string &stringValue)
68 {
69   LightType ret(AMBIENT);
70
71   if(stringValue == "AMBIENT")
72   {
73     ret =  AMBIENT;
74   }
75   else if(stringValue == "DIRECTIONAL")
76   {
77     ret =  DIRECTIONAL;
78   }
79   else if(stringValue == "SPOT")
80   {
81     ret =  SPOT;
82   }
83   else if(stringValue == "POINT")
84   {
85     ret =  POINT;
86   }
87   else
88   {
89     DALI_LOG_WARNING("Unknown Light Type:%s\n", stringValue.c_str());
90   }
91
92   return ret;
93 }
94
95 std::string LightTypeString(const LightType type)
96 {
97   std::string ret("AMBIENT");
98
99   switch ( type )
100   {
101     case AMBIENT:
102     {
103       ret = "AMBIENT";
104       break;
105     }
106
107     case DIRECTIONAL:
108     {
109       ret = "DIRECTIONAL";
110       break;
111     }
112
113     case SPOT:
114     {
115       ret = "SPOT";
116       break;
117     }
118     case POINT:
119     {
120       ret = "POINT";
121       break;
122     }
123   }
124   return ret;
125 }
126
127 } // namespace
128
129
130 LightActorPtr LightActor::New()
131 {
132   LightActorPtr actor(new LightActor());
133
134   // Second-phase construction
135
136   actor->Initialize();
137
138   // Create the attachment
139   actor->mLightAttachment = LightAttachment::New( *actor->mNode );
140   actor->Attach(*actor->mLightAttachment);
141   actor->mLightAttachment->SetName(actor->GetName());
142
143   return actor;
144 }
145
146
147 void LightActor::OnInitialize()
148 {
149   if(LightActor::mFirstInstance)
150   {
151     mDefaultLightActorPropertyLookup = new DefaultPropertyLookup();
152     const int start = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
153     for ( int i = 0; i < DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT; ++i )
154     {
155       (*mDefaultLightActorPropertyLookup)[DEFAULT_LIGHT_ACTOR_PROPERTY_DETAILS[i].name] = i + start;
156     }
157     LightActor::mFirstInstance = false ;
158   }
159 }
160
161 LightActor::LightActor()
162 : Actor( Actor::BASIC ),
163   mIsActive(false)
164 {
165 }
166
167 LightActor::~LightActor()
168 {
169 }
170
171 void LightActor::SetLight(Dali::Light light)
172 {
173   Internal::LightPtr lightPtr(&GetImplementation(light));
174   mLightAttachment->SetLight(lightPtr);
175   mLightAttachment->SetActive(true);
176 }
177
178 Dali::Light LightActor::GetLight() const
179 {
180   Internal::LightPtr lightPtr(mLightAttachment->GetLight());
181   return Dali::Light(lightPtr.Get());
182 }
183
184 void LightActor::SetActive(bool active)
185 {
186   mLightAttachment->SetActive(active);
187   mIsActive = active;
188 }
189
190 bool LightActor::GetActive()
191 {
192   return mIsActive;
193 }
194
195 unsigned int LightActor::GetDefaultPropertyCount() const
196 {
197   return Actor::GetDefaultPropertyCount() + DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT;
198 }
199
200 void LightActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
201 {
202   Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
203
204   indices.reserve( indices.size() + DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT );
205
206   int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
207   for ( int i = 0; i < DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT; ++i, ++index )
208   {
209     indices.push_back( index );
210   }
211 }
212
213 bool LightActor::IsDefaultPropertyWritable( Property::Index index ) const
214 {
215   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
216   {
217     return Actor::IsDefaultPropertyWritable(index) ;
218   }
219   else
220   {
221     return true ;
222   }
223 }
224
225 bool LightActor::IsDefaultPropertyAnimatable( Property::Index index ) const
226 {
227   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
228   {
229     return Actor::IsDefaultPropertyAnimatable(index) ;
230   }
231   else
232   {
233     return false ;
234   }
235 }
236
237 bool LightActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
238 {
239   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
240   {
241     return Actor::IsDefaultPropertyAConstraintInput(index);
242   }
243   return true; // Our properties can be used as input to constraints.
244 }
245
246 Property::Type LightActor::GetDefaultPropertyType( Property::Index index ) const
247 {
248   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
249   {
250     return Actor::GetDefaultPropertyType(index) ;
251   }
252   else
253   {
254     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
255
256     if ( ( index >= 0 ) && ( index < DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT ) )
257     {
258       return DEFAULT_LIGHT_ACTOR_PROPERTY_DETAILS[index].type;
259     }
260     else
261     {
262       // index out-of-bounds
263       return Property::NONE;
264     }
265   }
266 }
267
268 const std::string& LightActor::GetDefaultPropertyName( Property::Index index ) const
269 {
270   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
271   {
272     return Actor::GetDefaultPropertyName(index) ;
273   }
274   else
275   {
276     index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
277
278     if ( ( index >= 0 ) && ( index < DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT ) )
279     {
280       return DEFAULT_LIGHT_ACTOR_PROPERTY_DETAILS[index].name;
281     }
282     else
283     {
284       // index out-of-bounds
285       static const std::string INVALID_PROPERTY_NAME;
286       return INVALID_PROPERTY_NAME;
287     }
288   }
289 }
290
291 Property::Index LightActor::GetDefaultPropertyIndex(const std::string& name) const
292 {
293   Property::Index index = Property::INVALID_INDEX;
294
295   DALI_ASSERT_DEBUG( NULL != mDefaultLightActorPropertyLookup );
296
297   // Look for name in current class' default properties
298   DefaultPropertyLookup::const_iterator result = mDefaultLightActorPropertyLookup->find( name );
299   if ( mDefaultLightActorPropertyLookup->end() != result )
300   {
301     index = result->second;
302   }
303   else
304   {
305     // If not found, check in base class
306     index = Actor::GetDefaultPropertyIndex( name );
307   }
308
309   return index;
310 }
311
312 void LightActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
313 {
314   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
315   {
316     Actor::SetDefaultProperty(index, propertyValue) ;
317   }
318   else
319   {
320     switch(index)
321     {
322       case Dali::LightActor::LIGHT_TYPE:
323       {
324         mLightAttachment->SetType(LightTypeEnum(propertyValue.Get<std::string>()));
325         break;
326       }
327       case Dali::LightActor::ENABLE:
328       {
329         SetActive(propertyValue.Get<bool>());
330         break;
331       }
332       case Dali::LightActor::FALL_OFF:
333       {
334         mLightAttachment->SetFallOff(propertyValue.Get<Vector2>());
335         break;
336       }
337       case Dali::LightActor::SPOT_ANGLE:
338       {
339         mLightAttachment->SetSpotAngle(propertyValue.Get<Vector2>());
340         break;
341       }
342       case Dali::LightActor::AMBIENT_COLOR:
343       {
344         mLightAttachment->SetAmbientColor(propertyValue.Get<Vector3>());
345         break;
346       }
347       case Dali::LightActor::DIFFUSE_COLOR:
348       {
349         mLightAttachment->SetDiffuseColor(propertyValue.Get<Vector3>());
350         break;
351       }
352       case Dali::LightActor::SPECULAR_COLOR:
353       {
354         mLightAttachment->SetSpecularColor(propertyValue.Get<Vector3>());
355         break;
356       }
357       case Dali::LightActor::DIRECTION:
358       {
359         mLightAttachment->SetDirection(propertyValue.Get<Vector3>());
360         break;
361       }
362       default:
363       {
364         DALI_LOG_WARNING("Unknown property (%d)\n", index);
365         break;
366       }
367     } // switch(index)
368
369   } // else
370 }
371
372 Property::Value LightActor::GetDefaultProperty( Property::Index index ) const
373 {
374   Property::Value ret ;
375   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
376   {
377     ret = Actor::GetDefaultProperty(index) ;
378   }
379   else
380   {
381     switch(index)
382     {
383       case Dali::LightActor::LIGHT_TYPE:
384       {
385         ret = LightTypeString(mLightAttachment->GetType());
386         break;
387       }
388       case Dali::LightActor::ENABLE:
389       {
390         ret = mIsActive;
391         break;
392       }
393       case Dali::LightActor::FALL_OFF:
394       {
395         ret = mLightAttachment->GetFallOff();
396         break;
397       }
398       case Dali::LightActor::SPOT_ANGLE:
399       {
400         ret = mLightAttachment->GetSpotAngle();
401         break;
402       }
403       case Dali::LightActor::AMBIENT_COLOR:
404       {
405         ret = mLightAttachment->GetAmbientColor();
406         break;
407       }
408       case Dali::LightActor::DIFFUSE_COLOR:
409       {
410         ret = mLightAttachment->GetDiffuseColor();
411         break;
412       }
413       case Dali::LightActor::SPECULAR_COLOR:
414       {
415         ret = mLightAttachment->GetSpecularColor();
416         break;
417       }
418       case Dali::LightActor::DIRECTION:
419       {
420         ret = mLightAttachment->GetDirection();
421         break;
422       }
423       default:
424       {
425         DALI_LOG_WARNING("Unknown property (%d)\n", index);
426         break;
427       }
428     } // switch(index)
429   }
430
431   return ret ;
432 }
433
434
435 } // namespace Internal
436
437 } // namespace Dali