2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/public-api/controls/scrollable/item-view/album-layout.h>
23 #include <dali/public-api/animation/animation.h>
24 #include <dali/public-api/math/random.h>
27 using namespace Dali::Toolkit;
30 namespace // unnamed namespace
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;
36 const float SELECTED_RIGHT = 2.5f;
37 const float SELECTED_LEFT = 3.5f;
38 const float SELECTED_CENTER = 3.0f;
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;
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);
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;
62 const float SCALE = 1.0f;
64 const Vector2 COLOR = Vector2(1.0f,1.0f);
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;
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;
86 const float CHANCE_OF_RANDOM_ROTATION_OF_STACK = 0.5f;
87 const float RANGE_OF_RANDOM_ROTATION_OF_STACK = 0.5f;
89 const float THRESHHOLD_OF_MOVING = 0.02f;
90 const int NUM_OF_FRAME_FILTERED = 5;
92 const unsigned int SPREAD_ITEM_NUM = 6;
101 struct DefaultItemSizeFunction
103 Vector3 operator()(const Vector3& layoutSize)
105 float width = layoutSize.height * ALPHA_OF_SIZE;
106 return Vector3(width, width, width);
110 struct AlbumScaleConstraint
112 AlbumScaleConstraint(const float scaleRight, const float scaleLeft, const float selectedItemScale, vector<float> scaleSpread)
114 mScaleRight = scaleRight;
115 mScaleLeft = scaleLeft;
116 mSelectedItemScale = selectedItemScale;
118 if(scaleSpread.size() == SPREAD_ITEM_NUM)
120 mScaleVecSpread = scaleSpread;
124 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
128 float beginScale = 0.0f;
129 float endScale = 0.0f;
131 float pos = layoutPosition + SELECTED_CENTER;
133 if(pos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
137 else if(pos > LAYOUT_POSITION_NAGATIVE_1 && pos < LAYOUT_POSITION_0)/*items between -1.0f and 0.0f*/
139 beginScale = mScaleVecSpread.at(0);
140 endScale = mScaleRight;
142 scale = (endScale - beginScale) * fabs(pos) + beginScale;
144 else if(pos >= LAYOUT_POSITION_0 && pos < SELECTED_RIGHT)/*items between 0.0f and center*/
151 beginScale = mScaleVecSpread.at(begin);
152 endScale = mScaleVecSpread.at(end);
154 scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
158 scale = mScaleVecSpread.at(int(pos));
161 else if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)/*items of center*/
163 scale = mSelectedItemScale;
165 else if(pos > SELECTED_LEFT && pos <= LAYOUT_POSITION_6)/*items between center and 6.0f*/
172 beginScale = mScaleVecSpread.at(begin);
173 endScale = mScaleVecSpread.at(end);
175 scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
179 scale = mScaleVecSpread.at(int(pos)-1);
182 else if(pos > LAYOUT_POSITION_6 && pos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
184 beginScale = mScaleVecSpread.at(5);
185 endScale = mScaleLeft;
187 scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
189 else if(pos >= LAYOUT_POSITION_7)/*items of left stack*/
198 return Vector3(scale,scale,1.0f);
203 float mSelectedItemScale;
204 vector<float> mScaleVecSpread;
207 Vector3 CalculatePosition(Vector3 pos, float rotateX)
209 pos.z = pos.z - fabs(pos.y - LINE_OF_BOTTOM) * sinf(rotateX) / cosf(rotateX);
213 Vector3 CalculateStackPosition(Vector3 pos, float rotateX, int num, bool left)
215 pos.z = pos.z - fabs(pos.y - LINE_OF_BOTTOM) * sinf(rotateX) / cosf(rotateX);
219 pos.x = pos.x + num * ALPHA;
223 pos.x = pos.x - num * ALPHA;
226 pos.y -= num * ALBUM_HIGHT * sinf(rotateX);
227 pos.z += num * ALBUM_HIGHT * cosf(rotateX);
232 Vector3 GetPosition(float layoutPos, Vector3 posRight, Vector3 posLeft, Vector3 posSelectedItem, vector<Vector3> posVecSpread, float rotateX)
239 Vector3 beginPos = Vector3::ZERO;
240 Vector3 endPos = Vector3::ZERO;
242 Vector3 pos = Vector3::ZERO;
244 if(layoutPos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
246 if(int(layoutPos) > layoutPos)
248 begin = int(layoutPos);
249 end = int(layoutPos)-1;
251 beginPos = CalculateStackPosition(posRight, rotateX, int(LAYOUT_POSITION_NAGATIVE_1) - int(layoutPos),false);
253 endPos = CalculateStackPosition(posRight, rotateX, - int(layoutPos),false);
255 alpha = fabs(layoutPos - int(layoutPos));
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;
265 return CalculateStackPosition(posRight,rotateX,int(LAYOUT_POSITION_NAGATIVE_1) - int(layoutPos),false);
268 else if(layoutPos < LAYOUT_POSITION_0 && layoutPos > LAYOUT_POSITION_NAGATIVE_1)/*items between -1.0f and 0.0f*/
270 beginPos = CalculatePosition(posVecSpread.at(int(LAYOUT_POSITION_0)),rotateX);
271 endPos = CalculateStackPosition(posRight, rotateX, int(layoutPos),false);
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;
281 else if(layoutPos >= LAYOUT_POSITION_0 && layoutPos <= LAYOUT_POSITION_2)/*items between 0.0f and 2.0f*/
283 if(int(layoutPos) < layoutPos)
285 begin = int(layoutPos);
286 end = int(layoutPos) + 1;
288 beginPos = posVecSpread.at(begin);
289 endPos = posVecSpread.at(end);
291 alpha = fabs(layoutPos - int(layoutPos));
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;
299 pos = posVecSpread.at(int(layoutPos));
302 else if(layoutPos >LAYOUT_POSITION_2 && layoutPos<SELECTED_RIGHT)/*items between 2.0f and center*/
304 beginPos = posVecSpread.at(int(LAYOUT_POSITION_2));
305 endPos = VIRTUAL_ITEM_POSITION_RIGHT;
307 alpha = (layoutPos - LAYOUT_POSITION_2) / (SELECTED_RIGHT - LAYOUT_POSITION_2);
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;
313 else if(layoutPos > SELECTED_LEFT && layoutPos < LAYOUT_POSITION_4)/*items between center and 4.0f*/
315 beginPos = posVecSpread.at(int(LAYOUT_POSITION_3));
316 endPos = VIRTUAL_ITEM_POSITION_LEFT;
318 alpha = (LAYOUT_POSITION_4 - layoutPos) / (LAYOUT_POSITION_4 - SELECTED_LEFT);
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;
324 else if(layoutPos >= LAYOUT_POSITION_4 && layoutPos <= LAYOUT_POSITION_6)/*items between 4.0f and 6.0f*/
326 if(int(layoutPos) < layoutPos)
328 begin = int(layoutPos);
329 end = int(layoutPos) + 1;
331 beginPos = posVecSpread.at(begin - 1);
332 endPos = posVecSpread.at(end - 1);
334 alpha = fabs(layoutPos - int(layoutPos));
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;
342 pos = posVecSpread.at(int(layoutPos) -1);
345 else if(layoutPos > LAYOUT_POSITION_6 && layoutPos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
347 beginPos = CalculatePosition(posVecSpread.at(int(LAYOUT_POSITION_6) - 1),rotateX);
348 endPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) + 1 - int(LAYOUT_POSITION_7),true);
350 alpha = fabs(layoutPos - int(layoutPos));
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;
358 else if(layoutPos >= LAYOUT_POSITION_7)/*items of left stack*/
360 if(int(layoutPos) < layoutPos)
362 begin = int(layoutPos);
363 end = int(layoutPos) + 1;
365 beginPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) - int(LAYOUT_POSITION_7),true);
367 endPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) + 1 - int(LAYOUT_POSITION_7),true);
369 alpha = fabs(layoutPos - int(layoutPos));
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;
379 return CalculateStackPosition(posLeft, rotateX, int(layoutPos) - int(LAYOUT_POSITION_7),true);
383 return CalculatePosition(pos,rotateX);
386 struct AlbumPositionConstraint
388 AlbumPositionConstraint(const Vector3 posRight, const Vector3 posLeft, const Vector3 posSelectedItem, const vector<Vector3> posVecSpread, float rotateX)
390 mPositionRight = posRight;
391 mPositionLeft = posLeft;
392 mSelectedItemPosition = posSelectedItem;
393 mRotationX = rotateX;
395 if(posVecSpread.size() == SPREAD_ITEM_NUM)
397 mPositionVecSpread = posVecSpread;
401 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
403 float pos = layoutPosition + SELECTED_CENTER;
405 /*handle if the item is selected item(in the center)*/
406 if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)
408 return SELECTED_ITEM_POSITION;
411 /*get the spread items position*/
412 return GetPosition(pos,mPositionRight,mPositionLeft,mSelectedItemPosition,mPositionVecSpread,mRotationX);
415 Vector3 mPositionRight;
416 Vector3 mPositionLeft;
417 Vector3 mSelectedItemPosition;
418 vector<Vector3> mPositionVecSpread;
422 Quaternion GetRotation(float layoutPos, vector<float> rotateVecStack, vector<float> rotateVecSpread, float rotateX)
429 float beginRotation = 0.0f;
430 float endRotation = 0.0f;
432 float rotation = 0.0f;
433 if(layoutPos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
435 if(int(layoutPos) > layoutPos)
437 begin = int(layoutPos) + 1;
438 end = int(layoutPos);
443 beginRotation = rotateVecStack.at(begin);
444 endRotation = rotateVecStack.at(end);
446 alpha = fabs(layoutPos - int(layoutPos));
448 rotation = (endRotation - beginRotation) * alpha + beginRotation;
452 rotation = rotateVecStack.at(-int(layoutPos)-1);
455 else if(layoutPos > LAYOUT_POSITION_NAGATIVE_1 && layoutPos < LAYOUT_POSITION_0)/*items between -1.0f and 0.0f*/
460 beginRotation = rotateVecSpread.at(begin);
461 endRotation = rotateVecStack.at(end);
463 alpha = fabs(layoutPos);
465 rotation = (endRotation - beginRotation) * alpha + beginRotation;
467 else if(layoutPos >= LAYOUT_POSITION_0 && layoutPos < LAYOUT_POSITION_3)
469 if(int(layoutPos) < layoutPos)
471 begin = int(layoutPos);
472 end = int(layoutPos) + 1;
474 beginRotation = rotateVecSpread.at(begin);
475 endRotation = rotateVecSpread.at(end);
477 alpha = fabs(layoutPos - int(layoutPos));
479 rotation = (endRotation - beginRotation) * alpha + beginRotation;
483 rotation = rotateVecSpread.at(int(layoutPos));
486 else if(layoutPos > LAYOUT_POSITION_3 && layoutPos <= LAYOUT_POSITION_6)
488 if(int(layoutPos) < layoutPos)
490 begin = int(layoutPos) - 1;
491 end = int(layoutPos);
493 beginRotation = rotateVecSpread.at(begin);
494 endRotation = rotateVecSpread.at(end);
496 alpha = fabs(layoutPos - int(layoutPos));
498 rotation = (endRotation - beginRotation) * alpha + beginRotation;
502 rotation = rotateVecSpread.at(int(layoutPos)-1);
505 else if(layoutPos > LAYOUT_POSITION_6 && layoutPos < LAYOUT_POSITION_7)
510 beginRotation = rotateVecSpread.at(begin);
511 endRotation = rotateVecStack.at(end);
513 alpha = fabs(layoutPos - int(LAYOUT_POSITION_6));
515 rotation = (endRotation - beginRotation) * alpha + beginRotation;
517 else if(layoutPos >= LAYOUT_POSITION_7)
519 if(int(layoutPos) < layoutPos)
521 begin = int(layoutPos) - int(LAYOUT_POSITION_7);
522 end = int(layoutPos) - int(LAYOUT_POSITION_7) + 1;
524 beginRotation = rotateVecStack.at(begin);
525 endRotation = rotateVecStack.at(end);
527 alpha = fabs(layoutPos - int(layoutPos));
529 rotation = (endRotation - beginRotation) * alpha + beginRotation;
533 rotation = rotateVecStack.at(int(layoutPos)-int(LAYOUT_POSITION_7));
537 return Quaternion(rotateX, Vector3::XAXIS) * Quaternion(rotation, Vector3::ZAXIS);
540 struct AlbumRotationConstraint
542 AlbumRotationConstraint(const vector<float> rotatVecSpread, const vector<float> rotatVecStack, const float rotateX, int num)
544 mRotationX = rotateX;
549 mLastPosition = 0.0f;
552 if(rotatVecSpread.size() == SPREAD_ITEM_NUM)
554 mRotationVecSpread = rotatVecSpread;
557 mRotationVecStack = rotatVecStack;
560 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
562 float pos = layoutPosition + SELECTED_CENTER;
564 if(mIndex == mNumOfItems)
571 if(mLastIndex != mIndex)
575 if(mLeft == SCROLL_RIGHT)
577 if(pos > mLastPosition + THRESHHOLD_OF_MOVING)
582 else if(pos < mLastPosition)
585 mLeft = SCROLL_RIGHT;
590 if(mTimes > NUM_OF_FRAME_FILTERED)
597 else if(mLeft == SCROLL_LEFT)
599 if(pos > mLastPosition)
604 else if(pos < mLastPosition - THRESHHOLD_OF_MOVING)
607 mLeft = SCROLL_RIGHT;
612 if(mTimes > NUM_OF_FRAME_FILTERED)
621 if(pos < mLastPosition)
623 mLeft = SCROLL_RIGHT;
625 else if(pos > mLastPosition)
637 /*rotation for the selected item(center)*/
638 if(pos >= SELECTED_RIGHT && pos < SELECTED_LEFT)
640 if(mLeft == SCROLL_LEFT)
642 return Quaternion(-fabs(SELECTED_CENTER - pos), Vector3::YAXIS);
644 else if(mLeft == SCROLL_RIGHT)
646 return Quaternion(fabs(pos - SELECTED_CENTER), Vector3::YAXIS);
650 return Quaternion(0.0f, Vector3::YAXIS);
655 /*rotation for the spread item*/
656 return GetRotation(pos,mRotationVecStack,mRotationVecSpread,mRotationX);
659 vector<float> mRotationVecSpread;
660 vector<float> mRotationVecStack;
662 Actor mScrollDirectionActor;
667 ScrollDirection mLeft;
671 struct AlbumColorConstraint
673 AlbumColorConstraint(const Vector2 colorRight, const Vector2 colorLeft, const Vector2 colorSelectedItem, const vector<Vector2> spreadVecColor, const int stackNum)
675 mColorRight = colorRight;
676 mColorLeft = colorLeft;
677 mSelectedItemColor = colorSelectedItem;
678 mStackNum = stackNum;
680 if(spreadVecColor.size() == SPREAD_ITEM_NUM)
682 mColorVecSpread = spreadVecColor;
686 Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
689 Vector4 color = current;
690 float pos = layoutPosition + SELECTED_CENTER;
691 Vector2 temp = Vector2(0.0f,0.0f);
696 Vector2 beginColor = Vector2(0.0f,0.0f);
697 Vector2 endColor = Vector2(0.0f,0.0f);
699 if(pos <= -mStackNum-1)
704 else if(pos > -mStackNum-1 && pos < -mStackNum)
706 beginColor = mColorRight;
707 endColor = Vector2(0.0f,0.0f);
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;
712 else if(pos <= LAYOUT_POSITION_NAGATIVE_1 && pos >= -mStackNum)
714 color.w = mColorRight.x;
715 black = mColorRight.y;
717 else if(pos > LAYOUT_POSITION_NAGATIVE_1 && pos < LAYOUT_POSITION_0)
719 beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_0));
720 endColor = mColorRight;
722 color.w = (endColor.x - beginColor.x) * fabs(pos) + beginColor.x;
723 black = (endColor.y - beginColor.y) * fabs(pos) + beginColor.y;
725 else if(pos >= LAYOUT_POSITION_0 && pos <= LAYOUT_POSITION_2)
732 beginColor = mColorVecSpread.at(begin);
733 endColor = mColorVecSpread.at(end);
735 temp = (endColor - beginColor) * fabs(pos - int(pos)) + beginColor;
742 beginColor = mColorVecSpread.at(int(pos));
744 color.w = beginColor.x;
745 black = beginColor.y;
748 else if(pos > LAYOUT_POSITION_2 && pos < SELECTED_RIGHT)/*items between 2.0f and center*/
750 beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_2));
751 endColor = Vector2(0.0f,0.0f);
753 temp = (endColor - beginColor) * (pos - LAYOUT_POSITION_2)/(SELECTED_RIGHT - LAYOUT_POSITION_2) + beginColor;
758 else if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)/*items of center*/
760 color.w = mSelectedItemColor.x;
761 black = mSelectedItemColor.y;
763 else if(pos > SELECTED_LEFT && pos < LAYOUT_POSITION_4)/*items between center and 4.0f*/
765 beginColor = Vector2(0.0f,0.0f);
766 endColor = mColorVecSpread.at(int(LAYOUT_POSITION_3));
768 temp = (endColor - beginColor) * (pos - SELECTED_LEFT)/(LAYOUT_POSITION_4 - SELECTED_LEFT) + beginColor;
773 else if(pos >= LAYOUT_POSITION_4 && pos <= LAYOUT_POSITION_6)/*items between 4.0f and 6.0f*/
777 begin = int(pos) - 1;
780 beginColor = mColorVecSpread.at(begin);
781 endColor = mColorVecSpread.at(end);
783 temp = (endColor - beginColor) * fabs(pos - int(pos)) + beginColor;
790 beginColor = mColorVecSpread.at(int(pos) - 1);
792 color.w = beginColor.x;
793 black = beginColor.y;
796 else if(pos > LAYOUT_POSITION_6 && pos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
798 beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_6) - 1);
799 endColor = mColorLeft;
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;
804 else if(pos >= LAYOUT_POSITION_7 && pos <= mStackNum + int(LAYOUT_POSITION_7))/*items of left stack*/
806 color.w = mColorLeft.x;
807 black = mColorLeft.y;
809 else if(pos > mStackNum + int(LAYOUT_POSITION_7) && pos < mStackNum + int(LAYOUT_POSITION_7) + 1)
811 beginColor = mColorLeft;
812 endColor = Vector2(0.0f,0.0f);
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;
817 else if(pos >= mStackNum + int(LAYOUT_POSITION_7) +1)
823 color.r = color.r * black;
824 color.g = color.g * black;
825 color.b = color.b * black;
833 Vector2 mSelectedItemColor;
834 vector<Vector2> mColorVecSpread;
837 struct AlbumVisibilityConstraintPortrait
839 AlbumVisibilityConstraintPortrait()
843 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
849 } // unnamed namespace
857 struct AlbumLayout::Impl
860 : mItemSizeFunction(DefaultItemSizeFunction()),
861 mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
862 mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
863 mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION),
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;
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);
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);
897 /*Initialize the scale of spread items*/
898 for(unsigned int i=0; i<SPREAD_ITEM_NUM; i++)
900 mScaleVecSpread.push_back(SCALE);
903 /*Initialize the color of spread items*/
904 for(unsigned int i=0; i<SPREAD_ITEM_NUM; i++)
906 mColorVecSpread.push_back(COLOR);
910 void SetPosition(vector<Vector3> positionList)
912 if(positionList.size() == SPREAD_ITEM_NUM)
914 mPositionVecSpread = positionList;
918 vector<Vector3> GetPosition() const
920 return mPositionVecSpread;
923 void SetColor(vector<Vector2> colorList)
925 if(colorList.size() == SPREAD_ITEM_NUM)
927 mColorVecSpread = colorList;
931 vector<Vector2> GetColor() const
933 return mColorVecSpread;
936 void SetScale(vector<float> scaleList)
938 if(scaleList.size() == SPREAD_ITEM_NUM)
940 mScaleVecSpread = scaleList;
944 vector<float> GetScale() const
946 return mScaleVecSpread;
949 void SetRotationX(float rotat_x)
951 mRotationX = rotat_x;
954 float GetRotationX() const
959 void SetRotationZ(vector<float> rotationList)
961 if(rotationList.size() == SPREAD_ITEM_NUM)
963 mRotationVecSpread = rotationList;
967 vector<float> GetRotationZ() const
969 return mRotationVecSpread;
972 void SetCenterPosition(Vector3 pos)
974 mSelectedItemPosition = pos;
977 Vector3 GetCenterPosition() const
979 return mSelectedItemPosition;
982 void SetCenterScale(float scale)
984 mSelectedItemScale = scale;
987 float GetCenterScale() const
989 return mSelectedItemScale;
992 void SetCenterColor(Vector2 color)
994 mSelectedItemColor = color;
997 Vector2 GetCenterColor() const
999 return mSelectedItemColor;
1002 void SetStackPosition(Vector3 rightPos, Vector3 leftPos)
1004 mPositionRight = rightPos;
1005 mPositionLeft = leftPos;
1008 Vector3 GetRightStackPosition() const
1010 return mPositionRight;
1013 Vector3 GetLeftStackPosition() const
1015 return mPositionLeft;
1018 void SetStackScale(float rightScale, float leftScale)
1020 mScaleRight = rightScale;
1021 mScaleLeft = leftScale;
1024 float GetRightStackScale() const
1029 float GetLeftStackScale() const
1034 void SetStackColor(Vector2 rightColor, Vector2 leftColor)
1036 mColorRight = rightColor;
1037 mColorLeft = leftColor;
1040 Vector2 GetRightStackColor() const
1045 Vector2 GetLeftStackColor() const
1050 void SetNumOfItems(int num)
1054 /*Initialize the rotation of stack items*/
1055 for(int i=0; i<mNumOfItems; i++)
1057 if(Random::Chance(CHANCE_OF_RANDOM_ROTATION_OF_STACK))
1059 mRotationVecStack.push_back(Random::Range(-RANGE_OF_RANDOM_ROTATION_OF_STACK,RANGE_OF_RANDOM_ROTATION_OF_STACK));
1063 mRotationVecStack.push_back(0.0f);
1068 int GetNumOfItems() const
1073 void SetStackNum(int num)
1078 int GetStackNum() const
1083 ItemSizeFunction mItemSizeFunction;
1085 float mScrollSpeedFactor;
1086 float mMaximumSwipeSpeed;
1087 float mItemFlickAnimationDuration;
1089 Vector3 mSelectedItemPosition;/*position of selected item*/
1090 float mSelectedItemScale;/*scale of selected item*/
1091 Vector2 mSelectedItemColor;/*color of selected item*/
1093 float mRotationX;/*rotation around X*/
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*/
1100 vector<float> mRotationVecStack;/*rotations of the stack items*/
1102 float mRotationRight;/*rotation of right album stack*/
1103 float mRotationLeft;/*rotation of left album stack*/
1105 float mScaleRight;/*scale of right album stack*/
1106 float mScaleLeft;/*scale of left album stack*/
1108 Vector2 mColorRight;/*color of right album stack*/
1109 Vector2 mColorLeft;/*color of left album stack*/
1111 Vector3 mPositionRight;/*position of right album stack*/
1112 Vector3 mPositionLeft;/*position of left album stack*/
1114 int mNumOfItems;/*num of items*/
1115 int mStackNum;/*num of items of stack*/
1118 AlbumLayoutPtr AlbumLayout::New()
1120 return AlbumLayoutPtr(new AlbumLayout());
1123 AlbumLayout::~AlbumLayout()
1128 void AlbumLayout::SetItemSizeFunction(ItemSizeFunction function)
1130 mImpl->mItemSizeFunction = function;
1133 AlbumLayout::ItemSizeFunction AlbumLayout::GetItemSizeFunction() const
1135 return mImpl->mItemSizeFunction;
1138 void AlbumLayout::SetScrollSpeedFactor(float scrollSpeed)
1140 mImpl->mScrollSpeedFactor = scrollSpeed;
1143 void AlbumLayout::SetMaximumSwipeSpeed(float speed)
1145 mImpl->mMaximumSwipeSpeed = speed;
1148 void AlbumLayout::SetItemFlickAnimationDuration(float durationSeconds)
1150 mImpl->mItemFlickAnimationDuration = durationSeconds;
1153 float AlbumLayout::GetScrollSpeedFactor() const
1155 return mImpl->mScrollSpeedFactor;
1158 float AlbumLayout::GetMaximumSwipeSpeed() const
1160 return mImpl->mMaximumSwipeSpeed;
1163 float AlbumLayout::GetItemFlickAnimationDuration() const
1165 return mImpl->mItemFlickAnimationDuration;
1168 float AlbumLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
1170 return - static_cast<float>(numberOfItems) + 1;
1173 float AlbumLayout::GetClosestAnchorPosition(float layoutPosition) const
1175 return round(layoutPosition);
1178 float AlbumLayout::GetItemScrollToPosition(unsigned int itemId) const
1180 return -(static_cast<float>(itemId));
1183 ItemRange AlbumLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
1185 return ItemRange(0, mImpl->mNumOfItems);
1188 unsigned int AlbumLayout::GetReserveItemCount(Vector3 layoutSize) const
1193 bool AlbumLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const
1195 itemSize = mImpl->mItemSizeFunction(layoutSize);
1199 void AlbumLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const
1203 animation.Resize(actor, size);
1207 bool AlbumLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
1209 constraint = AlbumPositionConstraint(mImpl->mPositionRight,mImpl->mPositionLeft,mImpl->mSelectedItemPosition,mImpl->mPositionVecSpread,mImpl->mRotationX);
1213 bool AlbumLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const
1215 constraint = AlbumRotationConstraint(mImpl->mRotationVecSpread,mImpl->mRotationVecStack,mImpl->mRotationX,mImpl->mNumOfItems);
1219 bool AlbumLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
1221 constraint = AlbumScaleConstraint(mImpl->mScaleRight,mImpl->mScaleLeft,mImpl->mSelectedItemScale,mImpl->mScaleVecSpread);
1225 bool AlbumLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const
1227 constraint = AlbumColorConstraint(mImpl->mColorRight,mImpl->mColorLeft,mImpl->mSelectedItemColor,mImpl->mColorVecSpread,mImpl->mStackNum);
1231 bool AlbumLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const
1233 constraint = AlbumVisibilityConstraintPortrait();
1237 Degree AlbumLayout::GetScrollDirection() const
1239 Degree scrollDirection(0);
1241 scrollDirection = -90.0f;
1243 return scrollDirection;
1246 void AlbumLayout::SetNumOfItems(int num)
1248 mImpl->SetNumOfItems(num);
1251 int AlbumLayout::GetNumOfItems() const
1253 return mImpl->GetNumOfItems();
1256 void AlbumLayout::SetStackNum(int num)
1258 mImpl->SetStackNum(num);
1261 int AlbumLayout::GetStackNum() const
1263 return mImpl->GetStackNum();
1266 void AlbumLayout::SetPosition(vector<Vector3> positionList)
1268 mImpl->SetPosition(positionList);
1271 vector<Vector3> AlbumLayout::GetPosition() const
1273 return mImpl->GetPosition();
1276 void AlbumLayout::SetScale(vector<float> scaleList)
1278 mImpl->SetScale(scaleList);
1281 vector<float> AlbumLayout::GetScale() const
1283 return mImpl->GetScale();
1286 void AlbumLayout::SetColor(vector<Vector2> colorList)
1288 mImpl->SetColor(colorList);
1291 vector<Vector2> AlbumLayout::GetColor() const
1293 return mImpl->GetColor();
1296 void AlbumLayout::SetRotationX(float rotation)
1298 mImpl->SetRotationX(rotation);
1301 float AlbumLayout::GetRotationX() const
1303 return mImpl->GetRotationX();
1306 void AlbumLayout::SetRotationZ(vector<float> rotationList)
1308 mImpl->SetRotationZ(rotationList);
1311 vector<float> AlbumLayout::GetRotationZ() const
1313 return mImpl->GetRotationZ();
1316 void AlbumLayout::SetCenterPosition(Vector3 pos)
1318 mImpl->SetCenterPosition(pos);
1321 Vector3 AlbumLayout::GetCenterPosition() const
1323 return mImpl->GetCenterPosition();
1326 void AlbumLayout::SetCenterScale(float scale)
1328 mImpl->SetCenterScale(scale);
1331 float AlbumLayout::GetCenterScale() const
1333 return mImpl->GetCenterScale();
1336 void AlbumLayout::SetCenterColor(Vector2 color)
1338 mImpl->SetCenterColor(color);
1341 Vector2 AlbumLayout::GetCenterColor() const
1343 return mImpl->GetCenterColor();
1346 void AlbumLayout::SetStackPosition(Vector3 rightPos, Vector3 leftPos)
1348 mImpl->SetStackPosition(rightPos, leftPos);
1351 Vector3 AlbumLayout::GetRightStackPosition() const
1353 return mImpl->GetRightStackPosition();
1356 Vector3 AlbumLayout::GetLeftStackPosition() const
1358 return mImpl->GetLeftStackPosition();
1361 void AlbumLayout::SetStackScale(float rightScale, float leftScale)
1363 mImpl->SetStackScale(rightScale,leftScale);
1366 float AlbumLayout::GetRightStackScale() const
1368 return mImpl->GetRightStackScale();
1371 float AlbumLayout::GetLeftStackScale() const
1373 return mImpl->GetLeftStackScale();
1376 void AlbumLayout::SetStackColor(Vector2 rightColor, Vector2 leftColor)
1378 mImpl->SetStackColor(rightColor, leftColor);
1381 Vector2 AlbumLayout::GetRightStackColor() const
1383 return mImpl->GetRightStackColor();
1386 Vector2 AlbumLayout::GetLeftStackColor() const
1388 return mImpl->GetLeftStackColor();
1391 AlbumLayout::AlbumLayout()
1397 } // namespace Toolkit