-/*
- * Copyright(c) 2019 Samsung Electronics Co., Ltd.
+/*
+ * 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.
*
*/
using System;
-using Tizen.NUI.BaseComponents;
using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
using Tizen.NUI.Binding;
namespace Tizen.NUI.Components
{
/// <summary>
- /// The ScrollBar class of nui component. It allows users to recognize the direction and the range of lists/content. .
+ /// The Scrollbar is a component that contains track and thumb to indicate the current scrolled position of a scrollable object.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- public class ScrollBar : Control
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class Scrollbar : ScrollbarBase
{
- /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+ #region Fields
+
+ /// <summary>Bindable property of TrackThickness</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- public static readonly BindableProperty DirectionProperty = BindableProperty.Create("Direction", typeof(DirectionType), typeof(ScrollBar), DirectionType.Horizontal, propertyChanged: (bindable, oldValue, newValue) =>
+ public static readonly BindableProperty TrackThicknessProperty = BindableProperty.Create(nameof(TrackThickness), typeof(float), typeof(Scrollbar), default(float), propertyChanged: (bindable, oldValue, newValue) =>
{
- var instance = (ScrollBar)bindable;
- if (newValue != null)
- {
- instance.Style.Direction = (DirectionType?)newValue;
- instance.UpdateValue();
- }
+ var instance = ((Scrollbar)bindable);
+ var thickness = (float?)newValue;
+
+ instance.scrollbarStyle.TrackThickness = thickness;
+ instance.UpdateTrackThickness(thickness ?? 0);
},
defaultValueCreator: (bindable) =>
{
- var instance = (ScrollBar)bindable;
- return instance.Style.Direction;
+ return ((Scrollbar)bindable).scrollbarStyle.TrackThickness ?? 0;
});
- /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+
+ /// <summary>Bindable property of ThumbThickness</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- public static readonly BindableProperty MaxValueProperty = BindableProperty.Create("MaxValue", typeof(int), typeof(ScrollBar), default(int), propertyChanged: (bindable, oldValue, newValue) =>
+ public static readonly BindableProperty ThumbThicknessProperty = BindableProperty.Create(nameof(ThumbThickness), typeof(float), typeof(Scrollbar), default(float), propertyChanged: (bindable, oldValue, newValue) =>
{
- var instance = (ScrollBar)bindable;
- if (newValue != null)
- {
- if ((int)newValue >= 0)
- {
- instance.maxValue = (int)newValue;
- instance.UpdateValue();
- }
- }
+ var instance = ((Scrollbar)bindable);
+ var thickness = (float?)newValue;
+
+ instance.scrollbarStyle.ThumbThickness = thickness;
+ instance.UpdateThumbThickness(thickness ?? 0);
},
defaultValueCreator: (bindable) =>
{
- var instance = (ScrollBar)bindable;
- return instance.maxValue;
+ return ((Scrollbar)bindable).scrollbarStyle.ThumbThickness ?? 0;
});
- /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+
+ /// <summary>Bindable property of TrackColor</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- public static readonly BindableProperty MinValueProperty = BindableProperty.Create("MinValue", typeof(int), typeof(ScrollBar), default(int), propertyChanged: (bindable, oldValue, newValue) =>
+ public static readonly BindableProperty TrackColorProperty = BindableProperty.Create(nameof(TrackColor), typeof(Color), typeof(Scrollbar), null, propertyChanged: (bindable, oldValue, newValue) =>
{
- var instance = (ScrollBar)bindable;
- if (newValue != null)
- {
- if ((int)newValue >= 0)
- {
- instance.minValue = (int)newValue;
- instance.UpdateValue();
- }
- }
+ var instance = ((Scrollbar)bindable);
+ var color = (Color)newValue;
+
+ instance.scrollbarStyle.TrackColor = color;
+ instance.UpdateTrackColor(color);
},
defaultValueCreator: (bindable) =>
{
- var instance = (ScrollBar)bindable;
- return instance.minValue;
+ return ((Scrollbar)bindable).scrollbarStyle.TrackColor;
});
- /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+
+ /// <summary>Bindable property of ThumbColor</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- public static readonly BindableProperty CurrentValueProperty = BindableProperty.Create("CurrentValue", typeof(int), typeof(ScrollBar), default(int), propertyChanged: (bindable, oldValue, newValue) =>
+ public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(Scrollbar), null, propertyChanged: (bindable, oldValue, newValue) =>
{
- var instance = (ScrollBar)bindable;
- if (newValue != null)
- {
- if ((int)newValue >= 0)
- {
- instance.curValue = (int)newValue;
- instance.UpdateValue();
- }
- }
+ var instance = ((Scrollbar)bindable);
+ var color = (Color)newValue;
+
+ instance.scrollbarStyle.ThumbColor = color;
+ instance.UpdateThumbColor(color);
},
defaultValueCreator: (bindable) =>
{
- var instance = (ScrollBar)bindable;
- return instance.curValue;
+ return ((Scrollbar)bindable).scrollbarStyle.ThumbColor;
});
- /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+
+ /// <summary>Bindable property of TrackPadding</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- public static readonly BindableProperty DurationProperty = BindableProperty.Create("Duration", typeof(uint), typeof(ScrollBar), default(uint), propertyChanged: (bindable, oldValue, newValue) =>
+ public static readonly BindableProperty TrackPaddingProperty = BindableProperty.Create(nameof(TrackPadding), typeof(Extents), typeof(Scrollbar), null, propertyChanged: (bindable, oldValue, newValue) =>
{
- var instance = (ScrollBar)bindable;
- if (newValue != null)
- {
- instance.Style.Duration = (uint)newValue;
- if (instance.scrollAniPlayer != null)
- {
- instance.scrollAniPlayer.Duration = (int)newValue;
- }
- }
+ var instance = ((Scrollbar)bindable);
+ var trackPadding = (Extents)newValue;
+
+ instance.scrollbarStyle.TrackPadding = trackPadding;
+ instance.UpdateTrackPadding(trackPadding);
},
defaultValueCreator: (bindable) =>
{
- var instance = (ScrollBar)bindable;
- return instance.Style.Duration;
+ return ((Scrollbar)bindable).scrollbarStyle.TrackPadding;
});
- private ImageView trackImage;
- private ImageView thumbImage;
- private Animation scrollAniPlayer = null;
- private float thumbImagePosX;
- private float thumbImagePosY;
- private bool enableAni = false;
- private int minValue;
- private int maxValue;
- private int curValue;
+ private ColorVisual trackVisual;
+ private ColorVisual thumbVisual;
+ private Animation thumbPositionAnimation;
+ private Animation thumbSizeAnimation;
+ private Calculator calculator;
+ private Size containerSize = new Size(0, 0);
+ private ScrollbarStyle scrollbarStyle => ViewStyle as ScrollbarStyle;
+ private bool mScrollEnabled = true;
+ private float previousPosition;
+
+ #endregion Fields
+
+
+ #region Constructors
/// <summary>
- /// The constructor of ScrollBar.
+ /// Create an empty Scrollbar.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- public ScrollBar() : base()
+ public Scrollbar()
{
- Initialize();
}
/// <summary>
- /// The constructor of ScrollBar with specific style.
+ /// Create a Scrollbar and initialize with properties.
/// </summary>
- /// <param name="style">style name</param>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
+ /// <param name="contentLength">The length of the scrollable content area.</param>
+ /// <param name="viewportLength">The length of the viewport representing the amount of visible content.</param>
+ /// <param name="currentPosition">The current position of the viewport in scrollable content area. This is the viewport's top position if the scroller is vertical, otherwise, left.</param>
+ /// <param name="isHorizontal">Whether the direction of scrolling is horizontal or not. It is vertical by default.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
- public ScrollBar(string style) : base(style)
+ public Scrollbar(float contentLength, float viewportLength, float currentPosition, bool isHorizontal = false) : this()
{
- Initialize();
+ Initialize(contentLength, viewportLength, currentPosition, isHorizontal);
}
/// <summary>
- /// The constructor of ScrollBar with specific style.
+ /// Create an empty Scrollbar with a ScrollbarStyle instance to set style properties.
/// </summary>
- /// <param name="style">The style object to initialize the ScrollBar.</param>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
- public ScrollBar(ScrollBarStyle style) : base(style)
+ public Scrollbar(ScrollbarStyle style) : base(style)
{
- Initialize();
}
/// <summary>
- /// The direction type of the Scroll.
+ /// Static constructor to initialize bindable properties when loading.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- public enum DirectionType
- {
- /// <summary>
- /// The Horizontal type.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- Horizontal,
-
- /// <summary>
- /// The Vertical type.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- Vertical
+ static Scrollbar()
+ {
}
- #region public property
- /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+ #endregion Constructors
+
+
+ #region Properties
+
+ /// <summary>
+ /// The thickness of the track.
+ /// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- public new ScrollBarStyle Style => ViewStyle as ScrollBarStyle;
+ public float TrackThickness
+ {
+ get => (float)GetValue(TrackThicknessProperty);
+ set => SetValue(TrackThicknessProperty, value);
+ }
/// <summary>
- /// The property to get/set the direction of the ScrollBar.
+ /// The thickness of the thumb.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- public DirectionType Direction
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public float ThumbThickness
{
- get
- {
- return (DirectionType)GetValue(DirectionProperty);
- }
- set
- {
- SetValue(DirectionProperty, value);
- }
+ get => (float)GetValue(ThumbThicknessProperty);
+ set => SetValue(ThumbThicknessProperty, value);
}
/// <summary>
- /// The property to get/set the size of the thumb object.
+ /// The color of the track part.
/// </summary>
- /// <exception cref="InvalidOperationException">Throw when ThumbSize is null.</exception>
- /// <example>
- /// <code>
- /// ScrollBar scroll;
- /// try
- /// {
- /// scroll.ThumbSize = new Size(500, 10, 0);
- /// }
- /// catch(InvalidOperationException e)
- /// {
- /// Tizen.Log.Error(LogTag, "Failed to set ThumbSize value : " + e.Message);
- /// }
- /// </code>
- /// </example>
- /// <since_tizen> 6 </since_tizen>
- public Size ThumbSize
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Color TrackColor
{
- get
- {
- return Style?.Thumb?.Size;
- }
- set
- {
- if (null != Style?.Thumb)
- {
- Style.Thumb.Size = value;
- RelayoutRequest();
- }
- }
+ get => (Color)GetValue(TrackColorProperty);
+ set => SetValue(TrackColorProperty, value);
}
/// <summary>
- /// The property to get/set the image URL of the track object.
+ /// The color of the thumb part.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- public string TrackImageURL
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Color ThumbColor
{
- get
- {
- return Style?.Track?.ResourceUrl?.All;
- }
- set
- {
- if (null != Style?.Track)
- {
- Style.Track.ResourceUrl = value;
- RelayoutRequest();
- }
- }
+ get => (Color)GetValue(ThumbColorProperty);
+ set => SetValue(ThumbColorProperty, value);
}
/// <summary>
- /// The property to get/set the color of the track object.
+ /// The padding value of the track.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- public Color TrackColor
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Extents TrackPadding
{
- get
+ get => (Extents)GetValue(TrackPaddingProperty);
+ set => SetValue(TrackPaddingProperty, value);
+ }
+
+ #endregion Properties
+
+
+ #region Methods
+
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override void Initialize(float contentLength, float viewportLength, float currentPosition, bool isHorizontal = false)
+ {
+ if (isHorizontal)
{
- return Style?.Track?.BackgroundColor?.All;
+ calculator = new HorizontalCalculator(contentLength > 0.0f ? contentLength : 0.0f, viewportLength, currentPosition);
}
- set
+ else
{
- if (null != Style?.Track)
- {
- Style.Track.BackgroundColor = value;
- RelayoutRequest();
- }
+ calculator = new VerticalCalculator(contentLength > 0.0f ? contentLength : 0.0f, viewportLength, currentPosition);
}
- }
- /// <summary>
- /// The property to get/set the color of the thumb object.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- public Color ThumbColor
- {
- get
+ thumbPositionAnimation?.Stop();
+ thumbPositionAnimation = null;
+
+ thumbSizeAnimation?.Stop();
+ thumbSizeAnimation = null;
+
+ Size trackSize = calculator.CalculateTrackSize(TrackThickness, containerSize, TrackPadding);
+ Vector2 trackPosition = calculator.CalculateTrackPosition(TrackPadding);
+ Size thumbSize = calculator.CalculateThumbSize(ThumbThickness, trackSize);
+ Vector2 thumbPosition = calculator.CalculateThumbPosition(trackSize, thumbSize, TrackPadding);
+
+ if (trackVisual == null)
{
- return Style?.Thumb?.BackgroundColor?.All;
+ trackVisual = new ColorVisual
+ {
+ SuppressUpdateVisual = true,
+ Color = TrackColor,
+ SizePolicy = VisualTransformPolicyType.Absolute,
+ Origin = calculator.CalculatorTrackAlign(),
+ AnchorPoint = calculator.CalculatorTrackAlign(),
+ Size = trackSize,
+ Position = trackPosition,
+ };
+
+ AddVisual("Track", trackVisual);
}
- set
+ else
+ {
+ trackVisual.Size = trackSize;
+ trackVisual.Position = trackPosition;
+ trackVisual.UpdateVisual(true);
+ }
+
+ if (thumbVisual == null)
{
- if(null != Style?.Thumb)
+ thumbVisual = new ColorVisual
{
- Style.Thumb.BackgroundColor = value;
- RelayoutRequest();
- }
+ SuppressUpdateVisual = true,
+ MixColor = ThumbColor,
+ SizePolicy = VisualTransformPolicyType.Absolute,
+ Origin = calculator.CalculatorThumbAlign(),
+ AnchorPoint = calculator.CalculatorThumbAlign(),
+ Opacity = calculator.CalculateThumbVisibility() ? 1.0f : 0.0f,
+ Size = thumbSize,
+ Position = thumbPosition,
+ };
+
+ AddVisual("Thumb", thumbVisual);
+ }
+ else
+ {
+ thumbVisual.Size = thumbSize;
+ thumbVisual.Position = thumbPosition;
+ thumbVisual.UpdateVisual(true);
}
}
- /// <summary>
- /// The property to get/set the max value of the ScrollBar.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- public int MaxValue
+ /// <inheritdoc/>
+ /// <remarks>Please note that, for now, only alpha functions created with BuiltinFunctions are valid when animating. Otherwise, it will be treated as a linear alpha function. </remarks>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override void Update(float contentLength, float position, uint durationMs = 0, AlphaFunction alphaFunction = null)
{
- get
+ if (calculator == null)
{
- return (int)GetValue(MaxValueProperty);
+ return;
}
- set
+
+ calculator.contentLength = contentLength > 0.0f ? contentLength : 0.0f;
+ previousPosition = calculator.currentPosition;
+ calculator.currentPosition = position;
+
+ thumbVisual.Size = calculator.CalculateThumbSize(ThumbThickness, trackVisual.Size);
+ thumbVisual.Position = calculator.CalculateThumbScrollPosition(trackVisual.Size, thumbVisual.Position, TrackPadding);
+ thumbVisual.Opacity = calculator.CalculateThumbVisibility() ? 1.0f : 0.0f;
+
+ if (durationMs == 0)
{
- SetValue(MaxValueProperty, value);
+ thumbVisual.UpdateVisual(true);
+
+ return;
}
+
+ // TODO Support non built-in alpha function for visual trainsition in DALi.
+ AlphaFunction.BuiltinFunctions builtinAlphaFunction = alphaFunction?.GetBuiltinFunction() ?? AlphaFunction.BuiltinFunctions.Default;
+
+ thumbPositionAnimation?.Stop();
+ thumbPositionAnimation = AnimateVisual(thumbVisual, "position", thumbVisual.Position, 0, (int)durationMs, builtinAlphaFunction);
+ thumbPositionAnimation.Play();
+
+ thumbSizeAnimation?.Stop();
+ thumbSizeAnimation = AnimateVisual(thumbVisual, "size", thumbVisual.Size, 0, (int)durationMs, builtinAlphaFunction);
+ thumbSizeAnimation.Play();
}
- /// <summary>
- /// The property to get/set the min value of the ScrollBar.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- public int MinValue
+ /// <inheritdoc/>
+ /// <remarks>Please note that, for now, only alpha functions created with BuiltinFunctions are valid when animating. Otherwise, it will be treated as a linear alpha function. </remarks>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override void ScrollTo(float position, uint durationMs = 0, AlphaFunction alphaFunction = null)
{
- get
+ if (mScrollEnabled == false)
{
- return (int)GetValue(MinValueProperty);
+ return;
}
- set
+
+ if (calculator == null)
{
- SetValue(MinValueProperty, value);
+ return;
}
+
+ previousPosition = calculator.currentPosition;
+ calculator.currentPosition = position;
+ thumbVisual.Position = calculator.CalculateThumbScrollPosition(trackVisual.Size, thumbVisual.Position, TrackPadding);
+
+ if (durationMs == 0)
+ {
+ thumbVisual.UpdateVisual(true);
+
+ return;
+ }
+
+ // TODO Support non built-in alpha function for visual trainsition in DALi.
+ AlphaFunction.BuiltinFunctions builtinAlphaFunction = alphaFunction?.GetBuiltinFunction() ?? AlphaFunction.BuiltinFunctions.Default;
+
+ thumbPositionAnimation?.Stop();
+ thumbPositionAnimation = AnimateVisual(thumbVisual, "position", thumbVisual.Position, 0, (int)durationMs, builtinAlphaFunction);
+ thumbPositionAnimation.Play();
}
- /// <summary>
- /// The property to get/set the current value of the ScrollBar.
- /// </summary>
- /// <exception cref="ArgumentOutOfRangeException">Throw when Current value is less than Min value, or greater than Max value.</exception>
- /// <example>
- /// <code>
- /// ScrollBar scroll;
- /// scroll.MaxValue = 100;
- /// scroll.MinValue = 0;
- /// try
- /// {
- /// scroll.CurrentValue = 50;
- /// }
- /// catch(ArgumentOutOfRangeException e)
- /// {
- /// Tizen.Log.Error(LogTag, "Failed to set Current value : " + e.Message);
- /// }
- /// </code>
- /// </example>
- /// <since_tizen> 6 </since_tizen>
- public int CurrentValue
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override void OnRelayout(Vector2 size, RelayoutContainer container)
{
- get
+ base.OnRelayout(size, container);
+
+ if (size.Width == containerSize.Width && size.Height == containerSize.Height)
{
- return (int)GetValue(CurrentValueProperty);
+ return;
}
- set
+
+ containerSize = new Size(size.Width, size.Height);
+
+ if (calculator == null)
{
- SetValue(CurrentValueProperty, value);
+ return;
}
+
+ trackVisual.Size = calculator.CalculateTrackSize(TrackThickness, containerSize, TrackPadding);
+ trackVisual.Position = calculator.CalculateTrackPosition(TrackPadding);
+ thumbVisual.Size = calculator.CalculateThumbSize(ThumbThickness, trackVisual.Size);
+ thumbVisual.Position = calculator.CalculateThumbPosition(trackVisual.Size, thumbVisual.Size, TrackPadding);
+
+ trackVisual.UpdateVisual(true);
+ thumbVisual.UpdateVisual(true);
}
- /// <summary>
- /// Property to set/get animation duration.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- public uint Duration
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override void ApplyStyle(ViewStyle viewStyle)
{
- get
- {
- return (uint)GetValue(DurationProperty);
- }
- set
+ base.ApplyStyle(viewStyle);
+
+ if (viewStyle is ScrollbarStyle scrollbarStyle)
{
- SetValue(DurationProperty, value);
+ // Apply essential look.
+ if (scrollbarStyle.TrackThickness == null) scrollbarStyle.TrackThickness = 6.0f;
+ if (scrollbarStyle.ThumbThickness == null) scrollbarStyle.ThumbThickness = 6.0f;
+ if (scrollbarStyle.TrackColor == null) scrollbarStyle.TrackColor = new Color(1.0f, 1.0f, 1.0f, 0.15f);
+ if (scrollbarStyle.ThumbColor == null) scrollbarStyle.ThumbColor = new Color(0.6f, 0.6f, 0.6f, 1.0f);
+ if (scrollbarStyle.TrackPadding == null) scrollbarStyle.TrackPadding = 4;
+ if (scrollbarStyle.WidthResizePolicy == null) scrollbarStyle.WidthResizePolicy = ResizePolicyType.FillToParent;
+ if (scrollbarStyle.HeightResizePolicy == null) scrollbarStyle.HeightResizePolicy = ResizePolicyType.FillToParent;
}
}
- #endregion
- /// <summary>
- /// Method to set current value. The thumb object would move to the corresponding position with animation or not.
- /// </summary>
- /// <param name="currentValue">The special current value.</param>
- /// <param name="EnableAnimation">Enable move with animation or not, the default value is true.</param>
- /// <exception cref="ArgumentOutOfRangeException">Throw when current size is less than the min value, or greater than the max value.</exception>
- /// <example>
- /// <code>
- /// ScrollBar scroll;
- /// scroll.MinValue = 0;
- /// scroll.MaxValue = 100;
- /// try
- /// {
- /// scroll.SetCurrentValue(50);
- /// }
- /// catch(ArgumentOutOfRangeException e)
- /// {
- /// Tizen.Log.Error(LogTag, "Failed to set current value : " + e.Message);
- /// }
- /// </code>
- /// </example>
- /// <since_tizen> 6 </since_tizen>
- public void SetCurrentValue(int currentValue, bool enableAnimation = true)
- {
- if (currentValue < minValue || currentValue > maxValue)
- {
- //TNLog.E("Current value is less than the Min value, or greater than the Max value. currentValue = " + currentValue + ";");
- throw new ArgumentOutOfRangeException("Wrong Current value. It shoud be greater than the Min value, and less than the Max value!");
- }
-
- enableAni = enableAnimation;
- CurrentValue = currentValue;
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override ViewStyle CreateViewStyle()
+ {
+ return new ScrollbarStyle();
}
/// <summary>
- /// Dispose ScrollBar.
+ /// Update TrackThickness property of the scrollbar.
/// </summary>
- /// <param name="type">The DisposeTypes value.</param>
- /// <since_tizen> 6 </since_tizen>
- protected override void Dispose(DisposeTypes type)
+ /// <param name="thickness">The width of the track.</param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual void UpdateTrackThickness(float thickness)
{
- if (disposed)
+ if (trackVisual == null)
{
return;
}
- if (type == DisposeTypes.Explicit)
- {
- //Called by User
- //Release your own managed resources here.
- //You should release all of your own disposable objects here.
-
- Utility.Dispose(trackImage);
- Utility.Dispose(thumbImage);
+ trackVisual.Size = calculator.CalculateTrackSize(thickness, containerSize, TrackPadding);
+ trackVisual.UpdateVisual(true);
+ }
- if (scrollAniPlayer != null)
- {
- scrollAniPlayer.Stop();
- scrollAniPlayer.Clear();
- scrollAniPlayer.Dispose();
- scrollAniPlayer = null;
- }
+ /// <summary>
+ /// Update ThumbThickness property of the scrollbar.
+ /// </summary>
+ /// <param name="thickness">The width of the track.</param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual void UpdateThumbThickness(float thickness)
+ {
+ if (thumbVisual == null)
+ {
+ return;
}
- //Release your own unmanaged resources here.
- //You should not access any managed member here except static instance.
- //because the execution order of Finalizes is non-deterministic.
- //Unreference this from if a static instance refer to this.
-
- //You must call base.Dispose(type) just before exit.
- base.Dispose(type);
+ thumbVisual.Size = calculator.CalculateThumbSize(thickness, trackVisual.Size);
+ thumbVisual.UpdateVisual(true);
}
/// <summary>
- /// Get Scrollbar style.
+ /// Update TrackColor property of the scrollbar.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
+ /// <param name="color">The color of the track.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
- protected override ViewStyle GetViewStyle()
+ protected virtual void UpdateTrackColor(Color color)
{
- return new ScrollBarStyle();
+ if (trackVisual == null)
+ {
+ return;
+ }
+
+ trackVisual.MixColor = color;
+ trackVisual.UpdateVisual(true);
}
/// <summary>
- /// Theme change callback when theme is changed, this callback will be trigger.
+ /// Update ThumbColor property of the scrollbar.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
+ /// <param name="color">The color of the thumb.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
- protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
+ protected virtual void UpdateThumbColor(Color color)
{
- ScrollBarStyle tempStyle = StyleManager.Instance.GetViewStyle(style) as ScrollBarStyle;
- if (tempStyle != null)
+ if (thumbVisual == null)
{
- Style.CopyFrom(tempStyle);
- UpdateValue();
+ return;
}
+
+ thumbVisual.MixColor = color;
+ thumbVisual.UpdateVisual(true);
}
- private void Initialize()
+ /// <summary>
+ /// Update TrackPadding property of the scrollbar.
+ /// </summary>
+ /// <param name="trackPadding">The padding of the track.</param>
+ protected virtual void UpdateTrackPadding(Extents trackPadding)
{
- this.Focusable = false;
-
- trackImage = new ImageView
+ if (calculator == null)
{
- Focusable = false,
- WidthResizePolicy = ResizePolicyType.FillToParent,
- HeightResizePolicy = ResizePolicyType.FillToParent,
- PositionUsesPivotPoint = true,
- ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft,
- PivotPoint = Tizen.NUI.PivotPoint.CenterLeft
- };
- this.Add(trackImage);
- trackImage.ApplyStyle(Style.Track);
-
- thumbImage = new ImageView
- {
- Focusable = false,
- WidthResizePolicy = ResizePolicyType.Fixed,
- HeightResizePolicy = ResizePolicyType.Fixed,
- PositionUsesPivotPoint = true,
- ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft,
- PivotPoint = Tizen.NUI.PivotPoint.CenterLeft
- };
- this.Add(thumbImage);
- thumbImage.ApplyStyle(Style.Thumb);
+ return;
+ }
- scrollAniPlayer = new Animation(334);
- scrollAniPlayer.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.Linear);
+ trackVisual.Size = calculator.CalculateTrackSize(TrackThickness, containerSize, trackPadding);
+ trackVisual.Position = calculator.CalculateTrackPosition(trackPadding);
+ thumbVisual.Size = calculator.CalculateThumbSize(ThumbThickness, trackVisual.Size);
+ thumbVisual.Position = calculator.CalculateThumbPaddingPosition(trackVisual.Size, thumbVisual.Size, thumbVisual.Position, trackPadding);
- thumbImagePosX = 0;
- thumbImagePosY = 0;
- LayoutDirectionChanged += OnLayoutDirectionChanged;
+ trackVisual.UpdateVisual(true);
+ thumbVisual.UpdateVisual(true);
}
- private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
- {
- RelayoutRequest();
- }
-
- private void UpdateValue()
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool ScrollEnabled
{
- if (minValue >= maxValue || curValue < minValue || curValue > maxValue) return;
-
- float width = (float)Size2D.Width;
- float height = (float)Size2D.Height;
- float thumbW = 0.0f;
- float thumbH = 0.0f;
- if (Style.Thumb.Size == null)
+ get
{
- return;
+ return mScrollEnabled;
}
- else
+ set
{
- thumbW = Style.Thumb.Size.Width;
- thumbH = Style.Thumb.Size.Height;
+ if (value != mScrollEnabled)
+ {
+ mScrollEnabled = value;
+ }
}
- float ratio = (float)(curValue - minValue) / (float)(maxValue - minValue);
+ }
- if (Style.Direction == DirectionType.Horizontal)
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override Position ScrollPosition
+ {
+ get
{
- if (LayoutDirection == ViewLayoutDirectionType.RTL)
+ if (calculator == null)
{
- ratio = 1.0f - ratio;
+ return new Position(0.0f, 0.0f);
}
- float posX = ratio * (width - thumbW);
- float posY = (height - thumbH) / 2.0f;
+ float length = Math.Min(Math.Max(calculator.currentPosition, 0.0f), calculator.contentLength - calculator.visibleLength);
- thumbImagePosX = posX;
- if (null != scrollAniPlayer)
+ if (calculator is HorizontalCalculator)
{
- scrollAniPlayer.Stop();
- }
-
- if (!enableAni)
- {
- thumbImage.Position = new Position(posX, posY, 0);
+ return new Position(length, 0.0f);
}
else
{
- if (null != scrollAniPlayer)
- {
- scrollAniPlayer.Clear();
- scrollAniPlayer.AnimateTo(thumbImage, "PositionX", posX);
- scrollAniPlayer.Play();
- }
+ return new Position(0.0f, length);
}
}
- else
+ }
+
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override Position ScrollCurrentPosition
+ {
+ get
{
- float posX = (width - thumbW) / 2.0f;
- float posY = ratio * (height - thumbH);
+ if (calculator == null)
+ {
+ return new Position(0.0f, 0.0f);
+ }
+
+ float length = Math.Min(Math.Max(calculator.currentPosition, 0.0f), calculator.contentLength - calculator.visibleLength);
- thumbImagePosY = posY;
- if (null != scrollAniPlayer)
+ if (thumbPositionAnimation != null)
{
- scrollAniPlayer.Stop();
+ float progress = thumbPositionAnimation.CurrentProgress;
+ float previousLength = Math.Min(Math.Max(previousPosition, 0.0f), calculator.contentLength - calculator.visibleLength);
+
+ length = ((1.0f - progress) * previousLength) + (progress * length);
}
- if (!enableAni)
+ if (calculator is HorizontalCalculator)
{
- thumbImage.Position = new Position(posX, posY, 0);
+ return new Position(length, 0.0f);
}
else
{
- if (null != scrollAniPlayer)
- {
- scrollAniPlayer.Clear();
- scrollAniPlayer.AnimateTo(thumbImage, "PositionY", posY);
- scrollAniPlayer.Play();
- }
+ return new Position(0.0f, length);
}
}
+ }
+
+ #endregion Methods
+
- if (enableAni) enableAni = false;
+ #region Classes
+
+ private abstract class Calculator
+ {
+ public float contentLength;
+ public float visibleLength;
+ public float currentPosition;
+
+ public Calculator(float contentLength, float visibleLength, float currentPosition)
+ {
+ this.contentLength = contentLength;
+ this.visibleLength = visibleLength;
+ this.currentPosition = currentPosition;
+ }
+
+ public bool CalculateThumbVisibility()
+ {
+ return contentLength > visibleLength;
+ }
+
+ public abstract Visual.AlignType CalculatorTrackAlign();
+ public abstract Visual.AlignType CalculatorThumbAlign();
+ public abstract Size CalculateTrackSize(float thickness, Size containerSize, Extents trackPadding);
+ public abstract Vector2 CalculateTrackPosition(Extents trackPadding);
+ public abstract Size CalculateThumbSize(float thickness, Size trackSize);
+ public abstract Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, Extents trackPadding);
+ public abstract Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, Extents trackPadding);
+ public abstract Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbCurrentPosition, Extents trackPadding);
}
- private DirectionType CurrentDirection()
+ private class HorizontalCalculator : Calculator
{
- DirectionType dir = DirectionType.Horizontal;
- if (null != Style.Direction)
+ public HorizontalCalculator(float contentLength, float visibleLength, float currentPosition) : base(contentLength, visibleLength, currentPosition)
+ {
+ }
+
+ public override Visual.AlignType CalculatorTrackAlign()
+ {
+ return Visual.AlignType.BottomCenter;
+ }
+
+ public override Visual.AlignType CalculatorThumbAlign()
+ {
+ return Visual.AlignType.BottomBegin;
+ }
+
+ public override Size CalculateTrackSize(float thickness, Size containerSize, Extents trackPadding)
{
- dir = Style.Direction.Value;
+ return new Size(containerSize.Width - trackPadding?.Start ?? 0 - trackPadding?.End ?? 0, thickness);
+ }
+
+ public override Vector2 CalculateTrackPosition(Extents trackPadding)
+ {
+ return new Vector2(0, -trackPadding?.Bottom ?? 0);
+ }
+
+ public override Size CalculateThumbSize(float thickness, Size trackSize)
+ {
+ return new Size(trackSize.Width * visibleLength / contentLength, thickness);
+ }
+
+ public override Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, Extents trackPadding)
+ {
+ float padding = ((trackSize.Height - thumbSize.Height) / 2.0f) + trackPadding?.Bottom ?? 0;
+ float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
+ return new Vector2(trackPadding?.Start ?? 0 + trackSize.Width * pos / contentLength, -padding);
+ }
+
+ public override Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, Extents trackPadding)
+ {
+ float padding = ((trackSize.Height - thumbSize.Height) / 2.0f) + trackPadding?.Bottom ?? 0;
+ return new Vector2(thumbCurrentPosition.X, -padding);
+ }
+
+ public override Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbCurrentPosition, Extents trackPadding)
+ {
+ float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
+ return new Vector2(trackPadding?.Start ?? 0 + trackSize.Width * pos / contentLength, thumbCurrentPosition.Y);
}
- return dir;
}
- private int CalculateCurrentValue(float offset, DirectionType dir)
+ private class VerticalCalculator : Calculator
{
- if (dir == DirectionType.Horizontal)
+ public VerticalCalculator(float contentLength, float visibleLength, float currentPosition) : base(contentLength, visibleLength, currentPosition)
{
- thumbImagePosX += offset;
- if (thumbImagePosX < 0)
- {
- thumbImage.PositionX = 0;
- curValue = minValue;
- }
- else if (thumbImagePosX > Size2D.Width - thumbImage.Size2D.Width)
- {
- thumbImage.PositionX = Size2D.Width - thumbImage.Size2D.Width;
- curValue = maxValue;
- }
- else
- {
- thumbImage.PositionX = thumbImagePosX;
- curValue = (int)((thumbImagePosX / (float)(Size2D.Width - thumbImage.Size2D.Width)) * (float)(maxValue - minValue) + 0.5f);
- }
}
- else
+
+ public override Visual.AlignType CalculatorTrackAlign()
{
- thumbImagePosY += offset;
- if (thumbImagePosY < 0)
- {
- thumbImage.PositionY = 0;
- curValue = minValue;
- }
- else if (thumbImagePosY > Size2D.Height - thumbImage.Size2D.Height)
- {
- thumbImage.PositionY = Size2D.Height - thumbImage.Size2D.Height;
- curValue = maxValue;
- }
- else
- {
- thumbImage.PositionY = thumbImagePosY;
- curValue = (int)((thumbImagePosY / (float)(Size2D.Height - thumbImage.Size2D.Height)) * (float)(maxValue - minValue) + 0.5f);
- }
+ return Visual.AlignType.CenterEnd;
}
- return curValue;
+ public override Visual.AlignType CalculatorThumbAlign()
+ {
+ return Visual.AlignType.TopEnd;
+ }
+
+ public override Size CalculateTrackSize(float thickness, Size containerSize, Extents trackPadding)
+ {
+ return new Size(thickness, containerSize.Height - trackPadding?.Top ?? 0 - trackPadding?.Bottom ?? 0);
+ }
+
+ public override Vector2 CalculateTrackPosition(Extents trackPadding)
+ {
+ return new Vector2(-trackPadding?.End ?? 0, 0);
+ }
+
+ public override Size CalculateThumbSize(float thickness, Size trackSize)
+ {
+ return new Size(thickness, trackSize.Height * visibleLength / contentLength);
+ }
+
+ public override Vector2 CalculateThumbPosition(Size trackSize, Size thumbSize, Extents trackPadding)
+ {
+ float padding = ((trackSize.Width - thumbSize.Width) / 2.0f) + trackPadding?.End ?? 0;
+ float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
+ return new Vector2(-padding, trackPadding?.Top ?? 0 + trackSize.Height * pos / contentLength);
+ }
+
+ public override Vector2 CalculateThumbPaddingPosition(Size trackSize, Size thumbSize, Vector2 thumbCurrentPosition, Extents trackPadding)
+ {
+ float padding = ((trackSize.Width - thumbSize.Width) / 2.0f) + trackPadding?.End ?? 0;
+ return new Vector2(-padding, thumbCurrentPosition.Y);
+ }
+
+ public override Vector2 CalculateThumbScrollPosition(Size trackSize, Vector2 thumbPosition, Extents trackPadding)
+ {
+ float pos = Math.Min(Math.Max(currentPosition, 0.0f), contentLength - visibleLength);
+ return new Vector2(thumbPosition.X, trackPadding?.Top ?? 0 + trackSize.Height * pos / contentLength);
+ }
}
+
+ #endregion Classes
}
}