Fixed popup label properties
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / public-api / controls / scrollable / item-view / depth-layout.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/public-api/controls/scrollable/item-view/depth-layout.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <dali/public-api/animation/animation.h>
24
25 using namespace Dali;
26 using namespace Dali::Toolkit;
27
28 namespace // unnamed namespace
29 {
30
31 const unsigned int DEFAULT_NUMBER_OF_COLUMNS    = 3;
32 const float        DEFAULT_NUMBER_OF_ROWS       = 20.0f;
33 const float        DEFAULT_ROW_SPACING          = 55.0f;
34 const float        DEFAULT_BOTTOM_MARGIN_FACTOR = 0.1f;
35 const Radian       DEFAULT_TILT_ANGLE           ( Math::PI*0.12f );
36 const Radian       DEFAULT_ITEM_TILT_ANGLE      ( -Math::PI*0.025f );
37 const float        DEFAULT_SCROLL_SPEED_FACTOR  = 0.02f;
38 const float        DEFAULT_MAXIMUM_SWIPE_SPEED  = 50.0f;
39 const float        DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.03f;
40
41 static Vector3 GetItemSizeDefaultFunction(unsigned int numberOfColumns, float layoutWidth)
42 {
43   float width = layoutWidth / static_cast<float>(numberOfColumns + 1);
44
45   // 1x1 aspect ratio
46   return Vector3(width, width, width);
47 }
48
49 static float GetBottomMarginDefaultFunction(float layoutHeight)
50 {
51   return layoutHeight * DEFAULT_BOTTOM_MARGIN_FACTOR;
52 }
53
54 struct GetColumnPositionDefaultFunction
55 {
56   float operator()(unsigned int numberOfColumns,
57                    unsigned int columnNumber,
58                    const Vector3& itemSize,
59                    float layoutWidth)
60   {
61     // Share the available space between margins & column spacings
62     float availableSpace = std::max(0.0f, (layoutWidth - itemSize.width*numberOfColumns));
63
64     float leftMargin = availableSpace/numberOfColumns * 0.5f;
65
66     float columnPosition = leftMargin + itemSize.width*0.5f + columnNumber*(itemSize.width + availableSpace/numberOfColumns);
67
68     return columnPosition - layoutWidth*0.5f;
69   }
70 };
71
72 struct DepthPositionConstraint0
73 {
74   DepthPositionConstraint0(unsigned int numberOfColumns,
75                            unsigned int columnNumber,
76                            DepthLayout::ItemSizeFunction itemSizeFunction,
77                            DepthLayout::BottomMarginFunction bottomMarginFunction,
78                            DepthLayout::ColumnPositionFunction columnPositionFunction,
79                            float heightScale,
80                            float depthScale)
81   : mNumberOfColumns(numberOfColumns),
82     mColumnNumber(columnNumber),
83     mItemSizeFunction(itemSizeFunction),
84     mBottomMarginFunction(bottomMarginFunction),
85     mColumnPositionFunction(columnPositionFunction),
86     mHeightScale(heightScale),
87     mDepthScale(depthScale)
88   {
89   }
90
91   Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
92   {
93     Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width);
94
95     float rowLayoutPositon = layoutPosition - static_cast<float>(mColumnNumber);
96
97     return Vector3(  mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.width),
98                      rowLayoutPositon*mHeightScale + layoutSize.height*0.5f - mBottomMarginFunction(layoutSize.height) - itemSize.height * 0.5f,
99                     -rowLayoutPositon*mDepthScale );
100   }
101
102   unsigned int mNumberOfColumns;
103   unsigned int mColumnNumber;
104
105   DepthLayout::ItemSizeFunction       mItemSizeFunction;
106   DepthLayout::BottomMarginFunction   mBottomMarginFunction;
107   DepthLayout::ColumnPositionFunction mColumnPositionFunction;
108
109   float mHeightScale;
110   float mDepthScale;
111 };
112
113 struct DepthPositionConstraint90
114 {
115   DepthPositionConstraint90(unsigned int numberOfColumns,
116                             unsigned int columnNumber,
117                             DepthLayout::ItemSizeFunction itemSizeFunction,
118                             DepthLayout::BottomMarginFunction bottomMarginFunction,
119                             DepthLayout::ColumnPositionFunction columnPositionFunction,
120                             float heightScale,
121                             float depthScale)
122   : mNumberOfColumns(numberOfColumns),
123     mColumnNumber(columnNumber),
124     mItemSizeFunction(itemSizeFunction),
125     mBottomMarginFunction(bottomMarginFunction),
126     mColumnPositionFunction(columnPositionFunction),
127     mHeightScale(heightScale),
128     mDepthScale(depthScale)
129   {
130   }
131
132   Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
133   {
134     Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height);
135
136     float rowLayoutPositon = layoutPosition - static_cast<float>(mColumnNumber) + mNumberOfColumns*0.5f;
137
138     return Vector3(  rowLayoutPositon*mHeightScale + layoutSize.width*0.5f - mBottomMarginFunction(layoutSize.width) - itemSize.height * 0.5f,
139                      -mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.height),
140                     -rowLayoutPositon*mDepthScale );
141   }
142
143   unsigned int mNumberOfColumns;
144   unsigned int mColumnNumber;
145
146   DepthLayout::ItemSizeFunction       mItemSizeFunction;
147   DepthLayout::BottomMarginFunction   mBottomMarginFunction;
148   DepthLayout::ColumnPositionFunction mColumnPositionFunction;
149
150   float mHeightScale;
151   float mDepthScale;
152 };
153
154 struct DepthPositionConstraint180
155 {
156   DepthPositionConstraint180(unsigned int numberOfColumns,
157                              unsigned int columnNumber,
158                              DepthLayout::ItemSizeFunction itemSizeFunction,
159                              DepthLayout::BottomMarginFunction bottomMarginFunction,
160                              DepthLayout::ColumnPositionFunction columnPositionFunction,
161                              float heightScale,
162                              float depthScale)
163   : mNumberOfColumns(numberOfColumns),
164     mColumnNumber(columnNumber),
165     mItemSizeFunction(itemSizeFunction),
166     mBottomMarginFunction(bottomMarginFunction),
167     mColumnPositionFunction(columnPositionFunction),
168     mHeightScale(heightScale),
169     mDepthScale(depthScale)
170   {
171   }
172
173   Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
174   {
175     Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width);
176
177     float rowLayoutPositon = layoutPosition - static_cast<float>(mColumnNumber);
178
179     return Vector3( -mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.width),
180                     -(rowLayoutPositon*mHeightScale + layoutSize.height*0.5f - mBottomMarginFunction(layoutSize.height) - itemSize.height * 0.5f),
181                     -rowLayoutPositon*mDepthScale );
182   }
183
184   unsigned int mNumberOfColumns;
185   unsigned int mColumnNumber;
186
187   DepthLayout::ItemSizeFunction       mItemSizeFunction;
188   DepthLayout::BottomMarginFunction   mBottomMarginFunction;
189   DepthLayout::ColumnPositionFunction mColumnPositionFunction;
190
191   float mHeightScale;
192   float mDepthScale;
193 };
194
195 struct DepthPositionConstraint270
196 {
197   DepthPositionConstraint270(unsigned int numberOfColumns,
198                              unsigned int columnNumber,
199                              DepthLayout::ItemSizeFunction itemSizeFunction,
200                              DepthLayout::BottomMarginFunction bottomMarginFunction,
201                              DepthLayout::ColumnPositionFunction columnPositionFunction,
202                              float heightScale,
203                              float depthScale)
204   : mNumberOfColumns(numberOfColumns),
205     mColumnNumber(columnNumber),
206     mItemSizeFunction(itemSizeFunction),
207     mBottomMarginFunction(bottomMarginFunction),
208     mColumnPositionFunction(columnPositionFunction),
209     mHeightScale(heightScale),
210     mDepthScale(depthScale)
211   {
212   }
213
214   Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
215   {
216     Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height);
217
218     float rowLayoutPositon = layoutPosition - static_cast<float>(mColumnNumber) + mNumberOfColumns*0.5f;
219
220     return Vector3( -(rowLayoutPositon*mHeightScale + layoutSize.width*0.5f - mBottomMarginFunction(layoutSize.width) - itemSize.height * 0.5f),
221                     mColumnPositionFunction(mNumberOfColumns, mColumnNumber, itemSize, layoutSize.height),
222                     -rowLayoutPositon*mDepthScale );
223   }
224
225   unsigned int mNumberOfColumns;
226   unsigned int mColumnNumber;
227
228   DepthLayout::ItemSizeFunction       mItemSizeFunction;
229   DepthLayout::BottomMarginFunction   mBottomMarginFunction;
230   DepthLayout::ColumnPositionFunction mColumnPositionFunction;
231
232   float mHeightScale;
233   float mDepthScale;
234 };
235
236 struct DepthRotationConstraint0
237 {
238   DepthRotationConstraint0(float angleRadians)
239   : mTiltAngle(angleRadians)
240   {
241   }
242
243   Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
244   {
245     return Quaternion(0.0f, Vector3::ZAXIS) * Quaternion(mTiltAngle, Vector3::XAXIS);
246   }
247
248   float mTiltAngle;
249 };
250
251 struct DepthRotationConstraint90
252 {
253   DepthRotationConstraint90(float angleRadians)
254   : mTiltAngle(angleRadians)
255   {
256   }
257
258   Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
259   {
260     return Quaternion(1.5f * Math::PI, Vector3::ZAXIS) * Quaternion(mTiltAngle, Vector3::XAXIS);
261   }
262
263   float mTiltAngle;
264 };
265
266 struct DepthRotationConstraint180
267 {
268   DepthRotationConstraint180(float angleRadians)
269   : mTiltAngle(angleRadians)
270   {
271   }
272
273   Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
274   {
275     return Quaternion(-Math::PI, Vector3::ZAXIS) * Quaternion(mTiltAngle, Vector3::XAXIS);
276   }
277
278   float mTiltAngle;
279 };
280
281 struct DepthRotationConstraint270
282 {
283   DepthRotationConstraint270(float angleRadians)
284   : mTiltAngle(angleRadians)
285   {
286   }
287
288   Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
289   {
290     return Quaternion(0.5f * Math::PI, Vector3::ZAXIS) * Quaternion(mTiltAngle, Vector3::XAXIS);
291   }
292
293   float mTiltAngle;
294 };
295
296 struct DepthColorConstraint
297 {
298   DepthColorConstraint(unsigned int numberOfColumns, float numberOfRows, unsigned int columnNumber)
299   : mNumberOfColumns(numberOfColumns),
300     mNumberOfRows(numberOfRows),
301     mColumnNumber(columnNumber)
302   {
303   }
304
305   Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
306   {
307     float row = (layoutPosition - static_cast<float>(mColumnNumber)) / mNumberOfColumns;
308
309     float darkness(1.0f);
310     float alpha(1.0f);
311
312     if (row < 0.0f)
313     {
314       darkness = alpha = std::max(0.0f, 1.0f + row);
315     }
316     else
317     {
318       if (row > mNumberOfRows)
319       {
320         darkness = 0.0f;
321       }
322       else
323       {
324         darkness = 1.0f - ( 1.0f * (row / mNumberOfRows) );
325       }
326
327       if (row > (mNumberOfRows-1.0f))
328       {
329         alpha = std::max(0.0f, 1.0f - (row-(mNumberOfRows-1.0f)));
330       }
331     }
332
333     return Vector4( darkness, darkness, darkness, current.a * alpha );
334   }
335
336   unsigned int mNumberOfColumns;
337   float mNumberOfRows;
338   unsigned int mColumnNumber;
339 };
340
341 struct DepthVisibilityConstraint
342 {
343   DepthVisibilityConstraint(unsigned int numberOfColumns, float numberOfRows, unsigned int columnNumber)
344   : mNumberOfColumns(numberOfColumns),
345     mNumberOfRows(numberOfRows),
346     mColumnNumber(columnNumber)
347   {
348   }
349
350   bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
351   {
352     float row = (layoutPosition - static_cast<float>(mColumnNumber)) / mNumberOfColumns;
353     return (row > -1.0f) && (row < mNumberOfRows);
354   }
355
356   unsigned int mNumberOfColumns;
357   float mNumberOfRows;
358   unsigned int mColumnNumber;
359 };
360
361 } // unnamed namespace
362
363 namespace Dali
364 {
365
366 namespace Toolkit
367 {
368
369 struct PositionConstraintSet
370 {
371   ItemLayout::Vector3Function mOrientation0;
372   ItemLayout::Vector3Function mOrientation90;
373   ItemLayout::Vector3Function mOrientation180;
374   ItemLayout::Vector3Function mOrientation270;
375 };
376
377 struct DepthLayout::Impl
378 {
379   Impl()
380   : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS),
381     mNumberOfRows(DEFAULT_NUMBER_OF_ROWS),
382     mRowSpacing(DEFAULT_ROW_SPACING),
383     mTiltAngle(DEFAULT_TILT_ANGLE),
384     mItemTiltAngle(DEFAULT_ITEM_TILT_ANGLE),
385     mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
386     mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
387     mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION),
388     mItemSizeFunction(GetItemSizeDefaultFunction),
389     mBottomMarginFunction(GetBottomMarginDefaultFunction),
390     mColumnPositionFunction(GetColumnPositionDefaultFunction())
391   {
392   }
393
394   unsigned int mNumberOfColumns;
395   unsigned int mNumberOfRows;
396
397   float mRowSpacing;
398
399   Radian mTiltAngle;
400   Radian mItemTiltAngle;
401
402   float mScrollSpeedFactor;
403   float mMaximumSwipeSpeed;
404   float mItemFlickAnimationDuration;
405
406   ItemSizeFunction        mItemSizeFunction;
407   BottomMarginFunction    mBottomMarginFunction;
408   ColumnPositionFunction  mColumnPositionFunction;
409 };
410
411 DepthLayoutPtr DepthLayout::New()
412 {
413   return DepthLayoutPtr(new DepthLayout());
414 }
415
416 DepthLayout::~DepthLayout()
417 {
418   delete mImpl;
419 }
420
421 void DepthLayout::SetNumberOfColumns(unsigned int columns)
422 {
423   mImpl->mNumberOfColumns = columns;
424 }
425
426 unsigned int DepthLayout::GetNumberOfColumns() const
427 {
428   return mImpl->mNumberOfColumns;
429 }
430
431 void DepthLayout::SetNumberOfRows(unsigned int rows)
432 {
433   mImpl->mNumberOfRows = rows;
434 }
435
436 unsigned int DepthLayout::GetNumberOfRows() const
437 {
438   return mImpl->mNumberOfRows;
439 }
440
441 void DepthLayout::SetRowSpacing(float spacing)
442 {
443   mImpl->mRowSpacing = spacing;
444 }
445
446 float DepthLayout::GetRowSpacing() const
447 {
448   return mImpl->mRowSpacing;
449 }
450
451 void DepthLayout::SetTiltAngle(Degree angle)
452 {
453   mImpl->mTiltAngle = Degree( Clamp<float>(angle, -45.0f, 45.0f) );
454 }
455
456 Degree DepthLayout::GetTiltAngle() const
457 {
458   return mImpl->mTiltAngle;
459 }
460
461 void DepthLayout::SetItemSizeFunction(ItemSizeFunction function)
462 {
463   mImpl->mItemSizeFunction = function;
464 }
465
466 DepthLayout::ItemSizeFunction DepthLayout::GetItemSizeFunction() const
467 {
468   return mImpl->mItemSizeFunction;
469 }
470
471 void DepthLayout::SetBottomMarginFunction(BottomMarginFunction function)
472 {
473   mImpl->mBottomMarginFunction = function;
474 }
475
476 DepthLayout::BottomMarginFunction DepthLayout::GetBottomMarginFunction() const
477 {
478   return mImpl->mBottomMarginFunction;
479 }
480
481 void DepthLayout::SetItemTiltAngle(Degree angle)
482 {
483   mImpl->mItemTiltAngle = angle;
484 }
485
486 Degree DepthLayout::GetItemTiltAngle() const
487 {
488   return mImpl->mItemTiltAngle;
489 }
490
491 void DepthLayout::SetColumnPositionFunction(ColumnPositionFunction function)
492 {
493   mImpl->mColumnPositionFunction = function;
494 }
495
496 DepthLayout::ColumnPositionFunction DepthLayout::GetColumnPositionFunction() const
497 {
498   return mImpl->mColumnPositionFunction;
499 }
500
501 void DepthLayout::SetScrollSpeedFactor(float scrollSpeed)
502 {
503   mImpl->mScrollSpeedFactor = scrollSpeed;
504 }
505
506 void DepthLayout::SetMaximumSwipeSpeed(float speed)
507 {
508   mImpl->mMaximumSwipeSpeed = speed;
509 }
510
511 void DepthLayout::SetItemFlickAnimationDuration(float durationSeconds)
512 {
513   mImpl->mItemFlickAnimationDuration = durationSeconds;
514 }
515
516 float DepthLayout::GetScrollSpeedFactor() const
517 {
518   return mImpl->mScrollSpeedFactor;
519 }
520
521 float DepthLayout::GetMaximumSwipeSpeed() const
522 {
523   return mImpl->mMaximumSwipeSpeed;
524 }
525
526 float DepthLayout::GetItemFlickAnimationDuration() const
527 {
528   return mImpl->mItemFlickAnimationDuration;
529 }
530
531 float DepthLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
532 {
533   return static_cast<float>(mImpl->mNumberOfColumns) - static_cast<float>(numberOfItems);
534 }
535
536 float DepthLayout::GetClosestAnchorPosition(float layoutPosition) const
537 {
538   float rowIndex = static_cast<float>(round(layoutPosition / mImpl->mNumberOfColumns));
539   return rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
540 }
541
542 float DepthLayout::GetItemScrollToPosition(unsigned int itemId) const
543 {
544   float rowIndex = static_cast<float>(itemId / mImpl->mNumberOfColumns);
545   return -rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
546 }
547
548 ItemRange DepthLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
549 {
550   float firstRow = -(firstItemPosition/mImpl->mNumberOfColumns);
551   float lastRow = firstRow + mImpl->mNumberOfRows * 0.5f;
552
553   unsigned int firstItem = static_cast<unsigned int>(std::max(0.0f, firstRow * mImpl->mNumberOfColumns));
554   unsigned int lastItem  = static_cast<unsigned int>(std::max(0.0f, lastRow  * mImpl->mNumberOfColumns));
555
556   return ItemRange(firstItem, lastItem+1);
557 }
558
559 unsigned int DepthLayout::GetReserveItemCount(Vector3 layoutSize) const
560 {
561   float itemsWithinLayout = (layoutSize.depth * mImpl->mNumberOfColumns) / (cosf(mImpl->mTiltAngle) * mImpl->mRowSpacing);
562
563   return static_cast<unsigned int>(itemsWithinLayout);
564 }
565
566 bool DepthLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const
567 {
568   // Note: itemId is not checked, since every item has the same size
569
570   itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, (IsVertical(mOrientation) ? layoutSize.width : layoutSize.height) );
571   return true;
572 }
573
574 void DepthLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const
575 {
576   if(animation)
577   {
578     animation.Resize(actor, size);
579   }
580 }
581
582 bool DepthLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
583 {
584   float heightScale = -sinf(mImpl->mTiltAngle) * mImpl->mRowSpacing;
585   float depthScale  =  cosf(mImpl->mTiltAngle) * mImpl->mRowSpacing;
586
587   if (mOrientation == ControlOrientation::Up)
588   {
589     constraint = DepthPositionConstraint0( mImpl->mNumberOfColumns,
590                                            itemId % mImpl->mNumberOfColumns,
591                                            mImpl->mItemSizeFunction,
592                                            mImpl->mBottomMarginFunction,
593                                            mImpl->mColumnPositionFunction,
594                                            heightScale,
595                                            depthScale );
596   }
597   else if (mOrientation == ControlOrientation::Left)
598   {
599     constraint = DepthPositionConstraint90( mImpl->mNumberOfColumns,
600                                             itemId % mImpl->mNumberOfColumns,
601                                             mImpl->mItemSizeFunction,
602                                             mImpl->mBottomMarginFunction,
603                                             mImpl->mColumnPositionFunction,
604                                             heightScale,
605                                             depthScale );
606   }
607   else if (mOrientation == ControlOrientation::Down)
608   {
609     constraint = DepthPositionConstraint180( mImpl->mNumberOfColumns,
610                                              itemId % mImpl->mNumberOfColumns,
611                                              mImpl->mItemSizeFunction,
612                                              mImpl->mBottomMarginFunction,
613                                              mImpl->mColumnPositionFunction,
614                                              heightScale,
615                                              depthScale );
616   }
617   else // mOrientation == ControlOrientation::Right
618   {
619     constraint = DepthPositionConstraint270( mImpl->mNumberOfColumns,
620                                              itemId % mImpl->mNumberOfColumns,
621                                              mImpl->mItemSizeFunction,
622                                              mImpl->mBottomMarginFunction,
623                                              mImpl->mColumnPositionFunction,
624                                              heightScale,
625                                              depthScale );
626   }
627
628   return true;
629 }
630
631 bool DepthLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const
632 {
633   if (mOrientation == ControlOrientation::Up)
634   {
635     constraint = DepthRotationConstraint0(mImpl->mItemTiltAngle);
636   }
637   else if (mOrientation == ControlOrientation::Left)
638   {
639     constraint = DepthRotationConstraint90(mImpl->mItemTiltAngle);
640   }
641   else if (mOrientation == ControlOrientation::Down)
642   {
643     constraint = DepthRotationConstraint180(mImpl->mItemTiltAngle);
644   }
645   else // mOrientation == ControlOrientation::Right
646   {
647     constraint = DepthRotationConstraint270(mImpl->mItemTiltAngle);
648   }
649
650   return true;
651 }
652
653 bool DepthLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
654 {
655   return false; // No scaling
656 }
657
658 bool DepthLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const
659 {
660   constraint = DepthColorConstraint(mImpl->mNumberOfColumns, mImpl->mNumberOfRows*0.5f, itemId % mImpl->mNumberOfColumns);
661   return true;
662 }
663
664 bool DepthLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const
665 {
666   constraint = DepthVisibilityConstraint(mImpl->mNumberOfColumns, mImpl->mNumberOfRows*0.5f, itemId % mImpl->mNumberOfColumns);
667   return true;
668 }
669
670 Degree DepthLayout::GetScrollDirection() const
671 {
672   Degree scrollDirection(0.0f);
673
674   if (mOrientation == ControlOrientation::Up)
675   {
676     scrollDirection = 180.0f;
677   }
678   else if (mOrientation == ControlOrientation::Left)
679   {
680     scrollDirection = 270.0f;
681   }
682   else if (mOrientation == ControlOrientation::Down)
683   {
684     scrollDirection = 0.0f;
685   }
686   else // mOrientation == ControlOrientation::Right
687   {
688     scrollDirection = 90.0f;
689   }
690
691   return scrollDirection;
692 }
693
694 DepthLayout::DepthLayout()
695 : mImpl(NULL)
696 {
697   mImpl = new Impl();
698 }
699
700 float DepthLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize)
701 {
702   float scrollTo = currentLayoutPosition;
703   float row = (currentLayoutPosition + itemID - static_cast<float>(itemID % mImpl->mNumberOfColumns)) / mImpl->mNumberOfColumns;
704
705   // Check whether item is not within viewable area
706   if(row <= -1.0f)
707   {
708     scrollTo = GetItemScrollToPosition(itemID);
709   }
710   else if(row > mImpl->mNumberOfRows * 0.5f - 1.0f)
711   {
712     scrollTo = GetItemScrollToPosition(itemID) + (mImpl->mNumberOfRows - 1.0f) * 0.5f * mImpl->mNumberOfColumns;
713   }
714
715   return scrollTo;
716 }
717
718 int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
719 {
720   switch( direction )
721   {
722     case Control::Left:
723     {
724       itemID--;
725       if( itemID < 0 )
726       {
727         itemID = loopEnabled ? maxItems - 1 : 0;
728       }
729       break;
730     }
731     case Control::Up:
732     {
733       itemID += mImpl->mNumberOfColumns;
734       if( itemID >= maxItems )
735       {
736         itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns;
737       }
738       break;
739     }
740     case Control::Right:
741     {
742       itemID++;
743       if( itemID >= maxItems )
744       {
745         itemID = loopEnabled ? 0 : maxItems - 1;
746       }
747       break;
748     }
749     case Control::Down:
750     {
751       itemID -= mImpl->mNumberOfColumns;
752       if( itemID < 0 )
753       {
754         itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns;
755       }
756       break;
757     }
758   }
759   return itemID;
760 }
761
762 } // namespace Toolkit
763
764 } // namespace Dali