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