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> 8 </since_tizen>
635 public override void OnFocusGained()
637 //State = ControlStates.Focused;
638 UpdateState(true, isPressed);
639 base.OnFocusGained();
643 /// Focus Lost callback.
645 /// <since_tizen> 8 </since_tizen>
646 public override void OnFocusLost()
648 //State = ControlStates.Normal;
649 UpdateState(false, isPressed);
654 /// Apply style to scrollbar.
656 /// <param name="viewStyle">The style to apply.</param>
657 /// <since_tizen> 8 </since_tizen>
658 public override void ApplyStyle(ViewStyle viewStyle)
660 base.ApplyStyle(viewStyle);
662 SliderStyle sliderStyle = viewStyle as SliderStyle;
664 if (null != sliderStyle?.Progress)
666 CreateSlidedTrack().ApplyStyle(sliderStyle.Progress);
669 if (null != sliderStyle?.LowIndicator)
671 CreateLowIndicatorText().ApplyStyle(sliderStyle.LowIndicator);
674 if (null != sliderStyle?.HighIndicator)
676 CreateHighIndicatorText().ApplyStyle(sliderStyle.HighIndicator);
679 if (null != sliderStyle?.Track)
681 CreateBackgroundTrack().ApplyStyle(sliderStyle.Track);
684 if (null != sliderStyle?.Thumb)
686 CreateThumb().ApplyStyle(sliderStyle.Thumb);
689 EnableControlStatePropagation = true;
693 /// Get Slider style.
695 /// <returns>The default slider style.</returns>
696 /// <since_tizen> 8 </since_tizen>
697 protected override ViewStyle CreateViewStyle()
699 return new SliderStyle();
705 /// <param name="type">Dispose type.</param>
706 /// <since_tizen> 6 </since_tizen>
707 protected override void Dispose(DisposeTypes type)
714 if (type == DisposeTypes.Explicit)
716 if (null != panGestureDetector)
718 if (null != thumbImage)
720 panGestureDetector.Detach(thumbImage);
722 panGestureDetector.Detected -= OnPanGestureDetected;
723 panGestureDetector.Dispose();
724 panGestureDetector = null;
727 if (null != thumbImage)
729 thumbImage.TouchEvent -= OnTouchEventForThumb;
730 Utility.Dispose(thumbImage);
732 Utility.Dispose(slidedTrackImage);
733 if (null != bgTrackImage)
735 bgTrackImage.TouchEvent -= OnTouchEventForBgTrack;
736 Utility.Dispose(bgTrackImage);
738 Utility.Dispose(lowIndicatorImage);
739 Utility.Dispose(highIndicatorImage);
740 Utility.Dispose(lowIndicatorText);
741 Utility.Dispose(highIndicatorText);
748 /// Update Slider by style.
750 /// <since_tizen> 6 </since_tizen>
751 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
752 [EditorBrowsable(EditorBrowsableState.Never)]
753 protected override void OnUpdate()
755 RelayoutBaseComponent();
757 UpdateComponentByIndicatorTypeChanged();
759 UpdateBgTrackPosition();
760 UpdateLowIndicatorSize();
765 /// Theme change callback when theme is changed, this callback will be trigger.
767 /// <param name="sender">The sender</param>
768 /// <param name="e">The event data</param>
769 [EditorBrowsable(EditorBrowsableState.Never)]
770 protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
772 SliderStyle sliderStyle = StyleManager.Instance.GetViewStyle(StyleName) as SliderStyle;
773 if (sliderStyle != null)
775 Style?.CopyFrom(sliderStyle);
780 private void CalculateCurrentValueByGesture(float offset)
782 currentSlidedOffset += offset;
784 if (currentSlidedOffset <= 0)
788 else if (currentSlidedOffset >= BgTrackLength())
794 int bgTrackLength = BgTrackLength();
795 if (bgTrackLength != 0)
797 curValue = ((currentSlidedOffset / (float)bgTrackLength) * (float)(maxValue - minValue)) + minValue;
800 if (valueChangedHandler != null)
802 ValueChangedArgs args = new ValueChangedArgs();
803 args.CurrentValue = curValue;
804 valueChangedHandler(this, args);
808 private bool OnTouchEventForBgTrack(object source, TouchEventArgs e)
810 PointStateType state = e.Touch.GetState(0);
811 if (state == PointStateType.Down)
813 Vector2 pos = e.Touch.GetLocalPosition(0);
814 CalculateCurrentValueByTouch(pos);
816 if (null != slidingFinishedHandler)
818 SlidingFinishedArgs args = new SlidingFinishedArgs();
819 args.CurrentValue = curValue;
820 slidingFinishedHandler(this, args);
826 private bool OnTouchEventForThumb(object source, TouchEventArgs e)
828 PointStateType state = e.Touch.GetState(0);
829 if (state == PointStateType.Down)
831 UpdateState(isFocused, true);
833 else if (state == PointStateType.Up)
835 UpdateState(isFocused, false);
840 private void CalculateCurrentValueByTouch(Vector2 pos)
842 int bgTrackLength = BgTrackLength();
843 if (direction == DirectionType.Horizontal)
845 currentSlidedOffset = pos.X;
847 else if (direction == DirectionType.Vertical)
849 currentSlidedOffset = bgTrackLength - pos.Y;
851 if (bgTrackLength != 0)
853 curValue = ((currentSlidedOffset / (float)bgTrackLength) * (maxValue - minValue)) + minValue;
854 if (null != valueChangedHandler)
856 ValueChangedArgs args = new ValueChangedArgs();
857 args.CurrentValue = curValue;
858 valueChangedHandler(this, args);
863 private void UpdateState(bool isFocusedNew, bool isPressedNew)
865 if (isFocused == isFocusedNew && isPressed == isPressedNew)
869 if (thumbImage == null || Style == null)
873 isFocused = isFocusedNew;
874 isPressed = isPressedNew;
876 if (!isFocused && !isPressed)
878 ControlState = ControlStates.Normal;
879 if (stateChangedHandler != null)
881 StateChangedArgs args = new StateChangedArgs();
882 args.CurrentState = (ControlStates)ControlStates.Normal;
883 stateChangedHandler(this, args);
888 ControlState = ControlStates.Pressed;
890 if (stateChangedHandler != null)
892 StateChangedArgs args = new StateChangedArgs();
893 args.CurrentState = (ControlStates)ControlStates.Pressed;
894 stateChangedHandler(this, args);
897 else if (!isPressed && isFocused)
899 ControlState = ControlStates.Focused;
901 if (stateChangedHandler != null)
903 StateChangedArgs args = new StateChangedArgs();
904 args.CurrentState = (ControlStates)ControlStates.Focused;
905 stateChangedHandler(this, args);
910 private void UpdateComponentByIndicatorTypeChanged()
912 IndicatorType type = CurrentIndicatorType();
913 if (type == IndicatorType.None)
915 if (lowIndicatorImage != null)
917 lowIndicatorImage.Hide();
919 if (highIndicatorImage != null)
921 highIndicatorImage.Hide();
923 if (lowIndicatorText != null)
925 lowIndicatorText.Hide();
927 if (highIndicatorText != null)
929 highIndicatorText.Hide();
932 else if (type == IndicatorType.Image)
934 if (lowIndicatorImage != null)
936 lowIndicatorImage.Show();
938 if (highIndicatorImage != null)
940 highIndicatorImage.Show();
942 if (lowIndicatorText != null)
944 lowIndicatorText.Hide();
946 if (highIndicatorText != null)
948 highIndicatorText.Hide();
951 else if (type == IndicatorType.Text)
953 if (lowIndicatorText != null)
955 lowIndicatorText.Show();
957 if (highIndicatorText != null)
959 highIndicatorText.Show();
961 if (lowIndicatorImage != null)
963 lowIndicatorImage.Hide();
965 if (highIndicatorImage != null)
967 highIndicatorImage.Hide();
973 /// Value Changed event data.
975 /// <since_tizen> 6 </since_tizen>
976 public class ValueChangedArgs : EventArgs
981 /// <since_tizen> 6 </since_tizen>
982 public float CurrentValue;
986 /// Value Changed event data.
988 /// <since_tizen> 6 </since_tizen>
989 public class SlidingFinishedArgs : EventArgs
994 /// <since_tizen> 6 </since_tizen>
995 public float CurrentValue;
999 /// State Changed event data.
1001 /// <since_tizen> 6 </since_tizen>
1002 public class StateChangedArgs : EventArgs
1007 /// <since_tizen> 6 </since_tizen>
1008 public ControlStates CurrentState;