Added ScrollBar Indicator minimum size and padding properties 14/71514/4
authorTom Robinson <tom.robinson@samsung.com>
Wed, 25 May 2016 15:14:35 +0000 (16:14 +0100)
committerTom Robinson <tom.robinson@samsung.com>
Wed, 25 May 2016 17:49:14 +0000 (10:49 -0700)
These 3 properties are floats, and can be set as follows (these are examples only):
scrollBar.SetProperty( ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT, 20 );
scrollBar.SetProperty( ScrollBar::Property::INDICATOR_START_PADDING, 10 );
scrollBar.SetProperty( ScrollBar::Property::INDICATOR_END_PADDING, 10 );

Note: With a Vertical ScrollBar Direction: START and END padding properties refer to Top and Bottom respectively.

The defaults for all 3 properties is 0.

Change-Id: I79d9b28f36cca29a0e9115839cc5a5c70691bf65

dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h
dali-toolkit/public-api/controls/scroll-bar/scroll-bar.h

index 120dcb7..f10dfb5 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -28,7 +28,6 @@
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/integration-api/debug.h>
 
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h>
 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
@@ -39,12 +38,14 @@ namespace
 {
 
 const char* DEFAULT_INDICATOR_IMAGE_PATH = DALI_IMAGE_DIR "popup_scroll.9.png";
-const float MINIMUM_INDICATOR_HEIGHT(20.0f); // The minimum indicator height for the nine patch border
 const float DEFAULT_SLIDER_DEPTH(1.0f);
 const float DEFAULT_INDICATOR_SHOW_DURATION(0.5f);
 const float DEFAULT_INDICATOR_HIDE_DURATION(0.5f);
 const float DEFAULT_PAN_GESTURE_PROCESS_TIME(16.7f); // 16.7 milliseconds, i.e. one frame
 const float DEFAULT_INDICATOR_FIXED_HEIGHT(80.0f);
+const float DEFAULT_INDICATOR_MINIMUM_HEIGHT(0.0f);
+const float DEFAULT_INDICATOR_START_PADDING(0.0f);
+const float DEFAULT_INDICATOR_END_PADDING(0.0f);
 
 /**
  * Indicator size constraint
@@ -52,7 +53,13 @@ const float DEFAULT_INDICATOR_FIXED_HEIGHT(80.0f);
  */
 struct IndicatorSizeConstraint
 {
-  IndicatorSizeConstraint()
+  /**
+   * @param[in] minimumHeight The minimum height for the indicator
+   * @param[in] padding The sum of the padding at the start & end of the indicator
+   */
+  IndicatorSizeConstraint( float minimumHeight, float padding )
+  : mMinimumHeight( minimumHeight ),
+    mPadding( padding )
   {
   }
 
@@ -62,17 +69,23 @@ struct IndicatorSizeConstraint
    * @param[in] parentSizeProperty The parent size of scroll indicator.
    * @return The new scroll indicator size.
    */
-  void operator()(Vector3& current, const PropertyInputContainer& inputs )
+  void operator()( Vector3& current, const PropertyInputContainer& inputs )
   {
     const Vector3& parentSize = inputs[0]->GetVector3();
     const float contentSize = inputs[1]->GetFloat();
 
-    float height = contentSize > parentSize.height ?
-                   parentSize.height * ( parentSize.height / contentSize ) :
-                   parentSize.height * ( (parentSize.height - contentSize * 0.5f) / parentSize.height);
+    // Take into account padding that may exist at the beginning and end of the indicator.
+    const float parentHeightMinusPadding = parentSize.height - mPadding;
 
-    current.y = std::max(MINIMUM_INDICATOR_HEIGHT, height);
+    float height = contentSize > parentHeightMinusPadding ?
+                   parentHeightMinusPadding * ( parentHeightMinusPadding / contentSize ) :
+                   parentHeightMinusPadding * ( ( parentHeightMinusPadding - contentSize * 0.5f ) / parentHeightMinusPadding );
+
+    current.y = std::max( mMinimumHeight, height );
   }
+
+  float mMinimumHeight;
+  float mPadding;
 };
 
 /**
@@ -82,10 +95,12 @@ struct IndicatorSizeConstraint
 struct IndicatorPositionConstraint
 {
   /**
-   * @param[in] minPosition The minimum limit of scroll position
-   * @param[in] maxPosition the maximum limit of scroll position
+   * @param[in] startPadding The padding at the start of the indicator
+   * @param[in] endPadding The padding at the end of the indicator
    */
-  IndicatorPositionConstraint()
+  IndicatorPositionConstraint( float startPadding, float endPadding )
+  : mStartPadding( startPadding ),
+    mEndPadding( endPadding )
   {
   }
 
@@ -100,13 +115,19 @@ struct IndicatorPositionConstraint
     const Vector3& indicatorSize = inputs[0]->GetVector3();
     const Vector3& parentSize = inputs[1]->GetVector3();
     const float scrollPosition = -inputs[2]->GetFloat();
-    const float minScrollPosition = inputs[3]->GetFloat();
-    const float maxScrollPosition = inputs[4]->GetFloat();
+    const float minimumScrollPosition = inputs[3]->GetFloat();
+    const float maximumScrollPosition = inputs[4]->GetFloat();
 
-    float relativePosition = std::max( 0.0f, std::min( 1.0f, (scrollPosition - minScrollPosition) / (maxScrollPosition - minScrollPosition) ) );
-    current.y = ( parentSize.height - indicatorSize.height ) * relativePosition;
+    // Take into account padding that may exist at the beginning and end of the indicator.
+    const float parentHeightMinusPadding = parentSize.height - ( mStartPadding + mEndPadding );
+
+    float relativePosition = std::max( 0.0f, std::min( 1.0f, ( scrollPosition - minimumScrollPosition ) / ( maximumScrollPosition - minimumScrollPosition ) ) );
+    current.y = mStartPadding + ( parentHeightMinusPadding - indicatorSize.height ) * relativePosition;
     current.z = DEFAULT_SLIDER_DEPTH;
   }
+
+  float mStartPadding;
+  float mEndPadding;
 };
 
 } // unnamed namespace
@@ -139,6 +160,9 @@ DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorFixedHeight",
 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorShowDuration",             FLOAT,  INDICATOR_SHOW_DURATION   )
 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorHideDuration",             FLOAT,  INDICATOR_HIDE_DURATION   )
 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "scrollPositionIntervals",           ARRAY,  SCROLL_POSITION_INTERVALS )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorMinimumHeight",            FLOAT,  INDICATOR_MINIMUM_HEIGHT  )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorStartPadding",             FLOAT,  INDICATOR_START_PADDING   )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorEndPadding",               FLOAT,  INDICATOR_END_PADDING     )
 
 DALI_SIGNAL_REGISTRATION(   Toolkit, ScrollBar, "panFinished",                       PAN_FINISHED_SIGNAL )
 DALI_SIGNAL_REGISTRATION(   Toolkit, ScrollBar, "scrollPositionIntervalReached",     SCROLL_POSITION_INTERVAL_REACHED_SIGNAL )
@@ -165,6 +189,9 @@ ScrollBar::ScrollBar(Toolkit::ScrollBar::Direction direction)
   mCurrentScrollPosition(0.0f),
   mIndicatorHeightPolicy(Toolkit::ScrollBar::Variable),
   mIndicatorFixedHeight(DEFAULT_INDICATOR_FIXED_HEIGHT),
+  mIndicatorMinimumHeight(DEFAULT_INDICATOR_MINIMUM_HEIGHT),
+  mIndicatorStartPadding(DEFAULT_INDICATOR_START_PADDING),
+  mIndicatorEndPadding(DEFAULT_INDICATOR_END_PADDING),
   mIsPanning(false),
   mIndicatorFirstShow(true)
 {
@@ -265,7 +292,8 @@ void ScrollBar::ApplyConstraints()
     }
     else
     {
-      mIndicatorSizeConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::SIZE, IndicatorSizeConstraint() );
+      mIndicatorSizeConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::SIZE,
+                                                           IndicatorSizeConstraint( mIndicatorMinimumHeight, mIndicatorStartPadding + mIndicatorEndPadding ) );
       mIndicatorSizeConstraint.AddSource( ParentSource( Actor::Property::SIZE ) );
       mIndicatorSizeConstraint.AddSource( Source( scrollableHandle, mPropertyScrollContentSize ) );
       mIndicatorSizeConstraint.Apply();
@@ -276,7 +304,8 @@ void ScrollBar::ApplyConstraints()
       mIndicatorPositionConstraint.Remove();
     }
 
-    mIndicatorPositionConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::POSITION, IndicatorPositionConstraint() );
+    mIndicatorPositionConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::POSITION,
+                                                             IndicatorPositionConstraint( mIndicatorStartPadding, mIndicatorEndPadding ) );
     mIndicatorPositionConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
     mIndicatorPositionConstraint.AddSource( ParentSource( Actor::Property::SIZE ) );
     mIndicatorPositionConstraint.AddSource( Source( scrollableHandle, mPropertyScrollPosition ) );
@@ -409,16 +438,18 @@ void ScrollBar::OnPan( const PanGesture& gesture )
       }
       case Gesture::Continuing:
       {
-        Vector3 delta(gesture.displacement.x, gesture.displacement.y, 0.0f);
-        mGestureDisplacement+=delta;
+        mGestureDisplacement.x += gesture.displacement.x;
+        mGestureDisplacement.y += gesture.displacement.y;
 
-        Vector3 span = Self().GetCurrentSize() - mIndicator.GetCurrentSize();
-        float minScrollPosition = scrollableHandle.GetProperty<float>(mPropertyMinScrollPosition);
-        float maxScrollPosition = scrollableHandle.GetProperty<float>(mPropertyMaxScrollPosition);
+        float minScrollPosition = scrollableHandle.GetProperty<float>( mPropertyMinScrollPosition );
+        float maxScrollPosition = scrollableHandle.GetProperty<float>( mPropertyMaxScrollPosition );
+
+        // The domain size is the internal range
         float domainSize = maxScrollPosition - minScrollPosition;
+        float logicalSize = Self().GetCurrentSize().y - ( mIndicator.GetCurrentSize().y + mIndicatorStartPadding + mIndicatorEndPadding );
 
-        mCurrentScrollPosition = mScrollStart - mGestureDisplacement.y * domainSize / span.y;
-        mCurrentScrollPosition = 0.0f - std::min(maxScrollPosition, std::max(-mCurrentScrollPosition, minScrollPosition));
+        mCurrentScrollPosition = mScrollStart - ( ( mGestureDisplacement.y * domainSize ) / logicalSize );
+        mCurrentScrollPosition = -std::min( maxScrollPosition, std::max( -mCurrentScrollPosition, minScrollPosition ) );
 
         break;
       }
@@ -474,8 +505,11 @@ Toolkit::ScrollBar::Direction ScrollBar::GetScrollDirection() const
 
 void ScrollBar::SetIndicatorHeightPolicy( Toolkit::ScrollBar::IndicatorHeightPolicy policy )
 {
-  mIndicatorHeightPolicy = policy;
-  ApplyConstraints();
+  if( policy != mIndicatorHeightPolicy )
+  {
+    mIndicatorHeightPolicy = policy;
+    ApplyConstraints();
+  }
 }
 
 Toolkit::ScrollBar::IndicatorHeightPolicy ScrollBar::GetIndicatorHeightPolicy() const
@@ -627,6 +661,24 @@ void ScrollBar::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
+      {
+        scrollBarImpl.mIndicatorMinimumHeight = value.Get<float>();
+        scrollBarImpl.ApplyConstraints();
+        break;
+      }
+      case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
+      {
+        scrollBarImpl.mIndicatorStartPadding = value.Get<float>();
+        scrollBarImpl.ApplyConstraints();
+        break;
+      }
+      case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
+      {
+        scrollBarImpl.mIndicatorEndPadding = value.Get<float>();
+        scrollBarImpl.ApplyConstraints();
+        break;
+      }
     }
   }
 }
@@ -683,6 +735,21 @@ Property::Value ScrollBar::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
+      case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
+      {
+        value = scrollBarImpl.mIndicatorMinimumHeight;
+        break;
+      }
+      case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
+      {
+        value = scrollBarImpl.mIndicatorStartPadding;
+        break;
+      }
+      case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
+      {
+        value = scrollBarImpl.mIndicatorEndPadding;
+        break;
+      }
     }
   }
   return value;
index ff9e07d..0826ef3 100755 (executable)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_INTERNAL_SCROLL_BAR_H__
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -269,28 +269,31 @@ private:
 
   Toolkit::ScrollBar::Direction mDirection;                          ///< The direction of scroll bar (vertical or horizontal)
 
-  WeakHandleBase mScrollableObject;                                      ///< Object to be scrolled
+  WeakHandleBase mScrollableObject;                                  ///< Object to be scrolled
 
   Property::Index mPropertyScrollPosition;                           ///< Index of scroll position property owned by the object to be scrolled
   Property::Index mPropertyMinScrollPosition;                        ///< Index of minimum scroll position property owned by the object to be scrolled
   Property::Index mPropertyMaxScrollPosition;                        ///< Index of maximum scroll position property owned by the object to be scrolled
   Property::Index mPropertyScrollContentSize;                        ///< Index of scroll content size property owned by the object to be scrolled
 
-  float mIndicatorShowDuration;                                     ///< The duration of scroll indicator show animation
-  float mIndicatorHideDuration;                                     ///< The duration of scroll indicator hide animation
+  float mIndicatorShowDuration;                                      ///< The duration of scroll indicator show animation
+  float mIndicatorHideDuration;                                      ///< The duration of scroll indicator hide animation
 
   float mScrollStart;                                                ///< Scroll Start position (start of drag)
   Vector3 mGestureDisplacement;                                      ///< Gesture Displacement.
 
-  float mCurrentScrollPosition;                                     ///< The current scroll position updated by the pan gesture
+  float mCurrentScrollPosition;                                      ///< The current scroll position updated by the pan gesture
 
   Toolkit::ScrollBar::IndicatorHeightPolicy mIndicatorHeightPolicy;  ///< The height policy of scroll indicator (variable or fixed)
-  float mIndicatorFixedHeight;                                      ///< The fixed height of scroll indicator
+  float mIndicatorFixedHeight;                                       ///< The fixed height of scroll indicator
+  float mIndicatorMinimumHeight;                                     ///< The minimum height for a variable size indicator
+  float mIndicatorStartPadding;                                      ///< The padding at the start of the indicator
+  float mIndicatorEndPadding;                                        ///< The padding at the end of the indicator
 
   Timer mContractDelayTimer;                                         ///< Timer guarantee contract delay time.
   Timer mPanProcessTimer;                                            ///< The timer to process the pan gesture after the gesture is started.
 
-  Dali::Vector<float> mScrollPositionIntervals;                     ///< List of values to receive notification for when the current scroll position goes above or below them
+  Dali::Vector<float> mScrollPositionIntervals;                      ///< List of values to receive notification for when the current scroll position goes above or below them
   PropertyNotification mPositionNotification;                        ///< Stores the property notification used for scroll position changes
 
   PanFinishedSignalType mPanFinishedSignal;
@@ -300,8 +303,8 @@ private:
   Constraint mIndicatorSizeConstraint;
   Constraint mScrollPositionInCurrentAxisConstraint;
 
-  bool mIsPanning          : 1;                                      ///< Whether the scroll bar is being panned.
-  bool mIndicatorFirstShow : 1;                                      ///< True if the indicator has never been shown
+  bool mIsPanning                 : 1;                               ///< Whether the scroll bar is being panned.
+  bool mIndicatorFirstShow        : 1;                               ///< True if the indicator has never been shown
 };
 
 } // namespace Internal
index 5610934..f8cbfea 100755 (executable)
@@ -2,7 +2,7 @@
 #define __DALI_TOOLKIT_SCROLL_BAR_H__
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -73,12 +73,60 @@ public:
   {
     enum
     {
-      SCROLL_DIRECTION = PROPERTY_START_INDEX, ///< name "scrollDirection",          @see SetScrollDirection(),        type std::string @SINCE_1_0.0
-      INDICATOR_HEIGHT_POLICY,                 ///< name "indicatorHeightPolicy",    @see SetIndicatorHeightPolicy(),  type std::string @SINCE_1_0.0
-      INDICATOR_FIXED_HEIGHT,                  ///< name "indicatorFixedHeight",     @see SetIndicatorFixedHeight(),   type float @SINCE_1_0.0
-      INDICATOR_SHOW_DURATION,                 ///< name "indicatorShowDuration",    @see SetIndicatorShowDuration(),  type float @SINCE_1_0.0
-      INDICATOR_HIDE_DURATION,                 ///< name "indicatorHideDuration",    @see SetIndicatorHideDuration(),  type float @SINCE_1_0.0
-      SCROLL_POSITION_INTERVALS                ///< name "scrollPositionIntervals",  @see SetScrollPositionIntervals() type Property::Array @SINCE_1_0.0
+      /**
+       * @brief name "scrollDirection", type std::string
+       * @see SetScrollDirection()
+       * @SINCE_1_0.0
+       */
+      SCROLL_DIRECTION = PROPERTY_START_INDEX,
+      /**
+       * @brief name "indicatorHeightPolicy", type std::string
+       * @see SetIndicatorHeightPolicy()
+       * @SINCE_1_0.0
+       */
+      INDICATOR_HEIGHT_POLICY,
+      /**
+       * @brief name "indicatorFixedHeight", type float
+       * @see SetIndicatorFixedHeight()
+       * @SINCE_1_0.0
+       */
+      INDICATOR_FIXED_HEIGHT,
+      /**
+       * @brief name "indicatorShowDuration", type float
+       * @see SetIndicatorShowDuration()
+       * @SINCE_1_0.0
+       */
+      INDICATOR_SHOW_DURATION,
+      /**
+       * @brief name "indicatorHideDuration", type float
+       * @see SetIndicatorHideDuration()
+       * @SINCE_1_0.0
+       */
+      INDICATOR_HIDE_DURATION,
+      /**
+       * @brief name "scrollPositionIntervals", type Property::Array
+       * @see SetScrollPositionIntervals()
+       * @SINCE_1_0.0
+       */
+      SCROLL_POSITION_INTERVALS,
+      /**
+       * @brief name "indicatorMinimumHeight", type float
+       * The minimum height for a variable size indicator.
+       * @SINCE_1_1.36
+       */
+      INDICATOR_MINIMUM_HEIGHT,
+      /**
+       * @brief name "indicatorStartPadding", type float
+       * The padding at the start of the indicator. For example, the top if scrollDirection is Vertical.
+       * @SINCE_1_1.36
+       */
+      INDICATOR_START_PADDING,
+      /**
+       * @brief name "indicatorEndPadding", type float
+       * The padding at the end of the indicator. For example, the bottom if scrollDirection is Vertical.
+       * @SINCE_1_1.36
+       */
+      INDICATOR_END_PADDING
     };
   };