Browse Source

Discard additional lines upon inserting when AcceptsReturn=false (#14173)

* Discard additional lines upon inserting when AcceptReturn=false

* Use LineBreakEnumerator for detecting line breaks

* Remove unused member

Co-authored-by: Max Katz <maxkatz6@outlook.com>

* Use Grapheme enumerator

---------

Co-authored-by: Markus <markus@mlet.at>
Co-authored-by: Max Katz <maxkatz6@outlook.com>
Co-authored-by: Benedikt Stebner <Gillibald@users.noreply.github.com>
#Conflicts:
#	src/Avalonia.Controls/TextBox.cs
release/11.0.9
markl65536 2 years ago
committed by Max Katz
parent
commit
8434202629
  1. 30
      src/Avalonia.Controls/TextBox.cs
  2. 38
      tests/Avalonia.Controls.UnitTests/TextBoxTests.cs

30
src/Avalonia.Controls/TextBox.cs

@ -16,6 +16,7 @@ using Avalonia.Utilities;
using Avalonia.Controls.Metadata;
using Avalonia.Media.TextFormatting;
using Avalonia.Automation.Peers;
using Avalonia.Media.TextFormatting.Unicode;
using Avalonia.Threading;
namespace Avalonia.Controls
@ -839,9 +840,9 @@ namespace Avalonia.Controls
private void PresenterPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if(e.Property == TextPresenter.PreeditTextProperty)
if (e.Property == TextPresenter.PreeditTextProperty)
{
if(string.IsNullOrEmpty(e.OldValue as string) && !string.IsNullOrEmpty(e.NewValue as string))
if (string.IsNullOrEmpty(e.OldValue as string) && !string.IsNullOrEmpty(e.NewValue as string))
{
PseudoClasses.Set(":empty", false);
@ -962,7 +963,7 @@ namespace Avalonia.Controls
return;
}
input = RemoveInvalidCharacters(input);
input = SanitizeInputText(input);
if (string.IsNullOrEmpty(input))
{
@ -1015,11 +1016,30 @@ namespace Avalonia.Controls
}
}
private string? RemoveInvalidCharacters(string? text)
private string? SanitizeInputText(string? text)
{
if (text is null)
return null;
if (!AcceptsReturn)
{
var lineBreakStart = 0;
var graphemeEnumerator = new GraphemeEnumerator(text.AsSpan());
while (graphemeEnumerator.MoveNext(out var grapheme))
{
if (grapheme.FirstCodepoint.IsBreakChar)
{
break;
}
lineBreakStart += grapheme.Length;
}
// All lines except the first one are discarded when TextBox does not accept Return key
text = text.Substring(0, lineBreakStart);
}
for (var i = 0; i < invalidCharacters.Length; i++)
{
text = text.Replace(invalidCharacters[i], string.Empty);
@ -2085,7 +2105,7 @@ namespace Avalonia.Controls
protected override Size MeasureOverride(Size availableSize)
{
if(_scrollViewer != null)
if (_scrollViewer != null)
{
var maxHeight = double.PositiveInfinity;

38
tests/Avalonia.Controls.UnitTests/TextBoxTests.cs

@ -949,6 +949,44 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Insert_Multiline_Text_Should_Accept_Extra_Lines_When_AcceptsReturn_Is_True()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
AcceptsReturn = true
};
RaiseTextEvent(target, $"123 {Environment.NewLine}456");
Assert.Equal($"123 {Environment.NewLine}456", target.Text);
}
}
[Fact]
public void Insert_Multiline_Text_Should_Discard_Extra_Lines_When_AcceptsReturn_Is_False()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
AcceptsReturn = false
};
RaiseTextEvent(target, $"123 {"\r"}456");
Assert.Equal("123 ", target.Text);
target.Text = "";
RaiseTextEvent(target, $"123 {"\r\n"}456");
Assert.Equal("123 ", target.Text);
}
}
[Fact]
public void Should_Fullfill_MaxLines_Contraint()
{

Loading…
Cancel
Save