X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fscrollable%2Fitem-view%2Fitem-view-impl.cpp;h=e9b58c86275337a5e07a4701a8615ee4d81d9634;hp=23fcd36a6e0cf9c826a6f5ef696101a221739888;hb=34ff717e1cc4869695d01f8d2add4180f19811e8;hpb=1873773cb229ab98b29af3ec319dd18cde5f68dc diff --git a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp old mode 100755 new mode 100644 index 23fcd36..e9b58c8 --- a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,55 +19,53 @@ #include // EXTERNAL INCLUDES -#include // for strcmp -#include +#include +#include +#include #include - #include #include -#include -#include +#include #include -#include -#include #include -#include +#include +#include +#include // for strcmp // INTERNAL INCLUDES -#include -#include -#include -#include -#include -#include +#include +#include #include +#include #include -#include +#include +#include +#include using std::string; -using std::set; using namespace Dali; namespace // Unnamed namespace { - -const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f; -const float DEFAULT_MINIMUM_SWIPE_DISTANCE = 3.0f; +const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f; +const float DEFAULT_MINIMUM_SWIPE_DISTANCE = 3.0f; const float DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = 0.1f; const float DEFAULT_MINIMUM_SWIPE_DURATION = 0.45f; const float DEFAULT_MAXIMUM_SWIPE_DURATION = 2.6f; const float DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS = 20.0f; // 1 updates per 20 items -const int WHEEL_EVENT_FINISHED_TIME_OUT = 500; // 0.5 second +const int WHEEL_EVENT_FINISHED_TIME_OUT = 500; // 0.5 second -const float DEFAULT_ANCHORING_DURATION = 1.0f; // 1 second +const float DEFAULT_ANCHORING_DURATION = 1.0f; // 1 second const float MILLISECONDS_PER_SECONDS = 1000.0f; -const float OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD = 180.0f; +const float OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD = 180.0f; const Vector4 OVERSHOOT_OVERLAY_NINE_PATCH_BORDER(0.0f, 0.0f, 1.0f, 12.0f); -const float DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION = 0.2f; +const float DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION = 0.2f; + +const unsigned int OVERSHOOT_SIZE_CONSTRAINT_TAG(42); /** * Local helper to convert pan distance (in actor coordinates) to the layout-specific scrolling direction @@ -85,16 +83,16 @@ float CalculateScrollDistance(Vector2 panDistance, Toolkit::ItemLayout& layout) // Overshoot overlay constraints struct OvershootOverlaySizeConstraint { - OvershootOverlaySizeConstraint( float height ) - : mOvershootHeight( height ) + OvershootOverlaySizeConstraint(float height) + : mOvershootHeight(height) { } - void operator()( Vector3& current, const PropertyInputContainer& inputs ) + void operator()(Vector3& current, const PropertyInputContainer& inputs) { - const Vector2& parentScrollDirection = inputs[0]->GetVector2(); - const Toolkit::ControlOrientation::Type& layoutOrientation = static_cast(inputs[1]->GetInteger()); - const Vector3& parentSize = inputs[2]->GetVector3(); + const Vector2& parentScrollDirection = inputs[0]->GetVector2(); + const Toolkit::ControlOrientation::Type& layoutOrientation = static_cast(inputs[1]->GetInteger()); + const Vector3& parentSize = inputs[2]->GetVector3(); if(Toolkit::IsVertical(layoutOrientation)) { @@ -105,25 +103,24 @@ struct OvershootOverlaySizeConstraint current.width = fabsf(parentScrollDirection.x) > Math::MACHINE_EPSILON_1 ? parentSize.y : parentSize.x; } - current.height = ( current.width > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD ) ? mOvershootHeight : mOvershootHeight*0.5f; + current.height = (current.width > OVERSHOOT_BOUNCE_ACTOR_RESIZE_THRESHOLD) ? mOvershootHeight : mOvershootHeight * 0.5f; } float mOvershootHeight; }; -void OvershootOverlayRotationConstraint( Quaternion& current, const PropertyInputContainer& inputs ) +void OvershootOverlayRotationConstraint(Quaternion& current, const PropertyInputContainer& inputs) { - const Vector2& parentScrollDirection = inputs[0]->GetVector2(); - const Toolkit::ControlOrientation::Type& layoutOrientation = static_cast(inputs[1]->GetInteger()); - const float parentOvershoot = inputs[2]->GetFloat(); + const Vector2& parentScrollDirection = inputs[0]->GetVector2(); + const Toolkit::ControlOrientation::Type& layoutOrientation = static_cast(inputs[1]->GetInteger()); + const float parentOvershoot = inputs[2]->GetFloat(); float multiplier = 0; if(Toolkit::IsVertical(layoutOrientation)) { if(fabsf(parentScrollDirection.y) <= Math::MACHINE_EPSILON_1) { - if( (layoutOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0) - || (layoutOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0) ) + if((layoutOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0) || (layoutOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0)) { multiplier = 0.5f; } @@ -132,8 +129,7 @@ void OvershootOverlayRotationConstraint( Quaternion& current, const PropertyInpu multiplier = 1.5f; } } - else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0) - || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0) ) + else if((parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0) || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0)) { multiplier = 0.0f; } @@ -146,8 +142,7 @@ void OvershootOverlayRotationConstraint( Quaternion& current, const PropertyInpu { if(fabsf(parentScrollDirection.x) <= Math::MACHINE_EPSILON_1) { - if( (layoutOrientation == Toolkit::ControlOrientation::Left && parentOvershoot > Math::MACHINE_EPSILON_0) - ||(layoutOrientation == Toolkit::ControlOrientation::Right && parentOvershoot < Math::MACHINE_EPSILON_0) ) + if((layoutOrientation == Toolkit::ControlOrientation::Left && parentOvershoot > Math::MACHINE_EPSILON_0) || (layoutOrientation == Toolkit::ControlOrientation::Right && parentOvershoot < Math::MACHINE_EPSILON_0)) { multiplier = 1.0f; } @@ -156,8 +151,7 @@ void OvershootOverlayRotationConstraint( Quaternion& current, const PropertyInpu multiplier = 0.0f; } } - else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0) - || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0) ) + else if((parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0) || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0)) { multiplier = 1.5f; } @@ -167,15 +161,15 @@ void OvershootOverlayRotationConstraint( Quaternion& current, const PropertyInpu } } - current = Quaternion( Radian( multiplier * Math::PI ), Vector3::ZAXIS ); + current = Quaternion(Radian(multiplier * Math::PI), Vector3::ZAXIS); } -void OvershootOverlayPositionConstraint( Vector3& current, const PropertyInputContainer& inputs ) +void OvershootOverlayPositionConstraint(Vector3& current, const PropertyInputContainer& inputs) { - const Vector3& parentSize = inputs[0]->GetVector3(); - const Vector2& parentScrollDirection = inputs[1]->GetVector2(); - const Toolkit::ControlOrientation::Type& layoutOrientation = static_cast(inputs[2]->GetInteger()); - const float parentOvershoot = inputs[3]->GetFloat(); + const Vector3& parentSize = inputs[0]->GetVector3(); + const Vector2& parentScrollDirection = inputs[1]->GetVector2(); + const Toolkit::ControlOrientation::Type& layoutOrientation = static_cast(inputs[2]->GetInteger()); + const float parentOvershoot = inputs[3]->GetFloat(); Vector3 relativeOffset; @@ -183,18 +177,16 @@ void OvershootOverlayPositionConstraint( Vector3& current, const PropertyInputCo { if(fabsf(parentScrollDirection.y) <= Math::MACHINE_EPSILON_1) { - if( (layoutOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0) - || (layoutOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0) ) + if((layoutOrientation == Toolkit::ControlOrientation::Up && parentOvershoot < Math::MACHINE_EPSILON_0) || (layoutOrientation == Toolkit::ControlOrientation::Down && parentOvershoot > Math::MACHINE_EPSILON_0)) { relativeOffset = Vector3(1.0f, 0.0f, 0.0f); } else { - relativeOffset =Vector3(0.0f, 1.0f, 0.0f); + relativeOffset = Vector3(0.0f, 1.0f, 0.0f); } } - else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0) - || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0) ) + else if((parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.y > Math::MACHINE_EPSILON_0) || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.y < Math::MACHINE_EPSILON_0)) { relativeOffset = Vector3(0.0f, 0.0f, 0.0f); } @@ -207,8 +199,7 @@ void OvershootOverlayPositionConstraint( Vector3& current, const PropertyInputCo { if(fabsf(parentScrollDirection.x) <= Math::MACHINE_EPSILON_1) { - if( (layoutOrientation == Toolkit::ControlOrientation::Left && parentOvershoot < Math::MACHINE_EPSILON_0) - || (layoutOrientation == Toolkit::ControlOrientation::Right && parentOvershoot > Math::MACHINE_EPSILON_0) ) + if((layoutOrientation == Toolkit::ControlOrientation::Left && parentOvershoot < Math::MACHINE_EPSILON_0) || (layoutOrientation == Toolkit::ControlOrientation::Right && parentOvershoot > Math::MACHINE_EPSILON_0)) { relativeOffset = Vector3(0.0f, 0.0f, 0.0f); } @@ -217,8 +208,7 @@ void OvershootOverlayPositionConstraint( Vector3& current, const PropertyInputCo relativeOffset = Vector3(1.0f, 1.0f, 0.0f); } } - else if( (parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0) - || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0) ) + else if((parentOvershoot > Math::MACHINE_EPSILON_0 && parentScrollDirection.x > Math::MACHINE_EPSILON_0) || (parentOvershoot < Math::MACHINE_EPSILON_0 && parentScrollDirection.x < Math::MACHINE_EPSILON_0)) { relativeOffset = Vector3(0.0f, 1.0f, 0.0f); } @@ -231,7 +221,7 @@ void OvershootOverlayPositionConstraint( Vector3& current, const PropertyInputCo current = relativeOffset * parentSize; } -void OvershootOverlayVisibilityConstraint( bool& current, const PropertyInputContainer& inputs ) +void OvershootOverlayVisibilityConstraint(bool& current, const PropertyInputContainer& inputs) { current = inputs[0]->GetBoolean(); } @@ -240,55 +230,76 @@ void OvershootOverlayVisibilityConstraint( bool& current, const PropertyInputCon namespace Dali { - namespace Toolkit { - namespace Internal { - namespace // unnamed namespace { - //Type registration +// clang-format off +DALI_TYPE_REGISTRATION_BEGIN(Toolkit::ItemView, Toolkit::Scrollable, nullptr) -DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ItemView, Toolkit::Scrollable, NULL) +DALI_PROPERTY_REGISTRATION(Toolkit, ItemView, "minimumSwipeSpeed", FLOAT, MINIMUM_SWIPE_SPEED ) +DALI_PROPERTY_REGISTRATION(Toolkit, ItemView, "minimumSwipeDistance", FLOAT, MINIMUM_SWIPE_DISTANCE ) +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, "layout", ARRAY, LAYOUT ) -DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeSpeed", FLOAT, MINIMUM_SWIPE_SPEED ) -DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeDistance", FLOAT, MINIMUM_SWIPE_DISTANCE ) -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_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, ItemView, "layoutPosition", FLOAT, LAYOUT_POSITION ) +DALI_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, ItemView, "scrollSpeed", FLOAT, SCROLL_SPEED ) +DALI_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, ItemView, "overshoot", FLOAT, OVERSHOOT ) +DALI_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, ItemView, "scrollDirection", VECTOR2, SCROLL_DIRECTION ) +DALI_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, ItemView, "layoutOrientation", INTEGER, LAYOUT_ORIENTATION ) +DALI_ANIMATABLE_PROPERTY_REGISTRATION(Toolkit, ItemView, "scrollContentSize", FLOAT, SCROLL_CONTENT_SIZE) -DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition", FLOAT, LAYOUT_POSITION) -DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollSpeed", FLOAT, SCROLL_SPEED) -DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "overshoot", FLOAT, OVERSHOOT) -DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollDirection", VECTOR2, SCROLL_DIRECTION) -DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutOrientation", INTEGER, LAYOUT_ORIENTATION) -DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollContentSize", FLOAT, SCROLL_CONTENT_SIZE) +DALI_SIGNAL_REGISTRATION(Toolkit, ItemView, "layoutActivated", LAYOUT_ACTIVATED_SIGNAL) -DALI_SIGNAL_REGISTRATION( Toolkit, ItemView, "layoutActivated", LAYOUT_ACTIVATED_SIGNAL ) +DALI_ACTION_REGISTRATION(Toolkit, ItemView, "stopScrolling", ACTION_STOP_SCROLLING) -DALI_ACTION_REGISTRATION( Toolkit, ItemView, "stopScrolling", ACTION_STOP_SCROLLING ) - -DALI_ACTION_REGISTRATION( Toolkit, ItemView, "enableRefresh", ACTION_ENABLE_REFRESH ) -DALI_ACTION_REGISTRATION( Toolkit, ItemView, "disableRefresh", ACTION_DISABLE_REFRESH ) +DALI_ACTION_REGISTRATION(Toolkit, ItemView, "enableRefresh", ACTION_ENABLE_REFRESH ) +DALI_ACTION_REGISTRATION(Toolkit, ItemView, "disableRefresh", ACTION_DISABLE_REFRESH) DALI_TYPE_REGISTRATION_END() +// clang-format on -bool FindById( const ItemContainer& items, ItemId id ) +const ItemIter FindItemById(ItemContainer& items, ItemId id) { - for( ConstItemIter iter = items.begin(); items.end() != iter; ++iter ) + for(ItemIter iter = items.begin(); items.end() != iter; ++iter) { - if( iter->first == id ) + if(iter->first == id) { - return true; + return iter; } } - return false; + return items.end(); +} + +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 + * @param[in] The required height + */ +void ApplyOvershootSizeConstraint(Actor overshootOverlay, float height) +{ + Constraint constraint = Constraint::New(overshootOverlay, Actor::Property::SIZE, OvershootOverlaySizeConstraint(height)); + constraint.AddSource(ParentSource(Dali::Toolkit::ItemView::Property::SCROLL_DIRECTION)); + constraint.AddSource(ParentSource(Dali::Toolkit::ItemView::Property::LAYOUT_ORIENTATION)); + constraint.AddSource(ParentSource(Dali::Actor::Property::SIZE)); + constraint.SetTag(OVERSHOOT_SIZE_CONSTRAINT_TAG); + constraint.Apply(); } } // unnamed namespace @@ -309,7 +320,7 @@ Dali::Toolkit::ItemView ItemView::New(ItemFactory& factory) } ItemView::ItemView(ItemFactory& factory) -: Scrollable( ControlBehaviour( DISABLE_SIZE_NEGOTIATION | DISABLE_STYLE_CHANGE_SIGNALS | REQUIRES_WHEEL_EVENTS | REQUIRES_KEYBOARD_NAVIGATION_SUPPORT ) ), +: Scrollable(ControlBehaviour(DISABLE_SIZE_NEGOTIATION | DISABLE_STYLE_CHANGE_SIGNALS | REQUIRES_KEYBOARD_NAVIGATION_SUPPORT)), mItemFactory(factory), mItemsParentOrigin(ParentOrigin::CENTER), mItemsAnchorPoint(AnchorPoint::CENTER), @@ -323,11 +334,11 @@ ItemView::ItemView(ItemFactory& factory) mScrollDistance(0.0f), mScrollSpeed(0.0f), mScrollOvershoot(0.0f), - mGestureState(Gesture::Clear), + mGestureState(GestureState::CLEAR), mAnimatingOvershootOn(false), mAnimateOvershootOff(false), mAnchoringEnabled(false), - mRefreshOrderHint(true/*Refresh item 0 first*/), + mRefreshOrderHint(true /*Refresh item 0 first*/), mIsFlicking(false), mAddingItems(false), mRefreshEnabled(true), @@ -338,18 +349,27 @@ ItemView::ItemView(ItemFactory& factory) void ItemView::OnInitialize() { + Scrollable::OnInitialize(); + Actor self = Self(); - Vector2 stageSize = Stage::GetCurrent().GetSize(); + 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 ); + 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(new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_PANE)); + }); } ItemView::~ItemView() @@ -370,7 +390,7 @@ void ItemView::RemoveLayout(unsigned int layoutIndex) { DALI_ASSERT_ALWAYS(layoutIndex < mLayouts.size()); - if (mActiveLayout == mLayouts[layoutIndex].Get()) + if(mActiveLayout == mLayouts[layoutIndex].Get()) { mActiveLayout = NULL; } @@ -390,7 +410,7 @@ ItemLayoutPtr ItemView::GetActiveLayout() const float ItemView::GetCurrentLayoutPosition(unsigned int itemId) const { - return Self().GetProperty( Toolkit::ItemView::Property::LAYOUT_POSITION ) + static_cast( itemId ); + return Self().GetCurrentProperty(Toolkit::ItemView::Property::LAYOUT_POSITION) + static_cast(itemId); } void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSize, float durationSeconds) @@ -402,7 +422,7 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz Actor self = Self(); // The ItemView size should match the active layout size - self.SetSize(targetSize); + self.SetProperty(Actor::Property::SIZE, targetSize); mActiveLayoutTargetSize = targetSize; // Switch to the new layout @@ -410,49 +430,49 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz // Move the items to the new layout positions... - for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) + for(ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { unsigned int itemId = iter->first; - Actor actor = iter->second; + Actor actor = iter->second; // Remove constraints from previous layout actor.RemoveConstraints(); - mActiveLayout->ApplyConstraints(actor, itemId, targetSize, Self() ); + mActiveLayout->ApplyConstraints(actor, itemId, targetSize, Self()); Vector3 size; - mActiveLayout->GetItemSize( itemId, targetSize, size ); - actor.SetSize( size.GetVectorXY() ); + mActiveLayout->GetItemSize(itemId, targetSize, size); + actor.SetProperty(Actor::Property::SIZE, size.GetVectorXY()); } // Refresh the new layout - ItemRange range = GetItemRange(*mActiveLayout, targetSize, GetCurrentLayoutPosition(0), false/* don't reserve extra*/); - AddActorsWithinRange( range, targetSize ); + ItemRange range = GetItemRange(*mActiveLayout, targetSize, GetCurrentLayoutPosition(0), false /* don't reserve extra*/); + AddActorsWithinRange(range, targetSize); // Scroll to an appropriate layout position - bool scrollAnimationNeeded(false); + bool scrollAnimationNeeded(false); float firstItemScrollPosition(0.0f); float current = GetCurrentLayoutPosition(0); float minimum = ClampFirstItemPosition(current, targetSize, *mActiveLayout); - if (current < minimum) + if(current < minimum) { - scrollAnimationNeeded = true; + scrollAnimationNeeded = true; firstItemScrollPosition = minimum; } - else if (mAnchoringEnabled) + else if(mAnchoringEnabled) { - scrollAnimationNeeded = true; + scrollAnimationNeeded = true; firstItemScrollPosition = mActiveLayout->GetClosestAnchorPosition(current); } - if (scrollAnimationNeeded) + if(scrollAnimationNeeded) { RemoveAnimation(mScrollAnimation); mScrollAnimation = Animation::New(durationSeconds); - mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, AlphaFunction::EASE_OUT ); + mScrollAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, AlphaFunction::EASE_OUT); mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnLayoutActivationScrollFinished); mScrollAnimation.Play(); } @@ -475,9 +495,9 @@ void ItemView::ActivateLayout(unsigned int layoutIndex, const Vector3& targetSiz void ItemView::DeactivateCurrentLayout() { - if (mActiveLayout) + if(mActiveLayout) { - for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) + for(ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { Actor actor = iter->second; actor.RemoveConstraints(); @@ -489,7 +509,7 @@ void ItemView::DeactivateCurrentLayout() void ItemView::OnRefreshNotification(PropertyNotification& source) { - if( mRefreshNotificationEnabled ) + if(mRefreshNotificationEnabled) { // Cancel scroll animation to prevent any fighting of setting the scroll position property by scroll bar during fast scroll. if(!mRefreshEnabled && mScrollAnimation) @@ -504,9 +524,9 @@ void ItemView::OnRefreshNotification(PropertyNotification& source) void ItemView::Refresh() { - for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter ) + for(ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { - ReleaseActor( iter->first, iter->second ); + ReleaseActor(iter->first, iter->second); } mItemPool.clear(); @@ -515,13 +535,13 @@ void ItemView::Refresh() void ItemView::DoRefresh(float currentLayoutPosition, bool cacheExtra) { - if (mActiveLayout) + if(mActiveLayout) { - ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, currentLayoutPosition, cacheExtra/*reserve extra*/); - RemoveActorsOutsideRange( range ); - AddActorsWithinRange( range, Self().GetCurrentSize() ); + ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, currentLayoutPosition, cacheExtra /*reserve extra*/); + RemoveActorsOutsideRange(range); + AddActorsWithinRange(range, Self().GetCurrentProperty(Actor::Property::SIZE)); - mScrollUpdatedSignal.Emit( Vector2(0.0f, currentLayoutPosition) ); + mScrollUpdatedSignal.Emit(Vector2(0.0f, currentLayoutPosition)); } } @@ -577,7 +597,7 @@ float ItemView::GetAnchoringDuration() const void ItemView::SetRefreshInterval(float intervalLayoutPositions) { - if( !Equals(mRefreshIntervalLayoutPositions, intervalLayoutPositions) ) + if(!Equals(mRefreshIntervalLayoutPositions, intervalLayoutPositions)) { mRefreshIntervalLayoutPositions = intervalLayoutPositions; @@ -586,8 +606,8 @@ void ItemView::SetRefreshInterval(float intervalLayoutPositions) { self.RemovePropertyNotification(mRefreshNotification); } - mRefreshNotification = self.AddPropertyNotification( Toolkit::ItemView::Property::LAYOUT_POSITION, StepCondition(mRefreshIntervalLayoutPositions, 0.0f) ); - mRefreshNotification.NotifySignal().Connect( this, &ItemView::OnRefreshNotification ); + mRefreshNotification = self.AddPropertyNotification(Toolkit::ItemView::Property::LAYOUT_POSITION, StepCondition(mRefreshIntervalLayoutPositions, 0.0f)); + mRefreshNotification.NotifySignal().Connect(this, &ItemView::OnRefreshNotification); } } @@ -605,22 +625,25 @@ Actor ItemView::GetItem(unsigned int itemId) const { Actor actor; - ConstItemPoolIter iter = mItemPool.find( itemId ); - if( iter != mItemPool.end() ) + for(ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { - actor = iter->second; + if(iter->first == itemId) + { + actor = iter->second; + break; + } } return actor; } -unsigned int ItemView::GetItemId( Actor actor ) const +unsigned int ItemView::GetItemId(Actor actor) const { - unsigned int itemId( 0 ); + unsigned int itemId(0); - for ( ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter ) + for(ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { - if( iter->second == actor ) + if(iter->second == actor) { itemId = iter->first; break; @@ -630,21 +653,21 @@ unsigned int ItemView::GetItemId( Actor actor ) const return itemId; } -void ItemView::InsertItem( Item newItem, float durationSeconds ) +void ItemView::InsertItem(Item newItem, float durationSeconds) { - mAddingItems = true; - Vector3 layoutSize = Self().GetCurrentSize(); + mAddingItems = true; + Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); - Actor displacedActor; - ItemPoolIter afterDisplacedIter = mItemPool.end(); + Actor displacedActor; + ItemIter afterDisplacedIter = mItemPool.end(); - ItemPoolIter foundIter = mItemPool.find( newItem.first ); - if( mItemPool.end() != foundIter ) + ItemIter foundIter = FindItemById(mItemPool, newItem.first); + if(mItemPool.end() != foundIter) { - SetupActor( newItem, layoutSize ); - Self().Add( newItem.second ); + SetupActor(newItem, layoutSize); + Self().Add(newItem.second); - displacedActor = foundIter->second; + displacedActor = foundIter->second; foundIter->second = newItem.second; afterDisplacedIter = ++foundIter; @@ -652,113 +675,110 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) else { // Inserting before the existing item range? - ItemPoolIter iter = mItemPool.begin(); - if( iter != mItemPool.end() && - iter->first > newItem.first ) + ItemIter iter = mItemPool.begin(); + if(iter != mItemPool.end() && + iter->first > newItem.first) { displacedActor = iter->second; - mItemPool.erase( iter++ ); // iter is still valid after the erase + iter = mItemPool.erase(iter); // iter is still valid after the erase afterDisplacedIter = iter; } } - if( displacedActor ) + if(displacedActor) { // Move the existing actors to make room - for( ItemPoolIter iter = afterDisplacedIter; mItemPool.end() != iter; ++iter ) + for(ItemIter iter = afterDisplacedIter; mItemPool.end() != iter; ++iter) { - Actor temp = iter->second; - iter->second = displacedActor; + Actor temp = iter->second; + iter->second = displacedActor; displacedActor = temp; iter->second.RemoveConstraints(); - mActiveLayout->ApplyConstraints( iter->second, iter->first, layoutSize, Self() ); + mActiveLayout->ApplyConstraints(iter->second, iter->first, layoutSize, Self()); } // Create last item - ItemPool::reverse_iterator lastIter = mItemPool.rbegin(); - if ( lastIter != mItemPool.rend() ) + ItemContainer::reverse_iterator lastIter = mItemPool.rbegin(); + if(lastIter != mItemPool.rend()) { ItemId lastId = lastIter->first; - Item lastItem( lastId + 1, displacedActor ); - mItemPool.insert( lastItem ); + Item lastItem(lastId + 1, displacedActor); + InsertToItemContainer(mItemPool, lastItem); lastItem.second.RemoveConstraints(); - mActiveLayout->ApplyConstraints( lastItem.second, lastItem.first, layoutSize, Self() ); + mActiveLayout->ApplyConstraints(lastItem.second, lastItem.first, layoutSize, Self()); } } - CalculateDomainSize( layoutSize ); + CalculateDomainSize(layoutSize); mAddingItems = false; } -void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds ) +void ItemView::InsertItems(const ItemContainer& newItems, float durationSeconds) { - mAddingItems = true; - Vector3 layoutSize = Self().GetCurrentSize(); + mAddingItems = true; + Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); // Insert from lowest id to highest - std::set sortedItems; - for( ConstItemIter iter = newItems.begin(); newItems.end() != iter; ++iter ) - { - sortedItems.insert( *iter ); - } + ItemContainer sortedItems(newItems); + std::sort(sortedItems.begin(), sortedItems.end()); - for( std::set::iterator iter = sortedItems.begin(); sortedItems.end() != iter; ++iter ) + for(ItemIter iter = sortedItems.begin(); sortedItems.end() != iter; ++iter) { - Self().Add( iter->second ); + Self().Add(iter->second); - ItemPoolIter foundIter = mItemPool.find( iter->first ); - if( mItemPool.end() != foundIter ) + ItemIter foundIter = FindItemById(mItemPool, iter->first); + if(mItemPool.end() != foundIter) { - Actor moveMe = foundIter->second; + Actor moveMe = foundIter->second; foundIter->second = iter->second; // Move the existing actors to make room - for( ItemPoolIter iter = ++foundIter; mItemPool.end() != iter; ++iter ) + for(ItemIter iter = ++foundIter; mItemPool.end() != iter; ++iter) { - Actor temp = iter->second; + Actor temp = iter->second; iter->second = moveMe; - moveMe = temp; + moveMe = temp; } // Create last item ItemId lastId = mItemPool.rbegin()->first; - Item lastItem( lastId + 1, moveMe ); - mItemPool.insert( lastItem ); + Item lastItem(lastId + 1, moveMe); + InsertToItemContainer(mItemPool, lastItem); } else { - mItemPool.insert( *iter ); + InsertToItemContainer(mItemPool, *iter); } } // Relayout everything - for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) + for(ItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { // If newly inserted - if( FindById( newItems, iter->first ) ) + if(std::binary_search(sortedItems.begin(), sortedItems.end(), *iter)) { - SetupActor( *iter, layoutSize ); + SetupActor(*iter, layoutSize); } else { iter->second.RemoveConstraints(); - mActiveLayout->ApplyConstraints( iter->second, iter->first, layoutSize, Self() ); + mActiveLayout->ApplyConstraints(iter->second, iter->first, layoutSize, Self()); } } - CalculateDomainSize( layoutSize ); + CalculateDomainSize(layoutSize); mAddingItems = false; } -void ItemView::RemoveItem( unsigned int itemId, float durationSeconds ) +void ItemView::RemoveItem(unsigned int itemId, float durationSeconds) { - bool actorsReordered = RemoveActor( itemId ); - if( actorsReordered ) + bool actorsReordered = RemoveActor(itemId); + if(actorsReordered) { ReapplyAllConstraints(); @@ -766,26 +786,23 @@ void ItemView::RemoveItem( unsigned int itemId, float durationSeconds ) } } -void ItemView::RemoveItems( const ItemIdContainer& itemIds, float durationSeconds ) +void ItemView::RemoveItems(const ItemIdContainer& itemIds, float durationSeconds) { - bool actorsReordered( false ); + bool actorsReordered(false); // Remove from highest id to lowest - set sortedItems; - for( ConstItemIdIter iter = itemIds.begin(); itemIds.end() != iter; ++iter ) - { - sortedItems.insert( *iter ); - } + ItemIdContainer sortedItems(itemIds); + std::sort(sortedItems.begin(), sortedItems.end()); - for( set::reverse_iterator iter = sortedItems.rbegin(); sortedItems.rend() != iter; ++iter ) + for(ItemIdContainer::reverse_iterator iter = sortedItems.rbegin(); sortedItems.rend() != iter; ++iter) { - if( RemoveActor( *iter ) ) + if(RemoveActor(*iter)) { actorsReordered = true; } } - if( actorsReordered ) + if(actorsReordered) { ReapplyAllConstraints(); @@ -795,28 +812,28 @@ void ItemView::RemoveItems( const ItemIdContainer& itemIds, float durationSecond bool ItemView::RemoveActor(unsigned int itemId) { - bool reordered( false ); + bool reordered(false); - ItemPoolIter removeIter = mItemPool.find( itemId ); - if( removeIter != mItemPool.end() ) + ItemIter removeIter = FindItemById(mItemPool, itemId); + if(removeIter != mItemPool.end()) { ReleaseActor(itemId, removeIter->second); } else { // Removing before the existing item range? - ItemPoolIter iter = mItemPool.begin(); - if( iter != mItemPool.end() && - iter->first > itemId ) + ItemIter iter = mItemPool.begin(); + if(iter != mItemPool.end() && + iter->first > itemId) { // In order to decrement the first visible item ID - mItemPool.insert( Item(iter->first - 1, Actor()) ); + InsertToItemContainer(mItemPool, Item(iter->first - 1, Actor())); removeIter = mItemPool.begin(); } } - if( removeIter != mItemPool.end() ) + if(removeIter != mItemPool.end()) { reordered = true; @@ -826,15 +843,15 @@ bool ItemView::RemoveActor(unsigned int itemId) // ID 2 - ActorB ID 2 - ActorC (previously ID 3) // ID 3 - ActorC ID 3 - ActorB (previously ID 4) // ID 4 - ActorD - for (ItemPoolIter iter = removeIter; iter != mItemPool.end(); ++iter) + for(ItemIter iter = removeIter; iter != mItemPool.end(); ++iter) { - if( iter->first < mItemPool.rbegin()->first ) + if(iter->first < mItemPool.rbegin()->first) { - iter->second = mItemPool[ iter->first + 1 ]; + iter->second = (iter + 1)->second; } else { - mItemPool.erase( iter ); + mItemPool.erase(iter); break; } } @@ -843,50 +860,50 @@ bool ItemView::RemoveActor(unsigned int itemId) return reordered; } -void ItemView::ReplaceItem( Item replacementItem, float durationSeconds ) +void ItemView::ReplaceItem(Item replacementItem, float durationSeconds) { - mAddingItems = true; - Vector3 layoutSize = Self().GetCurrentSize(); + mAddingItems = true; + Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); - SetupActor( replacementItem, layoutSize ); - Self().Add( replacementItem.second ); + SetupActor(replacementItem, layoutSize); + Self().Add(replacementItem.second); - const ItemPoolIter iter = mItemPool.find( replacementItem.first ); - if( mItemPool.end() != iter ) + const ItemIter iter = FindItemById(mItemPool, replacementItem.first); + if(mItemPool.end() != iter) { ReleaseActor(iter->first, iter->second); iter->second = replacementItem.second; } else { - mItemPool.insert( replacementItem ); + InsertToItemContainer(mItemPool, replacementItem); } - CalculateDomainSize( layoutSize ); + CalculateDomainSize(layoutSize); mAddingItems = false; } -void ItemView::ReplaceItems( const ItemContainer& replacementItems, float durationSeconds ) +void ItemView::ReplaceItems(const ItemContainer& replacementItems, float durationSeconds) { - for( ConstItemIter iter = replacementItems.begin(); replacementItems.end() != iter; ++iter ) + for(ConstItemIter iter = replacementItems.begin(); replacementItems.end() != iter; ++iter) { - ReplaceItem( *iter, durationSeconds ); + ReplaceItem(*iter, durationSeconds); } } -void ItemView::RemoveActorsOutsideRange( ItemRange range ) +void ItemView::RemoveActorsOutsideRange(ItemRange range) { // Remove unwanted actors from the ItemView & ItemPool - for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ) + for(ItemIter iter = mItemPool.begin(); iter != mItemPool.end();) { unsigned int current = iter->first; - if( ! range.Within( current ) ) + if(!range.Within(current)) { ReleaseActor(iter->first, iter->second); - mItemPool.erase( iter++ ); // erase invalidates the return value of post-increment; iter remains valid + iter = mItemPool.erase(iter); // iter is still valid after the erase } else { @@ -895,71 +912,71 @@ void ItemView::RemoveActorsOutsideRange( ItemRange range ) } } -void ItemView::AddActorsWithinRange( ItemRange range, const Vector3& layoutSize ) +void ItemView::AddActorsWithinRange(ItemRange range, const Vector3& layoutSize) { range.end = std::min(mItemFactory.GetNumberOfItems(), range.end); // The order of addition depends on the scroll direction. - if (mRefreshOrderHint) + if(mRefreshOrderHint) { - for (unsigned int itemId = range.begin; itemId < range.end; ++itemId) + for(unsigned int itemId = range.begin; itemId < range.end; ++itemId) { - AddNewActor( itemId, layoutSize ); + AddNewActor(itemId, layoutSize); } } else { - for (unsigned int itemId = range.end; itemId > range.begin; --itemId) + for(unsigned int itemId = range.end; itemId > range.begin; --itemId) { - AddNewActor( itemId-1, layoutSize ); + AddNewActor(itemId - 1, layoutSize); } } // Total number of items may change dynamically. // Always recalculate the domain size to reflect that. - CalculateDomainSize(Self().GetCurrentSize()); + CalculateDomainSize(Self().GetCurrentProperty(Actor::Property::SIZE)); } -void ItemView::AddNewActor( unsigned int itemId, const Vector3& layoutSize ) +void ItemView::AddNewActor(unsigned int itemId, const Vector3& layoutSize) { mAddingItems = true; - if( mItemPool.end() == mItemPool.find( itemId ) ) + if(mItemPool.end() == FindItemById(mItemPool, itemId)) { - Actor actor = mItemFactory.NewItem( itemId ); + Actor actor = mItemFactory.NewItem(itemId); - if( actor ) + if(actor) { - Item newItem( itemId, actor ); + Item newItem(itemId, actor); - mItemPool.insert( newItem ); + InsertToItemContainer(mItemPool, newItem); - SetupActor( newItem, layoutSize ); - Self().Add( actor ); + SetupActor(newItem, layoutSize); + Self().Add(actor); } } mAddingItems = false; } -void ItemView::SetupActor( Item item, const Vector3& layoutSize ) +void ItemView::SetupActor(Item item, const Vector3& layoutSize) { - item.second.SetParentOrigin( mItemsParentOrigin ); - item.second.SetAnchorPoint( mItemsAnchorPoint ); + item.second.SetProperty(Actor::Property::PARENT_ORIGIN, mItemsParentOrigin); + item.second.SetProperty(Actor::Property::ANCHOR_POINT, mItemsAnchorPoint); - if( mActiveLayout ) + if(mActiveLayout) { Vector3 size; - mActiveLayout->GetItemSize( item.first, mActiveLayoutTargetSize, size ); - item.second.SetSize( size.GetVectorXY() ); + mActiveLayout->GetItemSize(item.first, mActiveLayoutTargetSize, size); + item.second.SetProperty(Actor::Property::SIZE, size.GetVectorXY()); - mActiveLayout->ApplyConstraints( item.second, item.first, layoutSize, Self() ); + mActiveLayout->ApplyConstraints(item.second, item.first, layoutSize, Self()); } } -void ItemView::ReleaseActor( ItemId item, Actor actor ) +void ItemView::ReleaseActor(ItemId item, Actor actor) { - Self().Remove( actor ); + Self().Remove(actor); mItemFactory.ItemReleased(item, actor); } @@ -969,13 +986,13 @@ ItemRange ItemView::GetItemRange(ItemLayout& layout, const Vector3& layoutSize, ItemRange available(0u, itemCount); - ItemRange range = layout.GetItemsWithinArea( layoutPosition, layoutSize ); + ItemRange range = layout.GetItemsWithinArea(layoutPosition, layoutSize); - if (reserveExtra) + if(reserveExtra) { // Add the reserve items for scrolling unsigned int extra = layout.GetReserveItemCount(layoutSize); - range.begin = (range.begin >= extra) ? (range.begin - extra) : 0u; + range.begin = (range.begin >= extra) ? (range.begin - extra) : 0u; range.end += extra; } @@ -997,25 +1014,27 @@ void ItemView::OnChildAdd(Actor& child) Toolkit::ItemView::Property::SCROLL_CONTENT_SIZE); } } + + Scrollable::OnChildAdd(child); } -bool ItemView::OnWheelEvent(const WheelEvent& event) +bool ItemView::OnWheelEvent(Actor actor, const WheelEvent& event) { // Respond the wheel event to scroll - if (mActiveLayout) + if(mActiveLayout) { - Actor self = Self(); - const Vector3 layoutSize = Self().GetCurrentSize(); - float layoutPositionDelta = GetCurrentLayoutPosition(0) - (event.z * mWheelScrollDistanceStep * mActiveLayout->GetScrollSpeedFactor()); - float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout); + Actor self = Self(); + const Vector3 layoutSize = Self().GetCurrentProperty(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 ); + self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition); mScrollStartedSignal.Emit(GetCurrentScrollPosition()); mRefreshEnabled = true; } - if (mWheelEventFinishedTimer.IsRunning()) + if(mWheelEventFinishedTimer.IsRunning()) { mWheelEventFinishedTimer.Stop(); } @@ -1027,13 +1046,13 @@ bool ItemView::OnWheelEvent(const WheelEvent& event) bool ItemView::OnWheelEventFinished() { - if (mActiveLayout) + if(mActiveLayout) { RemoveAnimation(mScrollAnimation); // No more wheel events coming. Do the anchoring if enabled. mScrollAnimation = DoAnchoring(); - if (mScrollAnimation) + if(mScrollAnimation) { mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished); mScrollAnimation.Play(); @@ -1052,12 +1071,12 @@ bool ItemView::OnWheelEventFinished() void ItemView::ReapplyAllConstraints() { - Vector3 layoutSize = Self().GetCurrentSize(); + Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); - for (ConstItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) + for(ConstItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { - unsigned int id = iter->first; - Actor actor = iter->second; + unsigned int id = iter->first; + Actor actor = iter->second; actor.RemoveConstraints(); mActiveLayout->ApplyConstraints(actor, id, layoutSize, Self()); @@ -1066,24 +1085,24 @@ void ItemView::ReapplyAllConstraints() void ItemView::OnItemsRemoved() { - CalculateDomainSize(Self().GetCurrentSize()); + CalculateDomainSize(Self().GetCurrentProperty(Actor::Property::SIZE)); // Adjust scroll-position after an item is removed - if( mActiveLayout ) + if(mActiveLayout) { - float firstItemScrollPosition = ClampFirstItemPosition(GetCurrentLayoutPosition(0), Self().GetCurrentSize(), *mActiveLayout); - Self().SetProperty( Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition ); + float firstItemScrollPosition = ClampFirstItemPosition(GetCurrentLayoutPosition(0), Self().GetCurrentProperty(Actor::Property::SIZE), *mActiveLayout); + Self().SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition); } } -float ItemView::ClampFirstItemPosition( float targetPosition, const Vector3& targetSize, ItemLayout& layout, bool updateOvershoot ) +float ItemView::ClampFirstItemPosition(float targetPosition, const Vector3& targetSize, ItemLayout& layout, bool updateOvershoot) { - Actor self = Self(); + Actor self = Self(); float minLayoutPosition = layout.GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), targetSize); - float clamppedPosition = std::min(0.0f, std::max(minLayoutPosition, targetPosition)); + float clamppedPosition = std::min(0.0f, std::max(minLayoutPosition, targetPosition)); self.SetProperty(Toolkit::Scrollable::Property::SCROLL_POSITION_MAX, Vector2(0.0f, -minLayoutPosition)); - if( updateOvershoot ) + if(updateOvershoot) { mScrollOvershoot = targetPosition - clamppedPosition; } @@ -1091,21 +1110,21 @@ float ItemView::ClampFirstItemPosition( float targetPosition, const Vector3& tar return clamppedPosition; } -bool ItemView::OnTouch( Actor actor, const TouchData& touch ) +bool ItemView::OnTouch(Actor actor, const TouchEvent& touch) { // Ignore events with multiple-touch points - if (touch.GetPointCount() != 1) + if(touch.GetPointCount() != 1) { return false; } - if ( touch.GetState( 0 ) == PointState::DOWN ) + if(touch.GetState(0) == PointState::DOWN) { // Cancel ongoing scrolling etc. - mGestureState = Gesture::Clear; + mGestureState = GestureState::CLEAR; mScrollDistance = 0.0f; - mScrollSpeed = 0.0f; + mScrollSpeed = 0.0f; Self().SetProperty(Toolkit::ItemView::Property::SCROLL_SPEED, mScrollSpeed); mScrollOvershoot = 0.0f; @@ -1119,72 +1138,73 @@ bool ItemView::OnTouch( Actor actor, const TouchData& touch ) RemoveAnimation(mScrollAnimation); } - return true; // consume since we're potentially scrolling + return false; // Do not consume as we're potentially scrolling (detecting pan gestures) } -void ItemView::OnPan( const PanGesture& gesture ) +void ItemView::OnPan(const PanGesture& gesture) { - Actor self = Self(); - const Vector3 layoutSize = Self().GetCurrentSize(); + Actor self = Self(); + const Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); RemoveAnimation(mScrollAnimation); // Short-circuit if there is no active layout - if (!mActiveLayout) + if(!mActiveLayout) { - mGestureState = Gesture::Clear; + mGestureState = GestureState::CLEAR; return; } - mGestureState = gesture.state; + mGestureState = gesture.GetState(); - switch (mGestureState) + switch(mGestureState) { - case Gesture::Finished: + case GestureState::FINISHED: { // Swipe Detection - if (fabsf(mScrollDistance) > mMinimumSwipeDistance && - mScrollSpeed > mMinimumSwipeSpeed) + if(fabsf(mScrollDistance) > mMinimumSwipeDistance && + mScrollSpeed > mMinimumSwipeSpeed) { float direction = (mScrollDistance < 0.0f) ? -1.0f : 1.0f; mRefreshOrderHint = true; - float currentLayoutPosition = GetCurrentLayoutPosition(0); + float currentLayoutPosition = GetCurrentLayoutPosition(0); float firstItemScrollPosition = ClampFirstItemPosition(currentLayoutPosition + mScrollSpeed * direction, layoutSize, *mActiveLayout); - if (mAnchoringEnabled) + if(mAnchoringEnabled) { firstItemScrollPosition = mActiveLayout->GetClosestAnchorPosition(firstItemScrollPosition); } RemoveAnimation(mScrollAnimation); - float flickAnimationDuration = Clamp( mActiveLayout->GetItemFlickAnimationDuration() * std::max(1.0f, fabsf(firstItemScrollPosition - GetCurrentLayoutPosition(0))) - , DEFAULT_MINIMUM_SWIPE_DURATION, DEFAULT_MAXIMUM_SWIPE_DURATION); + float flickAnimationDuration = Clamp(mActiveLayout->GetItemFlickAnimationDuration() * std::max(1.0f, fabsf(firstItemScrollPosition - GetCurrentLayoutPosition(0))), DEFAULT_MINIMUM_SWIPE_DURATION, DEFAULT_MAXIMUM_SWIPE_DURATION); mScrollAnimation = Animation::New(flickAnimationDuration); - mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION ), firstItemScrollPosition, AlphaFunction::EASE_OUT ); - mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::SCROLL_SPEED), 0.0f, AlphaFunction::EASE_OUT ); + mScrollAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, AlphaFunction::EASE_OUT); + mScrollAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::SCROLL_SPEED), 0.0f, AlphaFunction::EASE_OUT); mIsFlicking = true; + // Check whether it has already scrolled to the end - if(fabs(currentLayoutPosition - firstItemScrollPosition) > Math::MACHINE_EPSILON_0) + if(fabs(currentLayoutPosition - firstItemScrollPosition) < Math::MACHINE_EPSILON_0) { AnimateScrollOvershoot(0.0f); + RemoveAnimation(mScrollAnimation); } } // Anchoring may be triggered when there was no swipe - if (!mScrollAnimation) + if(!mScrollAnimation) { mScrollAnimation = DoAnchoring(); } // Reset the overshoot if no scroll animation. - if (!mScrollAnimation) + if(!mScrollAnimation) { mScrollCompletedSignal.Emit(GetCurrentScrollPosition()); @@ -1193,17 +1213,18 @@ void ItemView::OnPan( const PanGesture& gesture ) } break; - case Gesture::Started: // Fall through + case GestureState::STARTED: // Fall through { mTotalPanDisplacement = Vector2::ZERO; mScrollStartedSignal.Emit(GetCurrentScrollPosition()); mRefreshEnabled = true; } - case Gesture::Continuing: + case GestureState::CONTINUING: { - mScrollDistance = CalculateScrollDistance(gesture.displacement, *mActiveLayout); - mScrollSpeed = Clamp((gesture.GetSpeed() * gesture.GetSpeed() * mActiveLayout->GetFlickSpeedFactor() * MILLISECONDS_PER_SECONDS), 0.0f, mActiveLayout->GetMaximumSwipeSpeed()); + 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. mRefreshOrderHint = mScrollDistance < 0.0f; @@ -1212,16 +1233,16 @@ void ItemView::OnPan( const PanGesture& gesture ) float firstItemScrollPosition = ClampFirstItemPosition(layoutPositionDelta, layoutSize, *mActiveLayout); - float currentOvershoot = self.GetProperty(Toolkit::ItemView::Property::OVERSHOOT); + float currentOvershoot = self.GetCurrentProperty(Toolkit::ItemView::Property::OVERSHOOT); - self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition ); + self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition); - if( ( firstItemScrollPosition >= 0.0f && - currentOvershoot < 1.0f ) || - ( firstItemScrollPosition <= mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize) && - currentOvershoot > -1.0f ) ) + if((firstItemScrollPosition >= 0.0f && + currentOvershoot < 1.0f) || + (firstItemScrollPosition <= mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize) && + currentOvershoot > -1.0f)) { - mTotalPanDisplacement += gesture.displacement; + mTotalPanDisplacement += displacement; } mScrollOvershoot = CalculateScrollOvershoot(); @@ -1229,30 +1250,30 @@ void ItemView::OnPan( const PanGesture& gesture ) // If the view is moved in a direction against the overshoot indicator, then the indicator should be animated off. // First make sure we are not in an animation, otherwise a previously started // off-animation will be overwritten as the user continues scrolling. - if( !mInAnimation ) + if(!mInAnimation) { // Check if the movement is against the current overshoot amount (if we are currently displaying the indicator). - if( ( ( mScrollOvershoot > Math::MACHINE_EPSILON_0 ) && ( mScrollDistance < -Math::MACHINE_EPSILON_0 ) ) || - ( ( mScrollOvershoot < Math::MACHINE_EPSILON_0 ) && ( mScrollDistance > Math::MACHINE_EPSILON_0 ) ) ) + if(((mScrollOvershoot > Math::MACHINE_EPSILON_0) && (mScrollDistance < -Math::MACHINE_EPSILON_0)) || + ((mScrollOvershoot < Math::MACHINE_EPSILON_0) && (mScrollDistance > Math::MACHINE_EPSILON_0))) { // The user has moved against the indicator direction. // First, we reset the total displacement. This means the overshoot amount will become zero the next frame, // and if the user starts dragging in the overshoot direction again, the indicator will appear once more. mTotalPanDisplacement = Vector2::ZERO; // Animate the overshoot indicator off. - AnimateScrollOvershoot( 0.0f, false ); + AnimateScrollOvershoot(0.0f, false); } else { // Only set the property directly if we are not animating the overshoot away, // as otherwise this will overwrite the animation generated value. - self.SetProperty( Toolkit::ItemView::Property::OVERSHOOT, mScrollOvershoot ); + self.SetProperty(Toolkit::ItemView::Property::OVERSHOOT, mScrollOvershoot); } } } break; - case Gesture::Cancelled: + case GestureState::CANCELLED: { mScrollAnimation = DoAnchoring(); } @@ -1262,7 +1283,7 @@ void ItemView::OnPan( const PanGesture& gesture ) break; } - if (mScrollAnimation) + if(mScrollAnimation) { mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished); mScrollAnimation.Play(); @@ -1287,8 +1308,8 @@ Actor ItemView::GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::Key } else if(actor && actor.GetParent() == this->Self()) { - int itemID = GetItemId(actor); - nextItemID = mActiveLayout->GetNextFocusItemID(itemID, mItemFactory.GetNumberOfItems(), direction, loopEnabled); + int itemID = GetItemId(actor); + nextItemID = mActiveLayout->GetNextFocusItemID(itemID, mItemFactory.GetNumberOfItems(), direction, loopEnabled); nextFocusActor = GetItem(nextItemID); if(nextFocusActor == actor) { @@ -1297,14 +1318,14 @@ Actor ItemView::GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::Key return nextFocusActor; } } - float layoutPosition = mActiveLayout->GetClosestAnchorPosition( GetCurrentLayoutPosition(0) ); - Vector3 layoutSize = Self().GetCurrentSize(); + float layoutPosition = mActiveLayout->GetClosestAnchorPosition(GetCurrentLayoutPosition(0)); + Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); if(!nextFocusActor) { // likely the current item is not buffered, so not in our item pool, probably best to get first viewable item ItemRange viewableItems = mActiveLayout->GetItemsWithinArea(layoutPosition, layoutSize); - nextItemID = viewableItems.begin; - nextFocusActor = GetItem(nextItemID); + nextItemID = viewableItems.begin; + nextFocusActor = GetItem(nextItemID); } } return nextFocusActor; @@ -1315,27 +1336,34 @@ void ItemView::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor) // only in this function if our chosen focus actor was actually used if(commitedFocusableActor) { - int nextItemID = GetItemId(commitedFocusableActor); - float layoutPosition = GetCurrentLayoutPosition(0); - Vector3 layoutSize = Self().GetCurrentSize(); + int nextItemID = GetItemId(commitedFocusableActor); + float layoutPosition = GetCurrentLayoutPosition(0); + Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); float scrollTo = mActiveLayout->GetClosestOnScreenLayoutPosition(nextItemID, layoutPosition, layoutSize); ScrollTo(Vector2(0.0f, scrollTo), DEFAULT_KEYBOARD_FOCUS_SCROLL_DURATION); } } +bool ItemView::AccessibleImpl::ScrollToChild(Actor child) +{ + auto itemView = Dali::Toolkit::ItemView::DownCast(Self()); + Toolkit::GetImpl(itemView).OnKeyboardFocusChangeCommitted(child); + return true; +} + Animation ItemView::DoAnchoring() { Animation anchoringAnimation; - Actor self = Self(); + Actor self = Self(); - if (mActiveLayout && mAnchoringEnabled) + if(mActiveLayout && mAnchoringEnabled) { - float anchorPosition = mActiveLayout->GetClosestAnchorPosition( GetCurrentLayoutPosition(0) ); + float anchorPosition = mActiveLayout->GetClosestAnchorPosition(GetCurrentLayoutPosition(0)); anchoringAnimation = Animation::New(mAnchoringDuration); - anchoringAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), anchorPosition, AlphaFunction::EASE_OUT ); - anchoringAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::SCROLL_SPEED), 0.0f, AlphaFunction::EASE_OUT ); + anchoringAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), anchorPosition, AlphaFunction::EASE_OUT); + anchoringAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::SCROLL_SPEED), 0.0f, AlphaFunction::EASE_OUT); if(!mIsFlicking) { AnimateScrollOvershoot(0.0f); @@ -1355,12 +1383,12 @@ void ItemView::OnScrollFinished(Animation& source) if(mIsFlicking && fabsf(mScrollOvershoot) > Math::MACHINE_EPSILON_1) { - AnimateScrollOvershoot( mScrollOvershoot > 0.0f ? 1.0f : -1.0f, true); + AnimateScrollOvershoot(mScrollOvershoot > 0.0f ? 1.0f : -1.0f, true); } else { // Reset the overshoot - AnimateScrollOvershoot( 0.0f ); + AnimateScrollOvershoot(0.0f); } mIsFlicking = false; @@ -1391,21 +1419,21 @@ void ItemView::OnOvershootOnFinished(Animation& animation) void ItemView::ScrollToItem(unsigned int itemId, float durationSeconds) { - Actor self = Self(); - const Vector3 layoutSize = Self().GetCurrentSize(); - float firstItemScrollPosition = ClampFirstItemPosition(mActiveLayout->GetItemScrollToPosition(itemId), layoutSize, *mActiveLayout); + Actor self = Self(); + const Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); + float firstItemScrollPosition = ClampFirstItemPosition(mActiveLayout->GetItemScrollToPosition(itemId), layoutSize, *mActiveLayout); if(durationSeconds > 0.0f) { RemoveAnimation(mScrollAnimation); mScrollAnimation = Animation::New(durationSeconds); - mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, mScrollToAlphaFunction ); + mScrollAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, mScrollToAlphaFunction); mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished); mScrollAnimation.Play(); } else { - self.SetProperty( Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition ); + self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition); AnimateScrollOvershoot(0.0f); } @@ -1432,10 +1460,10 @@ void ItemView::CalculateDomainSize(const Vector3& layoutSize) if(mActiveLayout) { - firstItemPosition = mActiveLayout->GetItemPosition( 0,0,layoutSize ); + firstItemPosition = mActiveLayout->GetItemPosition(0, 0, layoutSize); float minLayoutPosition = mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize); - lastItemPosition = mActiveLayout->GetItemPosition( fabs(minLayoutPosition),fabs(minLayoutPosition),layoutSize ); + lastItemPosition = mActiveLayout->GetItemPosition(fabs(minLayoutPosition), fabs(minLayoutPosition), layoutSize); float domainSize; @@ -1463,27 +1491,27 @@ bool ItemView::IsLayoutScrollable(const Vector3& layoutSize) { Actor self = Self(); - float currentLayoutPosition = ClampFirstItemPosition( GetCurrentLayoutPosition(0), layoutSize, *mActiveLayout, false ); - float forwardClampedPosition = ClampFirstItemPosition( currentLayoutPosition + 1.0, layoutSize, *mActiveLayout, false ); - float backwardClampedPosition = ClampFirstItemPosition( currentLayoutPosition - 1.0, layoutSize, *mActiveLayout, false ); + float currentLayoutPosition = ClampFirstItemPosition(GetCurrentLayoutPosition(0), layoutSize, *mActiveLayout, false); + float forwardClampedPosition = ClampFirstItemPosition(currentLayoutPosition + 1.0, layoutSize, *mActiveLayout, false); + float backwardClampedPosition = ClampFirstItemPosition(currentLayoutPosition - 1.0, layoutSize, *mActiveLayout, false); return (fabs(forwardClampedPosition - backwardClampedPosition) > Math::MACHINE_EPSILON_0); } float ItemView::GetScrollPosition(float layoutPosition, const Vector3& layoutSize) const { - Vector3 firstItemPosition( mActiveLayout->GetItemPosition(0, layoutPosition, layoutSize ) ); - return IsHorizontal(mActiveLayout->GetOrientation()) ? firstItemPosition.x: firstItemPosition.y; + Vector3 firstItemPosition(mActiveLayout->GetItemPosition(0, layoutPosition, layoutSize)); + return IsHorizontal(mActiveLayout->GetOrientation()) ? firstItemPosition.x : firstItemPosition.y; } Vector2 ItemView::GetCurrentScrollPosition() const { - return Vector2(0.0f, GetScrollPosition(GetCurrentLayoutPosition(0), Self().GetCurrentSize())); + return Vector2(0.0f, GetScrollPosition(GetCurrentLayoutPosition(0), Self().GetCurrentProperty(Actor::Property::SIZE))); } void ItemView::AddOverlay(Actor actor) { - actor.SetDrawMode( DrawMode::OVERLAY_2D ); + actor.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D); Self().Add(actor); } @@ -1494,8 +1522,8 @@ void ItemView::RemoveOverlay(Actor actor) void ItemView::ScrollTo(const Vector2& position, float duration) { - Actor self = Self(); - const Vector3 layoutSize = Self().GetCurrentSize(); + Actor self = Self(); + const Vector3 layoutSize = Self().GetCurrentProperty(Actor::Property::SIZE); float firstItemScrollPosition = ClampFirstItemPosition(position.y, layoutSize, *mActiveLayout); @@ -1503,13 +1531,13 @@ void ItemView::ScrollTo(const Vector2& position, float duration) { RemoveAnimation(mScrollAnimation); mScrollAnimation = Animation::New(duration); - mScrollAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, mScrollToAlphaFunction ); + mScrollAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::LAYOUT_POSITION), firstItemScrollPosition, mScrollToAlphaFunction); mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished); mScrollAnimation.Play(); } else { - self.SetProperty( Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition ); + self.SetProperty(Toolkit::ItemView::Property::LAYOUT_POSITION, firstItemScrollPosition); AnimateScrollOvershoot(0.0f); } @@ -1517,63 +1545,69 @@ void ItemView::ScrollTo(const Vector2& position, float duration) mRefreshEnabled = true; } -void ItemView::SetOvershootEffectColor( const Vector4& color ) +void ItemView::SetOvershootSize(const Vector2& size) +{ + mOvershootSize = size; + + if(mOvershootOverlay) + { + // Remove old & add new size constraint + mOvershootOverlay.RemoveConstraints(OVERSHOOT_SIZE_CONSTRAINT_TAG); + ApplyOvershootSizeConstraint(mOvershootOverlay, mOvershootSize.height); + } +} + +void ItemView::SetOvershootEffectColor(const Vector4& color) { mOvershootEffectColor = color; - if( mOvershootOverlay ) + if(mOvershootOverlay) { - mOvershootOverlay.SetColor( color ); + mOvershootOverlay.SetProperty(Actor::Property::COLOR, color); } } -void ItemView::EnableScrollOvershoot( bool enable ) +void ItemView::EnableScrollOvershoot(bool enable) { Actor self = Self(); - if( enable ) + if(enable) { - if( !mOvershootOverlay ) + if(!mOvershootOverlay) { 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 = CreateBouncingEffectActor(effectOvershootPropertyIndex); + 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); - Constraint constraint = Constraint::New( mOvershootOverlay, Actor::Property::SIZE, OvershootOverlaySizeConstraint(mOvershootSize.height) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_DIRECTION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_ORIENTATION ) ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.Apply(); + ApplyOvershootSizeConstraint(mOvershootOverlay, mOvershootSize.height); - mOvershootOverlay.SetSize(mOvershootSize.width, mOvershootSize.height); - - constraint = Constraint::New( mOvershootOverlay, Actor::Property::ORIENTATION, OvershootOverlayRotationConstraint ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_DIRECTION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_ORIENTATION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::OVERSHOOT ) ); + Constraint constraint = Constraint::New(mOvershootOverlay, Actor::Property::ORIENTATION, OvershootOverlayRotationConstraint); + constraint.AddSource(ParentSource(Toolkit::ItemView::Property::SCROLL_DIRECTION)); + constraint.AddSource(ParentSource(Toolkit::ItemView::Property::LAYOUT_ORIENTATION)); + constraint.AddSource(ParentSource(Toolkit::ItemView::Property::OVERSHOOT)); constraint.Apply(); - constraint = Constraint::New( mOvershootOverlay, Actor::Property::POSITION, OvershootOverlayPositionConstraint ); - constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::SCROLL_DIRECTION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::LAYOUT_ORIENTATION ) ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::OVERSHOOT ) ); + constraint = Constraint::New(mOvershootOverlay, Actor::Property::POSITION, OvershootOverlayPositionConstraint); + constraint.AddSource(ParentSource(Actor::Property::SIZE)); + constraint.AddSource(ParentSource(Toolkit::ItemView::Property::SCROLL_DIRECTION)); + constraint.AddSource(ParentSource(Toolkit::ItemView::Property::LAYOUT_ORIENTATION)); + constraint.AddSource(ParentSource(Toolkit::ItemView::Property::OVERSHOOT)); constraint.Apply(); - constraint = Constraint::New( mOvershootOverlay, Actor::Property::VISIBLE, OvershootOverlayVisibilityConstraint ); - constraint.AddSource( ParentSource( Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL ) ); + constraint = Constraint::New(mOvershootOverlay, Actor::Property::VISIBLE, OvershootOverlayVisibilityConstraint); + constraint.AddSource(ParentSource(Toolkit::Scrollable::Property::CAN_SCROLL_VERTICAL)); constraint.Apply(); - constraint = Constraint::New( mOvershootOverlay, effectOvershootPropertyIndex, EqualToConstraint() ); - constraint.AddSource( ParentSource( Toolkit::ItemView::Property::OVERSHOOT ) ); + constraint = Constraint::New(mOvershootOverlay, effectOvershootPropertyIndex, EqualToConstraint()); + constraint.AddSource(ParentSource(Toolkit::ItemView::Property::OVERSHOOT)); constraint.Apply(); } } else { - if( mOvershootOverlay ) + if(mOvershootOverlay) { self.Remove(mOvershootOverlay); mOvershootOverlay.Reset(); @@ -1589,13 +1623,13 @@ float ItemView::CalculateScrollOvershoot() { // The overshoot must be calculated from the accumulated pan gesture displacement // since the pan gesture starts. - Actor self = Self(); - float scrollDistance = CalculateScrollDistance(mTotalPanDisplacement, *mActiveLayout) * mActiveLayout->GetScrollSpeedFactor(); - float positionDelta = GetCurrentLayoutPosition(0) + scrollDistance; - float minLayoutPosition = mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), Self().GetCurrentSize()); + Actor self = Self(); + float scrollDistance = CalculateScrollDistance(mTotalPanDisplacement, *mActiveLayout) * mActiveLayout->GetScrollSpeedFactor(); + float positionDelta = GetCurrentLayoutPosition(0) + scrollDistance; + float minLayoutPosition = mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), Self().GetCurrentProperty(Actor::Property::SIZE)); 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; + overshoot = positionDelta - clamppedPosition; } return overshoot > 0.0f ? std::min(overshoot, 1.0f) : std::max(overshoot, -1.0f); @@ -1608,7 +1642,7 @@ void ItemView::AnimateScrollOvershoot(float overshootAmount, bool animateBack) // make sure we animate back if needed mAnimateOvershootOff = animateBack || (!animatingOn && mAnimatingOvershootOn); - if( mAnimatingOvershootOn ) + if(mAnimatingOvershootOn) { // animating on, do not allow animate off return; @@ -1618,37 +1652,37 @@ void ItemView::AnimateScrollOvershoot(float overshootAmount, bool animateBack) if(mOvershootAnimationSpeed > Math::MACHINE_EPSILON_0) { - float currentOvershoot = self.GetProperty(Toolkit::ItemView::Property::OVERSHOOT); - float duration = 0.0f; + float currentOvershoot = self.GetCurrentProperty(Toolkit::ItemView::Property::OVERSHOOT); + float duration = 0.0f; - if (mOvershootOverlay) + if(mOvershootOverlay) { - duration = mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)) / mOvershootAnimationSpeed; + duration = mOvershootOverlay.GetCurrentProperty(Actor::Property::SIZE).height * (animatingOn ? (1.0f - fabsf(currentOvershoot)) : fabsf(currentOvershoot)) / mOvershootAnimationSpeed; } // Mark the animation as in progress to prevent manual property sets overwriting it. - mInAnimation = true; + mInAnimation = true; mAnimatingOvershootOn = animatingOn; RemoveAnimation(mScrollOvershootAnimation); mScrollOvershootAnimation = Animation::New(duration); mScrollOvershootAnimation.FinishedSignal().Connect(this, &ItemView::OnOvershootOnFinished); - mScrollOvershootAnimation.AnimateTo( Property(self, Toolkit::ItemView::Property::OVERSHOOT), overshootAmount, TimePeriod(0.0f, duration) ); + mScrollOvershootAnimation.AnimateTo(Property(self, Toolkit::ItemView::Property::OVERSHOOT), overshootAmount, TimePeriod(0.0f, duration)); mScrollOvershootAnimation.Play(); } else { - self.SetProperty( Toolkit::ItemView::Property::OVERSHOOT, overshootAmount ); + self.SetProperty(Toolkit::ItemView::Property::OVERSHOOT, overshootAmount); } } -void ItemView::SetItemsParentOrigin( const Vector3& parentOrigin ) +void ItemView::SetItemsParentOrigin(const Vector3& parentOrigin) { - if( parentOrigin != mItemsParentOrigin ) + if(parentOrigin != mItemsParentOrigin) { mItemsParentOrigin = parentOrigin; - for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) + for(ItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { - iter->second.SetParentOrigin(parentOrigin); + iter->second.SetProperty(Actor::Property::PARENT_ORIGIN, parentOrigin); } } } @@ -1658,14 +1692,14 @@ Vector3 ItemView::GetItemsParentOrigin() const return mItemsParentOrigin; } -void ItemView::SetItemsAnchorPoint( const Vector3& anchorPoint ) +void ItemView::SetItemsAnchorPoint(const Vector3& anchorPoint) { - if( anchorPoint != mItemsAnchorPoint ) + if(anchorPoint != mItemsAnchorPoint) { mItemsAnchorPoint = anchorPoint; - for (ItemPoolIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) + for(ItemIter iter = mItemPool.begin(); iter != mItemPool.end(); ++iter) { - iter->second.SetAnchorPoint(anchorPoint); + iter->second.SetProperty(Actor::Property::ANCHOR_POINT, anchorPoint); } } } @@ -1677,28 +1711,28 @@ Vector3 ItemView::GetItemsAnchorPoint() const void ItemView::GetItemsRange(ItemRange& range) { - if( !mItemPool.empty() ) + if(!mItemPool.empty()) { range.begin = mItemPool.begin()->first; - range.end = mItemPool.rbegin()->first + 1; + range.end = mItemPool.rbegin()->first + 1; } else { range.begin = 0; - range.end = 0; + range.end = 0; } } -bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor ) +bool ItemView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor) { - Dali::BaseHandle handle( object ); + Dali::BaseHandle handle(object); - bool connected( true ); - Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( handle ); + bool connected(true); + Toolkit::ItemView itemView = Toolkit::ItemView::DownCast(handle); - if( 0 == strcmp( signalName.c_str(), LAYOUT_ACTIVATED_SIGNAL ) ) + if(0 == strcmp(signalName.c_str(), LAYOUT_ACTIVATED_SIGNAL)) { - itemView.LayoutActivatedSignal().Connect( tracker, functor ); + itemView.LayoutActivatedSignal().Connect(tracker, functor); } else { @@ -1709,47 +1743,52 @@ bool ItemView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* return connected; } -void ItemView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +void ItemView::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value) { - Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) ); + Toolkit::ItemView itemView = Toolkit::ItemView::DownCast(Dali::BaseHandle(object)); - if( itemView ) + if(itemView) { - ItemView& itemViewImpl( GetImpl( itemView ) ); - switch( index ) + ItemView& itemViewImpl(GetImpl(itemView)); + switch(index) { case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED: { - itemViewImpl.SetMinimumSwipeSpeed( value.Get() ); + itemViewImpl.SetMinimumSwipeSpeed(value.Get()); break; } + case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE: { - itemViewImpl.SetMinimumSwipeDistance( value.Get() ); + itemViewImpl.SetMinimumSwipeDistance(value.Get()); break; } + case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP: { - itemViewImpl.SetWheelScrollDistanceStep( value.Get() ); + itemViewImpl.SetWheelScrollDistanceStep(value.Get()); break; } + case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED: { - itemViewImpl.SetAnchoring( value.Get() ); + itemViewImpl.SetAnchoring(value.Get()); break; } + case Toolkit::ItemView::Property::REFRESH_INTERVAL: { - itemViewImpl.SetRefreshInterval( value.Get() ); + itemViewImpl.SetRefreshInterval(value.Get()); break; } - case Toolkit::DevelItemView::Property::LAYOUT: + + case Toolkit::ItemView::Property::LAYOUT: { // Get a Property::Array from the property if possible. Property::Array layoutArray; - if( value.Get( layoutArray ) ) + if(value.Get(layoutArray)) { - itemViewImpl.SetLayoutArray( layoutArray ); + itemViewImpl.SetLayoutArray(layoutArray); } break; } @@ -1762,28 +1801,29 @@ Property::Array ItemView::GetLayoutArray() return mlayoutArray; } -void ItemView::SetLayoutArray( const Property::Array& layouts ) +void ItemView::SetLayoutArray(const Property::Array& layouts) { - mlayoutArray = layouts; - if(GetLayoutCount() > 0) + mlayoutArray = layouts; + const int layoutCount = GetLayoutCount(); + if(layoutCount > 0) { - for(unsigned int index = GetLayoutCount() - 1; index >= 0; --index) + for(int index = layoutCount - 1; index >= 0; --index) { RemoveLayout(index); if(index == 0) break; } } - for( unsigned int arrayIdx = 0, arrayCount = layouts.Count(); arrayIdx < arrayCount; ++arrayIdx ) + for(unsigned int arrayIdx = 0, arrayCount = layouts.Count(); arrayIdx < arrayCount; ++arrayIdx) { - const Property::Value& element = layouts.GetElementAt( arrayIdx ); + const Property::Value& element = layouts.GetElementAt(arrayIdx); - Property::Map* layout = element.GetMap(); - if( layout != NULL ) + const Property::Map* layout = element.GetMap(); + if(layout != NULL) { - for( unsigned int mapIdx = 0, mapCount = (*layout).Count(); mapIdx < mapCount; ++mapIdx ) + for(unsigned int mapIdx = 0, mapCount = (*layout).Count(); mapIdx < mapCount; ++mapIdx) { - KeyValuePair propertyPair( (*layout).GetKeyValue( mapIdx ) ); + KeyValuePair propertyPair((*layout).GetKeyValue(mapIdx)); if(propertyPair.first == DefaultItemLayoutProperty::TYPE) { @@ -1797,6 +1837,7 @@ void ItemView::SetLayoutArray( const Property::Array& layouts ) { Internal::DepthLayoutPtr depthLayout = Internal::DepthLayout::New(); (*depthLayout).SetLayoutProperties(*layout); + (*depthLayout).SetDepthLayoutProperties(*layout); AddLayout(*depthLayout); break; } @@ -1804,14 +1845,16 @@ void ItemView::SetLayoutArray( const Property::Array& layouts ) { Internal::GridLayoutPtr gridLayout = Internal::GridLayout::New(); (*gridLayout).SetLayoutProperties(*layout); + (*gridLayout).SetGridLayoutProperties(*layout); AddLayout(*gridLayout); break; } case DefaultItemLayout::LIST: { Internal::GridLayoutPtr listLayout = Internal::GridLayout::New(); - listLayout->SetNumberOfColumns( 1 ); + listLayout->SetNumberOfColumns(1); (*listLayout).SetLayoutProperties(*layout); + (*listLayout).SetGridLayoutProperties(*layout); AddLayout(*listLayout); break; } @@ -1819,6 +1862,7 @@ void ItemView::SetLayoutArray( const Property::Array& layouts ) { Internal::SpiralLayoutPtr spiralLayout = Internal::SpiralLayout::New(); (*spiralLayout).SetLayoutProperties(*layout); + (*spiralLayout).SetSpiralLayoutProperties(*layout); AddLayout(*spiralLayout); break; } @@ -1830,74 +1874,78 @@ void ItemView::SetLayoutArray( const Property::Array& layouts ) } } -Property::Value ItemView::GetProperty( BaseObject* object, Property::Index index ) +Property::Value ItemView::GetProperty(BaseObject* object, Property::Index index) { Property::Value value; - Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) ); + Toolkit::ItemView itemView = Toolkit::ItemView::DownCast(Dali::BaseHandle(object)); - if( itemView ) + if(itemView) { - ItemView& itemViewImpl( GetImpl( itemView ) ); - switch( index ) + ItemView& itemViewImpl(GetImpl(itemView)); + switch(index) { case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED: { value = itemViewImpl.GetMinimumSwipeSpeed(); 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::SNAP_TO_ITEM_ENABLED: { value = itemViewImpl.GetAnchoring(); break; } + case Toolkit::ItemView::Property::REFRESH_INTERVAL: { value = itemViewImpl.GetRefreshInterval(); break; } - case Toolkit::DevelItemView::Property::LAYOUT: + + case Toolkit::ItemView::Property::LAYOUT: { - Property::Array layouts= itemViewImpl.GetLayoutArray(); - value = layouts; + Property::Array layouts = itemViewImpl.GetLayoutArray(); + value = layouts; break; } - } } return value; } -bool ItemView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes ) +bool ItemView::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& attributes) { - Dali::BaseHandle handle( object ); + Dali::BaseHandle handle(object); - Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( handle ); + Toolkit::ItemView itemView = Toolkit::ItemView::DownCast(handle); - DALI_ASSERT_ALWAYS( itemView ); + DALI_ASSERT_ALWAYS(itemView); - if( 0 == strcmp( actionName.c_str(), ACTION_STOP_SCROLLING ) ) + if(0 == strcmp(actionName.c_str(), ACTION_STOP_SCROLLING)) { - GetImpl( itemView ).DoStopScrolling(); + GetImpl(itemView).DoStopScrolling(); } - else if ( 0 == strcmp( actionName.c_str(), ACTION_ENABLE_REFRESH ) ) + else if(0 == strcmp(actionName.c_str(), ACTION_ENABLE_REFRESH)) { - GetImpl( itemView ).SetRefreshNotificationEnabled( true ); + GetImpl(itemView).SetRefreshNotificationEnabled(true); } - else if ( 0 == strcmp( actionName.c_str(), ACTION_DISABLE_REFRESH ) ) + else if(0 == strcmp(actionName.c_str(), ACTION_DISABLE_REFRESH)) { - GetImpl( itemView ).SetRefreshNotificationEnabled( false ); + GetImpl(itemView).SetRefreshNotificationEnabled(false); } return true; @@ -1905,14 +1953,14 @@ bool ItemView::DoAction( BaseObject* object, const std::string& actionName, cons void ItemView::DoStopScrolling() { - if( mScrollAnimation ) + if(mScrollAnimation) { mScrollAnimation.Stop(); mScrollAnimation.Reset(); } } -void ItemView::SetRefreshNotificationEnabled( bool enabled ) +void ItemView::SetRefreshNotificationEnabled(bool enabled) { mRefreshNotificationEnabled = enabled; }