Files
GSS2Rework/GSS2/Views/NumericKeyboardView.axaml.cs
T
amkovkov 72ae26eee7 comprehensive update
1) remove unused components: camera view (due it causes segmentation faults), compute resources and all related, illuminator controller (due in useless without camera view), image storage service, temperature and humidity service
2) database schema - reduce tables references, features storing in records themselves in compressed form, add records creation and editing date and time, add separator comment column
3) analysis - rework of pipeline and ui, now database storing only raw data and all display values calculated from it
4) lights service - add reconnection if disconnected
5) add width and height command line arguments
6) fix some typos and other issues
2026-06-29 15:13:29 +03:00

129 lines
3.6 KiB
C#

using System.Text;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Interactivity;
namespace GSS2.Views;
public partial class NumericKeyboardView : UserControl
{
public static readonly StyledProperty<double?> ValueProperty = AvaloniaProperty.Register<NumericKeyboardView, double?>(nameof(Value));
public double? Value
{
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly RoutedEvent<RoutedEventArgs> ClosedEvent = RoutedEvent.Register<NumericKeyboardView, RoutedEventArgs>(nameof(KeyboardClosed), RoutingStrategies.Bubble);
public event EventHandler<RoutedEventArgs> KeyboardClosed
{
add => AddHandler(ClosedEvent, value);
remove => RemoveHandler(ClosedEvent, value);
}
private readonly TextPresenter? _presenter;
private StringBuilder _text = new();
private bool changingValue = false;
private int _cursor = 0;
public NumericKeyboardView()
{
InitializeComponent();
ValueProperty.Changed.AddClassHandler<NumericKeyboardView>((sender, value) =>
{
if (sender != this)
return;
if (changingValue)
return;
if (value.NewValue is not double doubleValue)
{
changingValue = true;
_text = new();
_cursor = _text.Length;
changingValue = false;
UpdateDisplay();
return;
}
changingValue = true;
_text.Clear();
_text.Insert(0, doubleValue.ToString("G6").Replace(".", ","));
_cursor = _text.Length;
changingValue = false;
UpdateDisplay();
});
_presenter = this.FindControl<TextPresenter>("Text");
if (Value is not null)
_text.Insert(0, Value.Value.ToString("G6").Replace(".", ","));
_cursor = _text.Length;
_presenter?.ShowCaret();
UpdateDisplay();
}
private void KeyPressed(object? sender, RoutedEventArgs e)
{
if (sender is not Button btn || btn.Content is not string symbol) return;
if (symbol == "," && _cursor == 0)
return;
if (symbol == "," && _text.ToString().Contains(','))
{
var index = _text.ToString().IndexOf(",");
_text.Remove(index, 1);
if (index < _cursor)
_cursor--;
}
_text.Insert(_cursor, symbol);
_cursor++;
UpdateDisplay();
}
private void Backspace(object? sender, RoutedEventArgs e)
{
if (_cursor > 0)
{
_cursor--;
_text.Remove(_cursor, 1);
UpdateDisplay();
}
}
private void MoveCursorLeft(object? sender, RoutedEventArgs e)
{
_cursor = Math.Max(0, _cursor - 1);
UpdateDisplay();
}
private void MoveCursorRight(object? sender, RoutedEventArgs e)
{
_cursor = Math.Min(_text.Length, _cursor + 1);
UpdateDisplay();
}
private void Accept(object? sender, RoutedEventArgs e)
{
if (double.TryParse(_text.ToString().Replace(",", "."), out double value))
Value = value;
}
private void Cancel(object? sender, RoutedEventArgs e) => Value = null;
private void UpdateDisplay()
{
if (_presenter is null) return;
_presenter.Text = _text.ToString();
_presenter.CaretIndex = _cursor;
_presenter.InvalidateVisual();
if (double.TryParse(_text.ToString().Replace(",", "."), out double value))
Value = value;
}
}