[dali_1.3.14] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scroll-bar / scroll-bar-impl.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23 #include <dali/public-api/animation/constraint.h>
24 #include <dali/public-api/animation/constraints.h>
25 #include <dali/public-api/images/resource-image.h>
26 #include <dali/public-api/object/type-registry.h>
27 #include <dali/public-api/object/property-array.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/devel-api/object/property-helper-devel.h>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h>
34 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
35
36 using namespace Dali;
37
38 namespace
39 {
40
41 const char* DEFAULT_INDICATOR_IMAGE_PATH = DALI_IMAGE_DIR "popup_scroll.9.png";
42 const float DEFAULT_SLIDER_DEPTH(1.0f);
43 const float DEFAULT_INDICATOR_SHOW_DURATION(0.5f);
44 const float DEFAULT_INDICATOR_HIDE_DURATION(0.5f);
45 const float DEFAULT_PAN_GESTURE_PROCESS_TIME(16.7f); // 16.7 milliseconds, i.e. one frame
46 const float DEFAULT_INDICATOR_FIXED_HEIGHT(80.0f);
47 const float DEFAULT_INDICATOR_MINIMUM_HEIGHT(0.0f);
48 const float DEFAULT_INDICATOR_START_PADDING(0.0f);
49 const float DEFAULT_INDICATOR_END_PADDING(0.0f);
50 const float DEFAULT_INDICATOR_TRANSIENT_DURATION(1.0f);
51
52 /**
53  * Indicator size constraint
54  * Indicator size depends on both indicator's parent size and the scroll content size
55  */
56 struct IndicatorSizeConstraint
57 {
58   /**
59    * @param[in] minimumHeight The minimum height for the indicator
60    * @param[in] padding The sum of the padding at the start & end of the indicator
61    */
62   IndicatorSizeConstraint( float minimumHeight, float padding )
63   : mMinimumHeight( minimumHeight ),
64     mPadding( padding )
65   {
66   }
67
68   /**
69    * Constraint operator
70    * @param[in] current The current indicator size
71    * @param[in] parentSizeProperty The parent size of scroll indicator.
72    * @return The new scroll indicator size.
73    */
74   void operator()( Vector3& current, const PropertyInputContainer& inputs )
75   {
76     const Vector3& parentSize = inputs[0]->GetVector3();
77     const float contentSize = inputs[1]->GetFloat();
78
79     // Take into account padding that may exist at the beginning and end of the indicator.
80     const float parentHeightMinusPadding = parentSize.height - mPadding;
81
82     float height = contentSize > parentHeightMinusPadding ?
83                    parentHeightMinusPadding * ( parentHeightMinusPadding / contentSize ) :
84                    parentHeightMinusPadding * ( ( parentHeightMinusPadding - contentSize * 0.5f ) / parentHeightMinusPadding );
85
86     current.y = std::max( mMinimumHeight, height );
87   }
88
89   float mMinimumHeight;
90   float mPadding;
91 };
92
93 /**
94  * Indicator position constraint
95  * Positions the indicator to reflect the current scroll position within the scroll domain.
96  */
97 struct IndicatorPositionConstraint
98 {
99   /**
100    * @param[in] startPadding The padding at the start of the indicator
101    * @param[in] endPadding The padding at the end of the indicator
102    */
103   IndicatorPositionConstraint( float startPadding, float endPadding )
104   : mStartPadding( startPadding ),
105     mEndPadding( endPadding )
106   {
107   }
108
109   /**
110    * Constraint operator
111    * @param[in,out] current The current indicator position
112    * @param[in] inputs Contains the size of indicator, the size of indicator's parent, and the scroll position of the scrollable container (from 0.0 -> 1.0 in each axis)
113    * @return The new indicator position is returned.
114    */
115   void operator()( Vector3& current, const PropertyInputContainer& inputs )
116   {
117     const Vector3& indicatorSize = inputs[0]->GetVector3();
118     const Vector3& parentSize = inputs[1]->GetVector3();
119     const float scrollPosition = -inputs[2]->GetFloat();
120     const float minimumScrollPosition = inputs[3]->GetFloat();
121     const float maximumScrollPosition = inputs[4]->GetFloat();
122
123     // Take into account padding that may exist at the beginning and end of the indicator.
124     const float parentHeightMinusPadding = parentSize.height - ( mStartPadding + mEndPadding );
125
126     float relativePosition = std::max( 0.0f, std::min( 1.0f, ( scrollPosition - minimumScrollPosition ) / ( maximumScrollPosition - minimumScrollPosition ) ) );
127     current.y = mStartPadding + ( parentHeightMinusPadding - indicatorSize.height ) * relativePosition;
128     current.z = DEFAULT_SLIDER_DEPTH;
129   }
130
131   float mStartPadding;
132   float mEndPadding;
133 };
134
135 } // unnamed namespace
136
137 namespace Dali
138 {
139
140 namespace Toolkit
141 {
142
143 namespace Internal
144 {
145
146 namespace
147 {
148
149 using namespace Dali;
150
151 BaseHandle Create()
152 {
153   return Toolkit::ScrollBar::New();
154 }
155
156 // Setup properties, signals and actions using the type-registry.
157 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ScrollBar, Toolkit::Control, Create );
158
159 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "scrollDirection",                   STRING, SCROLL_DIRECTION             )
160 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorHeightPolicy",             STRING, INDICATOR_HEIGHT_POLICY      )
161 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorFixedHeight",              FLOAT,  INDICATOR_FIXED_HEIGHT       )
162 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorShowDuration",             FLOAT,  INDICATOR_SHOW_DURATION      )
163 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorHideDuration",             FLOAT,  INDICATOR_HIDE_DURATION      )
164 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "scrollPositionIntervals",           ARRAY,  SCROLL_POSITION_INTERVALS    )
165 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorMinimumHeight",            FLOAT,  INDICATOR_MINIMUM_HEIGHT     )
166 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorStartPadding",             FLOAT,  INDICATOR_START_PADDING      )
167 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorEndPadding",               FLOAT,  INDICATOR_END_PADDING        )
168 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicatorTransientDuration",        FLOAT,  INDICATOR_TRANSIENT_DURATION )
169
170 DALI_SIGNAL_REGISTRATION(   Toolkit, ScrollBar, "panFinished",                       PAN_FINISHED_SIGNAL                     )
171 DALI_SIGNAL_REGISTRATION(   Toolkit, ScrollBar, "scrollPositionIntervalReached",     SCROLL_POSITION_INTERVAL_REACHED_SIGNAL )
172
173 DALI_ACTION_REGISTRATION(   Toolkit, ScrollBar, "ShowIndicator",                     ACTION_SHOW_INDICATOR                   )
174 DALI_ACTION_REGISTRATION(   Toolkit, ScrollBar, "HideIndicator",                     ACTION_HIDE_INDICATOR                   )
175 DALI_ACTION_REGISTRATION(   Toolkit, ScrollBar, "ShowTransientIndicator",            ACTION_SHOW_TRANSIENT_INDICATOR         )
176
177 DALI_TYPE_REGISTRATION_END()
178
179 const char* SCROLL_DIRECTION_NAME[] = {"Vertical", "Horizontal"};
180 const char* INDICATOR_HEIGHT_POLICY_NAME[] = {"Variable", "Fixed"};
181
182 }
183
184 ScrollBar::ScrollBar(Toolkit::ScrollBar::Direction direction)
185 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
186   mIndicatorShowAlpha(1.0f),
187   mDirection(direction),
188   mScrollableObject(WeakHandleBase()),
189   mPropertyScrollPosition(Property::INVALID_INDEX),
190   mPropertyMinScrollPosition(Property::INVALID_INDEX),
191   mPropertyMaxScrollPosition(Property::INVALID_INDEX),
192   mPropertyScrollContentSize(Property::INVALID_INDEX),
193   mIndicatorShowDuration(DEFAULT_INDICATOR_SHOW_DURATION),
194   mIndicatorHideDuration(DEFAULT_INDICATOR_HIDE_DURATION),
195   mTransientIndicatorDuration(DEFAULT_INDICATOR_TRANSIENT_DURATION),
196   mScrollStart(0.0f),
197   mGestureDisplacement( Vector3::ZERO ),
198   mCurrentScrollPosition(0.0f),
199   mIndicatorHeightPolicy(Toolkit::ScrollBar::Variable),
200   mIndicatorFixedHeight(DEFAULT_INDICATOR_FIXED_HEIGHT),
201   mIndicatorMinimumHeight(DEFAULT_INDICATOR_MINIMUM_HEIGHT),
202   mIndicatorStartPadding(DEFAULT_INDICATOR_START_PADDING),
203   mIndicatorEndPadding(DEFAULT_INDICATOR_END_PADDING),
204   mIsPanning(false),
205   mIndicatorFirstShow(true)
206 {
207 }
208
209 ScrollBar::~ScrollBar()
210 {
211 }
212
213 void ScrollBar::OnInitialize()
214 {
215   CreateDefaultIndicatorActor();
216   Self().SetDrawMode(DrawMode::OVERLAY_2D);
217 }
218
219 void ScrollBar::SetScrollPropertySource( Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize )
220 {
221   if( handle
222       && propertyScrollPosition != Property::INVALID_INDEX
223       && propertyMinScrollPosition != Property::INVALID_INDEX
224       && propertyMaxScrollPosition != Property::INVALID_INDEX
225       && propertyScrollContentSize != Property::INVALID_INDEX )
226   {
227     mScrollableObject = WeakHandleBase(handle);
228     mPropertyScrollPosition = propertyScrollPosition;
229     mPropertyMinScrollPosition = propertyMinScrollPosition;
230     mPropertyMaxScrollPosition = propertyMaxScrollPosition;
231     mPropertyScrollContentSize = propertyScrollContentSize;
232
233     ApplyConstraints();
234   }
235   else
236   {
237     DALI_LOG_ERROR("Can not set empty handle of source object or invalid source property index\n");
238   }
239 }
240
241 void ScrollBar::CreateDefaultIndicatorActor()
242 {
243   Toolkit::ImageView indicator = Toolkit::ImageView::New( DEFAULT_INDICATOR_IMAGE_PATH );
244   indicator.SetParentOrigin( ParentOrigin::TOP_LEFT );
245   indicator.SetAnchorPoint( AnchorPoint::TOP_LEFT );
246   indicator.SetStyleName( "ScrollBarIndicator" );
247   indicator.SetColorMode( USE_OWN_MULTIPLY_PARENT_COLOR );
248   SetScrollIndicator(indicator);
249 }
250
251 void ScrollBar::SetScrollIndicator( Actor indicator )
252 {
253   // Don't allow empty handle
254   if( indicator )
255   {
256     // Remove current Indicator
257     if( mIndicator )
258     {
259       Self().Remove( mIndicator );
260     }
261     mIndicator = indicator;
262
263     mIndicatorFirstShow = true;
264     Self().Add( mIndicator );
265
266     EnableGestureDetection( Gesture::Type( Gesture::Pan ) );
267
268     PanGestureDetector detector( GetPanGestureDetector() );
269     detector.DetachAll();
270     detector.Attach( mIndicator );
271
272     unsigned int childCount = mIndicator.GetChildCount();
273     for ( unsigned int index = 0; index < childCount; index++ )
274     {
275       Actor child = mIndicator.GetChildAt( index );
276       if ( child )
277       {
278         detector.Attach( child );
279       }
280     }
281   }
282   else
283   {
284     DALI_LOG_ERROR("Empty handle of scroll indicator\n");
285   }
286 }
287
288 Actor ScrollBar::GetScrollIndicator()
289 {
290   return mIndicator;
291 }
292
293 void ScrollBar::ApplyConstraints()
294 {
295   Handle scrollableHandle = mScrollableObject.GetBaseHandle();
296
297   if( scrollableHandle )
298   {
299     if(mIndicatorSizeConstraint)
300     {
301       mIndicatorSizeConstraint.Remove();
302     }
303
304     // Set indicator height according to the indicator's height policy
305     if(mIndicatorHeightPolicy == Toolkit::ScrollBar::Fixed)
306     {
307       mIndicator.SetSize(Self().GetCurrentSize().width, mIndicatorFixedHeight);
308     }
309     else
310     {
311       mIndicatorSizeConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::SIZE,
312                                                            IndicatorSizeConstraint( mIndicatorMinimumHeight, mIndicatorStartPadding + mIndicatorEndPadding ) );
313       mIndicatorSizeConstraint.AddSource( ParentSource( Actor::Property::SIZE ) );
314       mIndicatorSizeConstraint.AddSource( Source( scrollableHandle, mPropertyScrollContentSize ) );
315       mIndicatorSizeConstraint.Apply();
316     }
317
318     if(mIndicatorPositionConstraint)
319     {
320       mIndicatorPositionConstraint.Remove();
321     }
322
323     mIndicatorPositionConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::POSITION,
324                                                              IndicatorPositionConstraint( mIndicatorStartPadding, mIndicatorEndPadding ) );
325     mIndicatorPositionConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
326     mIndicatorPositionConstraint.AddSource( ParentSource( Actor::Property::SIZE ) );
327     mIndicatorPositionConstraint.AddSource( Source( scrollableHandle, mPropertyScrollPosition ) );
328     mIndicatorPositionConstraint.AddSource( Source( scrollableHandle, mPropertyMinScrollPosition ) );
329     mIndicatorPositionConstraint.AddSource( Source( scrollableHandle, mPropertyMaxScrollPosition ) );
330     mIndicatorPositionConstraint.Apply();
331   }
332 }
333
334 void ScrollBar::SetScrollPositionIntervals( const Dali::Vector<float>& positions )
335 {
336   mScrollPositionIntervals = positions;
337
338   Handle scrollableHandle = mScrollableObject.GetBaseHandle();
339
340   if( scrollableHandle )
341   {
342     if( mPositionNotification )
343     {
344       scrollableHandle.RemovePropertyNotification(mPositionNotification);
345     }
346
347     mPositionNotification = scrollableHandle.AddPropertyNotification( mPropertyScrollPosition, VariableStepCondition(mScrollPositionIntervals) );
348     mPositionNotification.NotifySignal().Connect( this, &ScrollBar::OnScrollPositionIntervalReached );
349   }
350 }
351
352 Dali::Vector<float> ScrollBar::GetScrollPositionIntervals() const
353 {
354   return mScrollPositionIntervals;
355 }
356
357 void ScrollBar::OnScrollPositionIntervalReached(PropertyNotification& source)
358 {
359   // Emit the signal to notify the scroll position crossing
360   Handle scrollableHandle = mScrollableObject.GetBaseHandle();
361   if(scrollableHandle)
362   {
363     mScrollPositionIntervalReachedSignal.Emit( scrollableHandle.GetCurrentProperty< float >( mPropertyScrollPosition ) );
364   }
365 }
366
367 void ScrollBar::ShowIndicator()
368 {
369   // Cancel any animation
370   if(mAnimation)
371   {
372     mAnimation.Clear();
373     mAnimation.Reset();
374   }
375
376   if( mIndicatorFirstShow )
377   {
378     // Preserve the alpha value from the stylesheet
379     mIndicatorShowAlpha = Self().GetCurrentColor().a;
380     mIndicatorFirstShow = false;
381   }
382
383   if(mIndicatorShowDuration > 0.0f)
384   {
385     mAnimation = Animation::New( mIndicatorShowDuration );
386     mAnimation.AnimateTo( Property( mIndicator, Actor::Property::COLOR_ALPHA ), mIndicatorShowAlpha, AlphaFunction::EASE_IN );
387     mAnimation.Play();
388   }
389   else
390   {
391     mIndicator.SetOpacity(mIndicatorShowAlpha);
392   }
393 }
394
395 void ScrollBar::HideIndicator()
396 {
397   // Cancel any animation
398   if(mAnimation)
399   {
400     mAnimation.Clear();
401     mAnimation.Reset();
402   }
403
404   if(mIndicatorHideDuration > 0.0f)
405   {
406     mAnimation = Animation::New( mIndicatorHideDuration );
407     mAnimation.AnimateTo( Property( mIndicator, Actor::Property::COLOR_ALPHA ), 0.0f, AlphaFunction::EASE_IN );
408     mAnimation.Play();
409   }
410   else
411   {
412     mIndicator.SetOpacity(0.0f);
413   }
414 }
415
416 void ScrollBar::ShowTransientIndicator()
417 {
418   // Cancel any animation
419   if(mAnimation)
420   {
421     mAnimation.Clear();
422     mAnimation.Reset();
423   }
424
425   mAnimation = Animation::New( mIndicatorShowDuration + mTransientIndicatorDuration + mIndicatorHideDuration );
426   if(mIndicatorShowDuration > 0.0f)
427   {
428     mAnimation.AnimateTo( Property( mIndicator, Actor::Property::COLOR_ALPHA ),
429                           mIndicatorShowAlpha, AlphaFunction::EASE_IN, TimePeriod(0, mIndicatorShowDuration) );
430   }
431   else
432   {
433     mIndicator.SetOpacity(mIndicatorShowAlpha);
434   }
435   mAnimation.AnimateTo( Property( mIndicator, Actor::Property::COLOR_ALPHA ),
436                         0.0f, AlphaFunction::EASE_IN, TimePeriod((mIndicatorShowDuration + mTransientIndicatorDuration), mIndicatorHideDuration) );
437   mAnimation.Play();
438 }
439
440 bool ScrollBar::OnPanGestureProcessTick()
441 {
442   // Update the scroll position property.
443   Handle scrollableHandle = mScrollableObject.GetBaseHandle();
444   if( scrollableHandle )
445   {
446     scrollableHandle.SetProperty(mPropertyScrollPosition, mCurrentScrollPosition);
447   }
448
449   return true;
450 }
451
452 void ScrollBar::OnPan( const PanGesture& gesture )
453 {
454   Handle scrollableHandle = mScrollableObject.GetBaseHandle();
455
456   if(scrollableHandle)
457   {
458     Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast(scrollableHandle);
459
460     switch(gesture.state)
461     {
462       case Gesture::Started:
463       {
464         if( !mPanProcessTimer )
465         {
466           // Make sure the pan gesture is only being processed once per frame.
467           mPanProcessTimer = Timer::New( DEFAULT_PAN_GESTURE_PROCESS_TIME );
468           mPanProcessTimer.TickSignal().Connect( this, &ScrollBar::OnPanGestureProcessTick );
469           mPanProcessTimer.Start();
470         }
471
472         ShowIndicator();
473         mScrollStart = scrollableHandle.GetCurrentProperty< float >( mPropertyScrollPosition );
474         mGestureDisplacement = Vector3::ZERO;
475         mIsPanning = true;
476
477         break;
478       }
479       case Gesture::Continuing:
480       {
481         mGestureDisplacement.x += gesture.displacement.x;
482         mGestureDisplacement.y += gesture.displacement.y;
483
484         float minScrollPosition = scrollableHandle.GetCurrentProperty<float>( mPropertyMinScrollPosition );
485         float maxScrollPosition = scrollableHandle.GetCurrentProperty<float>( mPropertyMaxScrollPosition );
486
487         // The domain size is the internal range
488         float domainSize = maxScrollPosition - minScrollPosition;
489         float logicalSize = Self().GetCurrentSize().y - ( mIndicator.GetCurrentSize().y + mIndicatorStartPadding + mIndicatorEndPadding );
490
491         mCurrentScrollPosition = mScrollStart - ( ( mGestureDisplacement.y * domainSize ) / logicalSize );
492         mCurrentScrollPosition = -std::min( maxScrollPosition, std::max( -mCurrentScrollPosition, minScrollPosition ) );
493
494         break;
495       }
496       default:
497       {
498         mIsPanning = false;
499
500         if( mPanProcessTimer )
501         {
502           // Destroy the timer when pan gesture is finished.
503           mPanProcessTimer.Stop();
504           mPanProcessTimer.TickSignal().Disconnect( this, &ScrollBar::OnPanGestureProcessTick );
505           mPanProcessTimer.Reset();
506         }
507
508         if(itemView)
509         {
510           // Refresh the ItemView cache with extra items
511           GetImpl(itemView).DoRefresh(mCurrentScrollPosition, true);
512         }
513
514         mPanFinishedSignal.Emit();
515
516         break;
517       }
518     }
519
520     if(itemView)
521     {
522       // Disable automatic refresh in ItemView during fast scrolling
523       GetImpl(itemView).SetRefreshEnabled(!mIsPanning);
524     }
525   }
526 }
527
528 void ScrollBar::OnSizeSet( const Vector3& size )
529 {
530   if(mIndicatorHeightPolicy == Toolkit::ScrollBar::Fixed)
531   {
532     mIndicator.SetSize(size.width, mIndicatorFixedHeight);
533   }
534
535   Control::OnSizeSet( size );
536 }
537
538 void ScrollBar::SetScrollDirection( Toolkit::ScrollBar::Direction direction )
539 {
540   mDirection = direction;
541 }
542
543 Toolkit::ScrollBar::Direction ScrollBar::GetScrollDirection() const
544 {
545   return mDirection;
546 }
547
548 void ScrollBar::SetIndicatorHeightPolicy( Toolkit::ScrollBar::IndicatorHeightPolicy policy )
549 {
550   if( policy != mIndicatorHeightPolicy )
551   {
552     mIndicatorHeightPolicy = policy;
553     ApplyConstraints();
554   }
555 }
556
557 Toolkit::ScrollBar::IndicatorHeightPolicy ScrollBar::GetIndicatorHeightPolicy() const
558 {
559   return mIndicatorHeightPolicy;
560 }
561
562 void ScrollBar::SetIndicatorFixedHeight( float height )
563 {
564   mIndicatorFixedHeight = height;
565
566   if(mIndicatorHeightPolicy == Toolkit::ScrollBar::Fixed)
567   {
568     mIndicator.SetSize(Self().GetCurrentSize().width, mIndicatorFixedHeight);
569   }
570 }
571
572 float ScrollBar::GetIndicatorFixedHeight() const
573 {
574   return mIndicatorFixedHeight;
575 }
576
577 void ScrollBar::SetIndicatorShowDuration( float durationSeconds )
578 {
579   mIndicatorShowDuration = durationSeconds;
580 }
581
582 float ScrollBar::GetIndicatorShowDuration() const
583 {
584   return mIndicatorShowDuration;
585 }
586
587 void ScrollBar::SetIndicatorHideDuration( float durationSeconds )
588 {
589   mIndicatorHideDuration = durationSeconds;
590 }
591
592 float ScrollBar::GetIndicatorHideDuration() const
593 {
594   return mIndicatorHideDuration;
595 }
596
597 void ScrollBar::OnScrollDirectionPropertySet( Property::Value propertyValue )
598 {
599   std::string directionName( propertyValue.Get<std::string>() );
600   if(directionName == "Vertical")
601   {
602     SetScrollDirection(Toolkit::ScrollBar::Vertical);
603   }
604   else if(directionName == "Horizontal")
605   {
606     SetScrollDirection(Toolkit::ScrollBar::Horizontal);
607   }
608   else
609   {
610     DALI_ASSERT_ALWAYS( !"ScrollBar::OnScrollDirectionPropertySet(). Invalid Property value." );
611   }
612 }
613
614 void ScrollBar::OnIndicatorHeightPolicyPropertySet( Property::Value propertyValue )
615 {
616   std::string policyName( propertyValue.Get<std::string>() );
617   if(policyName == "Variable")
618   {
619     SetIndicatorHeightPolicy(Toolkit::ScrollBar::Variable);
620   }
621   else if(policyName == "Fixed")
622   {
623     SetIndicatorHeightPolicy(Toolkit::ScrollBar::Fixed);
624   }
625   else
626   {
627     DALI_ASSERT_ALWAYS( !"ScrollBar::OnIndicatorHeightPolicyPropertySet(). Invalid Property value." );
628   }
629 }
630
631 bool ScrollBar::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
632 {
633   Dali::BaseHandle handle( object );
634
635   bool connected( true );
636   Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast( handle );
637
638   if( 0 == strcmp( signalName.c_str(), PAN_FINISHED_SIGNAL ) )
639   {
640     scrollBar.PanFinishedSignal().Connect( tracker, functor );
641   }
642   else if( 0 == strcmp( signalName.c_str(), SCROLL_POSITION_INTERVAL_REACHED_SIGNAL ) )
643   {
644     scrollBar.ScrollPositionIntervalReachedSignal().Connect( tracker, functor );
645   }
646   else
647   {
648     // signalName does not match any signal
649     connected = false;
650   }
651
652   return connected;
653 }
654
655 void ScrollBar::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
656 {
657   Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast( Dali::BaseHandle( object ) );
658
659   if( scrollBar )
660   {
661     ScrollBar& scrollBarImpl( GetImpl( scrollBar ) );
662     switch( index )
663     {
664       case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
665       {
666         scrollBarImpl.OnScrollDirectionPropertySet( value );
667         break;
668       }
669       case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
670       {
671         scrollBarImpl.OnIndicatorHeightPolicyPropertySet( value );
672         break;
673       }
674       case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
675       {
676         scrollBarImpl.SetIndicatorFixedHeight(value.Get<float>());
677         break;
678       }
679       case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
680       {
681         scrollBarImpl.SetIndicatorShowDuration(value.Get<float>());
682         break;
683       }
684       case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
685       {
686         scrollBarImpl.SetIndicatorHideDuration(value.Get<float>());
687         break;
688       }
689       case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
690       {
691         Property::Array* array = value.GetArray();
692         if( array )
693         {
694           Dali::Vector<float> positions;
695           size_t positionCount = array->Count();
696           positions.Resize( positionCount );
697           for( size_t i = 0; i != positionCount; ++i )
698           {
699             array->GetElementAt( i ).Get( positions[i] );
700           }
701
702           scrollBarImpl.SetScrollPositionIntervals(positions);
703         }
704         break;
705       }
706       case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
707       {
708         scrollBarImpl.mIndicatorMinimumHeight = value.Get<float>();
709         scrollBarImpl.ApplyConstraints();
710         break;
711       }
712       case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
713       {
714         scrollBarImpl.mIndicatorStartPadding = value.Get<float>();
715         scrollBarImpl.ApplyConstraints();
716         break;
717       }
718       case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
719       {
720         scrollBarImpl.mIndicatorEndPadding = value.Get<float>();
721         scrollBarImpl.ApplyConstraints();
722         break;
723       }
724       case Toolkit::ScrollBar::Property::INDICATOR_TRANSIENT_DURATION:
725       {
726         scrollBarImpl.mTransientIndicatorDuration = value.Get<float>();
727         break;
728       }
729     }
730   }
731 }
732
733 Property::Value ScrollBar::GetProperty( BaseObject* object, Property::Index index )
734 {
735   Property::Value value;
736
737   Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast( Dali::BaseHandle( object ) );
738
739   if( scrollBar )
740   {
741     ScrollBar& scrollBarImpl( GetImpl( scrollBar ) );
742     switch( index )
743     {
744       case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
745       {
746         value = SCROLL_DIRECTION_NAME[ scrollBarImpl.GetScrollDirection() ];
747         break;
748       }
749       case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
750       {
751         value = INDICATOR_HEIGHT_POLICY_NAME[ scrollBarImpl.GetIndicatorHeightPolicy() ];
752         break;
753       }
754       case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
755       {
756         value = scrollBarImpl.GetIndicatorFixedHeight();
757         break;
758       }
759       case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
760       {
761         value = scrollBarImpl.GetIndicatorShowDuration();
762         break;
763       }
764       case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
765       {
766         value = scrollBarImpl.GetIndicatorHideDuration();
767         break;
768       }
769       case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
770       {
771         Property::Value tempValue( Property::ARRAY );
772         Property::Array* array = tempValue.GetArray();
773
774         if( array )
775         {
776           Dali::Vector<float> positions = scrollBarImpl.GetScrollPositionIntervals();
777           size_t positionCount( positions.Count() );
778
779           for( size_t i( 0 ); i != positionCount; ++i )
780           {
781             array->PushBack( positions[i] );
782           }
783
784           value = tempValue;
785         }
786         break;
787       }
788       case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
789       {
790         value = scrollBarImpl.mIndicatorMinimumHeight;
791         break;
792       }
793       case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
794       {
795         value = scrollBarImpl.mIndicatorStartPadding;
796         break;
797       }
798       case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
799       {
800         value = scrollBarImpl.mIndicatorEndPadding;
801         break;
802       }
803       case Toolkit::ScrollBar::Property::INDICATOR_TRANSIENT_DURATION:
804       {
805         value = scrollBarImpl.mTransientIndicatorDuration;
806         break;
807       }
808     }
809   }
810   return value;
811 }
812
813 bool ScrollBar::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
814 {
815   bool ret = false;
816
817   Dali::BaseHandle handle( object );
818
819   Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast( handle );
820
821   DALI_ASSERT_DEBUG( scrollBar );
822
823   if( scrollBar )
824   {
825     if( 0 == strcmp( actionName.c_str(), ACTION_SHOW_INDICATOR ) )
826     {
827       GetImpl( scrollBar ).ShowIndicator();
828       ret = true;
829     }
830     else if( 0 == strcmp( actionName.c_str(), ACTION_HIDE_INDICATOR ) )
831     {
832       GetImpl( scrollBar ).HideIndicator();
833       ret = true;
834     }
835     else if( 0 == strcmp( actionName.c_str(), ACTION_SHOW_TRANSIENT_INDICATOR ) )
836     {
837       GetImpl( scrollBar ).ShowTransientIndicator();
838       ret = true;
839     }
840   }
841
842   return ret;
843 }
844
845 Toolkit::ScrollBar ScrollBar::New(Toolkit::ScrollBar::Direction direction)
846 {
847   // Create the implementation, temporarily owned by this handle on stack
848   IntrusivePtr< ScrollBar > impl = new ScrollBar(direction);
849
850   // Pass ownership to CustomActor handle
851   Toolkit::ScrollBar handle( *impl );
852
853   // Second-phase init of the implementation
854   // This can only be done after the CustomActor connection has been made...
855   impl->Initialize();
856
857   return handle;
858 }
859
860 } // namespace Internal
861
862 } // namespace Toolkit
863
864 } // namespace Dali