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 public event EventHandler<StateChangedArgs> StateChangedEvent
147 stateChangedHandler += value;
151 stateChangedHandler -= value;
156 /// The direction type of slider.
158 /// <since_tizen> 6 </since_tizen>
159 public enum DirectionType
162 /// The Horizontal type.
164 /// <since_tizen> 6 </since_tizen>
168 /// The Vertical type.
170 /// <since_tizen> 6 </since_tizen>
175 /// The indicator type of slider.
177 /// <since_tizen> 6 </since_tizen>
178 public enum IndicatorType
180 /// <summary> Only contains slider bar.</summary>
181 /// <since_tizen> 6 </since_tizen>
184 /// <summary> Contains slider bar, IndicatorImage.</summary>
185 /// <since_tizen> 6 </since_tizen>
188 /// <summary> Contains slider bar, IndicatorText.</summary>
189 /// <since_tizen> 6 </since_tizen>
194 /// Get style of slider.
196 /// <since_tizen> 8 </since_tizen>
197 public new SliderStyle Style => ViewStyle as SliderStyle;
200 /// Gets or sets the direction type of slider.
202 /// <since_tizen> 6 </since_tizen>
203 public DirectionType Direction
211 if (direction == value)
216 RelayoutBaseComponent(false);
218 UpdateBgTrackPosition();
224 /// Gets or sets the indicator type, arrow or sign.
226 /// <since_tizen> 6 </since_tizen>
227 public IndicatorType Indicator
231 return (IndicatorType)GetValue(IndicatorTypeProperty);
235 SetValue(IndicatorTypeProperty, value);
240 /// Gets or sets the minimum value of slider.
242 /// <since_tizen> 6 </since_tizen>
243 public float MinValue
257 /// Gets or sets the maximum value of slider.
259 /// <since_tizen> 6 </since_tizen>
260 public float MaxValue
274 /// Gets or sets the current value of slider.
276 /// <since_tizen> 6 </since_tizen>
277 public float CurrentValue
291 /// Gets or sets the size of the thumb image object.
293 /// <since_tizen> 6 </since_tizen>
294 public Size ThumbSize
298 return Style.Thumb?.Size;
302 Style.Thumb.Size = value;
307 /// Gets or sets the resource url of the thumb image object.
309 /// <since_tizen> 6 </since_tizen>
310 public string ThumbImageURL
314 return Style?.Thumb?.ResourceUrl?.All;
318 if (null != Style?.Thumb)
320 Style.Thumb.ResourceUrl = value;
326 /// Gets or sets the resource url selector of the thumb image object.
328 /// <since_tizen> 6 </since_tizen>
329 public StringSelector ThumbImageURLSelector
333 return thumbImageURLSelector;
337 if (value == null || thumbImageURLSelector == null)
339 Tizen.Log.Fatal("NUI", "[Exception] Slider.ThumbImageURLSelector is null");
340 throw new NullReferenceException("Slider.ThumbImageURLSelector is null");
344 thumbImageURLSelector.Clone(value);
350 /// Gets or sets the color of the background track image object.
352 /// <since_tizen> 6 </since_tizen>
353 public Color BgTrackColor
357 return Style?.Track?.BackgroundColor?.All;
361 if (null != Style?.Track)
363 Style.Track.BackgroundColor = value;
369 /// Gets or sets the color of the slided track image object.
371 /// <since_tizen> 6 </since_tizen>
372 public Color SlidedTrackColor
376 return Style?.Progress?.BackgroundColor?.All;
380 if (null != Style?.Progress)
382 Style.Progress.BackgroundColor = value;
388 /// Gets or sets the thickness value of the track.
390 /// <since_tizen> 6 </since_tizen>
391 public uint TrackThickness
395 return (uint)GetValue(TrackThicknessProperty);
399 SetValue(TrackThicknessProperty, value);
404 /// Gets or sets the resource url of the low indicator image object.
406 /// <since_tizen> 6 </since_tizen>
407 public string LowIndicatorImageURL
411 return Style?.LowIndicatorImage?.ResourceUrl?.All;
415 if (null != Style?.LowIndicatorImage)
417 Style.LowIndicatorImage.ResourceUrl = value;
423 /// Gets or sets the resource url of the high indicator image object.
425 /// <since_tizen> 6 </since_tizen>
426 public string HighIndicatorImageURL
430 return Style?.HighIndicatorImage?.ResourceUrl?.All;
434 if (null != Style?.HighIndicatorImage)
436 Style.HighIndicatorImage.ResourceUrl = value;
442 /// Gets or sets the text content of the low indicator text object.
444 /// <since_tizen> 6 </since_tizen>
445 public string LowIndicatorTextContent
449 return Style?.LowIndicator?.Text?.All;
453 if (null != Style?.LowIndicator)
455 Style.LowIndicator.Text= value;
461 /// Gets or sets the text content of the high indicator text object.
463 /// <since_tizen> 6 </since_tizen>
464 public string HighIndicatorTextContent
468 return Style?.HighIndicator?.Text?.All;
472 if (null != Style?.HighIndicator)
474 Style.HighIndicator.Text = value;
480 /// Gets or sets the size of the low indicator object(image or text).
482 /// <since_tizen> 6 </since_tizen>
483 public Size LowIndicatorSize
487 return lowIndicatorSize;
491 lowIndicatorSize = value;
492 UpdateLowIndicatorSize();
494 UpdateBgTrackPosition();
500 /// Gets or sets the size of the high indicator object(image or text).
502 /// <since_tizen> 6 </since_tizen>
503 public Size HighIndicatorSize
507 return Style.HighIndicator.Size;
511 Style.HighIndicator.Size = value;
516 /// Gets or sets the value of the space between track and indicator.
518 /// <since_tizen> 6 </since_tizen>
519 public uint SpaceBetweenTrackAndIndicator
523 return (uint)GetValue(SpaceBetweenTrackAndIndicatorProperty);
527 SetValue(SpaceBetweenTrackAndIndicatorProperty, value);
531 private Extents spaceBetweenTrackAndIndicator
535 if (null == _spaceBetweenTrackAndIndicator)
537 _spaceBetweenTrackAndIndicator = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
539 Extents extents = new Extents(start, end, top, bottom);
540 _spaceBetweenTrackAndIndicator.CopyFrom(extents);
544 return _spaceBetweenTrackAndIndicator;
548 private IndicatorType privateIndicatorType
552 return indicatorType;
556 if (indicatorType == value)
560 indicatorType = value;
561 RelayoutBaseComponent(false);
563 UpdateBgTrackPosition();
568 private uint privateTrackThickness
572 return trackThickness ?? 0;
576 trackThickness = value;
577 if (bgTrackImage != null)
579 if (direction == DirectionType.Horizontal)
581 bgTrackImage.SizeHeight = (float)trackThickness.Value;
583 else if (direction == DirectionType.Vertical)
585 bgTrackImage.SizeWidth = (float)trackThickness.Value;
588 if (slidedTrackImage != null)
590 if (direction == DirectionType.Horizontal)
592 slidedTrackImage.SizeHeight = (float)trackThickness.Value;
594 else if (direction == DirectionType.Vertical)
596 slidedTrackImage.SizeWidth = (float)trackThickness.Value;
602 private uint privateSpaceBetweenTrackAndIndicator
606 return privateTrackPadding.Start;
610 ushort val = (ushort)value;
611 privateTrackPadding = new Extents(val, val, val, val);
615 private Extents privateTrackPadding
619 return spaceBetweenTrackAndIndicator;
623 spaceBetweenTrackAndIndicator.CopyFrom(value);
624 UpdateComponentByIndicatorTypeChanged();
626 UpdateBgTrackPosition();
632 /// Focus gained callback.
634 /// <since_tizen> 6 </since_tizen>
635 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
636 [EditorBrowsable(EditorBrowsableState.Never)]
637 public override void OnFocusGained()
639 //State = ControlStates.Focused;
640 UpdateState(true, isPressed);
641 base.OnFocusGained();
645 /// Focus Lost callback.
647 /// <since_tizen> 6 </since_tizen>
648 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
649 [EditorBrowsable(EditorBrowsableState.Never)]
650 public override void OnFocusLost()
652 //State = ControlStates.Normal;
653 UpdateState(false, isPressed);
658 /// Apply style to scrollbar.
660 /// <param name="viewStyle">The style to apply.</param>
661 /// <since_tizen> 8 </since_tizen>
662 public override void ApplyStyle(ViewStyle viewStyle)
664 base.ApplyStyle(viewStyle);
666 SliderStyle sliderStyle = viewStyle as SliderStyle;
668 if (null != sliderStyle?.Progress)
670 CreateSlidedTrack().ApplyStyle(sliderStyle.Progress);
673 if (null != sliderStyle?.LowIndicator)
675 CreateLowIndicatorText().ApplyStyle(sliderStyle.LowIndicator);
678 if (null != sliderStyle?.HighIndicator)
680 CreateHighIndicatorText().ApplyStyle(sliderStyle.HighIndicator);
683 if (null != sliderStyle?.Track)
685 CreateBackgroundTrack().ApplyStyle(sliderStyle.Track);
688 if (null != sliderStyle?.Thumb)
690 CreateThumb().ApplyStyle(sliderStyle.Thumb);
693 EnableControlStatePropagation = true;
697 /// Get Slider style.
699 /// <returns>The default slider style.</returns>
700 /// <since_tizen> 8 </since_tizen>
701 protected override ViewStyle CreateViewStyle()
703 return new SliderStyle();
709 /// <param name="type">Dispose type.</param>
710 /// <since_tizen> 6 </since_tizen>
711 protected override void Dispose(DisposeTypes type)
718 if (type == DisposeTypes.Explicit)
720 if (null != panGestureDetector)
722 if (null != thumbImage)
724 panGestureDetector.Detach(thumbImage);
726 panGestureDetector.Detected -= OnPanGestureDetected;
727 panGestureDetector.Dispose();
728 panGestureDetector = null;
731 if (null != thumbImage)
733 thumbImage.TouchEvent -= OnTouchEventForThumb;
734 Utility.Dispose(thumbImage);
736 Utility.Dispose(slidedTrackImage);
737 if (null != bgTrackImage)
739 bgTrackImage.TouchEvent -= OnTouchEventForBgTrack;
740 Utility.Dispose(bgTrackImage);
742 Utility.Dispose(lowIndicatorImage);
743 Utility.Dispose(highIndicatorImage);
744 Utility.Dispose(lowIndicatorText);
745 Utility.Dispose(highIndicatorText);
752 /// Update Slider by style.
754 /// <since_tizen> 6 </since_tizen>
755 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
756 [EditorBrowsable(EditorBrowsableState.Never)]
757 protected override void OnUpdate()
759 RelayoutBaseComponent();
761 UpdateComponentByIndicatorTypeChanged();
763 UpdateBgTrackPosition();
764 UpdateLowIndicatorSize();
769 /// Theme change callback when theme is changed, this callback will be trigger.
771 /// <param name="sender">The sender</param>
772 /// <param name="e">The event data</param>
773 /// <since_tizen> 8 </since_tizen>
774 protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
776 SliderStyle sliderStyle = StyleManager.Instance.GetViewStyle(StyleName) as SliderStyle;
777 if (sliderStyle != null)
779 Style?.CopyFrom(sliderStyle);
784 private void CalculateCurrentValueByGesture(float offset)
786 currentSlidedOffset += offset;
788 if (currentSlidedOffset <= 0)
792 else if (currentSlidedOffset >= BgTrackLength())
798 int bgTrackLength = BgTrackLength();
799 if (bgTrackLength != 0)
801 curValue = ((currentSlidedOffset / (float)bgTrackLength) * (float)(maxValue - minValue)) + minValue;
804 if (valueChangedHandler != null)
806 ValueChangedArgs args = new ValueChangedArgs();
807 args.CurrentValue = curValue;
808 valueChangedHandler(this, args);
812 private bool OnTouchEventForBgTrack(object source, TouchEventArgs e)
814 PointStateType state = e.Touch.GetState(0);
815 if (state == PointStateType.Down)
817 Vector2 pos = e.Touch.GetLocalPosition(0);
818 CalculateCurrentValueByTouch(pos);
820 if (null != slidingFinishedHandler)
822 SlidingFinishedArgs args = new SlidingFinishedArgs();
823 args.CurrentValue = curValue;
824 slidingFinishedHandler(this, args);
830 private bool OnTouchEventForThumb(object source, TouchEventArgs e)
832 PointStateType state = e.Touch.GetState(0);
833 if (state == PointStateType.Down)
835 UpdateState(isFocused, true);
837 else if (state == PointStateType.Up)
839 UpdateState(isFocused, false);
844 private void CalculateCurrentValueByTouch(Vector2 pos)
846 int bgTrackLength = BgTrackLength();
847 if (direction == DirectionType.Horizontal)
849 currentSlidedOffset = pos.X;
851 else if (direction == DirectionType.Vertical)
853 currentSlidedOffset = bgTrackLength - pos.Y;
855 if (bgTrackLength != 0)
857 curValue = ((currentSlidedOffset / (float)bgTrackLength) * (maxValue - minValue)) + minValue;
858 if (null != valueChangedHandler)
860 ValueChangedArgs args = new ValueChangedArgs();
861 args.CurrentValue = curValue;
862 valueChangedHandler(this, args);
867 private void UpdateState(bool isFocusedNew, bool isPressedNew)
869 if (isFocused == isFocusedNew && isPressed == isPressedNew)
873 if (thumbImage == null || Style == null)
877 isFocused = isFocusedNew;
878 isPressed = isPressedNew;
880 if (!isFocused && !isPressed)
882 ControlState = ControlStates.Normal;
883 if (stateChangedHandler != null)
885 StateChangedArgs args = new StateChangedArgs();
886 args.CurrentState = (ControlStates)ControlStates.Normal;
887 stateChangedHandler(this, args);
892 ControlState = ControlStates.Pressed;
894 if (stateChangedHandler != null)
896 StateChangedArgs args = new StateChangedArgs();
897 args.CurrentState = (ControlStates)ControlStates.Pressed;
898 stateChangedHandler(this, args);
901 else if (!isPressed && isFocused)
903 ControlState = ControlStates.Focused;
905 if (stateChangedHandler != null)
907 StateChangedArgs args = new StateChangedArgs();
908 args.CurrentState = (ControlStates)ControlStates.Focused;
909 stateChangedHandler(this, args);
914 private void UpdateComponentByIndicatorTypeChanged()
916 IndicatorType type = CurrentIndicatorType();
917 if (type == IndicatorType.None)
919 if (lowIndicatorImage != null)
921 lowIndicatorImage.Hide();
923 if (highIndicatorImage != null)
925 highIndicatorImage.Hide();
927 if (lowIndicatorText != null)
929 lowIndicatorText.Hide();
931 if (highIndicatorText != null)
933 highIndicatorText.Hide();
936 else if (type == IndicatorType.Image)
938 if (lowIndicatorImage != null)
940 lowIndicatorImage.Show();
942 if (highIndicatorImage != null)
944 highIndicatorImage.Show();
946 if (lowIndicatorText != null)
948 lowIndicatorText.Hide();
950 if (highIndicatorText != null)
952 highIndicatorText.Hide();
955 else if (type == IndicatorType.Text)
957 if (lowIndicatorText != null)
959 lowIndicatorText.Show();
961 if (highIndicatorText != null)
963 highIndicatorText.Show();
965 if (lowIndicatorImage != null)
967 lowIndicatorImage.Hide();
969 if (highIndicatorImage != null)
971 highIndicatorImage.Hide();
977 /// Value Changed event data.
979 /// <since_tizen> 6 </since_tizen>
980 public class ValueChangedArgs : EventArgs
985 /// <since_tizen> 6 </since_tizen>
986 public float CurrentValue;
990 /// Value Changed event data.
992 /// <since_tizen> 6 </since_tizen>
993 public class SlidingFinishedArgs : EventArgs
998 /// <since_tizen> 6 </since_tizen>
999 public float CurrentValue;
1003 /// State Changed event data.
1005 /// <since_tizen> 6 </since_tizen>
1006 public class StateChangedArgs : EventArgs
1011 /// <since_tizen> 6 </since_tizen>
1012 public ControlStates CurrentState;