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