using System;
using MonoGame.Extended.Input;
using MonoGame.Extended.Input.InputListeners;
namespace MonoGame.Extended.NuclexGui.Controls.Desktop
{
/// Base class for a slider that can be moved using the mouse
///
/// Implements the common functionality for a slider moving either the direction
/// of the X or the Y axis (but not both). Derive any scroll bar-like controls
/// from this class to simplify their implementation.
///
public abstract class GuiSliderControl : GuiControl
{
/// Whether the mouse cursor is hovering over the thumb
private bool _mouseOverThumb;
/// X coordinate at which the thumb was picked up
private float _pickupX;
/// Y coordinate at which the thumb was picked up
private float _pickupY;
/// Whether the slider's thumb is currently in the depressed state
private bool _pressedDown;
/// Can be set by renderers to allow the control to locate its thumb
public IThumbLocator ThumbLocator;
/// Position of the thumb within the slider (0.0 .. 1.0)
public float ThumbPosition;
/// Fraction of the slider filled by the thumb (0.0 .. 1.0)
public float ThumbSize;
/// Initializes a new slider control
public GuiSliderControl()
{
ThumbPosition = 0.0f;
ThumbSize = 1.0f;
}
/// whether the mouse is currently hovering over the thumb
public bool MouseOverThumb => _mouseOverThumb;
/// Whether the pressable control is in the depressed state
public virtual bool ThumbDepressed => _pressedDown && _mouseOverThumb;
/// Triggered when the slider has been moved
public event EventHandler Moved;
/// Moves the thumb to the specified location
/// Location the thumb will be moved to
protected abstract void MoveThumb(float x, float y);
/// Obtains the region covered by the slider's thumb
/// The region covered by the slider's thumb
protected abstract RectangleF GetThumbRegion();
/// Called when a mouse button has been pressed down
/// Index of the button that has been pressed
protected override void OnMousePressed(MouseButton button)
{
if (button == MouseButton.Left)
{
var thumbRegion = GetThumbRegion();
if (thumbRegion.Contains(new Point2(_pickupX, _pickupY)))
{
_pressedDown = true;
_pickupX -= thumbRegion.X;
_pickupY -= thumbRegion.Y;
}
}
}
/// Called when a mouse button has been released again
/// Index of the button that has been released
protected override void OnMouseReleased(MouseButton button)
{
if (button == MouseButton.Left)
_pressedDown = false;
}
/// Called when the mouse position is updated
/// X coordinate of the mouse cursor on the control
/// Y coordinate of the mouse cursor on the control
protected override void OnMouseMoved(float x, float y)
{
if (_pressedDown)
{
//RectangleF bounds = GetAbsoluteBounds();
MoveThumb(x - _pickupX, y - _pickupY);
}
else
{
_pickupX = x;
_pickupY = y;
}
_mouseOverThumb = GetThumbRegion().Contains(new Point2(x, y));
}
///
/// Called when the mouse has left the control and is no longer hovering over it
///
protected override void OnMouseLeft(float x, float y)
{
_mouseOverThumb = false;
}
/// Fires the slider's Moved event
protected virtual void OnMoved()
{
Moved?.Invoke(this, EventArgs.Empty);
}
}
}