// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; namespace FlaxEngine.GUI { /// /// Progress bar control shows visual progress of the action or set of actions. /// /// public class ProgressBar : Control { /// /// The value. /// protected float _value; /// /// The current value (used to apply smooth progress changes). /// protected float _current; /// /// The minimum progress value. /// protected float _minimum; /// /// The maximum progress value. /// protected float _maximum = 100; /// /// Gets or sets the value smoothing scale (0 to not use it). /// [EditorOrder(40), Limit(0, 100, 0.1f), Tooltip("The value smoothing scale (0 to not use it).")] public float SmoothingScale { get; set; } = 1; /// /// Gets a value indicating whether use progress value smoothing. /// /// /// true if use progress value smoothing; otherwise, false. /// public bool UseSmoothing => !Mathf.IsZero(SmoothingScale); /// /// Gets or sets the minimum value. /// [EditorOrder(20), Tooltip("The minimum progress value.")] public float Minimum { get => _minimum; set { if (value > _maximum) throw new ArgumentOutOfRangeException(); _minimum = value; if (Value < _minimum) Value = _minimum; } } /// /// Gets or sets the maximum value. /// [EditorOrder(30), Tooltip("The maximum progress value.")] public float Maximum { get => _maximum; set { if (value < _minimum || Mathf.IsZero(value)) throw new ArgumentOutOfRangeException(); _maximum = value; if (Value > _maximum) Value = _maximum; } } /// /// Gets or sets the value. /// [EditorOrder(10), Tooltip("The current progress value.")] public float Value { get => _value; set { value = Mathf.Clamp(value, _minimum, _maximum); if (!Mathf.NearEqual(value, _value)) { _value = value; // Check if skip smoothing if (!UseSmoothing) { _current = _value; } } } } /// /// Gets or sets the margin for the progress bar rectangle within the control bounds. /// [EditorDisplay("Style"), EditorOrder(2000), Tooltip("The margin for the progress bar rectangle within the control bounds.")] public Margin BarMargin { get; set; } /// /// Gets or sets the color of the progress bar rectangle. /// [EditorDisplay("Style"), EditorOrder(2000), Tooltip("The color of the progress bar rectangle.")] public Color BarColor { get; set; } /// /// Initializes a new instance of the class. /// public ProgressBar() : this(0, 0, 120) { } /// /// Initializes a new instance of the class. /// public ProgressBar(float x, float y, float width, float height = 28) : base(x, y, width, height) { AutoFocus = false; var style = Style.Current; BackgroundColor = style.Background; BarColor = style.ProgressNormal; BarMargin = new Margin(1); } /// public override void Update(float deltaTime) { bool isDeltaSlow = deltaTime > (1 / 20.0f); // Ensure progress bar is visible if (Visible) { // Value smoothing if (Mathf.Abs(_current - _value) > 0.01f) { // Lerp or not if running slow float value; if (!isDeltaSlow && UseSmoothing) value = Mathf.Lerp(_current, _value, Mathf.Saturate(deltaTime * 5.0f * SmoothingScale)); else value = _value; _current = value; } } base.Update(deltaTime); } /// public override void Draw() { base.Draw(); float progressNormalized = (_current - _minimum) / _maximum; if (progressNormalized > 0.001f) { var barRect = new Rectangle(0, 0, Width * progressNormalized, Height); BarMargin.ShrinkRectangle(ref barRect); Render2D.FillRectangle(barRect, BarColor); } } } }