2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.h>
22 #include <dali/devel-api/actors/actor-devel.h>
23 #include <dali/devel-api/object/property-helper-devel.h>
24 #include <dali/integration-api/debug.h>
25 #include <dali/public-api/animation/constraint.h>
26 #include <dali/public-api/animation/constraints.h>
27 #include <dali/public-api/object/property-array.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/public-api/object/type-registry.h>
30 #include <cstring> // for strcmp
33 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
34 #include <dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h>
35 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
41 const char* DEFAULT_INDICATOR_IMAGE_FILE_NAME = "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);
53 * Indicator size constraint
54 * Indicator size depends on both indicator's parent size and the scroll content size
56 struct IndicatorSizeConstraint
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
62 IndicatorSizeConstraint(float minimumHeight, float padding)
63 : mMinimumHeight(minimumHeight),
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.
74 void operator()(Vector3& current, const PropertyInputContainer& inputs)
76 const Vector3& parentSize = inputs[0]->GetVector3();
77 const float contentSize = inputs[1]->GetFloat();
79 // Take into account padding that may exist at the beginning and end of the indicator.
80 const float parentHeightMinusPadding = parentSize.height - mPadding;
82 float height = contentSize > parentHeightMinusPadding ? parentHeightMinusPadding * (parentHeightMinusPadding / contentSize) : parentHeightMinusPadding * ((parentHeightMinusPadding - contentSize * 0.5f) / parentHeightMinusPadding);
84 current.y = std::max(mMinimumHeight, height);
92 * Indicator position constraint
93 * Positions the indicator to reflect the current scroll position within the scroll domain.
95 struct IndicatorPositionConstraint
98 * @param[in] startPadding The padding at the start of the indicator
99 * @param[in] endPadding The padding at the end of the indicator
101 IndicatorPositionConstraint(float startPadding, float endPadding)
102 : mStartPadding(startPadding),
103 mEndPadding(endPadding)
108 * Constraint operator
109 * @param[in,out] current The current indicator position
110 * @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)
111 * @return The new indicator position is returned.
113 void operator()(Vector3& current, const PropertyInputContainer& inputs)
115 const Vector3& indicatorSize = inputs[0]->GetVector3();
116 const Vector3& parentSize = inputs[1]->GetVector3();
117 const float scrollPosition = -inputs[2]->GetFloat();
118 const float minimumScrollPosition = inputs[3]->GetFloat();
119 const float maximumScrollPosition = inputs[4]->GetFloat();
121 // Take into account padding that may exist at the beginning and end of the indicator.
122 const float parentHeightMinusPadding = parentSize.height - (mStartPadding + mEndPadding);
124 float relativePosition = std::max(0.0f, std::min(1.0f, (scrollPosition - minimumScrollPosition) / (maximumScrollPosition - minimumScrollPosition)));
125 current.y = mStartPadding + (parentHeightMinusPadding - indicatorSize.height) * relativePosition;
126 current.z = DEFAULT_SLIDER_DEPTH;
133 } // unnamed namespace
143 using namespace Dali;
147 return Toolkit::ScrollBar::New();
151 // Setup properties, signals and actions using the type-registry.
152 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ScrollBar, Toolkit::Control, Create );
154 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "scrollDirection", STRING, SCROLL_DIRECTION )
155 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorHeightPolicy", STRING, INDICATOR_HEIGHT_POLICY )
156 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorFixedHeight", FLOAT, INDICATOR_FIXED_HEIGHT )
157 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorShowDuration", FLOAT, INDICATOR_SHOW_DURATION )
158 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorHideDuration", FLOAT, INDICATOR_HIDE_DURATION )
159 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "scrollPositionIntervals", ARRAY, SCROLL_POSITION_INTERVALS )
160 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorMinimumHeight", FLOAT, INDICATOR_MINIMUM_HEIGHT )
161 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorStartPadding", FLOAT, INDICATOR_START_PADDING )
162 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorEndPadding", FLOAT, INDICATOR_END_PADDING )
163 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorTransientDuration", FLOAT, INDICATOR_TRANSIENT_DURATION)
165 DALI_SIGNAL_REGISTRATION(Toolkit, ScrollBar, "panFinished", PAN_FINISHED_SIGNAL )
166 DALI_SIGNAL_REGISTRATION(Toolkit, ScrollBar, "scrollPositionIntervalReached", SCROLL_POSITION_INTERVAL_REACHED_SIGNAL)
168 DALI_ACTION_REGISTRATION(Toolkit, ScrollBar, "ShowIndicator", ACTION_SHOW_INDICATOR )
169 DALI_ACTION_REGISTRATION(Toolkit, ScrollBar, "HideIndicator", ACTION_HIDE_INDICATOR )
170 DALI_ACTION_REGISTRATION(Toolkit, ScrollBar, "ShowTransientIndicator", ACTION_SHOW_TRANSIENT_INDICATOR)
172 DALI_TYPE_REGISTRATION_END()
175 const char* SCROLL_DIRECTION_NAME[] = {"VERTICAL", "HORIZONTAL"};
176 const char* INDICATOR_HEIGHT_POLICY_NAME[] = {"VARIABLE", "FIXED"};
180 ScrollBar::ScrollBar(Toolkit::ScrollBar::Direction direction)
181 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
182 mIndicatorShowAlpha(1.0f),
183 mDirection(direction),
184 mScrollableObject(WeakHandle<Handle>()),
185 mPropertyScrollPosition(Property::INVALID_INDEX),
186 mPropertyMinScrollPosition(Property::INVALID_INDEX),
187 mPropertyMaxScrollPosition(Property::INVALID_INDEX),
188 mPropertyScrollContentSize(Property::INVALID_INDEX),
189 mIndicatorShowDuration(DEFAULT_INDICATOR_SHOW_DURATION),
190 mIndicatorHideDuration(DEFAULT_INDICATOR_HIDE_DURATION),
191 mTransientIndicatorDuration(DEFAULT_INDICATOR_TRANSIENT_DURATION),
193 mGestureDisplacement(Vector2::ZERO),
194 mCurrentScrollPosition(0.0f),
195 mIndicatorHeightPolicy(Toolkit::ScrollBar::VARIABLE),
196 mIndicatorFixedHeight(DEFAULT_INDICATOR_FIXED_HEIGHT),
197 mIndicatorMinimumHeight(DEFAULT_INDICATOR_MINIMUM_HEIGHT),
198 mIndicatorStartPadding(DEFAULT_INDICATOR_START_PADDING),
199 mIndicatorEndPadding(DEFAULT_INDICATOR_END_PADDING),
201 mIndicatorFirstShow(true)
205 ScrollBar::~ScrollBar()
209 void ScrollBar::OnInitialize()
211 CreateDefaultIndicatorActor();
212 Self().SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
214 DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
215 return std::unique_ptr<Dali::Accessibility::Accessible>(
216 new AccessibleImpl(actor, Dali::Accessibility::Role::SCROLL_BAR));
220 void ScrollBar::SetScrollPropertySource(Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize)
222 if(handle && propertyScrollPosition != Property::INVALID_INDEX && propertyMinScrollPosition != Property::INVALID_INDEX && propertyMaxScrollPosition != Property::INVALID_INDEX && propertyScrollContentSize != Property::INVALID_INDEX)
224 mScrollableObject = WeakHandle<Handle>(handle);
225 mPropertyScrollPosition = propertyScrollPosition;
226 mPropertyMinScrollPosition = propertyMinScrollPosition;
227 mPropertyMaxScrollPosition = propertyMaxScrollPosition;
228 mPropertyScrollContentSize = propertyScrollContentSize;
234 DALI_LOG_ERROR("Can not set empty handle of source object or invalid source property index\n");
238 void ScrollBar::CreateDefaultIndicatorActor()
240 const std::string imageDirPath = AssetManager::GetDaliImagePath();
241 Toolkit::ImageView indicator = Toolkit::ImageView::New(imageDirPath + DEFAULT_INDICATOR_IMAGE_FILE_NAME);
242 indicator.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
243 indicator.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
244 indicator.SetStyleName("ScrollBarIndicator");
245 indicator.SetProperty(Actor::Property::COLOR_MODE, USE_OWN_MULTIPLY_PARENT_COLOR);
246 SetScrollIndicator(indicator);
249 void ScrollBar::SetScrollIndicator(Actor indicator)
251 // Don't allow empty handle
254 // Remove current Indicator
257 Self().Remove(mIndicator);
259 mIndicator = indicator;
261 mIndicatorFirstShow = true;
262 Self().Add(mIndicator);
264 EnableGestureDetection(GestureType::Value(GestureType::PAN));
266 PanGestureDetector detector(GetPanGestureDetector());
267 detector.DetachAll();
268 detector.Attach(mIndicator);
270 unsigned int childCount = mIndicator.GetChildCount();
271 for(unsigned int index = 0; index < childCount; index++)
273 Actor child = mIndicator.GetChildAt(index);
276 detector.Attach(child);
282 DALI_LOG_ERROR("Empty handle of scroll indicator\n");
286 Actor ScrollBar::GetScrollIndicator()
291 void ScrollBar::ApplyConstraints()
293 Handle scrollableHandle = mScrollableObject.GetHandle();
297 if(mIndicatorSizeConstraint)
299 mIndicatorSizeConstraint.Remove();
302 // Set indicator height according to the indicator's height policy
303 if(mIndicatorHeightPolicy == Toolkit::ScrollBar::FIXED)
305 mIndicator.SetProperty(Actor::Property::SIZE, Vector2(Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE).width, mIndicatorFixedHeight));
309 mIndicatorSizeConstraint = Constraint::New<Vector3>(mIndicator, Actor::Property::SIZE, IndicatorSizeConstraint(mIndicatorMinimumHeight, mIndicatorStartPadding + mIndicatorEndPadding));
310 mIndicatorSizeConstraint.AddSource(ParentSource(Actor::Property::SIZE));
311 mIndicatorSizeConstraint.AddSource(Source(scrollableHandle, mPropertyScrollContentSize));
312 mIndicatorSizeConstraint.Apply();
315 if(mIndicatorPositionConstraint)
317 mIndicatorPositionConstraint.Remove();
320 mIndicatorPositionConstraint = Constraint::New<Vector3>(mIndicator, Actor::Property::POSITION, IndicatorPositionConstraint(mIndicatorStartPadding, mIndicatorEndPadding));
321 mIndicatorPositionConstraint.AddSource(LocalSource(Actor::Property::SIZE));
322 mIndicatorPositionConstraint.AddSource(ParentSource(Actor::Property::SIZE));
323 mIndicatorPositionConstraint.AddSource(Source(scrollableHandle, mPropertyScrollPosition));
324 mIndicatorPositionConstraint.AddSource(Source(scrollableHandle, mPropertyMinScrollPosition));
325 mIndicatorPositionConstraint.AddSource(Source(scrollableHandle, mPropertyMaxScrollPosition));
326 mIndicatorPositionConstraint.Apply();
330 void ScrollBar::SetScrollPositionIntervals(const Dali::Vector<float>& positions)
332 mScrollPositionIntervals = positions;
334 Handle scrollableHandle = mScrollableObject.GetHandle();
338 if(mPositionNotification)
340 scrollableHandle.RemovePropertyNotification(mPositionNotification);
343 mPositionNotification = scrollableHandle.AddPropertyNotification(mPropertyScrollPosition, VariableStepCondition(mScrollPositionIntervals));
344 mPositionNotification.NotifySignal().Connect(this, &ScrollBar::OnScrollPositionIntervalReached);
348 Dali::Vector<float> ScrollBar::GetScrollPositionIntervals() const
350 return mScrollPositionIntervals;
353 void ScrollBar::OnScrollPositionIntervalReached(PropertyNotification& source)
355 // Emit the signal to notify the scroll position crossing
356 Handle scrollableHandle = mScrollableObject.GetHandle();
359 mScrollPositionIntervalReachedSignal.Emit(scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition));
360 if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
362 Control::Impl::GetAccessibilityObject(Self())->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
367 void ScrollBar::ShowIndicator()
369 // Cancel any animation
376 if(mIndicatorFirstShow)
378 // Preserve the alpha value from the stylesheet
379 mIndicatorShowAlpha = Self().GetCurrentProperty<Vector4>(Actor::Property::COLOR).a;
380 mIndicatorFirstShow = false;
383 if(mIndicatorShowDuration > 0.0f)
385 mAnimation = Animation::New(mIndicatorShowDuration);
386 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA), mIndicatorShowAlpha, AlphaFunction::EASE_IN);
391 mIndicator.SetProperty(Actor::Property::OPACITY, mIndicatorShowAlpha);
395 void ScrollBar::HideIndicator()
397 // Cancel any animation
404 if(mIndicatorHideDuration > 0.0f)
406 mAnimation = Animation::New(mIndicatorHideDuration);
407 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA), 0.0f, AlphaFunction::EASE_IN);
412 mIndicator.SetProperty(Actor::Property::OPACITY, 0.0f);
416 void ScrollBar::ShowTransientIndicator()
418 // Cancel any animation
425 mAnimation = Animation::New(mIndicatorShowDuration + mTransientIndicatorDuration + mIndicatorHideDuration);
426 if(mIndicatorShowDuration > 0.0f)
428 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA),
430 AlphaFunction::EASE_IN,
431 TimePeriod(0, mIndicatorShowDuration));
435 mIndicator.SetProperty(Actor::Property::OPACITY, mIndicatorShowAlpha);
437 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA),
439 AlphaFunction::EASE_IN,
440 TimePeriod((mIndicatorShowDuration + mTransientIndicatorDuration), mIndicatorHideDuration));
444 bool ScrollBar::OnPanGestureProcessTick()
446 // Update the scroll position property.
447 Handle scrollableHandle = mScrollableObject.GetHandle();
450 scrollableHandle.SetProperty(mPropertyScrollPosition, mCurrentScrollPosition);
456 void ScrollBar::OnPan(const PanGesture& gesture)
458 Handle scrollableHandle = mScrollableObject.GetHandle();
462 Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast(scrollableHandle);
464 switch(gesture.GetState())
466 case Dali::GestureState::STARTED:
468 if(!mPanProcessTimer)
470 // Make sure the pan gesture is only being processed once per frame.
471 mPanProcessTimer = Timer::New(DEFAULT_PAN_GESTURE_PROCESS_TIME);
472 mPanProcessTimer.TickSignal().Connect(this, &ScrollBar::OnPanGestureProcessTick);
473 mPanProcessTimer.Start();
477 mScrollStart = scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition);
478 mGestureDisplacement = Vector2::ZERO;
483 case Dali::GestureState::CONTINUING:
485 mGestureDisplacement += gesture.GetDisplacement();
487 float minScrollPosition = scrollableHandle.GetCurrentProperty<float>(mPropertyMinScrollPosition);
488 float maxScrollPosition = scrollableHandle.GetCurrentProperty<float>(mPropertyMaxScrollPosition);
490 // The domain size is the internal range
491 float domainSize = maxScrollPosition - minScrollPosition;
492 float logicalSize = Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE).y - (mIndicator.GetCurrentProperty<Vector3>(Actor::Property::SIZE).y + mIndicatorStartPadding + mIndicatorEndPadding);
494 mCurrentScrollPosition = mScrollStart - ((mGestureDisplacement.y * domainSize) / logicalSize);
495 mCurrentScrollPosition = -std::min(maxScrollPosition, std::max(-mCurrentScrollPosition, minScrollPosition));
505 // Destroy the timer when pan gesture is finished.
506 mPanProcessTimer.Stop();
507 mPanProcessTimer.TickSignal().Disconnect(this, &ScrollBar::OnPanGestureProcessTick);
508 mPanProcessTimer.Reset();
513 // Refresh the ItemView cache with extra items
514 GetImpl(itemView).DoRefresh(mCurrentScrollPosition, true);
517 mPanFinishedSignal.Emit();
525 // Disable automatic refresh in ItemView during fast scrolling
526 GetImpl(itemView).SetRefreshEnabled(!mIsPanning);
531 void ScrollBar::OnSizeSet(const Vector3& size)
533 if(mIndicatorHeightPolicy == Toolkit::ScrollBar::FIXED)
535 mIndicator.SetProperty(Actor::Property::SIZE, Vector2(size.width, mIndicatorFixedHeight));
538 Control::OnSizeSet(size);
541 void ScrollBar::SetScrollDirection(Toolkit::ScrollBar::Direction direction)
543 mDirection = direction;
546 Toolkit::ScrollBar::Direction ScrollBar::GetScrollDirection() const
551 void ScrollBar::SetIndicatorHeightPolicy(Toolkit::ScrollBar::IndicatorHeightPolicy policy)
553 if(policy != mIndicatorHeightPolicy)
555 mIndicatorHeightPolicy = policy;
560 Toolkit::ScrollBar::IndicatorHeightPolicy ScrollBar::GetIndicatorHeightPolicy() const
562 return mIndicatorHeightPolicy;
565 void ScrollBar::SetIndicatorFixedHeight(float height)
567 mIndicatorFixedHeight = height;
569 if(mIndicatorHeightPolicy == Toolkit::ScrollBar::FIXED)
571 mIndicator.SetProperty(Actor::Property::SIZE, Vector2(Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE).width, mIndicatorFixedHeight));
575 float ScrollBar::GetIndicatorFixedHeight() const
577 return mIndicatorFixedHeight;
580 void ScrollBar::SetIndicatorShowDuration(float durationSeconds)
582 mIndicatorShowDuration = durationSeconds;
585 float ScrollBar::GetIndicatorShowDuration() const
587 return mIndicatorShowDuration;
590 void ScrollBar::SetIndicatorHideDuration(float durationSeconds)
592 mIndicatorHideDuration = durationSeconds;
595 float ScrollBar::GetIndicatorHideDuration() const
597 return mIndicatorHideDuration;
600 void ScrollBar::OnScrollDirectionPropertySet(Property::Value propertyValue)
602 std::string directionName(propertyValue.Get<std::string>());
603 if(directionName == "VERTICAL")
605 SetScrollDirection(Toolkit::ScrollBar::VERTICAL);
607 else if(directionName == "HORIZONTAL")
609 SetScrollDirection(Toolkit::ScrollBar::HORIZONTAL);
613 DALI_ASSERT_ALWAYS(!"ScrollBar::OnScrollDirectionPropertySet(). Invalid Property value.");
617 void ScrollBar::OnIndicatorHeightPolicyPropertySet(Property::Value propertyValue)
619 std::string policyName(propertyValue.Get<std::string>());
620 if(policyName == "VARIABLE")
622 SetIndicatorHeightPolicy(Toolkit::ScrollBar::VARIABLE);
624 else if(policyName == "FIXED")
626 SetIndicatorHeightPolicy(Toolkit::ScrollBar::FIXED);
630 DALI_ASSERT_ALWAYS(!"ScrollBar::OnIndicatorHeightPolicyPropertySet(). Invalid Property value.");
634 bool ScrollBar::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
636 Dali::BaseHandle handle(object);
638 bool connected(true);
639 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(handle);
641 if(0 == strcmp(signalName.c_str(), PAN_FINISHED_SIGNAL))
643 scrollBar.PanFinishedSignal().Connect(tracker, functor);
645 else if(0 == strcmp(signalName.c_str(), SCROLL_POSITION_INTERVAL_REACHED_SIGNAL))
647 scrollBar.ScrollPositionIntervalReachedSignal().Connect(tracker, functor);
651 // signalName does not match any signal
658 void ScrollBar::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
660 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(Dali::BaseHandle(object));
664 ScrollBar& scrollBarImpl(GetImpl(scrollBar));
667 case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
669 scrollBarImpl.OnScrollDirectionPropertySet(value);
672 case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
674 scrollBarImpl.OnIndicatorHeightPolicyPropertySet(value);
677 case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
679 scrollBarImpl.SetIndicatorFixedHeight(value.Get<float>());
682 case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
684 scrollBarImpl.SetIndicatorShowDuration(value.Get<float>());
687 case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
689 scrollBarImpl.SetIndicatorHideDuration(value.Get<float>());
692 case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
694 const Property::Array* array = value.GetArray();
697 Dali::Vector<float> positions;
698 size_t positionCount = array->Count();
699 positions.Resize(positionCount);
700 for(size_t i = 0; i != positionCount; ++i)
702 array->GetElementAt(i).Get(positions[i]);
705 scrollBarImpl.SetScrollPositionIntervals(positions);
709 case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
711 scrollBarImpl.mIndicatorMinimumHeight = value.Get<float>();
712 scrollBarImpl.ApplyConstraints();
715 case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
717 scrollBarImpl.mIndicatorStartPadding = value.Get<float>();
718 scrollBarImpl.ApplyConstraints();
721 case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
723 scrollBarImpl.mIndicatorEndPadding = value.Get<float>();
724 scrollBarImpl.ApplyConstraints();
727 case Toolkit::ScrollBar::Property::INDICATOR_TRANSIENT_DURATION:
729 scrollBarImpl.mTransientIndicatorDuration = value.Get<float>();
736 Property::Value ScrollBar::GetProperty(BaseObject* object, Property::Index index)
738 Property::Value value;
740 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(Dali::BaseHandle(object));
744 ScrollBar& scrollBarImpl(GetImpl(scrollBar));
747 case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
749 value = SCROLL_DIRECTION_NAME[scrollBarImpl.GetScrollDirection()];
752 case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
754 value = INDICATOR_HEIGHT_POLICY_NAME[scrollBarImpl.GetIndicatorHeightPolicy()];
757 case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
759 value = scrollBarImpl.GetIndicatorFixedHeight();
762 case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
764 value = scrollBarImpl.GetIndicatorShowDuration();
767 case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
769 value = scrollBarImpl.GetIndicatorHideDuration();
772 case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
774 Property::Value tempValue(Property::ARRAY);
775 Property::Array* array = tempValue.GetArray();
779 Dali::Vector<float> positions = scrollBarImpl.GetScrollPositionIntervals();
780 size_t positionCount(positions.Count());
782 for(size_t i(0); i != positionCount; ++i)
784 array->PushBack(positions[i]);
791 case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
793 value = scrollBarImpl.mIndicatorMinimumHeight;
796 case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
798 value = scrollBarImpl.mIndicatorStartPadding;
801 case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
803 value = scrollBarImpl.mIndicatorEndPadding;
806 case Toolkit::ScrollBar::Property::INDICATOR_TRANSIENT_DURATION:
808 value = scrollBarImpl.mTransientIndicatorDuration;
816 bool ScrollBar::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& attributes)
820 Dali::BaseHandle handle(object);
822 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(handle);
824 DALI_ASSERT_DEBUG(scrollBar);
828 if(0 == strcmp(actionName.c_str(), ACTION_SHOW_INDICATOR))
830 GetImpl(scrollBar).ShowIndicator();
833 else if(0 == strcmp(actionName.c_str(), ACTION_HIDE_INDICATOR))
835 GetImpl(scrollBar).HideIndicator();
838 else if(0 == strcmp(actionName.c_str(), ACTION_SHOW_TRANSIENT_INDICATOR))
840 GetImpl(scrollBar).ShowTransientIndicator();
848 Toolkit::ScrollBar ScrollBar::New(Toolkit::ScrollBar::Direction direction)
850 // Create the implementation, temporarily owned by this handle on stack
851 IntrusivePtr<ScrollBar> impl = new ScrollBar(direction);
853 // Pass ownership to CustomActor handle
854 Toolkit::ScrollBar handle(*impl);
856 // Second-phase init of the implementation
857 // This can only be done after the CustomActor connection has been made...
863 double ScrollBar::AccessibleImpl::GetMinimum()
865 auto p = Toolkit::ScrollBar::DownCast(self);
866 Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
867 return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(p).mPropertyMinScrollPosition) : 0.0f;
870 double ScrollBar::AccessibleImpl::GetCurrent()
872 auto p = Toolkit::ScrollBar::DownCast(self);
873 Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
874 return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(p).mPropertyScrollPosition) : 0.0f;
877 double ScrollBar::AccessibleImpl::GetMaximum()
879 auto p = Toolkit::ScrollBar::DownCast(self);
880 Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
881 return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(p).mPropertyMaxScrollPosition) : 1.0f;
884 bool ScrollBar::AccessibleImpl::SetCurrent(double current)
886 if(current < GetMinimum() || current > GetMaximum())
889 auto value_before = GetCurrent();
891 auto p = Toolkit::ScrollBar::DownCast(self);
892 Handle scrollableHandle = GetImpl(p).mScrollableObject.GetHandle();
893 if(!scrollableHandle)
895 scrollableHandle.SetProperty(GetImpl(p).mPropertyScrollPosition, static_cast<float>(current));
897 auto value_after = GetCurrent();
899 if((current != value_before) && (value_before == value_after))
905 double ScrollBar::AccessibleImpl::GetMinimumIncrement()
910 } // namespace Internal
912 } // namespace Toolkit