Browse Source

Added concrete implementations for various numeric types

pull/1457/head
dzhelnin 9 years ago
parent
commit
c1ed2b3b28
  1. 15
      src/Avalonia.Controls/NumericUpDown/AllowedSpecialValues.cs
  2. 24
      src/Avalonia.Controls/NumericUpDown/ByteUpDown.cs
  3. 2
      src/Avalonia.Controls/NumericUpDown/CommonNumericUpDown.cs
  4. 24
      src/Avalonia.Controls/NumericUpDown/DecimalUpDown.cs
  5. 109
      src/Avalonia.Controls/NumericUpDown/DoubleUpDown.cs
  6. 24
      src/Avalonia.Controls/NumericUpDown/IntegerUpDown.cs
  7. 24
      src/Avalonia.Controls/NumericUpDown/LongUpDown.cs
  8. 24
      src/Avalonia.Controls/NumericUpDown/ShortUpDown.cs
  9. 106
      src/Avalonia.Controls/NumericUpDown/SingleUpDown.cs

15
src/Avalonia.Controls/NumericUpDown/AllowedSpecialValues.cs

@ -0,0 +1,15 @@
using System;
namespace Avalonia.Controls
{
[Flags]
public enum AllowedSpecialValues
{
None = 0,
NaN = 1,
PositiveInfinity = 2,
NegativeInfinity = 4,
AnyInfinity = PositiveInfinity | NegativeInfinity,
Any = NaN | AnyInfinity
}
}

24
src/Avalonia.Controls/NumericUpDown/ByteUpDown.cs

@ -0,0 +1,24 @@
namespace Avalonia.Controls
{
/// <inheritdoc />
public class ByteUpDown : CommonNumericUpDown<byte>
{
/// <summary>
/// Initializes static members of the <see cref="ByteUpDown"/> class.
/// </summary>
static ByteUpDown() => UpdateMetadata(typeof(ByteUpDown), 1, byte.MinValue, byte.MaxValue);
/// <summary>
/// Initializes new instance of the <see cref="ByteUpDown"/> class.
/// </summary>
public ByteUpDown() : base(byte.TryParse, decimal.ToByte, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
{
}
/// <inheritdoc />
protected override byte IncrementValue(byte value, byte increment) => (byte)(value + increment);
/// <inheritdoc />
protected override byte DecrementValue(byte value, byte increment) => (byte)(value - increment);
}
}

2
src/Avalonia.Controls/NumericUpDown/CommonNumericUpDown.cs

@ -6,7 +6,7 @@ using System.Linq;
namespace Avalonia.Controls
{
/// <summary>
/// Base class for controls that represents a TextBox with button spinners that allow incrementing and decrementing numeric values.
/// Base class for controls that represents a TextBox with button spinners that allow incrementing and decrementing nullable numeric values.
/// </summary>
public abstract class CommonNumericUpDown<T> : NumericUpDown<T?> where T : struct, IFormattable, IComparable<T>
{

24
src/Avalonia.Controls/NumericUpDown/DecimalUpDown.cs

@ -0,0 +1,24 @@
namespace Avalonia.Controls
{
/// <inheritdoc />
public class DecimalUpDown : CommonNumericUpDown<decimal>
{
/// <summary>
/// Initializes static members of the <see cref="DecimalUpDown"/> class.
/// </summary>
static DecimalUpDown() => UpdateMetadata(typeof(DecimalUpDown), 1m, decimal.MinValue, decimal.MaxValue);
/// <summary>
/// Initializes new instance of the <see cref="DecimalUpDown"/> class.
/// </summary>
public DecimalUpDown() : base(decimal.TryParse, d => d, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
{
}
/// <inheritdoc />
protected override decimal IncrementValue(decimal value, decimal increment) => value + increment;
/// <inheritdoc />
protected override decimal DecrementValue(decimal value, decimal increment) => value - increment;
}
}

109
src/Avalonia.Controls/NumericUpDown/DoubleUpDown.cs

@ -0,0 +1,109 @@
using System;
namespace Avalonia.Controls
{
/// <inheritdoc />
public class DoubleUpDown : CommonNumericUpDown<double>
{
/// <summary>
/// Defines the <see cref="AllowInputSpecialValues"/> property.
/// </summary>
public static readonly DirectProperty<DoubleUpDown, AllowedSpecialValues> AllowInputSpecialValuesProperty =
AvaloniaProperty.RegisterDirect<DoubleUpDown, AllowedSpecialValues>(nameof(AllowInputSpecialValues),
updown => updown.AllowInputSpecialValues, (updown, v) => updown.AllowInputSpecialValues = v);
private AllowedSpecialValues _allowInputSpecialValues;
/// <summary>
/// Initializes static members of the <see cref="DoubleUpDown"/> class.
/// </summary>
static DoubleUpDown() => UpdateMetadata(typeof(DoubleUpDown), 1d, double.NegativeInfinity, double.PositiveInfinity);
/// <summary>
/// Initializes new instance of the <see cref="DoubleUpDown"/> class.
/// </summary>
public DoubleUpDown() : base(double.TryParse, decimal.ToDouble, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
{
}
/// <summary>
/// Gets or sets a value representing the special values the user is allowed to input, such as "Infinity", "-Infinity" and "NaN" values.
/// </summary>
public AllowedSpecialValues AllowInputSpecialValues
{
get { return _allowInputSpecialValues; }
set { SetAndRaise(AllowInputSpecialValuesProperty, ref _allowInputSpecialValues, value); }
}
/// <inheritdoc />
protected override double IncrementValue(double value, double increment) => value + increment;
/// <inheritdoc />
protected override double DecrementValue(double value, double increment) => value - increment;
/// <inheritdoc />
protected override double? OnCoerceIncrement(double? baseValue)
{
if (baseValue.HasValue && double.IsNaN(baseValue.Value))
{
throw new ArgumentException("NaN is invalid for Increment.");
}
return base.OnCoerceIncrement(baseValue);
}
/// <inheritdoc />
protected override double? OnCoerceMaximum(double? baseValue)
{
if (baseValue.HasValue && double.IsNaN(baseValue.Value))
{
throw new ArgumentException("NaN is invalid for Maximum.");
}
return base.OnCoerceMaximum(baseValue);
}
/// <inheritdoc />
protected override double? OnCoerceMinimum(double? baseValue)
{
if (baseValue.HasValue && double.IsNaN(baseValue.Value))
{
throw new ArgumentException("NaN is invalid for Minimum.");
}
return base.OnCoerceMinimum(baseValue);
}
/// <inheritdoc />
protected override void SetValidSpinDirection()
{
if (Value.HasValue && double.IsInfinity(Value.Value) && (Spinner != null))
{
Spinner.ValidSpinDirection = ValidSpinDirections.None;
}
else
{
base.SetValidSpinDirection();
}
}
/// <inheritdoc />
protected override double? ConvertTextToValue(string text)
{
var result = base.ConvertTextToValue(text);
if (result != null)
{
if (double.IsNaN(result.Value))
{
TestInputSpecialValue(AllowInputSpecialValues, AllowedSpecialValues.NaN);
}
else if (double.IsPositiveInfinity(result.Value))
{
TestInputSpecialValue(AllowInputSpecialValues, AllowedSpecialValues.PositiveInfinity);
}
else if (double.IsNegativeInfinity(result.Value))
{
TestInputSpecialValue(AllowInputSpecialValues, AllowedSpecialValues.NegativeInfinity);
}
}
return result;
}
}
}

24
src/Avalonia.Controls/NumericUpDown/IntegerUpDown.cs

@ -0,0 +1,24 @@
namespace Avalonia.Controls
{
/// <inheritdoc />
public class IntegerUpDown : CommonNumericUpDown<int>
{
/// <summary>
/// Initializes static members of the <see cref="IntegerUpDown"/> class.
/// </summary>
static IntegerUpDown() => UpdateMetadata(typeof(IntegerUpDown), 1, int.MinValue, int.MaxValue);
/// <summary>
/// Initializes new instance of the <see cref="IntegerUpDown"/> class.
/// </summary>
public IntegerUpDown() : base(int.TryParse, decimal.ToInt32, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
{
}
/// <inheritdoc />
protected override int IncrementValue(int value, int increment) => value + increment;
/// <inheritdoc />
protected override int DecrementValue(int value, int increment) => value - increment;
}
}

24
src/Avalonia.Controls/NumericUpDown/LongUpDown.cs

@ -0,0 +1,24 @@
namespace Avalonia.Controls
{
/// <inheritdoc />
public class LongUpDown : CommonNumericUpDown<long>
{
/// <summary>
/// Initializes static members of the <see cref="LongUpDown"/> class.
/// </summary>
static LongUpDown() => UpdateMetadata(typeof(LongUpDown), 1L, long.MinValue, long.MaxValue);
/// <summary>
/// Initializes new instance of the <see cref="LongUpDown"/> class.
/// </summary>
public LongUpDown() : base(long.TryParse, decimal.ToInt64, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
{
}
/// <inheritdoc />
protected override long IncrementValue(long value, long increment) => value + increment;
/// <inheritdoc />
protected override long DecrementValue(long value, long increment) => value - increment;
}
}

24
src/Avalonia.Controls/NumericUpDown/ShortUpDown.cs

@ -0,0 +1,24 @@
namespace Avalonia.Controls
{
/// <inheritdoc />
public class ShortUpDown : CommonNumericUpDown<short>
{
/// <summary>
/// Initializes static members of the <see cref="ShortUpDown"/> class.
/// </summary>
static ShortUpDown() => UpdateMetadata(typeof(ShortUpDown), 1, short.MinValue, short.MaxValue);
/// <summary>
/// Initializes new instance of the <see cref="ShortUpDown"/> class.
/// </summary>
public ShortUpDown() : base(short.TryParse, decimal.ToInt16, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
{
}
/// <inheritdoc />
protected override short IncrementValue(short value, short increment) => (short)(value + increment);
/// <inheritdoc />
protected override short DecrementValue(short value, short increment) => (short)(value - increment);
}
}

106
src/Avalonia.Controls/NumericUpDown/SingleUpDown.cs

@ -0,0 +1,106 @@
using System;
namespace Avalonia.Controls
{
/// <inheritdoc />
public class SingleUpDown : CommonNumericUpDown<float>
{
/// <summary>
/// Defines the <see cref="AllowInputSpecialValues"/> property.
/// </summary>
public static readonly DirectProperty<SingleUpDown, AllowedSpecialValues> AllowInputSpecialValuesProperty =
AvaloniaProperty.RegisterDirect<SingleUpDown, AllowedSpecialValues>(nameof(AllowInputSpecialValues),
updown => updown.AllowInputSpecialValues, (updown, v) => updown.AllowInputSpecialValues = v);
private AllowedSpecialValues _allowInputSpecialValues;
/// <summary>
/// Initializes static members of the <see cref="SingleUpDown"/> class.
/// </summary>
static SingleUpDown() => UpdateMetadata(typeof(SingleUpDown), 1f, float.NegativeInfinity, float.PositiveInfinity);
/// <summary>
/// Initializes new instance of the <see cref="SingleUpDown"/> class.
/// </summary>
public SingleUpDown() : base(float.TryParse, decimal.ToSingle, (v1, v2) => v1 < v2, (v1, v2) => v1 > v2)
{
}
/// <summary>
/// Gets or sets a value representing the special values the user is allowed to input, such as "Infinity", "-Infinity" and "NaN" values.
/// </summary>
public AllowedSpecialValues AllowInputSpecialValues
{
get { return _allowInputSpecialValues; }
set { SetAndRaise(AllowInputSpecialValuesProperty, ref _allowInputSpecialValues, value); }
}
/// <inheritdoc />
protected override float? OnCoerceIncrement(float? baseValue)
{
if (baseValue.HasValue && float.IsNaN(baseValue.Value))
throw new ArgumentException("NaN is invalid for Increment.");
return base.OnCoerceIncrement(baseValue);
}
/// <inheritdoc />
protected override float? OnCoerceMaximum(float? baseValue)
{
if (baseValue.HasValue && float.IsNaN(baseValue.Value))
throw new ArgumentException("NaN is invalid for Maximum.");
return base.OnCoerceMaximum(baseValue);
}
/// <inheritdoc />
protected override float? OnCoerceMinimum(float? baseValue)
{
if (baseValue.HasValue && float.IsNaN(baseValue.Value))
throw new ArgumentException("NaN is invalid for Minimum.");
return base.OnCoerceMinimum(baseValue);
}
/// <inheritdoc />
protected override float IncrementValue(float value, float increment) => value + increment;
/// <inheritdoc />
protected override float DecrementValue(float value, float increment) => value - increment;
/// <inheritdoc />
protected override void SetValidSpinDirection()
{
if (Value.HasValue && float.IsInfinity(Value.Value) && (Spinner != null))
{
Spinner.ValidSpinDirection = ValidSpinDirections.None;
}
else
{
base.SetValidSpinDirection();
}
}
/// <inheritdoc />
protected override float? ConvertTextToValue(string text)
{
var result = base.ConvertTextToValue(text);
if (result != null)
{
if (float.IsNaN(result.Value))
{
TestInputSpecialValue(AllowInputSpecialValues, AllowedSpecialValues.NaN);
}
else if (float.IsPositiveInfinity(result.Value))
{
TestInputSpecialValue(AllowInputSpecialValues, AllowedSpecialValues.PositiveInfinity);
}
else if (float.IsNegativeInfinity(result.Value))
{
TestInputSpecialValue(AllowInputSpecialValues, AllowedSpecialValues.NegativeInfinity);
}
}
return result;
}
}
}
Loading…
Cancel
Save