Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sn4k3/UVtools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'UVtools.WPF/Controls/SliderEx.cs')
-rw-r--r--UVtools.WPF/Controls/SliderEx.cs113
1 files changed, 65 insertions, 48 deletions
diff --git a/UVtools.WPF/Controls/SliderEx.cs b/UVtools.WPF/Controls/SliderEx.cs
index 4ceb2d8..6752206 100644
--- a/UVtools.WPF/Controls/SliderEx.cs
+++ b/UVtools.WPF/Controls/SliderEx.cs
@@ -9,8 +9,10 @@ using System;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
using Avalonia.Controls.Mixins;
using Avalonia.Controls.Primitives;
+using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Layout;
@@ -19,6 +21,7 @@ using Avalonia.Utilities;
namespace UVtools.WPF.Controls
{
+ [PseudoClasses(":vertical", ":horizontal", ":pressed")]
public class SliderEx : RangeBase, IStyleable
{
Type IStyleable.StyleKey => typeof(Slider);
@@ -27,31 +30,31 @@ namespace UVtools.WPF.Controls
/// Defines the <see cref="Orientation"/> property.
/// </summary>
public static readonly StyledProperty<Orientation> OrientationProperty =
- ScrollBar.OrientationProperty.AddOwner<Slider>();
+ ScrollBar.OrientationProperty.AddOwner<SliderEx>();
/// <summary>
/// Defines the <see cref="IsSnapToTickEnabled"/> property.
/// </summary>
public static readonly StyledProperty<bool> IsSnapToTickEnabledProperty =
- AvaloniaProperty.Register<Slider, bool>(nameof(IsSnapToTickEnabled), false);
+ AvaloniaProperty.Register<SliderEx, bool>(nameof(IsSnapToTickEnabled), false);
/// <summary>
/// Defines the <see cref="TickFrequency"/> property.
/// </summary>
public static readonly StyledProperty<double> TickFrequencyProperty =
- AvaloniaProperty.Register<Slider, double>(nameof(TickFrequency), 0.0);
+ AvaloniaProperty.Register<SliderEx, double>(nameof(TickFrequency), 0.0);
/// <summary>
/// Defines the <see cref="TickPlacement"/> property.
/// </summary>
public static readonly StyledProperty<TickPlacement> TickPlacementProperty =
- AvaloniaProperty.Register<TickBar, TickPlacement>(nameof(TickPlacement), 0d);
+ AvaloniaProperty.Register<SliderEx, TickPlacement>(nameof(TickPlacement), 0d);
/// <summary>
/// Defines the <see cref="TicksProperty"/> property.
/// </summary>
public static readonly StyledProperty<AvaloniaList<double>> TicksProperty =
- TickBar.TicksProperty.AddOwner<Slider>();
+ TickBar.TicksProperty.AddOwner<SliderEx>();
// Slider required parts
private bool _isDragging = false;
@@ -71,11 +74,13 @@ namespace UVtools.WPF.Controls
/// </summary>
static SliderEx()
{
- PressedMixin.Attach<Slider>();
- OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal);
+ PressedMixin.Attach<SliderEx>();
+ OrientationProperty.OverrideDefaultValue(typeof(SliderEx), Orientation.Horizontal);
Thumb.DragStartedEvent.AddClassHandler<SliderEx>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<SliderEx>((x, e) => x.OnThumbDragCompleted(e),
RoutingStrategies.Bubble);
+
+ ValueProperty.OverrideMetadata<SliderEx>(new DirectPropertyMetadata<double>(enableDataValidation: true));
}
/// <summary>
@@ -100,8 +105,8 @@ namespace UVtools.WPF.Controls
/// </summary>
public Orientation Orientation
{
- get => GetValue(OrientationProperty);
- set => SetValue(OrientationProperty, value);
+ get { return GetValue(OrientationProperty); }
+ set { SetValue(OrientationProperty, value); }
}
/// <summary>
@@ -109,8 +114,8 @@ namespace UVtools.WPF.Controls
/// </summary>
public bool IsSnapToTickEnabled
{
- get => GetValue(IsSnapToTickEnabledProperty);
- set => SetValue(IsSnapToTickEnabledProperty, value);
+ get { return GetValue(IsSnapToTickEnabledProperty); }
+ set { SetValue(IsSnapToTickEnabledProperty, value); }
}
/// <summary>
@@ -118,8 +123,8 @@ namespace UVtools.WPF.Controls
/// </summary>
public double TickFrequency
{
- get => GetValue(TickFrequencyProperty);
- set => SetValue(TickFrequencyProperty, value);
+ get { return GetValue(TickFrequencyProperty); }
+ set { SetValue(TickFrequencyProperty, value); }
}
/// <summary>
@@ -128,8 +133,8 @@ namespace UVtools.WPF.Controls
/// </summary>
public TickPlacement TickPlacement
{
- get => GetValue(TickPlacementProperty);
- set => SetValue(TickPlacementProperty, value);
+ get { return GetValue(TickPlacementProperty); }
+ set { SetValue(TickPlacementProperty, value); }
}
/// <inheritdoc/>
@@ -182,9 +187,11 @@ namespace UVtools.WPF.Controls
private void TrackPressed(object sender, PointerPressedEventArgs e)
{
- if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
- MoveToPoint(e.GetCurrentPoint(_track));
- _isDragging = true;
+ if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
+ {
+ MoveToPoint(e.GetCurrentPoint(_track));
+ _isDragging = true;
+ }
}
private void MoveToPoint(PointerPoint x)
@@ -205,6 +212,14 @@ namespace UVtools.WPF.Controls
Value = IsSnapToTickEnabled ? SnapToTick(finalValue) : finalValue;
}
+ protected override void UpdateDataValidation<T>(AvaloniaProperty<T> property, BindingValue<T> value)
+ {
+ if (property == ValueProperty)
+ {
+ DataValidationErrors.SetError(this, value.Error);
+ }
+ }
+
protected override void OnPropertyChanged<T>(AvaloniaPropertyChangedEventArgs<T> change)
{
base.OnPropertyChanged(change);
@@ -233,49 +248,51 @@ namespace UVtools.WPF.Controls
_isDragging = false;
}
-
/// <summary>
/// Snap the input 'value' to the closest tick.
/// </summary>
/// <param name="value">Value that want to snap to closest Tick.</param>
private double SnapToTick(double value)
{
- if (!IsSnapToTickEnabled) return value;
- double previous = Minimum;
- double next = Maximum;
+ if (IsSnapToTickEnabled)
+ {
+ double previous = Minimum;
+ double next = Maximum;
- // This property is rarely set so let's try to avoid the GetValue
- var ticks = Ticks;
+ // This property is rarely set so let's try to avoid the GetValue
+ var ticks = Ticks;
- // If ticks collection is available, use it.
- // Note that ticks may be unsorted.
- if ((ticks != null) && (ticks.Count > 0))
- {
- foreach (var tick in ticks)
+ // If ticks collection is available, use it.
+ // Note that ticks may be unsorted.
+ if ((ticks != null) && (ticks.Count > 0))
{
- if (MathUtilities.AreClose(tick, value))
- {
- return value;
- }
-
- if (MathUtilities.LessThan(tick, value) && MathUtilities.GreaterThan(tick, previous))
- {
- previous = tick;
- }
- else if (MathUtilities.GreaterThan(tick, value) && MathUtilities.LessThan(tick, next))
+ for (int i = 0; i < ticks.Count; i++)
{
- next = tick;
+ double tick = ticks[i];
+ if (MathUtilities.AreClose(tick, value))
+ {
+ return value;
+ }
+
+ if (MathUtilities.LessThan(tick, value) && MathUtilities.GreaterThan(tick, previous))
+ {
+ previous = tick;
+ }
+ else if (MathUtilities.GreaterThan(tick, value) && MathUtilities.LessThan(tick, next))
+ {
+ next = tick;
+ }
}
}
- }
- else if (MathUtilities.GreaterThan(TickFrequency, 0.0))
- {
- previous = Minimum + (Math.Round(((value - Minimum) / TickFrequency)) * TickFrequency);
- next = Math.Min(Maximum, previous + TickFrequency);
- }
+ else if (MathUtilities.GreaterThan(TickFrequency, 0.0))
+ {
+ previous = Minimum + (Math.Round(((value - Minimum) / TickFrequency)) * TickFrequency);
+ next = Math.Min(Maximum, previous + TickFrequency);
+ }
- // Choose the closest value between previous and next. If tie, snap to 'next'.
- value = MathUtilities.GreaterThanOrClose(value, (previous + next) * 0.5) ? next : previous;
+ // Choose the closest value between previous and next. If tie, snap to 'next'.
+ value = MathUtilities.GreaterThanOrClose(value, (previous + next) * 0.5) ? next : previous;
+ }
return value;
}