using LemonUI.Elements;
using System;
using System.Drawing;
namespace LemonUI.Menus
{
///
/// A slider item for changing integer values.
///
public class NativeSliderItem : NativeSlidableItem
{
#region Internal Fields
///
/// The background of the slider.
///
internal protected ScaledRectangle background = new ScaledRectangle(PointF.Empty, SizeF.Empty)
{
Color = Color.FromArgb(255, 4, 32, 57)
};
///
/// THe front of the slider.
///
internal protected ScaledRectangle slider = new ScaledRectangle(PointF.Empty, SizeF.Empty)
{
Color = Color.FromArgb(255, 57, 116, 200)
};
#endregion
#region Private Fields
///
/// The maximum value of the slider.
///
private int maximum = 0;
///
/// The current value of the slider.
///
private int _value = 100;
#endregion
#region Public Properties
///
/// The color of the Slider.
///
public Color SliderColor
{
get => slider.Color;
set => slider.Color = value;
}
///
/// The maximum value of the slider.
///
public int Maximum
{
get => maximum;
set
{
// If the value was not changed, return
if (maximum == value)
{
return;
}
// Otherwise, save the new value
maximum = value;
// If the current value is higher than the max, set the max
if (_value > maximum)
{
_value = maximum;
ValueChanged?.Invoke(this, EventArgs.Empty);
}
// Finally, update the location of the slider
UpdatePosition();
}
}
///
/// The current value of the slider.
///
public int Value
{
get => _value;
set
{
// If the value is over the limit, raise an exception
if (value > maximum)
{
throw new ArgumentOutOfRangeException(nameof(value), $"The value is over the maximum of {maximum - 1}");
}
// Otherwise, save it
_value = value;
// Trigger the respective event
ValueChanged?.Invoke(this, EventArgs.Empty);
// And update the location of the slider
UpdatePosition();
}
}
///
/// The multiplier for increasing and decreasing the value.
///
public int Multiplier { get; set; } = 1;
#endregion
#region Event
///
/// Event triggered when the value of the menu changes.
///
public event EventHandler ValueChanged;
#endregion
#region Constructors
///
/// Creates a with a maximum of 100.
///
/// The title of the Item.
public NativeSliderItem(string title) : this(title, string.Empty, 100, 0)
{
}
///
/// Creates a with a maximum of 100.
///
/// The title of the Item.
/// The description of the Item.
public NativeSliderItem(string title, string description) : this(title, description, 100, 0)
{
}
///
/// Creates a with a specific current and maximum value.
///
/// The title of the Item.
/// The maximum value of the Slider.
/// The current value of the Slider.
public NativeSliderItem(string title, int max, int value) : this(title, string.Empty, max, value)
{
}
///
/// Creates a with a specific maximum.
///
/// The title of the Item.
/// The description of the Item.
/// The maximum value of the Slider.
/// The current value of the Slider.
public NativeSliderItem(string title, string description, int max, int value) : base(title, description)
{
maximum = max;
_value = value;
}
#endregion
#region Internal Functions
///
/// Updates the position of the bar based on the value.
///
internal protected void UpdatePosition()
{
// Calculate the increment, and then the value of X
float increment = _value / (float)maximum;
float x = (background.Size.Width - slider.Size.Width) * increment;
// Then, add the X to the slider position
slider.Position = new PointF(background.Position.X + x, background.Position.Y);
}
#endregion
#region Public Functions
///
/// Recalculates the item positions and sizes with the specified values.
///
/// The position of the item.
/// The size of the item.
/// If this item has been selected.
public override void Recalculate(PointF pos, SizeF size, bool selected)
{
base.Recalculate(pos, size, selected);
// Set the position and size of the background
background.Size = new SizeF(150, 9);
background.Position = new PointF(pos.X + size.Width - background.Size.Width - 7 - LeftArrow.Size.Width, pos.Y + 14);
// And do the same for the left arrow
LeftArrow.Position = new PointF(background.Position.X - LeftArrow.Size.Width, pos.Y + 4);
// Finally, set the correct position of the slider
slider.Size = new SizeF(75, 9);
UpdatePosition();
}
///
/// Reduces the value of the slider.
///
public override void GoLeft()
{
// Calculate the new value
int newValue = _value - Multiplier;
// If is under zero, set it to zero
if (newValue < 0)
{
Value = 0;
}
// Otherwise, set it to the new value
else
{
Value = newValue;
}
}
///
/// Increases the value of the slider.
///
public override void GoRight()
{
// Calculate the new value
int newValue = _value + Multiplier;
// If the value is over the maximum, set the max
if (newValue > maximum)
{
Value = maximum;
}
// Otherwise, set the calculated value
else
{
Value = newValue;
}
}
///
/// Draws the slider.
///
public override void Draw()
{
base.Draw(); // Arrows, Title and Left Badge
background.Draw();
slider.Draw();
}
#endregion
}
}