X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dali-toolkit%2Fpublic-api%2Fcontrols%2Fscrollable%2Fitem-view%2Fitem-layout.cpp;h=7d6d17fa9bcfa3c3fd0ea4914daebf740e28f127;hb=030e7c680a6eb0e8d87bfdb8ec359a0267ef7db2;hp=177c1d8763c996c37e4ce5f74a54ca281bd67599;hpb=e2eda444afbe82e9591fe198eef339227f90a616;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp b/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp index 177c1d8..7d6d17f 100644 --- a/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp +++ b/dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp @@ -1,21 +1,127 @@ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +/* + * Copyright (c) 2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +// CLASS HEADER #include +// EXTERNAL INCLUDES +#include +#include +#include + +// INTERNAL INCLUDES +#include + +namespace +{ + +// Lerps between current and target using the progress +template< typename Type > +void Lerp( Type& current, const Type& target, float progress ) +{ + current += ((target - current) * progress); +} + +// Functors which wrap constraint functions with stored item IDs +struct WrappedQuaternionConstraint +{ + WrappedQuaternionConstraint( Dali::Toolkit::ItemLayout::QuaternionFunction wrapMe, unsigned int itemId ) + :mWrapMe(wrapMe), + mItemId(itemId) + { + } + + void operator()( Dali::Quaternion& current, const Dali::PropertyInputContainer& inputs ) + { + float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); + float weight = inputs[3]->GetFloat(); + + current = Dali::Quaternion::Slerp( current, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight ); + } + + Dali::Toolkit::ItemLayout::QuaternionFunction mWrapMe; + unsigned int mItemId; +}; + +struct WrappedVector3Constraint +{ + WrappedVector3Constraint( Dali::Toolkit::ItemLayout::Vector3Function wrapMe, unsigned int itemId ) + : mWrapMe(wrapMe), + mItemId(itemId) + { + } + + void operator()( Dali::Vector3& current, const Dali::PropertyInputContainer& inputs ) + { + float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); + float weight = inputs[3]->GetFloat(); + + Lerp( current, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight ); + } + + Dali::Toolkit::ItemLayout::Vector3Function mWrapMe; + unsigned int mItemId; +}; + +struct WrappedVector4Constraint +{ + WrappedVector4Constraint( Dali::Toolkit::ItemLayout::Vector4Function wrapMe, unsigned int itemId ) + : mWrapMe(wrapMe), + mItemId(itemId) + { + } + + void operator()( Dali::Vector4& current, const Dali::PropertyInputContainer& inputs ) + { + float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); + float weight = inputs[3]->GetFloat(); + + Lerp( current, mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ), weight ); + } + + Dali::Toolkit::ItemLayout::Vector4Function mWrapMe; + unsigned int mItemId; +}; + +struct WrappedBoolConstraint +{ + WrappedBoolConstraint( Dali::Toolkit::ItemLayout::BoolFunction wrapMe, unsigned int itemId ) + : mWrapMe(wrapMe), + mItemId(itemId) + { + } + + void operator()( bool& current, const Dali::PropertyInputContainer& inputs ) + { + float weight = inputs[3]->GetFloat(); + + if ( weight >= 1.0f ) + { + float offsetLayoutPosition = inputs[0]->GetFloat() + static_cast(mItemId); + current = mWrapMe( current, offsetLayoutPosition, inputs[1]->GetFloat(), inputs[2]->GetVector3() ); + } + } + + Dali::Toolkit::ItemLayout::BoolFunction mWrapMe; + unsigned int mItemId; +}; + +} //Unnamed namespace + namespace Dali { @@ -23,7 +129,9 @@ namespace Toolkit { ItemLayout::ItemLayout() -: mOrientation(ControlOrientation::Up) +: mOrientation( ControlOrientation::Up ), + mAlphaFunction( AlphaFunction::LINEAR ), + mWeightObject() { } @@ -43,12 +151,7 @@ ControlOrientation::Type ItemLayout::GetOrientation() const float ItemLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) { - ItemLayout::Vector3Function positionConstraint; - Vector3 itemPosition = Vector3::ZERO; - if (GetPositionConstraint(itemID, positionConstraint)) - { - itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize); - } + Vector3 itemPosition = GetItemPosition( itemID, currentLayoutPosition, layoutSize ); Vector3 itemSize; GetItemSize(itemID, layoutSize, itemSize); Vector3 onScreenArea = (layoutSize - itemSize) * 0.5f; @@ -64,178 +167,159 @@ float ItemLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayo return currentLayoutPosition; } -void ItemLayout::GetXAxisScrollHint(Vector2& scrollHint) const +int ItemLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled) { - scrollHint = Vector2::ZERO; - Radian scrollAngle(GetScrollDirection()); - Vector2 scrollDirection(sinf(scrollAngle), cosf(scrollAngle)); - switch(mOrientation) + switch( direction ) { - case ControlOrientation::Up: - { - if(fabsf(scrollDirection.y) < Math::MACHINE_EPSILON_1) - { - // we probably want x scrolling - if(scrollDirection.x > 0.0f) - { - // normal positive scrolling - scrollHint = Vector2::XAXIS; - } - else - { - scrollHint = -Vector2::XAXIS; - } - } - break; - } - case ControlOrientation::Down: - { - if(fabsf(scrollDirection.y) < Math::MACHINE_EPSILON_1) - { - // we probably want x scrolling - if(scrollDirection.x > 0.0f) - { - // normal positive scrolling - scrollHint = -Vector2::XAXIS; - } - else - { - scrollHint = Vector2::XAXIS; - } - } - break; - } - case ControlOrientation::Left: + case Control::Left: + case Control::Up: { - // we probably want x scrolling - if(scrollDirection.x > 0.0f) - { - // normal positive scrolling - scrollHint = Vector2::XAXIS; - } - else + itemID--; + if( itemID < 0 ) { - scrollHint = -Vector2::XAXIS; + itemID = loopEnabled ? maxItems - 1 : 0; } break; } - case ControlOrientation::Right: + case Control::Right: + case Control::Down: { - // we probably want x scrolling - if(scrollDirection.x > 0.0f) - { - // normal positive scrolling - scrollHint = -Vector2::XAXIS; - } - else + itemID++; + if( itemID >= maxItems ) { - scrollHint = Vector2::XAXIS; + itemID = loopEnabled ? 0 : maxItems - 1; } break; } } + return itemID; +} + +float ItemLayout::GetFlickSpeedFactor() const +{ + // By default, the speed factor while dragging and swiping is the same. + return GetScrollSpeedFactor(); } -void ItemLayout::GetYAxisScrollHint(Vector2& scrollHint) const +void ItemLayout::ApplyConstraints( Actor& actor, const int itemId, const float durationSeconds, Handle scrollPositionObject, const Actor& itemViewActor ) { - scrollHint = Vector2::ZERO; - Radian scrollAngle(GetScrollDirection()); - Vector2 scrollDirection(sinf(scrollAngle), cosf(scrollAngle)); - switch(mOrientation) + // This just implements the default behaviour of constraint application. + // Custom layouts can override this function to apply their custom constraints. + Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast( itemViewActor ); + if(itemView && scrollPositionObject) { - case ControlOrientation::Up: + Property::Index scrollSpeedProperty = itemView.GetPropertyIndex("item-view-scroll-speed"); + Property::Index scrollPositionProperty = scrollPositionObject.GetPropertyIndex("scroll-position"); + + // We want to animate the layout in so use a weight object to do this + if ( !mWeightObject ) { - // we probably want x scrolling - if(scrollDirection.y > 0.0f) - { - // normal positive scrolling - scrollHint = Vector2::YAXIS; - } - else - { - scrollHint = -Vector2::YAXIS; - } - break; + mWeightObject = WeightObject::New(); } - case ControlOrientation::Down: + + ItemLayout::Vector3Function positionConstraint; + if (GetPositionConstraint(itemId, positionConstraint)) { - // we probably want x scrolling - if(scrollDirection.y > 0.0f) - { - // normal positive scrolling - scrollHint = -Vector2::YAXIS; - } - else - { - scrollHint = Vector2::YAXIS; - } - break; + WrappedVector3Constraint wrapped(positionConstraint, itemId); + Constraint constraint = Constraint::New( actor, Actor::Property::POSITION, wrapped ); + constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) ); + constraint.AddSource( ParentSource( scrollSpeedProperty ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); + constraint.Apply(); } - case ControlOrientation::Left: + + ItemLayout::QuaternionFunction rotationConstraint; + if (GetRotationConstraint(itemId, rotationConstraint)) { - if(fabsf(scrollDirection.x) < Math::MACHINE_EPSILON_1) - { - // we probably want x scrolling - if(scrollDirection.y > 0.0f) - { - // normal positive scrolling - scrollHint = -Vector2::YAXIS; - } - else - { - scrollHint = Vector2::YAXIS; - } - } - break; + WrappedQuaternionConstraint wrapped(rotationConstraint, itemId); + + Constraint constraint = Constraint::New( actor, Actor::Property::ORIENTATION, wrapped ); + constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) ); + constraint.AddSource( ParentSource( scrollSpeedProperty ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); + constraint.Apply(); } - case ControlOrientation::Right: + + ItemLayout::Vector3Function scaleConstraint; + if (GetScaleConstraint(itemId, scaleConstraint)) { - if(fabsf(scrollDirection.x) < Math::MACHINE_EPSILON_1) - { - // we probably want x scrolling - if(scrollDirection.y > 0.0f) - { - // normal positive scrolling - scrollHint = Vector2::YAXIS; - } - else - { - scrollHint = -Vector2::YAXIS; - } - } - break; + WrappedVector3Constraint wrapped(scaleConstraint, itemId); + + Constraint constraint = Constraint::New( actor, Actor::Property::SCALE, wrapped ); + constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) ); + constraint.AddSource( ParentSource( scrollSpeedProperty ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); + constraint.Apply(); } - } -} -int ItemLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled) -{ - switch( direction ) - { - case Control::Left: - case Control::Up: + ItemLayout::Vector4Function colorConstraint; + if (GetColorConstraint(itemId, colorConstraint)) { - itemID--; - if( itemID < 0 ) - { - itemID = loopEnabled ? maxItems - 1 : 0; - } - break; + WrappedVector4Constraint wrapped(colorConstraint, itemId); + + Constraint constraint = Constraint::New( actor, Actor::Property::COLOR, wrapped ); + constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) ); + constraint.AddSource( ParentSource( scrollSpeedProperty ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); + constraint.SetRemoveAction(Dali::Constraint::Discard); + constraint.Apply(); } - case Control::Right: - case Control::Down: + + ItemLayout::BoolFunction visibilityConstraint; + if (GetVisibilityConstraint(itemId, visibilityConstraint)) { - itemID++; - if( itemID >= maxItems ) - { - itemID = loopEnabled ? 0 : maxItems - 1; - } - break; + WrappedBoolConstraint wrapped(visibilityConstraint, itemId); + + Constraint constraint = Constraint::New( actor, Actor::Property::VISIBLE, wrapped ); + constraint.AddSource( Source( scrollPositionObject, scrollPositionProperty ) ); + constraint.AddSource( ParentSource( scrollSpeedProperty ) ); + constraint.AddSource( ParentSource( Actor::Property::SIZE ) ); + constraint.AddSource( Source( mWeightObject, WeightObject::WEIGHT ) ); + + // Release visibility constraints the same time as the color constraint + constraint.SetRemoveAction(Dali::Constraint::Discard); + + constraint.Apply(); } + + KeyFrames keyFrames = KeyFrames::New(); + keyFrames.Add( 0.0f, 0.0f ); + keyFrames.Add( 1.0f, 1.0f ); + + Animation applyAnimation = Dali::Animation::New( durationSeconds ); + applyAnimation.AnimateBetween( Property( mWeightObject, WeightObject::WEIGHT ), keyFrames, mAlphaFunction, TimePeriod(durationSeconds) ); + applyAnimation.Play(); } - return itemID; } +Vector3 ItemLayout::GetItemPosition(int itemID, float currentLayoutPosition, const Vector3& layoutSize) const +{ + Vector3 itemPosition = Vector3::ZERO; + + ItemLayout::Vector3Function positionConstraint; + if (GetPositionConstraint(itemID, positionConstraint)) + { + itemPosition = positionConstraint(Vector3::ZERO, currentLayoutPosition + itemID, 0.0f, layoutSize); + } + + return itemPosition; +} + +void ItemLayout::SetAlphaFunction(AlphaFunction func) +{ + mAlphaFunction = func; +} + +AlphaFunction ItemLayout::GetAlphaFunction() const +{ + return mAlphaFunction; +} + + } // namespace Toolkit } // namespace Dali