Remove dali-any from Property::Value
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scroll-bar / scroll-bar-impl.cpp
1 /*
2  * Copyright (c) 2014 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/devel-api/object/type-registry-helper.h>
29 #include <dali/integration-api/debug.h>
30
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h>
34
35 using namespace Dali;
36
37 namespace
38 {
39
40 const char* DEFAULT_INDICATOR_IMAGE_PATH = DALI_IMAGE_DIR "popup_scroll.png";
41 const Vector4 DEFAULT_INDICATOR_NINE_PATCH_BORDER(4.0f, 9.0f, 7.0f, 11.0f);
42 const float MINIMUM_INDICATOR_HEIGHT(20.0f); // The minimum indicator height for the nine patch border
43 const float DEFAULT_SLIDER_DEPTH(1.0f);
44 const float DEFAULT_INDICATOR_SHOW_DURATION(0.5f);
45 const float DEFAULT_INDICATOR_HIDE_DURATION(0.5f);
46 const float DEFAULT_PAN_GESTURE_PROCESS_TIME(16.7f); // 16.7 milliseconds, i.e. one frame
47 const float DEFAULT_INDICATOR_FIXED_HEIGHT(80.0f);
48
49 /**
50  * Indicator size constraint
51  * Indicator size depends on both indicator's parent size and the scroll content size
52  */
53 struct IndicatorSizeConstraint
54 {
55   IndicatorSizeConstraint()
56   {
57   }
58
59   /**
60    * Constraint operator
61    * @param[in] current The current indicator size
62    * @param[in] parentSizeProperty The parent size of scroll indicator.
63    * @return The new scroll indicator size.
64    */
65   void operator()(Vector3& current, const PropertyInputContainer& inputs )
66   {
67     const Vector3& parentSize = inputs[0]->GetVector3();
68     const float contentSize = inputs[1]->GetFloat();
69
70     float height = contentSize > parentSize.height ?
71                    parentSize.height * ( parentSize.height / contentSize ) :
72                    parentSize.height * ( (parentSize.height - contentSize * 0.5f) / parentSize.height);
73
74     current.y = std::max(MINIMUM_INDICATOR_HEIGHT, height);
75   }
76 };
77
78 /**
79  * Indicator position constraint
80  * Positions the indicator to reflect the current scroll position within the scroll domain.
81  */
82 struct IndicatorPositionConstraint
83 {
84   /**
85    * @param[in] minPosition The minimum limit of scroll position
86    * @param[in] maxPosition the maximum limit of scroll position
87    */
88   IndicatorPositionConstraint()
89   {
90   }
91
92   /**
93    * Constraint operator
94    * @param[in,out] current The current indicator position
95    * @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)
96    * @return The new indicator position is returned.
97    */
98   void operator()( Vector3& current, const PropertyInputContainer& inputs )
99   {
100     const Vector3& indicatorSize = inputs[0]->GetVector3();
101     const Vector3& parentSize = inputs[1]->GetVector3();
102     const float scrollPosition = -inputs[2]->GetFloat();
103     const float minScrollPosition = inputs[3]->GetFloat();
104     const float maxScrollPosition = inputs[4]->GetFloat();
105
106     float relativePosition = std::max( 0.0f, std::min( 1.0f, (scrollPosition - minScrollPosition) / (maxScrollPosition - minScrollPosition) ) );
107     current.y = ( parentSize.height - indicatorSize.height ) * relativePosition;
108     current.z = DEFAULT_SLIDER_DEPTH;
109   }
110 };
111
112 } // unnamed namespace
113
114 namespace Dali
115 {
116
117 namespace Toolkit
118 {
119
120 namespace Internal
121 {
122
123 namespace
124 {
125
126 using namespace Dali;
127
128 BaseHandle Create()
129 {
130   return Toolkit::ScrollBar::New();
131 }
132
133 // Setup properties, signals and actions using the type-registry.
134 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ScrollBar, Toolkit::Control, Create );
135
136 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "scroll-direction",                  STRING, SCROLL_DIRECTION          )
137 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicator-height-policy",           STRING, INDICATOR_HEIGHT_POLICY   )
138 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicator-fixed-height",            FLOAT,  INDICATOR_FIXED_HEIGHT    )
139 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicator-show-duration",           FLOAT,  INDICATOR_SHOW_DURATION   )
140 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "indicator-hide-duration",           FLOAT,  INDICATOR_HIDE_DURATION   )
141 DALI_PROPERTY_REGISTRATION( Toolkit, ScrollBar, "scroll-position-intervals",         ARRAY,  SCROLL_POSITION_INTERVALS )
142
143 DALI_SIGNAL_REGISTRATION(   Toolkit, ScrollBar, "pan-finished",                      PAN_FINISHED_SIGNAL )
144 DALI_SIGNAL_REGISTRATION(   Toolkit, ScrollBar, "scroll-position-interval-reached",  SCROLL_POSITION_INTERVAL_REACHED_SIGNAL )
145
146 DALI_TYPE_REGISTRATION_END()
147
148 const char* SCROLL_DIRECTION_NAME[] = {"Vertical", "Horizontal"};
149 const char* INDICATOR_HEIGHT_POLICY_NAME[] = {"Variable", "Fixed"};
150
151 }
152
153 ScrollBar::ScrollBar(Toolkit::ScrollBar::Direction direction)
154 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
155   mDirection(direction),
156   mScrollableObject(Handle()),
157   mPropertyScrollPosition(Property::INVALID_INDEX),
158   mPropertyMinScrollPosition(Property::INVALID_INDEX),
159   mPropertyMaxScrollPosition(Property::INVALID_INDEX),
160   mPropertyScrollContentSize(Property::INVALID_INDEX),
161   mIndicatorShowDuration(DEFAULT_INDICATOR_SHOW_DURATION),
162   mIndicatorHideDuration(DEFAULT_INDICATOR_HIDE_DURATION),
163   mScrollStart(0.0f),
164   mIsPanning(false),
165   mCurrentScrollPosition(0.0f),
166   mIndicatorHeightPolicy(Toolkit::ScrollBar::Variable),
167   mIndicatorFixedHeight(DEFAULT_INDICATOR_FIXED_HEIGHT)
168 {
169 }
170
171 ScrollBar::~ScrollBar()
172 {
173 }
174
175 void ScrollBar::OnInitialize()
176 {
177   CreateDefaultIndicatorActor();
178 }
179
180 void ScrollBar::SetScrollPropertySource( Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize )
181 {
182   if( handle
183       && propertyScrollPosition != Property::INVALID_INDEX
184       && propertyMinScrollPosition != Property::INVALID_INDEX
185       && propertyMaxScrollPosition != Property::INVALID_INDEX
186       && propertyScrollContentSize != Property::INVALID_INDEX )
187   {
188     mScrollableObject = handle;
189     mPropertyScrollPosition = propertyScrollPosition;
190     mPropertyMinScrollPosition = propertyMinScrollPosition;
191     mPropertyMaxScrollPosition = propertyMaxScrollPosition;
192     mPropertyScrollContentSize = propertyScrollContentSize;
193
194     ApplyConstraints();
195   }
196   else
197   {
198     DALI_LOG_ERROR("Can not set empty handle of source object or invalid source property index\n");
199   }
200 }
201
202 void ScrollBar::CreateDefaultIndicatorActor()
203 {
204   Image indicatorImage = ResourceImage::New( DEFAULT_INDICATOR_IMAGE_PATH );
205   ImageActor indicator = ImageActor::New( indicatorImage );
206   indicator.SetNinePatchBorder( DEFAULT_INDICATOR_NINE_PATCH_BORDER );
207   indicator.SetStyle( ImageActor::STYLE_NINE_PATCH );
208   indicator.SetParentOrigin( ParentOrigin::TOP_LEFT );
209   indicator.SetAnchorPoint( AnchorPoint::TOP_LEFT );
210
211   SetScrollIndicator(indicator);
212 }
213
214 void ScrollBar::SetScrollIndicator( Actor indicator )
215 {
216   // Don't allow empty handle
217   if( indicator )
218   {
219     mIndicator = indicator;
220
221     Actor self = Self();
222     self.Add(mIndicator);
223     self.SetDrawMode(DrawMode::OVERLAY);
224
225     if( !mPanGestureDetector )
226     {
227       mPanGestureDetector = PanGestureDetector::New();
228       mPanGestureDetector.DetectedSignal().Connect(this, &ScrollBar::OnPan);
229     }
230
231     mPanGestureDetector.DetachAll();
232     mPanGestureDetector.Attach( mIndicator );
233
234     unsigned int childCount = mIndicator.GetChildCount();
235     for ( unsigned int index = 0; index < childCount; index++ )
236     {
237       Actor child = mIndicator.GetChildAt( index );
238       if ( child )
239       {
240         mPanGestureDetector.Attach( child );
241       }
242     }
243   }
244   else
245   {
246     DALI_LOG_ERROR("Empty handle of scroll indicator\n");
247   }
248 }
249
250 Actor ScrollBar::GetScrollIndicator()
251 {
252   return mIndicator;
253 }
254
255 void ScrollBar::ApplyConstraints()
256 {
257   if( mScrollableObject )
258   {
259     if(mIndicatorSizeConstraint)
260     {
261       mIndicatorSizeConstraint.Remove();
262     }
263
264     // Set indicator height according to the indicator's height policy
265     if(mIndicatorHeightPolicy == Toolkit::ScrollBar::Fixed)
266     {
267       mIndicator.SetSize(Self().GetCurrentSize().width, mIndicatorFixedHeight);
268     }
269     else
270     {
271       mIndicatorSizeConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::SIZE, IndicatorSizeConstraint() );
272       mIndicatorSizeConstraint.AddSource( ParentSource( Actor::Property::SIZE ) );
273       mIndicatorSizeConstraint.AddSource( Source( mScrollableObject, mPropertyScrollContentSize ) );
274       mIndicatorSizeConstraint.Apply();
275     }
276
277     if(mIndicatorPositionConstraint)
278     {
279       mIndicatorPositionConstraint.Remove();
280     }
281
282     mIndicatorPositionConstraint = Constraint::New<Vector3>( mIndicator, Actor::Property::POSITION, IndicatorPositionConstraint() );
283     mIndicatorPositionConstraint.AddSource( LocalSource( Actor::Property::SIZE ) );
284     mIndicatorPositionConstraint.AddSource( ParentSource( Actor::Property::SIZE ) );
285     mIndicatorPositionConstraint.AddSource( Source( mScrollableObject, mPropertyScrollPosition ) );
286     mIndicatorPositionConstraint.AddSource( Source( mScrollableObject, mPropertyMinScrollPosition ) );
287     mIndicatorPositionConstraint.AddSource( Source( mScrollableObject, mPropertyMaxScrollPosition ) );
288     mIndicatorPositionConstraint.Apply();
289   }
290 }
291
292 void ScrollBar::SetScrollPositionIntervals( const Dali::Vector<float>& positions )
293 {
294   mScrollPositionIntervals = positions;
295
296   if( mScrollableObject )
297   {
298     if( mPositionNotification )
299     {
300       mScrollableObject.RemovePropertyNotification(mPositionNotification);
301     }
302
303     mPositionNotification = mScrollableObject.AddPropertyNotification( mPropertyScrollPosition, VariableStepCondition(mScrollPositionIntervals) );
304     mPositionNotification.NotifySignal().Connect( this, &ScrollBar::OnScrollPositionIntervalReached );
305   }
306 }
307
308 Dali::Vector<float> ScrollBar::GetScrollPositionIntervals() const
309 {
310   return mScrollPositionIntervals;
311 }
312
313 void ScrollBar::OnScrollPositionIntervalReached(PropertyNotification& source)
314 {
315   // Emit the signal to notify the scroll position crossing
316   if(mScrollableObject)
317   {
318     mScrollPositionIntervalReachedSignal.Emit(mScrollableObject.GetProperty<float>(mPropertyScrollPosition));
319   }
320 }
321
322 void ScrollBar::ShowIndicator()
323 {
324   // Cancel any animation
325   if(mAnimation)
326   {
327     mAnimation.Clear();
328     mAnimation.Reset();
329   }
330
331   if(mIndicatorShowDuration > 0.0f)
332   {
333     mAnimation = Animation::New( mIndicatorShowDuration );
334     mAnimation.AnimateTo( Property( mIndicator, Actor::Property::COLOR_ALPHA ), 1.0f, AlphaFunction::EASE_IN );
335     mAnimation.Play();
336   }
337   else
338   {
339     mIndicator.SetOpacity(1.0f);
340   }
341 }
342
343 void ScrollBar::HideIndicator()
344 {
345   // Cancel any animation
346   if(mAnimation)
347   {
348     mAnimation.Clear();
349     mAnimation.Reset();
350   }
351
352   if(mIndicatorHideDuration > 0.0f)
353   {
354     mAnimation = Animation::New( mIndicatorHideDuration );
355     mAnimation.AnimateTo( Property( mIndicator, Actor::Property::COLOR_ALPHA ), 0.0f, AlphaFunction::EASE_IN );
356     mAnimation.Play();
357   }
358   else
359   {
360     mIndicator.SetOpacity(0.0f);
361   }
362 }
363
364 bool ScrollBar::OnPanGestureProcessTick()
365 {
366   // Update the scroll position property.
367   if( mScrollableObject )
368   {
369     mScrollableObject.SetProperty(mPropertyScrollPosition, mCurrentScrollPosition);
370   }
371
372   return true;
373 }
374
375 void ScrollBar::OnPan( Actor source, const PanGesture& gesture )
376 {
377   if(mScrollableObject)
378   {
379     Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast(mScrollableObject);
380
381     switch(gesture.state)
382     {
383       case Gesture::Started:
384       {
385         if( !mPanProcessTimer )
386         {
387           // Make sure the pan gesture is only being processed once per frame.
388           mPanProcessTimer = Timer::New( DEFAULT_PAN_GESTURE_PROCESS_TIME );
389           mPanProcessTimer.TickSignal().Connect( this, &ScrollBar::OnPanGestureProcessTick );
390           mPanProcessTimer.Start();
391         }
392
393         ShowIndicator();
394         mScrollStart = mScrollableObject.GetProperty<float>(mPropertyScrollPosition);
395         mGestureDisplacement = Vector3::ZERO;
396         mIsPanning = true;
397
398         break;
399       }
400       case Gesture::Continuing:
401       {
402         Vector3 delta(gesture.displacement.x, gesture.displacement.y, 0.0f);
403         mGestureDisplacement+=delta;
404
405         Vector3 span = Self().GetCurrentSize() - mIndicator.GetCurrentSize();
406         float minScrollPosition = mScrollableObject.GetProperty<float>(mPropertyMinScrollPosition);
407         float maxScrollPosition = mScrollableObject.GetProperty<float>(mPropertyMaxScrollPosition);
408         float domainSize = maxScrollPosition - minScrollPosition;
409
410         mCurrentScrollPosition = mScrollStart - mGestureDisplacement.y * domainSize / span.y;
411         mCurrentScrollPosition = 0.0f - std::min(maxScrollPosition, std::max(-mCurrentScrollPosition, minScrollPosition));
412
413         break;
414       }
415       default:
416       {
417         mIsPanning = false;
418
419         if( mPanProcessTimer )
420         {
421           // Destroy the timer when pan gesture is finished.
422           mPanProcessTimer.Stop();
423           mPanProcessTimer.TickSignal().Disconnect( this, &ScrollBar::OnPanGestureProcessTick );
424           mPanProcessTimer.Reset();
425         }
426
427         if(itemView)
428         {
429           // Refresh the ItemView cache with extra items
430           GetImpl(itemView).DoRefresh(mCurrentScrollPosition, true);
431         }
432
433         mPanFinishedSignal.Emit();
434
435         break;
436       }
437     }
438
439     if(itemView)
440     {
441       // Disable automatic refresh in ItemView during fast scrolling
442       GetImpl(itemView).SetRefreshEnabled(true);//!mIsPanning);
443     }
444   }
445 }
446
447 void ScrollBar::OnSizeSet( const Vector3& size )
448 {
449   if(mIndicatorHeightPolicy == Toolkit::ScrollBar::Fixed)
450   {
451     mIndicator.SetSize(size.width, mIndicatorFixedHeight);
452   }
453 }
454
455 void ScrollBar::SetScrollDirection( Toolkit::ScrollBar::Direction direction )
456 {
457   mDirection = direction;
458 }
459
460 Toolkit::ScrollBar::Direction ScrollBar::GetScrollDirection() const
461 {
462   return mDirection;
463 }
464
465 void ScrollBar::SetIndicatorHeightPolicy( Toolkit::ScrollBar::IndicatorHeightPolicy policy )
466 {
467   mIndicatorHeightPolicy = policy;
468   ApplyConstraints();
469 }
470
471 Toolkit::ScrollBar::IndicatorHeightPolicy ScrollBar::GetIndicatorHeightPolicy() const
472 {
473   return mIndicatorHeightPolicy;
474 }
475
476 void ScrollBar::SetIndicatorFixedHeight( float height )
477 {
478   mIndicatorFixedHeight = height;
479
480   if(mIndicatorHeightPolicy == Toolkit::ScrollBar::Fixed)
481   {
482     mIndicator.SetSize(Self().GetCurrentSize().width, mIndicatorFixedHeight);
483   }
484 }
485
486 float ScrollBar::GetIndicatorFixedHeight() const
487 {
488   return mIndicatorFixedHeight;
489 }
490
491 void ScrollBar::SetIndicatorShowDuration( float durationSeconds )
492 {
493   mIndicatorShowDuration = durationSeconds;
494 }
495
496 float ScrollBar::GetIndicatorShowDuration() const
497 {
498   return mIndicatorShowDuration;
499 }
500
501 void ScrollBar::SetIndicatorHideDuration( float durationSeconds )
502 {
503   mIndicatorHideDuration = durationSeconds;
504 }
505
506 float ScrollBar::GetIndicatorHideDuration() const
507 {
508   return mIndicatorHideDuration;
509 }
510
511 void ScrollBar::OnScrollDirectionPropertySet( Property::Value propertyValue )
512 {
513   std::string directionName( propertyValue.Get<std::string>() );
514   if(directionName == "Vertical")
515   {
516     SetScrollDirection(Toolkit::ScrollBar::Vertical);
517   }
518   else if(directionName == "Horizontal")
519   {
520     SetScrollDirection(Toolkit::ScrollBar::Horizontal);
521   }
522   else
523   {
524     DALI_ASSERT_ALWAYS( !"ScrollBar::OnScrollDirectionPropertySet(). Invalid Property value." );
525   }
526 }
527
528 void ScrollBar::OnIndicatorHeightPolicyPropertySet( Property::Value propertyValue )
529 {
530   std::string policyName( propertyValue.Get<std::string>() );
531   if(policyName == "Variable")
532   {
533     SetIndicatorHeightPolicy(Toolkit::ScrollBar::Variable);
534   }
535   else if(policyName == "Fixed")
536   {
537     SetIndicatorHeightPolicy(Toolkit::ScrollBar::Fixed);
538   }
539   else
540   {
541     DALI_ASSERT_ALWAYS( !"ScrollBar::OnIndicatorHeightPolicyPropertySet(). Invalid Property value." );
542   }
543 }
544
545 bool ScrollBar::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
546 {
547   Dali::BaseHandle handle( object );
548
549   bool connected( true );
550   Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast( handle );
551
552   if( 0 == strcmp( signalName.c_str(), PAN_FINISHED_SIGNAL ) )
553   {
554     scrollBar.PanFinishedSignal().Connect( tracker, functor );
555   }
556   else if( 0 == strcmp( signalName.c_str(), SCROLL_POSITION_INTERVAL_REACHED_SIGNAL ) )
557   {
558     scrollBar.ScrollPositionIntervalReachedSignal().Connect( tracker, functor );
559   }
560   else
561   {
562     // signalName does not match any signal
563     connected = false;
564   }
565
566   return connected;
567 }
568
569 void ScrollBar::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
570 {
571   Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast( Dali::BaseHandle( object ) );
572
573   if( scrollBar )
574   {
575     ScrollBar& scrollBarImpl( GetImpl( scrollBar ) );
576     switch( index )
577     {
578       case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
579       {
580         scrollBarImpl.OnScrollDirectionPropertySet( value );
581         break;
582       }
583       case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
584       {
585         scrollBarImpl.OnIndicatorHeightPolicyPropertySet( value );
586         break;
587       }
588       case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
589       {
590         scrollBarImpl.SetIndicatorFixedHeight(value.Get<float>());
591         break;
592       }
593       case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
594       {
595         scrollBarImpl.SetIndicatorShowDuration(value.Get<float>());
596         break;
597       }
598       case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
599       {
600         scrollBarImpl.SetIndicatorHideDuration(value.Get<float>());
601         break;
602       }
603       case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
604       {
605         Property::Array* array = value.GetArray();
606         if( array )
607         {
608           Dali::Vector<float> positions;
609           size_t positionCount = array->Count();
610           positions.Resize( positionCount );
611           for( size_t i = 0; i != positionCount; ++i )
612           {
613             array->GetElementAt( i ).Get( positions[i] );
614           }
615
616           scrollBarImpl.SetScrollPositionIntervals(positions);
617         }
618         break;
619       }
620     }
621   }
622 }
623
624 Property::Value ScrollBar::GetProperty( BaseObject* object, Property::Index index )
625 {
626   Property::Value value;
627
628   Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast( Dali::BaseHandle( object ) );
629
630   if( scrollBar )
631   {
632     ScrollBar& scrollBarImpl( GetImpl( scrollBar ) );
633     switch( index )
634     {
635       case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
636       {
637         value = SCROLL_DIRECTION_NAME[ scrollBarImpl.GetScrollDirection() ];
638         break;
639       }
640       case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
641       {
642         value = INDICATOR_HEIGHT_POLICY_NAME[ scrollBarImpl.GetIndicatorHeightPolicy() ];
643         break;
644       }
645       case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
646       {
647         value = scrollBarImpl.GetIndicatorFixedHeight();
648         break;
649       }
650       case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
651       {
652         value = scrollBarImpl.GetIndicatorShowDuration();
653         break;
654       }
655       case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
656       {
657         value = scrollBarImpl.GetIndicatorHideDuration();
658         break;
659       }
660       case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
661       {
662         Property::Value value( Property::ARRAY );
663         Property::Array* array = value.GetArray();
664         Dali::Vector<float> positions = scrollBarImpl.GetScrollPositionIntervals();
665         size_t positionCount( array->Count() );
666         for( size_t i( 0 ); i != positionCount; ++i )
667         {
668           array->PushBack( positions[i] );
669         }
670         break;
671       }
672     }
673   }
674   return value;
675 }
676
677 Toolkit::ScrollBar ScrollBar::New(Toolkit::ScrollBar::Direction direction)
678 {
679   // Create the implementation, temporarily owned by this handle on stack
680   IntrusivePtr< ScrollBar > impl = new ScrollBar(direction);
681
682   // Pass ownership to CustomActor handle
683   Toolkit::ScrollBar handle( *impl );
684
685   // Second-phase init of the implementation
686   // This can only be done after the CustomActor connection has been made...
687   impl->Initialize();
688
689   return handle;
690 }
691
692 } // namespace Internal
693
694 } // namespace Toolkit
695
696 } // namespace Dali