Conversion to Apache 2.0 license
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / public-api / controls / scrollable / item-view / album-layout.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 #include <algorithm>
19 #include <dali-toolkit/public-api/controls/scrollable/item-view/album-layout.h>
20
21 using namespace Dali;
22 using namespace Dali::Toolkit;
23 using namespace std;
24
25 namespace // unnamed namespace
26 {
27 const float DEFAULT_SCROLL_SPEED_FACTOR = 0.005f;
28 const float DEFAULT_MAXIMUM_SWIPE_SPEED = 3.0f;
29 const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.25f;
30
31 const float SELECTED_RIGHT = 2.5f;
32 const float SELECTED_LEFT = 3.5f;
33 const float SELECTED_CENTER = 3.0f;
34
35 const float LAYOUT_POSITION_NAGATIVE_1 = -1.0f;
36 const float LAYOUT_POSITION_0 = 0.0f;
37 const float LAYOUT_POSITION_2 = 2.0f;
38 const float LAYOUT_POSITION_3 = 3.0f;
39 const float LAYOUT_POSITION_4 = 4.0f;
40 const float LAYOUT_POSITION_6 = 6.0f;
41 const float LAYOUT_POSITION_7 = 7.0f;
42
43 const Vector3 POSITION_0 = Vector3(850.0f,-250.0f,0.0f);
44 const Vector3 POSITION_1 = Vector3(700.0f,50.0f,0.0f);
45 const Vector3 POSITION_2 = Vector3(440.0f,227.0f,0.0f);
46 const Vector3 POSITION_4 = Vector3(-440.0f,227.0f,0.0f);
47 const Vector3 POSITION_5 = Vector3(-700.0f,50.0f,0.0f);
48 const Vector3 POSITION_6 = Vector3(-850.0f,-250.0f,0.0f);
49
50 const float ROTATION_0 = Math::PI/6.0f;
51 const float ROTATION_1 = 0.0f;
52 const float ROTATION_2 = Math::PI/6.0f;
53 const float ROTATION_4 = -Math::PI/6.0f;
54 const float ROTATION_5 = 0.0f;
55 const float ROTATION_6 = -Math::PI/6.0f;
56
57 const float SCALE = 1.0f;
58
59 const Vector2 COLOR = Vector2(1.0f,1.0f);
60
61 const Vector3 SELECTED_ITEM_POSITION = Vector3( 0.0f,-80.0f,140.0f);
62 const float SELECETED_ITEM_SCALE = 1.72f;
63 const Vector2 SELECTED_ITEM_COLOR = Vector2(1.0f,1.0f);
64 const Vector3 VIRTUAL_ITEM_POSITION_RIGHT = Vector3( 280.0f,130.0f,130.0f);
65 const Vector3 VIRTUAL_ITEM_POSITION_LEFT = Vector3( -280.0f,130.0f,130.0f);
66 const float ROTATION_X = Math::PI/4.0f;
67 const float SCALE_RIGHT = 1.0f;
68 const float SCALE_LEFT = 1.0f;
69 const Vector2 COLOR_RIGHT = Vector2(1.0f,1.0f);
70 const Vector2 COLOR_LEFT = Vector2(1.0f,1.0f);
71 const Vector3 POSITION_RIGHT = Vector3(710.0f,-450.0f,0.0f);
72 const Vector3 POSITION_LEFT = Vector3(-710.0f,-450.0f,0.0f);
73 const float ROTATION_RIGHT = -Math::PI / 6.0f;
74 const float ROTATION_LEFT = Math::PI / 6.0f;
75
76 const float ALBUM_HIGHT = 7.0f;
77 const float ALPHA = 1.1f;
78 const float ALPHA_OF_SIZE = 0.35f;
79 const float LINE_OF_BOTTOM = 360.0f;
80
81 const float CHANCE_OF_RANDOM_ROTATION_OF_STACK = 0.5f;
82 const float RANGE_OF_RANDOM_ROTATION_OF_STACK = 0.5f;
83
84 const float THRESHHOLD_OF_MOVING = 0.02f;
85 const int NUM_OF_FRAME_FILTERED = 5;
86
87 const unsigned int SPREAD_ITEM_NUM = 6;
88
89 typedef enum
90 {
91  SCROLL_LEFT = 1,
92  SCROLL_NONE = 0,
93  SCROLL_RIGHT = -1
94 }ScrollDirection;
95
96 struct DefaultItemSizeFunction
97 {
98   Vector3 operator()(const Vector3& layoutSize)
99   {
100     float width = layoutSize.height * ALPHA_OF_SIZE;
101     return Vector3(width, width, width);
102   }
103 };
104
105 struct AlbumScaleConstraint
106 {
107   AlbumScaleConstraint(const float scaleRight, const float scaleLeft, const float selectedItemScale, vector<float> scaleSpread)
108   {
109      mScaleRight = scaleRight;
110      mScaleLeft = scaleLeft;
111      mSelectedItemScale = selectedItemScale;
112
113     if(scaleSpread.size() == SPREAD_ITEM_NUM)
114     {
115       mScaleVecSpread = scaleSpread;
116     }
117   }
118
119   Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
120   {
121     int begin = 0;
122     int end = 0;
123     float beginScale = 0.0f;
124     float endScale = 0.0f;
125     float scale = 0.0f;
126     float pos = layoutPosition + SELECTED_CENTER;
127
128     if(pos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
129     {
130       scale = mScaleRight;
131     }
132     else if(pos > LAYOUT_POSITION_NAGATIVE_1 && pos < LAYOUT_POSITION_0)/*items between -1.0f and 0.0f*/
133     {
134       beginScale = mScaleVecSpread.at(0);
135       endScale = mScaleRight;
136
137       scale = (endScale - beginScale) * fabs(pos) + beginScale;
138     }
139     else if(pos >= LAYOUT_POSITION_0 && pos < SELECTED_RIGHT)/*items between 0.0f and center*/
140     {
141       if(int(pos) < pos)
142       {
143         begin = int(pos);
144         end = int(pos) + 1;
145
146         beginScale = mScaleVecSpread.at(begin);
147         endScale = mScaleVecSpread.at(end);
148
149         scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
150       }
151       else
152       {
153         scale = mScaleVecSpread.at(int(pos));
154       }
155     }
156     else if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)/*items of center*/
157     {
158       scale = mSelectedItemScale;
159     }
160     else if(pos > SELECTED_LEFT && pos <= LAYOUT_POSITION_6)/*items between center and 6.0f*/
161     {
162       if(int(pos) < pos)
163       {
164         begin = int(pos)-1;
165         end = int(pos);
166
167         beginScale = mScaleVecSpread.at(begin);
168         endScale = mScaleVecSpread.at(end);
169
170         scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
171       }
172       else
173       {
174         scale = mScaleVecSpread.at(int(pos)-1);
175       }
176     }
177     else if(pos > LAYOUT_POSITION_6 && pos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
178     {
179       beginScale = mScaleVecSpread.at(5);
180       endScale = mScaleLeft;
181
182       scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
183     }
184     else if(pos >= LAYOUT_POSITION_7)/*items of left stack*/
185     {
186       scale = mScaleLeft;
187     }
188     else
189     {
190       scale = 1.0f;
191     }
192
193     return Vector3(scale,scale,1.0f);
194   }
195
196   float mScaleRight;
197   float mScaleLeft;
198   float mSelectedItemScale;
199   vector<float> mScaleVecSpread;
200 };
201
202 Vector3 CalculatePosition(Vector3 pos, float rotateX)
203 {
204   pos.z = pos.z - fabs(pos.y - LINE_OF_BOTTOM) * sinf(rotateX) / cosf(rotateX);
205   return pos;
206 }
207
208 Vector3 CalculateStackPosition(Vector3 pos, float rotateX, int num, bool left)
209 {
210   pos.z = pos.z - fabs(pos.y - LINE_OF_BOTTOM) * sinf(rotateX) / cosf(rotateX);
211
212   if(left)
213   {
214     pos.x = pos.x + num * ALPHA;
215   }
216   else
217   {
218     pos.x = pos.x - num * ALPHA;
219   }
220
221   pos.y -= num * ALBUM_HIGHT * sinf(rotateX);
222   pos.z += num * ALBUM_HIGHT * cosf(rotateX);
223
224   return pos;
225 }
226
227 Vector3 GetPosition(float layoutPos, Vector3 posRight, Vector3 posLeft, Vector3 posSelectedItem, vector<Vector3> posVecSpread, float rotateX)
228 {
229   int begin =0;
230   int end = 0;
231
232   float alpha = 0.0f;
233
234   Vector3 beginPos =  Vector3::ZERO;
235   Vector3 endPos = Vector3::ZERO;
236
237   Vector3 pos = Vector3::ZERO;
238
239   if(layoutPos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
240   {
241     if(int(layoutPos) > layoutPos)
242     {
243       begin = int(layoutPos);
244       end = int(layoutPos)-1;
245
246       beginPos = CalculateStackPosition(posRight, rotateX, int(LAYOUT_POSITION_NAGATIVE_1) - int(layoutPos),false);
247
248       endPos = CalculateStackPosition(posRight, rotateX, - int(layoutPos),false);
249
250       alpha = fabs(layoutPos - int(layoutPos));
251
252       pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
253       pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
254       pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
255
256       return pos;
257     }
258     else
259     {
260       return CalculateStackPosition(posRight,rotateX,int(LAYOUT_POSITION_NAGATIVE_1) - int(layoutPos),false);
261     }
262   }
263   else if(layoutPos < LAYOUT_POSITION_0 && layoutPos > LAYOUT_POSITION_NAGATIVE_1)/*items between -1.0f and 0.0f*/
264   {
265     beginPos = CalculatePosition(posVecSpread.at(int(LAYOUT_POSITION_0)),rotateX);
266     endPos = CalculateStackPosition(posRight, rotateX, int(layoutPos),false);
267
268     alpha = -layoutPos;
269
270     pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
271     pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
272     pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
273
274     return pos;
275   }
276   else if(layoutPos >= LAYOUT_POSITION_0 && layoutPos <= LAYOUT_POSITION_2)/*items between 0.0f and 2.0f*/
277   {
278     if(int(layoutPos) < layoutPos)
279     {
280       begin = int(layoutPos);
281       end = int(layoutPos) + 1;
282
283       beginPos = posVecSpread.at(begin);
284       endPos = posVecSpread.at(end);
285
286       alpha = fabs(layoutPos - int(layoutPos));
287
288       pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
289       pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
290       pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
291     }
292     else
293     {
294       pos = posVecSpread.at(int(layoutPos));
295     }
296   }
297   else if(layoutPos >LAYOUT_POSITION_2 && layoutPos<SELECTED_RIGHT)/*items between 2.0f and center*/
298   {
299     beginPos = posVecSpread.at(int(LAYOUT_POSITION_2));
300     endPos = VIRTUAL_ITEM_POSITION_RIGHT;
301
302     alpha = (layoutPos - LAYOUT_POSITION_2) / (SELECTED_RIGHT - LAYOUT_POSITION_2);
303
304     pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
305     pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
306     pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
307   }
308   else if(layoutPos > SELECTED_LEFT && layoutPos < LAYOUT_POSITION_4)/*items between center and 4.0f*/
309   {
310     beginPos = posVecSpread.at(int(LAYOUT_POSITION_3));
311     endPos = VIRTUAL_ITEM_POSITION_LEFT;
312
313     alpha = (LAYOUT_POSITION_4 - layoutPos) / (LAYOUT_POSITION_4 - SELECTED_LEFT);
314
315     pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
316     pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
317     pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
318   }
319   else if(layoutPos >= LAYOUT_POSITION_4 && layoutPos <= LAYOUT_POSITION_6)/*items between 4.0f and 6.0f*/
320   {
321     if(int(layoutPos) < layoutPos)
322     {
323       begin = int(layoutPos);
324       end = int(layoutPos) + 1;
325
326       beginPos = posVecSpread.at(begin - 1);
327       endPos = posVecSpread.at(end - 1);
328
329       alpha = fabs(layoutPos - int(layoutPos));
330
331       pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
332       pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
333       pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
334     }
335     else
336     {
337       pos = posVecSpread.at(int(layoutPos) -1);
338     }
339   }
340   else if(layoutPos > LAYOUT_POSITION_6 && layoutPos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
341   {
342     beginPos = CalculatePosition(posVecSpread.at(int(LAYOUT_POSITION_6) - 1),rotateX);
343     endPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) + 1 - int(LAYOUT_POSITION_7),true);
344
345     alpha = fabs(layoutPos - int(layoutPos));
346
347     pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
348     pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
349     pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
350
351     return pos;
352   }
353   else if(layoutPos >= LAYOUT_POSITION_7)/*items of left stack*/
354   {
355     if(int(layoutPos) < layoutPos)
356     {
357       begin = int(layoutPos);
358       end = int(layoutPos) + 1;
359
360       beginPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) - int(LAYOUT_POSITION_7),true);
361
362       endPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) + 1 - int(LAYOUT_POSITION_7),true);
363
364       alpha = fabs(layoutPos - int(layoutPos));
365
366       pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
367       pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
368       pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
369
370       return pos;
371     }
372     else
373     {
374       return CalculateStackPosition(posLeft, rotateX, int(layoutPos) - int(LAYOUT_POSITION_7),true);
375     }
376   }
377
378   return CalculatePosition(pos,rotateX);
379 }
380
381 struct AlbumPositionConstraint
382 {
383   AlbumPositionConstraint(const Vector3 posRight, const Vector3 posLeft, const Vector3 posSelectedItem, const vector<Vector3> posVecSpread, float rotateX)
384   {
385     mPositionRight = posRight;
386     mPositionLeft = posLeft;
387     mSelectedItemPosition = posSelectedItem;
388     mRotationX = rotateX;
389
390     if(posVecSpread.size() == SPREAD_ITEM_NUM)
391     {
392       mPositionVecSpread = posVecSpread;
393     }
394   }
395
396   Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
397   {
398     float pos = layoutPosition + SELECTED_CENTER;
399
400     /*handle if the item is selected item(in the center)*/
401     if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)
402     {
403       return SELECTED_ITEM_POSITION;
404     }
405
406     /*get the spread items position*/
407     return GetPosition(pos,mPositionRight,mPositionLeft,mSelectedItemPosition,mPositionVecSpread,mRotationX);
408   }
409
410   Vector3 mPositionRight;
411   Vector3 mPositionLeft;
412   Vector3 mSelectedItemPosition;
413   vector<Vector3> mPositionVecSpread;
414   float mRotationX;
415  };
416
417 Quaternion GetRotation(float layoutPos, vector<float> rotateVecStack, vector<float> rotateVecSpread, float rotateX)
418 {
419   int begin =0;
420   int end = 0;
421
422   float alpha = 0.0f;
423
424   float beginRotation = 0.0f;
425   float endRotation = 0.0f;
426
427   float rotation = 0.0f;
428   if(layoutPos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
429   {
430     if(int(layoutPos) > layoutPos)
431     {
432       begin = int(layoutPos) + 1;
433       end = int(layoutPos);
434
435       begin *= -1;
436       end *= -1;
437
438       beginRotation = rotateVecStack.at(begin);
439       endRotation = rotateVecStack.at(end);
440
441       alpha = fabs(layoutPos - int(layoutPos));
442
443       rotation = (endRotation - beginRotation) * alpha + beginRotation;
444     }
445     else
446     {
447       rotation = rotateVecStack.at(-int(layoutPos)-1);
448     }
449   }
450   else if(layoutPos > LAYOUT_POSITION_NAGATIVE_1 && layoutPos < LAYOUT_POSITION_0)/*items between -1.0f and 0.0f*/
451   {
452     begin = 0;
453     end = 0;
454
455     beginRotation = rotateVecSpread.at(begin);
456     endRotation = rotateVecStack.at(end);
457
458     alpha = fabs(layoutPos);
459
460     rotation = (endRotation - beginRotation) * alpha + beginRotation;
461   }
462   else if(layoutPos >= LAYOUT_POSITION_0 && layoutPos < LAYOUT_POSITION_3)
463   {
464     if(int(layoutPos) < layoutPos)
465     {
466       begin = int(layoutPos);
467       end = int(layoutPos) + 1;
468
469       beginRotation = rotateVecSpread.at(begin);
470       endRotation = rotateVecSpread.at(end);
471
472       alpha = fabs(layoutPos - int(layoutPos));
473
474       rotation = (endRotation - beginRotation) * alpha + beginRotation;
475     }
476     else
477     {
478       rotation = rotateVecSpread.at(int(layoutPos));
479     }
480   }
481   else if(layoutPos > LAYOUT_POSITION_3 && layoutPos <= LAYOUT_POSITION_6)
482   {
483     if(int(layoutPos) < layoutPos)
484     {
485       begin = int(layoutPos) - 1;
486       end = int(layoutPos);
487
488       beginRotation = rotateVecSpread.at(begin);
489       endRotation = rotateVecSpread.at(end);
490
491       alpha = fabs(layoutPos - int(layoutPos));
492
493       rotation = (endRotation - beginRotation) * alpha + beginRotation;
494     }
495     else
496     {
497       rotation = rotateVecSpread.at(int(layoutPos)-1);
498     }
499   }
500   else if(layoutPos > LAYOUT_POSITION_6 && layoutPos < LAYOUT_POSITION_7)
501   {
502     begin = 5;
503     end = 0;
504
505     beginRotation = rotateVecSpread.at(begin);
506     endRotation = rotateVecStack.at(end);
507
508     alpha = fabs(layoutPos - int(LAYOUT_POSITION_6));
509
510     rotation = (endRotation - beginRotation) * alpha + beginRotation;
511   }
512   else if(layoutPos >= LAYOUT_POSITION_7)
513   {
514     if(int(layoutPos) < layoutPos)
515     {
516       begin = int(layoutPos) - int(LAYOUT_POSITION_7);
517       end = int(layoutPos) - int(LAYOUT_POSITION_7) + 1;
518
519       beginRotation = rotateVecStack.at(begin);
520       endRotation = rotateVecStack.at(end);
521
522       alpha = fabs(layoutPos - int(layoutPos));
523
524       rotation = (endRotation - beginRotation) * alpha + beginRotation;
525     }
526     else
527     {
528       rotation = rotateVecStack.at(int(layoutPos)-int(LAYOUT_POSITION_7));
529     }
530   }
531
532   return Quaternion(rotateX, Vector3::XAXIS) * Quaternion(rotation, Vector3::ZAXIS);
533 }
534
535 struct AlbumRotationConstraint
536 {
537   AlbumRotationConstraint(const vector<float> rotatVecSpread, const vector<float> rotatVecStack, const float rotateX, int num)
538   {
539     mRotationX = rotateX;
540     mNumOfItems = num;
541     mIndex = 0;
542     mLastIndex = 0;
543     mLeft = SCROLL_NONE;
544     mLastPosition = 0.0f;
545     mTimes = 0;
546
547     if(rotatVecSpread.size() == SPREAD_ITEM_NUM)
548     {
549       mRotationVecSpread = rotatVecSpread;
550     }
551
552     mRotationVecStack = rotatVecStack;
553   }
554
555   Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
556   {
557     float pos = layoutPosition + SELECTED_CENTER;
558
559     if(mIndex == mNumOfItems)
560     {
561       mIndex = 0;
562     }
563
564     mIndex ++;
565
566     if(mLastIndex != mIndex)
567     {
568       mLastIndex = mIndex;
569
570       if(mLeft == SCROLL_RIGHT)
571       {
572         if(pos > mLastPosition + THRESHHOLD_OF_MOVING)
573         {
574           mTimes = 0;
575           mLeft = SCROLL_LEFT;
576         }
577         else if(pos < mLastPosition)
578         {
579           mTimes = 0;
580           mLeft = SCROLL_RIGHT;
581         }
582         else
583         {
584           mTimes++;
585           if(mTimes > NUM_OF_FRAME_FILTERED)
586           {
587             mTimes = 0;
588             mLeft = SCROLL_NONE;
589           }
590         }
591       }
592       else if(mLeft == SCROLL_LEFT)
593       {
594         if(pos > mLastPosition)
595         {
596           mTimes = 0;
597           mLeft = SCROLL_LEFT;
598         }
599         else if(pos < mLastPosition - THRESHHOLD_OF_MOVING)
600         {
601           mTimes = 0;
602           mLeft = SCROLL_RIGHT;
603         }
604         else
605         {
606           mTimes++;
607           if(mTimes > NUM_OF_FRAME_FILTERED)
608           {
609             mTimes = 0;
610             mLeft = SCROLL_NONE;
611           }
612         }
613       }
614       else
615       {
616         if(pos < mLastPosition)
617         {
618           mLeft = SCROLL_RIGHT;
619         }
620         else if(pos > mLastPosition)
621         {
622           mLeft = SCROLL_LEFT;
623         }
624         else
625         {
626           mLeft = SCROLL_NONE;
627         }
628       }
629
630       mLastPosition = pos;
631
632      /*rotation for the selected item(center)*/
633      if(pos >= SELECTED_RIGHT && pos < SELECTED_LEFT)
634      {
635        if(mLeft == SCROLL_LEFT)
636        {
637          return Quaternion(-fabs(SELECTED_CENTER - pos), Vector3::YAXIS);
638        }
639        else if(mLeft == SCROLL_RIGHT)
640        {
641          return Quaternion(fabs(pos - SELECTED_CENTER), Vector3::YAXIS);
642        }
643        else
644        {
645          return Quaternion(0.0f, Vector3::YAXIS);
646        }
647      }
648     }
649
650     /*rotation for the spread item*/
651     return GetRotation(pos,mRotationVecStack,mRotationVecSpread,mRotationX);
652   }
653
654   vector<float> mRotationVecSpread;
655   vector<float> mRotationVecStack;
656   float mRotationX;
657   Actor mScrollDirectionActor;
658   int mLastIndex;
659   int mIndex;
660   int mNumOfItems;
661   int mTimes;
662   ScrollDirection mLeft;
663   float mLastPosition;
664 };
665
666 struct AlbumColorConstraint
667 {
668   AlbumColorConstraint(const Vector2 colorRight, const Vector2 colorLeft, const Vector2 colorSelectedItem, const vector<Vector2> spreadVecColor, const int stackNum)
669   {
670     mColorRight = colorRight;
671     mColorLeft = colorLeft;
672     mSelectedItemColor = colorSelectedItem;
673     mStackNum = stackNum;
674
675     if(spreadVecColor.size() == SPREAD_ITEM_NUM)
676     {
677       mColorVecSpread = spreadVecColor;
678     }
679   }
680
681   Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
682   {
683     float black = 1.0f;
684     Vector4 color = current;
685     float pos = layoutPosition + SELECTED_CENTER;
686     Vector2 temp = Vector2(0.0f,0.0f);
687
688     int begin = 0;
689     int end = 0;
690
691     Vector2 beginColor = Vector2(0.0f,0.0f);
692     Vector2 endColor = Vector2(0.0f,0.0f);
693
694     if(pos <= -mStackNum-1)
695     {
696       color.w = 0.0f;
697       black = 0.0f;
698     }
699     else if(pos > -mStackNum-1 && pos < -mStackNum)
700     {
701       beginColor = mColorRight;
702       endColor = Vector2(0.0f,0.0f);
703
704       color.w = (endColor.x - beginColor.x) * fabs(pos - int(pos)) + beginColor.x;
705       black = (endColor.y - beginColor.y) * fabs(pos - int(pos)) + beginColor.y;
706     }
707     else if(pos <= LAYOUT_POSITION_NAGATIVE_1 && pos >= -mStackNum)
708     {
709       color.w = mColorRight.x;
710       black = mColorRight.y;
711     }
712     else if(pos > LAYOUT_POSITION_NAGATIVE_1 && pos < LAYOUT_POSITION_0)
713     {
714       beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_0));
715       endColor = mColorRight;
716
717       color.w = (endColor.x - beginColor.x) * fabs(pos) + beginColor.x;
718       black = (endColor.y - beginColor.y) * fabs(pos) + beginColor.y;
719     }
720     else if(pos >= LAYOUT_POSITION_0 && pos  <= LAYOUT_POSITION_2)
721     {
722       if(int(pos) < pos)
723       {
724         begin = int(pos);
725         end = int(pos) + 1;
726
727         beginColor = mColorVecSpread.at(begin);
728         endColor = mColorVecSpread.at(end);
729
730         temp = (endColor - beginColor) * fabs(pos - int(pos)) + beginColor;
731
732         color.w = temp.x;
733         black = temp.y;
734       }
735       else
736       {
737         beginColor = mColorVecSpread.at(int(pos));
738
739         color.w = beginColor.x;
740         black = beginColor.y;
741       }
742     }
743     else if(pos  > LAYOUT_POSITION_2 && pos < SELECTED_RIGHT)/*items between 2.0f and center*/
744     {
745       beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_2));
746       endColor = Vector2(0.0f,0.0f);
747
748       temp = (endColor - beginColor) * (pos - LAYOUT_POSITION_2)/(SELECTED_RIGHT - LAYOUT_POSITION_2) + beginColor;
749
750       color.w = temp.x;
751       black = temp.y;
752     }
753     else if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)/*items of center*/
754     {
755       color.w = mSelectedItemColor.x;
756       black = mSelectedItemColor.y;
757     }
758     else if(pos  > SELECTED_LEFT && pos < LAYOUT_POSITION_4)/*items between center and 4.0f*/
759     {
760       beginColor = Vector2(0.0f,0.0f);
761       endColor = mColorVecSpread.at(int(LAYOUT_POSITION_3));
762
763       temp = (endColor - beginColor) * (pos - SELECTED_LEFT)/(LAYOUT_POSITION_4 - SELECTED_LEFT) + beginColor;
764
765       color.w = temp.x;
766       black = temp.y;
767     }
768     else if(pos >= LAYOUT_POSITION_4 && pos <= LAYOUT_POSITION_6)/*items between 4.0f and 6.0f*/
769     {
770       if(int(pos) < pos)
771       {
772         begin = int(pos) - 1;
773         end = int(pos);
774
775         beginColor = mColorVecSpread.at(begin);
776         endColor = mColorVecSpread.at(end);
777
778         temp = (endColor - beginColor) * fabs(pos - int(pos)) + beginColor;
779
780         color.w = temp.x;
781         black = temp.y;
782       }
783       else
784       {
785         beginColor = mColorVecSpread.at(int(pos) -  1);
786
787         color.w = beginColor.x;
788         black = beginColor.y;
789       }
790     }
791     else if(pos > LAYOUT_POSITION_6 && pos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
792     {
793       beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_6) - 1);
794       endColor = mColorLeft;
795
796       color.w = (endColor.x - beginColor.x) * fabs(pos - int(pos)) + beginColor.x;
797       black = (endColor.y - beginColor.y) * fabs(pos - int(pos)) + beginColor.y;
798     }
799     else if(pos >= LAYOUT_POSITION_7 && pos <= mStackNum + int(LAYOUT_POSITION_7))/*items of left stack*/
800     {
801       color.w = mColorLeft.x;
802       black = mColorLeft.y;
803     }
804     else if(pos > mStackNum + int(LAYOUT_POSITION_7) && pos < mStackNum + int(LAYOUT_POSITION_7) + 1)
805     {
806       beginColor = mColorLeft;
807       endColor = Vector2(0.0f,0.0f);
808
809       color.w = (endColor.x - beginColor.x) * fabs(pos - int(pos)) + beginColor.x;
810       black = (endColor.y - beginColor.y) * fabs(pos - int(pos)) + beginColor.y;
811     }
812     else if(pos >= mStackNum + int(LAYOUT_POSITION_7) +1)
813     {
814       color.w = 0.0f;
815       black = 0.0f;
816     }
817
818     color.r = color.r * black;
819     color.g = color.g * black;
820     color.b = color.b * black;
821
822     return color;
823   }
824
825   int mStackNum;
826   Vector2 mColorRight;
827   Vector2 mColorLeft;
828   Vector2 mSelectedItemColor;
829   vector<Vector2> mColorVecSpread;
830 };
831
832 struct AlbumVisibilityConstraintPortrait
833 {
834   AlbumVisibilityConstraintPortrait()
835   {
836   }
837
838   bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
839   {
840     return true;
841   }
842 };
843
844 } // unnamed namespace
845
846 namespace Dali
847 {
848
849 namespace Toolkit
850 {
851
852 struct AlbumLayout::Impl
853 {
854   Impl()
855   : mItemSizeFunction(DefaultItemSizeFunction()),
856     mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
857     mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
858     mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION),
859     mNumOfItems(0)
860   {
861     /*Initialize the variables*/
862     mSelectedItemScale = SELECETED_ITEM_SCALE;
863     mRotationX = ROTATION_X;
864     mScaleRight = SCALE_RIGHT;
865     mScaleLeft = SCALE_LEFT;
866     mRotationRight = ROTATION_RIGHT;
867     mRotationLeft = ROTATION_LEFT;
868     mSelectedItemColor = SELECTED_ITEM_COLOR;
869     mSelectedItemPosition = SELECTED_ITEM_POSITION;
870     mColorRight = COLOR_RIGHT;
871     mColorLeft = COLOR_LEFT;
872     mPositionRight = POSITION_RIGHT;
873     mPositionLeft = POSITION_LEFT;
874     mStackNum = 50;
875
876     /*Initialize the position of spread items*/
877     mPositionVecSpread.push_back(POSITION_0);
878     mPositionVecSpread.push_back(POSITION_1);
879     mPositionVecSpread.push_back(POSITION_2);
880     mPositionVecSpread.push_back(POSITION_4);
881     mPositionVecSpread.push_back(POSITION_5);
882     mPositionVecSpread.push_back(POSITION_6);
883
884     /*Initialize the rotation of spread items*/
885     mRotationVecSpread.push_back(ROTATION_0);
886     mRotationVecSpread.push_back(ROTATION_1);
887     mRotationVecSpread.push_back(ROTATION_2);
888     mRotationVecSpread.push_back(ROTATION_4);
889     mRotationVecSpread.push_back(ROTATION_5);
890     mRotationVecSpread.push_back(ROTATION_6);
891
892     /*Initialize the scale of spread items*/
893     for(unsigned int i=0; i<SPREAD_ITEM_NUM; i++)
894     {
895       mScaleVecSpread.push_back(SCALE);
896     }
897
898     /*Initialize the color of spread items*/
899     for(unsigned int i=0; i<SPREAD_ITEM_NUM; i++)
900     {
901       mColorVecSpread.push_back(COLOR);
902     }
903   }
904
905   void SetPosition(vector<Vector3> positionList)
906   {
907     if(positionList.size() == SPREAD_ITEM_NUM)
908     {
909       mPositionVecSpread = positionList;
910     }
911   }
912
913   vector<Vector3> GetPosition() const
914   {
915     return mPositionVecSpread;
916   }
917
918   void SetColor(vector<Vector2> colorList)
919   {
920     if(colorList.size() == SPREAD_ITEM_NUM)
921     {
922       mColorVecSpread = colorList;
923     }
924   }
925
926   vector<Vector2> GetColor() const
927   {
928     return mColorVecSpread;
929   }
930
931   void SetScale(vector<float> scaleList)
932   {
933     if(scaleList.size() == SPREAD_ITEM_NUM)
934     {
935       mScaleVecSpread = scaleList;
936     }
937   }
938
939   vector<float> GetScale() const
940   {
941     return mScaleVecSpread;
942   }
943
944   void SetRotationX(float rotat_x)
945   {
946     mRotationX = rotat_x;
947   }
948
949   float GetRotationX() const
950   {
951     return mRotationX;
952   }
953
954   void SetRotationZ(vector<float> rotationList)
955   {
956     if(rotationList.size() == SPREAD_ITEM_NUM)
957     {
958       mRotationVecSpread = rotationList;
959     }
960   }
961
962   vector<float> GetRotationZ() const
963   {
964     return mRotationVecSpread;
965   }
966
967   void SetCenterPosition(Vector3 pos)
968   {
969     mSelectedItemPosition = pos;
970   }
971
972   Vector3 GetCenterPosition() const
973   {
974     return mSelectedItemPosition;
975   }
976
977   void SetCenterScale(float scale)
978   {
979     mSelectedItemScale = scale;
980   }
981
982   float GetCenterScale() const
983   {
984     return mSelectedItemScale;
985   }
986
987   void SetCenterColor(Vector2 color)
988   {
989     mSelectedItemColor = color;
990   }
991
992   Vector2 GetCenterColor() const
993   {
994     return mSelectedItemColor;
995   }
996
997   void SetStackPosition(Vector3 rightPos, Vector3 leftPos)
998   {
999     mPositionRight = rightPos;
1000     mPositionLeft = leftPos;
1001   }
1002
1003   Vector3 GetRightStackPosition() const
1004   {
1005     return mPositionRight;
1006   }
1007
1008   Vector3 GetLeftStackPosition() const
1009   {
1010     return mPositionLeft;
1011   }
1012
1013   void SetStackScale(float rightScale, float leftScale)
1014   {
1015     mScaleRight = rightScale;
1016     mScaleLeft = leftScale;
1017   }
1018
1019   float GetRightStackScale() const
1020   {
1021     return mScaleRight;
1022   }
1023
1024   float GetLeftStackScale() const
1025   {
1026     return mScaleLeft;
1027   }
1028
1029   void SetStackColor(Vector2 rightColor, Vector2 leftColor)
1030   {
1031     mColorRight = rightColor;
1032     mColorLeft = leftColor;
1033   }
1034
1035   Vector2 GetRightStackColor() const
1036   {
1037     return mColorRight;
1038   }
1039
1040   Vector2 GetLeftStackColor() const
1041   {
1042     return mColorLeft;
1043   }
1044
1045   void SetNumOfItems(int num)
1046   {
1047     mNumOfItems = num;
1048
1049     /*Initialize the rotation of stack items*/
1050     for(int i=0; i<mNumOfItems; i++)
1051     {
1052       if(Random::Chance(CHANCE_OF_RANDOM_ROTATION_OF_STACK))
1053       {
1054         mRotationVecStack.push_back(Random::Range(-RANGE_OF_RANDOM_ROTATION_OF_STACK,RANGE_OF_RANDOM_ROTATION_OF_STACK));
1055       }
1056       else
1057       {
1058         mRotationVecStack.push_back(0.0f);
1059       }
1060     }
1061   }
1062
1063   int GetNumOfItems() const
1064   {
1065     return mNumOfItems;
1066   }
1067
1068   void SetStackNum(int num)
1069   {
1070     mStackNum = num;
1071   }
1072
1073   int GetStackNum() const
1074   {
1075     return mStackNum;
1076   }
1077
1078   ItemSizeFunction mItemSizeFunction;
1079
1080   float mScrollSpeedFactor;
1081   float mMaximumSwipeSpeed;
1082   float mItemFlickAnimationDuration;
1083
1084   Vector3 mSelectedItemPosition;/*position of selected item*/
1085   float mSelectedItemScale;/*scale of selected item*/
1086   Vector2 mSelectedItemColor;/*color of selected item*/
1087
1088   float mRotationX;/*rotation around X*/
1089
1090   vector<Vector3> mPositionVecSpread;/*positions of the spread items*/
1091   vector<float> mRotationVecSpread;/*rotations of the spread items*/
1092   vector<float> mScaleVecSpread;/*scales of the spread items*/
1093   vector<Vector2> mColorVecSpread;/*colors of the spread items*/
1094
1095   vector<float> mRotationVecStack;/*rotations of the stack items*/
1096
1097   float mRotationRight;/*rotation of right album stack*/
1098   float mRotationLeft;/*rotation of left album stack*/
1099
1100   float mScaleRight;/*scale of right album stack*/
1101   float mScaleLeft;/*scale of left album stack*/
1102
1103   Vector2 mColorRight;/*color of right album stack*/
1104   Vector2 mColorLeft;/*color of left album stack*/
1105
1106   Vector3 mPositionRight;/*position of right album stack*/
1107   Vector3 mPositionLeft;/*position of left album stack*/
1108
1109   int mNumOfItems;/*num of items*/
1110   int mStackNum;/*num of items of stack*/
1111 };
1112
1113 AlbumLayoutPtr AlbumLayout::New()
1114 {
1115   return AlbumLayoutPtr(new AlbumLayout());
1116 }
1117
1118 AlbumLayout::~AlbumLayout()
1119 {
1120   delete mImpl;
1121 }
1122
1123 void AlbumLayout::SetItemSizeFunction(ItemSizeFunction function)
1124 {
1125   mImpl->mItemSizeFunction = function;
1126 }
1127
1128 AlbumLayout::ItemSizeFunction AlbumLayout::GetItemSizeFunction() const
1129 {
1130   return mImpl->mItemSizeFunction;
1131 }
1132
1133 void AlbumLayout::SetScrollSpeedFactor(float scrollSpeed)
1134 {
1135   mImpl->mScrollSpeedFactor = scrollSpeed;
1136 }
1137
1138 void AlbumLayout::SetMaximumSwipeSpeed(float speed)
1139 {
1140   mImpl->mMaximumSwipeSpeed = speed;
1141 }
1142
1143 void AlbumLayout::SetItemFlickAnimationDuration(float durationSeconds)
1144 {
1145   mImpl->mItemFlickAnimationDuration = durationSeconds;
1146 }
1147
1148 float AlbumLayout::GetScrollSpeedFactor() const
1149 {
1150   return mImpl->mScrollSpeedFactor;
1151 }
1152
1153 float AlbumLayout::GetMaximumSwipeSpeed() const
1154 {
1155   return mImpl->mMaximumSwipeSpeed;
1156 }
1157
1158 float AlbumLayout::GetItemFlickAnimationDuration() const
1159 {
1160   return mImpl->mItemFlickAnimationDuration;
1161 }
1162
1163 float AlbumLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
1164 {
1165   return - static_cast<float>(numberOfItems) + 1;
1166 }
1167
1168 float AlbumLayout::GetClosestAnchorPosition(float layoutPosition) const
1169 {
1170   return round(layoutPosition);
1171 }
1172
1173 float AlbumLayout::GetItemScrollToPosition(unsigned int itemId) const
1174 {
1175   return -(static_cast<float>(itemId));
1176 }
1177
1178 ItemRange AlbumLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
1179 {
1180   return ItemRange(0, mImpl->mNumOfItems);
1181 }
1182
1183 unsigned int AlbumLayout::GetReserveItemCount(Vector3 layoutSize) const
1184 {
1185   return 0;
1186 }
1187
1188 bool AlbumLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const
1189 {
1190   itemSize = mImpl->mItemSizeFunction(layoutSize);
1191   return true;
1192 }
1193
1194 void AlbumLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const
1195 {
1196   if(animation)
1197   {
1198     animation.Resize(actor, size);
1199   }
1200 }
1201
1202 bool AlbumLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
1203 {
1204   constraint = AlbumPositionConstraint(mImpl->mPositionRight,mImpl->mPositionLeft,mImpl->mSelectedItemPosition,mImpl->mPositionVecSpread,mImpl->mRotationX);
1205   return true;
1206 }
1207
1208 bool AlbumLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const
1209 {
1210   constraint = AlbumRotationConstraint(mImpl->mRotationVecSpread,mImpl->mRotationVecStack,mImpl->mRotationX,mImpl->mNumOfItems);
1211   return true;
1212 }
1213
1214 bool AlbumLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
1215 {
1216   constraint = AlbumScaleConstraint(mImpl->mScaleRight,mImpl->mScaleLeft,mImpl->mSelectedItemScale,mImpl->mScaleVecSpread);
1217   return true;
1218 }
1219
1220 bool AlbumLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const
1221 {
1222   constraint = AlbumColorConstraint(mImpl->mColorRight,mImpl->mColorLeft,mImpl->mSelectedItemColor,mImpl->mColorVecSpread,mImpl->mStackNum);
1223   return true;
1224 }
1225
1226 bool AlbumLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const
1227 {
1228   constraint = AlbumVisibilityConstraintPortrait();
1229   return true;
1230 }
1231
1232 Degree AlbumLayout::GetScrollDirection() const
1233 {
1234   Degree scrollDirection(0);
1235
1236   scrollDirection = -90.0f;
1237
1238   return scrollDirection;
1239 }
1240
1241 void AlbumLayout::SetNumOfItems(int num)
1242 {
1243   mImpl->SetNumOfItems(num);
1244 }
1245
1246 int AlbumLayout::GetNumOfItems() const
1247 {
1248   return mImpl->GetNumOfItems();
1249 }
1250
1251 void AlbumLayout::SetStackNum(int num)
1252 {
1253   mImpl->SetStackNum(num);
1254 }
1255
1256 int AlbumLayout::GetStackNum() const
1257 {
1258   return mImpl->GetStackNum();
1259 }
1260
1261 void AlbumLayout::SetPosition(vector<Vector3> positionList)
1262 {
1263   mImpl->SetPosition(positionList);
1264 }
1265
1266 vector<Vector3> AlbumLayout::GetPosition() const
1267 {
1268   return mImpl->GetPosition();
1269 }
1270
1271 void AlbumLayout::SetScale(vector<float> scaleList)
1272 {
1273   mImpl->SetScale(scaleList);
1274 }
1275
1276 vector<float> AlbumLayout::GetScale() const
1277 {
1278   return mImpl->GetScale();
1279 }
1280
1281 void AlbumLayout::SetColor(vector<Vector2> colorList)
1282 {
1283   mImpl->SetColor(colorList);
1284 }
1285
1286 vector<Vector2> AlbumLayout::GetColor() const
1287 {
1288   return mImpl->GetColor();
1289 }
1290
1291 void AlbumLayout::SetRotationX(float rotation)
1292 {
1293   mImpl->SetRotationX(rotation);
1294 }
1295
1296 float AlbumLayout::GetRotationX() const
1297 {
1298   return mImpl->GetRotationX();
1299 }
1300
1301 void AlbumLayout::SetRotationZ(vector<float> rotationList)
1302 {
1303   mImpl->SetRotationZ(rotationList);
1304 }
1305
1306 vector<float> AlbumLayout::GetRotationZ() const
1307 {
1308   return mImpl->GetRotationZ();
1309 }
1310
1311 void AlbumLayout::SetCenterPosition(Vector3 pos)
1312 {
1313   mImpl->SetCenterPosition(pos);
1314 }
1315
1316 Vector3 AlbumLayout::GetCenterPosition() const
1317 {
1318   return mImpl->GetCenterPosition();
1319 }
1320
1321 void AlbumLayout::SetCenterScale(float scale)
1322 {
1323   mImpl->SetCenterScale(scale);
1324 }
1325
1326 float AlbumLayout::GetCenterScale() const
1327 {
1328   return mImpl->GetCenterScale();
1329 }
1330
1331 void AlbumLayout::SetCenterColor(Vector2 color)
1332 {
1333   mImpl->SetCenterColor(color);
1334 }
1335
1336 Vector2 AlbumLayout::GetCenterColor() const
1337 {
1338   return mImpl->GetCenterColor();
1339 }
1340
1341 void AlbumLayout::SetStackPosition(Vector3 rightPos, Vector3 leftPos)
1342 {
1343   mImpl->SetStackPosition(rightPos, leftPos);
1344 }
1345
1346 Vector3 AlbumLayout::GetRightStackPosition() const
1347 {
1348   return mImpl->GetRightStackPosition();
1349 }
1350
1351 Vector3 AlbumLayout::GetLeftStackPosition() const
1352 {
1353   return mImpl->GetLeftStackPosition();
1354 }
1355
1356 void AlbumLayout::SetStackScale(float rightScale, float leftScale)
1357 {
1358   mImpl->SetStackScale(rightScale,leftScale);
1359 }
1360
1361 float AlbumLayout::GetRightStackScale() const
1362 {
1363   return mImpl->GetRightStackScale();
1364 }
1365
1366 float AlbumLayout::GetLeftStackScale() const
1367 {
1368   return mImpl->GetLeftStackScale();
1369 }
1370
1371 void AlbumLayout::SetStackColor(Vector2 rightColor, Vector2 leftColor)
1372 {
1373   mImpl->SetStackColor(rightColor, leftColor);
1374 }
1375
1376 Vector2 AlbumLayout::GetRightStackColor() const
1377 {
1378   return mImpl->GetRightStackColor();
1379 }
1380
1381 Vector2 AlbumLayout::GetLeftStackColor() const
1382 {
1383   return mImpl->GetLeftStackColor();
1384 }
1385
1386 AlbumLayout::AlbumLayout()
1387 : mImpl(NULL)
1388 {
1389   mImpl = new Impl();
1390 }
1391
1392 } // namespace Toolkit
1393
1394 } // namespace Dali