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/grid-layout.h>
23 #include <dali/public-api/animation/animation.h>
26 using namespace Dali::Toolkit;
29 namespace // unnamed namespace
32 const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 4;
33 const float DEFAULT_TOP_MARGIN = 95.0f;
34 const float DEFAULT_BOTTOM_MARGIN = 20.0f;
35 const float DEFAULT_SIDE_MARGIN = 20.0f;
36 const float DEFAULT_COLUMN_SPACING = 20.0f;
37 const float DEFAULT_ROW_SPACING = 20.0f;
38 const float DEFAULT_SCROLL_SPEED_FACTOR = 0.03f;
39 const float DEFAULT_MAXIMUM_SWIPE_SPEED = 100.0f;
40 const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.015f;
42 // 4 orientations are supported
43 static const unsigned int ORIENTATION_COUNT = 4;
45 static Vector3 GetItemSizeDefaultFunction(unsigned int numberOfColumns, float layoutWidth, float sideMargin, float columnSpacing)
47 float width = (layoutWidth - sideMargin * 2.0f - columnSpacing * static_cast<float>(numberOfColumns - 1)) / static_cast<float>(numberOfColumns);
50 return Vector3(width, width * 0.75f, width * 0.75f);
53 struct GridPositionConstraint0
55 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)
56 : mColumnIndex(columnIndex),
57 mNumberOfColumns(numberOfColumns),
58 mRowSpacing(rowSpacing),
59 mColumnSpacing(columnSpacing),
60 mTopMargin(topMargin),
61 mSideMargin(sideMargin),
62 mItemSizeFunction(itemSizeFunction),
67 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
69 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
71 return Vector3(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f,
72 ((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin,
73 mColumnIndex * mZGap);
78 unsigned int mColumnIndex;
79 unsigned int mNumberOfColumns;
84 GridLayout::ItemSizeFunction mItemSizeFunction;
88 struct GridPositionConstraint90
90 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)
91 : mColumnIndex(columnIndex),
92 mNumberOfColumns(numberOfColumns),
93 mRowSpacing(rowSpacing),
94 mColumnSpacing(columnSpacing),
95 mTopMargin(topMargin),
96 mSideMargin(sideMargin),
97 mItemSizeFunction(itemSizeFunction),
102 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
104 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
106 return Vector3(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin,
107 -(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y*0.5f),
108 mColumnIndex * mZGap);
113 unsigned int mColumnIndex;
114 unsigned int mNumberOfColumns;
116 float mColumnSpacing;
119 GridLayout::ItemSizeFunction mItemSizeFunction;
123 struct GridPositionConstraint180
125 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)
126 : mColumnIndex(columnIndex),
127 mNumberOfColumns(numberOfColumns),
128 mRowSpacing(rowSpacing),
129 mColumnSpacing(columnSpacing),
130 mTopMargin(topMargin),
131 mSideMargin(sideMargin),
132 mItemSizeFunction(itemSizeFunction),
137 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
139 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
141 return Vector3(-(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f),
142 -(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin),
143 mColumnIndex * mZGap);
148 unsigned int mColumnIndex;
149 unsigned int mNumberOfColumns;
151 float mColumnSpacing;
154 GridLayout::ItemSizeFunction mItemSizeFunction;
158 struct GridPositionConstraint270
160 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)
161 : mColumnIndex(columnIndex),
162 mNumberOfColumns(numberOfColumns),
163 mRowSpacing(rowSpacing),
164 mColumnSpacing(columnSpacing),
165 mTopMargin(topMargin),
166 mSideMargin(sideMargin),
167 mItemSizeFunction(itemSizeFunction),
172 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
174 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
176 return Vector3(-(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin),
177 mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y * 0.5f,
178 mColumnIndex * mZGap);
183 unsigned int mColumnIndex;
184 unsigned int mNumberOfColumns;
186 float mColumnSpacing;
189 GridLayout::ItemSizeFunction mItemSizeFunction;
193 struct GridRotationConstraint0
195 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
197 return Quaternion(0.0f, Vector3::ZAXIS);
201 struct GridRotationConstraint90
203 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
205 return Quaternion(1.5f * Math::PI, Vector3::ZAXIS);
209 struct GridRotationConstraint180
211 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
213 return Quaternion(Math::PI, Vector3::ZAXIS);
217 struct GridRotationConstraint270
219 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
221 return Quaternion(0.5f * Math::PI, Vector3::ZAXIS);
225 struct GridColorConstraint
227 Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
229 return Vector4( 1.0f, 1.0f, 1.0f, current.a );
233 struct GridVisibilityConstraintPortrait
235 GridVisibilityConstraintPortrait(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction)
236 : mColumnIndex(columnIndex),
237 mNumberOfColumns(numberOfColumns),
238 mRowSpacing(rowSpacing),
239 mColumnSpacing(columnSpacing),
240 mSideMargin(sideMargin),
241 mItemSizeFunction(itemSizeFunction)
245 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
247 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
249 float row = (layoutPosition - static_cast<float>(mColumnIndex)) / mNumberOfColumns;
250 int rowsPerPage = ceil(layoutSize.height / (itemSize.y + mRowSpacing));
252 return (row > -2.0f) && (row < rowsPerPage);
257 unsigned int mColumnIndex;
258 unsigned int mNumberOfColumns;
260 float mColumnSpacing;
262 GridLayout::ItemSizeFunction mItemSizeFunction;
265 struct GridVisibilityConstraintLandscape
267 GridVisibilityConstraintLandscape(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction)
268 : mColumnIndex(columnIndex),
269 mNumberOfColumns(numberOfColumns),
270 mRowSpacing(rowSpacing),
271 mColumnSpacing(columnSpacing),
272 mSideMargin(sideMargin),
273 mItemSizeFunction(itemSizeFunction)
277 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
279 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
281 float row = (layoutPosition - static_cast<float>(mColumnIndex)) / mNumberOfColumns;
282 int rowsPerPage = ceil(layoutSize.width / (itemSize.y + mRowSpacing));
284 return (row > -2.0f) && (row < rowsPerPage);
289 unsigned int mColumnIndex;
290 unsigned int mNumberOfColumns;
292 float mColumnSpacing;
294 GridLayout::ItemSizeFunction mItemSizeFunction;
297 } // unnamed namespace
305 struct GridLayout::Impl
308 : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS),
309 mRowSpacing(DEFAULT_ROW_SPACING),
310 mColumnSpacing(DEFAULT_COLUMN_SPACING),
311 mTopMargin(DEFAULT_TOP_MARGIN),
312 mBottomMargin(DEFAULT_BOTTOM_MARGIN),
313 mSideMargin(DEFAULT_SIDE_MARGIN),
315 mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
316 mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
317 mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION),
318 mItemSizeFunction(GetItemSizeDefaultFunction)
320 mColorConstraint = GridColorConstraint();
322 mRotationConstraint[0] = GridRotationConstraint0();
323 mRotationConstraint[1] = GridRotationConstraint90();
324 mRotationConstraint[2] = GridRotationConstraint180();
325 mRotationConstraint[3] = GridRotationConstraint270();
328 unsigned int mNumberOfColumns;
330 float mColumnSpacing;
336 float mScrollSpeedFactor;
337 float mMaximumSwipeSpeed;
338 float mItemFlickAnimationDuration;
340 ItemLayout::QuaternionFunction mRotationConstraint[ORIENTATION_COUNT];
341 ItemLayout::Vector4Function mColorConstraint;
343 ItemSizeFunction mItemSizeFunction;
346 GridLayoutPtr GridLayout::New()
348 return GridLayoutPtr(new GridLayout());
351 GridLayout::~GridLayout()
356 void GridLayout::SetNumberOfColumns(unsigned int columns)
358 mImpl->mNumberOfColumns = columns;
361 unsigned int GridLayout::GetNumberOfColumns() const
363 return mImpl->mNumberOfColumns;
366 void GridLayout::SetRowSpacing(float spacing)
368 mImpl->mRowSpacing = spacing;
371 float GridLayout::GetRowSpacing() const
373 return mImpl->mRowSpacing;
376 void GridLayout::SetColumnSpacing(float spacing)
378 mImpl->mColumnSpacing = spacing;
381 float GridLayout::GetColumnSpacing() const
383 return mImpl->mColumnSpacing;
386 void GridLayout::SetTopMargin(float margin)
388 mImpl->mTopMargin = margin;
391 float GridLayout::GetTopMargin() const
393 return mImpl->mTopMargin;
396 void GridLayout::SetBottomMargin(float margin)
398 mImpl->mBottomMargin = margin;
401 float GridLayout::GetBottomMargin() const
403 return mImpl->mBottomMargin;
406 void GridLayout::SetSideMargin(float margin)
408 mImpl->mSideMargin = margin;
411 float GridLayout::GetSideMargin() const
413 return mImpl->mSideMargin;
416 void GridLayout::SetZGap(float gap)
421 float GridLayout::GetZGap() const
426 void GridLayout::SetItemSizeFunction(ItemSizeFunction function)
428 mImpl->mItemSizeFunction = function;
431 GridLayout::ItemSizeFunction GridLayout::GetItemSizeFunction() const
433 return mImpl->mItemSizeFunction;
436 void GridLayout::SetScrollSpeedFactor(float scrollSpeed)
438 mImpl->mScrollSpeedFactor = scrollSpeed;
441 void GridLayout::SetMaximumSwipeSpeed(float speed)
443 mImpl->mMaximumSwipeSpeed = speed;
446 void GridLayout::SetItemFlickAnimationDuration(float durationSeconds)
448 mImpl->mItemFlickAnimationDuration = durationSeconds;
451 float GridLayout::GetScrollSpeedFactor() const
453 return mImpl->mScrollSpeedFactor;
456 float GridLayout::GetMaximumSwipeSpeed() const
458 return mImpl->mMaximumSwipeSpeed;
461 float GridLayout::GetItemFlickAnimationDuration() const
463 return mImpl->mItemFlickAnimationDuration;
466 float GridLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
468 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
469 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
471 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
473 unsigned int itemsLastRow = numberOfItems % mImpl->mNumberOfColumns;
474 if (itemsLastRow == 0)
476 itemsLastRow = mImpl->mNumberOfColumns;
479 float rowsLastPage = (layoutHeight - mImpl->mBottomMargin - mImpl->mTopMargin + mImpl->mRowSpacing) / (itemSize.y + mImpl->mRowSpacing);
480 float itemsLastPage = (rowsLastPage - 1.0f) * static_cast<float>(mImpl->mNumberOfColumns) + static_cast<float>(itemsLastRow);
482 return itemsLastPage - static_cast<float>(numberOfItems);
485 float GridLayout::GetClosestAnchorPosition(float layoutPosition) const
487 float rowIndex = static_cast<float>(round(layoutPosition / mImpl->mNumberOfColumns));
488 return rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
491 float GridLayout::GetItemScrollToPosition(unsigned int itemId) const
493 float rowIndex = static_cast<float>(itemId / mImpl->mNumberOfColumns);
494 return -rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
497 ItemRange GridLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
499 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
500 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
502 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
504 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
505 int firstVisibleItem = -(static_cast<int>(firstItemPosition / mImpl->mNumberOfColumns)) * mImpl->mNumberOfColumns;
507 int firstItemIndex = std::max(0, firstVisibleItem - static_cast<int>(mImpl->mNumberOfColumns));
508 int lastItemIndex = std::max(0, firstVisibleItem + itemsPerPage);
510 return ItemRange(firstItemIndex, lastItemIndex);
513 float GridLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize)
515 ItemLayout::Vector3Function positionConstraint;
516 Vector3 itemPosition = Vector3::ZERO;
517 if (GetPositionConstraint(itemID, positionConstraint))
519 itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize);
522 GetItemSize(itemID, layoutSize, itemSize);
523 Vector3 onScreenArea = (layoutSize - (IsVertical(mOrientation) ? itemSize : Vector3(itemSize.y, itemSize.x, itemSize.z))) * 0.5f;
524 if (itemPosition.x < -onScreenArea.x
525 || itemPosition.x > onScreenArea.x
526 || itemPosition.y < -onScreenArea.y
527 || itemPosition.y > onScreenArea.y)
529 // item not within viewable area
530 float rowHeight = itemSize.y + mImpl->mRowSpacing;
531 ItemLayout::Vector3Function firstItemPositionConstraint;
532 Vector3 firstItemPosition = Vector3::ZERO;
534 if (GetPositionConstraint(0, firstItemPositionConstraint))
536 firstItemPosition = firstItemPositionConstraint(Vector3::ZERO, 0.0f, 0.0f, layoutSize);
538 switch( mOrientation )
540 case ControlOrientation::Up:
542 if(itemPosition.y > onScreenArea.y)
544 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
548 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
552 case ControlOrientation::Down:
554 if(itemPosition.y < -onScreenArea.y)
556 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
560 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
564 case ControlOrientation::Left:
566 if(itemPosition.x > onScreenArea.x)
568 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
572 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
576 case ControlOrientation::Right:
578 if(itemPosition.x < -onScreenArea.x)
580 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
584 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
589 // work out number of rows from first item position to an item aligned to bottom of screen
590 float rowDiff = offset / rowHeight;
591 float layoutPositionOffset = rowDiff * mImpl->mNumberOfColumns;
592 float scrollTo = GetItemScrollToPosition(itemID) + layoutPositionOffset;
595 return currentLayoutPosition;
598 unsigned int GridLayout::GetReserveItemCount(Vector3 layoutSize) const
600 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
601 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
603 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
604 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
608 bool GridLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const
610 // Note: itemId is not checked, since every item has the same size
612 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, (IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width), mImpl->mSideMargin, mImpl->mColumnSpacing);
616 void GridLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const
620 Vector3 currentSize( actor.GetCurrentSize() );
621 Vector3 shrink( currentSize );
623 shrink.width = min(size.width, currentSize.width);
624 shrink.height = min(size.height, currentSize.height);
626 // Do a nonlinear size animation to shrink the actor first when the actor size changes,
627 // so that we can avoid the actors overlapping during orientation change.
628 animation.Resize( actor, shrink, AlphaFunctions::EaseOut, 0.0f, durationSeconds * 0.5f );
629 animation.Resize( actor, size, AlphaFunctions::EaseIn, 0.0f, durationSeconds );
633 bool GridLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
635 unsigned int columnIndex = itemId % mImpl->mNumberOfColumns;
637 if (mOrientation == ControlOrientation::Up)
639 constraint = GridPositionConstraint0(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
641 else if (mOrientation == ControlOrientation::Left)
643 constraint = GridPositionConstraint90(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
645 else if (mOrientation == ControlOrientation::Down)
647 constraint = GridPositionConstraint180(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
649 else // mOrientation == ControlOrientation::Right
651 constraint = GridPositionConstraint270(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
657 bool GridLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const
659 constraint = mImpl->mRotationConstraint[mOrientation];
663 bool GridLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
665 return false; // No scaling
668 bool GridLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const
670 constraint = mImpl->mColorConstraint;
674 bool GridLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const
676 unsigned int columnIndex = itemId % mImpl->mNumberOfColumns;
678 if (IsVertical(mOrientation))
680 constraint = GridVisibilityConstraintPortrait(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction);
684 constraint = GridVisibilityConstraintLandscape(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction);
690 Degree GridLayout::GetScrollDirection() const
692 Degree scrollDirection(0.0f);
694 if (mOrientation == ControlOrientation::Up)
696 scrollDirection = 0.0f;
698 else if (mOrientation == ControlOrientation::Left)
700 scrollDirection = 90.0f;
702 else if (mOrientation == ControlOrientation::Down)
704 scrollDirection = 180.0f;
706 else // mOrientation == ControlOrientation::Right
708 scrollDirection = 270.0f;
711 return scrollDirection;
714 int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
723 itemID = loopEnabled ? maxItems - 1 : 0;
729 itemID -= mImpl->mNumberOfColumns;
732 itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns;
739 if( itemID >= maxItems )
741 itemID = loopEnabled ? 0 : maxItems - 1;
747 itemID += mImpl->mNumberOfColumns;
748 if( itemID >= maxItems )
750 itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns;
758 GridLayout::GridLayout()
764 } // namespace Toolkit