2 * Copyright (c) 2015 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;
28 namespace // unnamed namespace
31 const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 4;
32 const float DEFAULT_TOP_MARGIN = 95.0f;
33 const float DEFAULT_BOTTOM_MARGIN = 20.0f;
34 const float DEFAULT_SIDE_MARGIN = 20.0f;
35 const float DEFAULT_COLUMN_SPACING = 20.0f;
36 const float DEFAULT_ROW_SPACING = 20.0f;
37 const float DEFAULT_SCROLL_SPEED_FACTOR = 0.03f;
38 const float DEFAULT_MAXIMUM_SWIPE_SPEED = 100.0f;
39 const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.015f;
41 // 4 orientations are supported
42 static const unsigned int ORIENTATION_COUNT = 4;
44 static Vector3 GetItemSizeDefaultFunction(unsigned int numberOfColumns, float layoutWidth, float sideMargin, float columnSpacing)
46 float width = (layoutWidth - sideMargin * 2.0f - columnSpacing * static_cast<float>(numberOfColumns - 1)) / static_cast<float>(numberOfColumns);
49 return Vector3(width, width * 0.75f, width * 0.75f);
52 struct GridPositionConstraint0
54 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)
55 : mColumnIndex(columnIndex),
56 mNumberOfColumns(numberOfColumns),
57 mRowSpacing(rowSpacing),
58 mColumnSpacing(columnSpacing),
59 mTopMargin(topMargin),
60 mSideMargin(sideMargin),
61 mItemSizeFunction(itemSizeFunction),
66 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
68 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
70 return Vector3(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f,
71 ((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin,
72 mColumnIndex * mZGap);
77 unsigned int mColumnIndex;
78 unsigned int mNumberOfColumns;
83 GridLayout::ItemSizeFunction mItemSizeFunction;
87 struct GridPositionConstraint90
89 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)
90 : mColumnIndex(columnIndex),
91 mNumberOfColumns(numberOfColumns),
92 mRowSpacing(rowSpacing),
93 mColumnSpacing(columnSpacing),
94 mTopMargin(topMargin),
95 mSideMargin(sideMargin),
96 mItemSizeFunction(itemSizeFunction),
101 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
103 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
105 return Vector3(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin,
106 -(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y*0.5f),
107 mColumnIndex * mZGap);
112 unsigned int mColumnIndex;
113 unsigned int mNumberOfColumns;
115 float mColumnSpacing;
118 GridLayout::ItemSizeFunction mItemSizeFunction;
122 struct GridPositionConstraint180
124 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)
125 : mColumnIndex(columnIndex),
126 mNumberOfColumns(numberOfColumns),
127 mRowSpacing(rowSpacing),
128 mColumnSpacing(columnSpacing),
129 mTopMargin(topMargin),
130 mSideMargin(sideMargin),
131 mItemSizeFunction(itemSizeFunction),
136 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
138 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
140 return Vector3(-(mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.x * 0.5f),
141 -(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.height * 0.5f + itemSize.y * 0.5f + mTopMargin),
142 mColumnIndex * mZGap);
147 unsigned int mColumnIndex;
148 unsigned int mNumberOfColumns;
150 float mColumnSpacing;
153 GridLayout::ItemSizeFunction mItemSizeFunction;
157 struct GridPositionConstraint270
159 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)
160 : mColumnIndex(columnIndex),
161 mNumberOfColumns(numberOfColumns),
162 mRowSpacing(rowSpacing),
163 mColumnSpacing(columnSpacing),
164 mTopMargin(topMargin),
165 mSideMargin(sideMargin),
166 mItemSizeFunction(itemSizeFunction),
171 Vector3 operator()(const Vector3& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
173 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
175 return Vector3(-(((itemSize.y + mRowSpacing) * (layoutPosition - mColumnIndex)) / mNumberOfColumns - layoutSize.width * 0.5f + itemSize.y * 0.5f + mTopMargin),
176 mSideMargin + (mColumnIndex * (itemSize.x + mColumnSpacing)) + itemSize.x * 0.5f - layoutSize.y * 0.5f,
177 mColumnIndex * mZGap);
182 unsigned int mColumnIndex;
183 unsigned int mNumberOfColumns;
185 float mColumnSpacing;
188 GridLayout::ItemSizeFunction mItemSizeFunction;
192 struct GridRotationConstraint0
194 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
196 return Quaternion( Radian( 0.0f ), Vector3::ZAXIS);
200 struct GridRotationConstraint90
202 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
204 return Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS);
208 struct GridRotationConstraint180
210 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
212 return Quaternion( Radian( Math::PI ), Vector3::ZAXIS);
216 struct GridRotationConstraint270
218 Quaternion operator()(const Quaternion& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
220 return Quaternion( Radian( 0.5f * Math::PI ), Vector3::ZAXIS);
224 struct GridColorConstraint
226 Vector4 operator()(const Vector4& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
228 return Vector4( 1.0f, 1.0f, 1.0f, current.a );
232 struct GridVisibilityConstraintPortrait
234 GridVisibilityConstraintPortrait(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction)
235 : mColumnIndex(columnIndex),
236 mNumberOfColumns(numberOfColumns),
237 mRowSpacing(rowSpacing),
238 mColumnSpacing(columnSpacing),
239 mSideMargin(sideMargin),
240 mItemSizeFunction(itemSizeFunction)
244 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
246 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.width, mSideMargin, mColumnSpacing);
248 float row = (layoutPosition - static_cast<float>(mColumnIndex)) / mNumberOfColumns;
249 int rowsPerPage = ceil(layoutSize.height / (itemSize.y + mRowSpacing));
251 return (row > -2.0f) && (row < rowsPerPage);
256 unsigned int mColumnIndex;
257 unsigned int mNumberOfColumns;
259 float mColumnSpacing;
261 GridLayout::ItemSizeFunction mItemSizeFunction;
264 struct GridVisibilityConstraintLandscape
266 GridVisibilityConstraintLandscape(const unsigned int columnIndex, const unsigned int numberOfColumns, const float rowSpacing, const float columnSpacing, const float sideMargin, GridLayout::ItemSizeFunction itemSizeFunction)
267 : mColumnIndex(columnIndex),
268 mNumberOfColumns(numberOfColumns),
269 mRowSpacing(rowSpacing),
270 mColumnSpacing(columnSpacing),
271 mSideMargin(sideMargin),
272 mItemSizeFunction(itemSizeFunction)
276 bool operator()(const bool& current, const float& layoutPosition, const float& scrollSpeed, const Vector3& layoutSize)
278 Vector3 itemSize = mItemSizeFunction(mNumberOfColumns, layoutSize.height, mSideMargin, mColumnSpacing);
280 float row = (layoutPosition - static_cast<float>(mColumnIndex)) / mNumberOfColumns;
281 int rowsPerPage = ceil(layoutSize.width / (itemSize.y + mRowSpacing));
283 return (row > -2.0f) && (row < rowsPerPage);
288 unsigned int mColumnIndex;
289 unsigned int mNumberOfColumns;
291 float mColumnSpacing;
293 GridLayout::ItemSizeFunction mItemSizeFunction;
296 } // unnamed namespace
304 struct GridLayout::Impl
307 : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS),
308 mRowSpacing(DEFAULT_ROW_SPACING),
309 mColumnSpacing(DEFAULT_COLUMN_SPACING),
310 mTopMargin(DEFAULT_TOP_MARGIN),
311 mBottomMargin(DEFAULT_BOTTOM_MARGIN),
312 mSideMargin(DEFAULT_SIDE_MARGIN),
314 mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
315 mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
316 mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION),
317 mItemSizeFunction(GetItemSizeDefaultFunction)
319 mColorConstraint = GridColorConstraint();
321 mRotationConstraint[0] = GridRotationConstraint0();
322 mRotationConstraint[1] = GridRotationConstraint90();
323 mRotationConstraint[2] = GridRotationConstraint180();
324 mRotationConstraint[3] = GridRotationConstraint270();
327 unsigned int mNumberOfColumns;
329 float mColumnSpacing;
335 float mScrollSpeedFactor;
336 float mMaximumSwipeSpeed;
337 float mItemFlickAnimationDuration;
339 ItemLayout::QuaternionFunction mRotationConstraint[ORIENTATION_COUNT];
340 ItemLayout::Vector4Function mColorConstraint;
342 ItemSizeFunction mItemSizeFunction;
345 GridLayoutPtr GridLayout::New()
347 return GridLayoutPtr(new GridLayout());
350 GridLayout::~GridLayout()
355 void GridLayout::SetNumberOfColumns(unsigned int columns)
357 mImpl->mNumberOfColumns = columns;
360 unsigned int GridLayout::GetNumberOfColumns() const
362 return mImpl->mNumberOfColumns;
365 void GridLayout::SetRowSpacing(float spacing)
367 mImpl->mRowSpacing = spacing;
370 float GridLayout::GetRowSpacing() const
372 return mImpl->mRowSpacing;
375 void GridLayout::SetColumnSpacing(float spacing)
377 mImpl->mColumnSpacing = spacing;
380 float GridLayout::GetColumnSpacing() const
382 return mImpl->mColumnSpacing;
385 void GridLayout::SetTopMargin(float margin)
387 mImpl->mTopMargin = margin;
390 float GridLayout::GetTopMargin() const
392 return mImpl->mTopMargin;
395 void GridLayout::SetBottomMargin(float margin)
397 mImpl->mBottomMargin = margin;
400 float GridLayout::GetBottomMargin() const
402 return mImpl->mBottomMargin;
405 void GridLayout::SetSideMargin(float margin)
407 mImpl->mSideMargin = margin;
410 float GridLayout::GetSideMargin() const
412 return mImpl->mSideMargin;
415 void GridLayout::SetZGap(float gap)
420 float GridLayout::GetZGap() const
425 void GridLayout::SetItemSizeFunction(ItemSizeFunction function)
427 mImpl->mItemSizeFunction = function;
430 GridLayout::ItemSizeFunction GridLayout::GetItemSizeFunction() const
432 return mImpl->mItemSizeFunction;
435 void GridLayout::SetScrollSpeedFactor(float scrollSpeed)
437 mImpl->mScrollSpeedFactor = scrollSpeed;
440 void GridLayout::SetMaximumSwipeSpeed(float speed)
442 mImpl->mMaximumSwipeSpeed = speed;
445 void GridLayout::SetItemFlickAnimationDuration(float durationSeconds)
447 mImpl->mItemFlickAnimationDuration = durationSeconds;
450 float GridLayout::GetScrollSpeedFactor() const
452 return mImpl->mScrollSpeedFactor;
455 float GridLayout::GetMaximumSwipeSpeed() const
457 return mImpl->mMaximumSwipeSpeed;
460 float GridLayout::GetItemFlickAnimationDuration() const
462 return mImpl->mItemFlickAnimationDuration;
465 float GridLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
467 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
468 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
470 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
472 unsigned int itemsLastRow = numberOfItems % mImpl->mNumberOfColumns;
473 if (itemsLastRow == 0)
475 itemsLastRow = mImpl->mNumberOfColumns;
478 float rowsLastPage = (layoutHeight - mImpl->mBottomMargin - mImpl->mTopMargin + mImpl->mRowSpacing) / (itemSize.y + mImpl->mRowSpacing);
479 float itemsLastPage = (rowsLastPage - 1.0f) * static_cast<float>(mImpl->mNumberOfColumns) + static_cast<float>(itemsLastRow);
481 return itemsLastPage - static_cast<float>(numberOfItems);
484 float GridLayout::GetClosestAnchorPosition(float layoutPosition) const
486 float rowIndex = static_cast<float>(round(layoutPosition / mImpl->mNumberOfColumns));
487 return rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
490 float GridLayout::GetItemScrollToPosition(unsigned int itemId) const
492 float rowIndex = static_cast<float>(itemId / mImpl->mNumberOfColumns);
493 return -rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
496 ItemRange GridLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
498 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
499 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
501 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
503 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
504 int firstVisibleItem = -(static_cast<int>(firstItemPosition / mImpl->mNumberOfColumns)) * mImpl->mNumberOfColumns;
506 int firstItemIndex = std::max(0, firstVisibleItem - static_cast<int>(mImpl->mNumberOfColumns));
507 int lastItemIndex = std::max(0, firstVisibleItem + itemsPerPage);
509 return ItemRange(firstItemIndex, lastItemIndex);
512 float GridLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize)
514 ItemLayout::Vector3Function positionConstraint;
515 Vector3 itemPosition = Vector3::ZERO;
516 if (GetPositionConstraint(itemID, positionConstraint))
518 itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize);
521 GetItemSize(itemID, layoutSize, itemSize);
522 Vector3 onScreenArea = (layoutSize - (IsVertical(mOrientation) ? itemSize : Vector3(itemSize.y, itemSize.x, itemSize.z))) * 0.5f;
523 if (itemPosition.x < -onScreenArea.x
524 || itemPosition.x > onScreenArea.x
525 || itemPosition.y < -onScreenArea.y
526 || itemPosition.y > onScreenArea.y)
528 // item not within viewable area
529 float rowHeight = itemSize.y + mImpl->mRowSpacing;
530 ItemLayout::Vector3Function firstItemPositionConstraint;
531 Vector3 firstItemPosition = Vector3::ZERO;
533 if (GetPositionConstraint(0, firstItemPositionConstraint))
535 firstItemPosition = firstItemPositionConstraint(Vector3::ZERO, 0.0f, 0.0f, layoutSize);
537 switch( mOrientation )
539 case ControlOrientation::Up:
541 if(itemPosition.y > onScreenArea.y)
543 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
547 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
551 case ControlOrientation::Down:
553 if(itemPosition.y < -onScreenArea.y)
555 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
559 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
563 case ControlOrientation::Left:
565 if(itemPosition.x > onScreenArea.x)
567 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
571 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
575 case ControlOrientation::Right:
577 if(itemPosition.x < -onScreenArea.x)
579 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
583 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
588 // work out number of rows from first item position to an item aligned to bottom of screen
589 float rowDiff = offset / rowHeight;
590 float layoutPositionOffset = rowDiff * mImpl->mNumberOfColumns;
591 float scrollTo = GetItemScrollToPosition(itemID) + layoutPositionOffset;
594 return currentLayoutPosition;
597 unsigned int GridLayout::GetReserveItemCount(Vector3 layoutSize) const
599 float layoutWidth = IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width;
600 float layoutHeight = IsHorizontal(mOrientation) ? layoutSize.width : layoutSize.height;
602 Vector3 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, layoutWidth, mImpl->mSideMargin, mImpl->mColumnSpacing);
603 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
607 bool GridLayout::GetItemSize(unsigned int itemId, Vector3 layoutSize, Vector3& itemSize) const
609 // Note: itemId is not checked, since every item has the same size
611 itemSize = mImpl->mItemSizeFunction( mImpl->mNumberOfColumns, (IsHorizontal(mOrientation) ? layoutSize.height : layoutSize.width), mImpl->mSideMargin, mImpl->mColumnSpacing);
615 void GridLayout::GetResizeAnimation(Animation& animation, Actor actor, Vector3 size, float durationSeconds) const
619 Vector3 currentSize( actor.GetCurrentSize() );
620 Vector3 shrink( currentSize );
622 shrink.width = std::min(size.width, currentSize.width);
623 shrink.height = std::min(size.height, currentSize.height);
625 // Do a nonlinear size animation to shrink the actor first when the actor size changes,
626 // so that we can avoid the actors overlapping during orientation change.
627 animation.AnimateTo( Property( actor, Actor::Property::SIZE ), shrink, AlphaFunction::EASE_OUT, TimePeriod( 0.0f, durationSeconds * 0.5f ) );
628 animation.AnimateTo( Property( actor, Actor::Property::SIZE ), size, AlphaFunction::EASE_IN, TimePeriod( 0.0f, durationSeconds ) );
632 bool GridLayout::GetPositionConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
634 unsigned int columnIndex = itemId % mImpl->mNumberOfColumns;
636 if (mOrientation == ControlOrientation::Up)
638 constraint = GridPositionConstraint0(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
640 else if (mOrientation == ControlOrientation::Left)
642 constraint = GridPositionConstraint90(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
644 else if (mOrientation == ControlOrientation::Down)
646 constraint = GridPositionConstraint180(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
648 else // mOrientation == ControlOrientation::Right
650 constraint = GridPositionConstraint270(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mTopMargin, mImpl->mSideMargin, mImpl->mItemSizeFunction, mImpl->mZGap);
656 bool GridLayout::GetRotationConstraint(unsigned int itemId, ItemLayout::QuaternionFunction& constraint) const
658 constraint = mImpl->mRotationConstraint[mOrientation];
662 bool GridLayout::GetScaleConstraint(unsigned int itemId, ItemLayout::Vector3Function& constraint) const
664 return false; // No scaling
667 bool GridLayout::GetColorConstraint(unsigned int itemId, ItemLayout::Vector4Function& constraint) const
669 constraint = mImpl->mColorConstraint;
673 bool GridLayout::GetVisibilityConstraint(unsigned int itemId, ItemLayout::BoolFunction& constraint) const
675 unsigned int columnIndex = itemId % mImpl->mNumberOfColumns;
677 if (IsVertical(mOrientation))
679 constraint = GridVisibilityConstraintPortrait(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction);
683 constraint = GridVisibilityConstraintLandscape(columnIndex, mImpl->mNumberOfColumns, mImpl->mRowSpacing, mImpl->mColumnSpacing, mImpl->mSideMargin, mImpl->mItemSizeFunction);
689 Degree GridLayout::GetScrollDirection() const
691 Degree scrollDirection(0.0f);
693 if (mOrientation == ControlOrientation::Up)
695 scrollDirection = Degree( 0.0f );
697 else if (mOrientation == ControlOrientation::Left)
699 scrollDirection = Degree( 90.0f );
701 else if (mOrientation == ControlOrientation::Down)
703 scrollDirection = Degree( 180.0f );
705 else // mOrientation == ControlOrientation::Right
707 scrollDirection = Degree( 270.0f );
710 return scrollDirection;
713 int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
722 itemID = loopEnabled ? maxItems - 1 : 0;
728 itemID -= mImpl->mNumberOfColumns;
731 itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns;
738 if( itemID >= maxItems )
740 itemID = loopEnabled ? 0 : maxItems - 1;
746 itemID += mImpl->mNumberOfColumns;
747 if( itemID >= maxItems )
749 itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns;
757 GridLayout::GridLayout()
763 } // namespace Toolkit