2 * Copyright (c) 2017 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/internal/controls/scrollable/item-view/grid-layout.h>
23 #include <dali/public-api/animation/animation.h>
24 #include <dali/public-api/animation/constraint.h>
27 #include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
28 #include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout-property.h>
31 using namespace Dali::Toolkit;
33 namespace // unnamed namespace
36 const unsigned int DEFAULT_NUMBER_OF_COLUMNS = 4;
37 const float DEFAULT_TOP_MARGIN = 95.0f;
38 const float DEFAULT_BOTTOM_MARGIN = 20.0f;
39 const float DEFAULT_SIDE_MARGIN = 20.0f;
40 const float DEFAULT_COLUMN_SPACING = 20.0f;
41 const float DEFAULT_ROW_SPACING = 20.0f;
42 const float DEFAULT_SCROLL_SPEED_FACTOR = 0.03f;
43 const float DEFAULT_MAXIMUM_SWIPE_SPEED = 100.0f;
44 const float DEFAULT_ITEM_FLICK_ANIMATION_DURATION = 0.015f;
46 struct GridPositionConstraint
48 GridPositionConstraint(
50 const unsigned int columnIndex,
51 const unsigned int numberOfColumns,
52 const float rowSpacing,
53 const float columnSpacing,
54 const float topMargin,
55 const float sideMargin,
56 const Vector3& itemSize,
58 : mItemSize( itemSize ),
60 mColumnIndex( columnIndex ),
61 mNumberOfColumns( numberOfColumns ),
62 mRowSpacing( rowSpacing ),
63 mColumnSpacing( columnSpacing ),
64 mTopMargin( topMargin ),
65 mSideMargin( sideMargin ),
70 inline void Orientation0( Vector3& current, float layoutPosition, const Vector3& layoutSize )
72 current.x = mSideMargin + ( mColumnIndex * ( mItemSize.x + mColumnSpacing ) ) + mItemSize.x * 0.5f - layoutSize.x * 0.5f;
73 current.y = ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex) ) / mNumberOfColumns - layoutSize.height * 0.5f + mItemSize.y * 0.5f + mTopMargin;
74 current.z = mColumnIndex * mZGap;
77 inline void Orientation90( Vector3& current, float layoutPosition, const Vector3& layoutSize )
79 current.x = ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex ) ) / mNumberOfColumns - layoutSize.width * 0.5f + mItemSize.y * 0.5f + mTopMargin;
80 current.y = -( mSideMargin + ( mColumnIndex * ( mItemSize.x + mColumnSpacing ) ) + mItemSize.x * 0.5f - layoutSize.y * 0.5f );
81 current.z = mColumnIndex * mZGap;
84 inline void Orientation180( Vector3& current, float layoutPosition, const Vector3& layoutSize )
86 current.x = -(mSideMargin + (mColumnIndex * (mItemSize.x + mColumnSpacing)) + mItemSize.x * 0.5f - layoutSize.x * 0.5f);
87 current.y = -( ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex ) ) / mNumberOfColumns - layoutSize.height * 0.5f + mItemSize.y * 0.5f + mTopMargin );
88 current.z = mColumnIndex * mZGap;
91 inline void Orientation270( Vector3& current, float layoutPosition, const Vector3& layoutSize )
93 current.x = -( ( ( mItemSize.y + mRowSpacing ) * ( layoutPosition - mColumnIndex ) ) / mNumberOfColumns - layoutSize.width * 0.5f + mItemSize.y * 0.5f + mTopMargin );
94 current.y = mSideMargin + ( mColumnIndex * ( mItemSize.x + mColumnSpacing ) ) + mItemSize.x * 0.5f - layoutSize.y * 0.5f;
95 current.z = mColumnIndex * mZGap;
98 void Orientation0( Vector3& current, const PropertyInputContainer& inputs )
100 float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId );
101 const Vector3& layoutSize = inputs[1]->GetVector3();
102 Orientation0( current, layoutPosition, layoutSize );
105 void Orientation90( Vector3& current, const PropertyInputContainer& inputs )
107 float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId );
108 const Vector3& layoutSize = inputs[1]->GetVector3();
109 Orientation90( current, layoutPosition, layoutSize );
112 void Orientation180( Vector3& current, const PropertyInputContainer& inputs )
114 float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId );
115 const Vector3& layoutSize = inputs[1]->GetVector3();
116 Orientation180( current, layoutPosition, layoutSize );
119 void Orientation270( Vector3& current, const PropertyInputContainer& inputs )
121 float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId );
122 const Vector3& layoutSize = inputs[1]->GetVector3();
123 Orientation270( current, layoutPosition, layoutSize );
129 unsigned int mItemId;
130 unsigned int mColumnIndex;
131 unsigned int mNumberOfColumns;
133 float mColumnSpacing;
139 void GridRotationConstraint0( Quaternion& current, const PropertyInputContainer& /* inputs */ )
141 current = Quaternion( Radian( 0.0f ), Vector3::ZAXIS );
144 void GridRotationConstraint90( Quaternion& current, const PropertyInputContainer& /* inputs */ )
146 current = Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS );
149 void GridRotationConstraint180( Quaternion& current, const PropertyInputContainer& /* inputs */ )
151 current = Quaternion( Radian( Math::PI ), Vector3::ZAXIS );
154 void GridRotationConstraint270( Quaternion& current, const PropertyInputContainer& /* inputs */ )
156 current = Quaternion( Radian( 0.5f * Math::PI ), Vector3::ZAXIS );
159 void GridColorConstraint( Vector4& current, const PropertyInputContainer& /* inputs */ )
161 current.r = current.g = current.b = 1.0f;
164 struct GridVisibilityConstraint
166 GridVisibilityConstraint(
168 const unsigned int columnIndex,
169 const unsigned int numberOfColumns,
170 const float rowSpacing,
171 const float columnSpacing,
172 const float sideMargin,
173 const Vector3& itemSize )
174 : mItemSize( itemSize ),
176 mColumnIndex( columnIndex ),
177 mNumberOfColumns( numberOfColumns ),
178 mRowSpacing( rowSpacing ),
179 mColumnSpacing( columnSpacing ),
180 mSideMargin( sideMargin )
184 void Portrait( bool& current, const PropertyInputContainer& inputs )
186 float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId );
187 const Vector3& layoutSize = inputs[1]->GetVector3();
189 float row = ( layoutPosition - static_cast< float >( mColumnIndex ) ) / mNumberOfColumns;
190 int rowsPerPage = ceil( layoutSize.height / ( mItemSize.y + mRowSpacing ) );
192 current = ( row > -2.0f ) && ( row < rowsPerPage );
195 void Landscape( bool& current, const PropertyInputContainer& inputs )
197 float layoutPosition = inputs[0]->GetFloat() + static_cast< float >( mItemId );
198 const Vector3& layoutSize = inputs[1]->GetVector3();
200 float row = ( layoutPosition - static_cast< float >( mColumnIndex ) ) / mNumberOfColumns;
201 int rowsPerPage = ceil( layoutSize.width / ( mItemSize.y + mRowSpacing ) );
203 current = ( row > -2.0f ) && ( row < rowsPerPage );
209 unsigned int mItemId;
210 unsigned int mColumnIndex;
211 unsigned int mNumberOfColumns;
213 float mColumnSpacing;
217 } // unnamed namespace
228 struct GridLayout::Impl
231 : mNumberOfColumns(DEFAULT_NUMBER_OF_COLUMNS),
232 mRowSpacing(DEFAULT_ROW_SPACING),
233 mColumnSpacing(DEFAULT_COLUMN_SPACING),
234 mTopMargin(DEFAULT_TOP_MARGIN),
235 mBottomMargin(DEFAULT_BOTTOM_MARGIN),
236 mSideMargin(DEFAULT_SIDE_MARGIN),
238 mScrollSpeedFactor(DEFAULT_SCROLL_SPEED_FACTOR),
239 mMaximumSwipeSpeed(DEFAULT_MAXIMUM_SWIPE_SPEED),
240 mItemFlickAnimationDuration(DEFAULT_ITEM_FLICK_ANIMATION_DURATION)
244 unsigned int mNumberOfColumns;
246 float mColumnSpacing;
252 float mScrollSpeedFactor;
253 float mMaximumSwipeSpeed;
254 float mItemFlickAnimationDuration;
257 GridLayoutPtr GridLayout::New()
259 return GridLayoutPtr(new GridLayout());
262 GridLayout::~GridLayout()
267 void GridLayout::SetNumberOfColumns(unsigned int columns)
269 mImpl->mNumberOfColumns = columns;
272 unsigned int GridLayout::GetNumberOfColumns() const
274 return mImpl->mNumberOfColumns;
277 void GridLayout::SetRowSpacing(float spacing)
279 mImpl->mRowSpacing = spacing;
282 float GridLayout::GetRowSpacing() const
284 return mImpl->mRowSpacing;
287 void GridLayout::SetColumnSpacing(float spacing)
289 mImpl->mColumnSpacing = spacing;
292 float GridLayout::GetColumnSpacing() const
294 return mImpl->mColumnSpacing;
297 void GridLayout::SetTopMargin(float margin)
299 mImpl->mTopMargin = margin;
302 float GridLayout::GetTopMargin() const
304 return mImpl->mTopMargin;
307 void GridLayout::SetBottomMargin(float margin)
309 mImpl->mBottomMargin = margin;
312 float GridLayout::GetBottomMargin() const
314 return mImpl->mBottomMargin;
317 void GridLayout::SetSideMargin(float margin)
319 mImpl->mSideMargin = margin;
322 float GridLayout::GetSideMargin() const
324 return mImpl->mSideMargin;
327 void GridLayout::SetZGap(float gap)
332 float GridLayout::GetZGap() const
337 void GridLayout::SetScrollSpeedFactor(float scrollSpeed)
339 mImpl->mScrollSpeedFactor = scrollSpeed;
342 void GridLayout::SetMaximumSwipeSpeed(float speed)
344 mImpl->mMaximumSwipeSpeed = speed;
347 void GridLayout::SetItemFlickAnimationDuration(float durationSeconds)
349 mImpl->mItemFlickAnimationDuration = durationSeconds;
352 float GridLayout::GetScrollSpeedFactor() const
354 return mImpl->mScrollSpeedFactor;
357 float GridLayout::GetMaximumSwipeSpeed() const
359 return mImpl->mMaximumSwipeSpeed;
362 float GridLayout::GetItemFlickAnimationDuration() const
364 return mImpl->mItemFlickAnimationDuration;
367 float GridLayout::GetMinimumLayoutPosition(unsigned int numberOfItems, Vector3 layoutSize) const
369 float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height;
372 GetItemSize( 0, layoutSize, itemSize );
374 unsigned int itemsLastRow = numberOfItems % mImpl->mNumberOfColumns;
375 if (itemsLastRow == 0)
377 itemsLastRow = mImpl->mNumberOfColumns;
380 float rowsLastPage = (layoutHeight - mImpl->mBottomMargin - mImpl->mTopMargin + mImpl->mRowSpacing) / (itemSize.y + mImpl->mRowSpacing);
381 float itemsLastPage = (rowsLastPage - 1.0f) * static_cast<float>(mImpl->mNumberOfColumns) + static_cast<float>(itemsLastRow);
383 return itemsLastPage - static_cast<float>(numberOfItems);
386 float GridLayout::GetClosestAnchorPosition(float layoutPosition) const
388 float rowIndex = static_cast<float>(round(layoutPosition / mImpl->mNumberOfColumns));
389 return rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
392 float GridLayout::GetItemScrollToPosition(unsigned int itemId) const
394 float rowIndex = static_cast< float >( itemId ) / mImpl->mNumberOfColumns;
395 return -rowIndex * static_cast<float>(mImpl->mNumberOfColumns);
398 ItemRange GridLayout::GetItemsWithinArea(float firstItemPosition, Vector3 layoutSize) const
400 float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height;
403 GetItemSize( 0, layoutSize, itemSize );
405 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
406 int firstVisibleItem = -(static_cast<int>(firstItemPosition / mImpl->mNumberOfColumns)) * mImpl->mNumberOfColumns;
408 int firstItemIndex = std::max(0, firstVisibleItem - static_cast<int>(mImpl->mNumberOfColumns));
409 int lastItemIndex = std::max(0, firstVisibleItem + itemsPerPage);
411 return ItemRange(firstItemIndex, lastItemIndex);
414 float GridLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize)
416 Vector3 itemPosition = GetItemPosition( itemID, currentLayoutPosition, layoutSize );
418 ControlOrientation::Type orientation = GetOrientation();
420 GetItemSize(itemID, layoutSize, itemSize);
421 Vector3 onScreenArea = ( layoutSize - ( IsVertical( orientation ) ? itemSize : Vector3( itemSize.y, itemSize.x, itemSize.z ) ) ) * 0.5f;
422 if (itemPosition.x < -onScreenArea.x
423 || itemPosition.x > onScreenArea.x
424 || itemPosition.y < -onScreenArea.y
425 || itemPosition.y > onScreenArea.y)
427 // item not within viewable area
428 float rowHeight = itemSize.y + mImpl->mRowSpacing;
429 Vector3 firstItemPosition = GetItemPosition( itemID, 0.0f, layoutSize );
431 switch( orientation )
433 case ControlOrientation::Up:
435 if(itemPosition.y > onScreenArea.y)
437 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
441 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
445 case ControlOrientation::Down:
447 if(itemPosition.y < -onScreenArea.y)
449 offset = ((layoutSize.y - rowHeight) * 0.5f) - firstItemPosition.y;
453 offset = ((-layoutSize.y + rowHeight) * 0.5f) - firstItemPosition.y;
457 case ControlOrientation::Left:
459 if(itemPosition.x > onScreenArea.x)
461 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
465 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
469 case ControlOrientation::Right:
471 if(itemPosition.x < -onScreenArea.x)
473 offset = ((layoutSize.x - rowHeight) * 0.5f) - firstItemPosition.x;
477 offset = ((-layoutSize.x + rowHeight) * 0.5f) - firstItemPosition.x;
482 // work out number of rows from first item position to an item aligned to bottom of screen
483 float rowDiff = offset / rowHeight;
484 float layoutPositionOffset = rowDiff * mImpl->mNumberOfColumns;
485 float scrollTo = GetItemScrollToPosition(itemID) + layoutPositionOffset;
488 return currentLayoutPosition;
491 unsigned int GridLayout::GetReserveItemCount(Vector3 layoutSize) const
493 float layoutHeight = IsHorizontal( GetOrientation() ) ? layoutSize.width : layoutSize.height;
496 GetItemSize( 0, layoutSize, itemSize );
497 int itemsPerPage = mImpl->mNumberOfColumns * ceil(layoutHeight / (itemSize.y + mImpl->mRowSpacing));
501 void GridLayout::GetDefaultItemSize( unsigned int itemId, const Vector3& layoutSize, Vector3& itemSize ) const
503 float layoutWidth = IsHorizontal( GetOrientation() ) ? layoutSize.height : layoutSize.width;
504 itemSize.width = ( layoutWidth - mImpl->mSideMargin * 2.0f - mImpl->mColumnSpacing * static_cast<float>( mImpl->mNumberOfColumns - 1 ) ) / static_cast<float>( mImpl->mNumberOfColumns );
507 itemSize.height = itemSize.depth = itemSize.width * 0.75f;
510 Degree GridLayout::GetScrollDirection() const
512 Degree scrollDirection(0.0f);
513 ControlOrientation::Type orientation = GetOrientation();
515 if ( orientation == ControlOrientation::Up )
517 scrollDirection = Degree( 0.0f );
519 else if ( orientation == ControlOrientation::Left )
521 scrollDirection = Degree( 90.0f );
523 else if ( orientation == ControlOrientation::Down )
525 scrollDirection = Degree( 180.0f );
527 else // orientation == ControlOrientation::Right
529 scrollDirection = Degree( 270.0f );
532 return scrollDirection;
535 void GridLayout::ApplyConstraints( Actor& actor, const int itemId, const Vector3& layoutSize, const Actor& itemViewActor )
537 // This just implements the default behaviour of constraint application.
538 // Custom layouts can override this function to apply their custom constraints.
539 Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast( itemViewActor );
543 GetItemSize( itemId, layoutSize, itemSize );
544 const unsigned int columnIndex = itemId % mImpl->mNumberOfColumns;
545 const ControlOrientation::Type orientation = GetOrientation();
547 // Position constraint
548 GridPositionConstraint positionConstraint( itemId,
550 mImpl->mNumberOfColumns,
552 mImpl->mColumnSpacing,
557 Constraint constraint;
558 if ( orientation == ControlOrientation::Up )
560 constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation0 );
562 else if ( orientation == ControlOrientation::Left )
564 constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation90 );
566 else if ( orientation == ControlOrientation::Down )
568 constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation180 );
570 else // orientation == ControlOrientation::Right
572 constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, positionConstraint, &GridPositionConstraint::Orientation270 );
574 constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) );
575 constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
578 // Rotation constraint
579 if ( orientation == ControlOrientation::Up )
581 constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint0 );
583 else if ( orientation == ControlOrientation::Left )
585 constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint90 );
587 else if ( orientation == ControlOrientation::Down )
589 constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint180 );
591 else // orientation == ControlOrientation::Right
593 constraint = Constraint::New< Quaternion >( actor, Actor::Property::ORIENTATION, &GridRotationConstraint270 );
598 constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, &GridColorConstraint );
599 constraint.SetRemoveAction( Dali::Constraint::Discard );
602 // Visibility constraint
603 GridVisibilityConstraint visibilityConstraint( itemId,
605 mImpl->mNumberOfColumns,
607 mImpl->mColumnSpacing,
610 if ( IsVertical( orientation ) )
612 constraint = Constraint::New<bool>( actor, Actor::Property::VISIBLE, visibilityConstraint, &GridVisibilityConstraint::Portrait );
616 constraint = Constraint::New<bool>( actor, Actor::Property::VISIBLE, visibilityConstraint, &GridVisibilityConstraint::Landscape );
618 constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_POSITION ) );
619 constraint.AddSource( ParentSource( Actor::Property::SIZE ) );
620 constraint.SetRemoveAction( Dali::Constraint::Discard );
625 void GridLayout::SetGridLayoutProperties(const Property::Map& properties)
627 // Set any properties specified for gridLayout.
628 for( unsigned int idx = 0, mapCount = properties.Count(); idx < mapCount; ++idx )
630 KeyValuePair propertyPair = properties.GetKeyValue( idx );
631 switch(DefaultItemLayoutProperty::Property(propertyPair.first.indexKey))
633 case DefaultItemLayoutProperty::GRID_COLUMN_NUMBER:
635 SetNumberOfColumns(propertyPair.second.Get<int>());
638 case DefaultItemLayoutProperty::GRID_ROW_SPACING:
640 SetRowSpacing(propertyPair.second.Get<float>());
643 case DefaultItemLayoutProperty::GRID_COLUMN_SPACING:
645 SetColumnSpacing(propertyPair.second.Get<float>());
648 case DefaultItemLayoutProperty::GRID_TOP_MARGIN:
650 SetTopMargin(propertyPair.second.Get<float>());
653 case DefaultItemLayoutProperty::GRID_BOTTOM_MARGIN:
655 SetBottomMargin(propertyPair.second.Get<float>());
658 case DefaultItemLayoutProperty::GRID_SIDE_MARGIN:
660 SetSideMargin(propertyPair.second.Get<float>());
663 case DefaultItemLayoutProperty::GRID_SCROLL_SPEED_FACTOR:
665 SetScrollSpeedFactor(propertyPair.second.Get<float>());
668 case DefaultItemLayoutProperty::GRID_MAXIMUM_SWIPE_SPEED:
670 SetMaximumSwipeSpeed(propertyPair.second.Get<float>());
673 case DefaultItemLayoutProperty::GRID_ITEM_FLICK_ANIMATION_DURATION:
675 SetItemFlickAnimationDuration(propertyPair.second.Get<float>());
686 Vector3 GridLayout::GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const
688 Vector3 itemPosition = Vector3::ZERO;
689 const unsigned int columnIndex = itemID % mImpl->mNumberOfColumns;
690 const ControlOrientation::Type orientation = GetOrientation();
692 GetItemSize( itemID, layoutSize, itemSize );
694 GridPositionConstraint positionConstraintStruct( itemID,
696 mImpl->mNumberOfColumns,
698 mImpl->mColumnSpacing,
704 if ( orientation == ControlOrientation::Up )
706 positionConstraintStruct.Orientation0( itemPosition, currentLayoutPosition + itemID, layoutSize );
708 else if ( orientation == ControlOrientation::Left )
710 positionConstraintStruct.Orientation90( itemPosition, currentLayoutPosition + itemID, layoutSize );
712 else if ( orientation == ControlOrientation::Down )
714 positionConstraintStruct.Orientation180( itemPosition, currentLayoutPosition + itemID, layoutSize );
716 else // orientation == ControlOrientation::Right
718 positionConstraintStruct.Orientation270( itemPosition, currentLayoutPosition + itemID, layoutSize );
724 int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
728 case Toolkit::Control::KeyboardFocus::LEFT:
733 itemID = loopEnabled ? maxItems - 1 : 0;
737 case Toolkit::Control::KeyboardFocus::UP:
739 itemID -= mImpl->mNumberOfColumns;
742 itemID = loopEnabled ? itemID + maxItems : itemID + mImpl->mNumberOfColumns;
746 case Toolkit::Control::KeyboardFocus::RIGHT:
749 if( itemID >= maxItems )
751 itemID = loopEnabled ? 0 : maxItems - 1;
755 case Toolkit::Control::KeyboardFocus::DOWN:
757 itemID += mImpl->mNumberOfColumns;
758 if( itemID >= maxItems )
760 itemID = loopEnabled ? 0 : itemID - mImpl->mNumberOfColumns;
772 GridLayout::GridLayout()
778 } // namespace Internal
780 } // namespace Toolkit