[NUI] Add CircularSlider to Wearable Component (#1659)
authorSeoyeon2Kim <34738918+Seoyeon2Kim@users.noreply.github.com>
Tue, 9 Jun 2020 05:14:19 +0000 (14:14 +0900)
committerGitHub <noreply@github.com>
Tue, 9 Jun 2020 05:14:19 +0000 (14:14 +0900)
* [NUI] Add CircularSlider to Wearable Component

Signed-off-by: Seoyeon Kim <seoyeon2.kim@samsung.com>
* Update implementation according to reviews

Signed-off-by: Seoyeon Kim <seoyeon2.kim@samsung.com>
src/Tizen.NUI.Wearable/src/public/CircularSlider.cs [new file with mode: 0755]
src/Tizen.NUI.Wearable/src/public/WearableStyle/CircularSliderStyle.cs [new file with mode: 0755]

diff --git a/src/Tizen.NUI.Wearable/src/public/CircularSlider.cs b/src/Tizen.NUI.Wearable/src/public/CircularSlider.cs
new file mode 100755 (executable)
index 0000000..4bb425b
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ * Copyright(c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components;
+using System.ComponentModel;
+
+namespace Tizen.NUI.Wearable
+{
+    /// <summary>
+    /// The CircularSlider class of Wearable is used to let users select a value from a continuous or discrete range of values by moving the slider thumb.
+    /// CircularSlider shows the current value with the length of the line.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CircularSlider : Control
+    {
+        #region Fields
+
+        /// <summary>Bindable property of Thickness</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ThicknessProperty = BindableProperty.Create(nameof(Thickness), typeof(float), typeof(CircularSlider), default(float), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = ((CircularSlider)bindable);
+
+            // TODO Set viewStyle.Thickness after style refactoring done.
+
+            instance.UpdateVisualThickness((float)newValue);
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)((CircularSlider)bindable).viewStyle)?.Thickness;
+        });
+
+        /// <summary>Bindable property of MaxValue</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty MaxValueProperty = BindableProperty.Create(nameof(MaxValue), typeof(float), typeof(CircularSlider), default(float), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+            if (newValue != null)
+            {
+                instance.maxValue = (float)newValue;
+                instance.UpdateValue();
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var instance = (CircularSlider)bindable;
+            return instance.maxValue;
+        });
+
+        /// <summary>Bindable property of MinValue</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty MinValueProperty = BindableProperty.Create(nameof(MinValue), typeof(float), typeof(CircularSlider), default(float), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+            if (newValue != null)
+            {
+                instance.minValue = (float)newValue;
+                instance.UpdateValue();
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var instance = (CircularSlider)bindable;
+            return instance.minValue;
+        });
+
+        /// <summary>Bindable property of CurrentValue</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create(nameof(CurrentValue), typeof(float), typeof(CircularSlider), default(float), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+            if (newValue != null)
+            {
+                if ((float)newValue > instance.maxValue || (float)newValue < instance.minValue)
+                {
+                    return;
+                }
+                instance.currentValue = (float)newValue;
+                instance.UpdateValue();
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var instance = (CircularSlider)bindable;
+            return instance.currentValue;
+        });
+
+        /// <summary>Bindable property of TrackColor</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty TrackColorProperty = BindableProperty.Create(nameof(TrackColor), typeof(Color), typeof(CircularSlider), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+
+            // TODO : Set viewStyle.TrackColor after style refactoring done.
+
+            instance.UpdateTrackVisualColor((Color)newValue);
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)((CircularSlider)bindable).viewStyle)?.TrackColor;
+        });
+
+        /// <summary>Bindable property of ProgressColor</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ProgressColorProperty = BindableProperty.Create(nameof(ProgressColor), typeof(Color), typeof(CircularSlider), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+
+            // TODO : Set viewStyle.ProgressColor after style refactoring done.
+
+            instance.UpdateProgressVisualColor((Color)newValue);
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)((CircularSlider)bindable).viewStyle)?.ProgressColor;
+        });
+
+        /// <summary>Bindable property of ThumbSize</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ThumbSizeProperty = BindableProperty.Create(nameof(ThumbSize), typeof(Size), typeof(CircularSlider), new Size(0,0), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+            if (newValue != null)
+            {
+                instance.thumbSize = (Size)newValue;
+                instance.UpdateThumbVisualSize((Size)newValue);
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var instance = (CircularSlider)bindable;
+            return instance.thumbSize;
+        });
+
+        /// <summary>Bindable property of ThumbColor</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(CircularSlider), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+
+            // TODO : Set viewStyle.ThumbColor after style refactoring done.
+
+            instance.UpdateThumbVisualColor((Color)newValue);
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)((CircularSlider)bindable).viewStyle)?.ThumbColor;
+        });
+
+        /// <summary>Bindable property of IsEnabled</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(CircularSlider), true, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (CircularSlider)bindable;
+            if (newValue != null)
+            {
+                instance.privateIsEnabled = (bool)newValue;
+            }
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            var instance = (CircularSlider)bindable;
+            return instance.privateIsEnabled;
+        });
+
+        private const string TrackVisualName = "Track";
+        private const string ProgressVisualName = "Progress";
+        private const string ThumbVisualName = "Thumb";
+        private ArcVisual trackVisual;
+        private ArcVisual progressVisual;
+        private ArcVisual thumbVisual;
+
+        private float maxValue = 100;
+        private float minValue = 0;
+        private float currentValue = 0;
+        private Size thumbSize;
+        private bool isEnabled = true;
+
+        float sliderPadding = 6.0f;
+
+        private Animation sweepAngleAnimation;
+        private Animation thumbAnimation;
+
+        /// <summary>
+        /// Get style of progress.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public new CircularSliderStyle Style => ViewStyle as CircularSliderStyle;
+
+        /// <summary>
+        /// Value Changed event data.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public class ValueChangedEventArgs : EventArgs
+        {
+            private float currentValue = 0.0f;
+
+            /// <summary>
+            /// Current value
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public float CurrentValue
+            {
+                get { return currentValue; }
+                set { currentValue = value; }
+            }
+        }
+
+        #endregion Fields
+
+
+        #region Constructors
+
+        static CircularSlider() { }
+        /// <summary>
+        /// The constructor of CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CircularSlider() : base(new CircularSliderStyle())
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// The constructor of the CircularSlider class with specific style.
+        /// </summary>
+        /// <param name="progressStyle">The style object to initialize the CircularSlider.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CircularSlider(CircularSliderStyle progressStyle) : base(progressStyle)
+        {
+            Initialize();
+        }
+
+        #endregion Constructors
+
+        #region Events
+
+        /// <summary>
+        /// The value changed event handler.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<ValueChangedEventArgs> ValueChanged;
+
+        #endregion Events
+
+        #region Properties
+
+        /// <summary>
+        /// The thickness of the track and progress.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float Thickness
+        {
+            get
+            {
+                return (float)GetValue(ThicknessProperty);
+            }
+            set
+            {
+                SetValue(ThicknessProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set the maximum value of the CircularSlider.
+        /// The default value is 100.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float MaxValue
+        {
+            get
+            {
+                return (float)GetValue(MaxValueProperty);
+            }
+            set
+            {
+                SetValue(MaxValueProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set the minimum value of the CircularSlider.
+        /// The default value is 0.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float MinValue
+        {
+            get
+            {
+                return (float)GetValue(MinValueProperty);
+            }
+            set
+            {
+                SetValue(MinValueProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set the current value of the CircularSlider.
+        /// The default value is 0.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float CurrentValue
+        {
+            get
+            {
+                return (float)GetValue(CurrentValueProperty);
+            }
+            set
+            {
+                if (sweepAngleAnimation)
+                {
+                    sweepAngleAnimation.Stop();
+                }
+                // For the first Animation effect
+                sweepAngleAnimation = AnimateVisual(progressVisual, "sweepAngle", progressVisual.SweepAngle, 0, 100, AlphaFunction.BuiltinFunctions.EaseIn);
+
+                SetValue(CurrentValueProperty, value);
+
+                UpdateAnimation();
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set Track object color of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color TrackColor
+        {
+            get
+            {
+                return (Color)GetValue(TrackColorProperty);
+            }
+            set
+            {
+                SetValue(TrackColorProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set Progress object color of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color ProgressColor
+        {
+            get
+            {
+                return (Color)GetValue(ProgressColorProperty);
+            }
+            set
+            {
+                SetValue(ProgressColorProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the size of the thumb of Slider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Size ThumbSize
+        {
+            get
+            {
+                return (Size)GetValue(ThumbSizeProperty);
+            }
+            set
+            {
+                SetValue(ThumbSizeProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set Thumb object color of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color ThumbColor
+        {
+            get
+            {
+                return (Color)GetValue(ThumbColorProperty);
+            }
+            set
+            {
+                SetValue(ThumbColorProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// Flag to be enabled or disabled in CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool IsEnabled
+        {
+            get
+            {
+                return (bool)GetValue(IsEnabledProperty);
+            }
+            set
+            {
+                SetValue(IsEnabledProperty, value);
+            }
+        }
+        private bool privateIsEnabled
+        {
+            get
+            {
+                return isEnabled;
+            }
+            set
+            {
+                isEnabled = value;
+                if (isEnabled)
+                {
+                    UpdateTrackVisualColor(new Color(0.0f, 0.16f, 0.30f, 1.0f)); // #002A4D
+                }
+                else
+                {
+                    UpdateTrackVisualColor(new Color(0.25f, 0.25f, 0.25f, 1.0f)); // #404040
+                }
+            }
+        }
+
+        #endregion Properties
+
+
+        #region Methods
+
+        /// <summary>
+        /// Dispose Progress and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                trackVisual = null;
+                progressVisual = null;
+                thumbVisual = null;
+            }
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
+        /// Update progress value
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected virtual void UpdateValue()
+        {
+            if (null == trackVisual || null == progressVisual || null == thumbVisual)
+            {
+                return;
+            }
+
+            if (minValue >= maxValue || currentValue < minValue || currentValue > maxValue)
+            {
+                return;
+            }
+
+            HandleProgressVisualVisibility();
+
+            UpdateProgressVisualSweepAngle();
+        }
+
+        /// <summary>
+        /// Get Progress style.
+        /// </summary>
+        /// <returns>The default progress style.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override ViewStyle GetViewStyle()
+        {
+            return new CircularSliderStyle();
+        }
+
+        private void Initialize()
+        {
+            Size = new Size(360.0f, 360.0f);
+
+            sweepAngleAnimation?.Stop();
+            sweepAngleAnimation = null;
+
+            thumbAnimation?.Stop();
+            thumbAnimation = null;
+
+            trackVisual = new ArcVisual
+            {
+                SuppressUpdateVisual = true,
+                Size = new Size(this.Size.Width - sliderPadding, this.Size.Height - sliderPadding),
+                SizePolicy = VisualTransformPolicyType.Absolute,
+                Thickness = this.Thickness,
+                Cap = ArcVisual.CapType.Butt,
+                MixColor = TrackColor,
+                StartAngle = 0.0f,
+                SweepAngle = 360.0f
+            };
+            this.AddVisual(TrackVisualName, trackVisual);
+
+            progressVisual = new ArcVisual
+            {
+                SuppressUpdateVisual = true,
+                Size = new Size(this.Size.Width - sliderPadding, this.Size.Height - sliderPadding),
+                SizePolicy = VisualTransformPolicyType.Absolute,
+                Thickness = this.Thickness,
+                Cap = ArcVisual.CapType.Butt,
+                MixColor = ProgressColor,
+                StartAngle = 0.0f,
+                SweepAngle = 0.0f
+            };
+            this.AddVisual(ProgressVisualName, progressVisual);
+
+            thumbVisual = new ArcVisual
+            {
+                SuppressUpdateVisual = true,
+                Size = new Size(this.Size.Width + sliderPadding, this.Size.Height + sliderPadding),
+                SizePolicy = VisualTransformPolicyType.Absolute,
+                Thickness = this.ThumbSize.Width,
+                Cap = ArcVisual.CapType.Round,
+                MixColor = this.ThumbColor,
+                StartAngle = 0.0f,
+                SweepAngle = 0.0f
+            };
+            this.AddVisual(ThumbVisualName,  thumbVisual);
+
+            HandleProgressVisualVisibility();
+
+            UpdateProgressVisualSweepAngle();
+        }
+
+        private void HandleProgressVisualVisibility()
+        {
+            if (isEnabled)
+            {
+                progressVisual.Opacity = 1.0f;
+            }
+            else if (!isEnabled)
+            {
+                progressVisual.Opacity = 0.6f;
+            }
+        }
+
+        private void UpdateVisualThickness(float thickness)
+        {
+            if (trackVisual == null)
+            {
+                return;
+            }
+
+            trackVisual.Thickness = thickness;
+            progressVisual.Thickness = thickness;
+
+            trackVisual.UpdateVisual(true);
+            progressVisual.UpdateVisual(true);
+        }
+
+        private void UpdateProgressVisualSweepAngle()
+        {
+            float progressRatio = (float)(currentValue - minValue) / (float)(maxValue - minValue);
+            float progressWidth = 360.0f * progressRatio; // Circle
+
+            progressVisual.SweepAngle = progressWidth;
+            thumbVisual.StartAngle = progressWidth;
+
+            if (!sweepAngleAnimation)
+            {
+                progressVisual.UpdateVisual(true);
+                thumbVisual.UpdateVisual(true);
+            }
+        }
+
+        private void UpdateAnimation()
+        {
+            // TODO : Currently not sure which effect is needed.
+            AlphaFunction.BuiltinFunctions builtinAlphaFunction = AlphaFunction.BuiltinFunctions.EaseOut;
+
+            if (sweepAngleAnimation)
+            {
+                sweepAngleAnimation.Stop();
+            }
+            if (thumbAnimation)
+            {
+                thumbAnimation.Stop();
+            }
+
+            sweepAngleAnimation = AnimateVisual(progressVisual, "sweepAngle", progressVisual.SweepAngle, 0, 500, builtinAlphaFunction);
+            thumbAnimation = AnimateVisual(thumbVisual, "startAngle", thumbVisual.StartAngle, 0, 500, builtinAlphaFunction);
+
+            if (sweepAngleAnimation)
+            {
+                sweepAngleAnimation.Play();
+                thumbAnimation.Play();
+            }
+
+            ValueChanged?.Invoke(this, new ValueChangedEventArgs() { CurrentValue = currentValue });
+        }
+
+        private void UpdateTrackVisualColor(Color trackColor)
+        {
+            if (trackVisual == null)
+            {
+                return;
+            }
+
+            trackVisual.MixColor = trackColor;
+            trackVisual.UpdateVisual(true);
+        }
+
+        private void UpdateProgressVisualColor(Color progressColor)
+        {
+            if (progressVisual == null)
+            {
+                return;
+            }
+
+            progressVisual.MixColor = progressColor;
+            if (!isEnabled) // Dim state
+            {
+                progressVisual.Opacity = 0.6f;
+            }
+
+            progressVisual.UpdateVisual(true);
+        }
+
+        private void UpdateThumbVisualSize(Size thumbSize)
+        {
+            if (thumbVisual == null)
+            {
+                return;
+            }
+
+            thumbVisual.Thickness = thumbSize.Width;
+            thumbVisual.UpdateVisual(true);
+        }
+
+        private void UpdateThumbVisualColor(Color thumbColor)
+        {
+            if (thumbVisual == null)
+            {
+                return;
+            }
+
+            thumbVisual.MixColor = thumbColor;
+            thumbVisual.UpdateVisual(true);
+        }
+
+
+        #endregion Methods
+    }
+}
diff --git a/src/Tizen.NUI.Wearable/src/public/WearableStyle/CircularSliderStyle.cs b/src/Tizen.NUI.Wearable/src/public/WearableStyle/CircularSliderStyle.cs
new file mode 100755 (executable)
index 0000000..cecf80b
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Copyright(c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components;
+
+namespace Tizen.NUI.Wearable
+{
+    /// <summary>
+    /// CircularSliderStyle is a class which saves CircularSlider's ux data.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CircularSliderStyle : ControlStyle
+    {
+        /// <summary>Bindable property of Thickness</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ThicknessProperty = BindableProperty.Create(nameof(Thickness), typeof(float?), typeof(CircularSliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).thickness = (float?)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).thickness;
+        });
+
+        /// <summary>Bindable property of MaxValue</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty MaxValueProperty = BindableProperty.Create(nameof(MaxValue), typeof(float), typeof(CircularSliderStyle), default(float), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).maxValue = (float)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).maxValue;
+        });
+
+        /// <summary>Bindable property of MinValue</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty MinValueProperty = BindableProperty.Create(nameof(MinValue), typeof(float), typeof(CircularSliderStyle), default(float), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).minValue = (float)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).minValue;
+        });
+
+        /// <summary>Bindable property of CurrentValue</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create(nameof(CurrentValue), typeof(float), typeof(CircularSliderStyle), default(float), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).currentValue = (float)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).currentValue;
+        });
+
+        /// <summary>Bindable property of TrackColor</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty TrackColorProperty = BindableProperty.Create(nameof(TrackColor), typeof(Color), typeof(CircularSliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).trackColor = (Color)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).trackColor;
+        });
+
+        /// <summary>Bindable property of ProgressColor</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ProgressColorProperty = BindableProperty.Create(nameof(ProgressColor), typeof(Color), typeof(CircularSliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).progressColor = (Color)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).progressColor;
+        });
+
+        /// <summary>Bindable property of ThumbSize</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ThumbSizeProperty = BindableProperty.Create(nameof(ThumbSize), typeof(Size), typeof(CircularSliderStyle), new Size(0,0), propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).thumbSize = (Size)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).thumbSize;
+        });
+
+        /// <summary>Bindable property of ThumbColor</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(CircularSliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).thumbColor = (Color)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).thumbColor;
+        });
+
+        /// <summary>Bindable property of IsEnabled</summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool?), typeof(CircularSliderStyle), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            ((CircularSliderStyle)bindable).isEnabled = (bool?)newValue;
+        },
+        defaultValueCreator: (bindable) =>
+        {
+            return ((CircularSliderStyle)bindable).isEnabled;
+        });
+
+        private float? thickness;
+        private float maxValue;
+        private float minValue;
+        private float currentValue;
+        private Color trackColor;
+        private Color progressColor;
+        private Color thumbColor;
+        private Size thumbSize;
+        private bool? isEnabled;
+
+        static CircularSliderStyle() { }
+
+        /// <summary>
+        /// Creates a new instance of a CircularSliderStyle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CircularSliderStyle() : base()
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of a CircularSliderStyle with style.
+        /// </summary>
+        /// <param name="style">Create CircularSliderStyle by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CircularSliderStyle(CircularSliderStyle style) : base(style)
+        {
+            if (null == style) return;
+            this.CopyFrom(style);
+        }
+
+        /// <summary>
+        /// The thickness of the track and progress.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float? Thickness
+        {
+            get
+            {
+                return (float?)GetValue(ThicknessProperty);
+            }
+            set
+            {
+                SetValue(ThicknessProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set the maximum value of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float MaxValue
+        {
+            get
+            {
+                return (float)GetValue(MaxValueProperty);
+            }
+            set
+            {
+                SetValue(MaxValueProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set the minim value of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float MinValue
+        {
+            get
+            {
+                return (float)GetValue(MinValueProperty);
+            }
+            set
+            {
+                SetValue(MinValueProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set the current value of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public float CurrentValue
+        {
+            get
+            {
+                return (float)GetValue(CurrentValueProperty);
+            }
+            set
+            {
+                SetValue(CurrentValueProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set Track object color of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color TrackColor
+        {
+            get
+            {
+                return (Color)GetValue(TrackColorProperty);
+            }
+            set
+            {
+                SetValue(TrackColorProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set Progress object color of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color ProgressColor
+        {
+            get
+            {
+                return (Color)GetValue(ProgressColorProperty);
+            }
+            set
+            {
+                SetValue(ProgressColorProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the size of the thumb of Slider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Size ThumbSize
+        {
+            get
+            {
+                return (Size)GetValue(ThumbSizeProperty);
+            }
+            set
+            {
+                SetValue(ThumbSizeProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The property to get/set Thumb object color of the CircularSlider.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Color ThumbColor
+        {
+            get
+            {
+                return (Color)GetValue(ThumbColorProperty);
+            }
+            set
+            {
+                SetValue(ThumbColorProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// Flag to be enabled or disabled in CircularSlider.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public bool? IsEnabled
+        {
+            get
+            {
+                return (bool?)GetValue(IsEnabledProperty);
+            }
+            set
+            {
+                SetValue(IsEnabledProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// Style's clone function.
+        /// </summary>
+        /// <param name="bindableObject">The style that need to copy.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void CopyFrom(BindableObject bindableObject)
+        {
+            base.CopyFrom(bindableObject);
+
+            CircularSliderStyle progressStyle = bindableObject as CircularSliderStyle;
+
+            if (null != progressStyle)
+            {
+                isEnabled = progressStyle.isEnabled;
+                thickness = progressStyle.Thickness;
+                maxValue = progressStyle.maxValue;
+                minValue = progressStyle.minValue;
+                currentValue = progressStyle.currentValue;
+                trackColor = progressStyle.trackColor;
+                progressColor = progressStyle.progressColor;
+                thumbSize = progressStyle.thumbSize;
+                thumbColor = progressStyle.thumbColor;
+            }
+        }
+
+        private void Initialize()
+        {
+            isEnabled = true;
+            thickness = 6.0f;
+            maxValue = 100.0f;
+            minValue = 0.0f;
+            currentValue = 0.0f;
+            trackColor = new Color(0.0f, 0.16f, 0.30f, 1.0f); // #002A4D
+            progressColor = new Color(0.0f, 0.55f, 1.0f, 1.0f); // #008CFF
+            thumbSize = new Size(19, 19);
+            thumbColor = new Color(0.0f, 0.55f, 1.0f, 1.0f); // #008CFF
+        }
+    }
+}