2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
17 #include <dali-toolkit/internal/controls/slider/slider-impl.h>
18 #include <dali-toolkit/public-api/controls/control-impl.h>
36 const float BACKING_Z = -0.1f;
37 const float PROGRESS_Z = 0.1f;
38 const float HANDLE_Z = 1.0f;
39 const float VALUE_TEXT_INCREMENT = 0.01f;
40 const float HANDLE_VALUE_DISPLAY_TEXT_Z = HANDLE_Z + VALUE_TEXT_INCREMENT;
41 const float VALUE_DISPLAY_TEXT_Z = VALUE_TEXT_INCREMENT + VALUE_TEXT_INCREMENT; // Put above HANDLE_VALUE_DISPLAY_TEXT_Z (parented to handle)
43 const float MARK_SNAP_TOLERANCE = 0.05f; // 5% of slider width
45 const int VALUE_VIEW_SHOW_DURATION = 1000; // millisec
46 const int VALUE_VIEW_SHOW_DURATION_LONG = 2000; // millisec
48 const float VALUE_VERTICAL_OFFSET = 48.0f;
50 const float DEFAULT_WIDTH = 0.0f;
51 const float DEFAULT_HEIGHT = 27.0f;
52 const float DEFAULT_HIT_HEIGHT = 72.0f;
53 const float DEFAULT_HANDLE_HEIGHT = DEFAULT_HIT_HEIGHT;
55 const char* SKINNED_BACKING_IMAGE_NAME = DALI_IMAGE_DIR "slider-skin.png";
56 const char* SKINNED_HANDLE_IMAGE_NAME = DALI_IMAGE_DIR "slider-skin-handle.png";;
57 const char* SKINNED_PROGRESS_IMAGE_NAME = DALI_IMAGE_DIR "slider-skin-progress.png";
58 const char* SKINNED_POPUP_IMAGE_NAME = DALI_IMAGE_DIR "slider-popup.png";
59 const char* SKINNED_POPUP_ARROW_IMAGE_NAME = DALI_IMAGE_DIR "slider-popup-arrow.png";
61 const Vector4 SKINNED_BACKING_SCALE9_BORDER( 12.0f, 0.0f, 12.0f, 0.0f );
62 const Vector4 SKINNED_PROGRESS_SCALE9_BORDER( 14.0f, 0.0f, 0.0f, 0.0f );
63 const Vector4 SKINNED_POPUP_SCALE9_BORDER( 10.0f, 10.0f, 10.0f, 10.0f );
65 const Vector2 DEFAULT_HIT_REGION( DEFAULT_WIDTH, DEFAULT_HIT_HEIGHT );
66 const Vector2 DEFAULT_BACKING_REGION( DEFAULT_WIDTH, DEFAULT_HEIGHT );
67 const Vector2 DEFAULT_HANDLE_REGION( DEFAULT_HANDLE_HEIGHT, DEFAULT_HANDLE_HEIGHT );
69 const Vector4 DEFAULT_DISABLE_COLOR( 0.5f, 0.5f, 0.5f, 1.0f );
70 const Vector4 DEFAULT_POPUP_TEXT_COLOR( 0.5f, 0.5f, 0.5f, 1.0f );
72 const float VALUE_POPUP_MARGIN = 10.0f;
73 const float VALUE_POPUP_HEIGHT = 81.0f;
74 const float VALUE_POPUP_MIN_WIDTH = 54.0f;
75 const Vector2 VALUE_POPUP_ARROW_SIZE( 18.0f, 18.0f );
77 const float DEFAULT_LOWER_BOUND = 0.0f;
78 const float DEFAULT_UPPER_BOUND = 1.0f;
79 const float DEFAULT_VALUE = 0.0f;
80 const int DEFAULT_VALUE_PRECISION = 0;
81 const bool DEFAULT_SHOW_POPUP = false;
82 const bool DEFAULT_SHOW_VALUE = true;
83 const bool DEFAULT_ENABLED = true;
88 return Dali::Toolkit::Slider::New();
91 TypeRegistration typeRegistration( typeid(Dali::Toolkit::Slider), typeid(Dali::Toolkit::Control), Create );
93 SignalConnectorType signalConnector1( typeRegistration, Toolkit::Slider::SIGNAL_VALUE_CHANGED, &Toolkit::Internal::Slider::DoConnectSignal );
94 SignalConnectorType signalConnector2( typeRegistration, Toolkit::Slider::SIGNAL_MARK, &Toolkit::Internal::Slider::DoConnectSignal );
98 ///////////////////////////////////////////////////////////////////////////////////////////////////
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
102 Dali::Toolkit::Slider Slider::New()
104 // Create the implementation
105 SliderPtr slider( new Slider() );
107 // Pass ownership to CustomActor via derived handle
108 Dali::Toolkit::Slider handle( *slider );
110 // Second-phase init of the implementation
111 // This can only be done after the CustomActor connection has been made...
112 slider->Initialize();
118 : ControlImpl( true ),
127 void Slider::OnInitialize()
135 // Register properties in a block so the properties are ready for the update functions
136 mPropertyHitRegion = self.RegisterProperty( Dali::Toolkit::Slider::HIT_REGION_PROPERTY_NAME, DEFAULT_HIT_REGION, Property::READ_WRITE );
137 mPropertyBackingRegion = self.RegisterProperty( Dali::Toolkit::Slider::BACKING_REGION_PROPERTY_NAME, DEFAULT_BACKING_REGION, Property::READ_WRITE );
138 mPropertyHandleRegion = self.RegisterProperty( Dali::Toolkit::Slider::HANDLE_REGION_PROPERTY_NAME, DEFAULT_HANDLE_REGION, Property::READ_WRITE );
140 mPropertyBackingImageName = self.RegisterProperty( Dali::Toolkit::Slider::BACKING_IMAGE_NAME_PROPERTY_NAME, SKINNED_BACKING_IMAGE_NAME, Property::READ_WRITE );
141 mPropertyHandleImageName = self.RegisterProperty( Dali::Toolkit::Slider::HANDLE_IMAGE_NAME_PROPERTY_NAME, SKINNED_HANDLE_IMAGE_NAME, Property::READ_WRITE );
143 mPropertyProgressImageName = self.RegisterProperty( Dali::Toolkit::Slider::PROGRESS_IMAGE_NAME_PROPERTY_NAME, SKINNED_PROGRESS_IMAGE_NAME, Property::READ_WRITE );
144 mPropertyPopupImageName = self.RegisterProperty( Dali::Toolkit::Slider::POPUP_IMAGE_NAME_PROPERTY_NAME, SKINNED_POPUP_IMAGE_NAME, Property::READ_WRITE );
145 mPropertyPopupArrowImageName = self.RegisterProperty( Dali::Toolkit::Slider::POPUP_ARROW_IMAGE_NAME_PROPERTY_NAME, SKINNED_POPUP_ARROW_IMAGE_NAME, Property::READ_WRITE );
147 mPropertyBackingScale9Border = self.RegisterProperty( Dali::Toolkit::Slider::BACKING_SCALE9_BORDER_PROPERTY_NAME, SKINNED_BACKING_SCALE9_BORDER, Property::READ_WRITE );
148 mPropertyProgressScale9Border = self.RegisterProperty( Dali::Toolkit::Slider::PROGRESS_SCALE9_BORDER_PROPERTY_NAME, SKINNED_PROGRESS_SCALE9_BORDER, Property::READ_WRITE );
149 mPropertyPopupScale9Border = self.RegisterProperty( Dali::Toolkit::Slider::POPUP_SCALE9_BORDER_PROPERTY_NAME, SKINNED_POPUP_SCALE9_BORDER, Property::READ_WRITE );
151 mPropertyDisableColor = self.RegisterProperty( Dali::Toolkit::Slider::DISABLE_COLOR_PROPERTY_NAME, DEFAULT_DISABLE_COLOR, Property::READ_WRITE );
152 mPropertyPopupTextColor = self.RegisterProperty( Dali::Toolkit::Slider::POPUP_TEXT_COLOR_PROPERTY_NAME, DEFAULT_POPUP_TEXT_COLOR, Property::READ_WRITE );
154 mPropertyValuePrecision = self.RegisterProperty( Dali::Toolkit::Slider::VALUE_PRECISION_PROPERTY_NAME, DEFAULT_VALUE_PRECISION, Property::READ_WRITE );
155 mPropertyShowPopup = self.RegisterProperty( Dali::Toolkit::Slider::SHOW_POPUP_PROPERTY_NAME, DEFAULT_SHOW_POPUP, Property::READ_WRITE );
156 mPropertyShowValue = self.RegisterProperty( Dali::Toolkit::Slider::SHOW_VALUE_PROPERTY_NAME, DEFAULT_SHOW_VALUE, Property::READ_WRITE );
158 mPropertyEnabled = self.RegisterProperty( Dali::Toolkit::Slider::ENABLED_PROPERTY_NAME, DEFAULT_ENABLED, Property::READ_WRITE );
160 mPropertyMarks = self.RegisterProperty( Dali::Toolkit::Slider::MARKS_PROPERTY_NAME, mMarks, Property::READ_WRITE );
161 mPropertySnapToMarks = self.RegisterProperty( Dali::Toolkit::Slider::SNAP_TO_MARKS_PROPERTY_NAME, false, Property::READ_WRITE );
162 mPropertyMarkTolerance = self.RegisterProperty( Dali::Toolkit::Slider::MARK_TOLERANCE_PROPERTY_NAME, MARK_SNAP_TOLERANCE, Property::READ_WRITE );
164 mPropertyLowerBound = self.RegisterProperty( Dali::Toolkit::Slider::LOWER_BOUND_PROPERTY_NAME, DEFAULT_LOWER_BOUND, Property::READ_WRITE );
165 mPropertyUpperBound = self.RegisterProperty( Dali::Toolkit::Slider::UPPER_BOUND_PROPERTY_NAME, DEFAULT_UPPER_BOUND, Property::READ_WRITE );
166 mPropertyValue = self.RegisterProperty( Dali::Toolkit::Slider::VALUE_PROPERTY_NAME, DEFAULT_VALUE, Property::READ_WRITE );
168 ResizeHitRegion( DEFAULT_HIT_REGION );
169 SetBackingRegion( DEFAULT_BACKING_REGION );
170 UpdateHandleRegion( DEFAULT_HANDLE_REGION );
171 CreateBackingImage( SKINNED_BACKING_IMAGE_NAME );
172 CreateHandleImage( SKINNED_HANDLE_IMAGE_NAME );
173 CreateProgressImage( SKINNED_PROGRESS_IMAGE_NAME );
174 CreatePopupImage( SKINNED_POPUP_IMAGE_NAME );
175 CreatePopupArrowImage( SKINNED_POPUP_ARROW_IMAGE_NAME );
176 SetBackingScale9( SKINNED_BACKING_SCALE9_BORDER );
177 SetProgressScale9( SKINNED_PROGRESS_SCALE9_BORDER );
178 SetPopupScale9( SKINNED_POPUP_SCALE9_BORDER );
179 UpdatePopupTextColor( DEFAULT_POPUP_TEXT_COLOR );
180 ShowPopup( DEFAULT_SHOW_POPUP );
181 ShowValue( DEFAULT_SHOW_VALUE );
182 SetEnabled( DEFAULT_ENABLED );
183 UpdateLowerBound( DEFAULT_LOWER_BOUND );
184 UpdateUpperBound( DEFAULT_UPPER_BOUND );
186 DisplayValue( DEFAULT_VALUE, false ); // Run this last to display the correct value
188 // Size the Slider actor to a default
189 self.SetSize( DEFAULT_HIT_REGION.x, DEFAULT_HIT_REGION.y );
192 void Slider::OnControlSizeSet( const Vector3& size )
194 // Factor in handle overshoot into size of backing
195 SetHitRegion( Vector2( size.x, GetHitRegion().y ) );
196 SetBackingRegion( Vector2( size.x - GetHandleRegion().x, GetBackingRegion().y ) );
199 bool Slider::OnTouchEvent(Actor actor, const TouchEvent& event)
201 if( mState != DISABLED )
203 TouchPoint::State touchState = event.GetPoint(0).state;
205 if( touchState == TouchPoint::Down )
209 float percentage = MapPercentage( event.GetPoint(0).local );
210 float value = MapBounds( ( GetSnapToMarks() ) ? SnapToMark( percentage ) : MarkFilter( percentage ), GetLowerBound(), GetUpperBound() );
212 DisplayPopup( value );
214 else if( touchState == TouchPoint::Up)
216 if( mState == PRESSED )
219 mSlidingFinishedSignal.Emit( Toolkit::Slider::DownCast( Self() ), Self().GetProperty( mPropertyValue ).Get<float>());
227 void Slider::OnPan( Actor actor, PanGesture gesture )
229 // gesture.position is in local actor coordinates
230 if( mState != DISABLED )
232 switch( gesture.state )
234 case Gesture::Continuing:
236 if( mState == PRESSED )
238 float value = MapBounds( MarkFilter ( MapPercentage( gesture.position ) ), GetLowerBound(), GetUpperBound() );
240 DisplayPopup( value );
244 case Gesture::Finished:
246 if( mState == PRESSED )
248 if( GetSnapToMarks() )
250 float value = MapBounds( SnapToMark( MapPercentage( gesture.position ) ), GetLowerBound(), GetUpperBound() );
252 DisplayPopup( value );
254 mSlidingFinishedSignal.Emit( Toolkit::Slider::DownCast( Self() ), Self().GetProperty( mPropertyValue ).Get<float>());
268 float Slider::HitSpaceToDomain( float x )
270 float halfRegionWidth = GetHitRegion().x * 0.5f;
271 float halfDomainWidth = ( mDomain.to.x - mDomain.from.x ) * 0.5f;
272 float endDiff = halfRegionWidth - halfDomainWidth;
277 float Slider::MapPercentage( const Vector2& point )
279 return Clamp( ( HitSpaceToDomain( point.x ) - mDomain.from.x ) / ( mDomain.to.x - mDomain.from.x ), 0.0f, 1.0f );
282 float Slider::MapValuePercentage( float value )
284 return ( value - GetLowerBound() ) / ( GetUpperBound() - GetLowerBound() );
287 float Slider::MapBounds( float percent, float lowerBound, float upperBound )
289 return lowerBound + percent * ( upperBound - lowerBound );
292 Slider::Domain Slider::CalcDomain( const Vector2& currentSize )
294 return Domain( Vector2( 0.0f, 0.0f ), currentSize );
297 void Slider::DisplayValue( float value, bool raiseSignals )
299 float clampledValue = Clamp( value, GetLowerBound(), GetUpperBound() );
301 float percent = MapValuePercentage( clampledValue );
303 float x = mDomain.from.x + percent * ( mDomain.to.x - mDomain.from.x );
305 mHandle.SetPosition( x, 0.0f, HANDLE_Z );
310 if( clampledValue > 0.0f )
312 mProgress.SetVisible( true ); // Deliberately set this in case multiple SetValues are fired at once
313 mProgress.SetSize( x, GetBackingRegion().y );
317 mProgress.SetVisible( false );
324 Toolkit::Slider self = Toolkit::Slider::DownCast( Self() );
325 mValueChangedSignal.Emit( self, clampledValue );
328 if( MarkReached( percent, markIndex ) )
330 mMarkSignal.Emit( self, markIndex );
334 if( mHandleValueTextView )
336 std::stringstream ss;
337 ss.precision( GetValuePrecision() );
338 ss << fixed << clampledValue;
339 mHandleValueTextView.SetText( ss.str() );
343 void Slider::SetMarks( const MarkList& marks )
346 for( MarkList::const_iterator it = marks.begin(), itEnd = marks.end(); it != itEnd; ++it )
348 const Property::Value& propertyValue = *it;
349 propertyValue.Get( value );
351 mMarks.push_back( value );
355 const Slider::MarkList& Slider::GetMarks() const
360 bool Slider::GetSnapToMarks() const
362 return Self().GetProperty<bool>( mPropertySnapToMarks );
365 Actor Slider::CreateHitRegion()
367 Actor hitRegion = Actor::New();
368 hitRegion.SetParentOrigin( ParentOrigin::CENTER );
369 hitRegion.SetAnchorPoint( AnchorPoint::CENTER );
370 hitRegion.TouchedSignal().Connect( this, &Slider::OnTouchEvent );
375 ImageActor Slider::CreateBacking()
377 ImageActor backing = ImageActor::New();
378 backing.SetParentOrigin( ParentOrigin::CENTER );
379 backing.SetAnchorPoint( AnchorPoint::CENTER );
380 backing.SetZ( BACKING_Z );
385 void Slider::CreateBackingImage( const std::string& imageName )
387 if( mBacking && imageName != String::EMPTY )
389 Image image = Image::New( imageName );
390 mBacking.SetImage( image );
394 void Slider::SetBackingScale9( const Vector4& border )
398 mBacking.SetStyle( ImageActor::STYLE_NINE_PATCH );
399 mBacking.SetNinePatchBorder( border );
403 void Slider::SetBackingRegionSize( const Vector2& region )
407 mBacking.SetSize( region );
411 ImageActor Slider::CreateProgress()
413 ImageActor progress = ImageActor::New();
414 progress.SetParentOrigin( ParentOrigin::CENTER_LEFT );
415 progress.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
416 progress.SetZ( PROGRESS_Z );
421 void Slider::CreateProgressImage( const std::string& imageName )
423 if( mProgress && imageName != String::EMPTY )
425 Image image = Image::New( imageName );
426 mProgress.SetImage( image );
430 void Slider::CreatePopupImage( const std::string& imageName )
432 if( mPopup && imageName != String::EMPTY )
434 Image image = Image::New( imageName );
435 mPopup.SetImage( image );
439 void Slider::CreatePopupArrowImage( const std::string& imageName )
441 if( mPopupArrow && imageName != String::EMPTY )
443 Image image = Image::New( imageName );
444 mPopupArrow.SetImage( image );
448 void Slider::SetProgressScale9( const Vector4& border )
452 mProgress.SetStyle( ImageActor::STYLE_NINE_PATCH );
453 mProgress.SetNinePatchBorder( border );
457 void Slider::SetPopupScale9( const Vector4& border )
461 mPopup.SetStyle( ImageActor::STYLE_NINE_PATCH );
462 mPopup.SetNinePatchBorder( border );
466 void Slider::ResizeProgressRegion( const Vector2& region )
470 mProgress.SetSize( region );
474 ImageActor Slider::CreateHandle()
476 ImageActor handle = ImageActor::New();
477 handle.SetParentOrigin( ParentOrigin::CENTER_LEFT );
478 handle.SetAnchorPoint( AnchorPoint::CENTER );
479 handle.SetZ( HANDLE_Z );
484 ImageActor Slider::CreatePopupArrow()
486 ImageActor arrow = ImageActor::New();
487 arrow.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
488 arrow.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
489 arrow.SetZ( HANDLE_Z );
494 Toolkit::TextView Slider::CreatePopupText()
496 Toolkit::TextView textView = Toolkit::TextView::New();
497 textView.SetParentOrigin( ParentOrigin::CENTER );
498 textView.SetAnchorPoint( AnchorPoint::CENTER );
499 textView.SetSizePolicy( Control::Flexible, Control::Flexible );
500 textView.SetZ( VALUE_DISPLAY_TEXT_Z );
504 ImageActor Slider::CreatePopup()
506 ImageActor popup = ImageActor::New();
507 popup.SetParentOrigin( ParentOrigin::TOP_CENTER );
508 popup.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
510 mValueTextView = CreatePopupText();
511 popup.Add( mValueTextView );
516 void Slider::CreateHandleImage( const std::string& imageName )
518 if( mHandle && imageName != String::EMPTY )
520 Image image = Image::New( imageName );
521 mHandle.SetImage( image );
525 void Slider::ResizeHandleRegion( const Vector2& region )
529 mHandle.SetSize( region );
533 void Slider::CreateHandleValueDisplay()
535 if( mHandle && !mHandleValueTextView )
537 mHandleValueTextView = Toolkit::TextView::New();
538 mHandleValueTextView.SetParentOrigin( ParentOrigin::CENTER );
539 mHandleValueTextView.SetAnchorPoint( AnchorPoint::CENTER );
540 mHandleValueTextView.SetSize( GetHandleRegion() );
541 mHandleValueTextView.SetZ( HANDLE_VALUE_DISPLAY_TEXT_Z );
542 mHandle.Add( mHandleValueTextView );
546 void Slider::DestroyHandleValueDisplay()
548 if(mHandleValueTextView)
550 mHandleValueTextView.Unparent();
551 mHandleValueTextView.Reset();
555 void Slider::UpdatePopupTextColor( const Vector4& color )
559 mValueTextView.SetColor( color );
563 Actor Slider::CreateValueDisplay()
565 Actor popup = Actor::New();
566 popup.SetParentOrigin( ParentOrigin::TOP_CENTER );
567 popup.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
569 mPopupArrow = CreatePopupArrow();
570 popup.Add( mPopupArrow );
572 mPopup = CreatePopup();
573 mPopup.SetSize( 0.0f, VALUE_POPUP_HEIGHT );
574 mPopupArrow.Add( mPopup );
579 Toolkit::Slider::ValueChangedSignalType& Slider::ValueChangedSignal()
581 return mValueChangedSignal;
584 Toolkit::Slider::ValueChangedSignalType& Slider::SlidingFinishedSignal()
586 return mSlidingFinishedSignal;
589 Toolkit::Slider::MarkSignalType& Slider::MarkSignal()
594 void Slider::UpdateSkin()
600 mBacking.SetColor( Color::WHITE );
601 mHandle.SetColor( Color::WHITE );
602 mProgress.SetColor( Color::WHITE );
607 Vector4 disableColor = GetDisableColor();
608 mBacking.SetColor( disableColor );
609 mHandle.SetColor( disableColor );
610 mProgress.SetColor( disableColor );
624 void Slider::CreateChildren()
629 mHitArea = CreateHitRegion();
630 mPanDetector = PanGestureDetector::New();
631 mPanDetector.Attach( mHitArea );
632 mPanDetector.DetectedSignal().Connect( this, &Slider::OnPan );
633 self.Add( mHitArea );
636 mBacking = CreateBacking();
637 self.Add( mBacking );
640 mProgress = CreateProgress();
641 mBacking.Add( mProgress );
644 mHandle = CreateHandle();
645 mBacking.Add( mHandle );
648 void Slider::ResizeHitRegion( const Vector2& size )
652 mHitArea.SetSize( size );
656 void Slider::AddPopup()
660 mValueDisplay = CreateValueDisplay();
661 mValueDisplay.SetVisible( false );
662 mHandle.Add( mValueDisplay );
665 CreatePopupImage( self.GetProperty<std::string>( mPropertyPopupImageName ) );
666 SetPopupScale9( GetPopupScale9Border() );
667 CreatePopupArrowImage( self.GetProperty<std::string>( mPropertyPopupArrowImageName ) );
669 mValueTimer = Timer::New( VALUE_VIEW_SHOW_DURATION );
670 mValueTimer.TickSignal().Connect( this, &Slider::HideValueView );
674 void Slider::RemovePopup()
681 mPopupArrow.Unparent();
684 mValueDisplay.Unparent();
685 mValueDisplay.Reset();
687 mValueTimer.TickSignal().Disconnect( this, &Slider::HideValueView );
693 float Slider::MarkFilter( float value )
695 const float MARK_TOLERANCE = GetMarkTolerance();
698 for( MarkList::iterator it = mMarks.begin(), itEnd = mMarks.end(); it != itEnd; ++it )
700 const Property::Value& propertyValue = *it;
701 propertyValue.Get( mark );
702 mark = MapValuePercentage( mark );
704 // If close to a mark, return the mark
705 if( fabsf( mark - value ) < MARK_TOLERANCE )
714 float Slider::SnapToMark( float value )
716 float closestMark = value;
717 float closestDist = std::numeric_limits<float>::max();
720 for( MarkList::iterator it = mMarks.begin(), itEnd = mMarks.end(); it != itEnd; ++it )
722 const Property::Value& propertyValue = *it;
723 propertyValue.Get( mark );
724 mark = MapValuePercentage( mark );
726 float dist = fabsf( mark - value );
727 if( dist < closestDist )
737 bool Slider::MarkReached( float value, int& outIndex )
739 const float MARK_TOLERANCE = GetMarkTolerance();
743 tail = mMarks.size() - 1;
747 while( head <= tail )
749 current = head + ( tail - head ) / 2;
751 const Property::Value& propertyValue = mMarks[ current ];
752 propertyValue.Get( mark );
753 mark = MapValuePercentage( mark );
755 if( fabsf( mark - value ) < MARK_TOLERANCE )
776 bool Slider::HideValueView()
780 mValueDisplay.SetVisible( false );
786 void Slider::OnPropertySet( Property::Index index, Property::Value propertyValue )
788 if( index == mPropertyLowerBound )
790 UpdateLowerBound( propertyValue.Get<float>() );
792 else if( index == mPropertyUpperBound )
794 UpdateUpperBound( propertyValue.Get<float>() );
796 else if( index == mPropertyValue )
798 DisplayValue( propertyValue.Get<float>(), true );
800 else if( index == mPropertyHitRegion )
802 ResizeHitRegion( propertyValue.Get<Vector2>() );
804 else if( index == mPropertyBackingRegion )
806 ResizeBackingRegion( propertyValue.Get<Vector2>() );
808 else if( index == mPropertyHandleRegion )
810 UpdateHandleRegion( propertyValue.Get<Vector2>() );
812 else if( index == mPropertyBackingImageName )
814 CreateBackingImage( propertyValue.Get<std::string>() );
816 else if( index == mPropertyHandleImageName )
818 CreateHandleImage( propertyValue.Get<std::string>() );
820 else if( index == mPropertyProgressImageName )
822 CreateProgressImage( propertyValue.Get<std::string>() );
824 else if( index == mPropertyPopupImageName )
826 CreatePopupImage( propertyValue.Get<std::string>() );
828 else if( index == mPropertyPopupArrowImageName )
830 CreatePopupArrowImage( propertyValue.Get<std::string>() );
832 else if( index == mPropertyBackingScale9Border )
834 SetBackingScale9( propertyValue.Get<Vector4>() );
836 else if( index == mPropertyProgressScale9Border )
838 SetProgressScale9( propertyValue.Get<Vector4>() );
840 else if( index == mPropertyPopupScale9Border )
842 SetPopupScale9( propertyValue.Get<Vector4>() );
844 else if( index == mPropertyDisableColor )
848 else if( index == mPropertyPopupTextColor )
850 UpdatePopupTextColor( propertyValue.Get<Vector4>() );
852 else if( index == mPropertyValuePrecision )
854 DisplayValue( GetValue(), false );
856 else if( index == mPropertyShowPopup )
858 ShowPopup( propertyValue.Get<bool>() );
860 else if( index == mPropertyShowValue )
862 ShowValue( propertyValue.Get<bool>() );
864 else if( index == mPropertyEnabled )
866 SetEnabled( propertyValue.Get<bool>() );
868 else if( index == mPropertyMarks )
870 SetMarks( propertyValue.Get<Property::Array>() );
872 else if( index == mPropertySnapToMarks )
876 else if( index == mPropertyMarkTolerance )
882 void Slider::UpdateLowerBound( float bound )
884 DisplayValue( GetValue(), false );
887 float Slider::GetLowerBound() const
889 return Self().GetProperty<float>( mPropertyLowerBound );
892 void Slider::UpdateUpperBound( float bound )
894 DisplayValue( GetValue(), false );
897 float Slider::GetUpperBound() const
899 return Self().GetProperty<float>( mPropertyUpperBound );
902 void Slider::SetValue( float value )
904 Self().SetProperty( mPropertyValue, value );
907 float Slider::GetValue() const
909 return Self().GetProperty<float>( mPropertyValue );
912 void Slider::SetHitRegion( const Vector2& region )
914 Self().SetProperty( mPropertyHitRegion, region );
917 Vector2 Slider::GetHitRegion() const
919 return Self().GetProperty<Vector2>( mPropertyHitRegion );
922 void Slider::SetBackingRegion( const Vector2& region )
924 Self().SetProperty( mPropertyBackingRegion, region );
927 void Slider::ResizeBackingRegion( const Vector2& region )
929 SetBackingRegionSize( region );
930 ResizeProgressRegion( Vector2( 0.0f, region.y ) );
932 mDomain = CalcDomain( region );
934 DisplayValue( GetValue(), false ); // Set the progress bar to correct width
937 Vector2 Slider::GetBackingRegion() const
939 return Self().GetProperty<Vector2>( mPropertyBackingRegion );
942 void Slider::UpdateHandleRegion( const Vector2& region )
944 ResizeHandleRegion( region );
946 Vector2 hitRegion = GetHitRegion();
947 hitRegion.x += region.x;
948 SetHitRegion( hitRegion );
951 Vector2 Slider::GetHandleRegion() const
953 return Self().GetProperty<Vector2>( mPropertyHandleRegion );
956 Vector4 Slider::GetBackingScale9Border() const
958 return Self().GetProperty<Vector4>( mPropertyBackingScale9Border );
961 Vector4 Slider::GetPopupScale9Border() const
963 return Self().GetProperty<Vector4>( mPropertyPopupScale9Border );
966 Vector4 Slider::GetDisableColor() const
968 return Self().GetProperty<Vector4>( mPropertyDisableColor );
971 Vector4 Slider::GetPopupTextColor() const
973 return Self().GetProperty<Vector4>( mPropertyPopupTextColor );
976 int Slider::GetValuePrecision() const
978 return Self().GetProperty<int>( mPropertyValuePrecision );
981 void Slider::ShowPopup( bool showPopup )
994 bool Slider::GetShowPopup() const
996 return Self().GetProperty<bool>( mPropertyShowPopup );
999 void Slider::ShowValue( bool showValue )
1003 CreateHandleValueDisplay();
1007 DestroyHandleValueDisplay();
1011 bool Slider::GetShowValue() const
1013 return Self().GetProperty<bool>( mPropertyShowValue );
1016 void Slider::SetEnabled( bool enabled )
1030 bool Slider::IsEnabled() const
1032 return mState != DISABLED;
1035 float Slider::GetMarkTolerance() const
1037 return Self().GetProperty<float>( mPropertyMarkTolerance );
1040 // static class method to support script connecting signals
1042 bool Slider::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1044 Dali::BaseHandle handle( object );
1046 bool connected = true;
1047 Toolkit::Slider slider = Toolkit::Slider::DownCast( handle );
1049 if( signalName == Dali::Toolkit::Slider::SIGNAL_VALUE_CHANGED )
1051 slider.ValueChangedSignal().Connect( tracker, functor );
1053 else if( signalName == Dali::Toolkit::Slider::SIGNAL_MARK )
1055 slider.MarkSignal().Connect( tracker, functor );
1059 // signalName does not match any signal
1066 void Slider::DisplayPopup( float value )
1069 if( mValueTextView )
1071 std::stringstream ss;
1072 ss.precision( GetValuePrecision() );
1073 ss << fixed << value;
1074 mValueTextView.SetText( ss.str() );
1076 style.SetTextColor( GetPopupTextColor() );
1077 mValueTextView.SetStyleToCurrentText( style, TextStyle::COLOR);
1081 Font font = Font::New();
1082 float popupWidth = font.MeasureText( ss.str() ).x + VALUE_POPUP_MARGIN * 2.0f;
1083 if( popupWidth < VALUE_POPUP_MIN_WIDTH )
1085 popupWidth = VALUE_POPUP_MIN_WIDTH;
1088 mPopup.SetSize( popupWidth, VALUE_POPUP_HEIGHT );
1089 mValueDisplay.SetVisible( true );
1091 mValueTimer.SetInterval( VALUE_VIEW_SHOW_DURATION );
1097 } // namespace Internal
1099 } // namespace Toolkit