using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;
namespace StrixMusic.Sdk.WinUI.Controls
{
///
/// An extended that has events for the Slider is modified by the user.
///
///
/// Partially stolen from StackOverflow:
/// https://stackoverflow.com/questions/48833441/how-do-i-listen-to-uwp-xaml-slider-manipulation-start-end-events
///
public partial class SliderEx : Slider
{
private bool IsSliderBeingManipulated => _isContainerHeld || _isThumbHeld;
private bool _isThumbHeld;
private bool _isContainerHeld;
///
/// for the property.
///
public static readonly DependencyProperty RemainingProperty =
DependencyProperty.Register(
nameof(Remaining),
typeof(bool),
typeof(SliderEx),
new PropertyMetadata(true));
///
/// The has begun being manipulation by the user.
///
public event EventHandler? SliderManipulationStarted;
///
/// The has finished being manipulation by user.
///
public event EventHandler? SliderManipulationCompleted;
///
/// The has value has changed as a result of the user.
///
public event EventHandler? SliderManipulationMoved;
///
/// Gets the value remaining on the Slider.
///
public double Remaining
{
get => (double)GetValue(RemainingProperty);
private set => SetValue(RemainingProperty, value);
}
///
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
// Find thumb PART
var thumb = GetTemplateChild("HorizontalThumb") as Thumb ?? GetTemplateChild("VerticalThumb") as Thumb;
// Setup events on Thumb
if (thumb != null)
{
thumb.DragStarted += Thumb_DragStarted;
thumb.DragCompleted += Thumb_DragCompleted;
thumb.DragDelta += Thumb_DragDelta;
}
// Find SliderContainer
// ReSharper disable once UsePatternMatching
var sliderContainer = GetTemplateChild("SliderContainer") as Grid;
if (sliderContainer != null)
{
sliderContainer.AddHandler(PointerPressedEvent, new PointerEventHandler(SliderContainer_PointerPressed), true);
sliderContainer.AddHandler(PointerReleasedEvent, new PointerEventHandler(SliderContainer_PointerReleased), true);
sliderContainer.AddHandler(PointerMovedEvent, new PointerEventHandler(SliderContainer_PointerMoved), true);
}
}
///
protected override void OnValueChanged(double oldValue, double newValue)
{
base.OnValueChanged(oldValue, newValue);
Remaining = Maximum - newValue;
}
private void SliderContainer_PointerMoved(object sender, PointerRoutedEventArgs e)
{
InvokeMove();
}
private void SliderContainer_PointerReleased(object sender, PointerRoutedEventArgs e)
{
SetContainerHeld(false);
}
private void SliderContainer_PointerPressed(object sender, PointerRoutedEventArgs e)
{
SetContainerHeld(true);
}
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
InvokeMove();
}
private void Thumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
SetThumbHeld(false);
}
private void Thumb_DragStarted(object sender, DragStartedEventArgs e)
{
SetThumbHeld(true);
}
private void SetThumbHeld(bool held)
{
var wasManipulated = IsSliderBeingManipulated;
_isThumbHeld = held;
InvokeStateChange(wasManipulated);
}
private void SetContainerHeld(bool held)
{
var wasManipulated = IsSliderBeingManipulated;
_isContainerHeld = held;
InvokeStateChange(wasManipulated);
}
private void InvokeMove()
{
SliderManipulationMoved?.Invoke(this, EventArgs.Empty);
}
private void InvokeStateChange(bool wasBeingManipulated)
{
if (wasBeingManipulated != IsSliderBeingManipulated)
{
if (IsSliderBeingManipulated)
{
SliderManipulationStarted?.Invoke(this, EventArgs.Empty);
}
else
{
SliderManipulationCompleted?.Invoke(this, EventArgs.Empty);
}
}
}
}
}