Skip to content

File TimerBarObjective.cs

File List > LemonUI > LemonUI > TimerBars > TimerBarObjective.cs

Go to the documentation of this file


using System;
using System.Collections.Generic;
using System.Drawing;
using LemonUI.Elements;

namespace LemonUI.TimerBars
{
    public class TimerBarObjective : TimerBar
    {
        #region Fields

        private const float width = 20;
        private const float height = 20;

        private static readonly Color colorWhite = Color.FromArgb(255, 255, 255);
        private static readonly Color colorCompleted = Color.FromArgb(101, 180, 212);

        private readonly List<ScaledTexture> objectives = new List<ScaledTexture>();

        private PointF lastPosition = default;

        private int count = 1;
        private int completed = 0;
        private Color colorSet = colorCompleted;
        private ObjectiveSpacing objectiveSpacing = ObjectiveSpacing.Equal;

        #endregion

        #region Properties

        public int Count
        {
            get => count;
            set
            {
                if (count == value)
                {
                    return;
                }

                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "The number of objectives can't be under or equal to zero.");
                }

                count = value;
                UpdateObjectiveCount();
            }
        }
        public int Completed
        {
            get => completed;
            set
            {
                if (completed == value)
                {
                    return;
                }

                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "The number of completed objectives can't be under zero.");
                }
                if (value > Count)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "The number of completed objectives can't be over the total number of objectives.");
                }

                completed = value;

                UpdateObjectiveColors();
            }
        }
        public Color CompletedColor
        {
            get => colorSet;
            set
            {
                if (colorSet == value)
                {
                    return;
                }

                colorSet = value;
                UpdateObjectiveColors();
            }
        }
        public ObjectiveSpacing Spacing
        {
            get => objectiveSpacing;
            set
            {
                if (objectiveSpacing == value)
                {
                    return;
                }

                objectiveSpacing = value;
                Recalculate(lastPosition);
            }
        }

        #endregion

        #region Constructors

        public TimerBarObjective(string title) : base(title, string.Empty)
        {
            UpdateObjectiveCount();
        }

        #endregion

        #region Tools

        private void UpdateObjectiveCount()
        {
            // just to make sure
            if (completed > count)
            {
                completed = count;
            }

            objectives.Clear();

            for (int i = 0; i < count; i++)
            {
                objectives.Add(new ScaledTexture("timerbars", "circle_checkpoints"));
            }

            UpdateObjectiveColors();
        }
        private void UpdateObjectiveColors()
        {
            for (int i = 0; i < objectives.Count; i++)
            {
                ScaledTexture texture = objectives[i];
                texture.Color = i < completed ? colorSet : colorWhite;
            }
        }

        #endregion

        #region Functions

        public override void Draw()
        {
            background.Draw();
            title.Draw();

            foreach (ScaledTexture texture in objectives)
            {
                texture.Draw();
            }
        }
        public override void Recalculate(PointF pos)
        {
            lastPosition = pos;

            base.Recalculate(pos);

            const float safe = width + 5;
            float startY = pos.Y + (backgroundHeight * 0.5f) - (height * 0.5f);

            switch (objectiveSpacing)
            {
                case ObjectiveSpacing.Equal:
                {
                    const float half = backgroundWidth * 0.5f;
                    float startX = pos.X + half;
                    float spacingWidth = (half - safe) / (objectives.Count - 1);

                    for (int i = 0; i < objectives.Count; i++)
                    {
                        ScaledTexture texture = objectives[i];
                        texture.Size = new SizeF(width, height);
                        texture.Position = new PointF(startX + (spacingWidth * i), startY);
                    }

                    break;
                }
                case ObjectiveSpacing.Fixed:
                {
                    float startX = pos.X + backgroundWidth - safe - (width * (count - 1));

                    for (int i = 0; i < objectives.Count; i++)
                    {
                        ScaledTexture texture = objectives[i];
                        texture.Size = new SizeF(width, height);
                        texture.Position = new PointF(startX + (i * width), startY);
                    }

                    break;
                }
            }
        }

        #endregion
    }
}