From 818994dc0acac601b0b27c0b715259b504ef4ceb Mon Sep 17 00:00:00 2001 From: Richard Huang Date: Thu, 27 Mar 2014 15:41:23 +0000 Subject: [PATCH] Implemented scroll bar control [Issue] N/A [Problem] Need a scroll bar control that can be added to other actors to indicate the current scroll position of the actor's scrollable content. [Cause] N/A [Solution] Implemented a scroll bar control. Change-Id: I4e4b174f6cdf41caffe93dc362ca9ca6eb484c94 Signed-off-by: Richard Huang --- build/slp/dali-toolkit/Makefile.am | 2 + .../public-api/controls/control-impl.h | 76 ++--- capi/dali-toolkit/public-api/controls/control.h | 32 ++ .../controls/scrollable/item-view/item-view.h | 11 +- .../controls/scrollable/scroll-connector.h | 28 +- dali-toolkit/dali-toolkit.h | 2 + .../controls/scroll-bar/scroll-bar-impl.cpp | 332 +++++++++++++++++++++ .../internal/controls/scroll-bar/scroll-bar-impl.h | 189 ++++++++++++ ...l-bar-impl.cpp => scroll-bar-internal-impl.cpp} | 104 +++---- ...croll-bar-impl.h => scroll-bar-internal-impl.h} | 40 +-- .../{scroll-bar.cpp => scroll-bar-internal.cpp} | 30 +- .../{scroll-bar.h => scroll-bar-internal.h} | 44 +-- .../scroll-component/scroll-component-impl.cpp | 6 +- .../scroll-component/scroll-component-impl.h | 4 +- .../controls/scroll-component/scroll-component.h | 4 +- .../scrollable/item-view/item-view-impl.cpp | 129 ++++---- .../controls/scrollable/item-view/item-view-impl.h | 41 ++- .../controls/scrollable/scroll-connector-impl.cpp | 8 +- .../controls/scrollable/scroll-connector-impl.h | 23 +- .../controls/scrollable/scrollable-impl.cpp | 2 +- dali-toolkit/internal/file.list | 5 +- dali-toolkit/public-api/controls/control.cpp | 20 ++ .../public-api/controls/scroll-bar/scroll-bar.cpp | 113 +++++++ .../public-api/controls/scroll-bar/scroll-bar.h | 191 ++++++++++++ .../controls/scrollable/item-view/item-view.cpp | 6 +- .../controls/scrollable/scroll-connector.cpp | 15 +- dali-toolkit/public-api/file.list | 4 + 27 files changed, 1195 insertions(+), 266 deletions(-) create mode 100755 dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp create mode 100755 dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h rename dali-toolkit/internal/controls/scroll-component/{scroll-bar-impl.cpp => scroll-bar-internal-impl.cpp} (85%) rename dali-toolkit/internal/controls/scroll-component/{scroll-bar-impl.h => scroll-bar-internal-impl.h} (76%) rename dali-toolkit/internal/controls/scroll-component/{scroll-bar.cpp => scroll-bar-internal.cpp} (55%) rename dali-toolkit/internal/controls/scroll-component/{scroll-bar.h => scroll-bar-internal.h} (61%) create mode 100755 dali-toolkit/public-api/controls/scroll-bar/scroll-bar.cpp create mode 100755 dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h diff --git a/build/slp/dali-toolkit/Makefile.am b/build/slp/dali-toolkit/Makefile.am index c9cdc77..f4a1002 100644 --- a/build/slp/dali-toolkit/Makefile.am +++ b/build/slp/dali-toolkit/Makefile.am @@ -75,6 +75,7 @@ publicapiitemviewdir = $(publicapidir)/controls/scrollable/item-view publicapimagnifierdir = $(publicapidir)/controls/magnifier publicapipopupdir = $(publicapidir)/controls/popup publicapipageturnviewdir = $(publicapidir)/controls/page-turn-view +publicapiscrollbardir = $(publicapidir)/controls/scroll-bar publicapiscrollcomponentdir = $(publicapidir)/controls/scroll-component publicapiscrollabledir = $(publicapidir)/controls/scrollable publicapiscrollviewdir = $(publicapidir)/controls/scrollable/scroll-view @@ -113,6 +114,7 @@ publicapiitemview_HEADERS = $(public_api_item_view_header_files) publicapimagnifier_HEADERS = $(public_api_magnifier_header_files) publicapipopup_HEADERS = $(public_api_popup_header_files) publicapipageturnview_HEADERS = $(public_api_page_turn_view_header_files) +publicapiscrollbar_HEADERS = $(public_api_scroll_bar_header_files) publicapiscrollcomponent_HEADERS = $(public_api_scroll_component_header_files) publicapiscrollable_HEADERS = $(public_api_scrollable_header_files) publicapiscrollview_HEADERS = $(public_api_scroll_view_header_files) diff --git a/capi/dali-toolkit/public-api/controls/control-impl.h b/capi/dali-toolkit/public-api/controls/control-impl.h index 42be06c..e9c96f8 100644 --- a/capi/dali-toolkit/public-api/controls/control-impl.h +++ b/capi/dali-toolkit/public-api/controls/control-impl.h @@ -166,44 +166,6 @@ public: */ static bool DoAction(BaseObject* object, const std::string& actionName, const std::vector& attributes); -public: - - /** - * @copydoc Dali::Toolkit::Control::KeyEventSignal() - */ - Toolkit::Control::KeyEventSignalV2& KeyEventSignal(); - -protected: - - // Construction - - /** - * @brief Second phase initialization. - */ - void Initialize(); - - // Gesture Detection - - /** - * @brief Allows deriving classes to enable any of the gesture detectors that are available. - * - * Gesture detection can be enabled one at a time or in bitwise format as shown: - * @code - * EnableGestureDetection(Gesture::Type(Gesture::Pinch | Gesture::Tap | Gesture::Pan)); - * @endcode - * @param[in] type The gesture type(s) to enable. - */ - void EnableGestureDetection(Gesture::Type type); - - /** - * @brief Allows deriving classes to disable any of the gesture detectors. - * - * Like EnableGestureDetection, this can also be called using bitwise or. - * @param[in] type The gesture type(s) to disable. - * @see EnableGetureDetection - */ - void DisableGestureDetection(Gesture::Type type); - /** * @brief If deriving classes wish to fine tune pinch gesture * detection then they can access the gesture detector through this @@ -248,6 +210,44 @@ protected: */ LongPressGestureDetector GetLongPressGestureDetector() const; +public: + + /** + * @copydoc Dali::Toolkit::Control::KeyEventSignal() + */ + Toolkit::Control::KeyEventSignalV2& KeyEventSignal(); + +protected: + + // Construction + + /** + * @brief Second phase initialization. + */ + void Initialize(); + + // Gesture Detection + + /** + * @brief Allows deriving classes to enable any of the gesture detectors that are available. + * + * Gesture detection can be enabled one at a time or in bitwise format as shown: + * @code + * EnableGestureDetection(Gesture::Type(Gesture::Pinch | Gesture::Tap | Gesture::Pan)); + * @endcode + * @param[in] type The gesture type(s) to enable. + */ + void EnableGestureDetection(Gesture::Type type); + + /** + * @brief Allows deriving classes to disable any of the gesture detectors. + * + * Like EnableGestureDetection, this can also be called using bitwise or. + * @param[in] type The gesture type(s) to disable. + * @see EnableGetureDetection + */ + void DisableGestureDetection(Gesture::Type type); + private: // For derived classes to override /** diff --git a/capi/dali-toolkit/public-api/controls/control.h b/capi/dali-toolkit/public-api/controls/control.h index f588a2c..a8d87ea 100644 --- a/capi/dali-toolkit/public-api/controls/control.h +++ b/capi/dali-toolkit/public-api/controls/control.h @@ -262,6 +262,38 @@ public: */ void ClearKeyInputFocus(); + /** + * @brief Retrieves the pinch gesture detector of the control. + * + * @return The pinch gesture detector. + * @pre Pinch detection should have been enabled in the control. + */ + PinchGestureDetector GetPinchGestureDetector() const; + + /** + * @brief Retrieves the pan gesture detector of the control. + * + * @return The pan gesture detector. + * @pre Pan detection should have been enabled in the control. + */ + PanGestureDetector GetPanGestureDetector() const; + + /** + * @brief Retrieves the tap gesture detector of the control. + * + * @return The tap gesture detector. + * @pre Tap detection should have been enabled in the control. + */ + TapGestureDetector GetTapGestureDetector() const; + + /** + * @brief Retrieves the long press gesture detector of the control. + * + * @return The long press gesture detector. + * @pre Long press detection should have been enabled in the control. + */ + LongPressGestureDetector GetLongPressGestureDetector() const; + //signals public: diff --git a/capi/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h b/capi/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h index 5d123b1..82752b0 100644 --- a/capi/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h +++ b/capi/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h @@ -280,18 +280,19 @@ public: void ScrollToItem(ItemId itemId, float durationSeconds); /** - * @brief Set the interval between refreshes, during which new items are requested from ItemFactory. + * @brief Set the interval between refreshes. When the layout-position of items is changed by this interval, + * new items are requested from ItemFactory. * - * @param[in] intervalMilliseconds The refresh interval in milliseconds. + * @param[in] intervalLayoutPositions The refresh interval in layout position. */ - void SetRefreshInterval(unsigned int intervalMilliseconds); + void SetRefreshInterval(float intervalLayoutPositions); /** - * @brief Get the interval between refreshes in milliseconds. + * @brief Get the interval between refreshes in layout position. * * @return The refresh interval */ - unsigned int GetRefreshInterval() const; + float GetRefreshInterval() const; /** * @brief Given the Item ID, this returns the accompanying actor. diff --git a/capi/dali-toolkit/public-api/controls/scrollable/scroll-connector.h b/capi/dali-toolkit/public-api/controls/scrollable/scroll-connector.h index c03da89..0458d0d 100644 --- a/capi/dali-toolkit/public-api/controls/scrollable/scroll-connector.h +++ b/capi/dali-toolkit/public-api/controls/scrollable/scroll-connector.h @@ -38,9 +38,10 @@ class ScrollConnector; * - A "scroll-position" property which controls which part of the scrollable content is visible * - The minimum/maximum limits of the scroll position, which corresponds to the start & end points of the scollable list etc. * - An "overshoot" property which shows any attempts to exceed the start & end points. + * - The scrollable content size, which corresponds to the length of the scrollable content in the scrollable container in actor coordinates. * - * The provider of the scrollable content is responsible for calling SetLimits(). Scroll-bar components are then expected to - * receive these values via the LIMITS_CHANGED signal. + * The provider of the scrollable content is responsible for calling SetScrollDomain(). Scroll-bar components are then expected to + * receive these values via the DOMAIN_CHANGED signal. * * The scroll-position property is accessible via GetScrollPositionObject(). This is intended to be shared by multiple controls * e.g. a list control may be scrolled by panning the list content, or indirectly by dragging a connected scroll-bar control. @@ -60,8 +61,8 @@ public: static const Property::Index OVERSHOOT; ///< The index of the "overshoot" property // Signals - static const char* const LIMITS_CHANGED_SIGNAL_NAME; ///< "limits-changed" signal name - typedef SignalV2< void ( float min, float max ) > LimitsChangedSignalType; + static const char* const DOMAIN_CHANGED_SIGNAL_NAME; ///< "domain-changed" signal name + typedef SignalV2< void ( float min, float max, float size ) > DomainChangedSignalType; /** * Create a ScrollConnector. @@ -97,11 +98,12 @@ public: static ScrollConnector DownCast( BaseHandle handle ); /** - * Set The min/max values, corresponding to the start & end position of the scrollable content. - * @param[in] min The minimum value. - * @param[in] max The maximum value. + * Set the scroll domain, corresponding to the start & end position, and size of the scrollable content in actor coordinates. + * @param[in] min The minimum scroll position limit. + * @param[in] max The maximum scroll position limit. + * @param[in] length The length of the scrollable content in actor coordinates. */ - void SetLimits( float min, float max ); + void SetScrollDomain( float min, float max, float length ); /** * Retrieve the min limit. @@ -116,9 +118,15 @@ public: float GetMaxLimit() const; /** - * Signal emitted after the SetLimits() method has been called. + * Retrieve the length of the scrollable content in actor coordinates. + * @return The length of the scrollable content. */ - ScrollConnector::LimitsChangedSignalType& LimitsChangedSignal(); + float GetContentLength() const; + + /** + * Signal emitted after the SetScrollDomain() method has been called. + */ + ScrollConnector::DomainChangedSignalType& DomainChangedSignal(); /** * Retrieve the object which provides the "scroll-position" property. diff --git a/dali-toolkit/dali-toolkit.h b/dali-toolkit/dali-toolkit.h index 00f7bad..b4f8455 100644 --- a/dali-toolkit/dali-toolkit.h +++ b/dali-toolkit/dali-toolkit.h @@ -38,6 +38,8 @@ #include #include +#include +#include #include #include #include diff --git a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp new file mode 100755 index 0000000..f9473b9 --- /dev/null +++ b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp @@ -0,0 +1,332 @@ +// +// 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. +// + +#include + +using namespace Dali; + +namespace +{ + +const char* DEFAULT_INDICATOR_IMAGE_PATH = DALI_IMAGE_DIR "popup_scroll.png"; +const Vector4 DEFAULT_INDICATOR_NINE_PATCH_BORDER(0.0f, 12.0f, 14.0f, 14.0f); +const float DEFAULT_SLIDER_DEPTH(1.0f); +const float INDICATOR_SHOW_TIME(0.5f); +const float INDICATOR_HIDE_TIME(0.5f); + +/** + * Indicator size constraint + * Indicator size depends on both indicator's parent size and the scroll content size + */ +struct IndicatorSizeConstraint +{ + /** + * @param[in] contentSize The size of scrollable content + */ + IndicatorSizeConstraint(float contentSize) + : mContentSize(contentSize) + { + } + + /** + * Constraint operator + * @param[in] current The current indicator size + * @param[in] parentSizeProperty The parent size of scroll indicator. + * @return The new scroll indicator size. + */ + Vector3 operator()(const Vector3& current, + const PropertyInput& parentSizeProperty) + { + const Vector3& parentSize = parentSizeProperty.GetVector3(); + float height = mContentSize > parentSize.height ? parentSize.height * ( parentSize.height / mContentSize ) : parentSize.height * ( (parentSize.height - mContentSize * 0.5f) / parentSize.height); + return Vector3( parentSize.width, height, parentSize.depth ); + } + + float mContentSize; ///< The size of scrollable content +}; + +/** + * Indicator position constraint + * Positions the indicator to reflect the current scroll position within the scroll domain. + */ +struct IndicatorPositionConstraint +{ + /** + * @param[in] minPosition The minimum limit of scroll position + * @param[in] maxPosition the maximum limit of scroll position + */ + IndicatorPositionConstraint(float minPosition, float maxPosition) + : mMinPosition(minPosition), + mMaxPosition(maxPosition) + { + } + + /** + * Constraint operator + * @param[in] current The current indicator position + * @param[in] indicatorSizeProperty The size of indicator. + * @param[in] parentSizeProperty The parent size of indicator. + * @param[in] scrollPositionProperty The scroll position of the scrollable container // (from 0.0 -> 1.0 in each axis) + * @return The new indicator position is returned. + */ + Vector3 operator()(const Vector3& current, + const PropertyInput& indicatorSizeProperty, + const PropertyInput& parentSizeProperty, + const PropertyInput& scrollPositionProperty) + { + Vector3 indicatorSize = indicatorSizeProperty.GetVector3(); + Vector3 parentSize = parentSizeProperty.GetVector3(); + float scrollPosition = scrollPositionProperty.GetFloat(); + + const float domainSize = fabs(mMaxPosition - mMinPosition); + float relativePosition = (mMaxPosition - scrollPosition) / domainSize; + return Vector3(current.x, relativePosition * (parentSize.height - indicatorSize.height), DEFAULT_SLIDER_DEPTH); + } + + float mMinPosition; ///< The minimum scroll position + float mMaxPosition; ///< The maximum scroll position +}; + +} // unnamed namespace + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ + +using namespace Dali; + +BaseHandle Create() +{ + return BaseHandle(); +} + +TypeRegistration mType( typeid(Toolkit::ScrollBar), typeid(Toolkit::Control), Create ); + +} + +ScrollBar::ScrollBar() +: ControlImpl(true/*requires touch*/), + mScrollStart(0.0f) +{ +} + +ScrollBar::~ScrollBar() +{ +} + +void ScrollBar::OnInitialize() +{ + Actor self = Self(); + + Image indicatorImage = Image::New( DEFAULT_INDICATOR_IMAGE_PATH ); + mIndicator = ImageActor::New( indicatorImage ); + mIndicator.SetNinePatchBorder( DEFAULT_INDICATOR_NINE_PATCH_BORDER ); + mIndicator.SetStyle( ImageActor::STYLE_NINE_PATCH ); + mIndicator.SetParentOrigin( ParentOrigin::TOP_LEFT ); + mIndicator.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + self.Add(mIndicator); + + self.SetDrawMode(DrawMode::OVERLAY); + + // Enable the pan gesture which is attached to the control + EnableGestureDetection(Gesture::Type(Gesture::Pan)); +} + +void ScrollBar::SetScrollConnector( Toolkit::ScrollConnector connector ) +{ + if(mScrollConnector) + { + mScrollConnector.DomainChangedSignal().Disconnect(this, &ScrollBar::OnScrollDomainChanged); + } + + mScrollConnector = connector; + mScrollPositionObject = mScrollConnector.GetScrollPositionObject(); + + ApplyConstraints(); + mScrollConnector.DomainChangedSignal().Connect(this, &ScrollBar::OnScrollDomainChanged); +} + +void ScrollBar::SetBackgroundImage( Image image, const Vector4& border ) +{ + if (!mBackground ) + { + mBackground = ImageActor::New( image ); + mBackground.SetParentOrigin( ParentOrigin::TOP_LEFT ); + mBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + Self().Add(mBackground); + } + else + { + mBackground.SetImage(image); + } + + mBackground.SetNinePatchBorder( border ); + mBackground.SetStyle( ImageActor::STYLE_NINE_PATCH ); +} + +void ScrollBar::SetIndicatorImage( Image image, const Vector4& border ) +{ + mIndicator.SetImage(image); + mIndicator.SetNinePatchBorder( border ); + mIndicator.SetStyle( ImageActor::STYLE_NINE_PATCH ); +} + +Actor ScrollBar::GetScrollIndicator() +{ + return mIndicator; +} + +void ScrollBar::ApplyConstraints() +{ + mIndicator.RemoveConstraints(); + + Constraint constraint = Constraint::New( Actor::SIZE, + ParentSource( Actor::SIZE ), + IndicatorSizeConstraint( mScrollConnector.GetContentLength() ) ); + mIndicator.ApplyConstraint( constraint ); + + constraint = Constraint::New( Actor::POSITION, + LocalSource( Actor::SIZE ), + ParentSource( Actor::SIZE ), + Source( mScrollPositionObject, Toolkit::ScrollConnector::SCROLL_POSITION ), + IndicatorPositionConstraint( mScrollConnector.GetMinLimit(), mScrollConnector.GetMaxLimit() ) ); + mIndicator.ApplyConstraint( constraint ); + + if( mBackground ) + { + mBackground.RemoveConstraints(); + + constraint = Constraint::New(Actor::SIZE, + ParentSource(Actor::SIZE), + EqualToConstraint()); + mBackground.ApplyConstraint(constraint); + } +} + +void ScrollBar::SetPositionNotifications( const std::vector& positions ) +{ + if(mScrollPositionObject) + { + if(mPositionNotification) + { + mScrollPositionObject.RemovePropertyNotification(mPositionNotification); + } + mPositionNotification = mScrollPositionObject.AddPropertyNotification( Toolkit::ScrollConnector::SCROLL_POSITION, VariableStepCondition(positions) ); + mPositionNotification.NotifySignal().Connect( this, &ScrollBar::OnScrollPositionNotified ); + } +} + +void ScrollBar::OnScrollPositionNotified(PropertyNotification& source) +{ + // Emit the signal to notify the scroll position crossing + mScrollPositionNotifiedSignal.Emit(mScrollPositionObject.GetProperty( Toolkit::ScrollConnector::SCROLL_POSITION )); +} + +void ScrollBar::Show() +{ + // Cancel any animation + if(mAnimation) + { + mAnimation.Clear(); + mAnimation.Reset(); + } + + mAnimation = Animation::New( INDICATOR_SHOW_TIME ); + mAnimation.OpacityTo( Self(), 1.0f, AlphaFunctions::EaseIn ); + mAnimation.Play(); +} + +void ScrollBar::Hide() +{ + // Cancel any animation + if(mAnimation) + { + mAnimation.Clear(); + mAnimation.Reset(); + } + + mAnimation = Animation::New( INDICATOR_HIDE_TIME ); + mAnimation.OpacityTo( Self(), 0.0f, AlphaFunctions::EaseIn ); + mAnimation.Play(); +} + +void ScrollBar::OnPan( PanGesture gesture ) +{ + if(mScrollPositionObject) + { + switch(gesture.state) + { + case Gesture::Started: + { + Show(); + mScrollStart = mScrollPositionObject.GetProperty( Toolkit::ScrollConnector::SCROLL_POSITION ); + mGestureDisplacement = Vector3::ZERO; + break; + } + case Gesture::Continuing: + { + Vector3 delta(gesture.displacement.x, gesture.displacement.y, 0.0f); + mGestureDisplacement+=delta; + + Vector3 span = Self().GetCurrentSize() - mIndicator.GetCurrentSize(); + const float domainSize = fabs(mScrollConnector.GetMaxLimit() - mScrollConnector.GetMinLimit()); + float position = mScrollStart - mGestureDisplacement.y * domainSize / span.y; + position = std::min(mScrollConnector.GetMaxLimit(), std::max(position, mScrollConnector.GetMinLimit())); + mScrollPositionObject.SetProperty( Toolkit::ScrollConnector::SCROLL_POSITION, position ); + break; + } + default: + { + break; + } + } + } +} + +void ScrollBar::OnScrollDomainChanged(float minPosition, float maxPosition, float contentSize) +{ + // Reapply constraints when the scroll domain is changed + ApplyConstraints(); +} + +Toolkit::ScrollBar ScrollBar::New() +{ + // Create the implementation, temporarily owned by this handle on stack + IntrusivePtr< ScrollBar > impl = new ScrollBar(); + + // Pass ownership to CustomActor handle + Toolkit::ScrollBar handle( *impl ); + + // Second-phase init of the implementation + // This can only be done after the CustomActor connection has been made... + impl->Initialize(); + + return handle; +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h new file mode 100755 index 0000000..1da0474 --- /dev/null +++ b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h @@ -0,0 +1,189 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__ +#define __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__ + +// +// 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. +// + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +class ScrollBar; + +typedef IntrusivePtr ScrollBarPtr; + +/** + * ScrollBar is a UI component that can be added to the scrollable controls + * indicating the current scroll position of the scrollable content. + */ +class ScrollBar : public ControlImpl +{ + +public: + + typedef Toolkit::ScrollBar::ScrollPositionNotifiedSignalType ScrollPositionNotifiedSignalType; + +public: + + /** + * @copydoc Toolkit::ScrollBar::ScrollBar() + */ + ScrollBar(); + + /** + * @copydoc Toolkit::ScrollBar::~ScrollBar() + */ + virtual ~ScrollBar(); + + /** + * @copydoc Toolkit::ScrollBar::New() + */ + static Toolkit::ScrollBar New(); + + /** + * @copydoc Toolkit::ScrollBar::SetScrollConnector() + */ + void SetScrollConnector( Toolkit::ScrollConnector connector ); + + /** + * @copydoc Toolkit::ScrollBar::SetBackgroundImage() + */ + void SetBackgroundImage( Image image, const Vector4& border ); + + /** + * @copydoc Toolkit::ScrollBar::SetIndicatorImage() + */ + void SetIndicatorImage( Image image, const Vector4& border ); + + /** + * @copydoc Toolkit::ScrollBar::GetScrollIndicator() + */ + Actor GetScrollIndicator(); + + /** + * @copydoc Toolkit::ScrollBar::SetPositionNotifications() + */ + void SetPositionNotifications( const std::vector& positions ); + + /** + * @copydoc Toolkit::ScrollBar::Show() + */ + void Show(); + + /** + * @copydoc Toolkit::ScrollBar::Hide() + */ + void Hide(); + + /** + * Signal emitted after the SetScrollDomain() method has been called. + */ + ScrollPositionNotifiedSignalType& ScrollPositionNotifiedSignal() + { + return mScrollPositionNotifiedSignal; + } + +private: // from ControlImpl + + /** + * @copydoc Toolkit::Control::OnInitialize + */ + virtual void OnInitialize(); + + /** + * @copydoc Toolkit::Control::OnPan + */ + virtual void OnPan( PanGesture gesture ); + +private: + + /** + * Apply constraints for background and indicator. + * These constraints are based on values from the scroll connector. + */ + void ApplyConstraints(); + + /** + * Callback when the start & end position and size of the scrollable content are changed. + * @param[in] minPosition The minimum position. + * @param[in] maxPosition The maximum position. + * @param[in] contentSize The size of scrollable content. + */ + void OnScrollDomainChanged(float minPosition, float maxPosition, float contentSize); + + /** + * Callback when the current scroll position of the scrollable content goes above or + * below the values specified by SetPositionNotifications(). + * @param[in] source the property notification that triggered this callback + */ + void OnScrollPositionNotified(PropertyNotification& source); + +private: + + Toolkit::ScrollConnector mScrollConnector; ///< Connects scroll bar with the scrollable container. + Constrainable mScrollPositionObject; ///< From mScrollConnector + + ImageActor mBackground; ///< Background image of scroll bar. + ImageActor mIndicator; ///< Image of scroll indicator. + Animation mAnimation; ///< Scroll indicator Show/Hide Animation. + + float mScrollStart; ///< Scroll Start position (start of drag) + Vector3 mGestureDisplacement; ///< Gesture Displacement. + + Property::Index mPropertyIndicatorPosition; ///< Indicatore Position ("indicator-position") + + PropertyNotification mPositionNotification; ///< Stores the property notification used for scroll position changes + + ScrollPositionNotifiedSignalType mScrollPositionNotifiedSignal; +}; + +} // namespace Internal + +// Helpers for public-api forwarding methods + +inline Toolkit::Internal::ScrollBar& GetImpl(Toolkit::ScrollBar& scrollBar) +{ + DALI_ASSERT_ALWAYS(scrollBar); + + Dali::RefObject& handle = scrollBar.GetImplementation(); + + return static_cast(handle); +} + +inline const Toolkit::Internal::ScrollBar& GetImpl(const Toolkit::ScrollBar& scrollBar) +{ + DALI_ASSERT_ALWAYS(scrollBar); + + const Dali::RefObject& handle = scrollBar.GetImplementation(); + + return static_cast(handle); +} + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__ diff --git a/dali-toolkit/internal/controls/scroll-component/scroll-bar-impl.cpp b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal-impl.cpp similarity index 85% rename from dali-toolkit/internal/controls/scroll-component/scroll-bar-impl.cpp rename to dali-toolkit/internal/controls/scroll-component/scroll-bar-internal-impl.cpp index ca69446..408530d 100755 --- a/dali-toolkit/internal/controls/scroll-component/scroll-bar-impl.cpp +++ b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal-impl.cpp @@ -14,7 +14,7 @@ // limitations under the License. // -#include +#include #include using namespace Dali; @@ -44,10 +44,10 @@ const float BAR_HIDE_TIME(0.5f); const int SECOND_UNIT(1000); /** - * ScrollBar Visibility Constraint + * ScrollBarInternal Visibility Constraint * Returns whether scroll bar is visible */ -bool ScrollBarVisibilityConstraint(const bool& current, +bool ScrollBarInternalVisibilityConstraint(const bool& current, const PropertyInput& canScrollProperty) { bool canScroll = canScrollProperty.GetBoolean(); @@ -55,28 +55,28 @@ bool ScrollBarVisibilityConstraint(const bool& current, } /** - * ScrollBar Size Constraint - * Resize ScrollBar Size depends on both ScrollSize and DomainSize + * ScrollBarInternal Size Constraint + * Resize ScrollBarInternal Size depends on both ScrollSize and DomainSize */ -struct ScrollBarSizeConstraint +struct ScrollBarInternalSizeConstraint { /** * @param[in] vertical Whether this constraint controls a vertical scrollbar (true) * or a horizontal one (false) */ - ScrollBarSizeConstraint(bool vertical) + ScrollBarInternalSizeConstraint(bool vertical) : mVertical(vertical) { } /** * Constraint operator - * @param[in] current The current ScrollBar size + * @param[in] current The current ScrollBarInternal size * @param[in] scrollMinProperty The container's minimum position. * @param[in] scrollMaxProperty The container's maximum position. * @param[in] scrollDirectionProperty The container's scroll direction. * @param[in] scrollSizeProperty The container's size of viewport. - * @return The new ScrollBar position is returned. + * @return The new ScrollBarInternal position is returned. */ Vector3 operator()(const Vector3& current, const PropertyInput& scrollMinProperty, @@ -107,25 +107,25 @@ struct ScrollBarSizeConstraint }; /** - * ScrollBar rotation Constraint - * Rotate ScrollBar depends on the scroll direction + * ScrollBarInternal rotation Constraint + * Rotate ScrollBarInternal depends on the scroll direction */ -struct ScrollBarRotationConstraint +struct ScrollBarInternalRotationConstraint { /** * @param[in] vertical Whether this constraint controls a vertical scrollbar (true) * or a horizontal one (false) */ - ScrollBarRotationConstraint(bool vertical) + ScrollBarInternalRotationConstraint(bool vertical) : mVertical(vertical) { } /** * Constraint operator - * @param[in] current The current ScrollBar rotation + * @param[in] current The current ScrollBarInternal rotation * @param[in] scrollDirectionProperty The container's scroll direction. - * @return The new ScrollBar rotation is returned. + * @return The new ScrollBarInternal rotation is returned. */ Quaternion operator()(const Quaternion& current, const PropertyInput& scrollDirectionProperty) @@ -147,18 +147,18 @@ struct ScrollBarRotationConstraint }; /** - * ScrollBar Position Constraint + * ScrollBarInternal Position Constraint * Positions the scroll bar to reflect the current scroll position * within the domain. */ -struct ScrollBarPositionConstraint +struct ScrollBarInternalPositionConstraint { /** * @param[in] vertical Whether this constraint controls a vertical scrollbar (true) * or a horizontal one (false) * @param[in] wrap Whether to base scrollbar on original position or wrapped position */ - ScrollBarPositionConstraint(bool vertical, bool wrap = false) + ScrollBarInternalPositionConstraint(bool vertical, bool wrap = false) : mVertical(vertical), mWrap(wrap) { @@ -166,14 +166,14 @@ struct ScrollBarPositionConstraint /** * Constraint operator - * @param[in] current The current ScrollBar position - * @param[in] scrollBarSizeProperty ScrollBar size + * @param[in] current The current ScrollBarInternal position + * @param[in] scrollBarSizeProperty ScrollBarInternal size * @param[in] scrollRelativePositionProperty The container's relative position (from 0.0 -> 1.0 in each axis) * @param[in] scrollMinProperty The container's minimum position. * @param[in] scrollMaxProperty The container's maximum position. * @param[in] scrollDirectionProperty The container's scroll direction. * @param[in] scrollSizeProperty The container's size of viewport. - * @return The new ScrollBar position is returned. + * @return The new ScrollBarInternal position is returned. */ Vector3 operator()(const Vector3& current, const PropertyInput& scrollBarSizeProperty, @@ -276,17 +276,17 @@ struct ScrollBarPositionConstraint }; /** - * ScrollBar HitSize Constraint + * ScrollBarInternal HitSize Constraint * Resizes HitArea to size of the container. */ -struct ScrollBarHitSizeConstraint +struct ScrollBarInternalHitSizeConstraint { /** * @param[in] vertical Whether this constraint controls a vertical scrollbar (true) * or a horizontal one (false) * @param[in] thickness The thickness of the scrollbar */ - ScrollBarHitSizeConstraint(bool vertical, + ScrollBarInternalHitSizeConstraint(bool vertical, float thickness) : mVertical(vertical), mThickness(thickness) @@ -298,7 +298,7 @@ struct ScrollBarHitSizeConstraint * @param[in] current The current HitSize * @param[in] scrollDirectionProperty The container's scroll direction. * @param[in] scrollSizeProperty The container's size of viewport. - * @return The new ScrollBar Hit Area size is returned. + * @return The new ScrollBarInternal Hit Area size is returned. */ Vector3 operator()(const Vector3& current, const PropertyInput& scrollDirectionProperty, @@ -350,11 +350,11 @@ BaseHandle Create() return BaseHandle(); } -TypeRegistration mType( typeid(Toolkit::ScrollBar), typeid(Toolkit::ScrollComponent), Create ); +TypeRegistration mType( typeid(Toolkit::ScrollBarInternal), typeid(Toolkit::ScrollComponent), Create ); } -ScrollBar::ScrollBar(Toolkit::Scrollable& container, bool vertical) +ScrollBarInternal::ScrollBarInternal(Toolkit::Scrollable& container, bool vertical) : mContainer(static_cast(container.GetImplementation())), mVertical(vertical), mAxisMask(vertical ? Vector3::YAXIS : Vector3::XAXIS), @@ -381,7 +381,7 @@ ScrollBar::ScrollBar(Toolkit::Scrollable& container, bool vertical) Actor target = mContainer.Self(); Constraint constraint = Constraint::New( Actor::VISIBLE, Source( target, vertical ? target.GetPropertyIndex(Scrollable::SCROLLABLE_CAN_SCROLL_VERTICAL) : target.GetPropertyIndex(Scrollable::SCROLLABLE_CAN_SCROLL_HORIZONTAL)), - ScrollBarVisibilityConstraint ); + ScrollBarInternalVisibilityConstraint ); mSlider.ApplyConstraint( constraint ); mSliderWrap.ApplyConstraint( constraint ); @@ -390,13 +390,13 @@ ScrollBar::ScrollBar(Toolkit::Scrollable& container, bool vertical) Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_POSITION_MAX_PROPERTY_NAME ) ), Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_DIRECTION_PROPERTY_NAME ) ), Source( target, Actor::SIZE ), - ScrollBarSizeConstraint( vertical ) ); + ScrollBarInternalSizeConstraint( vertical ) ); mSlider.ApplyConstraint( constraint ); mSliderWrap.ApplyConstraint( constraint ); constraint = Constraint::New( Actor::ROTATION, Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_DIRECTION_PROPERTY_NAME ) ), - ScrollBarRotationConstraint( vertical ) ); + ScrollBarInternalRotationConstraint( vertical ) ); mSlider.ApplyConstraint( constraint ); mSliderWrap.ApplyConstraint( constraint ); @@ -407,7 +407,7 @@ ScrollBar::ScrollBar(Toolkit::Scrollable& container, bool vertical) Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_POSITION_MAX_PROPERTY_NAME ) ), Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_DIRECTION_PROPERTY_NAME ) ), Source( target, Actor::SIZE ), - ScrollBarPositionConstraint(vertical) ); + ScrollBarInternalPositionConstraint(vertical) ); mSlider.ApplyConstraint( constraint ); @@ -418,15 +418,15 @@ ScrollBar::ScrollBar(Toolkit::Scrollable& container, bool vertical) Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_POSITION_MAX_PROPERTY_NAME ) ), Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_DIRECTION_PROPERTY_NAME ) ), Source( target, Actor::SIZE ), - ScrollBarPositionConstraint(vertical, true) ); + ScrollBarInternalPositionConstraint(vertical, true) ); mSliderWrap.ApplyConstraint( constraint ); // Add Sliders to internal Actor, to avoid mixing up with regular // Actors added by user. mContainer.AddOverlay( mSlider ); mContainer.AddOverlay( mSliderWrap ); - mContainer.ScrollStartedSignal().Connect( this, &ScrollBar::OnStarted ); - mContainer.ScrollCompletedSignal().Connect( this, &ScrollBar::OnCompleted ); + mContainer.ScrollStartedSignal().Connect( this, &ScrollBarInternal::OnStarted ); + mContainer.ScrollCompletedSignal().Connect( this, &ScrollBarInternal::OnCompleted ); // Hit Area for dragging slider ///////////////////////////////////////////// mHitArea = Actor::New(); @@ -436,7 +436,7 @@ ScrollBar::ScrollBar(Toolkit::Scrollable& container, bool vertical) constraint = Constraint::New( Actor::SIZE, Source( target, target.GetPropertyIndex( Toolkit::Scrollable::SCROLL_DIRECTION_PROPERTY_NAME ) ), Source( target, Actor::SIZE ), - ScrollBarHitSizeConstraint(vertical, BAR_TAB_SIZE.width) ); + ScrollBarInternalHitSizeConstraint(vertical, BAR_TAB_SIZE.width) ); mHitArea.ApplyConstraint( constraint ); if(vertical) @@ -453,24 +453,24 @@ ScrollBar::ScrollBar(Toolkit::Scrollable& container, bool vertical) WaitingContractDelay(); } -ScrollBar::~ScrollBar() +ScrollBarInternal::~ScrollBarInternal() { DestructTimer(); } -void ScrollBar::OnInitialize() +void ScrollBarInternal::OnInitialize() { EnableGestureDetection(Gesture::Type(Gesture::Pan)); } -void ScrollBar::OnDisconnect() +void ScrollBarInternal::OnDisconnect() { // Disconnect all connected callback functions. mContainer.RemoveOverlay( mSlider ); mContainer.RemoveOverlay( mSliderWrap ); } -void ScrollBar::OnPanGesture(Actor actor, PanGesture gesture) +void ScrollBarInternal::OnPanGesture(Actor actor, PanGesture gesture) { switch(gesture.state) { @@ -503,7 +503,7 @@ void ScrollBar::OnPanGesture(Actor actor, PanGesture gesture) } } -void ScrollBar::OnStarted(const Vector3& position) +void ScrollBarInternal::OnStarted(const Vector3& position) { // TODO: Need to disable this for the scrollbar which isn't being scrolled. if(!mDragMode) @@ -513,7 +513,7 @@ void ScrollBar::OnStarted(const Vector3& position) } } -void ScrollBar::OnCompleted(const Vector3& position) +void ScrollBarInternal::OnCompleted(const Vector3& position) { if( mDragMode ) { @@ -523,7 +523,7 @@ void ScrollBar::OnCompleted(const Vector3& position) } } -bool ScrollBar::OnContractDelayExpired() +bool ScrollBarInternal::OnContractDelayExpired() { if ( !mDragMode ) { @@ -535,7 +535,7 @@ bool ScrollBar::OnContractDelayExpired() return true; } -void ScrollBar::Show() +void ScrollBarInternal::Show() { // Cancel any animation if(mAnimation) @@ -552,7 +552,7 @@ void ScrollBar::Show() DestructTimer(); } -void ScrollBar::Hide() +void ScrollBarInternal::Hide() { // Cancel any animation if(mAnimation) @@ -567,39 +567,39 @@ void ScrollBar::Hide() mAnimation.Play(); } -void ScrollBar::CreateTimer() +void ScrollBarInternal::CreateTimer() { if( !mTimer ) { // Create timer for contract delay mTimer = Timer::New( BAR_CONTRACT_DELAY * SECOND_UNIT ); - mTimer.TickSignal().Connect( this, &ScrollBar::OnContractDelayExpired ); + mTimer.TickSignal().Connect( this, &ScrollBarInternal::OnContractDelayExpired ); } } -void ScrollBar::DestructTimer() +void ScrollBarInternal::DestructTimer() { if( mTimer ) { mTimer.Stop(); - mTimer.TickSignal().Disconnect( this, &ScrollBar::OnContractDelayExpired ); + mTimer.TickSignal().Disconnect( this, &ScrollBarInternal::OnContractDelayExpired ); mTimer.Reset(); } } -void ScrollBar::WaitingContractDelay() +void ScrollBarInternal::WaitingContractDelay() { CreateTimer(); mTimer.Start(); } -Toolkit::ScrollBar ScrollBar::New(Toolkit::Scrollable& container, bool vertical) +Toolkit::ScrollBarInternal ScrollBarInternal::New(Toolkit::Scrollable& container, bool vertical) { // Create the implementation, temporarily owned by this handle on stack - IntrusivePtr< ScrollBar > impl = new ScrollBar( container, vertical ); + IntrusivePtr< ScrollBarInternal > impl = new ScrollBarInternal( container, vertical ); // Pass ownership to CustomActor handle - Toolkit::ScrollBar handle( *impl ); + Toolkit::ScrollBarInternal handle( *impl ); // Second-phase init of the implementation // This can only be done after the CustomActor connection has been made... diff --git a/dali-toolkit/internal/controls/scroll-component/scroll-bar-impl.h b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal-impl.h similarity index 76% rename from dali-toolkit/internal/controls/scroll-component/scroll-bar-impl.h rename to dali-toolkit/internal/controls/scroll-component/scroll-bar-internal-impl.h index 30248ca..22e92ff 100755 --- a/dali-toolkit/internal/controls/scroll-component/scroll-bar-impl.h +++ b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal-impl.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__ -#define __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__ +#ifndef __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_INTERNAL_H__ +#define __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_INTERNAL_H__ // // Copyright (c) 2014 Samsung Electronics Co., Ltd. @@ -20,7 +20,7 @@ // INTERNAL INCLUDES #include #include -#include +#include #include namespace Dali @@ -33,43 +33,43 @@ namespace Internal { /** - * ScrollBar is a UI component that can be added to the sides of the ScrollView + * ScrollBarInternal is a UI component that can be added to the sides of the ScrollView * indicating the current scroll position within the domain. */ -class ScrollBar : public ScrollComponent +class ScrollBarInternal : public ScrollComponent { public: /** - * ScrollBar constructor. + * ScrollBarInternal constructor. * @param[in] container Reference to the container of scroll bar - * @param[in] vertical Whether ScrollBar should be oriented vertically (true) + * @param[in] vertical Whether ScrollBarInternal should be oriented vertically (true) * or horizontally (false) */ - ScrollBar(Toolkit::Scrollable& container, bool vertical); + ScrollBarInternal(Toolkit::Scrollable& container, bool vertical); /** * Virtual destructor */ - virtual ~ScrollBar(); + virtual ~ScrollBarInternal(); /** - * Create an initialized ScrollBar + * Create an initialized ScrollBarInternal * @param[in] container Reference to the container of scroll bar - * @param[in] vertical Whether ScrollBar should be oriented vertically (true) + * @param[in] vertical Whether ScrollBarInternal should be oriented vertically (true) * or horizontally (false) - * @return A pointer to the created ScrollBar. + * @return A pointer to the created ScrollBarInternal. */ - static Toolkit::ScrollBar New(Toolkit::Scrollable& container, bool vertical); + static Toolkit::ScrollBarInternal New(Toolkit::Scrollable& container, bool vertical); /** - * Show ScrollBar + * Show ScrollBarInternal */ void Show(); /** - * Hide ScrollBar + * Hide ScrollBarInternal */ void Hide(); @@ -144,26 +144,26 @@ private: // Helpers for public-api forwarding methods -inline Toolkit::Internal::ScrollBar& GetImpl(Toolkit::ScrollBar& scrollBar) +inline Toolkit::Internal::ScrollBarInternal& GetImpl(Toolkit::ScrollBarInternal& scrollBar) { DALI_ASSERT_ALWAYS(scrollBar); Dali::RefObject& handle = scrollBar.GetImplementation(); - return static_cast(handle); + return static_cast(handle); } -inline const Toolkit::Internal::ScrollBar& GetImpl(const Toolkit::ScrollBar& scrollBar) +inline const Toolkit::Internal::ScrollBarInternal& GetImpl(const Toolkit::ScrollBarInternal& scrollBar) { DALI_ASSERT_ALWAYS(scrollBar); const Dali::RefObject& handle = scrollBar.GetImplementation(); - return static_cast(handle); + return static_cast(handle); } } // namespace Toolkit } // namespace Dali -#endif // __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__ +#endif // __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_INTERNAL_H__ diff --git a/dali-toolkit/internal/controls/scroll-component/scroll-bar.cpp b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal.cpp similarity index 55% rename from dali-toolkit/internal/controls/scroll-component/scroll-bar.cpp rename to dali-toolkit/internal/controls/scroll-component/scroll-bar-internal.cpp index 7abeb82..18189fe 100755 --- a/dali-toolkit/internal/controls/scroll-component/scroll-bar.cpp +++ b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal.cpp @@ -14,8 +14,8 @@ // limitations under the License. // -#include -#include +#include +#include namespace Dali { @@ -23,27 +23,27 @@ namespace Dali namespace Toolkit { -ScrollBar::ScrollBar() +ScrollBarInternal::ScrollBarInternal() { } -ScrollBar::ScrollBar(Internal::ScrollBar& implementation) +ScrollBarInternal::ScrollBarInternal(Internal::ScrollBarInternal& implementation) : ScrollComponent(implementation) { } -ScrollBar::ScrollBar( Dali::Internal::CustomActor* internal ) +ScrollBarInternal::ScrollBarInternal( Dali::Internal::CustomActor* internal ) : ScrollComponent( internal ) { - VerifyCustomActorPointer(internal); + VerifyCustomActorPointer(internal); } -ScrollBar::ScrollBar( const ScrollBar& scrollBar ) +ScrollBarInternal::ScrollBarInternal( const ScrollBarInternal& scrollBar ) : ScrollComponent(scrollBar) { } -ScrollBar& ScrollBar::operator=( const ScrollBar& scrollBar ) +ScrollBarInternal& ScrollBarInternal::operator=( const ScrollBarInternal& scrollBar ) { if( &scrollBar != this ) { @@ -52,26 +52,26 @@ ScrollBar& ScrollBar::operator=( const ScrollBar& scrollBar ) return *this; } -ScrollBar ScrollBar::New(Scrollable& container, bool vertical) +ScrollBarInternal ScrollBarInternal::New(Scrollable& container, bool vertical) { - return Internal::ScrollBar::New(container, vertical); + return Internal::ScrollBarInternal::New(container, vertical); } -ScrollBar ScrollBar::DownCast( BaseHandle handle ) +ScrollBarInternal ScrollBarInternal::DownCast( BaseHandle handle ) { - return Control::DownCast(handle); + return Control::DownCast(handle); } -ScrollBar::~ScrollBar() +ScrollBarInternal::~ScrollBarInternal() { } -void ScrollBar::Show() +void ScrollBarInternal::Show() { GetImpl(*this).Show(); } -void ScrollBar::Hide() +void ScrollBarInternal::Hide() { GetImpl(*this).Hide(); } diff --git a/dali-toolkit/internal/controls/scroll-component/scroll-bar.h b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal.h similarity index 61% rename from dali-toolkit/internal/controls/scroll-component/scroll-bar.h rename to dali-toolkit/internal/controls/scroll-component/scroll-bar-internal.h index 21c4a03..ea98a94 100755 --- a/dali-toolkit/internal/controls/scroll-component/scroll-bar.h +++ b/dali-toolkit/internal/controls/scroll-component/scroll-bar-internal.h @@ -1,5 +1,5 @@ -#ifndef __DALI_TOOLKIT_SCROLL_BAR_H__ -#define __DALI_TOOLKIT_SCROLL_BAR_H__ +#ifndef __DALI_TOOLKIT_SCROLL_BAR_INTERNAL_H__ +#define __DALI_TOOLKIT_SCROLL_BAR_INTERNAL_H__ // // Copyright (c) 2014 Samsung Electronics Co., Ltd. @@ -33,65 +33,65 @@ namespace Internal DALI_INTERNAL { // Forward declarations -class ScrollBar; +class ScrollBarInternal; } /** - * ScrollBar is a UI component that can be added to the sides of the scrollable controls + * ScrollBarInternal is a UI component that can be added to the sides of the scrollable controls * indicating the current scroll position. */ -class ScrollBar : public ScrollComponent +class ScrollBarInternal : public ScrollComponent { public: /** - * Create an uninitialized ScrollBar; this can be initialized with ScrollBar::New() + * Create an uninitialized ScrollBarInternal; this can be initialized with ScrollBarInternal::New() * Calling member functions with an uninitialized Dali::Object is not allowed. * or horizontally (false) */ - ScrollBar(); + ScrollBarInternal(); /** * Copy constructor. */ - ScrollBar( const ScrollBar& scrollBar ); + ScrollBarInternal( const ScrollBarInternal& scrollBar ); /** * Assignment operator. */ - ScrollBar& operator=( const ScrollBar& scrollBar ); + ScrollBarInternal& operator=( const ScrollBarInternal& scrollBar ); /** * Virtual destructor. * Dali::Object derived classes typically do not contain member data. */ - virtual ~ScrollBar(); + virtual ~ScrollBarInternal(); /** - * Create an initialized ScrollBar + * Create an initialized ScrollBarInternal * @param[in] container Reference to the container of scroll bar - * @param[in] vertical Whether ScrollBar should be oriented vertically (true) + * @param[in] vertical Whether ScrollBarInternal should be oriented vertically (true) * or horizontally (false) - * @return A pointer to the created ScrollBar. + * @return A pointer to the created ScrollBarInternal. */ - static ScrollBar New(Scrollable& container, bool vertical); + static ScrollBarInternal New(Scrollable& container, bool vertical); /** - * Downcast an Object handle to ScrollBar. If handle points to a ScrollBar the + * Downcast an Object handle to ScrollBarInternal. If handle points to a ScrollBarInternal the * downcast produces valid handle. If not the returned handle is left uninitialized. * @param[in] handle Handle to an object - * @return handle to a ScrollBar or an uninitialized handle + * @return handle to a ScrollBarInternal or an uninitialized handle */ - static ScrollBar DownCast( BaseHandle handle ); + static ScrollBarInternal DownCast( BaseHandle handle ); /** - * Show ScrollBar + * Show ScrollBarInternal */ void Show(); /** - * Hide ScrollBar + * Hide ScrollBarInternal */ void Hide(); @@ -101,17 +101,17 @@ public: // Not intended for application developers * Creates a handle using the Toolkit::Internal implementation. * @param[in] implementation The Control implementation. */ - ScrollBar( Internal::ScrollBar& implementation ); + ScrollBarInternal( Internal::ScrollBarInternal& implementation ); /** * Allows the creation of this Control from an Internal::CustomActor pointer. * @param[in] internal A pointer to the internal CustomActor. */ - ScrollBar( Dali::Internal::CustomActor* internal ); + ScrollBarInternal( Dali::Internal::CustomActor* internal ); }; } // namespace Toolkit } // namespace Dali -#endif // __DALI_TOOLKIT_SCROLL_BAR_H__ +#endif // __DALI_TOOLKIT_SCROLL_BAR_INTERNAL_H__ diff --git a/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.cpp b/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.cpp index ae0a22c..729ee54 100644 --- a/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.cpp +++ b/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.cpp @@ -16,7 +16,7 @@ // CLASS HEADER #include -#include +#include namespace Dali { @@ -57,12 +57,12 @@ Toolkit::ScrollComponent ScrollComponent::New(Toolkit::Scrollable& scrollable, T { case Toolkit::Scrollable::VerticalScrollBar: { - instance = static_cast(Toolkit::ScrollBar::New(scrollable, true)); + instance = static_cast(Toolkit::ScrollBarInternal::New(scrollable, true)); break; } case Toolkit::Scrollable::HorizontalScrollBar: { - instance = static_cast(Toolkit::ScrollBar::New(scrollable, false)); + instance = static_cast(Toolkit::ScrollBarInternal::New(scrollable, false)); break; } default: diff --git a/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.h b/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.h index cb33df4..2f93012 100644 --- a/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.h +++ b/dali-toolkit/internal/controls/scroll-component/scroll-component-impl.h @@ -39,8 +39,8 @@ typedef IntrusivePtr ScrollComponentPtr; /** * Base class for derived ScrollComponents - * ScrollComponents such as ScrollBar are derived from this class. - * To instantiate these ScrollBars and other derived components. + * ScrollComponents such as ScrollBarInternal are derived from this class. + * To instantiate these ScrollBarInternals and other derived components. */ class ScrollComponent : public ControlImpl { diff --git a/dali-toolkit/internal/controls/scroll-component/scroll-component.h b/dali-toolkit/internal/controls/scroll-component/scroll-component.h index ce63e64..640200a 100644 --- a/dali-toolkit/internal/controls/scroll-component/scroll-component.h +++ b/dali-toolkit/internal/controls/scroll-component/scroll-component.h @@ -34,8 +34,8 @@ class ScrollComponent; /** * Base class for derived ScrollComponents - * ScrollComponents such as ScrollBar are derived from this class. - * To instantiate these ScrollBars and other derived components + * ScrollComponents such as ScrollBarInternal are derived from this class. + * To instantiate these ScrollBarInternals and other derived components */ class ScrollComponent : public Control { 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 index 5f1f7b8..289290c 100644 --- a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp @@ -23,6 +23,7 @@ // INTERNAL INCLUDES #include #include +#include #include using namespace std; @@ -38,7 +39,7 @@ const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f; const float DEFAULT_MINIMUM_SWIPE_DISTANCE = 3.0f; const float DEFAULT_MOUSE_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = 0.1f; -const int DEFAULT_REFRESH_INTERVAL_MILLISECONDS = 50; // 20 updates per second +const float DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS = 20.0f; // 1 updates per 20 items const int MOUSE_WHEEL_EVENT_FINISHED_TIME_OUT = 500; // 0.5 second const float DEFAULT_ANCHORING_DURATION = 1.0f; // 1 second @@ -400,7 +401,7 @@ ItemView::ItemView(ItemFactory& factory) mAnimateOvershootOff(false), mAnchoringEnabled(true), mAnchoringDuration(DEFAULT_ANCHORING_DURATION), - mRefreshIntervalMilliseconds(DEFAULT_REFRESH_INTERVAL_MILLISECONDS), + mRefreshIntervalLayoutPositions(DEFAULT_REFRESH_INTERVAL_LAYOUT_POSITIONS), mRefreshOrderHint(true/*Refresh item 0 first*/), mMinimumSwipeSpeed(DEFAULT_MINIMUM_SWIPE_SPEED), mMinimumSwipeDistance(DEFAULT_MINIMUM_SWIPE_DISTANCE), @@ -409,7 +410,8 @@ ItemView::ItemView(ItemFactory& factory) mTotalPanDisplacement(Vector2::ZERO), mScrollOvershoot(0.0f), mIsFlicking(false), - mGestureState(Gesture::Clear) + mGestureState(Gesture::Clear), + mAddingItems(false) { SetRequiresMouseWheelEvents(true); SetKeyboardNavigationSupport(true); @@ -457,6 +459,8 @@ void ItemView::OnInitialize() mMouseWheelEventFinishedTimer = Timer::New( MOUSE_WHEEL_EVENT_FINISHED_TIME_OUT ); mMouseWheelEventFinishedTimer.TickSignal().Connect( this, &ItemView::OnMouseWheelEventFinished ); + + SetRefreshInterval(mRefreshIntervalLayoutPositions); } ItemView::~ItemView() @@ -619,8 +623,6 @@ void ItemView::DeactivateCurrentLayout() mActiveLayout = NULL; } - - CancelRefreshTimer(); } void ItemView::SetDefaultAlphaFunction(AlphaFunction func) @@ -633,22 +635,17 @@ AlphaFunction ItemView::GetDefaultAlphaFunction() const return mDefaultAlphaFunction; } -bool ItemView::OnRefreshTick() +void ItemView::OnRefreshNotification(PropertyNotification& source) { - // Short-circuit if there is no active layout - if (!mActiveLayout) + if (mActiveLayout) { - return false; - } - - ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, true/*reserve extra*/); + ItemRange range = GetItemRange(*mActiveLayout, mActiveLayoutTargetSize, true/*reserve extra*/); + RemoveActorsOutsideRange( range ); + AddActorsWithinRange( range, 0.0f/*immediate*/ ); - RemoveActorsOutsideRange( range ); - - AddActorsWithinRange( range, 0.0f/*immediate*/ ); - - // Keep refreshing whilst the layout is moving - return mScrollAnimation || (mGestureState == Gesture::Started || mGestureState == Gesture::Continuing); + Vector3 currentScrollPosition = GetCurrentScrollPosition(); + mScrollUpdatedSignalV2.Emit( currentScrollPosition ); + } } void ItemView::SetMinimumSwipeSpeed(float speed) @@ -701,14 +698,21 @@ float ItemView::GetAnchoringDuration() const return mAnchoringDuration; } -void ItemView::SetRefreshInterval(unsigned int intervalMilliseconds) +void ItemView::SetRefreshInterval(float intervalLayoutPositions) { - mRefreshIntervalMilliseconds = intervalMilliseconds; + mRefreshIntervalLayoutPositions = intervalLayoutPositions; + + if(mRefreshNotification) + { + mScrollPositionObject.RemovePropertyNotification(mRefreshNotification); + } + mRefreshNotification = mScrollPositionObject.AddPropertyNotification( ScrollConnector::SCROLL_POSITION, StepCondition(mRefreshIntervalLayoutPositions, 0.0f) ); + mRefreshNotification.NotifySignal().Connect( this, &ItemView::OnRefreshNotification ); } -unsigned int ItemView::GetRefreshInterval() const +float ItemView::GetRefreshInterval() const { - return mRefreshIntervalMilliseconds; + return mRefreshIntervalLayoutPositions; } Actor ItemView::GetItem(unsigned int itemId) const @@ -742,6 +746,8 @@ unsigned int ItemView::GetItemId( Actor actor ) const void ItemView::InsertItem( Item newItem, float durationSeconds ) { + mAddingItems = true; + SetupActor( newItem, durationSeconds ); Self().Add( newItem.second ); @@ -774,10 +780,16 @@ void ItemView::InsertItem( Item newItem, float durationSeconds ) { mItemPool.insert( newItem ); } + + CalculateDomainSize(Self().GetCurrentSize()); + + mAddingItems = false; } void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds ) { + mAddingItems = true; + // Insert from lowest id to highest set sortedItems; for( ConstItemIter iter = newItems.begin(); newItems.end() != iter; ++iter ) @@ -830,6 +842,10 @@ void ItemView::InsertItems( const ItemContainer& newItems, float durationSeconds ApplyConstraints( iter->second, *mActiveLayout, iter->first, durationSeconds ); } } + + CalculateDomainSize(Self().GetCurrentSize()); + + mAddingItems = false; } void ItemView::RemoveItem( unsigned int itemId, float durationSeconds ) @@ -902,6 +918,8 @@ bool ItemView::RemoveActor(unsigned int itemId) void ItemView::ReplaceItem( Item replacementItem, float durationSeconds ) { + mAddingItems = true; + SetupActor( replacementItem, durationSeconds ); Self().Add( replacementItem.second ); @@ -915,6 +933,10 @@ void ItemView::ReplaceItem( Item replacementItem, float durationSeconds ) { mItemPool.insert( replacementItem ); } + + CalculateDomainSize(Self().GetCurrentSize()); + + mAddingItems = false; } void ItemView::ReplaceItems( const ItemContainer& replacementItems, float durationSeconds ) @@ -964,10 +986,16 @@ void ItemView::AddActorsWithinRange( ItemRange range, float durationSeconds ) AddNewActor( itemId-1, durationSeconds ); } } + + // Total number of items may change dynamically. + // Always recalculate the domain size to reflect that. + CalculateDomainSize(Self().GetCurrentSize()); } void ItemView::AddNewActor( unsigned int itemId, float durationSeconds ) { + mAddingItems = true; + if( mItemPool.end() == mItemPool.find( itemId ) ) { Actor actor = mItemFactory.NewItem( itemId ); @@ -982,6 +1010,8 @@ void ItemView::AddNewActor( unsigned int itemId, float durationSeconds ) Self().Add( actor ); } } + + mAddingItems = false; } void ItemView::SetupActor( Item item, float durationSeconds ) @@ -1020,6 +1050,20 @@ ItemRange ItemView::GetItemRange(ItemLayout& layout, const Vector3& layoutSize, return range.Intersection(available); } +void ItemView::OnChildAdd(Actor& child) +{ + if(!mAddingItems) + { + // We don't want to do this downcast check for any item added by ItemView itself. + Dali::Toolkit::ScrollBar scrollBar = Dali::Toolkit::ScrollBar::DownCast(child); + if(scrollBar) + { + // Set the scroll connector when scroll bar is being added + scrollBar.SetScrollConnector(mScrollConnector); + } + } +} + bool ItemView::OnTouchEvent(const TouchEvent& event) { // Ignore events with multiple-touch points @@ -1061,7 +1105,6 @@ bool ItemView::OnMouseWheelEvent(const MouseWheelEvent& event) mScrollPositionObject.SetProperty( ScrollConnector::SCROLL_POSITION, firstItemScrollPosition ); self.SetProperty(mPropertyPosition, GetScrollPosition(firstItemScrollPosition, layoutSize)); mScrollStartedSignalV2.Emit(GetCurrentScrollPosition()); - StartRefreshTimer(); } if (mMouseWheelEventFinishedTimer.IsRunning()) @@ -1084,8 +1127,6 @@ bool ItemView::OnMouseWheelEventFinished() mScrollAnimation = DoAnchoring(); if (mScrollAnimation) { - StartRefreshTimer(); - mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished); mScrollAnimation.Play(); } @@ -1327,8 +1368,6 @@ void ItemView::OnPan(PanGesture gesture) { AnimateScrollOvershoot(0.0f); } - - StartRefreshTimer(); } break; @@ -1344,8 +1383,6 @@ void ItemView::OnPan(PanGesture gesture) if (mScrollAnimation) { - StartRefreshTimer(); - mScrollAnimation.FinishedSignal().Connect(this, &ItemView::OnScrollFinished); mScrollAnimation.Play(); } @@ -1467,36 +1504,12 @@ void ItemView::OnOvershootOnFinished(Animation& animation) } } -void ItemView::StartRefreshTimer() -{ - if (!mRefreshTimer) - { - mRefreshTimer = Timer::New( mRefreshIntervalMilliseconds ); - mRefreshTimer.TickSignal().Connect( this, &ItemView::OnRefreshTick ); - } - - if (!mRefreshTimer.IsRunning()) - { - mRefreshTimer.Start(); - } -} - -void ItemView::CancelRefreshTimer() -{ - if (mRefreshTimer) - { - mRefreshTimer.Stop(); - } -} - void ItemView::ScrollToItem(unsigned int itemId, float durationSeconds) { Actor self = Self(); const Vector3 layoutSize = Self().GetCurrentSize(); float firstItemScrollPosition = ClampFirstItemPosition(mActiveLayout->GetItemScrollToPosition(itemId), layoutSize, *mActiveLayout); - StartRefreshTimer(); - if(durationSeconds > 0.0f) { RemoveAnimation(mScrollAnimation); @@ -1541,23 +1554,31 @@ void ItemView::CalculateDomainSize(const Vector3& layoutSize) } float minLayoutPosition = mActiveLayout->GetMinimumLayoutPosition(mItemFactory.GetNumberOfItems(), layoutSize); + self.SetProperty(mPropertyMinimumLayoutPosition, minLayoutPosition); + ItemLayout::Vector3Function lastItemPositionConstraint; if (mActiveLayout->GetPositionConstraint(fabs(minLayoutPosition), lastItemPositionConstraint)) { lastItemPosition = lastItemPositionConstraint(Vector3::ZERO, fabs(minLayoutPosition), 0.0f, layoutSize); } + float domainSize; + if(IsHorizontal(mActiveLayout->GetOrientation())) { self.SetProperty(mPropertyPositionMin, Vector3(0.0f, firstItemPosition.x, 0.0f)); self.SetProperty(mPropertyPositionMax, Vector3(0.0f, lastItemPosition.x, 0.0f)); + domainSize = fabs(firstItemPosition.x - lastItemPosition.x); } else { self.SetProperty(mPropertyPositionMin, Vector3(0.0f, firstItemPosition.y, 0.0f)); self.SetProperty(mPropertyPositionMax, Vector3(0.0f, lastItemPosition.y, 0.0f)); + domainSize = fabs(firstItemPosition.y - lastItemPosition.y); } + mScrollConnector.SetScrollDomain(minLayoutPosition, 0.0f, domainSize); + bool isLayoutScrollable = IsLayoutScrollable(layoutSize); self.SetProperty(mPropertyCanScrollVertical, isLayoutScrollable); self.SetProperty(mPropertyCanScrollHorizontal, false); @@ -1620,8 +1641,6 @@ void ItemView::ScrollTo(const Vector3& position, float duration) float firstItemScrollPosition = ClampFirstItemPosition(position.y, layoutSize, *mActiveLayout); - StartRefreshTimer(); - if(duration > 0.0f) { RemoveAnimation(mScrollAnimation); diff --git a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h index 75022c7..038a567 100644 --- a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h +++ b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h @@ -171,12 +171,12 @@ public: /** * @copydoc Toolkit::ItemView::SetRefreshInterval */ - void SetRefreshInterval(unsigned int intervalMilliseconds); + void SetRefreshInterval(float intervalLayoutPositions); /** * @copydoc Toolkit::ItemView::GetRefreshInterval */ - unsigned int GetRefreshInterval() const; + float GetRefreshInterval() const; /** * @copydoc Toolkit::ItemView::GetItem @@ -282,6 +282,12 @@ private: private: // From CustomActorImpl /** + * From CustomActorImpl; called after a child has been added to the owning actor. + * @param[in] child The child which has been added. + */ + virtual void OnChildAdd(Actor& child); + + /** * From CustomActorImpl; called after a touch-signal is received by the owning actor. * @param[in] event The touch event. * @return True if the event should be consumed. @@ -421,23 +427,6 @@ private: void OnOvershootOnFinished(Animation& animation); /** - * Helper to start the refresh timer. - */ - void StartRefreshTimer(); - - /** - * Helper to cancel the refresh timer. - */ - void CancelRefreshTimer(); - - /** - * Refresh the ItemView; this is called after a timeout when scrolling. - * During a refresh, ItemFactory::NewItem() will be called to create newly visible items. - * @return True if the refresh timer should be kept running. - */ - bool OnRefreshTick(); - - /** * This is called after a timeout when no new mouse wheel event is received for a certain period of time. * @return will return false; one-shot timer. */ @@ -488,6 +477,14 @@ private: */ bool IsLayoutScrollable(const Vector3& layoutSize); + /** + * Callback when the current layout position of ItemView changes in both positive + * and negative directions by the specified amount. Refresh the ItemView to create + * newly visible items. + * @param[in] source the property notification that triggered this callback + */ + void OnRefreshNotification(PropertyNotification& source); + private: ItemFactory& mItemFactory; @@ -514,8 +511,8 @@ private: bool mAnchoringEnabled; float mAnchoringDuration; - Timer mRefreshTimer; - int mRefreshIntervalMilliseconds; + float mRefreshIntervalLayoutPositions; ///< Refresh item view when the layout position changes by this interval in both positive and negative directions. + PropertyNotification mRefreshNotification; // stores the property notification used for item view refresh bool mRefreshOrderHint; ///< True if scrolling towards the last item // Input handling @@ -541,6 +538,8 @@ private: Dali::Toolkit::ScrollConnector mScrollConnector; ///< Connects ItemView with scrollable components e.g. scroll bars Constrainable mScrollPositionObject; ///< From mScrollConnector + bool mAddingItems; + Property::Index mPropertyPosition; ///< The physical position of the first item within the layout Property::Index mPropertyMinimumLayoutPosition; ///< The minimum valid layout position in the layout. Property::Index mPropertyScrollSpeed; ///< The current scroll speed of item view diff --git a/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.cpp b/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.cpp index 1db9119..a001f0c 100644 --- a/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.cpp @@ -37,17 +37,19 @@ ScrollConnector* ScrollConnector::New() return new ScrollConnector(); } -void ScrollConnector::SetLimits( float min, float max ) +void ScrollConnector::SetScrollDomain( float min, float max, float length ) { mMinLimit = min; mMaxLimit = max; + mContentLength = length; - mLimitsChangedSignal.Emit( mMinLimit, mMaxLimit ); + mDomainChangedSignal.Emit( mMinLimit, mMaxLimit, mContentLength ); } ScrollConnector::ScrollConnector() : mMinLimit( 0.0f ), - mMaxLimit( 0.0f ) + mMaxLimit( 0.0f ), + mContentLength( 0.0f ) { mScrollPositionObject = Constrainable::New(); diff --git a/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.h b/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.h index 5d169b1..a5603a9 100644 --- a/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.h +++ b/dali-toolkit/internal/controls/scrollable/scroll-connector-impl.h @@ -36,7 +36,7 @@ class ScrollConnector : public Dali::BaseObject { public: - typedef Toolkit::ScrollConnector::LimitsChangedSignalType LimitsChangedSignalType; + typedef Toolkit::ScrollConnector::DomainChangedSignalType DomainChangedSignalType; static const Property::Index SCROLL_POSITION; static const Property::Index OVERSHOOT; @@ -48,9 +48,9 @@ public: static ScrollConnector* New(); /** - * @copydoc Toolkit::ScrollConnector::SetLimits() + * @copydoc Toolkit::ScrollConnector::SetScrollDomain() */ - void SetLimits( float min, float max ); + void SetScrollDomain( float min, float max, float length ); /** * @copydoc Toolkit::ScrollConnector::GetMinLimit() @@ -69,11 +69,19 @@ public: } /** - * Signal emitted after the SetLimits() method has been called. + * @copydoc Toolkit::ScrollConnector::GetContentLength() */ - LimitsChangedSignalType& LimitsChangedSignal() + float GetContentLength() const { - return mLimitsChangedSignal; + return mContentLength; + } + + /** + * Signal emitted after the SetScrollDomain() method has been called. + */ + DomainChangedSignalType& DomainChangedSignal() + { + return mDomainChangedSignal; } /** @@ -107,10 +115,11 @@ private: Constrainable mScrollPositionObject; - LimitsChangedSignalType mLimitsChangedSignal; + DomainChangedSignalType mDomainChangedSignal; float mMinLimit; float mMaxLimit; + float mContentLength; }; } // namespace Internal diff --git a/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp b/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp index 1421d3e..b506dd4 100644 --- a/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/scrollable-impl.cpp @@ -16,7 +16,7 @@ // INTERNAL INCLUDES #include -#include +#include using namespace Dali; diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 352076d..e190fe4 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -32,9 +32,10 @@ toolkit_src_files = \ $(toolkit_src_dir)/controls/page-turn-view/page-turn-landscape-view-impl.cpp \ $(toolkit_src_dir)/controls/popup/popup-impl.cpp \ $(toolkit_src_dir)/controls/popup/popup-style-impl.cpp \ - $(toolkit_src_dir)/controls/scroll-component/scroll-bar-impl.cpp \ + $(toolkit_src_dir)/controls/scroll-bar/scroll-bar-impl.cpp \ + $(toolkit_src_dir)/controls/scroll-component/scroll-bar-internal-impl.cpp \ $(toolkit_src_dir)/controls/scroll-component/scroll-component-impl.cpp \ - $(toolkit_src_dir)/controls/scroll-component/scroll-bar.cpp \ + $(toolkit_src_dir)/controls/scroll-component/scroll-bar-internal.cpp \ $(toolkit_src_dir)/controls/scroll-component/scroll-component.cpp \ $(toolkit_src_dir)/controls/scrollable/item-view/item-view-impl.cpp \ $(toolkit_src_dir)/controls/scrollable/scrollable-impl.cpp \ diff --git a/dali-toolkit/public-api/controls/control.cpp b/dali-toolkit/public-api/controls/control.cpp index 2022ce5..bf3d9cc 100644 --- a/dali-toolkit/public-api/controls/control.cpp +++ b/dali-toolkit/public-api/controls/control.cpp @@ -128,6 +128,26 @@ void Control::ClearKeyInputFocus() GetImplementation().ClearKeyInputFocus(); } +PinchGestureDetector Control::GetPinchGestureDetector() const +{ + return GetImplementation().GetPinchGestureDetector(); +} + +PanGestureDetector Control::GetPanGestureDetector() const +{ + return GetImplementation().GetPanGestureDetector(); +} + +TapGestureDetector Control::GetTapGestureDetector() const +{ + return GetImplementation().GetTapGestureDetector(); +} + +LongPressGestureDetector Control::GetLongPressGestureDetector() const +{ + return GetImplementation().GetLongPressGestureDetector(); +} + Control::KeyEventSignalV2& Control::KeyEventSignal() { return GetImplementation().KeyEventSignal(); diff --git a/dali-toolkit/public-api/controls/scroll-bar/scroll-bar.cpp b/dali-toolkit/public-api/controls/scroll-bar/scroll-bar.cpp new file mode 100755 index 0000000..8f93e2c --- /dev/null +++ b/dali-toolkit/public-api/controls/scroll-bar/scroll-bar.cpp @@ -0,0 +1,113 @@ +// +// 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. +// + +#include +#include + +namespace Dali +{ + +namespace Toolkit +{ + +const char* const ScrollBar::SCROLL_POSITION_NOTIFIED_SIGNAL_NAME = "scroll-position-notified"; + +ScrollBar::ScrollBar() +{ +} + +ScrollBar::ScrollBar(Internal::ScrollBar& implementation) +: Control( implementation ) +{ +} + +ScrollBar::ScrollBar( Dali::Internal::CustomActor* internal ) +: Control( internal ) +{ + VerifyCustomActorPointer(internal); +} + +ScrollBar::ScrollBar( const ScrollBar& scrollBar ) +: Control( scrollBar ) +{ +} + +ScrollBar& ScrollBar::operator=( const ScrollBar& scrollBar ) +{ + if( &scrollBar != this ) + { + Control::operator=( scrollBar ); + } + return *this; +} + +ScrollBar ScrollBar::New() +{ + return Internal::ScrollBar::New(); +} + +ScrollBar ScrollBar::DownCast( BaseHandle handle ) +{ + return Control::DownCast(handle); +} + +ScrollBar::~ScrollBar() +{ +} + +void ScrollBar::SetScrollConnector( ScrollConnector connector ) +{ + GetImpl(*this).SetScrollConnector(connector); +} + +void ScrollBar::SetBackgroundImage( Image image, const Vector4& border ) +{ + GetImpl(*this).SetBackgroundImage(image, border); +} + +void ScrollBar::SetIndicatorImage( Image image, const Vector4& border ) +{ + GetImpl(*this).SetIndicatorImage(image, border); +} + +Actor ScrollBar::GetScrollIndicator() +{ + return GetImpl(*this).GetScrollIndicator(); +} + +void ScrollBar::SetPositionNotifications( const std::vector& positions ) +{ + GetImpl(*this).SetPositionNotifications(positions); +} + +void ScrollBar::Show() +{ + GetImpl(*this).Show(); +} + +void ScrollBar::Hide() +{ + GetImpl(*this).Hide(); +} + +ScrollBar::ScrollPositionNotifiedSignalType& ScrollBar::ScrollPositionNotifiedSignal() +{ + return GetImpl(*this).ScrollPositionNotifiedSignal(); +} + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h b/dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h new file mode 100755 index 0000000..5adb04c --- /dev/null +++ b/dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h @@ -0,0 +1,191 @@ +#ifndef __DALI_TOOLKIT_SCROLL_BAR_H__ +#define __DALI_TOOLKIT_SCROLL_BAR_H__ + +// +// 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. +// + +// INTERNAL INCLUDES +#include +#include + +namespace Dali DALI_IMPORT_API +{ + +namespace Toolkit +{ + +// Forward declarations +class ScrollConnector; + +namespace Internal DALI_INTERNAL +{ +// Forward declarations + +class ScrollBar; +} + +/** + * ScrollBar is a UI component that can be added to the scrollable controls + * indicating the current scroll position of the scrollable content. + */ +class ScrollBar : public Control +{ +public: + + // Signals + static const char* const SCROLL_POSITION_NOTIFIED_SIGNAL_NAME; ///< "scroll-position-notified" signal name + typedef SignalV2< void ( float ) > ScrollPositionNotifiedSignalType; + +public: + + /** + * @brief Create an uninitialized ScrollBar; this can be initialized with ScrollBar::New() + * Calling member functions with an uninitialized Dali::Object is not allowed. + * or horizontally (false) + */ + ScrollBar(); + + /** + * @brief Copy constructor. + */ + ScrollBar( const ScrollBar& scrollBar ); + + /** + * @brief Assignment operator. + */ + ScrollBar& operator=( const ScrollBar& scrollBar ); + + /** + * @brief Virtual destructor. + * Dali::Object derived classes typically do not contain member data. + */ + virtual ~ScrollBar(); + + /** + * @brief Create an initialized ScrollBar + * @return A pointer to the created ScrollBar. + */ + static ScrollBar New(); + + /** + * @brief Downcast an Object handle to ScrollBar. If handle points to a ScrollBar the + * downcast produces valid handle. If not the returned handle is left uninitialized. + * @param[in] handle Handle to an object + * @return handle to a ScrollBar or an uninitialized handle + */ + static ScrollBar DownCast( BaseHandle handle ); + + /** + * @brief Sets the scroll connector for the scroll bar. + * + * @pre The scroll bar actor has been initialised. + * + * @param[in] connector Scroll connector used to connect scrollable container with this ScrollBar + */ + void SetScrollConnector( ScrollConnector connector ); + + /** + * @brief Sets the image for the background of scroll indicator. + * + * @pre The scroll bar actor has been initialised. + * + * The background image is resized (stretched according to scale settings), + * to the size of the ScrollBar. + * + * @param[in] image The image to cover background + * @param[in] border The nine patch border for the image. + */ + void SetBackgroundImage( Image image, const Vector4& border ); + + /** + * @brief Sets the image for the indicator of scroll bar. + * + * @pre The scroll bar actor has been initialised. + * + * The indicator image is resized (stretched according to scale settings), + * to reflect the size of the scroll indicator and minimum/maximum limits + * of the scroll position. + * + * @param[in] image The image of indicator that moves to indicate the current scroll position. + * @param[in] border The nine patch border for the image. + */ + void SetIndicatorImage( Image image, const Vector4& border ); + + /** + * @brief Gets the indicator of scroll bar. + * + * @pre The scroll bar actor has been initialised. + * + * The indicator indicates the current scroll position of the scrollable content. + */ + Actor GetScrollIndicator(); + + /** + * @brief Sets the values to get notification when the current scroll position of the scrollable + * content goes above or below any of these values. + * + * @pre The scroll bar actor has been initialised. + * + * @param[in] positions List of values to receive notifications for when the current scroll position crosses them + */ + void SetPositionNotifications( const std::vector& positions ); + + /** + * @brief Shows the scroll indicator + */ + void Show(); + + /** + * @brief Hides the scroll indicator + */ + void Hide(); + + /** + * @brief Signal emitted when the current scroll position of the scrollable content goes above or below the values + * specified by SetPositionNotifications. + * + * A callback of the following type may be connected: + * @code + * void YourCallbackName(float currentScrollPosition); + * @endcode + * @pre The Object has been initialized. + * @return The signal to connect to. + */ + ScrollBar::ScrollPositionNotifiedSignalType& ScrollPositionNotifiedSignal(); + +public: // Not intended for application developers + + /** + * Creates a handle using the Toolkit::Internal implementation. + * @param[in] implementation The Control implementation. + */ + ScrollBar( Internal::ScrollBar& implementation ); + + /** + * Allows the creation of this Control from an Internal::CustomActor pointer. + * @param[in] internal A pointer to the internal CustomActor. + */ + ScrollBar( Dali::Internal::CustomActor* internal ); +}; + +} // namespace Toolkit + +} // namespace Dali + +/** + * @} + */ +#endif // __DALI_TOOLKIT_SCROLL_BAR_H__ diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/item-view.cpp b/dali-toolkit/public-api/controls/scrollable/item-view/item-view.cpp index eff45ac..d9f856e 100644 --- a/dali-toolkit/public-api/controls/scrollable/item-view/item-view.cpp +++ b/dali-toolkit/public-api/controls/scrollable/item-view/item-view.cpp @@ -177,12 +177,12 @@ void ItemView::ScrollToItem(unsigned int itemId, float durationSeconds) GetImpl(*this).ScrollToItem(itemId, durationSeconds); } -void ItemView::SetRefreshInterval(unsigned int intervalMilliseconds) +void ItemView::SetRefreshInterval(float intervalLayoutPositions) { - GetImpl(*this).SetRefreshInterval(intervalMilliseconds); + GetImpl(*this).SetRefreshInterval(intervalLayoutPositions); } -unsigned int ItemView::GetRefreshInterval() const +float ItemView::GetRefreshInterval() const { return GetImpl(*this).GetRefreshInterval(); } diff --git a/dali-toolkit/public-api/controls/scrollable/scroll-connector.cpp b/dali-toolkit/public-api/controls/scrollable/scroll-connector.cpp index 97721b2..ef55cdb 100644 --- a/dali-toolkit/public-api/controls/scrollable/scroll-connector.cpp +++ b/dali-toolkit/public-api/controls/scrollable/scroll-connector.cpp @@ -31,7 +31,7 @@ const char* const ScrollConnector::OVERSHOOT_PROPERTY_NAME = "overshoot"; const Property::Index ScrollConnector::SCROLL_POSITION = Internal::ScrollConnector::SCROLL_POSITION; const Property::Index ScrollConnector::OVERSHOOT = Internal::ScrollConnector::OVERSHOOT; -const char* const ScrollConnector::LIMITS_CHANGED_SIGNAL_NAME = "limits-changed"; +const char* const ScrollConnector::DOMAIN_CHANGED_SIGNAL_NAME = "domain-changed"; ScrollConnector ScrollConnector::New() { @@ -56,9 +56,9 @@ ScrollConnector ScrollConnector::DownCast( BaseHandle handle ) return ScrollConnector( dynamic_cast(handle.GetObjectPtr()) ); } -void ScrollConnector::SetLimits( float min, float max ) +void ScrollConnector::SetScrollDomain( float min, float max, float length ) { - GetImpl(*this).SetLimits( min, max ); + GetImpl(*this).SetScrollDomain( min, max, length ); } float ScrollConnector::GetMinLimit() const @@ -71,14 +71,19 @@ float ScrollConnector::GetMaxLimit() const return GetImpl(*this).GetMaxLimit(); } +float ScrollConnector::GetContentLength() const +{ + return GetImpl(*this).GetContentLength(); +} + Constrainable ScrollConnector::GetScrollPositionObject() const { return GetImpl(*this).GetScrollPositionObject(); } -ScrollConnector::LimitsChangedSignalType& ScrollConnector::LimitsChangedSignal() +ScrollConnector::DomainChangedSignalType& ScrollConnector::DomainChangedSignal() { - return GetImpl(*this).LimitsChangedSignal(); + return GetImpl(*this).DomainChangedSignal(); } ScrollConnector::ScrollConnector( Internal::ScrollConnector* impl ) diff --git a/dali-toolkit/public-api/file.list b/dali-toolkit/public-api/file.list index 670ffe0..7942f20 100755 --- a/dali-toolkit/public-api/file.list +++ b/dali-toolkit/public-api/file.list @@ -24,6 +24,7 @@ public_api_src_files = \ $(public_api_src_dir)/controls/page-turn-view/page-turn-portrait-view.cpp \ $(public_api_src_dir)/controls/page-turn-view/page-turn-landscape-view.cpp \ $(public_api_src_dir)/controls/popup/popup.cpp \ + $(public_api_src_dir)/controls/scroll-bar/scroll-bar.cpp \ $(public_api_src_dir)/controls/scrollable/item-view/item-factory.cpp \ $(public_api_src_dir)/controls/scrollable/item-view/item-layout.cpp \ $(public_api_src_dir)/controls/scrollable/item-view/item-view.cpp \ @@ -152,6 +153,9 @@ public_api_scroll_component_header_files = public_api_scrollable_header_files = +public_api_scroll_bar_header_files = \ + $(public_api_src_dir)/controls/scroll-bar/scroll-bar.h + public_api_scroll_view_header_files = \ $(public_api_src_dir)/controls/scrollable/scroll-view/scroll-view-constraints.h \ $(public_api_src_dir)/controls/scrollable/scroll-view/scroll-view-carousel-effect.h \ -- 2.7.4