[4.0] Add Property::EXTENTS type
[platform/core/uifw/dali-core.git] / dali / public-api / object / property-value.cpp
1 /*
2  * Copyright (c) 2016 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/public-api/object/property-value.h>
20
21 // EXTERNAL INCLUDES
22 #include <ostream>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/extents.h>
26 #include <dali/public-api/math/angle-axis.h>
27 #include <dali/public-api/math/radian.h>
28 #include <dali/public-api/math/vector2.h>
29 #include <dali/public-api/math/vector3.h>
30 #include <dali/public-api/math/vector4.h>
31 #include <dali/public-api/math/matrix3.h>
32 #include <dali/public-api/math/matrix.h>
33 #include <dali/public-api/math/rect.h>
34 #include <dali/public-api/math/quaternion.h>
35 #include <dali/public-api/object/property-map.h>
36 #include <dali/public-api/object/property-array.h>
37 #include <dali/public-api/object/property-types.h>
38 #include <dali/integration-api/debug.h>
39
40 namespace Dali
41 {
42
43 namespace
44 {
45 /**
46  * Helper to check if the property value can be read as int/bool
47  */
48 inline bool IsIntegerType( Property::Type type )
49 {
50   return ( Property::BOOLEAN == type )||( Property::INTEGER == type );
51 }
52 }
53
54 struct Property::Value::Impl
55 {
56   Impl()
57   : type( Property::NONE ),
58     integerValue( 0 )
59   { }
60
61   Impl( bool booleanValue )
62   : type( Property::BOOLEAN ),
63     integerValue( booleanValue )
64   { }
65
66   Impl( float floatValue )
67   : type( Property::FLOAT ),
68     floatValue( floatValue )
69   { }
70
71   Impl( int integerValue )
72   : type( Property::INTEGER ),
73     integerValue( integerValue )
74   { }
75
76   Impl( const Vector2& vectorValue )
77   : type( Property::VECTOR2 ),
78     vector2Value( new Vector2( vectorValue ) )
79   { }
80
81   Impl( const Vector3& vectorValue )
82   : type( Property::VECTOR3 ),
83     vector3Value( new Vector3( vectorValue ) )
84   { }
85
86   Impl( const Vector4& vectorValue )
87   : type( Property::VECTOR4 ),
88     vector4Value( new Vector4( vectorValue ) )
89   { }
90
91   Impl( const Matrix3& matrixValue )
92   : type( Property::MATRIX3 ),
93     matrix3Value( new Matrix3( matrixValue ) )
94   {
95   }
96
97   Impl( const Matrix& matrixValue )
98   : type( Property::MATRIX ),
99     matrixValue( new Matrix( matrixValue ) )
100   {
101   }
102
103   Impl( const AngleAxis& angleAxisValue )
104   : type( Property::ROTATION ),
105     angleAxisValue( new AngleAxis(angleAxisValue) )
106   {
107   }
108
109   Impl( const Quaternion& quaternionValue )
110   : type( Property::ROTATION ),
111     angleAxisValue( new AngleAxis() )
112   {
113     quaternionValue.ToAxisAngle( angleAxisValue->axis, angleAxisValue->angle );
114   }
115
116   Impl(const std::string& stringValue)
117   : type( Property::STRING ),
118     stringValue( new std::string( stringValue ) )
119   {
120   }
121
122   Impl( const Rect<int>& rectValue )
123   : type( Property::RECTANGLE ),
124     rectValue( new Rect<int>( rectValue ) )
125   {
126   }
127
128   Impl( const Property::Array& arrayValue )
129   : type( Property::ARRAY ),
130     arrayValue( new Property::Array( arrayValue ) )
131   {
132   }
133
134   Impl( const Property::Map& mapValue )
135   : type( Property::MAP ),
136     mapValue( new Property::Map( mapValue ) )
137   {
138   }
139
140   Impl( const Extents& extentsValue )
141   : type( Property::EXTENTS ),
142     extentsValue( new Extents( extentsValue ) )
143   {
144   }
145
146   /**
147    * Destructor, takes care of releasing the dynamically allocated types
148    */
149   ~Impl()
150   {
151     switch( type )
152     {
153       case Property::NONE :             // FALLTHROUGH
154       case Property::BOOLEAN :          // FALLTHROUGH
155       case Property::FLOAT :            // FALLTHROUGH
156       case Property::INTEGER :
157       {
158         break; // nothing to do
159       }
160       case Property::VECTOR2 :
161       {
162         delete vector2Value;
163         break;
164       }
165       case Property::VECTOR3:
166       {
167         delete vector3Value;
168         break;
169       }
170       case Property::VECTOR4:
171       {
172         delete vector4Value;
173         break;
174       }
175       case Property::MATRIX3:
176       {
177         delete matrix3Value;
178         break;
179       }
180       case Property::MATRIX:
181       {
182         delete matrixValue;
183         break;
184       }
185       case Property::RECTANGLE:
186       {
187         delete rectValue;
188         break;
189       }
190       case Property::ROTATION:
191       {
192         delete angleAxisValue;
193         break;
194       }
195       case Property::STRING:
196       {
197         delete stringValue;
198         break;
199       }
200       case Property::ARRAY:
201       {
202         delete arrayValue;
203         break;
204       }
205       case Property::MAP:
206       {
207         delete mapValue;
208         break;
209       }
210       case Property::EXTENTS:
211       {
212         delete extentsValue;
213         break;
214       }
215     }
216   }
217
218 public: // Data
219
220   Type type;
221   union
222   {
223     int integerValue;
224     float floatValue;
225     // must use pointers for any class value pre c++ 11
226     Vector2* vector2Value;
227     Vector3* vector3Value;
228     Vector4* vector4Value;
229     Matrix3* matrix3Value;
230     Matrix* matrixValue;
231     AngleAxis* angleAxisValue;
232     std::string* stringValue;
233     Rect<int>* rectValue;
234     Property::Array* arrayValue;
235     Property::Map* mapValue;
236     Extents* extentsValue;
237   };
238
239 private:
240
241   Impl( const Impl& ); ///< Undefined
242   Impl& operator=( const Impl& ); ///< Undefined
243 };
244
245 Property::Value::Value()
246 : mImpl( NULL )
247 {
248 }
249
250 Property::Value::Value( bool booleanValue )
251 : mImpl( new Impl( booleanValue ) )
252 {
253 }
254
255 Property::Value::Value( float floatValue )
256 : mImpl( new Impl( floatValue ) )
257 {
258 }
259
260 Property::Value::Value( int integerValue )
261 : mImpl( new Impl( integerValue ) )
262 {
263 }
264
265 Property::Value::Value( const Vector2& vectorValue )
266 : mImpl( new Impl( vectorValue ) )
267 {
268 }
269
270 Property::Value::Value( const Vector3& vectorValue )
271 : mImpl( new Impl( vectorValue ) )
272 {
273 }
274
275 Property::Value::Value( const Vector4& vectorValue )
276 : mImpl( new Impl( vectorValue ) )
277 {
278 }
279
280 Property::Value::Value( const Matrix3& matrixValue )
281 : mImpl( new Impl( matrixValue ) )
282 {
283 }
284
285 Property::Value::Value( const Matrix& matrixValue )
286 : mImpl( new Impl( matrixValue ) )
287 {
288 }
289
290 Property::Value::Value( const Rect<int>& rectValue )
291 : mImpl( new Impl( rectValue ) )
292 {
293 }
294
295 Property::Value::Value( const AngleAxis& angleAxisValue )
296 : mImpl( new Impl( angleAxisValue ) )
297 {
298 }
299
300 Property::Value::Value( const Quaternion& quaternionValue )
301 : mImpl( new Impl( quaternionValue ) )
302 {
303 }
304
305 Property::Value::Value( const std::string& stringValue )
306 : mImpl( new Impl( stringValue ) )
307 {
308 }
309
310 Property::Value::Value( const char* stringValue )
311 : mImpl( NULL )
312 {
313   if( stringValue ) // string constructor is undefined with NULL pointer
314   {
315     mImpl = new Impl( std::string(stringValue) );
316   }
317   else
318   {
319     mImpl = new Impl( std::string() );
320   }
321 }
322
323 Property::Value::Value( Property::Array& arrayValue )
324 : mImpl( new Impl( arrayValue ) )
325 {
326 }
327
328 Property::Value::Value( Property::Map& mapValue )
329 : mImpl( new Impl( mapValue ) )
330 {
331 }
332
333 Property::Value::Value( const Extents& extentsValue )
334 : mImpl( new Impl( extentsValue ) )
335 {
336 }
337
338 Property::Value::Value( Type type )
339 : mImpl( NULL )
340 {
341   switch (type)
342   {
343     case Property::BOOLEAN:
344     {
345       mImpl = new Impl( false );
346       break;
347     }
348     case Property::FLOAT:
349     {
350       mImpl = new Impl( 0.f );
351       break;
352     }
353     case Property::INTEGER:
354     {
355       mImpl = new Impl( 0 );
356       break;
357     }
358     case Property::VECTOR2:
359     {
360       mImpl = new Impl( Vector2::ZERO );
361       break;
362     }
363     case Property::VECTOR3:
364     {
365       mImpl = new Impl( Vector3::ZERO );
366       break;
367     }
368     case Property::VECTOR4:
369     {
370       mImpl = new Impl( Vector4::ZERO );
371       break;
372     }
373     case Property::RECTANGLE:
374     {
375       mImpl = new Impl( Rect<int>(0,0,0,0) );
376       break;
377     }
378     case Property::ROTATION:
379     {
380       mImpl = new Impl( AngleAxis() );
381       break;
382     }
383     case Property::STRING:
384     {
385       mImpl = new Impl( std::string() );
386       break;
387     }
388     case Property::MATRIX:
389     {
390       mImpl = new Impl( Matrix() );
391       break;
392     }
393     case Property::MATRIX3:
394     {
395       mImpl = new Impl( Matrix3() );
396       break;
397     }
398     case Property::ARRAY:
399     {
400       mImpl = new Impl( Property::Array() );
401       break;
402     }
403     case Property::MAP:
404     {
405       mImpl = new Impl( Property::Map() );
406       break;
407     }
408     case Property::EXTENTS:
409     {
410       mImpl = new Impl( Extents() );
411       break;
412     }
413     case Property::NONE:
414     {
415       mImpl = new Impl();
416       break;
417     }
418   }
419 }
420
421 Property::Value::Value( const Property::Value& value )
422 : mImpl( NULL )
423 {
424   // reuse assignment operator
425   operator=( value );
426 }
427
428 Property::Value& Property::Value::operator=( const Property::Value& value )
429 {
430   if ( this == &value )
431   {
432     // skip self assignment
433     return *this;
434   }
435   // if we are assigned an empty value, just drop impl
436   if( !value.mImpl )
437   {
438     delete mImpl;
439     mImpl = NULL;
440     return *this;
441   }
442   // first check if the type is the same, no need to change impl, just assign
443   if( mImpl && ( mImpl->type == value.mImpl->type ) )
444   {
445     switch( mImpl->type )
446     {
447       case Property::BOOLEAN:
448       {
449         mImpl->integerValue = value.mImpl->integerValue;
450         break;
451       }
452       case Property::FLOAT:
453       {
454         mImpl->floatValue = value.mImpl->floatValue;
455         break;
456       }
457       case Property::INTEGER:
458       {
459         mImpl->integerValue = value.mImpl->integerValue;
460         break;
461       }
462       case Property::VECTOR2:
463       {
464         *mImpl->vector2Value = *value.mImpl->vector2Value; // type cannot change in mImpl so vector is allocated
465         break;
466       }
467       case Property::VECTOR3:
468       {
469         *mImpl->vector3Value = *value.mImpl->vector3Value; // type cannot change in mImpl so vector is allocated
470         break;
471       }
472       case Property::VECTOR4:
473       {
474         *mImpl->vector4Value = *value.mImpl->vector4Value; // type cannot change in mImpl so vector is allocated
475         break;
476       }
477       case Property::RECTANGLE:
478       {
479         *mImpl->rectValue = *value.mImpl->rectValue; // type cannot change in mImpl so rect is allocated
480         break;
481       }
482       case Property::ROTATION:
483       {
484         *mImpl->angleAxisValue = *value.mImpl->angleAxisValue; // type cannot change in mImpl so quaternion is allocated
485         break;
486       }
487       case Property::STRING:
488       {
489         *mImpl->stringValue = *value.mImpl->stringValue; // type cannot change in mImpl so string is allocated
490         break;
491       }
492       case Property::MATRIX:
493       {
494         *mImpl->matrixValue = *value.mImpl->matrixValue; // type cannot change in mImpl so matrix is allocated
495         break;
496       }
497       case Property::MATRIX3:
498       {
499         *mImpl->matrix3Value = *value.mImpl->matrix3Value; // type cannot change in mImpl so matrix is allocated
500         break;
501       }
502       case Property::ARRAY:
503       {
504         *mImpl->arrayValue = *value.mImpl->arrayValue; // type cannot change in mImpl so array is allocated
505         break;
506       }
507       case Property::MAP:
508       {
509         *mImpl->mapValue = *value.mImpl->mapValue; // type cannot change in mImpl so map is allocated
510         break;
511       }
512       case Property::EXTENTS:
513       {
514         *mImpl->extentsValue = *value.mImpl->extentsValue; // type cannot change in mImpl so extents is allocated
515         break;
516       }
517       case Property::NONE:
518       { // mImpl will be NULL, there's no way to get to this case
519       }
520     }
521   }
522   else
523   {
524     // different type, release old impl and create new
525     Impl* newImpl( NULL );
526     switch ( value.mImpl->type )
527     {
528       case Property::BOOLEAN:
529       {
530         newImpl = new Impl( bool( value.mImpl->integerValue ) );
531         break;
532       }
533       case Property::FLOAT:
534       {
535         newImpl = new Impl( value.mImpl->floatValue );
536         break;
537       }
538       case Property::INTEGER:
539       {
540         newImpl = new Impl( value.mImpl->integerValue );
541         break;
542       }
543       case Property::VECTOR2:
544       {
545         newImpl = new Impl( *value.mImpl->vector2Value ); // type cannot change in mImpl so vector is allocated
546         break;
547       }
548       case Property::VECTOR3:
549       {
550         newImpl = new Impl( *value.mImpl->vector3Value ); // type cannot change in mImpl so vector is allocated
551         break;
552       }
553       case Property::VECTOR4:
554       {
555         newImpl = new Impl( *value.mImpl->vector4Value ); // type cannot change in mImpl so vector is allocated
556         break;
557       }
558       case Property::RECTANGLE:
559       {
560         newImpl = new Impl( *value.mImpl->rectValue ); // type cannot change in mImpl so rect is allocated
561         break;
562       }
563       case Property::ROTATION:
564       {
565         newImpl = new Impl( *value.mImpl->angleAxisValue ); // type cannot change in mImpl so quaternion is allocated
566         break;
567       }
568       case Property::MATRIX3:
569       {
570         newImpl = new Impl( *value.mImpl->matrix3Value ); // type cannot change in mImpl so matrix is allocated
571         break;
572       }
573       case Property::MATRIX:
574       {
575         newImpl = new Impl( *value.mImpl->matrixValue ); // type cannot change in mImpl so matrix is allocated
576         break;
577       }
578       case Property::STRING:
579       {
580         newImpl = new Impl( *value.mImpl->stringValue ); // type cannot change in mImpl so string is allocated
581         break;
582       }
583       case Property::ARRAY:
584       {
585         newImpl = new Impl( *value.mImpl->arrayValue ); // type cannot change in mImpl so array is allocated
586         break;
587       }
588       case Property::MAP:
589       {
590         newImpl = new Impl( *value.mImpl->mapValue ); // type cannot change in mImpl so map is allocated
591         break;
592       }
593       case Property::EXTENTS:
594       {
595         newImpl = new Impl( *value.mImpl->extentsValue ); // type cannot change in mImpl so extents is allocated
596         break;
597       }
598       case Property::NONE:
599       { // NULL value will be used for "empty" value
600       }
601     }
602     delete mImpl;
603     mImpl = newImpl;
604   }
605
606   return *this;
607 }
608
609 Property::Value::~Value()
610 {
611   delete mImpl;
612 }
613
614 Property::Type Property::Value::GetType() const
615 {
616   Property::Type type( Property::NONE );
617   if( mImpl )
618   {
619     type = mImpl->type;
620   }
621   return type;
622 }
623
624 bool Property::Value::Get( bool& booleanValue ) const
625 {
626   bool converted = false;
627   if( mImpl && IsIntegerType( mImpl->type ) )
628   {
629     booleanValue = mImpl->integerValue;
630     converted = true;
631   }
632   return converted;
633 }
634
635 bool Property::Value::Get( float& floatValue ) const
636 {
637   bool converted = false;
638   if( mImpl )
639   {
640     if( mImpl->type == FLOAT )
641     {
642       floatValue = mImpl->floatValue;
643       converted = true;
644     }
645     else if( IsIntegerType( mImpl->type ) )
646     {
647       floatValue = static_cast< float >( mImpl->integerValue );
648       converted = true;
649     }
650   }
651   return converted;
652 }
653
654 bool Property::Value::Get( int& integerValue ) const
655 {
656   bool converted = false;
657   if( mImpl )
658   {
659     if( IsIntegerType( mImpl->type ) )
660     {
661       integerValue = mImpl->integerValue;
662       converted = true;
663     }
664     else if( mImpl->type == FLOAT )
665     {
666       integerValue = static_cast< int >( mImpl->floatValue );
667       converted = true;
668     }
669   }
670   return converted;
671 }
672
673 bool Property::Value::Get( Vector2& vectorValue ) const
674 {
675   bool converted = false;
676   if( mImpl )
677   {
678     // type cannot change in mImpl so vector is allocated
679     if( mImpl->type == VECTOR2 || mImpl->type == VECTOR3 || mImpl->type == VECTOR4 )
680     {
681       vectorValue = *(mImpl->vector2Value); // if Vector3 or 4 only x and y are assigned
682       converted = true;
683     }
684   }
685   return converted;
686 }
687
688 bool Property::Value::Get( Vector3& vectorValue ) const
689 {
690   bool converted = false;
691   if( mImpl )
692   {
693     // type cannot change in mImpl so vector is allocated
694     if ( mImpl->type == VECTOR3 || mImpl->type == VECTOR4 )
695     {
696       vectorValue = *(mImpl->vector3Value); // if Vector4 only x,y,z are assigned
697       converted = true;
698     }
699     else if( mImpl->type == VECTOR2 )
700     {
701       vectorValue = *(mImpl->vector2Value);
702       converted = true;
703     }
704   }
705   return converted;
706 }
707
708 bool Property::Value::Get( Vector4& vectorValue ) const
709 {
710   bool converted = false;
711   if( mImpl )
712   {
713     if( mImpl->type == VECTOR4 ) // type cannot change in mImpl so vector is allocated
714     {
715       vectorValue = *(mImpl->vector4Value);
716       converted = true;
717     }
718     else if( mImpl->type == VECTOR2 )
719     {
720       vectorValue = *(mImpl->vector2Value);
721       converted = true;
722     }
723     else if( mImpl->type == VECTOR3 )
724     {
725       vectorValue = *(mImpl->vector3Value);
726       converted = true;
727     }
728   }
729   return converted;
730 }
731
732 bool Property::Value::Get( Matrix3& matrixValue ) const
733 {
734   bool converted = false;
735   if( mImpl && (mImpl->type == MATRIX3) ) // type cannot change in mImpl so matrix is allocated
736   {
737     matrixValue = *(mImpl->matrix3Value);
738     converted = true;
739   }
740   return converted;
741 }
742
743 bool Property::Value::Get( Matrix& matrixValue ) const
744 {
745   bool converted = false;
746   if( mImpl && (mImpl->type == MATRIX) ) // type cannot change in mImpl so matrix is allocated
747   {
748     matrixValue = *(mImpl->matrixValue);
749     converted = true;
750   }
751   return converted;
752 }
753
754 bool Property::Value::Get( Rect<int>& rectValue ) const
755 {
756   bool converted = false;
757   if( mImpl && (mImpl->type == RECTANGLE) ) // type cannot change in mImpl so rect is allocated
758   {
759     rectValue = *(mImpl->rectValue);
760     converted = true;
761   }
762   return converted;
763 }
764
765 bool Property::Value::Get( AngleAxis& angleAxisValue ) const
766 {
767   bool converted = false;
768   if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so angleAxis is allocated
769   {
770     angleAxisValue = *(mImpl->angleAxisValue);
771     converted = true;
772   }
773   return converted;
774 }
775
776 bool Property::Value::Get( Quaternion& quaternionValue ) const
777 {
778   bool converted = false;
779   if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so angleAxis is allocated
780   {
781     quaternionValue = Quaternion(mImpl->angleAxisValue->angle, mImpl->angleAxisValue->axis );
782     converted = true;
783   }
784   return converted;
785 }
786
787 bool Property::Value::Get( std::string& stringValue ) const
788 {
789   bool converted = false;
790   if( mImpl && (mImpl->type == STRING) ) // type cannot change in mImpl so string is allocated
791   {
792     stringValue.assign( *(mImpl->stringValue) );
793     converted = true;
794   }
795   return converted;
796 }
797
798 bool Property::Value::Get( Property::Array& arrayValue ) const
799 {
800   bool converted = false;
801   if( mImpl && (mImpl->type == ARRAY) ) // type cannot change in mImpl so array is allocated
802   {
803     arrayValue = *(mImpl->arrayValue);
804     converted = true;
805   }
806   return converted;
807 }
808
809 bool Property::Value::Get( Property::Map& mapValue ) const
810 {
811   bool converted = false;
812   if( mImpl && (mImpl->type == MAP) ) // type cannot change in mImpl so map is allocated
813   {
814     mapValue = *(mImpl->mapValue);
815     converted = true;
816   }
817   return converted;
818 }
819
820 Property::Array* Property::Value::GetArray() const
821 {
822   Property::Array* array = NULL;
823   if( mImpl && (mImpl->type == ARRAY) ) // type cannot change in mImpl so array is allocated
824   {
825     array = mImpl->arrayValue;
826   }
827   return array;
828 }
829
830 Property::Map* Property::Value::GetMap() const
831 {
832   Property::Map* map = NULL;
833   if( mImpl && (mImpl->type == MAP) ) // type cannot change in mImpl so map is allocated
834   {
835     map = mImpl->mapValue;
836   }
837   return map;
838 }
839
840 bool Property::Value::Get( Extents& extentsValue ) const
841 {
842   bool converted = false;
843   if( mImpl )
844   {
845     if( mImpl->type == EXTENTS )
846     {
847       extentsValue = *(mImpl->extentsValue);
848       converted = true;
849     }
850     else if( mImpl->type == VECTOR4 )
851     {
852       extentsValue.start = static_cast< uint16_t >( mImpl->vector4Value->x );
853       extentsValue.end = static_cast< uint16_t >( mImpl->vector4Value->y );
854       extentsValue.top = static_cast< uint16_t >( mImpl->vector4Value->z );
855       extentsValue.bottom = static_cast< uint16_t >( mImpl->vector4Value->w );
856       converted = true;
857     }
858   }
859   return converted;
860 }
861
862 std::ostream& operator<<( std::ostream& stream, const Property::Value& value )
863 {
864   if( value.mImpl )
865   {
866     const Property::Value::Impl& impl( *value.mImpl );
867
868     switch( impl.type )
869     {
870       case Dali::Property::BOOLEAN:
871       {
872         stream << impl.integerValue;
873         break;
874       }
875       case Dali::Property::FLOAT:
876       {
877         stream << impl.floatValue;
878         break;
879       }
880       case Dali::Property::INTEGER:
881       {
882          stream << impl.integerValue;
883          break;
884       }
885       case Dali::Property::VECTOR2:
886       {
887         stream << *impl.vector2Value;
888         break;
889       }
890       case Dali::Property::VECTOR3:
891       {
892         stream << *impl.vector3Value;
893         break;
894       }
895       case Dali::Property::VECTOR4:
896       {
897         stream << *impl.vector4Value;
898         break;
899       }
900       case Dali::Property::MATRIX3:
901       {
902         stream << *impl.matrix3Value;
903         break;
904       }
905       case Dali::Property::MATRIX:
906       {
907         stream << *impl.matrixValue;
908         break;
909       }
910       case Dali::Property::RECTANGLE:
911       {
912         stream << *impl.rectValue;
913         break;
914       }
915       case Dali::Property::ROTATION:
916       {
917         stream << *impl.angleAxisValue;
918         break;
919       }
920       case Dali::Property::STRING:
921       {
922         stream << *impl.stringValue;
923         break;
924       }
925       case Dali::Property::ARRAY:
926       {
927         stream << *(value.GetArray());
928         break;
929       }
930       case Dali::Property::MAP:
931       {
932         stream << *(value.GetMap());
933         break;
934       }
935       case Dali::Property::EXTENTS:
936       {
937         stream << *impl.extentsValue;
938         break;
939       }
940       case Dali::Property::NONE:
941       {
942         stream << "undefined type";
943         break;
944       }
945     }
946   }
947   else
948   {
949     stream << "empty type";
950   }
951   return stream;
952 }
953
954
955 } // namespace Dali