mirror of
https://github.com/hawkeye-stan/msfs-popout-panel-manager.git
synced 2024-11-21 21:30:12 +00:00
222 lines
8.1 KiB
C#
222 lines
8.1 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Controls.Primitives;
|
|
using System.Windows.Input;
|
|
|
|
namespace MSFSPopoutPanelManager.MainApp.CustomControl
|
|
{
|
|
[TemplatePart(Name = "PART_TextBox", Type = typeof(TextBox))]
|
|
[TemplatePart(Name = "PART_ButtonUp", Type = typeof(ButtonBase))]
|
|
[TemplatePart(Name = "PART_ButtonDown", Type = typeof(ButtonBase))]
|
|
public class NumericUpDown : Control
|
|
{
|
|
private TextBox PART_TextBox = new TextBox();
|
|
|
|
public override void OnApplyTemplate()
|
|
{
|
|
base.OnApplyTemplate();
|
|
|
|
TextBox textBox = GetTemplateChild("PART_TextBox") as TextBox;
|
|
if (textBox != null)
|
|
{
|
|
PART_TextBox = textBox;
|
|
PART_TextBox.PreviewKeyDown += textBox_PreviewKeyDown;
|
|
PART_TextBox.TextChanged += textBox_TextChanged;
|
|
PART_TextBox.Text = Value.ToString();
|
|
}
|
|
|
|
ButtonBase PART_ButtonUp = GetTemplateChild("PART_ButtonUp") as ButtonBase;
|
|
if (PART_ButtonUp != null)
|
|
{
|
|
PART_ButtonUp.Click += buttonUp_Click;
|
|
}
|
|
|
|
ButtonBase PART_ButtonDown = GetTemplateChild("PART_ButtonDown") as ButtonBase;
|
|
if (PART_ButtonDown != null)
|
|
{
|
|
PART_ButtonDown.Click += buttonDown_Click;
|
|
}
|
|
}
|
|
|
|
static NumericUpDown()
|
|
{
|
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown), new FrameworkPropertyMetadata(typeof(NumericUpDown)));
|
|
}
|
|
|
|
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent(
|
|
"ValueChanged", RoutingStrategy.Direct,
|
|
typeof(ValueChangedEventHandler), typeof(NumericUpDown));
|
|
public event ValueChangedEventHandler ValueChanged
|
|
{
|
|
add
|
|
{
|
|
base.AddHandler(NumericUpDown.ValueChangedEvent, value);
|
|
}
|
|
remove
|
|
{
|
|
base.RemoveHandler(NumericUpDown.ValueChangedEvent, value);
|
|
}
|
|
}
|
|
|
|
public int Places
|
|
{
|
|
get => (int)GetValue(PlacesProperty);
|
|
set => SetValue(PlacesProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty PlacesProperty = DependencyProperty.Register("Places", typeof(int), typeof(NumericUpDown));
|
|
|
|
public double MaxValue
|
|
{
|
|
get => (double)GetValue(MaxValueProperty);
|
|
set => SetValue(MaxValueProperty, value);
|
|
}
|
|
public static readonly DependencyProperty MaxValueProperty =
|
|
DependencyProperty.Register("MaxValue", typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(100D, maxValueChangedCallback, coerceMaxValueCallback));
|
|
private static object coerceMaxValueCallback(DependencyObject d, object value)
|
|
{
|
|
double minValue = ((NumericUpDown)d).MinValue;
|
|
if ((double)value < minValue)
|
|
return minValue;
|
|
|
|
return value;
|
|
}
|
|
private static void maxValueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
NumericUpDown numericUpDown = ((NumericUpDown)d);
|
|
numericUpDown.CoerceValue(MinValueProperty);
|
|
numericUpDown.CoerceValue(ValueProperty);
|
|
}
|
|
|
|
public double MinValue
|
|
{
|
|
get => (double)GetValue(MinValueProperty);
|
|
set => SetValue(MinValueProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty MinValueProperty =
|
|
DependencyProperty.Register("MinValue", typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(0D, minValueChangedCallback, coerceMinValueCallback));
|
|
|
|
private static object coerceMinValueCallback(DependencyObject d, object value)
|
|
{
|
|
double maxValue = ((NumericUpDown)d).MaxValue;
|
|
if ((double)value > maxValue)
|
|
return maxValue;
|
|
|
|
return value;
|
|
}
|
|
|
|
private static void minValueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
NumericUpDown numericUpDown = ((NumericUpDown)d);
|
|
numericUpDown.CoerceValue(NumericUpDown.MaxValueProperty);
|
|
numericUpDown.CoerceValue(NumericUpDown.ValueProperty);
|
|
}
|
|
|
|
public double Increment
|
|
{
|
|
get => (double)GetValue(IncrementProperty);
|
|
set => SetValue(IncrementProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty IncrementProperty =
|
|
DependencyProperty.Register(nameof(Increment), typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(1D, null, coerceIncrementCallback));
|
|
|
|
private static object coerceIncrementCallback(DependencyObject d, object value)
|
|
{
|
|
NumericUpDown numericUpDown = ((NumericUpDown)d);
|
|
double i = numericUpDown.MaxValue - numericUpDown.MinValue;
|
|
if ((double)value > i)
|
|
return i;
|
|
|
|
return value;
|
|
}
|
|
|
|
public double Value
|
|
{
|
|
get => (double)GetValue(ValueProperty);
|
|
set => SetValue(ValueProperty, value);
|
|
}
|
|
|
|
public static readonly DependencyProperty ValueProperty =
|
|
DependencyProperty.Register(nameof(Value), typeof(double), typeof(NumericUpDown), new FrameworkPropertyMetadata(0D, valueChangedCallback, coerceValueCallback), validateValueCallback);
|
|
|
|
private static void valueChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
NumericUpDown numericUpDown = (NumericUpDown)d;
|
|
ValueChangedEventArgs ea =
|
|
new ValueChangedEventArgs(NumericUpDown.ValueChangedEvent, d, (double)e.OldValue, (double)e.NewValue);
|
|
numericUpDown.RaiseEvent(ea);
|
|
numericUpDown.PART_TextBox.Text = e.NewValue.ToString();
|
|
}
|
|
|
|
private static bool validateValueCallback(object value)
|
|
{
|
|
double val = (double)value;
|
|
if (val > double.MinValue && val < double.MaxValue)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
private static object coerceValueCallback(DependencyObject d, object value)
|
|
{
|
|
double val = (double)value;
|
|
double minValue = ((NumericUpDown)d).MinValue;
|
|
double maxValue = ((NumericUpDown)d).MaxValue;
|
|
double result;
|
|
if (val < minValue)
|
|
result = minValue;
|
|
else if (val > maxValue)
|
|
result = maxValue;
|
|
else
|
|
result = (double)value;
|
|
|
|
return result;
|
|
}
|
|
|
|
private void buttonUp_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (Value < MaxValue)
|
|
Value += Increment;
|
|
|
|
Value = Math.Round(Value, Places);
|
|
}
|
|
private void buttonDown_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
if (Value > MinValue)
|
|
Value -= Increment;
|
|
|
|
Value = Math.Round(Value, Places);
|
|
}
|
|
|
|
private void textBox_PreviewKeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.Key == Key.Space)
|
|
e.Handled = true;
|
|
}
|
|
private void textBox_TextChanged(object sender, TextChangedEventArgs e)
|
|
{
|
|
int index = PART_TextBox.CaretIndex;
|
|
double result;
|
|
if (!double.TryParse(PART_TextBox.Text, out result))
|
|
{
|
|
var changes = e.Changes.FirstOrDefault();
|
|
if (changes != null)
|
|
{
|
|
PART_TextBox.Text = PART_TextBox.Text.Remove(changes.Offset, changes.AddedLength);
|
|
PART_TextBox.CaretIndex = index > 0 ? index - changes.AddedLength : 0;
|
|
}
|
|
}
|
|
else if (result < MaxValue && result > MinValue)
|
|
Value = result;
|
|
else
|
|
{
|
|
PART_TextBox.Text = Value.ToString();
|
|
PART_TextBox.CaretIndex = index > 0 ? index - 1 : 0;
|
|
}
|
|
}
|
|
}
|
|
}
|