*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/devel-api/object/property-helper-devel.h>
// INTERNAL INCLUDES
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/devel-api/object/property-helper-devel.h>
// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
#include <dali-toolkit/internal/controls/scrollable/item-view/grid-layout.h>
#include <dali-toolkit/internal/controls/scrollable/item-view/depth-layout.h>
#include <dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.h>
#include <dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h>
using std::string;
#include <dali-toolkit/internal/controls/scrollable/item-view/grid-layout.h>
#include <dali-toolkit/internal/controls/scrollable/item-view/depth-layout.h>
#include <dali-toolkit/internal/controls/scrollable/item-view/spiral-layout.h>
#include <dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h>
using std::string;
DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "wheelScrollDistanceStep", FLOAT, WHEEL_SCROLL_DISTANCE_STEP )
DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "snapToItemEnabled", BOOLEAN, SNAP_TO_ITEM_ENABLED )
DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "refreshInterval", FLOAT, REFRESH_INTERVAL )
DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "wheelScrollDistanceStep", FLOAT, WHEEL_SCROLL_DISTANCE_STEP )
DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "snapToItemEnabled", BOOLEAN, SNAP_TO_ITEM_ENABLED )
DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "refreshInterval", FLOAT, REFRESH_INTERVAL )
-DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, ItemView, "layout", ARRAY, LAYOUT )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "layout", ARRAY, LAYOUT )
DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition", FLOAT, LAYOUT_POSITION)
DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition", FLOAT, LAYOUT_POSITION)
+void InsertToItemContainer( ItemContainer& items, Item item )
+{
+ if( items.end() == FindItemById( items, item.first ) )
+ {
+ ItemIter iterToInsert = std::lower_bound( items.begin(), items.end(), item );
+ items.insert( iterToInsert, item );
+ }
+}
+
+
/**
* Helper to apply size constraint to mOvershootOverlay
* @param[in] overshootOverlay The overshootOverlay actor
/**
* Helper to apply size constraint to mOvershootOverlay
* @param[in] overshootOverlay The overshootOverlay actor
mItemFactory(factory),
mItemsParentOrigin(ParentOrigin::CENTER),
mItemsAnchorPoint(AnchorPoint::CENTER),
mItemFactory(factory),
mItemsParentOrigin(ParentOrigin::CENTER),
mItemsAnchorPoint(AnchorPoint::CENTER),
mAnimatingOvershootOn(false),
mAnimateOvershootOff(false),
mAnchoringEnabled(false),
mAnimatingOvershootOn(false),
mAnimateOvershootOff(false),
mAnchoringEnabled(false),
Actor self = Self();
Vector2 stageSize = Stage::GetCurrent().GetSize();
mWheelScrollDistanceStep = stageSize.y * DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
Actor self = Self();
Vector2 stageSize = Stage::GetCurrent().GetSize();
mWheelScrollDistanceStep = stageSize.y * DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION;
- self.TouchSignal().Connect( this, &ItemView::OnTouch );
- EnableGestureDetection(Gesture::Type(Gesture::Pan));
+ self.TouchedSignal().Connect( this, &ItemView::OnTouch );
+ EnableGestureDetection(GestureType::Value(GestureType::PAN));
mWheelEventFinishedTimer = Timer::New( WHEEL_EVENT_FINISHED_TIME_OUT );
mWheelEventFinishedTimer.TickSignal().Connect( this, &ItemView::OnWheelEventFinished );
SetRefreshInterval(DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS);
mWheelEventFinishedTimer = Timer::New( WHEEL_EVENT_FINISHED_TIME_OUT );
mWheelEventFinishedTimer.TickSignal().Connect( this, &ItemView::OnWheelEventFinished );
SetRefreshInterval(DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS);
+
+ // Connect wheel event
+ self.WheelEventSignal().Connect( this, &ItemView::OnWheelEvent );
+
+ DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor)
+ {
+ return std::unique_ptr<Dali::Accessibility::Accessible>(new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE));
+ });
}
void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSize, float durationSeconds)
}
void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSize, float durationSeconds)
{
ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, currentLayoutPosition, cacheExtra/*reserve extra*/);
RemoveActorsOutsideRange( range );
{
ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, currentLayoutPosition, cacheExtra/*reserve extra*/);
RemoveActorsOutsideRange( range );
if( mItemPool.end() != foundIter )
{
SetupActor( newItem, layoutSize );
if( mItemPool.end() != foundIter )
{
SetupActor( newItem, layoutSize );
if( iter != mItemPool.end() &&
iter->first > newItem.first )
{
displacedActor = iter->second;
if( iter != mItemPool.end() &&
iter->first > newItem.first )
{
displacedActor = iter->second;
if ( lastIter != mItemPool.rend() )
{
ItemId lastId = lastIter->first;
Item lastItem( lastId + 1, displacedActor );
if ( lastIter != mItemPool.rend() )
{
ItemId lastId = lastIter->first;
Item lastItem( lastId + 1, displacedActor );
lastItem.second.RemoveConstraints();
mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, layoutSize, Self() );
lastItem.second.RemoveConstraints();
mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, layoutSize, Self() );
- std::set<Item> sortedItems;
- for( ConstItemIter iter = newItems.begin(); newItems.end() != iter; ++iter )
- {
- sortedItems.insert( *iter );
- }
+ ItemContainer sortedItems(newItems);
+ std::sort( sortedItems.begin(), sortedItems.end() );
if( mItemPool.end() != foundIter )
{
Actor moveMe = foundIter->second;
foundIter->second = iter->second;
// Move the existing actors to make room
if( mItemPool.end() != foundIter )
{
Actor moveMe = foundIter->second;
foundIter->second = iter->second;
// Move the existing actors to make room
// Create last item
ItemId lastId = mItemPool.rbegin()->first;
Item lastItem( lastId + 1, moveMe );
// Create last item
ItemId lastId = mItemPool.rbegin()->first;
Item lastItem( lastId + 1, moveMe );
- set<ItemId> sortedItems;
- for( ConstItemIdIter iter = itemIds.begin(); itemIds.end() != iter; ++iter )
- {
- sortedItems.insert( *iter );
- }
+ ItemIdContainer sortedItems(itemIds);
+ std::sort( sortedItems.begin(), sortedItems.end() );
if( removeIter != mItemPool.end() )
{
ReleaseActor(itemId, removeIter->second);
if( removeIter != mItemPool.end() )
{
ReleaseActor(itemId, removeIter->second);
SetupActor( replacementItem, layoutSize );
Self().Add( replacementItem.second );
SetupActor( replacementItem, layoutSize );
Self().Add( replacementItem.second );
if( mItemPool.end() != iter )
{
ReleaseActor(iter->first, iter->second);
if( mItemPool.end() != iter )
{
ReleaseActor(iter->first, iter->second);
void ItemView::RemoveActorsOutsideRange( ItemRange range )
{
// Remove unwanted actors from the ItemView & ItemPool
void ItemView::RemoveActorsOutsideRange( ItemRange range )
{
// Remove unwanted actors from the ItemView & ItemPool
// Total number of items may change dynamically.
// Always recalculate the domain size to reflect that.
// Total number of items may change dynamically.
// Always recalculate the domain size to reflect that.
- item.second.SetParentOrigin( mItemsParentOrigin );
- item.second.SetAnchorPoint( mItemsAnchorPoint );
+ item.second.SetProperty( Actor::Property::PARENT_ORIGIN, mItemsParentOrigin );
+ item.second.SetProperty( Actor::Property::ANCHOR_POINT, mItemsAnchorPoint );
mActiveLayout->ApplyConstraints( item.second, item.first, layoutSize, Self() );
}
mActiveLayout->ApplyConstraints( item.second, item.first, layoutSize, Self() );
}
- const Vector3 layoutSize = Self().GetCurrentSize();
- float layoutPositionDelta = GetCurrentLayoutPosition(0) - (event.z * mWheelScrollDistanceStep * mActiveLayout->GetScrollSpeedFactor());
+ const Vector3 layoutSize = Self().GetCurrentProperty< Vector3 >( Actor::Property::SIZE );
+ float layoutPositionDelta = GetCurrentLayoutPosition(0) - (event.GetDelta() * mWheelScrollDistanceStep * mActiveLayout->GetScrollSpeedFactor());
float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout);
self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition );
float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout);
self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition );
- float firstItemScrollPosition = ClampFirstItemPosition(GetCurrentLayoutPosition(0), Self().GetCurrentSize(), *mActiveLayout);
+ float firstItemScrollPosition = ClampFirstItemPosition(GetCurrentLayoutPosition(0), Self().GetCurrentProperty< Vector3 >( Actor::Property::SIZE ), *mActiveLayout);
- mScrollDistance = CalculateScrollDistance(gesture.displacement, *mActiveLayout);
+ const Vector2& displacement = gesture.GetDisplacement();
+ mScrollDistance = CalculateScrollDistance(displacement, *mActiveLayout);
mScrollSpeed = Clamp((gesture.GetSpeed() * gesture.GetSpeed() * mActiveLayout->GetFlickSpeedFactor() * MILLISECONDS_PER_SECONDS), 0.0f, mActiveLayout->GetMaximumSwipeSpeed());
// Refresh order depends on the direction of the scroll; negative is towards the last item.
mScrollSpeed = Clamp((gesture.GetSpeed() * gesture.GetSpeed() * mActiveLayout->GetFlickSpeedFactor() * MILLISECONDS_PER_SECONDS), 0.0f, mActiveLayout->GetMaximumSwipeSpeed());
// Refresh order depends on the direction of the scroll; negative is towards the last item.
float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout);
float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout);
( firstItemScrollPosition <= mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize) &&
currentOvershoot > -1.0f ) )
{
( firstItemScrollPosition <= mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize) &&
currentOvershoot > -1.0f ) )
{
if(!nextFocusActor)
{
// likely the current item is not buffered, so not in our item pool, probably best to get first viewable item
if(!nextFocusActor)
{
// likely the current item is not buffered, so not in our item pool, probably best to get first viewable item
{
int nextItemID = GetItemId(commitedFocusableActor);
float layoutPosition = GetCurrentLayoutPosition(0);
{
int nextItemID = GetItemId(commitedFocusableActor);
float layoutPosition = GetCurrentLayoutPosition(0);
float scrollTo = mActiveLayout->GetClosestOnScreenLayoutPosition(nextItemID, layoutPosition, layoutSize);
ScrollTo(Vector2(0.0f, scrollTo), DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION);
}
}
float scrollTo = mActiveLayout->GetClosestOnScreenLayoutPosition(nextItemID, layoutPosition, layoutSize);
ScrollTo(Vector2(0.0f, scrollTo), DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION);
}
}
float firstItemScrollPosition = ClampFirstItemPosition(mActiveLayout->GetItemScrollToPosition(itemId), layoutSize, *mActiveLayout);
if(durationSeconds > 0.0f)
float firstItemScrollPosition = ClampFirstItemPosition(mActiveLayout->GetItemScrollToPosition(itemId), layoutSize, *mActiveLayout);
if(durationSeconds > 0.0f)
- return Vector2(0.0f, GetScrollPosition(GetCurrentLayoutPosition(0), Self().GetCurrentSize()));
+ return Vector2(0.0f, GetScrollPosition(GetCurrentLayoutPosition(0), Self().GetCurrentProperty< Vector3 >( Actor::Property::SIZE )));
{
Property::Index effectOvershootPropertyIndex = Property::INVALID_INDEX;
mOvershootOverlay = CreateBouncingEffectActor( effectOvershootPropertyIndex );
{
Property::Index effectOvershootPropertyIndex = Property::INVALID_INDEX;
mOvershootOverlay = CreateBouncingEffectActor( effectOvershootPropertyIndex );
- mOvershootOverlay.SetColor(mOvershootEffectColor);
- mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT);
- mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT);
- mOvershootOverlay.SetDrawMode( DrawMode::OVERLAY_2D );
+ mOvershootOverlay.SetProperty( Actor::Property::COLOR,mOvershootEffectColor);
+ mOvershootOverlay.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::TOP_LEFT );
+ mOvershootOverlay.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
+ mOvershootOverlay.SetProperty( Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D );
self.Add(mOvershootOverlay);
ApplyOvershootSizeConstraint( mOvershootOverlay, mOvershootSize.height );
self.Add(mOvershootOverlay);
ApplyOvershootSizeConstraint( mOvershootOverlay, mOvershootSize.height );
Actor self = Self();
float scrollDistance = CalculateScrollDistance(mTotalPanDisplacement, *mActiveLayout) * mActiveLayout->GetScrollSpeedFactor();
float positionDelta = GetCurrentLayoutPosition(0) + scrollDistance;
Actor self = Self();
float scrollDistance = CalculateScrollDistance(mTotalPanDisplacement, *mActiveLayout) * mActiveLayout->GetScrollSpeedFactor();
float positionDelta = GetCurrentLayoutPosition(0) + scrollDistance;
self.SetProperty(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX, Vector2(0.0f, -minLayoutPosition));
float clamppedPosition = std::min(0.0f, std::max(minLayoutPosition, positionDelta));
overshoot = positionDelta - clamppedPosition;
self.SetProperty(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX, Vector2(0.0f, -minLayoutPosition));
float clamppedPosition = std::min(0.0f, std::max(minLayoutPosition, positionDelta));
overshoot = positionDelta - clamppedPosition;
case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
{
itemViewImpl.SetMinimumSwipeDistance( value.Get<float>() );
break;
}
case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
{
itemViewImpl.SetMinimumSwipeDistance( value.Get<float>() );
break;
}
case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
{
itemViewImpl.SetWheelScrollDistanceStep( value.Get<float>() );
break;
}
case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
{
itemViewImpl.SetWheelScrollDistanceStep( value.Get<float>() );
break;
}
case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
{
itemViewImpl.SetAnchoring( value.Get<bool>() );
break;
}
case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
{
itemViewImpl.SetAnchoring( value.Get<bool>() );
break;
}
case Toolkit::ItemView::Property::REFRESH_INTERVAL:
{
itemViewImpl.SetRefreshInterval( value.Get<float>() );
break;
}
case Toolkit::ItemView::Property::REFRESH_INTERVAL:
{
itemViewImpl.SetRefreshInterval( value.Get<float>() );
break;
}
case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
{
value = itemViewImpl.GetMinimumSwipeDistance();
break;
}
case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
{
value = itemViewImpl.GetMinimumSwipeDistance();
break;
}
case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
{
value = itemViewImpl.GetWheelScrollDistanceStep();
break;
}
case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
{
value = itemViewImpl.GetWheelScrollDistanceStep();
break;
}