diff --git a/Source/Engine/UI/GUI/Common/Slider.cs b/Source/Engine/UI/GUI/Common/Slider.cs
index 6dbd5082c..6332088b4 100644
--- a/Source/Engine/UI/GUI/Common/Slider.cs
+++ b/Source/Engine/UI/GUI/Common/Slider.cs
@@ -7,6 +7,32 @@ namespace FlaxEngine.GUI;
///
public class Slider : ContainerControl
{
+ ///
+ /// The slider direction
+ ///
+ public enum SliderDirection
+ {
+ ///
+ /// Slider direction, horizontal right
+ ///
+ HorizontalRight,
+
+ ///
+ /// Slider direction, horizontal left
+ ///
+ HorizontalLeft,
+
+ ///
+ /// Slider direction, vertical up
+ ///
+ VerticalUp,
+
+ ///
+ /// Slider direction, vertical down
+ ///
+ VerticalDown,
+ }
+
///
/// The minimum value.
///
@@ -15,26 +41,7 @@ public class Slider : ContainerControl
///
/// The maximum value.
///
- protected float _maximum = 100f;
-
- ///
- /// Gets or sets the minimum value.
- ///
- [EditorOrder(20), Tooltip("The minimum value.")]
- public float Minimum
- {
- get => _minimum;
- set
- {
- if (value > _maximum)
- throw new ArgumentOutOfRangeException();
- if (WholeNumbers)
- value = Mathf.RoundToInt(value);
- _minimum = value;
- if (Value < _minimum)
- Value = _minimum;
- }
- }
+ protected float _maximum = 100;
///
/// Gets or sets the maximum value.
@@ -45,8 +52,8 @@ public class Slider : ContainerControl
get => _maximum;
set
{
- if (value < _minimum || Mathf.IsZero(value))
- throw new ArgumentOutOfRangeException();
+ //if (value < _minimum || Mathf.IsZero(value))
+ //throw new ArgumentOutOfRangeException();
if (WholeNumbers)
value = Mathf.RoundToInt(value);
_maximum = value;
@@ -55,6 +62,40 @@ public class Slider : ContainerControl
}
}
+ ///
+ /// Gets or sets the minimum value.
+ ///
+ [EditorOrder(20), Tooltip("The minimum value.")]
+ public float Minimum
+ {
+ get => _minimum;
+ set
+ {
+ //if (value > _maximum)
+ //throw new ArgumentOutOfRangeException();
+ if (WholeNumbers)
+ value = Mathf.RoundToInt(value);
+ _minimum = value;
+ if (Value < _minimum)
+ Value = _minimum;
+ }
+ }
+
+ ///
+ /// Gets or sets the slider direction.
+ ///
+ [EditorOrder(40), Tooltip("Slider Direction.")]
+ public SliderDirection Direction
+ {
+ get => _direction;
+ set
+ {
+ _direction = value;
+ UpdateThumb();
+ }
+ }
+
+ private SliderDirection _direction = SliderDirection.HorizontalRight;
private float _value = 100f;
private Rectangle _thumbRect;
private float _thumbCenter;
@@ -89,25 +130,61 @@ public class Slider : ContainerControl
/// The local position of the thumb center
///
[HideInEditor]
- public Float2 ThumbCenter => new(_thumbCenter, Height / 2);
+ public Float2 ThumbCenter => (Direction is SliderDirection.HorizontalLeft or SliderDirection.HorizontalRight) ? new Float2(_thumbCenter, Height / 2) : new Float2(Width / 2, _thumbCenter);
///
/// The local position of the beginning of the track.
///
[HideInEditor]
- public Float2 TrackBeginning => new(_thumbSize.X / 2, Height / 2);
+ public Float2 TrackBeginning
+ {
+ get
+ {
+ switch (Direction)
+ {
+ case SliderDirection.HorizontalRight:
+ return new Float2(_thumbSize.X / 2, Height / 2);
+ case SliderDirection.HorizontalLeft:
+ return new Float2(Width - _thumbSize.X / 2, Height / 2);
+ case SliderDirection.VerticalUp:
+ return new Float2(Width / 2, Height - _thumbSize.Y / 2);
+ case SliderDirection.VerticalDown:
+ return new Float2(Width / 2, _thumbSize.Y / 2);
+ default: break;
+ }
+ return Float2.Zero;
+ }
+ }
///
/// The local position of the end of the track.
///
[HideInEditor]
- public Float2 TrackEnd => new(Width - _thumbSize.X / 2, Height / 2);
-
+ public Float2 TrackEnd
+ {
+ get
+ {
+ switch (Direction)
+ {
+ case SliderDirection.HorizontalRight:
+ return new Float2(Width - _thumbSize.X / 2, Height / 2);
+ case SliderDirection.HorizontalLeft:
+ return new Float2(_thumbSize.X / 2, Height / 2);
+ case SliderDirection.VerticalUp:
+ return new Float2(Width / 2, _thumbSize.Y / 2);
+ case SliderDirection.VerticalDown:
+ return new Float2(Width / 2, Height - _thumbSize.Y / 2);
+ default: break;
+ }
+ return Float2.Zero;
+ }
+ }
+
///
/// The height of the track.
///
[EditorOrder(40), Tooltip("The track height.")]
- public int TrackHeight { get; set; } = 2;
+ public int TrackThickness { get; set; } = 2;
///
/// The thumb size.
@@ -147,9 +224,14 @@ public class Slider : ContainerControl
public Color TrackFillLineColor { get; set; }
///
- /// Gets the size of the track.
+ /// Gets the width of the track.
///
- private float TrackWidth => Width;
+ private float TrackWidth => (Direction is SliderDirection.HorizontalLeft or SliderDirection.HorizontalRight) ? Width - _thumbSize.X : TrackThickness;
+
+ ///
+ /// Gets the height of the track.
+ ///
+ private float TrackHeight => (Direction is SliderDirection.HorizontalLeft or SliderDirection.HorizontalRight) ? TrackThickness : Height - _thumbSize.Y;
///
/// Gets or sets the brush used for slider track drawing.
@@ -236,13 +318,32 @@ public class Slider : ContainerControl
private void UpdateThumb()
{
// Cache data
- float trackSize = TrackWidth;
+ var isHorizontal = Direction is SliderDirection.HorizontalRight or SliderDirection.HorizontalLeft;
+ float trackSize = isHorizontal ? Width : Height;
float range = Maximum - Minimum;
- float pixelRange = trackSize - _thumbSize.X;
+ float pixelRange = trackSize - (isHorizontal ? _thumbSize.X : _thumbSize.Y);
float perc = (_value - Minimum) / range;
float thumbPosition = (int)(perc * pixelRange);
- _thumbCenter = thumbPosition + _thumbSize.X / 2;
- _thumbRect = new Rectangle(thumbPosition, (Height - _thumbSize.Y) / 2, _thumbSize.X, _thumbSize.Y);
+ switch (Direction)
+ {
+ case SliderDirection.HorizontalRight:
+ _thumbCenter = thumbPosition + _thumbSize.X / 2;
+ _thumbRect = new Rectangle(thumbPosition, (Height - _thumbSize.Y) / 2, _thumbSize.X, _thumbSize.Y);
+ break;
+ case SliderDirection.VerticalDown:
+ _thumbCenter = thumbPosition + _thumbSize.Y / 2;
+ _thumbRect = new Rectangle((Width - _thumbSize.X) / 2, thumbPosition, _thumbSize.X, _thumbSize.Y);
+ break;
+ case SliderDirection.HorizontalLeft:
+ _thumbCenter = Width - thumbPosition - _thumbSize.X / 2;
+ _thumbRect = new Rectangle(Width - thumbPosition - _thumbSize.X, (Height - _thumbSize.Y) / 2, _thumbSize.X, _thumbSize.Y);
+ break;
+ case SliderDirection.VerticalUp:
+ _thumbCenter = Height - thumbPosition - _thumbSize.Y / 2;
+ _thumbRect = new Rectangle((Width - _thumbSize.X) / 2, Height - thumbPosition - _thumbSize.Y, _thumbSize.X, _thumbSize.Y);
+ break;
+ default: break;
+ }
}
private void EndSliding()
@@ -256,19 +357,37 @@ public class Slider : ContainerControl
public override void Draw()
{
base.Draw();
-
+
+ // Set rectangles
+ var lineRect = new Rectangle(_thumbSize.X / 2, (Height - TrackThickness) / 2, Width - _thumbSize.X, TrackThickness);
+ var fillLineRect = new Rectangle(_thumbSize.X / 2 - 1, (Height - TrackThickness - 2) / 2, Width - (Width - _thumbCenter) - _thumbSize.X / 2 + 1, TrackThickness + 2);
+ switch (Direction)
+ {
+ case SliderDirection.HorizontalRight:
+ break;
+ case SliderDirection.VerticalDown:
+ lineRect = new Rectangle((Width - TrackThickness) / 2 , _thumbSize.Y / 2, TrackThickness, Height - _thumbSize.Y);
+ fillLineRect = new Rectangle((Width - TrackThickness - 2) / 2, _thumbSize.Y / 2 - 1, TrackThickness + 2, Height - (Height - _thumbCenter) - _thumbSize.Y / 2 + 1);
+ break;
+ case SliderDirection.HorizontalLeft:
+ fillLineRect = new Rectangle(Width - (Width - _thumbCenter) - 1, (Height - TrackThickness - 2) / 2, Width - _thumbCenter + 1, TrackThickness + 2);
+ break;
+ case SliderDirection.VerticalUp:
+ lineRect = new Rectangle((Width - TrackThickness) / 2 , _thumbSize.Y / 2, TrackThickness, Height - _thumbSize.Y);
+ fillLineRect = new Rectangle((Width - TrackThickness - 2) / 2, Height - (Height - _thumbCenter) - 1, TrackThickness + 2, Height - _thumbCenter + 1);
+ break;
+ default: break;
+ }
+
// Draw track line
- //var lineRect = new Rectangle(4, (Height - TrackHeight) / 2, Width - 8, TrackHeight);
- var lineRect = new Rectangle(_thumbSize.X / 2, (Height - TrackHeight) / 2, Width - _thumbSize.X, TrackHeight);
if (TrackBrush != null)
TrackBrush.Draw(lineRect, TrackLineColor);
else
- Render2D.FillRectangle(lineRect, TrackLineColor);
-
+ Render2D.FillRectangle(lineRect, TrackLineColor);
+
// Draw track fill
if (FillTrack)
{
- var fillLineRect = new Rectangle(_thumbSize.X / 2 - 1, (Height - TrackHeight - 2) / 2, Width - (Width - _thumbCenter) - _thumbSize.X / 2, TrackHeight + 2);
Render2D.PushClip(ref fillLineRect);
if (FillTrackBrush != null)
FillTrackBrush.Draw(lineRect, TrackFillLineColor);
@@ -276,13 +395,13 @@ public class Slider : ContainerControl
Render2D.FillRectangle(lineRect, TrackFillLineColor);
Render2D.PopClip();
}
-
+
// Draw thumb
- var thumbColor = _isSliding ? ThumbColorSelected : (_mouseOverThumb ? ThumbColorHighlighted : ThumbColor);
+ var thumbColorV = _isSliding ? ThumbColorSelected : (_mouseOverThumb ? ThumbColorHighlighted : ThumbColor);
if (ThumbBrush != null)
- ThumbBrush.Draw(_thumbRect, thumbColor);
+ ThumbBrush.Draw(_thumbRect, thumbColorV);
else
- Render2D.FillRectangle(_thumbRect, thumbColor);
+ Render2D.FillRectangle(_thumbRect, thumbColorV);
}
///
@@ -302,7 +421,7 @@ public class Slider : ContainerControl
if (button == MouseButton.Left)
{
Focus();
- float mousePosition = location.X;
+ float mousePosition = Direction is SliderDirection.HorizontalRight or SliderDirection.HorizontalLeft ? location.X : location.Y;
if (_thumbRect.Contains(ref location))
{
@@ -315,7 +434,16 @@ public class Slider : ContainerControl
else
{
// Click change
- Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
+ switch (Direction)
+ {
+ case SliderDirection.HorizontalRight or SliderDirection.VerticalDown:
+ Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
+ break;
+ case SliderDirection.HorizontalLeft or SliderDirection.VerticalUp:
+ Value -= (mousePosition < _thumbCenter ? -1 : 1) * 10;
+ break;
+ default: break;
+ }
}
}
@@ -330,7 +458,22 @@ public class Slider : ContainerControl
{
// Update sliding
var slidePosition = location + Root.TrackingMouseOffset;
- Value = Mathf.Remap(slidePosition.X, 4, TrackWidth - 4, Minimum, Maximum);
+ switch (Direction)
+ {
+ case SliderDirection.HorizontalRight:
+ Value = Mathf.Remap(slidePosition.X, 4, Width - 4, Minimum, Maximum);
+ break;
+ case SliderDirection.VerticalDown:
+ Value = Mathf.Remap(slidePosition.Y, 4, Height - 4, Minimum, Maximum);
+ break;
+ case SliderDirection.HorizontalLeft:
+ Value = Mathf.Remap(slidePosition.X, Width - 4, 4, Minimum, Maximum);
+ break;
+ case SliderDirection.VerticalUp:
+ Value = Mathf.Remap(slidePosition.Y, Height - 4, 4, Minimum, Maximum);
+ break;
+ default: break;
+ }
}
else
{