// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Data;
using Avalonia.Utilities;
namespace Avalonia.Controls.Primitives
{
///
/// Base class for controls that display a value within a range.
///
public abstract class RangeBase : TemplatedControl
{
///
/// Defines the property.
///
public static readonly DirectProperty MinimumProperty =
AvaloniaProperty.RegisterDirect(
nameof(Minimum),
o => o.Minimum,
(o, v) => o.Minimum = v);
///
/// Defines the property.
///
public static readonly DirectProperty MaximumProperty =
AvaloniaProperty.RegisterDirect(
nameof(Maximum),
o => o.Maximum,
(o, v) => o.Maximum = v);
///
/// Defines the property.
///
public static readonly DirectProperty ValueProperty =
AvaloniaProperty.RegisterDirect(
nameof(Value),
o => o.Value,
(o, v) => o.Value = v,
defaultBindingMode: BindingMode.TwoWay);
///
/// Defines the property.
///
public static readonly StyledProperty SmallChangeProperty =
AvaloniaProperty.Register(nameof(SmallChange), 1);
///
/// Defines the property.
///
public static readonly StyledProperty LargeChangeProperty =
AvaloniaProperty.Register(nameof(LargeChange), 10);
private double _minimum;
private double _maximum = 100.0;
private double _value;
///
/// Initializes a new instance of the class.
///
public RangeBase()
{
}
///
/// Gets or sets the minimum value.
///
public double Minimum
{
get
{
return _minimum;
}
set
{
ValidateDouble(value, "Minimum");
if (IsInitialized)
{
SetAndRaise(MinimumProperty, ref _minimum, value);
Maximum = ValidateMaximum(Maximum);
Value = ValidateValue(Value);
}
else
{
SetAndRaise(MinimumProperty, ref _minimum, value);
}
}
}
///
/// Gets or sets the maximum value.
///
public double Maximum
{
get
{
return _maximum;
}
set
{
ValidateDouble(value, "Maximum");
if (IsInitialized)
{
value = ValidateMaximum(value);
SetAndRaise(MaximumProperty, ref _maximum, value);
Value = ValidateValue(Value);
}
else
{
SetAndRaise(MaximumProperty, ref _maximum, value);
}
}
}
///
/// Gets or sets the current value.
///
public double Value
{
get
{
return _value;
}
set
{
ValidateDouble(value, "Value");
if (IsInitialized)
{
value = ValidateValue(value);
SetAndRaise(ValueProperty, ref _value, value);
}
else
{
SetAndRaise(ValueProperty, ref _value, value);
}
}
}
public double SmallChange
{
get => GetValue(SmallChangeProperty);
set => SetValue(SmallChangeProperty, value);
}
public double LargeChange
{
get => GetValue(LargeChangeProperty);
set => SetValue(LargeChangeProperty, value);
}
protected override void OnInitialized()
{
base.OnInitialized();
Maximum = ValidateMaximum(Maximum);
Value = ValidateValue(Value);
}
///
/// Throws an exception if the double value is NaN or Inf.
///
/// The value.
/// The name of the property being set.
private static void ValidateDouble(double value, string property)
{
if (double.IsInfinity(value) || double.IsNaN(value))
{
throw new ArgumentException($"{value} is not a valid value for {property}.");
}
}
///
/// Validates/coerces the property.
///
/// The value.
/// The coerced value.
private double ValidateMaximum(double value)
{
return Math.Max(value, Minimum);
}
///
/// Validates/coerces the property.
///
/// The value.
/// The coerced value.
private double ValidateValue(double value)
{
return MathUtilities.Clamp(value, Minimum, Maximum);
}
}
}