2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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/grid-layout.h>
22 using namespace Dali::Toolkit;
25 namespace // unnamed namespace
28 const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 4;
29 const float DEFAULT_TOP_MARGIN = 95.0f;
30 const float DEFAULT_BOTTOM_MARGIN = 20.0f;
31 const float DEFAULT_SIDE_MARGIN = 20.0f;
32 const float DEFAULT_COLUMN_SPACING = 20.0f;
33 const float DEFAULT_ROW_SPACING = 20.0f;
34 const float DEFAULT_SCROLL_SPEED_FACTOR = 0.03f;
35 const float DEFAULT_MAXIMUM_SWIPE_SPEED = 100.0f;
36 const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.015f;
38 // 4 orientations are supported
39 static const unsigned int ORIENTATION_COUNT = 4;
41 static Vector3 GetItemSizeDefaultFunction(unsigned int numberOfColumns, float layoutWidth, float sideMargin, float columnSpacing)
43 float width = (layoutWidth - sideMargin * 2.0f - columnSpacing * static_cast<float>(numberOfColumns - 1)) / static_cast<float>(numberOfColumns);
46 return Vector3(width, width * 0.75f, width * 0.75f);
49 struct GridPositionConstraint0
51 GridPositionConstraint0(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap)
52 : mColumnIndex(columnIndex),
53 mNumberOfColumns(numberOfColumns),
54 mRowSpacing(rowSpacing),
55 mColumnSpacing(columnSpacing),
56 mTopMargin(topMargin),
57 mSideMargin(sideMargin),
58 mItemSizeFunction(itemSizeFunction),
63 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
65 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
67 return Vector3(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f,
68 ((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin,
69 mColumnIndex * mZGap);
74 unsigned int mColumnIndex;
75 unsigned int mNumberOfColumns;
80 GridLayout::ItemSizeFunction mItemSizeFunction;
84 struct GridPositionConstraint90
86 GridPositionConstraint90(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap)
87 : mColumnIndex(columnIndex),
88 mNumberOfColumns(numberOfColumns),
89 mRowSpacing(rowSpacing),
90 mColumnSpacing(columnSpacing),
91 mTopMargin(topMargin),
92 mSideMargin(sideMargin),
93 mItemSizeFunction(itemSizeFunction),
98 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
100 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
102 return Vector3(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin,
103 -(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y*0.5f),
104 mColumnIndex * mZGap);
109 unsigned int mColumnIndex;
110 unsigned int mNumberOfColumns;
112 float mColumnSpacing;
115 GridLayout::ItemSizeFunction mItemSizeFunction;
119 struct GridPositionConstraint180
121 GridPositionConstraint180(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap)
122 : mColumnIndex(columnIndex),
123 mNumberOfColumns(numberOfColumns),
124 mRowSpacing(rowSpacing),
125 mColumnSpacing(columnSpacing),
126 mTopMargin(topMargin),
127 mSideMargin(sideMargin),
128 mItemSizeFunction(itemSizeFunction),
133 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
135 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
137 return Vector3(-(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f),
138 -(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin),
139 mColumnIndex * mZGap);
144 unsigned int mColumnIndex;
145 unsigned int mNumberOfColumns;
147 float mColumnSpacing;
150 GridLayout::ItemSizeFunction mItemSizeFunction;
154 struct GridPositionConstraint270
156 GridPositionConstraint270(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float topMargin, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction, const float gap)
157 : mColumnIndex(columnIndex),
158 mNumberOfColumns(numberOfColumns),
159 mRowSpacing(rowSpacing),
160 mColumnSpacing(columnSpacing),
161 mTopMargin(topMargin),
162 mSideMargin(sideMargin),
163 mItemSizeFunction(itemSizeFunction),
168 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
170 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
172 return Vector3(-(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin),
173 mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y * 0.5f,
174 mColumnIndex * mZGap);
179 unsigned int mColumnIndex;
180 unsigned int mNumberOfColumns;
182 float mColumnSpacing;
185 GridLayout::ItemSizeFunction mItemSizeFunction;
189 struct GridRotationConstraint0
191 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
193 return Quaternion(0.0f, Vector3::ZAXIS);
197 struct GridRotationConstraint90
199 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
201 return Quaternion(1.5f * Math::PI, Vector3::ZAXIS);
205 struct GridRotationConstraint180
207 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
209 return Quaternion(Math::PI, Vector3::ZAXIS);
213 struct GridRotationConstraint270
215 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
217 return Quaternion(0.5f * Math::PI, Vector3::ZAXIS);
221 struct GridColorConstraint
223 Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
225 return Vector4( 1.0f, 1.0f, 1.0f, current.a );
229 struct GridVisibilityConstraintPortrait
231 GridVisibilityConstraintPortrait(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction)
232 : mColumnIndex(columnIndex),
233 mNumberOfColumns(numberOfColumns),
234 mRowSpacing(rowSpacing),
235 mColumnSpacing(columnSpacing),
236 mSideMargin(sideMargin),
237 mItemSizeFunction(itemSizeFunction)
241 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
243 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
245 float row = (layoutPosition - static_cast<float>(mColumnIndex)) / mNumberOfColumns;
246 int rowsPerPage = ceil(layoutSize.height / (itemSize.y + mRowSpacing));
248 return (row > -2.0f) && (row < rowsPerPage);
253 unsigned int mColumnIndex;
254 unsigned int mNumberOfColumns;
256 float mColumnSpacing;
258 GridLayout::ItemSizeFunction mItemSizeFunction;
261 struct GridVisibilityConstraintLandscape
263 GridVisibilityConstraintLandscape(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction)
264 : mColumnIndex(columnIndex),
265 mNumberOfColumns(numberOfColumns),
266 mRowSpacing(rowSpacing),
267 mColumnSpacing(columnSpacing),
268 mSideMargin(sideMargin),
269 mItemSizeFunction(itemSizeFunction)
273 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
275 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
277 float row = (layoutPosition - static_cast<float>(mColumnIndex)) / mNumberOfColumns;
278 int rowsPerPage = ceil(layoutSize.width / (itemSize.y + mRowSpacing));
280 return (row > -2.0f) && (row < rowsPerPage);
285 unsigned int mColumnIndex;
286 unsigned int mNumberOfColumns;
288 float mColumnSpacing;
290 GridLayout::ItemSizeFunction mItemSizeFunction;
293 } // unnamed namespace
301 struct GridLayout::Impl
304 : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS),
305 mRowSpacing(DEFAULT_ROW_SPACING),
306 mColumnSpacing(DEFAULT_COLUMN_SPACING),
307 mTopMargin(DEFAULT_TOP_MARGIN),
308 mBottomMargin(DEFAULT_BOTTOM_MARGIN),
309 mSideMargin(DEFAULT_SIDE_MARGIN),
310 mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
311 mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
312 mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION),
313 mItemSizeFunction(GetItemSizeDefaultFunction)
315 mColorConstraint = GridColorConstraint();
317 mRotationConstraint[0] = GridRotationConstraint0();
318 mRotationConstraint[1] = GridRotationConstraint90();
319 mRotationConstraint[2] = GridRotationConstraint180();
320 mRotationConstraint[3] = GridRotationConstraint270();
323 unsigned int mNumberOfColumns;
325 float mColumnSpacing;
331 float mScrollSpeedFactor;
332 float mMaximumSwipeSpeed;
333 float mItemFlickAnimationDuration;
335 ItemLayout::QuaternionFunction mRotationConstraint[ORIENTATION_COUNT];
336 ItemLayout::Vector4Function mColorConstraint;
338 ItemSizeFunction mItemSizeFunction;
341 GridLayoutPtr GridLayout::New()
343 return GridLayoutPtr(new GridLayout());
346 GridLayout::~GridLayout()
351 void GridLayout::SetNumberOfColumns(unsigned int columns)
353 mImpl->mNumberOfColumns = columns;
356 unsigned int GridLayout::GetNumberOfColumns() const
358 return mImpl->mNumberOfColumns;
361 void GridLayout::SetRowSpacing(float spacing)
363 mImpl->mRowSpacing = spacing;
366 float GridLayout::GetRowSpacing() const
368 return mImpl->mRowSpacing;
371 void GridLayout::SetColumnSpacing(float spacing)
373 mImpl->mColumnSpacing = spacing;
376 float GridLayout::GetColumnSpacing() const
378 return mImpl->mColumnSpacing;
381 void GridLayout::SetTopMargin(float margin)
383 mImpl->mTopMargin = margin;
386 float GridLayout::GetTopMargin() const
388 return mImpl->mTopMargin;
391 void GridLayout::SetBottomMargin(float margin)
393 mImpl->mBottomMargin = margin;
396 float GridLayout::GetBottomMargin() const
398 return mImpl->mBottomMargin;
401 void GridLayout::SetSideMargin(float margin)
403 mImpl->mSideMargin = margin;
406 float GridLayout::GetSideMargin() const
408 return mImpl->mSideMargin;
411 void GridLayout::SetZGap(float gap)
416 float GridLayout::GetZGap() const
421 void GridLayout::SetItemSizeFunction(ItemSizeFunction function)
423 mImpl->mItemSizeFunction = function;
426 GridLayout::ItemSizeFunction GridLayout::GetItemSizeFunction() const
428 return mImpl->mItemSizeFunction;
431 void GridLayout::SetScrollSpeedFactor(float scrollSpeed)
433 mImpl->mScrollSpeedFactor = scrollSpeed;
436 void GridLayout::SetMaximumSwipeSpeed(float speed)
438 mImpl->mMaximumSwipeSpeed = speed;
441 void GridLayout::SetItemFlickAnimationDuration(float durationSeconds)
443 mImpl->mItemFlickAnimationDuration = durationSeconds;
446 float GridLayout::GetScrollSpeedFactor() const
448 return mImpl->mScrollSpeedFactor;
451 float GridLayout::GetMaximumSwipeSpeed() const
453 return mImpl->mMaximumSwipeSpeed;
456 float GridLayout::GetItemFlickAnimationDuration() const
458 return mImpl->mItemFlickAnimationDuration;
461 float GridLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
463 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
464 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
466 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
468 unsigned int itemsLastRow = numberOfItems % mImpl->mNumberOfColumns;
469 if (itemsLastRow == 0)
471 itemsLastRow = mImpl->mNumberOfColumns;
474 float rowsLastPage = (layoutHeight - mImpl->mBottomMargin - mImpl->mTopMargin + mImpl->mRowSpacing) / (itemSize.y + mImpl->mRowSpacing);
475 float itemsLastPage = (rowsLastPage - 1.0f) * static_cast<float>(mImpl->mNumberOfColumns) + static_cast<float>(itemsLastRow);
477 return itemsLastPage - static_cast<float>(numberOfItems);
480 float GridLayout::GetClosestAnchorPosition(float layoutPosition) const
482 float rowIndex = static_cast<float>(round(layoutPosition / mImpl->mNumberOfColumns));
483 return rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
486 float GridLayout::GetItemScrollToPosition(unsigned int itemId) const
488 float rowIndex = static_cast<float>(itemId / mImpl->mNumberOfColumns);
489 return -rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
492 ItemRange GridLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
494 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
495 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
497 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
499 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
500 int firstVisibleItem = -(static_cast<int>(firstItemPosition / mImpl->mNumberOfColumns)) * mImpl->mNumberOfColumns;
502 int firstItemIndex = std::max(0, firstVisibleItem - static_cast<int>(mImpl->mNumberOfColumns));
503 int lastItemIndex = std::max(0, firstVisibleItem + itemsPerPage);
505 return ItemRange(firstItemIndex, lastItemIndex);
508 float GridLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize)
510 ItemLayout::Vector3Function positionConstraint;
511 Vector3 itemPosition = Vector3::ZERO;
512 if (GetPositionConstraint(itemID, positionConstraint))
514 itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize);
517 GetItemSize(itemID, layoutSize, itemSize);
518 Vector3 onScreenArea = (layoutSize - (IsVertical(mOrientation) ? itemSize : Vector3(itemSize.y, itemSize.x, itemSize.z))) * 0.5f;
519 if (itemPosition.x < -onScreenArea.x
520 || itemPosition.x > onScreenArea.x
521 || itemPosition.y < -onScreenArea.y
522 || itemPosition.y > onScreenArea.y)
524 // item not within viewable area
525 float rowHeight = itemSize.y + mImpl->mRowSpacing;
526 ItemLayout::Vector3Function firstItemPositionConstraint;
527 Vector3 firstItemPosition = Vector3::ZERO;
529 if (GetPositionConstraint(0, firstItemPositionConstraint))
531 firstItemPosition = firstItemPositionConstraint(Vector3::ZERO, 0.0f, 0.0f, layoutSize);
533 switch( mOrientation )
535 case ControlOrientation::Up:
537 if(itemPosition.y > onScreenArea.y)
539 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
543 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
547 case ControlOrientation::Down:
549 if(itemPosition.y < -onScreenArea.y)
551 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
555 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
559 case ControlOrientation::Left:
561 if(itemPosition.x > onScreenArea.x)
563 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
567 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
571 case ControlOrientation::Right:
573 if(itemPosition.x < -onScreenArea.x)
575 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
579 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
584 // work out number of rows from first item position to an item aligned to bottom of screen
585 float rowDiff = offset / rowHeight;
586 float layoutPositionOffset = rowDiff * mImpl->mNumberOfColumns;
587 float scrollTo = GetItemScrollToPosition(itemID) + layoutPositionOffset;
590 return currentLayoutPosition;
593 unsigned int GridLayout::GetReserveItemCount(Vector3 layoutSize) const
595 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
596 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
598 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
599 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
603 bool GridLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const
605 // Note: itemId is not checked, since every item has the same size
607 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, (IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width), mImpl->mSideMargin, mImpl->mColumnSpacing);
611 void GridLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const
615 Vector3 currentSize( actor.GetCurrentSize() );
616 Vector3 shrink( currentSize );
618 shrink.width = min(size.width, currentSize.width);
619 shrink.height = min(size.height, currentSize.height);
621 // Do a nonlinear size animation to shrink the actor first when the actor size changes,
622 // so that we can avoid the actors overlapping during orientation change.
623 animation.Resize( actor, shrink, AlphaFunctions::EaseOut, 0.0f, durationSeconds * 0.5f );
624 animation.Resize( actor, size, AlphaFunctions::EaseIn, 0.0f, durationSeconds );
625 animation.SetDestroyAction( Animation::Bake );
629 bool GridLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
631 unsigned int columnIndex = itemId % mImpl->mNumberOfColumns;
633 if (mOrientation == ControlOrientation::Up)
635 constraint = GridPositionConstraint0(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
637 else if (mOrientation == ControlOrientation::Left)
639 constraint = GridPositionConstraint90(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
641 else if (mOrientation == ControlOrientation::Down)
643 constraint = GridPositionConstraint180(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
645 else // mOrientation == ControlOrientation::Right
647 constraint = GridPositionConstraint270(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
653 bool GridLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const
655 constraint = mImpl->mRotationConstraint[mOrientation];
659 bool GridLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
661 return false; // No scaling
664 bool GridLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const
666 constraint = mImpl->mColorConstraint;
670 bool GridLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const
672 unsigned int columnIndex = itemId % mImpl->mNumberOfColumns;
674 if (IsVertical(mOrientation))
676 constraint = GridVisibilityConstraintPortrait(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction);
680 constraint = GridVisibilityConstraintLandscape(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction);
686 Degree GridLayout::GetScrollDirection() const
688 Degree scrollDirection(0.0f);
690 if (mOrientation == ControlOrientation::Up)
692 scrollDirection = 0.0f;
694 else if (mOrientation == ControlOrientation::Left)
696 scrollDirection = 90.0f;
698 else if (mOrientation == ControlOrientation::Down)
700 scrollDirection = 180.0f;
702 else // mOrientation == ControlOrientation::Right
704 scrollDirection = 270.0f;
707 return scrollDirection;
710 int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
719 itemID = loopEnabled ? maxItems - 1 : 0;
725 itemID -= mImpl->mNumberOfColumns;
728 itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns;
735 if( itemID >= maxItems )
737 itemID = loopEnabled ? 0 : maxItems - 1;
743 itemID += mImpl->mNumberOfColumns;
744 if( itemID >= maxItems )
746 itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns;
754 GridLayout::GridLayout()
760 } // namespace Toolkit