2 * Copyright(c) 2019 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.
18 using Tizen.NUI.BaseComponents;
19 using System.ComponentModel;
20 using Tizen.NUI.Binding;
22 namespace Tizen.NUI.Components
25 /// A slider lets users select a value from a continuous or discrete range of values by moving the slider thumb.
27 /// <since_tizen> 6 </since_tizen>
28 public partial class Slider : Control
30 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
31 [EditorBrowsable(EditorBrowsableState.Never)]
32 public static readonly BindableProperty IndicatorTypeProperty = BindableProperty.Create("IndicatorType", typeof(IndicatorType), typeof(Slider), IndicatorType.None, propertyChanged: (bindable, oldValue, newValue) =>
34 var instance = (Slider)bindable;
37 instance.privateIndicatorType = (IndicatorType)newValue;
40 defaultValueCreator: (bindable) =>
42 var instance = (Slider)bindable;
43 return instance.privateIndicatorType;
45 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
46 [EditorBrowsable(EditorBrowsableState.Never)]
47 public static readonly BindableProperty SpaceBetweenTrackAndIndicatorProperty = BindableProperty.Create(nameof(SpaceBetweenTrackAndIndicator), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
49 var instance = (Slider)bindable;
52 instance.privateSpaceBetweenTrackAndIndicator = (uint)newValue;
55 defaultValueCreator: (bindable) =>
57 var instance = (Slider)bindable;
58 return instance.privateSpaceBetweenTrackAndIndicator;
60 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
61 [EditorBrowsable(EditorBrowsableState.Never)]
62 public static readonly BindableProperty TrackThicknessProperty = BindableProperty.Create(nameof(TrackThickness), typeof(uint), typeof(Slider), (uint)0, propertyChanged: (bindable, oldValue, newValue) =>
64 var instance = (Slider)bindable;
67 instance.privateTrackThickness = (uint)newValue;
70 defaultValueCreator: (bindable) =>
72 var instance = (Slider)bindable;
73 return instance.privateTrackThickness;
79 /// The constructor of the Slider class.
81 /// <since_tizen> 6 </since_tizen>
88 /// The constructor of the Slider class with specific style.
90 /// <param name="style">The string to initialize the Slider</param>
91 /// <since_tizen> 8 </since_tizen>
92 public Slider(string style) : base(style)
98 /// The constructor of the Slider class with specific style.
100 /// <param name="sliderStyle">The style object to initialize the Slider</param>
101 /// <since_tizen> 8 </since_tizen>
102 public Slider(SliderStyle sliderStyle) : base(sliderStyle)
108 /// The value changed event handler.
110 /// <since_tizen> 6 </since_tizen>
111 public event EventHandler<ValueChangedArgs> ValueChangedEvent
115 valueChangedHandler += value;
119 valueChangedHandler -= value;
124 /// The sliding finished event handler.
126 /// <since_tizen> 6 </since_tizen>
127 public event EventHandler<SlidingFinishedArgs> SlidingFinishedEvent
131 slidingFinishedHandler += value;
135 slidingFinishedHandler -= value;
140 /// The state changed event handler.
142 /// <since_tizen> 6 </since_tizen>
143 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
144 public event EventHandler<StateChangedArgs> StateChangedEvent
148 stateChangedHandler += value;
152 stateChangedHandler -= value;
157 /// The direction type of slider.
159 /// <since_tizen> 6 </since_tizen>
160 public enum DirectionType
163 /// The Horizontal type.
165 /// <since_tizen> 6 </since_tizen>
169 /// The Vertical type.
171 /// <since_tizen> 6 </since_tizen>
176 /// The indicator type of slider.
178 /// <since_tizen> 6 </since_tizen>
179 public enum IndicatorType
181 /// <summary> Only contains slider bar.</summary>
182 /// <since_tizen> 6 </since_tizen>
185 /// <summary> Contains slider bar, IndicatorImage.</summary>
186 /// <since_tizen> 6 </since_tizen>
189 /// <summary> Contains slider bar, IndicatorText.</summary>
190 /// <since_tizen> 6 </since_tizen>
195 /// Return a copied Style instance of Slider
198 /// It returns copied Style instance and changing it does not effect to the Slider.
199 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
201 /// <since_tizen> 8 </since_tizen>
202 public new SliderStyle Style
206 var result = new SliderStyle(sliderStyle);
207 result.CopyPropertiesFromView(this);
208 result.Track.CopyPropertiesFromView(bgTrackImage);
209 result.Progress.CopyPropertiesFromView(slidedTrackImage);
210 result.Thumb.CopyPropertiesFromView(thumbImage);
211 result.LowIndicatorImage.CopyPropertiesFromView(lowIndicatorImage);
212 result.HighIndicatorImage.CopyPropertiesFromView(highIndicatorImage);
213 result.LowIndicator.CopyPropertiesFromView(lowIndicatorText);
214 result.HighIndicator.CopyPropertiesFromView(highIndicatorText);
220 /// Return a copied Style instance of Slider
222 private SliderStyle sliderStyle => ViewStyle as SliderStyle;
225 /// Gets or sets the direction type of slider.
227 /// <since_tizen> 6 </since_tizen>
228 public DirectionType Direction
236 if (direction == value)
241 RelayoutBaseComponent(false);
243 UpdateBgTrackPosition();
249 /// Gets or sets the indicator type, arrow or sign.
251 /// <since_tizen> 6 </since_tizen>
252 public IndicatorType Indicator
256 return (IndicatorType)GetValue(IndicatorTypeProperty);
260 SetValue(IndicatorTypeProperty, value);
265 /// Gets or sets the minimum value of slider.
267 /// <since_tizen> 6 </since_tizen>
268 public float MinValue
282 /// Gets or sets the maximum value of slider.
284 /// <since_tizen> 6 </since_tizen>
285 public float MaxValue
299 /// Gets or sets the current value of slider.
301 /// <since_tizen> 6 </since_tizen>
302 public float CurrentValue
316 /// Gets or sets the size of the thumb image object.
318 /// <since_tizen> 6 </since_tizen>
319 public Size ThumbSize
323 return thumbImage?.Size;
327 if (null != thumbImage)
329 thumbImage.Size = value;
330 sliderStyle.Thumb.Size = value;
336 /// Gets or sets the resource url of the thumb image object.
338 /// <since_tizen> 6 </since_tizen>
339 public string ThumbImageURL
343 return thumbImage?.ResourceUrl;
347 if (null != thumbImage)
349 thumbImage.ResourceUrl = value;
350 sliderStyle.Thumb.ResourceUrl = value;
356 /// Gets or sets the resource url selector of the thumb image object.
357 /// Getter returns copied selector value if exist, null otherwise.
359 /// <since_tizen> 6 </since_tizen>
360 public StringSelector ThumbImageURLSelector
362 get => thumbImage == null ? null : new StringSelector((Selector<string>)thumbImage.GetValue(ImageView.ResourceUrlSelectorProperty));
363 set => thumbImage?.SetValue(ImageView.ResourceUrlSelectorProperty, value);
367 /// Gets or sets the color of the background track image object.
369 /// <since_tizen> 6 </since_tizen>
370 public Color BgTrackColor
374 return bgTrackImage?.BackgroundColor;
378 if (null != bgTrackImage)
380 bgTrackImage.BackgroundColor = value;
381 sliderStyle.Track.BackgroundColor = value;
387 /// Gets or sets the color of the slided track image object.
389 /// <since_tizen> 6 </since_tizen>
390 public Color SlidedTrackColor
394 return slidedTrackImage?.BackgroundColor;
398 if (null != slidedTrackImage)
400 slidedTrackImage.BackgroundColor = value;
401 sliderStyle.Progress.BackgroundColor = value;
407 /// Gets or sets the thickness value of the track.
409 /// <since_tizen> 6 </since_tizen>
410 public uint TrackThickness
414 return (uint)GetValue(TrackThicknessProperty);
418 SetValue(TrackThicknessProperty, value);
423 /// Gets or sets the resource url of the low indicator image object.
425 /// <since_tizen> 6 </since_tizen>
426 public string LowIndicatorImageURL
430 return lowIndicatorImage?.ResourceUrl;
434 if (null != lowIndicatorImage)
436 lowIndicatorImage.ResourceUrl = value;
437 sliderStyle.LowIndicatorImage.ResourceUrl = value;
443 /// Gets or sets the resource url of the high indicator image object.
445 /// <since_tizen> 6 </since_tizen>
446 public string HighIndicatorImageURL
450 return highIndicatorImage?.ResourceUrl;
454 if (null != highIndicatorImage)
456 highIndicatorImage.ResourceUrl = value;
457 sliderStyle.HighIndicatorImage.ResourceUrl = value;
463 /// Gets or sets the text content of the low indicator text object.
465 /// <since_tizen> 6 </since_tizen>
466 public string LowIndicatorTextContent
470 return lowIndicatorText?.Text;
474 if (null != lowIndicatorText)
476 lowIndicatorText.Text= value;
477 sliderStyle.LowIndicator.Text= value;
483 /// Gets or sets the text content of the high indicator text object.
485 /// <since_tizen> 6 </since_tizen>
486 public string HighIndicatorTextContent
490 return highIndicatorText?.Text;
494 if (null != highIndicatorText)
496 highIndicatorText.Text = value;
497 sliderStyle.HighIndicator.Text = value;
503 /// Gets or sets the size of the low indicator object(image or text).
505 /// <since_tizen> 6 </since_tizen>
506 public Size LowIndicatorSize
510 return lowIndicatorSize;
514 lowIndicatorSize = value;
515 UpdateLowIndicatorSize();
517 UpdateBgTrackPosition();
523 /// Gets or sets the size of the high indicator object(image or text).
525 /// <since_tizen> 6 </since_tizen>
526 public Size HighIndicatorSize
530 return highIndicatorText?.Size;
534 if (null != highIndicatorText)
536 highIndicatorText.Size = value;
537 sliderStyle.HighIndicator.Size = value;
543 /// Gets or sets the value of the space between track and indicator.
545 /// <since_tizen> 6 </since_tizen>
546 public uint SpaceBetweenTrackAndIndicator
550 return (uint)GetValue(SpaceBetweenTrackAndIndicatorProperty);
554 SetValue(SpaceBetweenTrackAndIndicatorProperty, value);
558 private Extents spaceBetweenTrackAndIndicator
562 if (null == _spaceBetweenTrackAndIndicator)
564 _spaceBetweenTrackAndIndicator = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
566 Extents extents = new Extents(start, end, top, bottom);
567 _spaceBetweenTrackAndIndicator.CopyFrom(extents);
571 return _spaceBetweenTrackAndIndicator;
575 private IndicatorType privateIndicatorType
579 return indicatorType;
583 if (indicatorType == value)
587 indicatorType = value;
588 RelayoutBaseComponent(false);
590 UpdateBgTrackPosition();
595 private uint privateTrackThickness
599 return trackThickness ?? 0;
603 trackThickness = value;
604 if (bgTrackImage != null)
606 if (direction == DirectionType.Horizontal)
608 bgTrackImage.SizeHeight = (float)trackThickness.Value;
610 else if (direction == DirectionType.Vertical)
612 bgTrackImage.SizeWidth = (float)trackThickness.Value;
615 if (slidedTrackImage != null)
617 if (direction == DirectionType.Horizontal)
619 slidedTrackImage.SizeHeight = (float)trackThickness.Value;
621 else if (direction == DirectionType.Vertical)
623 slidedTrackImage.SizeWidth = (float)trackThickness.Value;
629 private uint privateSpaceBetweenTrackAndIndicator
633 return privateTrackPadding.Start;
637 ushort val = (ushort)value;
638 privateTrackPadding = new Extents(val, val, val, val);
642 private Extents privateTrackPadding
646 return spaceBetweenTrackAndIndicator;
650 spaceBetweenTrackAndIndicator.CopyFrom(value);
651 UpdateComponentByIndicatorTypeChanged();
653 UpdateBgTrackPosition();
659 /// Focus gained callback.
661 /// <since_tizen> 8 </since_tizen>
662 public override void OnFocusGained()
664 //State = ControlStates.Focused;
665 UpdateState(true, isPressed);
666 base.OnFocusGained();
670 /// Focus Lost callback.
672 /// <since_tizen> 8 </since_tizen>
673 public override void OnFocusLost()
675 //State = ControlStates.Normal;
676 UpdateState(false, isPressed);
681 /// Apply style to scrollbar.
683 /// <param name="viewStyle">The style to apply.</param>
684 /// <since_tizen> 8 </since_tizen>
685 public override void ApplyStyle(ViewStyle viewStyle)
687 base.ApplyStyle(viewStyle);
689 SliderStyle sliderStyle = viewStyle as SliderStyle;
691 if (null != sliderStyle?.Progress)
693 CreateSlidedTrack().ApplyStyle(sliderStyle.Progress);
696 if (null != sliderStyle?.LowIndicator)
698 CreateLowIndicatorText().ApplyStyle(sliderStyle.LowIndicator);
701 if (null != sliderStyle?.HighIndicator)
703 CreateHighIndicatorText().ApplyStyle(sliderStyle.HighIndicator);
706 if (null != sliderStyle?.Track)
708 CreateBackgroundTrack().ApplyStyle(sliderStyle.Track);
711 if (null != sliderStyle?.Thumb)
713 CreateThumb().ApplyStyle(sliderStyle.Thumb);
716 EnableControlStatePropagation = true;
720 /// Get Slider style.
722 /// <returns>The default slider style.</returns>
723 /// <since_tizen> 8 </since_tizen>
724 protected override ViewStyle CreateViewStyle()
726 return new SliderStyle();
732 /// <param name="type">Dispose type.</param>
733 /// <since_tizen> 6 </since_tizen>
734 protected override void Dispose(DisposeTypes type)
741 if (type == DisposeTypes.Explicit)
743 if (null != panGestureDetector)
745 if (null != thumbImage)
747 panGestureDetector.Detach(thumbImage);
749 panGestureDetector.Detected -= OnPanGestureDetected;
750 panGestureDetector.Dispose();
751 panGestureDetector = null;
754 if (null != thumbImage)
756 thumbImage.TouchEvent -= OnTouchEventForThumb;
757 Utility.Dispose(thumbImage);
759 Utility.Dispose(slidedTrackImage);
760 if (null != bgTrackImage)
762 bgTrackImage.TouchEvent -= OnTouchEventForBgTrack;
763 Utility.Dispose(bgTrackImage);
765 Utility.Dispose(lowIndicatorImage);
766 Utility.Dispose(highIndicatorImage);
767 Utility.Dispose(lowIndicatorText);
768 Utility.Dispose(highIndicatorText);
775 /// Update Slider by style.
777 /// <since_tizen> 6 </since_tizen>
778 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
779 [EditorBrowsable(EditorBrowsableState.Never)]
780 protected override void OnUpdate()
782 RelayoutBaseComponent();
784 UpdateComponentByIndicatorTypeChanged();
786 UpdateBgTrackPosition();
787 UpdateLowIndicatorSize();
792 /// Theme change callback when theme is changed, this callback will be trigger.
794 /// <param name="sender">The sender</param>
795 /// <param name="e">The event data</param>
796 [EditorBrowsable(EditorBrowsableState.Never)]
797 protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
799 SliderStyle sliderStyle = StyleManager.Instance.GetViewStyle(StyleName) as SliderStyle;
800 if (sliderStyle != null)
802 ApplyStyle(sliderStyle);
807 private void CalculateCurrentValueByGesture(float offset)
809 currentSlidedOffset += offset;
811 if (currentSlidedOffset <= 0)
815 else if (currentSlidedOffset >= BgTrackLength())
821 int bgTrackLength = BgTrackLength();
822 if (bgTrackLength != 0)
824 curValue = ((currentSlidedOffset / (float)bgTrackLength) * (float)(maxValue - minValue)) + minValue;
827 if (valueChangedHandler != null)
829 ValueChangedArgs args = new ValueChangedArgs();
830 args.CurrentValue = curValue;
831 valueChangedHandler(this, args);
835 private bool OnTouchEventForBgTrack(object source, TouchEventArgs e)
837 PointStateType state = e.Touch.GetState(0);
838 if (state == PointStateType.Down)
840 Vector2 pos = e.Touch.GetLocalPosition(0);
841 CalculateCurrentValueByTouch(pos);
843 if (null != slidingFinishedHandler)
845 SlidingFinishedArgs args = new SlidingFinishedArgs();
846 args.CurrentValue = curValue;
847 slidingFinishedHandler(this, args);
853 private bool OnTouchEventForThumb(object source, TouchEventArgs e)
855 PointStateType state = e.Touch.GetState(0);
856 if (state == PointStateType.Down)
858 UpdateState(isFocused, true);
860 else if (state == PointStateType.Up)
862 UpdateState(isFocused, false);
867 private void CalculateCurrentValueByTouch(Vector2 pos)
869 int bgTrackLength = BgTrackLength();
870 if (direction == DirectionType.Horizontal)
872 currentSlidedOffset = pos.X;
874 else if (direction == DirectionType.Vertical)
876 currentSlidedOffset = bgTrackLength - pos.Y;
878 if (bgTrackLength != 0)
880 curValue = ((currentSlidedOffset / (float)bgTrackLength) * (maxValue - minValue)) + minValue;
881 if (null != valueChangedHandler)
883 ValueChangedArgs args = new ValueChangedArgs();
884 args.CurrentValue = curValue;
885 valueChangedHandler(this, args);
890 private void UpdateState(bool isFocusedNew, bool isPressedNew)
892 if (isFocused == isFocusedNew && isPressed == isPressedNew)
896 if (thumbImage == null || Style == null)
900 isFocused = isFocusedNew;
901 isPressed = isPressedNew;
903 if (!isFocused && !isPressed)
905 ControlState = ControlState.Normal;
906 if (stateChangedHandler != null)
908 StateChangedArgs args = new StateChangedArgs();
909 args.CurrentState = (ControlStates)ControlStates.Normal;
910 stateChangedHandler(this, args);
915 ControlState = ControlState.Pressed;
917 if (stateChangedHandler != null)
919 StateChangedArgs args = new StateChangedArgs();
920 args.CurrentState = (ControlStates)ControlStates.Pressed;
921 stateChangedHandler(this, args);
924 else if (!isPressed && isFocused)
926 ControlState = ControlState.Focused;
928 if (stateChangedHandler != null)
930 StateChangedArgs args = new StateChangedArgs();
931 args.CurrentState = (ControlStates)ControlStates.Focused;
932 stateChangedHandler(this, args);
937 private void UpdateComponentByIndicatorTypeChanged()
939 IndicatorType type = CurrentIndicatorType();
940 if (type == IndicatorType.None)
942 if (lowIndicatorImage != null)
944 lowIndicatorImage.Hide();
946 if (highIndicatorImage != null)
948 highIndicatorImage.Hide();
950 if (lowIndicatorText != null)
952 lowIndicatorText.Hide();
954 if (highIndicatorText != null)
956 highIndicatorText.Hide();
959 else if (type == IndicatorType.Image)
961 if (lowIndicatorImage != null)
963 lowIndicatorImage.Show();
965 if (highIndicatorImage != null)
967 highIndicatorImage.Show();
969 if (lowIndicatorText != null)
971 lowIndicatorText.Hide();
973 if (highIndicatorText != null)
975 highIndicatorText.Hide();
978 else if (type == IndicatorType.Text)
980 if (lowIndicatorText != null)
982 lowIndicatorText.Show();
984 if (highIndicatorText != null)
986 highIndicatorText.Show();
988 if (lowIndicatorImage != null)
990 lowIndicatorImage.Hide();
992 if (highIndicatorImage != null)
994 highIndicatorImage.Hide();
1000 /// Value Changed event data.
1002 /// <since_tizen> 6 </since_tizen>
1003 public class ValueChangedArgs : EventArgs
1008 /// <since_tizen> 6 </since_tizen>
1009 public float CurrentValue;
1013 /// Value Changed event data.
1015 /// <since_tizen> 6 </since_tizen>
1016 public class SlidingFinishedArgs : EventArgs
1021 /// <since_tizen> 6 </since_tizen>
1022 public float CurrentValue;
1026 /// State Changed event data.
1028 /// <since_tizen> 6 </since_tizen>
1029 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
1030 public class StateChangedArgs : EventArgs
1035 /// <since_tizen> 6 </since_tizen>
1036 [Obsolete("Deprecated in API8; Will be removed in API10")]
1037 public ControlStates CurrentState;