feat: add more input handling.

This commit is contained in:
rabbitism
2023-02-24 22:47:20 +08:00
parent d433c16314
commit 573e3ada21

View File

@@ -6,6 +6,7 @@ using Avalonia.Controls.Metadata;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Media.TextFormatting; using Avalonia.Media.TextFormatting;
@@ -54,9 +55,23 @@ public class IPv4Box: TemplatedControl
_presenters[2] = _thirdText; _presenters[2] = _thirdText;
_presenters[3] = _fourthText; _presenters[3] = _fourthText;
} }
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {
if (_currentActivePresenter is null) return;
var keymap = AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>();
bool Match(List<KeyGesture> gestures) => gestures.Any(g => g.Matches(e));
if (e.Key == Key.Enter)
{
ParseBytes();
SetIPAddress();
return;
}
if (Match(keymap.SelectAll))
{
_currentActivePresenter.SelectionStart = 0;
_currentActivePresenter.SelectionEnd = _currentActivePresenter.Text?.Length ?? 0;
return;
}
if (e.Key == Key.Tab) if (e.Key == Key.Tab)
{ {
_currentActivePresenter?.HideCaret(); _currentActivePresenter?.HideCaret();
@@ -73,7 +88,7 @@ public class IPv4Box: TemplatedControl
} }
else if (e.Key == Key.Back) else if (e.Key == Key.Back)
{ {
DeleteCurrentCharacter(_currentActivePresenter); DeleteImplementation(_currentActivePresenter);
} }
else if (e.Key == Key.Right ) else if (e.Key == Key.Right )
{ {
@@ -133,6 +148,7 @@ public class IPv4Box: TemplatedControl
if (e.Handled) return; if (e.Handled) return;
string? s = e.Text; string? s = e.Text;
if (string.IsNullOrEmpty(s)) return; if (string.IsNullOrEmpty(s)) return;
if (!char.IsNumber(s[0])) return;
if (_currentActivePresenter != null) if (_currentActivePresenter != null)
{ {
int index = _currentActivePresenter.CaretIndex; int index = _currentActivePresenter.CaretIndex;
@@ -151,8 +167,23 @@ public class IPv4Box: TemplatedControl
string? newText = string.IsNullOrEmpty(oldText) string? newText = string.IsNullOrEmpty(oldText)
? s ? s
: (oldText?.Substring(0, index) + s + oldText?.Substring(index)); : (oldText?.Substring(0, index) + s + oldText?.Substring(index));
if (newText.Length > 3)
{
newText = newText.Substring(0, 3);
}
_currentActivePresenter.Text = newText; _currentActivePresenter.Text = newText;
_currentActivePresenter.MoveCaretHorizontal(); _currentActivePresenter.MoveCaretHorizontal();
if (_currentActivePresenter.CaretIndex == 3)
{
_currentActivePresenter.HideCaret();
bool success = MoveToNextPresenter(_currentActivePresenter, true);
_currentActivePresenter.ShowCaret();
if (success)
{
SelectAll(_currentActivePresenter);
_currentActivePresenter.CaretIndex = 0;
}
}
} }
} }
} }
@@ -168,7 +199,9 @@ public class IPv4Box: TemplatedControl
var end = Math.Max(selectionStart, selectionEnd); var end = Math.Max(selectionStart, selectionEnd);
var text = presenter.Text; var text = presenter.Text;
string newText = text is null ? string.Empty : text.Substring(0, start) + text.Substring(end); string newText = text is null
? string.Empty
: text.Substring(0, start) + text.Substring(Math.Min(end, text.Length));
presenter.Text = newText; presenter.Text = newText;
presenter.MoveCaretToTextPosition(start); presenter.MoveCaretToTextPosition(start);
} }
@@ -193,7 +226,6 @@ public class IPv4Box: TemplatedControl
presenter?.ShowCaret(); presenter?.ShowCaret();
_currentActivePresenter = presenter; _currentActivePresenter = presenter;
var caretPosition = position.WithX(position.X - presenter.Bounds.X); var caretPosition = position.WithX(position.X - presenter.Bounds.X);
SetIPAddress();
presenter?.MoveCaretToPoint(caretPosition); presenter?.MoveCaretToPoint(caretPosition);
} }
else else
@@ -214,11 +246,20 @@ public class IPv4Box: TemplatedControl
ClearSelection(pre); ClearSelection(pre);
} }
_currentActivePresenter = null; _currentActivePresenter = null;
ParseBytes();
SetIPAddress();
}
private void ParseBytes()
{
_firstByte = byte.TryParse(_firstText?.Text, out byte b1) ? b1 : (byte)0; _firstByte = byte.TryParse(_firstText?.Text, out byte b1) ? b1 : (byte)0;
_secondByte = byte.TryParse(_secondText?.Text, out byte b2) ? b2 : (byte)0; _secondByte = byte.TryParse(_secondText?.Text, out byte b2) ? b2 : (byte)0;
_thirdByte = byte.TryParse(_thirdText?.Text, out byte b3) ? b3 : (byte)0; _thirdByte = byte.TryParse(_thirdText?.Text, out byte b3) ? b3 : (byte)0;
_fourthByte = byte.TryParse(_fourthText?.Text, out byte b4) ? b4 : (byte)0; _fourthByte = byte.TryParse(_fourthText?.Text, out byte b4) ? b4 : (byte)0;
SetIPAddress(); if (_firstText != null) _firstText.Text = _firstByte.ToString();
if (_secondText != null) _secondText.Text = _secondByte.ToString();
if (_thirdText != null) _thirdText.Text = _thirdByte.ToString();
if (_fourthText != null) _fourthText.Text = _fourthByte.ToString();
} }
protected override void OnGotFocus(GotFocusEventArgs e) protected override void OnGotFocus(GotFocusEventArgs e)
@@ -228,13 +269,15 @@ public class IPv4Box: TemplatedControl
base.OnGotFocus(e); base.OnGotFocus(e);
} }
private void MoveToNextPresenter(TextPresenter? presenter, bool selectAllAfterMove) private bool MoveToNextPresenter(TextPresenter? presenter, bool selectAllAfterMove)
{ {
if (presenter is null) return; if (presenter is null) return false;
if (Equals(presenter, _fourthText)) return false;
if (Equals(presenter, _firstText)) _currentActivePresenter = _secondText; if (Equals(presenter, _firstText)) _currentActivePresenter = _secondText;
else if (Equals(presenter, _secondText)) _currentActivePresenter = _thirdText; else if (Equals(presenter, _secondText)) _currentActivePresenter = _thirdText;
else if (Equals(presenter, _thirdText)) _currentActivePresenter = _fourthText; else if (Equals(presenter, _thirdText)) _currentActivePresenter = _fourthText;
if(selectAllAfterMove) SelectAll(_currentActivePresenter); if(selectAllAfterMove) SelectAll(_currentActivePresenter);
return true;
} }
private bool MoveToPreviousTextPresenter(TextPresenter? presenter) private bool MoveToPreviousTextPresenter(TextPresenter? presenter)
@@ -262,15 +305,30 @@ public class IPv4Box: TemplatedControl
address += _firstByte; address += _firstByte;
address += _secondByte << 8; address += _secondByte << 8;
address += _thirdByte << 16; address += _thirdByte << 16;
address += _fourthByte << 24; address += (long)_fourthByte << 24;
IPAddress = new IPAddress(address); try
{
IPAddress = new IPAddress(address);
}
catch
{
IPAddress = null;
}
} }
private void DeleteCurrentCharacter(TextPresenter? presenter) private void DeleteImplementation(TextPresenter? presenter)
{ {
if(presenter is null) return; if(presenter is null) return;
var oldText = presenter.Text; var oldText = presenter.Text;
if (string.IsNullOrWhiteSpace(oldText)) if (presenter.SelectionStart != presenter.SelectionEnd)
{
int start = presenter.SelectionStart;
int end = presenter.SelectionEnd;
string newText = oldText?.Substring(0, start) + oldText?.Substring(end);
presenter.Text = newText;
presenter.CaretIndex = start;
}
else if (string.IsNullOrWhiteSpace(oldText))
{ {
presenter.HideCaret(); presenter.HideCaret();
MoveToPreviousTextPresenter(presenter); MoveToPreviousTextPresenter(presenter);
@@ -279,12 +337,19 @@ public class IPv4Box: TemplatedControl
_currentActivePresenter.ShowCaret(); _currentActivePresenter.ShowCaret();
_currentActivePresenter.CaretIndex = _currentActivePresenter.Text?.Length ?? 0; _currentActivePresenter.CaretIndex = _currentActivePresenter.Text?.Length ?? 0;
} }
return;
} }
int index = presenter.CaretIndex; else
if (index == 0) return; {
string newText = oldText?.Substring(0, index - 1) + oldText?.Substring(index); int index = presenter.CaretIndex;
presenter.MoveCaretHorizontal(LogicalDirection.Backward); if (index == 0) return;
presenter.Text = newText; string newText = oldText?.Substring(0, index - 1) + oldText?.Substring(index);
presenter.MoveCaretHorizontal(LogicalDirection.Backward);
presenter.Text = newText;
}
}
public async void Cut()
{
} }
} }