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>
22 using namespace Dali::Toolkit;
25 namespace // unnamed namespace
27 const float DEFAULT_SCROLL_SPEED_FACTOR = 0.005f;
28 const float DEFAULT_MAXIMUM_SWIPE_SPEED = 3.0f;
29 const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.25f;
31 const float SELECTED_RIGHT = 2.5f;
32 const float SELECTED_LEFT = 3.5f;
33 const float SELECTED_CENTER = 3.0f;
35 const float LAYOUT_POSITION_NAGATIVE_1 = -1.0f;
36 const float LAYOUT_POSITION_0 = 0.0f;
37 const float LAYOUT_POSITION_2 = 2.0f;
38 const float LAYOUT_POSITION_3 = 3.0f;
39 const float LAYOUT_POSITION_4 = 4.0f;
40 const float LAYOUT_POSITION_6 = 6.0f;
41 const float LAYOUT_POSITION_7 = 7.0f;
43 const Vector3 POSITION_0 = Vector3(850.0f,-250.0f,0.0f);
44 const Vector3 POSITION_1 = Vector3(700.0f,50.0f,0.0f);
45 const Vector3 POSITION_2 = Vector3(440.0f,227.0f,0.0f);
46 const Vector3 POSITION_4 = Vector3(-440.0f,227.0f,0.0f);
47 const Vector3 POSITION_5 = Vector3(-700.0f,50.0f,0.0f);
48 const Vector3 POSITION_6 = Vector3(-850.0f,-250.0f,0.0f);
50 const float ROTATION_0 = Math::PI/6.0f;
51 const float ROTATION_1 = 0.0f;
52 const float ROTATION_2 = Math::PI/6.0f;
53 const float ROTATION_4 = -Math::PI/6.0f;
54 const float ROTATION_5 = 0.0f;
55 const float ROTATION_6 = -Math::PI/6.0f;
57 const float SCALE = 1.0f;
59 const Vector2 COLOR = Vector2(1.0f,1.0f);
61 const Vector3 SELECTED_ITEM_POSITION = Vector3( 0.0f,-80.0f,140.0f);
62 const float SELECETED_ITEM_SCALE = 1.72f;
63 const Vector2 SELECTED_ITEM_COLOR = Vector2(1.0f,1.0f);
64 const Vector3 VIRTUAL_ITEM_POSITION_RIGHT = Vector3( 280.0f,130.0f,130.0f);
65 const Vector3 VIRTUAL_ITEM_POSITION_LEFT = Vector3( -280.0f,130.0f,130.0f);
66 const float ROTATION_X = Math::PI/4.0f;
67 const float SCALE_RIGHT = 1.0f;
68 const float SCALE_LEFT = 1.0f;
69 const Vector2 COLOR_RIGHT = Vector2(1.0f,1.0f);
70 const Vector2 COLOR_LEFT = Vector2(1.0f,1.0f);
71 const Vector3 POSITION_RIGHT = Vector3(710.0f,-450.0f,0.0f);
72 const Vector3 POSITION_LEFT = Vector3(-710.0f,-450.0f,0.0f);
73 const float ROTATION_RIGHT = -Math::PI / 6.0f;
74 const float ROTATION_LEFT = Math::PI / 6.0f;
76 const float ALBUM_HIGHT = 7.0f;
77 const float ALPHA = 1.1f;
78 const float ALPHA_OF_SIZE = 0.35f;
79 const float LINE_OF_BOTTOM = 360.0f;
81 const float CHANCE_OF_RANDOM_ROTATION_OF_STACK = 0.5f;
82 const float RANGE_OF_RANDOM_ROTATION_OF_STACK = 0.5f;
84 const float THRESHHOLD_OF_MOVING = 0.02f;
85 const int NUM_OF_FRAME_FILTERED = 5;
87 const unsigned int SPREAD_ITEM_NUM = 6;
96 struct DefaultItemSizeFunction
98 Vector3 operator()(const Vector3& layoutSize)
100 float width = layoutSize.height * ALPHA_OF_SIZE;
101 return Vector3(width, width, width);
105 struct AlbumScaleConstraint
107 AlbumScaleConstraint(const float scaleRight, const float scaleLeft, const float selectedItemScale, vector<float> scaleSpread)
109 mScaleRight = scaleRight;
110 mScaleLeft = scaleLeft;
111 mSelectedItemScale = selectedItemScale;
113 if(scaleSpread.size() == SPREAD_ITEM_NUM)
115 mScaleVecSpread = scaleSpread;
119 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
123 float beginScale = 0.0f;
124 float endScale = 0.0f;
126 float pos = layoutPosition + SELECTED_CENTER;
128 if(pos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
132 else if(pos > LAYOUT_POSITION_NAGATIVE_1 && pos < LAYOUT_POSITION_0)/*items between -1.0f and 0.0f*/
134 beginScale = mScaleVecSpread.at(0);
135 endScale = mScaleRight;
137 scale = (endScale - beginScale) * fabs(pos) + beginScale;
139 else if(pos >= LAYOUT_POSITION_0 && pos < SELECTED_RIGHT)/*items between 0.0f and center*/
146 beginScale = mScaleVecSpread.at(begin);
147 endScale = mScaleVecSpread.at(end);
149 scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
153 scale = mScaleVecSpread.at(int(pos));
156 else if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)/*items of center*/
158 scale = mSelectedItemScale;
160 else if(pos > SELECTED_LEFT && pos <= LAYOUT_POSITION_6)/*items between center and 6.0f*/
167 beginScale = mScaleVecSpread.at(begin);
168 endScale = mScaleVecSpread.at(end);
170 scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
174 scale = mScaleVecSpread.at(int(pos)-1);
177 else if(pos > LAYOUT_POSITION_6 && pos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
179 beginScale = mScaleVecSpread.at(5);
180 endScale = mScaleLeft;
182 scale = (endScale - beginScale) * fabs(pos - int(pos)) + beginScale;
184 else if(pos >= LAYOUT_POSITION_7)/*items of left stack*/
193 return Vector3(scale,scale,1.0f);
198 float mSelectedItemScale;
199 vector<float> mScaleVecSpread;
202 Vector3 CalculatePosition(Vector3 pos, float rotateX)
204 pos.z = pos.z - fabs(pos.y - LINE_OF_BOTTOM) * sinf(rotateX) / cosf(rotateX);
208 Vector3 CalculateStackPosition(Vector3 pos, float rotateX, int num, bool left)
210 pos.z = pos.z - fabs(pos.y - LINE_OF_BOTTOM) * sinf(rotateX) / cosf(rotateX);
214 pos.x = pos.x + num * ALPHA;
218 pos.x = pos.x - num * ALPHA;
221 pos.y -= num * ALBUM_HIGHT * sinf(rotateX);
222 pos.z += num * ALBUM_HIGHT * cosf(rotateX);
227 Vector3 GetPosition(float layoutPos, Vector3 posRight, Vector3 posLeft, Vector3 posSelectedItem, vector<Vector3> posVecSpread, float rotateX)
234 Vector3 beginPos = Vector3::ZERO;
235 Vector3 endPos = Vector3::ZERO;
237 Vector3 pos = Vector3::ZERO;
239 if(layoutPos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
241 if(int(layoutPos) > layoutPos)
243 begin = int(layoutPos);
244 end = int(layoutPos)-1;
246 beginPos = CalculateStackPosition(posRight, rotateX, int(LAYOUT_POSITION_NAGATIVE_1) - int(layoutPos),false);
248 endPos = CalculateStackPosition(posRight, rotateX, - int(layoutPos),false);
250 alpha = fabs(layoutPos - int(layoutPos));
252 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
253 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
254 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
260 return CalculateStackPosition(posRight,rotateX,int(LAYOUT_POSITION_NAGATIVE_1) - int(layoutPos),false);
263 else if(layoutPos < LAYOUT_POSITION_0 && layoutPos > LAYOUT_POSITION_NAGATIVE_1)/*items between -1.0f and 0.0f*/
265 beginPos = CalculatePosition(posVecSpread.at(int(LAYOUT_POSITION_0)),rotateX);
266 endPos = CalculateStackPosition(posRight, rotateX, int(layoutPos),false);
270 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
271 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
272 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
276 else if(layoutPos >= LAYOUT_POSITION_0 && layoutPos <= LAYOUT_POSITION_2)/*items between 0.0f and 2.0f*/
278 if(int(layoutPos) < layoutPos)
280 begin = int(layoutPos);
281 end = int(layoutPos) + 1;
283 beginPos = posVecSpread.at(begin);
284 endPos = posVecSpread.at(end);
286 alpha = fabs(layoutPos - int(layoutPos));
288 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
289 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
290 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
294 pos = posVecSpread.at(int(layoutPos));
297 else if(layoutPos >LAYOUT_POSITION_2 && layoutPos<SELECTED_RIGHT)/*items between 2.0f and center*/
299 beginPos = posVecSpread.at(int(LAYOUT_POSITION_2));
300 endPos = VIRTUAL_ITEM_POSITION_RIGHT;
302 alpha = (layoutPos - LAYOUT_POSITION_2) / (SELECTED_RIGHT - LAYOUT_POSITION_2);
304 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
305 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
306 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
308 else if(layoutPos > SELECTED_LEFT && layoutPos < LAYOUT_POSITION_4)/*items between center and 4.0f*/
310 beginPos = posVecSpread.at(int(LAYOUT_POSITION_3));
311 endPos = VIRTUAL_ITEM_POSITION_LEFT;
313 alpha = (LAYOUT_POSITION_4 - layoutPos) / (LAYOUT_POSITION_4 - SELECTED_LEFT);
315 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
316 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
317 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
319 else if(layoutPos >= LAYOUT_POSITION_4 && layoutPos <= LAYOUT_POSITION_6)/*items between 4.0f and 6.0f*/
321 if(int(layoutPos) < layoutPos)
323 begin = int(layoutPos);
324 end = int(layoutPos) + 1;
326 beginPos = posVecSpread.at(begin - 1);
327 endPos = posVecSpread.at(end - 1);
329 alpha = fabs(layoutPos - int(layoutPos));
331 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
332 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
333 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
337 pos = posVecSpread.at(int(layoutPos) -1);
340 else if(layoutPos > LAYOUT_POSITION_6 && layoutPos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
342 beginPos = CalculatePosition(posVecSpread.at(int(LAYOUT_POSITION_6) - 1),rotateX);
343 endPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) + 1 - int(LAYOUT_POSITION_7),true);
345 alpha = fabs(layoutPos - int(layoutPos));
347 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
348 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
349 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
353 else if(layoutPos >= LAYOUT_POSITION_7)/*items of left stack*/
355 if(int(layoutPos) < layoutPos)
357 begin = int(layoutPos);
358 end = int(layoutPos) + 1;
360 beginPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) - int(LAYOUT_POSITION_7),true);
362 endPos = CalculateStackPosition(posLeft, rotateX, int(layoutPos) + 1 - int(LAYOUT_POSITION_7),true);
364 alpha = fabs(layoutPos - int(layoutPos));
366 pos.x = (endPos.x - beginPos.x) * alpha + beginPos.x;
367 pos.y = (endPos.y - beginPos.y) * alpha + beginPos.y;
368 pos.z = (endPos.z - beginPos.z) * alpha + beginPos.z;
374 return CalculateStackPosition(posLeft, rotateX, int(layoutPos) - int(LAYOUT_POSITION_7),true);
378 return CalculatePosition(pos,rotateX);
381 struct AlbumPositionConstraint
383 AlbumPositionConstraint(const Vector3 posRight, const Vector3 posLeft, const Vector3 posSelectedItem, const vector<Vector3> posVecSpread, float rotateX)
385 mPositionRight = posRight;
386 mPositionLeft = posLeft;
387 mSelectedItemPosition = posSelectedItem;
388 mRotationX = rotateX;
390 if(posVecSpread.size() == SPREAD_ITEM_NUM)
392 mPositionVecSpread = posVecSpread;
396 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
398 float pos = layoutPosition + SELECTED_CENTER;
400 /*handle if the item is selected item(in the center)*/
401 if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)
403 return SELECTED_ITEM_POSITION;
406 /*get the spread items position*/
407 return GetPosition(pos,mPositionRight,mPositionLeft,mSelectedItemPosition,mPositionVecSpread,mRotationX);
410 Vector3 mPositionRight;
411 Vector3 mPositionLeft;
412 Vector3 mSelectedItemPosition;
413 vector<Vector3> mPositionVecSpread;
417 Quaternion GetRotation(float layoutPos, vector<float> rotateVecStack, vector<float> rotateVecSpread, float rotateX)
424 float beginRotation = 0.0f;
425 float endRotation = 0.0f;
427 float rotation = 0.0f;
428 if(layoutPos <= LAYOUT_POSITION_NAGATIVE_1)/*items of right stack*/
430 if(int(layoutPos) > layoutPos)
432 begin = int(layoutPos) + 1;
433 end = int(layoutPos);
438 beginRotation = rotateVecStack.at(begin);
439 endRotation = rotateVecStack.at(end);
441 alpha = fabs(layoutPos - int(layoutPos));
443 rotation = (endRotation - beginRotation) * alpha + beginRotation;
447 rotation = rotateVecStack.at(-int(layoutPos)-1);
450 else if(layoutPos > LAYOUT_POSITION_NAGATIVE_1 && layoutPos < LAYOUT_POSITION_0)/*items between -1.0f and 0.0f*/
455 beginRotation = rotateVecSpread.at(begin);
456 endRotation = rotateVecStack.at(end);
458 alpha = fabs(layoutPos);
460 rotation = (endRotation - beginRotation) * alpha + beginRotation;
462 else if(layoutPos >= LAYOUT_POSITION_0 && layoutPos < LAYOUT_POSITION_3)
464 if(int(layoutPos) < layoutPos)
466 begin = int(layoutPos);
467 end = int(layoutPos) + 1;
469 beginRotation = rotateVecSpread.at(begin);
470 endRotation = rotateVecSpread.at(end);
472 alpha = fabs(layoutPos - int(layoutPos));
474 rotation = (endRotation - beginRotation) * alpha + beginRotation;
478 rotation = rotateVecSpread.at(int(layoutPos));
481 else if(layoutPos > LAYOUT_POSITION_3 && layoutPos <= LAYOUT_POSITION_6)
483 if(int(layoutPos) < layoutPos)
485 begin = int(layoutPos) - 1;
486 end = int(layoutPos);
488 beginRotation = rotateVecSpread.at(begin);
489 endRotation = rotateVecSpread.at(end);
491 alpha = fabs(layoutPos - int(layoutPos));
493 rotation = (endRotation - beginRotation) * alpha + beginRotation;
497 rotation = rotateVecSpread.at(int(layoutPos)-1);
500 else if(layoutPos > LAYOUT_POSITION_6 && layoutPos < LAYOUT_POSITION_7)
505 beginRotation = rotateVecSpread.at(begin);
506 endRotation = rotateVecStack.at(end);
508 alpha = fabs(layoutPos - int(LAYOUT_POSITION_6));
510 rotation = (endRotation - beginRotation) * alpha + beginRotation;
512 else if(layoutPos >= LAYOUT_POSITION_7)
514 if(int(layoutPos) < layoutPos)
516 begin = int(layoutPos) - int(LAYOUT_POSITION_7);
517 end = int(layoutPos) - int(LAYOUT_POSITION_7) + 1;
519 beginRotation = rotateVecStack.at(begin);
520 endRotation = rotateVecStack.at(end);
522 alpha = fabs(layoutPos - int(layoutPos));
524 rotation = (endRotation - beginRotation) * alpha + beginRotation;
528 rotation = rotateVecStack.at(int(layoutPos)-int(LAYOUT_POSITION_7));
532 return Quaternion(rotateX, Vector3::XAXIS) * Quaternion(rotation, Vector3::ZAXIS);
535 struct AlbumRotationConstraint
537 AlbumRotationConstraint(const vector<float> rotatVecSpread, const vector<float> rotatVecStack, const float rotateX, int num)
539 mRotationX = rotateX;
544 mLastPosition = 0.0f;
547 if(rotatVecSpread.size() == SPREAD_ITEM_NUM)
549 mRotationVecSpread = rotatVecSpread;
552 mRotationVecStack = rotatVecStack;
555 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
557 float pos = layoutPosition + SELECTED_CENTER;
559 if(mIndex == mNumOfItems)
566 if(mLastIndex != mIndex)
570 if(mLeft == SCROLL_RIGHT)
572 if(pos > mLastPosition + THRESHHOLD_OF_MOVING)
577 else if(pos < mLastPosition)
580 mLeft = SCROLL_RIGHT;
585 if(mTimes > NUM_OF_FRAME_FILTERED)
592 else if(mLeft == SCROLL_LEFT)
594 if(pos > mLastPosition)
599 else if(pos < mLastPosition - THRESHHOLD_OF_MOVING)
602 mLeft = SCROLL_RIGHT;
607 if(mTimes > NUM_OF_FRAME_FILTERED)
616 if(pos < mLastPosition)
618 mLeft = SCROLL_RIGHT;
620 else if(pos > mLastPosition)
632 /*rotation for the selected item(center)*/
633 if(pos >= SELECTED_RIGHT && pos < SELECTED_LEFT)
635 if(mLeft == SCROLL_LEFT)
637 return Quaternion(-fabs(SELECTED_CENTER - pos), Vector3::YAXIS);
639 else if(mLeft == SCROLL_RIGHT)
641 return Quaternion(fabs(pos - SELECTED_CENTER), Vector3::YAXIS);
645 return Quaternion(0.0f, Vector3::YAXIS);
650 /*rotation for the spread item*/
651 return GetRotation(pos,mRotationVecStack,mRotationVecSpread,mRotationX);
654 vector<float> mRotationVecSpread;
655 vector<float> mRotationVecStack;
657 Actor mScrollDirectionActor;
662 ScrollDirection mLeft;
666 struct AlbumColorConstraint
668 AlbumColorConstraint(const Vector2 colorRight, const Vector2 colorLeft, const Vector2 colorSelectedItem, const vector<Vector2> spreadVecColor, const int stackNum)
670 mColorRight = colorRight;
671 mColorLeft = colorLeft;
672 mSelectedItemColor = colorSelectedItem;
673 mStackNum = stackNum;
675 if(spreadVecColor.size() == SPREAD_ITEM_NUM)
677 mColorVecSpread = spreadVecColor;
681 Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
684 Vector4 color = current;
685 float pos = layoutPosition + SELECTED_CENTER;
686 Vector2 temp = Vector2(0.0f,0.0f);
691 Vector2 beginColor = Vector2(0.0f,0.0f);
692 Vector2 endColor = Vector2(0.0f,0.0f);
694 if(pos <= -mStackNum-1)
699 else if(pos > -mStackNum-1 && pos < -mStackNum)
701 beginColor = mColorRight;
702 endColor = Vector2(0.0f,0.0f);
704 color.w = (endColor.x - beginColor.x) * fabs(pos - int(pos)) + beginColor.x;
705 black = (endColor.y - beginColor.y) * fabs(pos - int(pos)) + beginColor.y;
707 else if(pos <= LAYOUT_POSITION_NAGATIVE_1 && pos >= -mStackNum)
709 color.w = mColorRight.x;
710 black = mColorRight.y;
712 else if(pos > LAYOUT_POSITION_NAGATIVE_1 && pos < LAYOUT_POSITION_0)
714 beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_0));
715 endColor = mColorRight;
717 color.w = (endColor.x - beginColor.x) * fabs(pos) + beginColor.x;
718 black = (endColor.y - beginColor.y) * fabs(pos) + beginColor.y;
720 else if(pos >= LAYOUT_POSITION_0 && pos <= LAYOUT_POSITION_2)
727 beginColor = mColorVecSpread.at(begin);
728 endColor = mColorVecSpread.at(end);
730 temp = (endColor - beginColor) * fabs(pos - int(pos)) + beginColor;
737 beginColor = mColorVecSpread.at(int(pos));
739 color.w = beginColor.x;
740 black = beginColor.y;
743 else if(pos > LAYOUT_POSITION_2 && pos < SELECTED_RIGHT)/*items between 2.0f and center*/
745 beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_2));
746 endColor = Vector2(0.0f,0.0f);
748 temp = (endColor - beginColor) * (pos - LAYOUT_POSITION_2)/(SELECTED_RIGHT - LAYOUT_POSITION_2) + beginColor;
753 else if(pos >= SELECTED_RIGHT && pos <= SELECTED_LEFT)/*items of center*/
755 color.w = mSelectedItemColor.x;
756 black = mSelectedItemColor.y;
758 else if(pos > SELECTED_LEFT && pos < LAYOUT_POSITION_4)/*items between center and 4.0f*/
760 beginColor = Vector2(0.0f,0.0f);
761 endColor = mColorVecSpread.at(int(LAYOUT_POSITION_3));
763 temp = (endColor - beginColor) * (pos - SELECTED_LEFT)/(LAYOUT_POSITION_4 - SELECTED_LEFT) + beginColor;
768 else if(pos >= LAYOUT_POSITION_4 && pos <= LAYOUT_POSITION_6)/*items between 4.0f and 6.0f*/
772 begin = int(pos) - 1;
775 beginColor = mColorVecSpread.at(begin);
776 endColor = mColorVecSpread.at(end);
778 temp = (endColor - beginColor) * fabs(pos - int(pos)) + beginColor;
785 beginColor = mColorVecSpread.at(int(pos) - 1);
787 color.w = beginColor.x;
788 black = beginColor.y;
791 else if(pos > LAYOUT_POSITION_6 && pos < LAYOUT_POSITION_7)/*items between 6.0f and 7.0f*/
793 beginColor = mColorVecSpread.at(int(LAYOUT_POSITION_6) - 1);
794 endColor = mColorLeft;
796 color.w = (endColor.x - beginColor.x) * fabs(pos - int(pos)) + beginColor.x;
797 black = (endColor.y - beginColor.y) * fabs(pos - int(pos)) + beginColor.y;
799 else if(pos >= LAYOUT_POSITION_7 && pos <= mStackNum + int(LAYOUT_POSITION_7))/*items of left stack*/
801 color.w = mColorLeft.x;
802 black = mColorLeft.y;
804 else if(pos > mStackNum + int(LAYOUT_POSITION_7) && pos < mStackNum + int(LAYOUT_POSITION_7) + 1)
806 beginColor = mColorLeft;
807 endColor = Vector2(0.0f,0.0f);
809 color.w = (endColor.x - beginColor.x) * fabs(pos - int(pos)) + beginColor.x;
810 black = (endColor.y - beginColor.y) * fabs(pos - int(pos)) + beginColor.y;
812 else if(pos >= mStackNum + int(LAYOUT_POSITION_7) +1)
818 color.r = color.r * black;
819 color.g = color.g * black;
820 color.b = color.b * black;
828 Vector2 mSelectedItemColor;
829 vector<Vector2> mColorVecSpread;
832 struct AlbumVisibilityConstraintPortrait
834 AlbumVisibilityConstraintPortrait()
838 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
844 } // unnamed namespace
852 struct AlbumLayout::Impl
855 : mItemSizeFunction(DefaultItemSizeFunction()),
856 mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
857 mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
858 mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION),
861 /*Initialize the variables*/
862 mSelectedItemScale = SELECETED_ITEM_SCALE;
863 mRotationX = ROTATION_X;
864 mScaleRight = SCALE_RIGHT;
865 mScaleLeft = SCALE_LEFT;
866 mRotationRight = ROTATION_RIGHT;
867 mRotationLeft = ROTATION_LEFT;
868 mSelectedItemColor = SELECTED_ITEM_COLOR;
869 mSelectedItemPosition = SELECTED_ITEM_POSITION;
870 mColorRight = COLOR_RIGHT;
871 mColorLeft = COLOR_LEFT;
872 mPositionRight = POSITION_RIGHT;
873 mPositionLeft = POSITION_LEFT;
876 /*Initialize the position of spread items*/
877 mPositionVecSpread.push_back(POSITION_0);
878 mPositionVecSpread.push_back(POSITION_1);
879 mPositionVecSpread.push_back(POSITION_2);
880 mPositionVecSpread.push_back(POSITION_4);
881 mPositionVecSpread.push_back(POSITION_5);
882 mPositionVecSpread.push_back(POSITION_6);
884 /*Initialize the rotation of spread items*/
885 mRotationVecSpread.push_back(ROTATION_0);
886 mRotationVecSpread.push_back(ROTATION_1);
887 mRotationVecSpread.push_back(ROTATION_2);
888 mRotationVecSpread.push_back(ROTATION_4);
889 mRotationVecSpread.push_back(ROTATION_5);
890 mRotationVecSpread.push_back(ROTATION_6);
892 /*Initialize the scale of spread items*/
893 for(unsigned int i=0; i<SPREAD_ITEM_NUM; i++)
895 mScaleVecSpread.push_back(SCALE);
898 /*Initialize the color of spread items*/
899 for(unsigned int i=0; i<SPREAD_ITEM_NUM; i++)
901 mColorVecSpread.push_back(COLOR);
905 void SetPosition(vector<Vector3> positionList)
907 if(positionList.size() == SPREAD_ITEM_NUM)
909 mPositionVecSpread = positionList;
913 vector<Vector3> GetPosition() const
915 return mPositionVecSpread;
918 void SetColor(vector<Vector2> colorList)
920 if(colorList.size() == SPREAD_ITEM_NUM)
922 mColorVecSpread = colorList;
926 vector<Vector2> GetColor() const
928 return mColorVecSpread;
931 void SetScale(vector<float> scaleList)
933 if(scaleList.size() == SPREAD_ITEM_NUM)
935 mScaleVecSpread = scaleList;
939 vector<float> GetScale() const
941 return mScaleVecSpread;
944 void SetRotationX(float rotat_x)
946 mRotationX = rotat_x;
949 float GetRotationX() const
954 void SetRotationZ(vector<float> rotationList)
956 if(rotationList.size() == SPREAD_ITEM_NUM)
958 mRotationVecSpread = rotationList;
962 vector<float> GetRotationZ() const
964 return mRotationVecSpread;
967 void SetCenterPosition(Vector3 pos)
969 mSelectedItemPosition = pos;
972 Vector3 GetCenterPosition() const
974 return mSelectedItemPosition;
977 void SetCenterScale(float scale)
979 mSelectedItemScale = scale;
982 float GetCenterScale() const
984 return mSelectedItemScale;
987 void SetCenterColor(Vector2 color)
989 mSelectedItemColor = color;
992 Vector2 GetCenterColor() const
994 return mSelectedItemColor;
997 void SetStackPosition(Vector3 rightPos, Vector3 leftPos)
999 mPositionRight = rightPos;
1000 mPositionLeft = leftPos;
1003 Vector3 GetRightStackPosition() const
1005 return mPositionRight;
1008 Vector3 GetLeftStackPosition() const
1010 return mPositionLeft;
1013 void SetStackScale(float rightScale, float leftScale)
1015 mScaleRight = rightScale;
1016 mScaleLeft = leftScale;
1019 float GetRightStackScale() const
1024 float GetLeftStackScale() const
1029 void SetStackColor(Vector2 rightColor, Vector2 leftColor)
1031 mColorRight = rightColor;
1032 mColorLeft = leftColor;
1035 Vector2 GetRightStackColor() const
1040 Vector2 GetLeftStackColor() const
1045 void SetNumOfItems(int num)
1049 /*Initialize the rotation of stack items*/
1050 for(int i=0; i<mNumOfItems; i++)
1052 if(Random::Chance(CHANCE_OF_RANDOM_ROTATION_OF_STACK))
1054 mRotationVecStack.push_back(Random::Range(-RANGE_OF_RANDOM_ROTATION_OF_STACK,RANGE_OF_RANDOM_ROTATION_OF_STACK));
1058 mRotationVecStack.push_back(0.0f);
1063 int GetNumOfItems() const
1068 void SetStackNum(int num)
1073 int GetStackNum() const
1078 ItemSizeFunction mItemSizeFunction;
1080 float mScrollSpeedFactor;
1081 float mMaximumSwipeSpeed;
1082 float mItemFlickAnimationDuration;
1084 Vector3 mSelectedItemPosition;/*position of selected item*/
1085 float mSelectedItemScale;/*scale of selected item*/
1086 Vector2 mSelectedItemColor;/*color of selected item*/
1088 float mRotationX;/*rotation around X*/
1090 vector<Vector3> mPositionVecSpread;/*positions of the spread items*/
1091 vector<float> mRotationVecSpread;/*rotations of the spread items*/
1092 vector<float> mScaleVecSpread;/*scales of the spread items*/
1093 vector<Vector2> mColorVecSpread;/*colors of the spread items*/
1095 vector<float> mRotationVecStack;/*rotations of the stack items*/
1097 float mRotationRight;/*rotation of right album stack*/
1098 float mRotationLeft;/*rotation of left album stack*/
1100 float mScaleRight;/*scale of right album stack*/
1101 float mScaleLeft;/*scale of left album stack*/
1103 Vector2 mColorRight;/*color of right album stack*/
1104 Vector2 mColorLeft;/*color of left album stack*/
1106 Vector3 mPositionRight;/*position of right album stack*/
1107 Vector3 mPositionLeft;/*position of left album stack*/
1109 int mNumOfItems;/*num of items*/
1110 int mStackNum;/*num of items of stack*/
1113 AlbumLayoutPtr AlbumLayout::New()
1115 return AlbumLayoutPtr(new AlbumLayout());
1118 AlbumLayout::~AlbumLayout()
1123 void AlbumLayout::SetItemSizeFunction(ItemSizeFunction function)
1125 mImpl->mItemSizeFunction = function;
1128 AlbumLayout::ItemSizeFunction AlbumLayout::GetItemSizeFunction() const
1130 return mImpl->mItemSizeFunction;
1133 void AlbumLayout::SetScrollSpeedFactor(float scrollSpeed)
1135 mImpl->mScrollSpeedFactor = scrollSpeed;
1138 void AlbumLayout::SetMaximumSwipeSpeed(float speed)
1140 mImpl->mMaximumSwipeSpeed = speed;
1143 void AlbumLayout::SetItemFlickAnimationDuration(float durationSeconds)
1145 mImpl->mItemFlickAnimationDuration = durationSeconds;
1148 float AlbumLayout::GetScrollSpeedFactor() const
1150 return mImpl->mScrollSpeedFactor;
1153 float AlbumLayout::GetMaximumSwipeSpeed() const
1155 return mImpl->mMaximumSwipeSpeed;
1158 float AlbumLayout::GetItemFlickAnimationDuration() const
1160 return mImpl->mItemFlickAnimationDuration;
1163 float AlbumLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
1165 return - static_cast<float>(numberOfItems) + 1;
1168 float AlbumLayout::GetClosestAnchorPosition(float layoutPosition) const
1170 return round(layoutPosition);
1173 float AlbumLayout::GetItemScrollToPosition(unsigned int itemId) const
1175 return -(static_cast<float>(itemId));
1178 ItemRange AlbumLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
1180 return ItemRange(0, mImpl->mNumOfItems);
1183 unsigned int AlbumLayout::GetReserveItemCount(Vector3 layoutSize) const
1188 bool AlbumLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const
1190 itemSize = mImpl->mItemSizeFunction(layoutSize);
1194 void AlbumLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const
1198 animation.Resize(actor, size);
1202 bool AlbumLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
1204 constraint = AlbumPositionConstraint(mImpl->mPositionRight,mImpl->mPositionLeft,mImpl->mSelectedItemPosition,mImpl->mPositionVecSpread,mImpl->mRotationX);
1208 bool AlbumLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const
1210 constraint = AlbumRotationConstraint(mImpl->mRotationVecSpread,mImpl->mRotationVecStack,mImpl->mRotationX,mImpl->mNumOfItems);
1214 bool AlbumLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
1216 constraint = AlbumScaleConstraint(mImpl->mScaleRight,mImpl->mScaleLeft,mImpl->mSelectedItemScale,mImpl->mScaleVecSpread);
1220 bool AlbumLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const
1222 constraint = AlbumColorConstraint(mImpl->mColorRight,mImpl->mColorLeft,mImpl->mSelectedItemColor,mImpl->mColorVecSpread,mImpl->mStackNum);
1226 bool AlbumLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const
1228 constraint = AlbumVisibilityConstraintPortrait();
1232 Degree AlbumLayout::GetScrollDirection() const
1234 Degree scrollDirection(0);
1236 scrollDirection = -90.0f;
1238 return scrollDirection;
1241 void AlbumLayout::SetNumOfItems(int num)
1243 mImpl->SetNumOfItems(num);
1246 int AlbumLayout::GetNumOfItems() const
1248 return mImpl->GetNumOfItems();
1251 void AlbumLayout::SetStackNum(int num)
1253 mImpl->SetStackNum(num);
1256 int AlbumLayout::GetStackNum() const
1258 return mImpl->GetStackNum();
1261 void AlbumLayout::SetPosition(vector<Vector3> positionList)
1263 mImpl->SetPosition(positionList);
1266 vector<Vector3> AlbumLayout::GetPosition() const
1268 return mImpl->GetPosition();
1271 void AlbumLayout::SetScale(vector<float> scaleList)
1273 mImpl->SetScale(scaleList);
1276 vector<float> AlbumLayout::GetScale() const
1278 return mImpl->GetScale();
1281 void AlbumLayout::SetColor(vector<Vector2> colorList)
1283 mImpl->SetColor(colorList);
1286 vector<Vector2> AlbumLayout::GetColor() const
1288 return mImpl->GetColor();
1291 void AlbumLayout::SetRotationX(float rotation)
1293 mImpl->SetRotationX(rotation);
1296 float AlbumLayout::GetRotationX() const
1298 return mImpl->GetRotationX();
1301 void AlbumLayout::SetRotationZ(vector<float> rotationList)
1303 mImpl->SetRotationZ(rotationList);
1306 vector<float> AlbumLayout::GetRotationZ() const
1308 return mImpl->GetRotationZ();
1311 void AlbumLayout::SetCenterPosition(Vector3 pos)
1313 mImpl->SetCenterPosition(pos);
1316 Vector3 AlbumLayout::GetCenterPosition() const
1318 return mImpl->GetCenterPosition();
1321 void AlbumLayout::SetCenterScale(float scale)
1323 mImpl->SetCenterScale(scale);
1326 float AlbumLayout::GetCenterScale() const
1328 return mImpl->GetCenterScale();
1331 void AlbumLayout::SetCenterColor(Vector2 color)
1333 mImpl->SetCenterColor(color);
1336 Vector2 AlbumLayout::GetCenterColor() const
1338 return mImpl->GetCenterColor();
1341 void AlbumLayout::SetStackPosition(Vector3 rightPos, Vector3 leftPos)
1343 mImpl->SetStackPosition(rightPos, leftPos);
1346 Vector3 AlbumLayout::GetRightStackPosition() const
1348 return mImpl->GetRightStackPosition();
1351 Vector3 AlbumLayout::GetLeftStackPosition() const
1353 return mImpl->GetLeftStackPosition();
1356 void AlbumLayout::SetStackScale(float rightScale, float leftScale)
1358 mImpl->SetStackScale(rightScale,leftScale);
1361 float AlbumLayout::GetRightStackScale() const
1363 return mImpl->GetRightStackScale();
1366 float AlbumLayout::GetLeftStackScale() const
1368 return mImpl->GetLeftStackScale();
1371 void AlbumLayout::SetStackColor(Vector2 rightColor, Vector2 leftColor)
1373 mImpl->SetStackColor(rightColor, leftColor);
1376 Vector2 AlbumLayout::GetRightStackColor() const
1378 return mImpl->GetRightStackColor();
1381 Vector2 AlbumLayout::GetLeftStackColor() const
1383 return mImpl->GetLeftStackColor();
1386 AlbumLayout::AlbumLayout()
1392 } // namespace Toolkit