2 * Copyright (c) 2024 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/math/math-utils.h>
28 #include <dali/public-api/object/property-array.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30 #include <dali/public-api/object/type-registry.h>
31 #include <cstring> // for strcmp
34 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
35 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
36 #include <dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h>
37 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
43 const char* DEFAULT_INDICATOR_IMAGE_FILE_NAME = "popup_scroll.9.png";
44 const float DEFAULT_SLIDER_DEPTH(1.0f);
45 const float DEFAULT_INDICATOR_SHOW_DURATION(0.5f);
46 const float DEFAULT_INDICATOR_HIDE_DURATION(0.5f);
47 const float DEFAULT_PAN_GESTURE_PROCESS_TIME(16.7f); // 16.7 milliseconds, i.e. one frame
48 const float DEFAULT_INDICATOR_FIXED_HEIGHT(80.0f);
49 const float DEFAULT_INDICATOR_MINIMUM_HEIGHT(0.0f);
50 const float DEFAULT_INDICATOR_START_PADDING(0.0f);
51 const float DEFAULT_INDICATOR_END_PADDING(0.0f);
52 const float DEFAULT_INDICATOR_TRANSIENT_DURATION(1.0f);
55 * Indicator size constraint
56 * Indicator size depends on both indicator's parent size and the scroll content size
58 struct IndicatorSizeConstraint
61 * @param[in] minimumHeight The minimum height for the indicator
62 * @param[in] padding The sum of the padding at the start & end of the indicator
64 IndicatorSizeConstraint(float minimumHeight, float padding)
65 : mMinimumHeight(minimumHeight),
72 * @param[in] current The current indicator size
73 * @param[in] parentSizeProperty The parent size of scroll indicator.
74 * @return The new scroll indicator size.
76 void operator()(Vector3& current, const PropertyInputContainer& inputs)
78 const Vector3& parentSize = inputs[0]->GetVector3();
79 const float contentSize = inputs[1]->GetFloat();
81 // Take into account padding that may exist at the beginning and end of the indicator.
82 const float parentHeightMinusPadding = parentSize.height - mPadding;
84 float height = contentSize > parentHeightMinusPadding ? parentHeightMinusPadding * (parentHeightMinusPadding / contentSize) : parentHeightMinusPadding * ((parentHeightMinusPadding - contentSize * 0.5f) / parentHeightMinusPadding);
86 current.y = std::max(mMinimumHeight, height);
94 * Indicator position constraint
95 * Positions the indicator to reflect the current scroll position within the scroll domain.
97 struct IndicatorPositionConstraint
100 * @param[in] startPadding The padding at the start of the indicator
101 * @param[in] endPadding The padding at the end of the indicator
103 IndicatorPositionConstraint(float startPadding, float endPadding)
104 : mStartPadding(startPadding),
105 mEndPadding(endPadding)
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.
115 void operator()(Vector3& current, const PropertyInputContainer& inputs)
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();
123 // Take into account padding that may exist at the beginning and end of the indicator.
124 const float parentHeightMinusPadding = parentSize.height - (mStartPadding + mEndPadding);
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;
135 } // unnamed namespace
145 using namespace Dali;
149 return Toolkit::ScrollBar::New();
153 // Setup properties, signals and actions using the type-registry.
154 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ScrollBar, Toolkit::Control, Create );
156 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "scrollDirection", STRING, SCROLL_DIRECTION )
157 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorHeightPolicy", STRING, INDICATOR_HEIGHT_POLICY )
158 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorFixedHeight", FLOAT, INDICATOR_FIXED_HEIGHT )
159 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorShowDuration", FLOAT, INDICATOR_SHOW_DURATION )
160 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorHideDuration", FLOAT, INDICATOR_HIDE_DURATION )
161 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "scrollPositionIntervals", ARRAY, SCROLL_POSITION_INTERVALS )
162 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorMinimumHeight", FLOAT, INDICATOR_MINIMUM_HEIGHT )
163 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorStartPadding", FLOAT, INDICATOR_START_PADDING )
164 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorEndPadding", FLOAT, INDICATOR_END_PADDING )
165 DALI_PROPERTY_REGISTRATION(Toolkit, ScrollBar, "indicatorTransientDuration", FLOAT, INDICATOR_TRANSIENT_DURATION)
167 DALI_SIGNAL_REGISTRATION(Toolkit, ScrollBar, "panFinished", PAN_FINISHED_SIGNAL )
168 DALI_SIGNAL_REGISTRATION(Toolkit, ScrollBar, "scrollPositionIntervalReached", SCROLL_POSITION_INTERVAL_REACHED_SIGNAL)
170 DALI_ACTION_REGISTRATION(Toolkit, ScrollBar, "ShowIndicator", ACTION_SHOW_INDICATOR )
171 DALI_ACTION_REGISTRATION(Toolkit, ScrollBar, "HideIndicator", ACTION_HIDE_INDICATOR )
172 DALI_ACTION_REGISTRATION(Toolkit, ScrollBar, "ShowTransientIndicator", ACTION_SHOW_TRANSIENT_INDICATOR)
174 DALI_TYPE_REGISTRATION_END()
177 const char* SCROLL_DIRECTION_NAME[] = {"VERTICAL", "HORIZONTAL"};
178 const char* INDICATOR_HEIGHT_POLICY_NAME[] = {"VARIABLE", "FIXED"};
182 ScrollBar::ScrollBar(Toolkit::ScrollBar::Direction direction)
183 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
184 mIndicatorShowAlpha(1.0f),
185 mDirection(direction),
186 mScrollableObject(WeakHandle<Handle>()),
187 mPropertyScrollPosition(Property::INVALID_INDEX),
188 mPropertyMinScrollPosition(Property::INVALID_INDEX),
189 mPropertyMaxScrollPosition(Property::INVALID_INDEX),
190 mPropertyScrollContentSize(Property::INVALID_INDEX),
191 mIndicatorShowDuration(DEFAULT_INDICATOR_SHOW_DURATION),
192 mIndicatorHideDuration(DEFAULT_INDICATOR_HIDE_DURATION),
193 mTransientIndicatorDuration(DEFAULT_INDICATOR_TRANSIENT_DURATION),
195 mGestureDisplacement(Vector2::ZERO),
196 mCurrentScrollPosition(0.0f),
197 mIndicatorHeightPolicy(Toolkit::ScrollBar::VARIABLE),
198 mIndicatorFixedHeight(DEFAULT_INDICATOR_FIXED_HEIGHT),
199 mIndicatorMinimumHeight(DEFAULT_INDICATOR_MINIMUM_HEIGHT),
200 mIndicatorStartPadding(DEFAULT_INDICATOR_START_PADDING),
201 mIndicatorEndPadding(DEFAULT_INDICATOR_END_PADDING),
203 mIndicatorFirstShow(true)
207 ScrollBar::~ScrollBar()
211 void ScrollBar::OnInitialize()
215 CreateDefaultIndicatorActor();
216 self.SetProperty(Actor::Property::DRAW_MODE, DrawMode::OVERLAY_2D);
218 self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::SCROLL_BAR);
221 DevelControl::ControlAccessible* ScrollBar::CreateAccessibleObject()
223 return new ScrollBarAccessible(Self());
226 void ScrollBar::SetScrollPropertySource(Handle handle, Property::Index propertyScrollPosition, Property::Index propertyMinScrollPosition, Property::Index propertyMaxScrollPosition, Property::Index propertyScrollContentSize)
228 if(handle && propertyScrollPosition != Property::INVALID_INDEX && propertyMinScrollPosition != Property::INVALID_INDEX && propertyMaxScrollPosition != Property::INVALID_INDEX && propertyScrollContentSize != Property::INVALID_INDEX)
230 mScrollableObject = WeakHandle<Handle>(handle);
231 mPropertyScrollPosition = propertyScrollPosition;
232 mPropertyMinScrollPosition = propertyMinScrollPosition;
233 mPropertyMaxScrollPosition = propertyMaxScrollPosition;
234 mPropertyScrollContentSize = propertyScrollContentSize;
240 DALI_LOG_ERROR("Can not set empty handle of source object or invalid source property index\n");
244 void ScrollBar::CreateDefaultIndicatorActor()
246 const std::string imageDirPath = AssetManager::GetDaliImagePath();
247 Toolkit::ImageView indicator = Toolkit::ImageView::New(imageDirPath + DEFAULT_INDICATOR_IMAGE_FILE_NAME);
248 indicator.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
249 indicator.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
250 indicator.SetStyleName("ScrollBarIndicator");
251 indicator.SetProperty(Actor::Property::COLOR_MODE, USE_OWN_MULTIPLY_PARENT_COLOR);
252 SetScrollIndicator(indicator);
255 void ScrollBar::SetScrollIndicator(Actor indicator)
257 // Don't allow empty handle
260 // Remove current Indicator
263 Self().Remove(mIndicator);
265 mIndicator = indicator;
267 mIndicatorFirstShow = true;
268 Self().Add(mIndicator);
270 EnableGestureDetection(GestureType::Value(GestureType::PAN));
272 PanGestureDetector detector(GetPanGestureDetector());
273 detector.DetachAll();
274 detector.Attach(mIndicator);
276 unsigned int childCount = mIndicator.GetChildCount();
277 for(unsigned int index = 0; index < childCount; index++)
279 Actor child = mIndicator.GetChildAt(index);
282 detector.Attach(child);
288 DALI_LOG_ERROR("Empty handle of scroll indicator\n");
292 Actor ScrollBar::GetScrollIndicator()
297 void ScrollBar::ApplyConstraints()
299 Handle scrollableHandle = mScrollableObject.GetHandle();
303 if(mIndicatorSizeConstraint)
305 mIndicatorSizeConstraint.Remove();
308 // Set indicator height according to the indicator's height policy
309 if(mIndicatorHeightPolicy == Toolkit::ScrollBar::FIXED)
311 mIndicator.SetProperty(Actor::Property::SIZE, Vector2(Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE).width, mIndicatorFixedHeight));
315 mIndicatorSizeConstraint = Constraint::New<Vector3>(mIndicator, Actor::Property::SIZE, IndicatorSizeConstraint(mIndicatorMinimumHeight, mIndicatorStartPadding + mIndicatorEndPadding));
316 mIndicatorSizeConstraint.AddSource(ParentSource(Actor::Property::SIZE));
317 mIndicatorSizeConstraint.AddSource(Source(scrollableHandle, mPropertyScrollContentSize));
318 mIndicatorSizeConstraint.Apply();
321 if(mIndicatorPositionConstraint)
323 mIndicatorPositionConstraint.Remove();
326 mIndicatorPositionConstraint = Constraint::New<Vector3>(mIndicator, Actor::Property::POSITION, IndicatorPositionConstraint(mIndicatorStartPadding, mIndicatorEndPadding));
327 mIndicatorPositionConstraint.AddSource(LocalSource(Actor::Property::SIZE));
328 mIndicatorPositionConstraint.AddSource(ParentSource(Actor::Property::SIZE));
329 mIndicatorPositionConstraint.AddSource(Source(scrollableHandle, mPropertyScrollPosition));
330 mIndicatorPositionConstraint.AddSource(Source(scrollableHandle, mPropertyMinScrollPosition));
331 mIndicatorPositionConstraint.AddSource(Source(scrollableHandle, mPropertyMaxScrollPosition));
332 mIndicatorPositionConstraint.Apply();
336 void ScrollBar::SetScrollPositionIntervals(const Dali::Vector<float>& positions)
338 mScrollPositionIntervals = positions;
340 Handle scrollableHandle = mScrollableObject.GetHandle();
344 if(mPositionNotification)
346 scrollableHandle.RemovePropertyNotification(mPositionNotification);
349 mPositionNotification = scrollableHandle.AddPropertyNotification(mPropertyScrollPosition, VariableStepCondition(mScrollPositionIntervals));
350 mPositionNotification.NotifySignal().Connect(this, &ScrollBar::OnScrollPositionIntervalReached);
354 Dali::Vector<float> ScrollBar::GetScrollPositionIntervals() const
356 return mScrollPositionIntervals;
359 void ScrollBar::OnScrollPositionIntervalReached(PropertyNotification& source)
361 // Emit the signal to notify the scroll position crossing
362 Handle scrollableHandle = mScrollableObject.GetHandle();
365 mScrollPositionIntervalReachedSignal.Emit(scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition));
367 auto accessible = GetAccessibleObject();
368 if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
370 accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
375 void ScrollBar::ShowIndicator()
377 // Cancel any animation
384 if(mIndicatorFirstShow)
386 // Preserve the alpha value from the stylesheet
387 mIndicatorShowAlpha = Self().GetCurrentProperty<Vector4>(Actor::Property::COLOR).a;
388 mIndicatorFirstShow = false;
391 if(mIndicatorShowDuration > 0.0f)
393 mAnimation = Animation::New(mIndicatorShowDuration);
394 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA), mIndicatorShowAlpha, AlphaFunction::EASE_IN);
399 mIndicator.SetProperty(Actor::Property::OPACITY, mIndicatorShowAlpha);
403 void ScrollBar::HideIndicator()
405 // Cancel any animation
412 if(mIndicatorHideDuration > 0.0f)
414 mAnimation = Animation::New(mIndicatorHideDuration);
415 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA), 0.0f, AlphaFunction::EASE_IN);
420 mIndicator.SetProperty(Actor::Property::OPACITY, 0.0f);
424 void ScrollBar::ShowTransientIndicator()
426 // Cancel any animation
433 mAnimation = Animation::New(mIndicatorShowDuration + mTransientIndicatorDuration + mIndicatorHideDuration);
434 if(mIndicatorShowDuration > 0.0f)
436 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA),
438 AlphaFunction::EASE_IN,
439 TimePeriod(0, mIndicatorShowDuration));
443 mIndicator.SetProperty(Actor::Property::OPACITY, mIndicatorShowAlpha);
445 mAnimation.AnimateTo(Property(mIndicator, Actor::Property::COLOR_ALPHA),
447 AlphaFunction::EASE_IN,
448 TimePeriod((mIndicatorShowDuration + mTransientIndicatorDuration), mIndicatorHideDuration));
452 bool ScrollBar::OnPanGestureProcessTick()
454 // Update the scroll position property.
455 Handle scrollableHandle = mScrollableObject.GetHandle();
458 scrollableHandle.SetProperty(mPropertyScrollPosition, mCurrentScrollPosition);
464 void ScrollBar::OnPan(const PanGesture& gesture)
466 Handle scrollableHandle = mScrollableObject.GetHandle();
470 Dali::Toolkit::ItemView itemView = Dali::Toolkit::ItemView::DownCast(scrollableHandle);
472 switch(gesture.GetState())
474 case Dali::GestureState::STARTED:
476 if(!mPanProcessTimer)
478 // Make sure the pan gesture is only being processed once per frame.
479 mPanProcessTimer = Timer::New(DEFAULT_PAN_GESTURE_PROCESS_TIME);
480 mPanProcessTimer.TickSignal().Connect(this, &ScrollBar::OnPanGestureProcessTick);
481 mPanProcessTimer.Start();
485 mScrollStart = scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition);
486 mGestureDisplacement = Vector2::ZERO;
491 case Dali::GestureState::CONTINUING:
493 mGestureDisplacement += gesture.GetDisplacement();
495 float minScrollPosition = scrollableHandle.GetCurrentProperty<float>(mPropertyMinScrollPosition);
496 float maxScrollPosition = scrollableHandle.GetCurrentProperty<float>(mPropertyMaxScrollPosition);
498 // The domain size is the internal range
499 float domainSize = maxScrollPosition - minScrollPosition;
500 float logicalSize = Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE).y - (mIndicator.GetCurrentProperty<Vector3>(Actor::Property::SIZE).y + mIndicatorStartPadding + mIndicatorEndPadding);
502 mCurrentScrollPosition = mScrollStart - ((mGestureDisplacement.y * domainSize) / logicalSize);
503 mCurrentScrollPosition = -std::min(maxScrollPosition, std::max(-mCurrentScrollPosition, minScrollPosition));
513 // Destroy the timer when pan gesture is finished.
514 mPanProcessTimer.Stop();
515 mPanProcessTimer.TickSignal().Disconnect(this, &ScrollBar::OnPanGestureProcessTick);
516 mPanProcessTimer.Reset();
521 // Refresh the ItemView cache with extra items
522 GetImpl(itemView).DoRefresh(mCurrentScrollPosition, true);
525 mPanFinishedSignal.Emit();
533 // Disable automatic refresh in ItemView during fast scrolling
534 GetImpl(itemView).SetRefreshEnabled(!mIsPanning);
539 void ScrollBar::OnSizeSet(const Vector3& size)
541 if(mIndicatorHeightPolicy == Toolkit::ScrollBar::FIXED)
543 mIndicator.SetProperty(Actor::Property::SIZE, Vector2(size.width, mIndicatorFixedHeight));
546 Control::OnSizeSet(size);
549 void ScrollBar::SetScrollDirection(Toolkit::ScrollBar::Direction direction)
551 mDirection = direction;
554 Toolkit::ScrollBar::Direction ScrollBar::GetScrollDirection() const
559 void ScrollBar::SetIndicatorHeightPolicy(Toolkit::ScrollBar::IndicatorHeightPolicy policy)
561 if(policy != mIndicatorHeightPolicy)
563 mIndicatorHeightPolicy = policy;
568 Toolkit::ScrollBar::IndicatorHeightPolicy ScrollBar::GetIndicatorHeightPolicy() const
570 return mIndicatorHeightPolicy;
573 void ScrollBar::SetIndicatorFixedHeight(float height)
575 mIndicatorFixedHeight = height;
577 if(mIndicatorHeightPolicy == Toolkit::ScrollBar::FIXED)
579 mIndicator.SetProperty(Actor::Property::SIZE, Vector2(Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE).width, mIndicatorFixedHeight));
583 float ScrollBar::GetIndicatorFixedHeight() const
585 return mIndicatorFixedHeight;
588 void ScrollBar::SetIndicatorShowDuration(float durationSeconds)
590 mIndicatorShowDuration = durationSeconds;
593 float ScrollBar::GetIndicatorShowDuration() const
595 return mIndicatorShowDuration;
598 void ScrollBar::SetIndicatorHideDuration(float durationSeconds)
600 mIndicatorHideDuration = durationSeconds;
603 float ScrollBar::GetIndicatorHideDuration() const
605 return mIndicatorHideDuration;
608 void ScrollBar::OnScrollDirectionPropertySet(Property::Value propertyValue)
610 std::string directionName(propertyValue.Get<std::string>());
611 if(directionName == "VERTICAL")
613 SetScrollDirection(Toolkit::ScrollBar::VERTICAL);
615 else if(directionName == "HORIZONTAL")
617 SetScrollDirection(Toolkit::ScrollBar::HORIZONTAL);
621 DALI_ASSERT_ALWAYS(!"ScrollBar::OnScrollDirectionPropertySet(). Invalid Property value.");
625 void ScrollBar::OnIndicatorHeightPolicyPropertySet(Property::Value propertyValue)
627 std::string policyName(propertyValue.Get<std::string>());
628 if(policyName == "VARIABLE")
630 SetIndicatorHeightPolicy(Toolkit::ScrollBar::VARIABLE);
632 else if(policyName == "FIXED")
634 SetIndicatorHeightPolicy(Toolkit::ScrollBar::FIXED);
638 DALI_ASSERT_ALWAYS(!"ScrollBar::OnIndicatorHeightPolicyPropertySet(). Invalid Property value.");
642 bool ScrollBar::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
644 Dali::BaseHandle handle(object);
646 bool connected(true);
647 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(handle);
649 if(0 == strcmp(signalName.c_str(), PAN_FINISHED_SIGNAL))
651 scrollBar.PanFinishedSignal().Connect(tracker, functor);
653 else if(0 == strcmp(signalName.c_str(), SCROLL_POSITION_INTERVAL_REACHED_SIGNAL))
655 scrollBar.ScrollPositionIntervalReachedSignal().Connect(tracker, functor);
659 // signalName does not match any signal
666 void ScrollBar::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
668 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(Dali::BaseHandle(object));
672 ScrollBar& scrollBarImpl(GetImpl(scrollBar));
675 case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
677 scrollBarImpl.OnScrollDirectionPropertySet(value);
680 case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
682 scrollBarImpl.OnIndicatorHeightPolicyPropertySet(value);
685 case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
687 scrollBarImpl.SetIndicatorFixedHeight(value.Get<float>());
690 case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
692 scrollBarImpl.SetIndicatorShowDuration(value.Get<float>());
695 case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
697 scrollBarImpl.SetIndicatorHideDuration(value.Get<float>());
700 case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
702 const Property::Array* array = value.GetArray();
705 Dali::Vector<float> positions;
706 size_t positionCount = array->Count();
707 positions.Resize(positionCount);
710 for(size_t i = 0; i != positionCount; ++i)
712 if(DALI_UNLIKELY(!array->GetElementAt(i).Get(positions[i])))
714 // Given array is invalid. Fast out.
720 if(DALI_LIKELY(valid))
722 scrollBarImpl.SetScrollPositionIntervals(positions);
727 case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
729 scrollBarImpl.mIndicatorMinimumHeight = value.Get<float>();
730 scrollBarImpl.ApplyConstraints();
733 case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
735 scrollBarImpl.mIndicatorStartPadding = value.Get<float>();
736 scrollBarImpl.ApplyConstraints();
739 case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
741 scrollBarImpl.mIndicatorEndPadding = value.Get<float>();
742 scrollBarImpl.ApplyConstraints();
745 case Toolkit::ScrollBar::Property::INDICATOR_TRANSIENT_DURATION:
747 scrollBarImpl.mTransientIndicatorDuration = value.Get<float>();
754 Property::Value ScrollBar::GetProperty(BaseObject* object, Property::Index index)
756 Property::Value value;
758 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(Dali::BaseHandle(object));
762 ScrollBar& scrollBarImpl(GetImpl(scrollBar));
765 case Toolkit::ScrollBar::Property::SCROLL_DIRECTION:
767 value = SCROLL_DIRECTION_NAME[scrollBarImpl.GetScrollDirection()];
770 case Toolkit::ScrollBar::Property::INDICATOR_HEIGHT_POLICY:
772 value = INDICATOR_HEIGHT_POLICY_NAME[scrollBarImpl.GetIndicatorHeightPolicy()];
775 case Toolkit::ScrollBar::Property::INDICATOR_FIXED_HEIGHT:
777 value = scrollBarImpl.GetIndicatorFixedHeight();
780 case Toolkit::ScrollBar::Property::INDICATOR_SHOW_DURATION:
782 value = scrollBarImpl.GetIndicatorShowDuration();
785 case Toolkit::ScrollBar::Property::INDICATOR_HIDE_DURATION:
787 value = scrollBarImpl.GetIndicatorHideDuration();
790 case Toolkit::ScrollBar::Property::SCROLL_POSITION_INTERVALS:
792 Property::Value tempValue(Property::ARRAY);
793 Property::Array* array = tempValue.GetArray();
797 Dali::Vector<float> positions = scrollBarImpl.GetScrollPositionIntervals();
798 size_t positionCount(positions.Count());
800 for(size_t i(0); i != positionCount; ++i)
802 array->PushBack(positions[i]);
809 case Toolkit::ScrollBar::Property::INDICATOR_MINIMUM_HEIGHT:
811 value = scrollBarImpl.mIndicatorMinimumHeight;
814 case Toolkit::ScrollBar::Property::INDICATOR_START_PADDING:
816 value = scrollBarImpl.mIndicatorStartPadding;
819 case Toolkit::ScrollBar::Property::INDICATOR_END_PADDING:
821 value = scrollBarImpl.mIndicatorEndPadding;
824 case Toolkit::ScrollBar::Property::INDICATOR_TRANSIENT_DURATION:
826 value = scrollBarImpl.mTransientIndicatorDuration;
834 bool ScrollBar::DoAction(BaseObject* object, const std::string& actionName, const Property::Map& attributes)
838 Dali::BaseHandle handle(object);
840 Toolkit::ScrollBar scrollBar = Toolkit::ScrollBar::DownCast(handle);
842 DALI_ASSERT_DEBUG(scrollBar);
846 if(0 == strcmp(actionName.c_str(), ACTION_SHOW_INDICATOR))
848 GetImpl(scrollBar).ShowIndicator();
851 else if(0 == strcmp(actionName.c_str(), ACTION_HIDE_INDICATOR))
853 GetImpl(scrollBar).HideIndicator();
856 else if(0 == strcmp(actionName.c_str(), ACTION_SHOW_TRANSIENT_INDICATOR))
858 GetImpl(scrollBar).ShowTransientIndicator();
866 Toolkit::ScrollBar ScrollBar::New(Toolkit::ScrollBar::Direction direction)
868 // Create the implementation, temporarily owned by this handle on stack
869 IntrusivePtr<ScrollBar> impl = new ScrollBar(direction);
871 // Pass ownership to CustomActor handle
872 Toolkit::ScrollBar handle(*impl);
874 // Second-phase init of the implementation
875 // This can only be done after the CustomActor connection has been made...
881 double ScrollBar::ScrollBarAccessible::GetMinimum() const
883 auto self = Toolkit::ScrollBar::DownCast(Self());
884 Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
885 return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMinScrollPosition) : 0.0f;
888 double ScrollBar::ScrollBarAccessible::GetCurrent() const
890 auto self = Toolkit::ScrollBar::DownCast(Self());
891 Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
892 return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyScrollPosition) : 0.0f;
895 std::string ScrollBar::ScrollBarAccessible::GetValueText() const
897 return {}; // Text mode is not used at the moment
900 double ScrollBar::ScrollBarAccessible::GetMaximum() const
902 auto self = Toolkit::ScrollBar::DownCast(Self());
903 Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
904 return scrollableHandle ? scrollableHandle.GetCurrentProperty<float>(GetImpl(self).mPropertyMaxScrollPosition) : 1.0f;
907 bool ScrollBar::ScrollBarAccessible::SetCurrent(double current)
909 if(current < GetMinimum() || current > GetMaximum())
914 auto valueBefore = GetCurrent();
916 auto self = Toolkit::ScrollBar::DownCast(Self());
917 Handle scrollableHandle = GetImpl(self).mScrollableObject.GetHandle();
918 if(!scrollableHandle)
923 scrollableHandle.SetProperty(GetImpl(self).mPropertyScrollPosition, static_cast<float>(current));
925 auto valueAfter = GetCurrent();
927 if(!Dali::Equals(current, valueBefore) && Dali::Equals(valueBefore, valueAfter))
935 double ScrollBar::ScrollBarAccessible::GetMinimumIncrement() const
940 } // namespace Internal
942 } // namespace Toolkit